private static bool TryLoadNUnitTypes(
            Compilation compilation,
            out NUnitTypes types
            )
        {
            ImmutableHashSet <INamedTypeSymbol> testAttributes = ImmutableHashSet
                                                                 .Create(
                compilation.GetTypeByMetadataName("NUnit.Framework.TestAttribute"),
                compilation.GetTypeByMetadataName("NUnit.Framework.TestCaseAttribute"),
                compilation.GetTypeByMetadataName("NUnit.Framework.TestCaseSourceAttribute"),
                compilation.GetTypeByMetadataName("NUnit.Framework.TheoryAttribute")
                );
            ImmutableHashSet <INamedTypeSymbol> setupTeardownAttributes = ImmutableHashSet
                                                                          .Create(
                compilation.GetTypeByMetadataName("NUnit.Framework.SetUpAttribute"),
                compilation.GetTypeByMetadataName("NUnit.Framework.OneTimeSetUpAttribute"),
                compilation.GetTypeByMetadataName("NUnit.Framework.TearDownAttribute"),
                compilation.GetTypeByMetadataName("NUnit.Framework.OneTimeTearDownAttribute")
                );

            INamedTypeSymbol testFixtureAttribute = compilation.GetTypeByMetadataName("NUnit.Framework.TestFixtureAttribute");

            types = new NUnitTypes(testAttributes, setupTeardownAttributes, testFixtureAttribute);
            return(true);
        }
        private static bool TryLoadNUnitTypes(
            Compilation compilation,
            out NUnitTypes types
            )
        {
            INamedTypeSymbol categoryAttribute = compilation.GetTypeByMetadataName("NUnit.Framework.CategoryAttribute");

            if (categoryAttribute == null || categoryAttribute.TypeKind == TypeKind.Error)
            {
                types = null;
                return(false);
            }

            ImmutableHashSet <INamedTypeSymbol> testAttributes = ImmutableHashSet
                                                                 .Create(
                compilation.GetTypeByMetadataName("NUnit.Framework.TestAttribute"),
                compilation.GetTypeByMetadataName("NUnit.Framework.TestCaseAttribute"),
                compilation.GetTypeByMetadataName("NUnit.Framework.TestCaseSourceAttribute"),
                compilation.GetTypeByMetadataName("NUnit.Framework.TheoryAttribute")
                );

            INamedTypeSymbol testFixtureAttribute = compilation.GetTypeByMetadataName("NUnit.Framework.TestFixtureAttribute");

            types = new NUnitTypes(categoryAttribute, testAttributes, testFixtureAttribute);
            return(true);
        }
        private static void AnalyzeMethod(
            SyntaxNodeAnalysisContext context,
            NUnitTypes types,
            MethodDeclarationSyntax syntax
            )
        {
            SemanticModel model = context.SemanticModel;

            IMethodSymbol method = model.GetDeclaredSymbol(syntax, context.CancellationToken);

            if (method == null)
            {
                return;
            }

            if (!IsTestMethod(types, method))
            {
                return;
            }

            ImmutableSortedSet <string> categories = GatherTestMethodCategories(types, method);

            if (categories.Overlaps(RequiredCategories))
            {
                return;
            }

            context.ReportDiagnostic(Diagnostic.Create(
                                         Diagnostics.NUnitCategory,
                                         syntax.Identifier.GetLocation(),
                                         $"Test must be categorized as one of [{string.Join( ", ", RequiredCategories )}], but saw [{string.Join( ", ", categories )}]. See http://docs.dev.d2l/index.php/Test_Categories."
                                         ));
        }
        private static void VisitCategories(
            NUnitTypes types,
            ISymbol symbol,
            Action <string, AttributeData> visitor
            )
        {
            foreach (AttributeData attribute in symbol.GetAttributes())
            {
                INamedTypeSymbol attributeType = attribute.AttributeClass;
                if (types.CategoryAttribute == attributeType)
                {
                    VisitCategoryAttribute(attribute, visitor);
                    continue;
                }

                if (types.TestFixtureAttribute == attributeType)
                {
                    VisitTestFixtureAttribute(attribute, visitor);
                    continue;
                }
            }

            if (symbol is INamedTypeSymbol typeSymbol)
            {
                if (typeSymbol.BaseType != null)
                {
                    VisitCategories(types, typeSymbol.BaseType, visitor);
                }
            }
        }
        private static ImmutableSortedSet <string> GetCategories(
            NUnitTypes types,
            ISymbol symbol
            )
        {
            var categories = ImmutableSortedSet.CreateBuilder <string>(StringComparer.OrdinalIgnoreCase);

            VisitCategories(types, symbol, (category, _) => categories.Add(category));

            return(categories.ToImmutable());
        }
Esempio n. 6
0
        private static void AnalyzeMethod(
            SyntaxNodeAnalysisContext context,
            NUnitTypes types,
            MethodDeclarationSyntax syntax
            )
        {
            SemanticModel model = context.SemanticModel;

            IMethodSymbol method = model.GetDeclaredSymbol(syntax, context.CancellationToken);

            if (method == null)
            {
                return;
            }

            // Any private/helper methods should be private/internal and can be ignored
            if (method.DeclaredAccessibility != Accessibility.Public)
            {
                return;
            }

            ImmutableSortedSet <string> categories = GatherTestMethodCategories(types, method);

            if (!categories.Overlaps(RequiredCategories))
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             Diagnostics.NUnitCategory,
                                             syntax.Identifier.GetLocation(),
                                             $"Test must be categorized as one of [{string.Join( ", ", RequiredCategories )}], but saw [{string.Join( ", ", categories )}]. See http://docs.dev.d2l/index.php/Test_Categories."
                                             ));
            }

            // We need the declaring class to be a [TestFixture] to continue
            INamedTypeSymbol declaringClass = method.ContainingType;

            if (!declaringClass.GetAttributes().Any(attr => attr.AttributeClass == types.TestFixtureAttribute))
            {
                return;
            }

            // If we don't have a Test type attribute on the method, report a diagnostic
            bool isTest = IsTestMethod(types, method);

            if (!isTest)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             Diagnostics.TestAttributeMissed, syntax.Identifier.GetLocation(), method.Name)
                                         );
                return;
            }
        }
Esempio n. 7
0
        private static void AnalyzeMethod(
            SyntaxNodeAnalysisContext context,
            NUnitTypes types,
            MethodDeclarationSyntax syntax,
            ImmutableHashSet <string> disallowedList
            )
        {
            SemanticModel model = context.SemanticModel;

            IMethodSymbol method = model.GetDeclaredSymbol(syntax, context.CancellationToken);

            if (method == null)
            {
                return;
            }

            // Any private/helper methods should be private/internal and can be ignored
            if (method.DeclaredAccessibility != Accessibility.Public)
            {
                return;
            }

            // We need the declaring class to be a [TestFixture] to continue
            INamedTypeSymbol declaringClass = method.ContainingType;

            if (!declaringClass.GetAttributes().Any(
                    attr => attr.AttributeClass.Equals(types.TestFixtureAttribute, SymbolEqualityComparer.Default)
                    ))
            {
                return;
            }

            // Ignore any classes which are disallowed
            if (IsClassAllowed(disallowedList, method.ContainingType))
            {
                return;
            }

            bool isTest = IsTestMethod(types, method);

            if (!isTest)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             Diagnostics.TestAttributeMissed, syntax.Identifier.GetLocation(), method.Name)
                                         );
                return;
            }
        }
        private static bool IsTestMethod(
            NUnitTypes types,
            IMethodSymbol method
            )
        {
            foreach (AttributeData attribute in method.GetAttributes())
            {
                INamedTypeSymbol attributeType = attribute.AttributeClass;
                if (types.TestAttributes.Contains(attributeType) || types.SetupTeardownAttributes.Contains(attributeType))
                {
                    return(true);
                }
            }

            return(false);
        }
        private static ImmutableSortedSet <string> GatherTestMethodCategories(
            NUnitTypes types,
            IMethodSymbol method
            )
        {
            ImmutableSortedSet <string> methodCategories   = GetCategories(types, method);
            ImmutableSortedSet <string> fixtureCategories  = GetCategories(types, method.ContainingType);
            ImmutableSortedSet <string> assemblyCategories = GetCategories(types, method.ContainingAssembly);

            ImmutableSortedSet <string> categories =
                methodCategories
                .Union(fixtureCategories)
                .Union(assemblyCategories);

            return(categories);
        }