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; } }
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)); } }
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(); }
public MockBoilerplateSettingsFactory(IBoilerplateSettings settings) { this.settings = settings; }
public void Refresh() { this.settings = this.SettingsFactory.Get(); this.templateHoldingDictionary.Clear(); this.RaiseAllChanged(); }
public TestFramework FindTestFramework(string projectFileName, IBoilerplateSettings settings) { var matchingFrameworks = this.FindTestFrameworks(projectFileName); return(this.PickDefaultTestFramework(matchingFrameworks, settings)); }
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()); }
public MockFramework FindMockFramework(Project project, IBoilerplateSettings settings) { var matchingFrameworks = this.FindMockFrameworks(project); return(this.PickDefaultMockFramework(matchingFrameworks, settings)); }
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)); }
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)); }
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)); }