@@ -20,6 +20,74 @@ namespace RubberduckTests.Refactoring
20
20
[ TestClass ]
21
21
public class RenameTests : VbeTestBase
22
22
{
23
+ [ TestMethod ]
24
+ public void RenameRefactoring_RenameSub_Issue2727 ( )
25
+ {
26
+ //Input
27
+ string inputCode = GetIssue2727ExampleCode ( ) ;
28
+
29
+ Selection selection = Select2727Variable ( ) ;
30
+
31
+ //New name provided by the user - no conflicts
32
+ var userEnteredName = "Value" ;
33
+
34
+ //Expectation
35
+ //Expecation is that the messageBox.Show() is not invoked
36
+
37
+ //Arrange
38
+ var builder = new MockVbeBuilder ( ) ;
39
+ IVBComponent component ;
40
+ var vbe = builder . BuildFromSingleStandardModule ( inputCode , out component , selection ) ;
41
+ var project = vbe . Object . VBProjects [ 0 ] ;
42
+ var module = project . VBComponents [ 0 ] . CodeModule ;
43
+ var mockHost = new Mock < IHostApplication > ( ) ;
44
+ mockHost . SetupAllProperties ( ) ;
45
+ var parser = MockParser . Create ( vbe . Object , new RubberduckParserState ( vbe . Object ) ) ;
46
+
47
+ parser . Parse ( new CancellationTokenSource ( ) ) ;
48
+ if ( parser . State . Status >= ParserState . Error ) { Assert . Inconclusive ( "Parser Error" ) ; }
49
+
50
+ var qualifiedSelection = new QualifiedSelection ( new QualifiedModuleName ( component ) , selection ) ;
51
+
52
+ var msgbox = new Mock < IMessageBox > ( ) ;
53
+ msgbox . Setup ( m => m . Show ( It . IsAny < string > ( ) , It . IsAny < string > ( ) , MessageBoxButtons . YesNo , It . IsAny < MessageBoxIcon > ( ) ) )
54
+ . Returns ( DialogResult . Yes ) ;
55
+
56
+ var vbeWrapper = vbe . Object ;
57
+ var model = new RenameModel ( vbeWrapper , parser . State , qualifiedSelection , msgbox . Object ) { NewName = userEnteredName } ;
58
+
59
+ //SetupFactory
60
+ var factory = SetupFactory ( model ) ;
61
+
62
+ //Act
63
+ var refactoring = new RenameRefactoring ( vbeWrapper , factory . Object , msgbox . Object , parser . State ) ;
64
+ refactoring . Refactor ( qualifiedSelection ) ;
65
+
66
+ //Assert
67
+ //#2727 bug describes a scenario where a declaration collision is detected where none exists.
68
+ //The result of detecting one or more collisions is that the messagebox is presented to the user
69
+ //To see if he wants to continue with the Renaming process.
70
+ //To pass this test, FindDeclarationForIdentifier() should find zero collisions and therefore
71
+ //skips the logic that presents the message box to the user.
72
+ bool msgboxShowWasInvoked = true ; // == failing condition
73
+ try
74
+ {
75
+ //Throws an exception if Show() was NOT called => this is the successful behavior
76
+ msgbox . Verify ( m => m . Show ( It . IsAny < string > ( ) , It . IsAny < string > ( ) , MessageBoxButtons . YesNo , It . IsAny < MessageBoxIcon > ( ) ) ) ;
77
+ msgboxShowWasInvoked = true ; //this line executed if the MessageBox is presented to the user
78
+ }
79
+ catch ( MockException )
80
+ {
81
+ msgboxShowWasInvoked = false ;
82
+ }
83
+ catch
84
+ {
85
+ throw ;
86
+ }
87
+ Assert . IsFalse ( msgboxShowWasInvoked , "RenameRefactoring found a conflicting declaration where none exists." ) ;
88
+ }
89
+
90
+
23
91
[ TestMethod ]
24
92
public void RenameRefactoring_RenameSub ( )
25
93
{
@@ -1421,5 +1489,64 @@ private static Mock<IRefactoringPresenterFactory<IRenamePresenter>> SetupFactory
1421
1489
}
1422
1490
1423
1491
#endregion
1492
+
1493
+ //Module code taken directly from Issue #2727 - choosing to rename "ic" in 'Let Industry'
1494
+ //resulted in a false-positive name collision with parameter 'Value' in 'Let IndustryCode'.
1495
+ private string GetIssue2727ExampleCode ( )
1496
+ {
1497
+ return
1498
+ @"
1499
+ Option Explicit
1500
+ '@folder ""Data Objects""
1501
+
1502
+ Private pName As String
1503
+ Private pIndustryCode As Long
1504
+ Private pIndustry As String
1505
+ Private pLastYearAppts As Long
1506
+ Private pLastYearEmail As Long
1507
+
1508
+ Public Property Get IndustryCode() As String
1509
+ IndustryCode = pIndustryCode
1510
+ End Property
1511
+ Public Property Let IndustryCode(ByVal Value As String)
1512
+ pIndustryCode = Value
1513
+ End Property
1514
+
1515
+ Public Property Get Industry() As String
1516
+ Industry = pIndustry
1517
+ End Property
1518
+ Public Property Let Industry(ByVal ic As String)
1519
+ pIndustry = ic
1520
+ End Property
1521
+
1522
+ Public Property Get LastYearAppts() As Long
1523
+ LastYearAppts = pLastYearAppts
1524
+ End Property
1525
+ Public Property Let LastYearAppts(ByVal Value As Long)
1526
+ pLastYearAppts = Value
1527
+ End Property
1528
+ " ;
1529
+ }
1530
+ private Selection Select2727Variable ( )
1531
+ {
1532
+ var inputCode = GetIssue2727ExampleCode ( ) ;
1533
+ //Create the selection
1534
+ var splitToken = new string [ ] { "\r \n " } ;
1535
+ const string renameTarget = " ic " ;
1536
+
1537
+ var lines = inputCode . Split ( splitToken , System . StringSplitOptions . None ) ;
1538
+ int lineNumber = 0 ;
1539
+ for ( int idx = 0 ; idx < lines . Count ( ) & lineNumber < 1 ; idx ++ )
1540
+ {
1541
+ if ( lines [ idx ] . Contains ( renameTarget ) )
1542
+ {
1543
+ lineNumber = idx + 1 ;
1544
+ }
1545
+ }
1546
+ var column = lines [ lineNumber - 1 ] . IndexOf ( renameTarget ) + 3 ; /*places cursor between the 'i' and 'c'*/
1547
+ var selection = new Selection ( lineNumber , column , lineNumber , column ) ;
1548
+ return selection ;
1549
+ }
1550
+
1424
1551
}
1425
1552
}
0 commit comments