public void Refresh()
        {
            this.settings = this.SettingsFactory.Get();

            this.TestFileNameFormat = this.settings.FileNameTemplate;
            TestFramework settingsPreferredTestFramework = this.settings.PreferredTestFramework;

            if (settingsPreferredTestFramework == null)
            {
                this.PreferredTestFramework = this.TestFrameworkChoices[0];
            }
            else
            {
                this.PreferredTestFramework = settingsPreferredTestFramework;
            }

            MockFramework settingsPreferredMockFramework = this.settings.PreferredMockFramework;

            if (settingsPreferredMockFramework == null)
            {
                this.PreferredMockFramework = this.MockFrameworkChoices[0];
            }
            else
            {
                this.PreferredMockFramework = settingsPreferredMockFramework;
            }
        }
Exemple #2
0
 public TestGenerationContext(
     MockFramework mockFramework,
     TestFramework testFramework,
     Document document,
     IBoilerplateSettings settings,
     string unitTestNamespace,
     string className,
     string classNamespace,
     IList <InjectableProperty> properties,
     IList <InjectableType> constructorTypes,
     IList <InjectableType> injectedTypes,
     IList <MethodDescriptor> methodDeclarations)
 {
     this.MockFramework      = mockFramework;
     this.TestFramework      = testFramework;
     this.Document           = document;
     this.Settings           = settings;
     this.UnitTestNamespace  = unitTestNamespace;
     this.ClassName          = className;
     this.ClassNamespace     = classNamespace;
     this.Properties         = properties;
     this.ConstructorTypes   = constructorTypes;
     this.InjectedTypes      = injectedTypes;
     this.MethodDeclarations = methodDeclarations;
 }
 public SelfTestDetectionTest(string projectName, IBoilerplateSettings settings, string expectedTestFramework, string expectedMockFramework)
 {
     this.ProjectName           = projectName;
     this.Settings              = settings;
     this.ExpectedTestFramework = expectedTestFramework;
     this.ExpectedMockFramework = expectedMockFramework;
 }
        public void Refresh()
        {
            this.settings = this.SettingsFactory.Get();

            this.TestProjectNameFormat = this.settings.TestProjectNameFormat;
            this.TestFileNameFormat    = this.settings.FileNameTemplate;
            TestFramework settingsPreferredTestFramework = this.settings.PreferredTestFramework;

            if (settingsPreferredTestFramework == null)
            {
                this.PreferredTestFramework = this.TestFrameworkChoices[0];
            }
            else
            {
                this.PreferredTestFramework = settingsPreferredTestFramework;
            }

            MockFramework settingsPreferredMockFramework = this.settings.PreferredMockFramework;

            if (settingsPreferredMockFramework == null)
            {
                this.PreferredMockFramework = this.MockFrameworkChoices[0];
            }
            else
            {
                this.PreferredMockFramework = settingsPreferredMockFramework;
            }

            this.CustomMocks.Clear();
            IDictionary <string, string> customMocks = this.settings.CustomMocks;

            if (customMocks != null)
            {
                foreach (var pair in customMocks)
                {
                    this.CustomMocks.Add(new CustomMockViewModel {
                        Interface = pair.Key, Class = pair.Value
                    });
                }
            }

            this.CustomMocks.Add(new CustomMockViewModel {
                Interface = string.Empty, Class = string.Empty
            });

            this.CustomMockFieldDeclarationTemplate    = this.settings.CustomMockFieldDeclarationTemplate ?? string.Empty;
            this.CustomMockFieldInitializationTemplate = this.settings.CustomMockFieldInitializationTemplate ?? string.Empty;
            this.CustomMockObjectReferenceTemplate     = this.settings.CustomMockObjectReferenceTemplate ?? string.Empty;
        }
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private async void MenuItemCallback(object sender, EventArgs e)
        {
            var dialog = new OpenFileDialog();

            dialog.Title  = "Choose .csproj file to run detection on";
            dialog.Filter = "Project files|*.csproj";
            if (dialog.ShowDialog() == true)
            {
                IComponentModel componentModel = (IComponentModel)await this.package.GetServiceAsync(typeof(SComponentModel));

                var frameworkPickerService    = componentModel.GetService <IFrameworkPickerService>();
                var settingsFactory           = componentModel.GetService <IBoilerplateSettingsFactory>();
                IBoilerplateSettings settings = settingsFactory.Get();

                MessageBox.Show("Test framework: " + frameworkPickerService.FindTestFramework(dialog.FileName, settings) + Environment.NewLine + "Mock framework: " +
                                frameworkPickerService.FindMockFramework(dialog.FileName, settings));
            }
        }
Exemple #6
0
        private void UpdateFrameworks()
        {
            if (this.selectedProject == null)
            {
                this.SelectedTestFramework = TestFrameworks.Default;
                this.SelectedMockFramework = MockFrameworks.Default;
            }
            else
            {
                IBoilerplateSettings settings = this.SettingsFactory.Get();

                List <TestFramework> testFrameworks = this.FrameworkPickerService.FindTestFrameworks(this.selectedProject.Project);
                List <MockFramework> mockFrameworks = this.FrameworkPickerService.FindMockFrameworks(this.selectedProject.Project);

                this.SelectedTestFramework = this.FrameworkPickerService.PickDefaultTestFramework(testFrameworks, settings);
                this.SelectedMockFramework = this.FrameworkPickerService.PickDefaultMockFramework(mockFrameworks, settings);

                if (testFrameworks.Count == 0)
                {
                    this.DetectedTestFrameworks = "Detected: None";
                }
                else
                {
                    this.DetectedTestFrameworks = "Detected: " + string.Join(", ", testFrameworks);
                }

                if (mockFrameworks.Count == 0)
                {
                    this.DetectedMockFrameworks = "Detected: None";
                }
                else
                {
                    this.DetectedMockFrameworks = "Detected: " + string.Join(", ", mockFrameworks);
                }
            }
        }
 public void Initialize()
 {
     this.settings = this.SettingsFactory.Get();
 }
Exemple #8
0
 public MockBoilerplateSettingsFactory(IBoilerplateSettings settings)
 {
     this.settings = settings;
 }
 public void Refresh()
 {
     this.settings = this.SettingsFactory.Get();
     this.templateHoldingDictionary.Clear();
     this.RaiseAllChanged();
 }
Exemple #10
0
        public TestFramework FindTestFramework(string projectFileName, IBoilerplateSettings settings)
        {
            var matchingFrameworks = this.FindTestFrameworks(projectFileName);

            return(this.PickDefaultTestFramework(matchingFrameworks, settings));
        }
Exemple #11
0
        public TestFramework PickDefaultTestFramework(IList <TestFramework> frameworks, IBoilerplateSettings settings)
        {
            // If there's only one framework detected, that must be it
            if (frameworks.Count == 1)
            {
                return(frameworks.First());
            }

            // If the preferred framework is included in the list, use it.
            TestFramework preferredFramework = settings.PreferredTestFramework;

            if (frameworks.Contains(preferredFramework))
            {
                return(preferredFramework);
            }

            // If there's nothing in the list, pick our fallback
            if (frameworks.Count == 0)
            {
                if (preferredFramework == null)
                {
                    return(TestFrameworks.Default);
                }
                else
                {
                    return(preferredFramework);
                }
            }

            // If there are multiple frameworks and no preferred item is declared, pick the one stack ranked first.
            return(frameworks.OrderBy(f => f.DetectionRank).First());
        }
Exemple #12
0
        public MockFramework FindMockFramework(Project project, IBoilerplateSettings settings)
        {
            var matchingFrameworks = this.FindMockFrameworks(project);

            return(this.PickDefaultMockFramework(matchingFrameworks, settings));
        }
Exemple #13
0
        private async Task <TestGenerationContext> CollectTestGenerationContextAsync(ProjectItemSummary selectedFile, EnvDTE.Project targetProject, TestFramework testFramework, MockFramework mockFramework, IBoilerplateSettings settings)
        {
            string targetProjectNamespace = targetProject.Properties.Item("DefaultNamespace").Value as string;

            return(await this.CollectTestGenerationContextAsync(selectedFile, targetProjectNamespace, testFramework, mockFramework, settings));
        }
Exemple #14
0
        private async Task <TestGenerationContext> CollectTestGenerationContextAsync(
            ProjectItemSummary selectedFile,
            string targetProjectNamespace,
            TestFramework testFramework,
            MockFramework mockFramework,
            IBoilerplateSettings settings)
        {
            Microsoft.CodeAnalysis.Solution solution = CreateUnitTestBoilerplateCommandPackage.VisualStudioWorkspace.CurrentSolution;
            DocumentId documentId = solution.GetDocumentIdsWithFilePath(selectedFile.FilePath).FirstOrDefault();

            if (documentId == null)
            {
                throw new InvalidOperationException("Could not find document in solution with file path " + selectedFile.FilePath);
            }

            var document = solution.GetDocument(documentId);

            SyntaxNode root = await document.GetSyntaxRootAsync();

            SemanticModel semanticModel = await document.GetSemanticModelAsync();

            SyntaxNode firstClassDeclaration = root.DescendantNodes().FirstOrDefault(node => node.Kind() == SyntaxKind.ClassDeclaration || node.Kind() == SyntaxKind.StructDeclaration);

            if (firstClassDeclaration == null)
            {
                throw new InvalidOperationException("Could not find class or struct declaration.");
            }

            if (firstClassDeclaration.ChildTokens().Any(node => node.Kind() == SyntaxKind.AbstractKeyword))
            {
                throw new InvalidOperationException("Cannot unit test an abstract class.");
            }

            SyntaxToken classIdentifierToken = firstClassDeclaration.ChildTokens().FirstOrDefault(n => n.Kind() == SyntaxKind.IdentifierToken);

            if (classIdentifierToken == default(SyntaxToken))
            {
                throw new InvalidOperationException("Could not find class identifier.");
            }

            NamespaceDeclarationSyntax namespaceDeclarationSyntax = null;

            if (!TypeUtilities.TryGetParentSyntax(firstClassDeclaration, out namespaceDeclarationSyntax))
            {
                throw new InvalidOperationException("Could not find class namespace.");
            }

            // Find property injection types
            var injectableProperties = new List <InjectableProperty>();

            string           classFullName = namespaceDeclarationSyntax.Name + "." + classIdentifierToken;
            INamedTypeSymbol classType     = semanticModel.Compilation.GetTypeByMetadataName(classFullName);

            foreach (ISymbol member in classType.GetBaseTypesAndThis().SelectMany(n => n.GetMembers()))
            {
                if (member.Kind == SymbolKind.Property)
                {
                    IPropertySymbol property = (IPropertySymbol)member;

                    foreach (AttributeData attribute in property.GetAttributes())
                    {
                        if (PropertyInjectionAttributeNames.Contains(attribute.AttributeClass.ToString()))
                        {
                            var injectableProperty = InjectableProperty.TryCreateInjectableProperty(property.Name, property.Type.ToString(), mockFramework);
                            if (injectableProperty != null)
                            {
                                injectableProperties.Add(injectableProperty);
                            }
                        }
                    }
                }
            }

            string className = classIdentifierToken.ToString();

            // Find constructor injection types
            List <InjectableType> constructorInjectionTypes = new List <InjectableType>();

            SyntaxNode constructorDeclaration = firstClassDeclaration.ChildNodes().FirstOrDefault(n => n.Kind() == SyntaxKind.ConstructorDeclaration);

            if (constructorDeclaration != null)
            {
                constructorInjectionTypes.AddRange(
                    GetParameterListNodes(constructorDeclaration)
                    .Select(node => InjectableType.TryCreateInjectableTypeFromParameterNode(node, semanticModel, mockFramework)));
            }

            // Find public method declarations
            IList <MethodDescriptor> methodDeclarations = new List <MethodDescriptor>();

            foreach (MethodDeclarationSyntax methodDeclaration in
                     firstClassDeclaration.ChildNodes().Where(
                         n => n.Kind() == SyntaxKind.MethodDeclaration &&
                         ((MethodDeclarationSyntax)n).Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword))))
            {
                var parameterList = GetParameterListNodes(methodDeclaration).ToList();

                var parameterTypes = GetArgumentDescriptors(parameterList, semanticModel, mockFramework);

                var isAsync =
                    methodDeclaration.Modifiers.Any(m => m.IsKind(SyntaxKind.AsyncKeyword)) ||
                    DoesReturnTask(methodDeclaration);

                var hasReturnType = !DoesReturnNonGenericTask(methodDeclaration) && !DoesReturnVoid(methodDeclaration);

                methodDeclarations.Add(new MethodDescriptor(methodDeclaration.Identifier.Text, parameterTypes, isAsync, hasReturnType));
            }

            string unitTestNamespace;

            string relativePath = this.GetRelativePath(selectedFile);

            if (string.IsNullOrEmpty(relativePath))
            {
                unitTestNamespace = targetProjectNamespace;
            }
            else
            {
                List <string> defaultNamespaceParts  = targetProjectNamespace.Split('.').ToList();
                List <string> unitTestNamespaceParts = new List <string>(defaultNamespaceParts);
                unitTestNamespaceParts.AddRange(relativePath.Split('\\'));

                unitTestNamespace = string.Join(".", unitTestNamespaceParts);
            }

            List <InjectableType> injectedTypes = new List <InjectableType>(injectableProperties);

            injectedTypes.AddRange(constructorInjectionTypes.Where(t => t != null));

            GenerateMockNames(injectedTypes);

            return(new TestGenerationContext(
                       mockFramework,
                       testFramework,
                       document,
                       settings,
                       unitTestNamespace,
                       className,
                       namespaceDeclarationSyntax.Name.ToString(),
                       injectableProperties,
                       constructorInjectionTypes,
                       injectedTypes,
                       methodDeclarations));
        }
Exemple #15
0
 public TemplateBasedStrategy(IBoilerplateSettings settings, DTE2 dte)
 {
     this.settings = settings;
     this.dte      = dte;
 }
        private async Task <TestGenerationContext> CollectTestGenerationContextAsync(
            ProjectItemSummary selectedFile,
            string targetProjectNamespace,
            TestFramework testFramework,
            MockFramework mockFramework,
            IBoilerplateSettings settings)
        {
            Microsoft.CodeAnalysis.Solution solution = CreateUnitTestBoilerplateCommandPackage.VisualStudioWorkspace.CurrentSolution;
            DocumentId documentId = solution.GetDocumentIdsWithFilePath(selectedFile.FilePath).FirstOrDefault();

            if (documentId == null)
            {
                throw new InvalidOperationException("Could not find document in solution with file path " + selectedFile.FilePath);
            }

            var document = solution.GetDocument(documentId);

            SyntaxNode root = await document.GetSyntaxRootAsync();

            SemanticModel semanticModel = await document.GetSemanticModelAsync();

            SyntaxNode firstClassLikeDeclaration = root.DescendantNodes().FirstOrDefault(node =>
            {
                var kind = node.Kind();
                return(kind == SyntaxKind.ClassDeclaration || kind == SyntaxKind.StructDeclaration || kind == (SyntaxKind)9063);                // record - Cannot update CodeAnalysis library because it's not found in VS 2019
            });

            if (firstClassLikeDeclaration == null)
            {
                throw new InvalidOperationException("Could not find class, struct or record declaration.");
            }

            if (firstClassLikeDeclaration.ChildTokens().Any(node => node.Kind() == SyntaxKind.AbstractKeyword))
            {
                throw new InvalidOperationException("Cannot unit test an abstract class.");
            }

            SyntaxToken classIdentifierToken = firstClassLikeDeclaration.ChildTokens().FirstOrDefault(n => n.Kind() == SyntaxKind.IdentifierToken);

            if (classIdentifierToken == default(SyntaxToken))
            {
                throw new InvalidOperationException("Could not find class identifier.");
            }

            object namespaceDeclarationSyntax = null;

            // 8842 is NamespaceDeclaration
            // 8845 is FileScopedNamespaceDeclaration
            // We would normally look for a node descended from BaseNamespaceDeclarationSyntax, but we don't have that type defined in the v1 Microsoft.CodeAnalysis DLL.
            // We can fix this once we are building against a higher version and can drop support for VS 2019.
            if (!TypeUtilities.TryGetParentSyntax(firstClassLikeDeclaration, (syntaxNode) => { return(syntaxNode.RawKind == 8842 || syntaxNode.RawKind == 8845); }, out namespaceDeclarationSyntax))
            {
                throw new InvalidOperationException("Could not find class namespace.");
            }

            // Find property injection types
            var injectableProperties = new List <InjectableProperty>();

            // We need to get the name via reflection since the DLL we are building against does not have the BaseNamespaceDeclarationSyntax or FileScopedNamespaceDeclarationSyntax types.
            string qualifiedNamespaceString = namespaceDeclarationSyntax.GetType().GetProperty("Name").GetValue(namespaceDeclarationSyntax, null).ToString();

            string           classFullName = qualifiedNamespaceString + "." + classIdentifierToken;
            INamedTypeSymbol classType     = semanticModel.Compilation.GetTypeByMetadataName(classFullName);

            foreach (ISymbol member in classType.GetBaseTypesAndThis().SelectMany(n => n.GetMembers()))
            {
                if (member.Kind == SymbolKind.Property)
                {
                    IPropertySymbol property = (IPropertySymbol)member;

                    foreach (AttributeData attribute in property.GetAttributes())
                    {
                        if (PropertyInjectionAttributeNames.Contains(attribute.AttributeClass.ToString()))
                        {
                            var injectableProperty = InjectableProperty.TryCreateInjectableProperty(property.Name, property.Type.ToString(), mockFramework);
                            if (injectableProperty != null)
                            {
                                injectableProperties.Add(injectableProperty);
                            }
                        }
                    }
                }
            }

            string className = classIdentifierToken.ToString();

            // Find constructor injection types
            List <InjectableType> constructorInjectionTypes = new List <InjectableType>();

            SyntaxNode constructorDeclaration = firstClassLikeDeclaration.ChildNodes().FirstOrDefault(n => n.Kind() == SyntaxKind.ConstructorDeclaration);

            if (constructorDeclaration != null)
            {
                constructorInjectionTypes.AddRange(
                    GetParameterListNodes(constructorDeclaration)
                    .Select(node => InjectableType.TryCreateInjectableTypeFromParameterNode(node, semanticModel, mockFramework)));
            }

            // Find public method declarations
            IList <MethodDescriptor> methodDeclarations = new List <MethodDescriptor>();

            foreach (MethodDeclarationSyntax methodDeclaration in
                     firstClassLikeDeclaration.ChildNodes().Where(
                         n => n.Kind() == SyntaxKind.MethodDeclaration &&
                         ((MethodDeclarationSyntax)n).Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword))))
            {
                var parameterList  = GetParameterListNodes(methodDeclaration).ToList();
                var parameterTypes = GetArgumentDescriptors(parameterList, semanticModel, mockFramework);

                var attributeList = GetAttributeListNodes(methodDeclaration);

                var isAsync =
                    methodDeclaration.Modifiers.Any(m => m.IsKind(SyntaxKind.AsyncKeyword)) ||
                    DoesReturnTask(methodDeclaration);

                var hasReturnType = !DoesReturnNonGenericTask(methodDeclaration) && !DoesReturnVoid(methodDeclaration);

                string returnType = methodDeclaration.ReturnType.ToFullString();

                methodDeclarations.Add(new MethodDescriptor(methodDeclaration.Identifier.Text, parameterTypes, isAsync, hasReturnType, returnType, attributeList));
            }

            string unitTestNamespace;

            string relativePath = this.GetRelativePath(selectedFile);

            if (string.IsNullOrEmpty(relativePath))
            {
                unitTestNamespace = targetProjectNamespace;
            }
            else
            {
                List <string> defaultNamespaceParts  = targetProjectNamespace.Split('.').ToList();
                List <string> unitTestNamespaceParts = new List <string>(defaultNamespaceParts);
                unitTestNamespaceParts.AddRange(relativePath.Split('\\'));

                unitTestNamespace = string.Join(".", unitTestNamespaceParts);
            }

            List <InjectableType> injectedTypes = new List <InjectableType>(injectableProperties);

            injectedTypes.AddRange(constructorInjectionTypes.Where(t => t != null));

            GenerateMockNames(injectedTypes);

            return(new TestGenerationContext(
                       mockFramework,
                       testFramework,
                       document,
                       settings,
                       unitTestNamespace,
                       className,
                       qualifiedNamespaceString,
                       injectableProperties,
                       constructorInjectionTypes,
                       injectedTypes,
                       methodDeclarations));
        }