public Class ( string className ) : Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax | ||
className | string | |
return | Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax |
private ClassDeclarationSyntax ImplementInterfaceByChild(string childClassName) { var sourceCode = new SourceCode(Files.Interface); var childClass = sourceCode.Class(childClassName); var startPos = childClass.GetLocation().SourceSpan.Start; // create a mixin class that implements an interface var mixin = Substitute.For<MixinReference>(); var @class = Substitute.For<ClassWithTypeSymbol>(); @class.IsInterface.Returns(false); @class.Interfaces.Returns( new InterfaceList( new Interface(sourceCode.GetTypeByName(nameof(IFirstInterface))))); mixin.Class.Returns(@class); var interfaces = new InterfaceList(new[] { new Interface(sourceCode.GetTypeByName(nameof(IFirstInterface))) }); var addInterfaceWriter = new AddInterfacesToChildSyntaxWriter(mixin,sourceCode.Semantic, startPos); var newChildClass = addInterfaceWriter.Visit(childClass); return (ClassDeclarationSyntax)newChildClass; }
public void ChildWithOneInterface_IncludeMixinWithManyInterfaces_OnlyMissingInterfacesAdded() { var sourceCode = new SourceCode(Files.Interface); var childClass = sourceCode.Class(nameof(ChildWithInterface)); var startPos = childClass.GetLocation().SourceSpan.Start; var interfaces = new InterfaceList(new[] { new Interface(sourceCode.GetTypeByName(nameof(IFirstInterface))), new Interface(sourceCode.GetTypeByName(nameof(ISecondInterface))) }); var @class = Substitute.For<ClassWithTypeSymbol>(); @class.IsInterface.Returns(false); @class.Interfaces.Returns(interfaces); var mixin = Substitute.For<MixinReference>(); mixin.Class.Returns(@class); var addInterfaceWriter = new AddInterfacesToChildSyntaxWriter(mixin, sourceCode.Semantic, startPos); var newChildClass = (ClassDeclarationSyntax)addInterfaceWriter.Visit(childClass); var baseList = newChildClass.BaseList.Types; // assert: child class should have both interfaces Assert.AreEqual(2, baseList.Count); Assert.IsNotNull( baseList.Single(x => x.TypeName() == nameof(IFirstInterface))); Assert.IsNotNull( baseList.Single(x => x.TypeName() == nameof(ISecondInterface))); }
public void ClassWithBaseClass_CreateFromSymbol_ClassAndBaseClassCreated() { // arrange // 1. load source files and get class and mixin declarations var sourceCode = new SourceCode(Files.Person); var personClass = sourceCode.Class(nameof(ThirdPersonClass)); var classFactory = new ClassFactory(sourceCode.Semantic); var @class = classFactory.Create(personClass); Assert.IsFalse(@class.Properties.Any()); Assert.AreEqual("Name", @class.BaseClass.BaseClass.Properties.Single().Name); }
public void ClassFactory_CreateFromCode_ClassCreated() { // arrange // 1. load source files and get class and mixin declarations var sourceCode = new SourceCode(Files.Person); var personClass = sourceCode.Class(nameof(WorkingPerson)); var classFactory = new ClassFactory(sourceCode.Semantic); var @class = classFactory.Create(personClass); Assert.AreEqual("Name", @class.Properties.Single().Name); Assert.AreEqual("void Work(int toolNumber)", @class.Methods.Single().ToString()); }
public void ClassWithMethodWithParameter_Read_MethodRead() { // arrange // 1. load source files and get class and mixin declarations var sourceCode = new SourceCode(Files.Worker); var workerClass = sourceCode.Class(nameof(WorkerWithTool)); var methodList = new MethodList(); var methodReader = new MethodSyntaxReader(methodList, sourceCode.Semantic); methodReader.Visit(workerClass); Assert.AreEqual(1, methodList.Count); Assert.AreEqual("void Work(int toolNumber)", methodList[0].ToString()); }
public void ClassWithProperty_Read_PropertyRead() { // arrange // 1. load source files and get class and mixin declarations var sourceCode = new SourceCode(Files.Person); var personClass = sourceCode.Class(nameof(PersonWithName)); var propertyList = new PropertyList(); var propertySyntaxReader = new PropertySyntaxReader(propertyList,sourceCode.Semantic); propertySyntaxReader.Visit(personClass); Assert.AreEqual(1, propertyList.Count); Assert.AreEqual("Name", propertyList[0].Name); }
public void PropertiesInBaseClass_Mix_NoPropertyToImplement() { var sourceCode = new SourceCode(Files.Person, Files.Name); var personClass = sourceCode.Class(nameof(ThirdPersonClass)); var mixinField = personClass.FindMixinReference("_name"); var child = new ClassFactory(sourceCode.Semantic).Create(personClass); var mixin = new MixinReferenceFactory(sourceCode.Semantic).Create(mixinField); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // Assert: all properties of mixin should be implemented Assert.IsEmpty(mixer.MembersToImplement); }
public void PropertiesInMixinAndChild_Mix_OnlyMissingPropertiesToImplement() { var sourceCode = new SourceCode(Files.Person, Files.Name); var personClass = sourceCode.Class(nameof(PersonWithFullName)); var mixinField = personClass.FindMixinReference("_name"); var child = new ClassFactory(sourceCode.Semantic).Create(personClass); var mixin = new MixinReferenceFactory(sourceCode.Semantic).Create(mixinField); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // Assert: all properties of mixin should be implemented Assert.AreEqual(2, mixer.MembersToImplement.Count()); }
public void ClassDeclarationWithLambda_ReadParameter_IgnoreLambdaParameter() { var sourceCode = new SourceCode(Files.Person); var personClass = sourceCode.Class(nameof(PersonWithLambdaMethod)); var parameterList = new ParameterList(); var parameterSyntaxReader = new ParameterSyntaxReader(parameterList, sourceCode.Semantic); parameterSyntaxReader.Visit(personClass); // the parameter that is used in the lambda expression should not // be added to the parameter list, but the method parameter should be Assert.AreEqual(1, parameterList.ParameterCount); Assert.AreEqual("methodParameter", parameterList.Single().Name); }
public void MethodImplementedWithOtherParameter_Include_MethodIncluded() { var sourceCode = new SourceCode(Files.Person, Files.Worker); var personClass = sourceCode.Class(nameof(PersonWithOtherWorkMethod)); var mixinReference = personClass.FindMixinReference("_worker"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // no method to implement Assert.AreEqual(1,mixer.MethodsToImplement.Count(x => x.Name == "Work")); }
public void MixinWithStaticMethod_Include_MethodNotIncluded() { var sourceCode = new SourceCode(Files.Person, Files.Worker); var personClass = sourceCode.Class(nameof(PersonWithStaticMethodMixin)); var mixinReference = personClass.FindMixinReference("_worker"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // no method to implement Assert.IsEmpty(mixer.MethodsToImplement); }
public void MixinWithMethod_Include_MethodsIncluded() { var sourceCode = new SourceCode(Files.Person, Files.Worker); var personClass = sourceCode.Class(nameof(Person)); var mixinReference = personClass.FindMixinReference("_worker"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); Assert.AreEqual(mixer.MethodsToImplement.Count(), mixin.Class.Methods.Count()); foreach (var service in mixin.Class.Methods) Assert.AreEqual(1, mixer.MethodsToImplement.Count(x => x.Name == service.Name)); }
public void MixinClassWithProperty_Include_PropertiesIncluded() { // arrange var sourceCode = new SourceCode(Files.Person, Files.Name); var personClass = sourceCode.Class(nameof(Person)); var mixinReference = personClass.FindMixinReference("_name"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); // act var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // assert all properties of the mixin should have been added Assert.AreEqual(mixin.Class.Properties.Count(),mixer.PropertiesToImplement.Count()); // check that every method of mixin appears only once in the child foreach (var service in mixin.Class.Properties) Assert.AreEqual(1, mixer.PropertiesToImplement.Count(x => x.Name == service.Name)); }
public void MixinWithPropertyExpressionBody_Include_PropertyHasGetter() { // arrange // 1. load source files and get class and mixin declarations var sourceCode = new SourceCode(Files.Person, Files.Name); var personClass = sourceCode.Class(nameof(PersonWithGetterName)); var mixinReference = personClass.FindMixinReference("_name"); var semanticModel = sourceCode.Semantic; // 2. create instances for mixin and child mixin var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); // act var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // assert. Only one property in resulting class Assert.AreEqual(1, mixer.PropertiesToImplement.Count()); // the expression body should be converted to a HasGetter Assert.AreEqual(1, mixer.PropertiesToImplement.Count(x => x.IsReadOnly)); }
private void ValidateCommentForMember(string mixinReferenceName) { // arrange var sourceCode = new SourceCode(Files.Comments); var childClass = sourceCode.Class(nameof(Child)); var mixinClass = new MixinReferenceFactory(sourceCode.Semantic) .Create(childClass.FindMixinReference(mixinReferenceName)); var settings = new Settings(includeDocumentation: true); var mixinCommand = new IncludeMixinCommand(mixinClass); // act var newClassDeclaration = mixinCommand.Execute( childClass, sourceCode.Semantic, settings); Assert.IsTrue( ValidationHelpers.HasSameDocumentation( newClassDeclaration, mixinCommand.Mixin)); }
public void MixinInterfaceWithProperty_Include_PropertiesIncluded() { // arrange // 1. load source files and get class and mixin declarations var sourceCode = new SourceCode(Files.Person, Files.Name); var personClass = sourceCode.Class(nameof(Person)); var mixinReference = personClass.FindMixinReference("_interfaceName"); var semanticModel = sourceCode.Semantic; // 2. create instances for mixin and child mixin var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); // act var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // assert. The child should have the same properties as the mixin Assert.AreEqual(mixin.Class.Properties.Count(), mixer.PropertiesToImplement.Count()); // check that every method of mixin appears only once in the child foreach (var service in mixin.Class.Properties) Assert.AreEqual(1, mixer.PropertiesToImplement.Count(x => x.Name == service.Name)); }
public void AddDocumentationAndCreateRegion_Created() { // arrange var sourceCode = new SourceCode(Files.Comments); var childClass = sourceCode.Class(nameof(Child)); var mixinClass = new MixinReferenceFactory(sourceCode.Semantic) .Create(childClass.FindMixinReference("_mixinWithProperty")); var settings = new Settings(includeDocumentation: true,createRegions: true); var mixinCommand = new IncludeMixinCommand(mixinClass); // act var newClassDeclaration = mixinCommand.Execute(childClass, sourceCode.Semantic,settings); // assert: there should be a region and a documentation var isPropertyBetweenRegion = IsPropertyBetweenRegion( newClassDeclaration, "mixin _mixinWithProperty", "Property"); var hasSameDocumentation = HasSameDocumentation(newClassDeclaration, mixinCommand.Mixin); Assert.IsTrue(isPropertyBetweenRegion); Assert.IsTrue(hasSameDocumentation); }
public void MixinWithIndexer_Include_IndexerImplemented() { // arrange var sourceCode = new SourceCode(Files.Person, Files.Collection); var personClass = sourceCode.Class(nameof(PersonWithIndexer)); var mixinReference = personClass.FindMixinReference("_collection"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); // act var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // child should also have an indexer property now Assert.AreEqual(1, mixer.PropertiesToImplement.Count()); Assert.AreEqual("string this[int index]", mixer.PropertiesToImplement.Single().ToString()); }
public void ChildWithOverrideMethod_Include_MethodOverrideNotCreated() { var sourceCode = new SourceCode(Files.Person, Files.Worker); var personClass = sourceCode.Class(nameof(PersonWithOverriddenMethod)); var mixinReference = personClass.FindMixinReference("_worker"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // there should not be any method to override, // because the child itself already overrides the method Assert.AreEqual(0, mixer.MethodsToImplement.Count()); }
public void ChildHasBaseClassWithBaseClassesWithProperty_Include_PropertyNotReimplemented() { // arrange var sourceCode = new SourceCode(Files.Person, Files.Name); var personClass = sourceCode.Class(nameof(ThirdPersonClass)); var mixinReference = personClass.FindMixinReference("_name"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); // act var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // nothing to implement for the mixer, child already has property Assert.IsEmpty(mixer.PropertiesToImplement); }
public void ChildHasInterfaceWithProperty_Include_PropertyImplemented() { // arrange var sourceCode = new SourceCode(Files.NotCompilable, Files.Name); var personClass = sourceCode.Class("DerivedFromInterfaceClass"); var mixinReference = personClass.FindMixinReference("_name"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); // act var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // assert: Child should have one "Name" property Assert.AreEqual(1, mixer.PropertiesToImplement.Count(x => x.Name == "Name")); // this one property should have only getter (signature from interface and mixin is the same) Assert.IsTrue(mixer.PropertiesToImplement.Single(x => x.Name == "Name").IsReadOnly); }
public void MixinIsInterface_Include_MixinAddedAsInterface() { var sourceCode = new SourceCode(Files.Interface); var childClass = sourceCode.Class(nameof(ChildWithoutInterface)); var startPos = childClass.GetLocation().SourceSpan.Start; // the mixin will be an interface var @class = Substitute.For<ClassWithTypeSymbol>(); @class.IsInterface.Returns(true); @class.AsInterface().Returns(new Interface(sourceCode.GetTypeByName(nameof(IFirstInterface)))); var mixin = Substitute.For<MixinReference>(); mixin.Class.Returns(@class); // act var addInterfaceWriter = new AddInterfacesToChildSyntaxWriter(mixin, sourceCode.Semantic, startPos); var newChildClass = (ClassDeclarationSyntax)addInterfaceWriter.Visit(childClass); var baseList = newChildClass.BaseList.Types; // assert: child class should have the mixin as interface Assert.AreEqual(1, baseList.Count); Assert.IsNotNull(baseList.Single(x => x.TypeName() == nameof(IFirstInterface))); }
public void ChildWithBaseMethod_Include_BaseMethodNotImplemented() { var sourceCode = new SourceCode(Files.Person, Files.Worker); var personClass = sourceCode.Class(nameof(DerivedPerson)); var mixinReference = personClass.FindMixinReference("_worker"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // there should be two methods, from base mixin and derived mixin Assert.AreEqual(1, mixer.MethodsToImplement.Count()); // only one method from the mixin should be implemented, the other one // is alredy implemented by childs base Assert.AreEqual(1, mixer.MethodsToImplement.Count(x => x.Name == "Work")); }
public void ChildWithAbstractMethodFromBase_Include_AbstractMethodOverridden() { // file Person with base class is also needed here var sourceCode = new SourceCode(Files.Person, Files.NotCompilable, Files.Worker); var personClass = sourceCode.Class("PersonFromAbstractWork"); var mixinReference = personClass.FindMixinReference("_worker"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // there should be one method that overrides the abstract method Assert.AreEqual(1, mixer.MethodsToImplement.Count()); // only one method from the mixin should be implemented, the other one // is alredy implemented by childs base Assert.AreEqual(1, mixer.MethodsToImplement.Count(x => x.Name == "Work")); Assert.IsTrue(mixer.MethodsToImplement.Single().IsOverride); }
public void MixinIsInterfaceInDifferentNamespace_Include_MixinAddedAsFullQualifiedInterface() { var sourceCode = new SourceCode(Files.Interface); var childClass = sourceCode.Class(nameof(ChildWithoutInterface)); // changing the start position here will force the type resolver // to use a full qualified type name var startPos = 0; // the mixin will be an interface var @class = Substitute.For<ClassWithTypeSymbol>(); @class.IsInterface.Returns(true); @class.AsInterface().Returns(new Interface( sourceCode.GetTypeByName(nameof(IFirstInterface)))); var mixin = Substitute.For<MixinReference>(); mixin.Class.Returns(@class); // act var addInterfaceWriter = new AddInterfacesToChildSyntaxWriter(mixin, sourceCode.Semantic, startPos); var newChildClass = (ClassDeclarationSyntax)addInterfaceWriter.Visit(childClass); var baseList = newChildClass.BaseList.Types; // assert: child class should have the mixin as interface Assert.AreEqual(1, baseList.Count); Assert.IsNotNull(baseList.Single(x => x.TypeName() == "MixinRefactoring.Test.IFirstInterface")); }
public void MixinWithStaticProperty_Include_PropertyNotImplemented() { // arrange var sourceCode = new SourceCode(Files.Person, Files.Name); var personClass = sourceCode.Class(nameof(PersonWithStaticMixin)); var mixinReference = personClass.FindMixinReference("_name"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); // act var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // assert: Child should not have a "Name" property Assert.IsEmpty(mixer.PropertiesToImplement); }
public void MixinWithGenericProperty_Include_PropertyImplemented() { // arrange var sourceCode = new SourceCode(Files.Person, Files.Name); var personClass = sourceCode.Class(nameof(PersonWithGenericMixin)); var mixinReference = personClass.FindMixinReference("_name"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); // act var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // child should have "Name" property Assert.AreEqual(1, mixer.PropertiesToImplement.Count(x => x.Name == "Names")); // name property should be of type "IEnumerable<string>" var typeName = mixer.PropertiesToImplement.Single().Type.ToString(); Assert.AreEqual("System.Collections.Generic.IEnumerable<string>", typeName); }
public void MixinWithToString_Include_ToStringShouldBeImplemented() { var sourceCode = new SourceCode(Files.Person, Files.Worker); var personClass = sourceCode.Class(nameof(PersonWithToString)); var mixinReference = personClass.FindMixinReference("_toString"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // ToString should be in list of methods to override Assert.IsTrue(mixer.MethodsToImplement.Any(x => x.Name == "ToString")); // ToString in mixin must have override keyword Assert.IsTrue(mixer.MethodsToImplement.Single(x => x.Name == "ToString").IsOverrideFromObject); }
public void ChildWithOverrideProperty_Include_PropertyOverrideNotCreated() { var sourceCode = new SourceCode(Files.Person, Files.Name); var personClass = sourceCode.Class(nameof(PersonWithOverriddenProperty)); var mixinReference = personClass.FindMixinReference("_name"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // no property to override because child overrides it already Assert.AreEqual(0, mixer.PropertiesToImplement.Count()); }
public void ChildWithAbstractProperty_Include_AbstractPropertyOverridden() { // we need Person file and NotCompilable because // the base class is defined in Person file var sourceCode = new SourceCode(Files.Person, Files.NotCompilable, Files.Name); var personClass = sourceCode.Class("PersonFromAbstractName"); var mixinReference = personClass.FindMixinReference("_name"); var semanticModel = sourceCode.Semantic; var mixin = new MixinReferenceFactory(semanticModel).Create(mixinReference); var child = new ClassFactory(semanticModel).Create(personClass); var mixer = new Mixer(); mixer.IncludeMixinInChild(mixin, child); // there should be two methods, from base mixin and derived mixin Assert.AreEqual(1, mixer.PropertiesToImplement.Count()); // only one method from the mixin should be implemented, the other one // is alredy implemented by childs base Assert.AreEqual(1, mixer.PropertiesToImplement.Count(x => x.Name == "Name")); Assert.IsTrue(mixer.PropertiesToImplement.Single().IsOverride); }