public void ImplementInterface_Function_WithImplicitType()
        {
            //Input
            const string inputCode1 =
                @"Public Function Foo()
End Function";

            const string inputCode2 =
                @"Implements Class1";

            var selection = Selection.Home;

            //Expectation
            const string expectedCode =
                @"Implements Class1

Private Function Class1_Foo() As Variant
    Err.Raise 5 'TODO implement interface member
End Function
";

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                null,
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode, actualCode["Class2"]);
        }
        public void ImplementInterface_Procedure_WithParams()
        {
            //Input
            const string inputCode1 =
                @"Public Sub Foo(ByVal a As Integer, ByRef b, c, d As Long)
End Sub";

            const string inputCode2 =
                @"Implements Class1";
            var selection = Selection.Home;

            //Expectation
            const string expectedCode =
                @"Implements Class1

Private Sub Class1_Foo(ByVal a As Integer, ByRef b As Variant, ByRef c As Variant, ByRef d As Long)
    Err.Raise 5 'TODO implement interface member
End Sub
";

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                null,
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode, actualCode["Class2"]);
        }
        public void ImplementInterface_SelectionOnImplementsStatement()
        {
            //Input
            const string inputCode1 =
                @"Public Sub Foo()
End Sub";

            const string inputCode2 =
                @"Implements Class1";

            var selection = Selection.Home;

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                null,
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule));

            StringAssert.Contains("Implements Class1", actualCode["Class2"]);
            StringAssert.Contains("Private Sub Class1_Foo()", actualCode["Class2"]);
            StringAssert.Contains(errRaise, actualCode["Class2"]);
            StringAssert.Contains(todoMsg, actualCode["Class2"]);
            StringAssert.Contains("End Sub", actualCode["Class2"]);
        }
        public void ImplementsCorrectInterface_MultipleInterfaces()
        {
            //Input
            const string inputCode1 =
                @"Public Sub Foo()
End Sub";

            const string inputCode2 =
                @"Implements Class1
Implements Class3";

            var selection = new Selection(1, 1);

            const string inputCode3 =
                @"Public Sub Foo()
End Sub";

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                null,
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule),
                ("Class3", inputCode3, ComponentType.ClassModule));

            StringAssert.Contains("Implements Class3", actualCode["Class2"]);
            StringAssert.Contains(errRaise, actualCode["Class2"]);
            StringAssert.Contains(todoMsg, actualCode["Class2"]);
        }
        public void ImplementInterface_PropertySet_WithParam()
        {
            //Input
            const string inputCode1 =
                @"Public Property Set Foo(a)
End Property";

            const string inputCode2 =
                @"Implements Class1";

            var selection = Selection.Home;

            //Expectation
            const string expectedCode =
                @"Implements Class1

Private Property Set Class1_Foo(ByRef a As Variant)
    Err.Raise 5 'TODO implement interface member
End Property
";

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                null,
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode, actualCode["Class2"]);
        }
Example #6
0
        public void MoveToFolderRefactoring_UpdateAnnotation()
        {
            const string code         = @"
'@Folder(""MyOldFolder.MyOldSubfolder.SubSub"")
Public Sub Foo()
End Sub
";
            const string expectedCode = @"
'@Folder ""MyNewFolder.MySubFolder""
Public Sub Foo()
End Sub
";
            Func <MoveMultipleToFolderModel, MoveMultipleToFolderModel> presenterAction = (model) =>
            {
                model.TargetFolder = "MyNewFolder.MySubFolder";
                return(model);
            };

            var refactoredCode = RefactoredCode(
                "TestModule",
                DeclarationType.Module,
                presenterAction,
                null,
                ("TestModule", code, ComponentType.StandardModule));

            Assert.AreEqual(expectedCode, refactoredCode["TestModule"]);
        }
Example #7
0
        public void GivenReferencedPublicField_UpdatesReferenceToNewProperty()
        {
            const string codeClass1 =
                @"|Public fizz As Integer

Sub Foo()
    fizz = 1
End Sub";
            const string codeClass2 =
                @"Sub Foo()
    Dim theClass As Class1
    theClass.fizz = 0
    Bar theClass.fizz
End Sub

Sub Bar(ByVal v As Integer)
End Sub";

            var presenterAction = Support.SetParametersForSingleTarget("fizz", "Name", true);

            var class1CodeString = codeClass1.ToCodeString();
            var actualCode       = RefactoredCode(
                "Class1",
                class1CodeString.CaretPosition.ToOneBased(),
                presenterAction,
                null,
                false,
                ("Class1", class1CodeString.Code, ComponentType.ClassModule),
                ("Class2", codeClass2, ComponentType.ClassModule));

            StringAssert.Contains("Name = 1", actualCode["Class1"]);
            StringAssert.Contains("theClass.Name = 0", actualCode["Class2"]);
            StringAssert.Contains("Bar theClass.Name", actualCode["Class2"]);
            StringAssert.DoesNotContain("fizz", actualCode["Class2"]);
        }
Example #8
0
        public void ExtractInterfaceRefactoring_InvalidTargetType_Throws()
        {
            //Input
            const string inputCode =
                @"Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
End Sub";

            Func <ExtractInterfaceModel, ExtractInterfaceModel> presenterAction = model =>
            {
                foreach (var interfaceMember in model.Members)
                {
                    interfaceMember.IsSelected = true;
                }

                return(model);
            };

            var actualCode = RefactoredCode(
                "Module",
                DeclarationType.ProceduralModule,
                presenterAction,
                typeof(InvalidDeclarationTypeException),
                ("Module", inputCode, ComponentType.StandardModule));

            Assert.AreEqual(inputCode, actualCode["Module"]);
        }
Example #9
0
        public void MoveToFolderRefactoring_NameContainingDoubleQuotes()
        {
            const string code         = @"
Public Sub Foo()
End Sub
";
            const string expectedCode = @"'@Folder ""MyNew""""Folder.My""""""""""""""""SubFolder""

Public Sub Foo()
End Sub
";
            Func <MoveMultipleToFolderModel, MoveMultipleToFolderModel> presenterAction = (model) =>
            {
                model.TargetFolder = "MyNew\"Folder.My\"\"\"\"SubFolder";
                return(model);
            };

            var refactoredCode = RefactoredCode(
                "TestModule",
                DeclarationType.Module,
                presenterAction,
                null,
                ("TestModule", code, ComponentType.StandardModule));

            Assert.AreEqual(expectedCode, refactoredCode["TestModule"]);
        }
Example #10
0
        public void ExtractInterfaceRefactoring_NoValidTargetSelected_Throws()
        {
            //Input
            const string inputCode =
                @"Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
End Sub";
            var selection = new Selection(1, 23, 1, 27);

            Func <ExtractInterfaceModel, ExtractInterfaceModel> presenterAction = model =>
            {
                foreach (var interfaceMember in model.Members)
                {
                    interfaceMember.IsSelected = true;
                }

                return(model);
            };

            var actualCode = RefactoredCode(
                "Module",
                selection,
                presenterAction,
                typeof(NoDeclarationForSelectionException),
                false,
                ("Module", inputCode, ComponentType.StandardModule));

            Assert.AreEqual(inputCode, actualCode["Module"]);
        }
        public void ExtractInterfaceRefactoring_RenamesReferencesOfNonInterfaceMembers(ExtractInterfaceImplementationOption extractOption)
        {
            const string inputCode =
                @"
Public Function AddABunch(ByVal arg1 As Long) As Long
    AddABunch = AddOne(arg1) + AddTwo(arg1) + AddThree(arg1)
End Function

Public Function AddOne(ByVal arg1 As Long) As Long
    AddOne = arg1 + 1
End Function

Public Function AddTwo(ByVal arg1 As Long) As Long
    AddTwo = arg1 + 2
End Function

Public Function AddThree(ByVal arg1 As Long) As Long
    AddThree = arg1 + 3
End Function

Public Function SomeOtherFunction(ByVal arg1 As Long) As Long
    SomeOtherFunction = AddOne(arg1) + AddTwo(arg1) + AddThree(arg1)
End Function
";

            ExtractInterfaceModel presenterAction(ExtractInterfaceModel model)
            => UserSelectsAllMembers(model, extractOption);

            var actualCode       = RefactoredCode("Class", DeclarationType.ClassModule, presenterAction, null, ("Class", inputCode, ComponentType.ClassModule));
            var sourceModuleCode = actualCode["Class"];

            StringAssert.DoesNotContain(errRaise, sourceModuleCode);
            StringAssert.Contains("IClass_AddABunch = IClass_AddOne(arg1) + IClass_AddTwo(arg1) + IClass_AddThree(arg1)", sourceModuleCode);
            StringAssert.Contains("SomeOtherFunction = IClass_AddOne(arg1) + IClass_AddTwo(arg1) + IClass_AddThree(arg1)", sourceModuleCode);
        }
        public void MoveCloser_RespectsObjectProperties_InUsages()
        {
            string inputClassCode =
                @"
Option Explicit

Private _name As Long
Private _myOtherProperty As Long

Public Property Set Name(name As String)
    _name = name
End Property

Public Property Get Name() As String
    Name = _name
End Property

Public Property Set OtherProperty(val As Long)
    _myOtherProperty = val
End Property

Public Property Get OtherProperty() As Long
    OtherProperty = _myOtherProperty
End Property

";
            string inputCode = @"Private foo As Class1


Public Sub Test()
    Debug.Print ""Some statements between""
    Debug.Print ""Declaration and first usage!""
    Set foo = new Class1
    foo.Name = ""FooName""
    foo.OtherProperty = 1626
End Sub";

            var selection = new Selection(1, 1);

            const string expectedCode = @"

Public Sub Test()
    Debug.Print ""Some statements between""
    Debug.Print ""Declaration and first usage!""
    Dim foo As Class1
    Set foo = new Class1
    foo.Name = ""FooName""
    foo.OtherProperty = 1626
End Sub";

            var actualCode = RefactoredCode(
                "Module1",
                selection,
                null,
                false,
                ("Module1", inputCode, ComponentType.StandardModule),
                ("Class1", inputClassCode, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode, actualCode["Module1"]);
        }
        public void MoveContainingFolderRefactoring_WorksForMultipleInFolder()
        {
            const string code1         = @"
'@Folder(""MyOldFolder.MyOldSubFolder"")
Public Sub Foo()
End Sub
";
            const string code2         = @"
'@Folder(""MyOldFolder.MyOldSubFolder"")
Public Sub Foo()
End Sub
";
            const string code3         = @"
'@Folder(""MyOldFolder.MyOldSubFolder.SubSub"")
Public Sub Foo()
End Sub
";
            const string code4         = @"
'@Folder(""MyOldFolder.MyOtherSubFolder"")
Public Sub Foo()
End Sub
";
            const string expectedCode1 = @"
'@Folder ""MyNewFolder.MySubFolder.MyOldSubFolder""
Public Sub Foo()
End Sub
";
            const string expectedCode2 = @"
'@Folder ""MyNewFolder.MySubFolder.MyOldSubFolder""
Public Sub Foo()
End Sub
";
            const string expectedCode3 = @"
'@Folder ""MyNewFolder.MySubFolder.MyOldSubFolder.SubSub""
Public Sub Foo()
End Sub
";
            const string expectedCode4 = code4;

            Func <MoveMultipleFoldersModel, MoveMultipleFoldersModel> presenterAction = (model) =>
            {
                model.TargetFolder = "MyNewFolder.MySubFolder";
                return(model);
            };

            var refactoredCode = RefactoredCode(
                "TestModule",
                DeclarationType.Module,
                presenterAction,
                null,
                ("TestModule", code1, ComponentType.StandardModule),
                ("SameFolderModule", code2, ComponentType.StandardModule),
                ("SubFolderModule", code3, ComponentType.StandardModule),
                ("OtherFolderModule", code4, ComponentType.StandardModule));

            Assert.AreEqual(expectedCode1, refactoredCode["TestModule"]);
            Assert.AreEqual(expectedCode2, refactoredCode["SameFolderModule"]);
            Assert.AreEqual(expectedCode3, refactoredCode["SubFolderModule"]);
            Assert.AreEqual(expectedCode4, refactoredCode["OtherFolderModule"]);
        }
Example #14
0
        public void DoesNotImplementInterface_SelectionNotOnImplementsStatement()
        {
            //Input
            const string inputCode1 =
                @"Public Sub Foo()
End Sub";

            const string inputCode2 =
                @"Implements Class1
   
";
            var selection = new Selection(2, 2);

            //Expectation
            const string expectedCode =
                @"Implements Class1
   
";

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                typeof(NoImplementsStatementSelectedException),
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode, actualCode["Class2"]);
        }
        public void MoveCloserToUsageRefactoring_FieldInOtherClass()
        {
            //Input
            const string inputModuleCode =
                @"Public bar As Boolean";

            const string inputClassCode =
                @"Private Sub Foo()
Module1.bar = True
End Sub";
            var selection = new Selection(1, 1);

            //Expectation
            const string expectedModuleCode =
                @"";

            const string expectedClassCode =
                @"Private Sub Foo()
Dim bar As Boolean
bar = True
End Sub";

            var actualCode = RefactoredCode(
                "Module1",
                selection,
                null,
                false,
                ("Module1", inputModuleCode, ComponentType.StandardModule),
                ("Class1", inputClassCode, ComponentType.ClassModule));

            Assert.AreEqual(expectedModuleCode, actualCode["Module1"]);
            Assert.AreEqual(expectedClassCode, actualCode["Class1"]);
        }
Example #16
0
        public void ImplementInterface_SelectionOnImplementsStatement()
        {
            //Input
            const string inputCode1 =
                @"Public Sub Foo()
End Sub";

            const string inputCode2 =
                @"Implements Class1";

            var selection = Selection.Home;

            //Expectation
            const string expectedCode =
                @"Implements Class1

Private Sub Class1_Foo()
    Err.Raise 5 'TODO implement interface member
End Sub
";

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                null,
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode, actualCode["Class2"]);
        }
Example #17
0
        public void ImplementsInterfaceInUserFormModule()
        {
            const string interfaceCode = @"Option Explicit
Public Sub DoSomething()
End Sub
";
            const string initialCode   = @"Implements IInterface";

            var selection = Selection.Home;

            const string expectedCode = @"Implements IInterface

Private Sub IInterface_DoSomething()
    Err.Raise 5 'TODO implement interface member
End Sub
";

            var actualCode = RefactoredCode(
                "Form1",
                selection,
                null,
                false,
                ("IInterface", interfaceCode, ComponentType.ClassModule),
                ("Form1", initialCode, ComponentType.UserForm));

            Assert.AreEqual(expectedCode, actualCode["Form1"]);
        }
        public void ImplementInterface_PublicVariant(string inputCode1)
        {
            const string inputCode2 =
                @"Implements Class1";

            var selection = Selection.Home;

            //Expectation
            const string expectedCode =
                @"Implements Class1

Private Property Get Class1_Foo() As Variant
    Err.Raise 5 'TODO implement interface member
End Property

Private Property Let Class1_Foo(ByVal rhs As Variant)
    Err.Raise 5 'TODO implement interface member
End Property

Private Property Set Class1_Foo(ByVal rhs As Variant)
    Err.Raise 5 'TODO implement interface member
End Property
";

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                null,
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode, actualCode["Class2"]);
        }
        public void UserDefinedTypeMembers_ObjectField(string accessibility)
        {
            string inputCode =
                $@"
Option Explicit

{accessibility} mThe|Class As Class1";

            string classContent =
                $@"
Option Explicit

Private Sub Class_Initialize()
End Sub
";

            var presenterAction = Support.UserAcceptsDefaults();

            var codeString       = inputCode.ToCodeString();
            var actualModuleCode = RefactoredCode(
                "Module1",
                codeString.CaretPosition.ToOneBased(),
                presenterAction,
                null,
                false,
                ("Class1", classContent, ComponentType.ClassModule),
                ("Module1", codeString.Code, ComponentType.StandardModule));

            var actualCode = actualModuleCode["Module1"];

            StringAssert.Contains($"Private mTheClass As Class1", actualCode);
            StringAssert.Contains($"Set mTheClass = {Support.RHSIdentifier}", actualCode);
            StringAssert.Contains($"Set TheClass = mTheClass", actualCode);
            StringAssert.Contains($"Public Property Set TheClass", actualCode);
        }
        public void ExtractInterfaceRefactoring_IndenterApplied()
        {
            var inputCode =
                $@"
Public Function DivideBy(ByVal arg1 As Long, ByVal arg2 As Long) As Single
On Error Goto ErrorExit:
Dim result As Single
result = arg1 / arg2
DivideBy = result
Exit Function
ErrorExit:
DivideBy = 0
End Function";

            var expectedCode =
                $@"Private Function IClass_DivideBy(ByVal arg1 As Long, ByVal arg2 As Long) As Single
    On Error Goto ErrorExit:
    Dim result As Single
    result = arg1 / arg2
    IClass_DivideBy = result
    Exit Function
    ErrorExit:
    IClass_DivideBy = 0
End Function";

            var extractOption = ExtractInterfaceImplementationOption.ReplaceObjectMembersWithInterface;

            ExtractInterfaceModel presenterAction(ExtractInterfaceModel model)
            => UserSelectsAllMembers(model, extractOption);

            var actualCode       = RefactoredCode("Class", DeclarationType.ClassModule, presenterAction, null, ("Class", inputCode, ComponentType.ClassModule));
            var sourceModuleCode = actualCode["Class"].Substring(actualCode["Class"].IndexOf("\r\n")).Trim();

            Assert.AreEqual(expectedCode, sourceModuleCode);
        }
        public void ClassModuleUDTFieldSelection_ExternalReferences_ClassModule()
        {
            var sourceModuleName = "SourceModule";
            var sourceClassName  = "theClass";
            var sourceModuleCode =
                $@"

Public th|is As TBar";


            string classModuleReferencingCode =
                $@"Option Explicit

Private {sourceClassName} As {sourceModuleName}
Private Const foo As String = ""Foo""
Private Const bar As Long = 7

Private Sub Class_Initialize()
    Set {sourceClassName} = New {sourceModuleName}
End Sub

Public Sub Foo()
    {sourceClassName}.this.First = foo
End Sub

Public Sub Bar()
    {sourceClassName}.this.Second = bar
End Sub

Public Sub FooBar()
    With {sourceClassName}
        .this.First = foo
        .this.Second = bar
    End With
End Sub
";

            var userInput = new UserInputDataObject()
                            .UserSelectsField("this", "MyType");

            var presenterAction = Support.SetParameters(userInput);

            var sourceCodeString = sourceModuleCode.ToCodeString();

            var actualModuleCode = RefactoredCode(
                sourceModuleName,
                sourceCodeString.CaretPosition.ToOneBased(),
                presenterAction,
                null,
                false,
                ("ClassModule", classModuleReferencingCode, ComponentType.ClassModule),
                (sourceModuleName, sourceCodeString.Code, ComponentType.ClassModule));

            var referencingClassCode = actualModuleCode["ClassModule"];

            StringAssert.Contains($"{sourceClassName}.MyType.First = ", referencingClassCode);
            StringAssert.Contains($"{sourceClassName}.MyType.Second = ", referencingClassCode);
            StringAssert.Contains($"  .MyType.Second = ", referencingClassCode);
        }
        public void CreatesMethodStubForAllProcedureKinds()
        {
            //Input
            const string interfaceCode =
                @"Public Sub Foo(ByVal arg1 As Integer, ByVal arg2 As String)
End Sub

Public Function Fizz(b)
End Function

Public Property Get Buzz() As Variant
End Property

Public Property Let Buzz(value)
End Property

Public Property Set Buzz(value)
End Property";

            const string inputCode =
                @"Implements IClassModule";

            var selection = Selection.Home;

            //Expectation
            const string expectedCode =
                @"Implements IClassModule

Private Sub IClassModule_Foo(ByVal arg1 As Integer, ByVal arg2 As String)
    Err.Raise 5 'TODO implement interface member
End Sub

Private Function IClassModule_Fizz(ByRef b As Variant) As Variant
    Err.Raise 5 'TODO implement interface member
End Function

Private Property Get IClassModule_Buzz() As Variant
    Err.Raise 5 'TODO implement interface member
End Property

Private Property Let IClassModule_Buzz(ByRef value As Variant)
    Err.Raise 5 'TODO implement interface member
End Property

Private Property Set IClassModule_Buzz(ByRef value As Variant)
    Err.Raise 5 'TODO implement interface member
End Property
";

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                null,
                false,
                ("IClassModule", interfaceCode, ComponentType.ClassModule),
                ("Class2", inputCode, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode, actualCode["Class2"]);
        }
Example #23
0
        private void ExecuteTest(string classCode, string interfaceCode, string expectedClassCode)
        {
            var refactoredCode = RefactoredCode(
                TestModel,
                ("Class1", classCode, ComponentType.ClassModule),
                ("Interface1", interfaceCode, ComponentType.ClassModule));

            Assert.AreEqual(expectedClassCode.Trim(), refactoredCode["Class1"].Trim());
        }
        public void MoveMultipleToFolderBaseRefactoring_Works()
        {
            const string code1         = @"
'@Folder(""MyOldFolder.MyOldSubfolder.SubSub"")
Public Sub Foo()
End Sub
";
            const string code2         = @"
Public Sub Foo()
End Sub
";
            const string code3         = @"
'@Folder(""MyOldFolder.MyOldSubfolder.SubSub"")
Public Sub Foo()
End Sub
";
            const string code4         = @"
Public Sub Foo()
End Sub
";
            const string expectedCode1 = @"
'@Folder ""MyNewFolder.MySubFolder""
Public Sub Foo()
End Sub
";
            const string expectedCode2 = @"'@Folder ""MyNewFolder.MySubFolder""

Public Sub Foo()
End Sub
";
            const string expectedCode3 = code3;
            const string expectedCode4 = code4;
            Func <RubberduckParserState, MoveMultipleToFolderModel> modelBuilder = (state) =>
            {
                var standardModule = state.DeclarationFinder
                                     .UserDeclarations(DeclarationType.ProceduralModule)
                                     .Single(declaration => declaration.IdentifierName.Equals("TestModule")) as ModuleDeclaration;
                var classModule = state.DeclarationFinder
                                  .UserDeclarations(DeclarationType.ClassModule)
                                  .Single(declaration => declaration.IdentifierName.Equals("TestClass")) as ModuleDeclaration;
                return(new MoveMultipleToFolderModel(new List <ModuleDeclaration> {
                    standardModule, classModule
                }, "MyNewFolder.MySubFolder"));
            };

            var refactoredCode = RefactoredCode(
                modelBuilder,
                ("TestModule", code1, ComponentType.StandardModule),
                ("TestClass", code2, ComponentType.ClassModule),
                ("OtherClass", code3, ComponentType.ClassModule),
                ("OtherModule", code4, ComponentType.StandardModule));

            Assert.AreEqual(expectedCode1, refactoredCode["TestModule"]);
            Assert.AreEqual(expectedCode2, refactoredCode["TestClass"]);
            Assert.AreEqual(expectedCode3, refactoredCode["OtherClass"]);
            Assert.AreEqual(expectedCode4, refactoredCode["OtherModule"]);
        }
        private void ExecuteTest(string inputCode, string expectedClassCode, string expectedInterfaceCode, Func <ExtractInterfaceModel, ExtractInterfaceModel> modelAdjustment)
        {
            var refactoredCode = RefactoredCode(
                state => TestModel(state, modelAdjustment),
                ("Class", inputCode, ComponentType.ClassModule));

            Assert.AreEqual(expectedClassCode.Trim(), refactoredCode["Class"].Trim());
            Assert.AreEqual(expectedInterfaceCode.Trim(), refactoredCode["IClass"].Trim());
        }
        public void StdModuleSource_PublicUDTField_PublicType_StdModuleReference(string sourceModuleName, string referenceQualifier)
        {
            var sourceModuleCode =
                $@"
Public Type TBar
    First As String
    Second As Long
End Type

Public th|is As TBar";

            var moduleReferencingCode =
                $@"Option Explicit

'StdModule referencing the UDT

Private Const fooConst As String = ""Foo""

Private Const barConst As Long = 7

Public Sub Foo()
    {referenceQualifier}.First = fooConst
End Sub

Public Sub Bar()
    {referenceQualifier}.Second = barConst
End Sub

Public Sub FooBar()
    With {sourceModuleName}
        .this.First = fooConst
        .this.Second = barConst
    End With
End Sub
";
            var userInput = new UserInputDataObject()
                            .UserSelectsField("this", "MyType");

            var presenterAction = Support.SetParameters(userInput);

            var sourceCodeString = sourceModuleCode.ToCodeString();

            var actualModuleCode = RefactoredCode(
                sourceModuleName,
                sourceCodeString.CaretPosition.ToOneBased(),
                presenterAction,
                null,
                false,
                ("StdModule", moduleReferencingCode, ComponentType.StandardModule),
                (sourceModuleName, sourceCodeString.Code, ComponentType.StandardModule));

            var referencingModuleCode = actualModuleCode["StdModule"];

            StringAssert.Contains($"{sourceModuleName}.MyType.First = ", referencingModuleCode);
            StringAssert.Contains($"{sourceModuleName}.MyType.Second = ", referencingModuleCode);
            StringAssert.Contains($"  .MyType.Second = ", referencingModuleCode);
        }
        public void ImplementInterface_PropertySet_AllTypes()
        {
            //Input
            const string inputCode1 =
                @"Public Sub Foo()
End Sub

Public Function Bar(ByVal a As Integer) As Boolean
End Function

Public Property Get Buz(ByVal a As Boolean) As Integer
End Property

Public Property Let Buz(ByVal a As Boolean, ByRef value As Integer)
End Property";

            const string inputCode2 =
                @"Implements Class1";

            var selection = Selection.Home;

            //Expectation
            const string expectedCode =
                @"Implements Class1

Private Sub Class1_Foo()
    Err.Raise 5 'TODO implement interface member
End Sub

Private Function Class1_Bar(ByVal a As Integer) As Boolean
    Err.Raise 5 'TODO implement interface member
End Function

Private Property Get Class1_Buz(ByVal a As Boolean) As Integer
    Err.Raise 5 'TODO implement interface member
End Property

Private Property Let Class1_Buz(ByVal a As Boolean, ByRef value As Integer)
    Err.Raise 5 'TODO implement interface member
End Property
";

            var actualCode = RefactoredCode(
                "Class2",
                selection,
                null,
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode, actualCode["Class2"]);
        }
        public void ModifiesCorrectUDTMemberReference_WithMemberAccessExternal()
        {
            string sourceModuleName = "SourceModule";
            string inputCode        =
                $@"
Public Type TBar
    First As String
    Second As Long
End Type

Public th|is As TBar

Private that As TBar
";
            string module2 =
                $@"
Public Sub Foo(arg1 As String, arg2 As Long)
    With {sourceModuleName}.this
        .First = arg1
        .Second = arg2
    End With

    With that
        .First = arg1
        .Second = arg2
    End With
End Sub
";

            var presenterAction = Support.UserAcceptsDefaults();

            var codeString = inputCode.ToCodeString();

            var actualModuleCode = RefactoredCode(
                sourceModuleName,
                codeString.CaretPosition.ToOneBased(),
                presenterAction,
                null,
                false,
                ("Module2", module2, ComponentType.StandardModule),
                (sourceModuleName, codeString.Code, ComponentType.StandardModule));

            var actualCode = actualModuleCode["Module2"];
            var sourceCode = actualModuleCode[sourceModuleName];

            StringAssert.DoesNotContain($" First = arg1", actualCode);
            StringAssert.DoesNotContain($" Second = arg2", actualCode);
            StringAssert.Contains($" .First = arg1", actualCode);
            StringAssert.Contains($" .Second = arg2", actualCode);
            StringAssert.Contains($"With {sourceModuleName}.This", actualCode);
        }
        public void ReorderParametersRefactoring_EventParamsSwapped_DifferentParamNames_TwoHandlers()
        {
            //Input
            const string inputCode1 =
                @"Public Event Foo(ByVal arg1 As Integer, ByVal arg2 As String)";

            const string inputCode2 =
                @"Private WithEvents abc As Class1

Private Sub abc_Foo(ByVal i As Integer, ByVal s As String)
End Sub";
            const string inputCode3 =
                @"Private WithEvents abc As Class1

Private Sub abc_Foo(ByVal v1 As Integer, ByVal v2 As String)
End Sub";

            var selection = new Selection(1, 15, 1, 15);

            //Expectation
            const string expectedCode1 =
                @"Public Event Foo(ByVal arg2 As String, ByVal arg1 As Integer)";

            const string expectedCode2 =
                @"Private WithEvents abc As Class1

Private Sub abc_Foo(ByVal s As String, ByVal i As Integer)
End Sub";   // note: IDE removes excess spaces

            const string expectedCode3 =
                @"Private WithEvents abc As Class1

Private Sub abc_Foo(ByVal v2 As String, ByVal v1 As Integer)
End Sub";   // note: IDE removes excess spaces

            var presenterAction = ReverseParameters();
            var actualCode      = RefactoredCode(
                "Class1",
                selection,
                presenterAction,
                null,
                false,
                ("Class1", inputCode1, ComponentType.ClassModule),
                ("Class2", inputCode2, ComponentType.ClassModule),
                ("Class3", inputCode3, ComponentType.ClassModule));

            Assert.AreEqual(expectedCode1, actualCode["Class1"]);
            Assert.AreEqual(expectedCode2, actualCode["Class2"]);
            Assert.AreEqual(expectedCode3, actualCode["Class3"]);
        }
        public void UserDefinedTypeMembers_ExternallyDefinedType(string accessibility)
        {
            string inputCode =
                $@"
Option Explicit

{accessibility} th|is As TBar";

            string typeDefinition =
                $@"
Public Type TBar
    First As String
    Second As Long
End Type
";

            var userInput = new UserInputDataObject()
                            .UserSelectsField("this", "MyType");

            var presenterAction = Support.SetParameters(userInput);

            var codeString       = inputCode.ToCodeString();
            var actualModuleCode = RefactoredCode(
                "Class1",
                codeString.CaretPosition.ToOneBased(),
                presenterAction,
                null,
                false,
                ("Class1", codeString.Code, ComponentType.ClassModule),
                ("Module1", typeDefinition, ComponentType.StandardModule));

            Assert.AreEqual(typeDefinition, actualModuleCode["Module1"]);


            var actualCode = actualModuleCode["Class1"];

            StringAssert.Contains("Private this As TBar", actualCode);

            if (accessibility == "Public")
            {
                StringAssert.Contains($"this = {Support.RHSIdentifier}", actualCode);
                StringAssert.Contains("MyType = this", actualCode);
                StringAssert.Contains($"Public Property Get MyType", actualCode);
                Assert.AreEqual(actualCode.IndexOf("MyType = this"), actualCode.LastIndexOf("MyType = this"));
                StringAssert.DoesNotContain($"this.First = {Support.RHSIdentifier}", actualCode);
                StringAssert.DoesNotContain($"this.Second = {Support.RHSIdentifier}", actualCode);
                StringAssert.DoesNotContain($"Second = Second", actualCode);
                StringAssert.Contains($"Public Property Let MyType(ByRef {Support.RHSIdentifier} As TBar", actualCode);
            }
        }