Skip to content

Commit 6d3c228

Browse files
committed
Removed concrete Dialog class dependency within AssignedByValParameterMakeLocalCopyQuickFix
1 parent 8cd219b commit 6d3c228

10 files changed

+148
-71
lines changed

RetailCoder.VBE/Inspections/QuickFixes/AssignedByValParameterMakeLocalCopyQuickFix.cs

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,23 @@ public class AssignedByValParameterMakeLocalCopyQuickFix : QuickFixBase
1919
private readonly Declaration _target;
2020
private string _localCopyVariableName;
2121
private string[] _variableNamesAccessibleToProcedureContext;
22-
private bool _isQuickFixUnitTest;
22+
private IAssignedByValParameterQuickFixDialogFactory _factory;
2323

24-
public AssignedByValParameterMakeLocalCopyQuickFix(Declaration target, QualifiedSelection selection)
24+
public AssignedByValParameterMakeLocalCopyQuickFix(Declaration target, QualifiedSelection selection, IAssignedByValParameterQuickFixDialogFactory factory)
2525
: base(target.Context, selection, InspectionsUI.AssignedByValParameterMakeLocalCopyQuickFix)
2626
{
2727
_target = target;
28-
_isQuickFixUnitTest = false;
28+
_factory = factory;
2929
_localCopyVariableName = "x" + _target.IdentifierName.CapitalizeFirstLetter();
3030
_variableNamesAccessibleToProcedureContext = GetVariableNamesAccessibleToProcedureContext(_target.Context.Parent.Parent);
3131
}
3232

3333
public override bool CanFixInModule { get { return false; } }
3434
public override bool CanFixInProject { get { return false; } }
3535

36-
//This function exists solely to support unit testing
37-
public void TESTONLY_FixUsingAutoGeneratedName(string suggestedName = "")
38-
{
39-
//Prevent the popup dialog and forces the use of the Suggested Name
40-
_isQuickFixUnitTest = true;
41-
if (suggestedName.Length > 0)
42-
{
43-
_localCopyVariableName = suggestedName; //unit test poses as user input
44-
}
45-
46-
Fix();
47-
}
48-
4936
public override void Fix()
5037
{
51-
SetLocalCopyVariableName();
38+
RequestLocalCopyVariableName();
5239

5340
if (!ProposedLocalVariableNameIsValid() || IsCancelled)
5441
{
@@ -60,17 +47,14 @@ public override void Fix()
6047
InsertLocalVariableDeclarationAndAssignment();
6148
}
6249

63-
private void SetLocalCopyVariableName()
50+
private void RequestLocalCopyVariableName()
6451
{
65-
using (var view = new AssignedByValParameterQuickFixDialog(_target, Selection))
52+
using( var view = _factory.Create(_target.IdentifierName, _target.DeclarationType.ToString()))
6653
{
6754
view.NewName = _localCopyVariableName;
6855
view.IdentifierNamesAlreadyDeclared = _variableNamesAccessibleToProcedureContext;
69-
if (!_isQuickFixUnitTest)
70-
{
71-
view.ShowDialog();
72-
IsCancelled = view.DialogResult == DialogResult.Cancel;
73-
}
56+
view.ShowDialog();
57+
IsCancelled = view.DialogResult == DialogResult.Cancel;
7458
if (!IsCancelled)
7559
{
7660
_localCopyVariableName = view.NewName;
@@ -98,11 +82,9 @@ private void ReplaceAssignedByValParameterReferences()
9882
private void InsertLocalVariableDeclarationAndAssignment()
9983
{
10084
var blocks = QuickFixHelper.GetBlockStmtContextsForContext(_target.Context.Parent.Parent);
101-
var firstBlockLineNumber = blocks.FirstOrDefault().Start.Line;
102-
103-
var module = Selection.QualifiedName.Component.CodeModule;
10485
string[] lines = { BuildLocalCopyDeclaration(), BuildLocalCopyAssignment() };
105-
module.InsertLines(firstBlockLineNumber, lines);
86+
var module = Selection.QualifiedName.Component.CodeModule;
87+
module.InsertLines(blocks.FirstOrDefault().Start.Line, lines);
10688
}
10789

10890
private string BuildLocalCopyDeclaration()

RetailCoder.VBE/Inspections/Resources/InspectionsUI.de.resx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,4 @@ Falls der Parameter 'null' sein kann, bitte dieses Auftreten ignorieren. 'null'
594594
<data name="AggregateInspectionResultFormat" xml:space="preserve">
595595
<value>{0} ({1} Ergebnisse)</value>
596596
</data>
597-
<data name="AssignedByValParameterMakeLocalCopyQuickFix" xml:space="preserve">
598-
<value>Create and use a local copy of the parameter</value>
599-
</data>
600597
</root>

RetailCoder.VBE/Inspections/Resources/InspectionsUI.fr.resx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,4 @@ Si le paramètre peut être nul, ignorer ce résultat; passer une valeur nulle
604604
<data name="AggregateInspectionResultFormat" xml:space="preserve">
605605
<value>{0} ({1} résultats)</value>
606606
</data>
607-
<data name="AssignedByValParameterMakeLocalCopyQuickFix" xml:space="preserve">
608-
<value>Create and use a local copy of the parameter</value>
609-
</data>
610607
</root>

RetailCoder.VBE/Inspections/Results/AssignedByValParameterInspectionResult.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Rubberduck.Inspections.QuickFixes;
55
using Rubberduck.Inspections.Resources;
66
using Rubberduck.Parsing.Symbols;
7+
using Rubberduck.UI.Refactorings;
78

89
namespace Rubberduck.Inspections.Results
910
{
@@ -25,9 +26,10 @@ public override IEnumerable<QuickFixBase> QuickFixes
2526
{
2627
get
2728
{
29+
IAssignedByValParameterQuickFixDialogFactory factory = new AssignedByValParameterQuickFixDialogFactory();
2830
return _quickFixes ?? (_quickFixes = new QuickFixBase[]
2931
{
30-
new AssignedByValParameterMakeLocalCopyQuickFix(Target, QualifiedSelection),
32+
new AssignedByValParameterMakeLocalCopyQuickFix(Target, QualifiedSelection, factory),
3133
new PassParameterByReferenceQuickFix(Target, QualifiedSelection),
3234
new IgnoreOnceQuickFix(Context, QualifiedSelection, Inspection.AnnotationName)
3335
});

RetailCoder.VBE/Rubberduck.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,9 @@
470470
<Compile Include="UI\CodeExplorer\Commands\AddStdModuleCommand.cs" />
471471
<Compile Include="UI\CodeExplorer\Commands\AddTestModuleCommand.cs" />
472472
<Compile Include="UI\ModernFolderBrowser.cs" />
473+
<Compile Include="UI\Refactorings\AssignedByValParameterQuickFixDialogFactory.cs" />
474+
<Compile Include="UI\Refactorings\IAssignedByValParameterQuickFixDialog.cs" />
475+
<Compile Include="UI\Refactorings\IAssignedByValParameterQuickFixDialogFactory.cs" />
473476
<Compile Include="VersionCheck\IVersionCheck.cs" />
474477
<Compile Include="UI\Command\MenuItems\CommandBars\AppCommandBarBase.cs" />
475478
<Compile Include="UI\Command\MenuItems\CommandBars\ContextSelectionLabelMenuItem.cs" />

RetailCoder.VBE/UI/Refactorings/AssignedByValParameterQuickFixDialog.cs

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,42 @@
11
using System;
22
using System.Windows.Forms;
3-
using Rubberduck.Parsing.Symbols;
43
using Rubberduck.Inspections;
5-
using Rubberduck.VBEditor;
64
using System.Linq;
75

86
namespace Rubberduck.UI.Refactorings
97
{
10-
public partial class AssignedByValParameterQuickFixDialog : Form, IDialogView
8+
public partial class AssignedByValParameterQuickFixDialog : Form, IAssignedByValParameterQuickFixDialog
119
{
1210
private string[] _identifierNamesAlreadyDeclared;
11+
private string _identifierName;
1312

14-
public AssignedByValParameterQuickFixDialog(Declaration target, QualifiedSelection selection)
13+
public AssignedByValParameterQuickFixDialog(string identifierName, string declarationType)
1514
{
1615
InitializeComponent();
17-
InitializeCaptions();
18-
Target = target;
16+
InitializeCaptions(identifierName, declarationType);
17+
_identifierName = identifierName;
1918
_identifierNamesAlreadyDeclared = Enumerable.Empty<string>().ToArray();
2019
}
2120

22-
private void InitializeCaptions()
21+
private void InitializeCaptions(string identifierName, string targetDeclarationType)
2322
{
2423
Text = RubberduckUI.AssignedByValParamQFixDialog_Caption;
2524
OkButton.Text = RubberduckUI.OK;
2625
CancelDialogButton.Text = RubberduckUI.CancelButtonText;
2726
TitleLabel.Text = RubberduckUI.AssignedByValParamQFixDialog_TitleText;
28-
InstructionsLabel.Text = RubberduckUI.AssignedByValParamQFixDialog_InstructionsLabelText;
2927
NameLabel.Text = RubberduckUI.NameLabelText;
28+
29+
var declarationType =
30+
RubberduckUI.ResourceManager.GetString("DeclarationType_" + targetDeclarationType, Settings.Settings.Culture);
31+
InstructionsLabel.Text = string.Format(RubberduckUI.AssignedByValParamQFixDialog_InstructionsLabelText, declarationType,
32+
identifierName);
3033
}
3134

3235
private void NewNameBox_TextChanged(object sender, EventArgs e)
3336
{
3437
NewName = NewNameBox.Text;
3538
}
3639

37-
private Declaration _target;
38-
public Declaration Target
39-
{
40-
get { return _target; }
41-
set
42-
{
43-
_target = value;
44-
if (_target == null)
45-
{
46-
return;
47-
}
48-
SetInstructionLableText();
49-
}
50-
}
51-
5240
public string NewName
5341
{
5442
get { return NewNameBox.Text; }
@@ -65,14 +53,6 @@ public string[] IdentifierNamesAlreadyDeclared
6553
set { _identifierNamesAlreadyDeclared = value; }
6654
}
6755

68-
private void SetInstructionLableText()
69-
{
70-
var declarationType =
71-
RubberduckUI.ResourceManager.GetString("DeclarationType_" + _target.DeclarationType, Settings.Settings.Culture);
72-
InstructionsLabel.Text = string.Format(RubberduckUI.AssignedByValParamQFixDialog_InstructionsLabelText, declarationType,
73-
_target.IdentifierName);
74-
}
75-
7656
private string GetVariableNameFeedback()
7757
{
7858
var validator = new VariableNameValidator(NewName);
@@ -124,12 +104,14 @@ private bool UserInputIsBlank()
124104

125105
private bool IsByValIdentifier()
126106
{
127-
return NewName.Equals(Target.IdentifierName, StringComparison.OrdinalIgnoreCase);
107+
return NewName.Equals(_identifierName, StringComparison.OrdinalIgnoreCase);
128108
}
129109

130110
private bool NewNameAlreadyUsed()
131111
{
132-
return _identifierNamesAlreadyDeclared.Contains(NewName);
112+
//Comparison needs to be case-insensitive, or VBE will often change an existing
113+
//same-spelling local variable's casing to conform with the NewName
114+
return _identifierNamesAlreadyDeclared.Any(n => n.Equals(NewName, StringComparison.OrdinalIgnoreCase));
133115
}
134116
}
135117
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Rubberduck.Parsing.Symbols;
7+
using Rubberduck.VBEditor;
8+
9+
namespace Rubberduck.UI.Refactorings
10+
{
11+
public class AssignedByValParameterQuickFixDialogFactory : IAssignedByValParameterQuickFixDialogFactory
12+
{
13+
IAssignedByValParameterQuickFixDialog IAssignedByValParameterQuickFixDialogFactory.Create(string identifier, string identifierType)
14+
{
15+
return new AssignedByValParameterQuickFixDialog(identifier, identifierType);
16+
}
17+
}
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using System.Windows.Forms;
7+
8+
namespace Rubberduck.UI.Refactorings
9+
{
10+
public interface IAssignedByValParameterQuickFixDialog : IDialogView
11+
{
12+
DialogResult DialogResult { get;}
13+
string NewName { get; set; }
14+
string[] IdentifierNamesAlreadyDeclared { get; set; }
15+
}
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Rubberduck.Parsing.Symbols;
2+
using Rubberduck.VBEditor;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace Rubberduck.UI.Refactorings
10+
{
11+
public interface IAssignedByValParameterQuickFixDialogFactory
12+
{
13+
IAssignedByValParameterQuickFixDialog Create(string identifier, string identifierType);
14+
}
15+
}

RubberduckTests/Inspections/AssignedByValParameterMakeLocalCopyQuickFixTests.cs

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,20 @@
99
using Rubberduck.Inspections.Resources;
1010
using RubberduckTests.Mocks;
1111
using System.Threading;
12+
using Rubberduck.UI.Refactorings;
13+
using Rubberduck.Parsing.Symbols;
14+
using Rubberduck.VBEditor;
15+
using System;
16+
using System.Windows.Forms;
1217

1318
namespace RubberduckTests.Inspections
1419
{
20+
1521
[TestClass]
16-
public class AssignedByValParameterMakeLocalCopyQuickFixTests
22+
public class AssignedByValParameterMakeLocalCopyQuickFixTests : IAssignedByValParameterQuickFixDialogFactory
1723
{
24+
private IAssignedByValParameterQuickFixDialog _mockDialog;
25+
1826
[TestMethod]
1927
[TestCategory("Inspections")]
2028
public void AssignedByValParameter_LocalVariableAssignment()
@@ -453,10 +461,20 @@ private string ApplyLocalVariableQuickFixToVBAFragment(string inputCode, string
453461
var vbe = BuildMockVBEStandardModuleForVBAFragment(inputCode);
454462
var inspectionResults = GetInspectionResults(vbe);
455463

464+
//If the test calls for a specific user entered variable name, then
465+
//make the Mock dialog now so we can retain the input
466+
if (userEnteredName.Length > 0)
467+
{
468+
var mockDialog = new MockAssignedByValParameterQuickFixDialog();
469+
mockDialog.SetupUserEnteredName(userEnteredName);
470+
_mockDialog = (IAssignedByValParameterQuickFixDialog)mockDialog;
471+
}
472+
456473
var quickFixBase = inspectionResults.First().QuickFixes.Single(s => s is AssignedByValParameterMakeLocalCopyQuickFix);
457-
AssignedByValParameterMakeLocalCopyQuickFix assignByValParamQFix = (AssignedByValParameterMakeLocalCopyQuickFix)quickFixBase;
458474

459-
assignByValParamQFix.TESTONLY_FixUsingAutoGeneratedName(userEnteredName);
475+
//Create a new instance of the QuickFix referencing the test-version of the dialog factory
476+
var testQuickFix = new AssignedByValParameterMakeLocalCopyQuickFix(inspectionResults.FirstOrDefault().Target, quickFixBase.Selection, this);
477+
testQuickFix.Fix();
460478

461479
return GetModuleContent(vbe);
462480
}
@@ -483,5 +501,52 @@ private Mock<IVBE> BuildMockVBEStandardModuleForVBAFragment(string inputCode)
483501
IVBComponent component;
484502
return builder.BuildFromSingleStandardModule(inputCode, out component);
485503
}
504+
505+
//Test class provides the dialog factory implementation for tests
506+
public IAssignedByValParameterQuickFixDialog Create(string identifier, string identifierType)
507+
{
508+
if(_mockDialog == null)
509+
{
510+
_mockDialog = (IAssignedByValParameterQuickFixDialog)new MockAssignedByValParameterQuickFixDialog();
511+
}
512+
return _mockDialog;
513+
}
514+
515+
//Provide an IAssignedByValParameterQuickFixDialog implementation for testing
516+
public class MockAssignedByValParameterQuickFixDialog : IAssignedByValParameterQuickFixDialog
517+
{
518+
private string _testLocalVariableName;
519+
public MockAssignedByValParameterQuickFixDialog()
520+
{
521+
_testLocalVariableName = string.Empty;
522+
}
523+
public DialogResult ShowDialog() { return DialogResult.OK; }
524+
525+
public void Dispose()
526+
{
527+
}
528+
public void SetupUserEnteredName(string response)
529+
{
530+
_testLocalVariableName = response;
531+
}
532+
public DialogResult DialogResult { set; get; }
533+
private string _newName;
534+
public string NewName
535+
{
536+
get
537+
{
538+
if (_testLocalVariableName.Length > 0)
539+
{
540+
return _testLocalVariableName;
541+
}
542+
else
543+
{
544+
return _newName;
545+
}
546+
}
547+
set { _newName = value; }
548+
}
549+
public string[] IdentifierNamesAlreadyDeclared { get; set; }
550+
}
486551
}
487552
}

0 commit comments

Comments
 (0)