Ejemplo n.º 1
0
        public void HasAttribute_ReturnsTrueForAttributesOnOverridenProperties()
        {
            // Arrange
            var source = @"
using System;
namespace TestApp
{
    public class TestAttribute : Attribute { }

    public class TestControllerBase
    {
        [TestAttribute]
        public virtual string SomeProperty { get; set; }
    }

    public class TestController : TestControllerBase
    {
        public override string SomeProperty { get; set; }
    }
}";

            var compilation = TestCompilation.Create(source);
            var attribute   = compilation.GetTypeByMetadataName("TestApp.TestAttribute");
            var testClass   = compilation.GetTypeByMetadataName("TestApp.TestController");
            var property    = (IPropertySymbol)testClass.GetMembers("SomeProperty").First();

            // Act
            var hasAttributeWithoutInherit = CodeAnalysisExtensions.HasAttribute(property, attribute, inherit: false);
            var hasAttributeWithInherit    = CodeAnalysisExtensions.HasAttribute(property, attribute, inherit: true);

            // Assert
            Assert.False(hasAttributeWithoutInherit);
            Assert.True(hasAttributeWithInherit);
        }
Ejemplo n.º 2
0
        public async Task GetAttributes_BaseTypeWithAttributes()
        {
            // Arrange
            var compilation = await GetCompilation();

            var attribute = compilation.GetTypeByMetadataName(typeof(ApiConventionTypeAttribute).FullName);
            var testClass = compilation.GetTypeByMetadataName(typeof(GetAttributes_BaseTypeWithAttributesDerived).FullName);

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(testClass, attribute, inherit: true);

            // Assert
            Assert.Collection(
                attributes,
                attributeData =>
            {
                Assert.Same(attribute, attributeData.AttributeClass);
                Assert.Equal(attributeData.ConstructorArguments[0].Value, compilation.GetSpecialType(SpecialType.System_Int32));
            },
                attributeData =>
            {
                Assert.Same(attribute, attributeData.AttributeClass);
                Assert.Equal(attributeData.ConstructorArguments[0].Value, compilation.GetSpecialType(SpecialType.System_Object));
            },
                attributeData =>
            {
                Assert.Same(attribute, attributeData.AttributeClass);
                Assert.Equal(attributeData.ConstructorArguments[0].Value, compilation.GetSpecialType(SpecialType.System_String));
            });
        }
Ejemplo n.º 3
0
        public void HasAttribute_ReturnsTrueForAttributesOnMethods()
        {
            // Arrange
            var source = @"
using System;
namespace TestApp
{
    public class TestAttribute : Attribute { }

    public class TestController
    {
        [TestAttribute]
        public void SomeMethod() { }
    }
}";

            var compilation = TestCompilation.Create(source);
            var attribute   = compilation.GetTypeByMetadataName("TestApp.TestAttribute");
            var testClass   = compilation.GetTypeByMetadataName("TestApp.TestController");
            var method      = (IMethodSymbol)testClass.GetMembers("SomeMethod").First();

            // Act
            var hasAttribute = CodeAnalysisExtensions.HasAttribute(method, attribute, inherit: false);

            // Assert
            Assert.True(hasAttribute);
        }
Ejemplo n.º 4
0
        public void IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface()
        {
            // Arrange
            var source      = @"
namespace TestApp
{
public interface ITestInterface
{
}

public class ITestInterfaceA : ITestInterface
{
}

public class ITestInterfaceB : ITestInterfaceA
{
}

public class TestClass : ITestInterfaceB
{
}";
            var compilation = TestCompilation.Create(source);
            var sourceType  = compilation.GetTypeByMetadataName("TestApp.ITestInterface");
            var target      = compilation.GetTypeByMetadataName("TestApp.TestClass");

            // Act
            var isAssignableFrom        = CodeAnalysisExtensions.IsAssignableFrom(sourceType, target);
            var isAssignableFromDerived = CodeAnalysisExtensions.IsAssignableFrom(target, sourceType);

            // Assert
            Assert.True(isAssignableFrom);
            Assert.False(isAssignableFromDerived); // Inverse shouldn't be true
        }
Ejemplo n.º 5
0
        public void GetAttributes_WithInheritFalse_ReturnsAllAttributesOnCurrentAction()
        {
            // Arrange
            var source = @"
using Microsoft.AspNetCore.Mvc;
namespace TestApp
{
    public class BaseClass
    {
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        public virtual void Method() { }
    }

    public class TestClass : BaseClass
    {
        [ProducesResponseType(400)]
        public override void Method() { }
    }
}
";

            var compilation = TestCompilation.Create(source);
            var attribute   = compilation.GetTypeByMetadataName(typeof(ProducesResponseTypeAttribute).FullName);
            var testClass   = compilation.GetTypeByMetadataName("TestApp.TestClass");
            var method      = (IMethodSymbol)testClass.GetMembers("Method").First();

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(method, attribute, inherit: false);

            // Assert
            Assert.Collection(
                attributes,
                attributeData => Assert.Equal(400, attributeData.ConstructorArguments[0].Value));
        }
Ejemplo n.º 6
0
        public void HasAttribute_ReturnsTrueForInterfaceContractOnAttribute()
        {
            // Arrange
            var source = @"
using System;
namespace TestApp
{
    public interface ITestInterface { }

    public class TestAttribute : Attribute, ITestInterface  { }

    [TestAttribute]
    public class TestController
    {
    }
}";

            var compilation = TestCompilation.Create(source);
            var @interface  = compilation.GetTypeByMetadataName("TestApp.ITestInterface");
            var testClass   = compilation.GetTypeByMetadataName("TestApp.TestController");

            // Act
            var hasAttribute          = CodeAnalysisExtensions.HasAttribute(testClass, @interface, inherit: true);
            var hasAttributeOnDerived = CodeAnalysisExtensions.HasAttribute(testClass, @interface, inherit: true);

            // Assert
            Assert.True(hasAttribute);
            Assert.True(hasAttributeOnDerived);
        }
Ejemplo n.º 7
0
        public void HasAttribute_ReturnsTrueIfBaseTypeHasAttribute()
        {
            // Arrange
            var source = @"
using Microsoft.AspNetCore.Mvc;
namespace TestApp
{
    [Controller]
    public class TestControllerBase { }

    public class TestController : TestControllerBase { }
}";

            var compilation = TestCompilation.Create(source);

            var attribute = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Mvc.ControllerAttribute");
            var testClass = compilation.GetTypeByMetadataName($"TestApp.TestController");

            // Act
            var hasAttributeWithoutInherit = CodeAnalysisExtensions.HasAttribute(testClass, attribute, inherit: false);
            var hasAttributeWithInherit    = CodeAnalysisExtensions.HasAttribute(testClass, attribute, inherit: true);

            // Assert
            Assert.False(hasAttributeWithoutInherit);
            Assert.True(hasAttributeWithInherit);
        }
Ejemplo n.º 8
0
        public async Task IsAssignable_ReturnsFalseForDifferentTypes()
        {
            // Arrange
            var compilation = await GetCompilation();

            var source = compilation.GetTypeByMetadataName($"{Namespace}.IsAssignable_ReturnsFalseForDifferentTypesA");
            var target = compilation.GetTypeByMetadataName($"{Namespace}.IsAssignable_ReturnsFalseForDifferentTypesB");

            // Act
            var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(source, target);

            // Assert
            Assert.False(isAssignableFrom);
        }
Ejemplo n.º 9
0
        public async Task IsAssignable_ReturnsFalseIfTypeDoesNotImplementInterface()
        {
            // Arrange
            var compilation = await GetCompilation(nameof(IsAssignable_ReturnsFalseForDifferentTypes));

            var source = compilation.GetTypeByMetadataName($"{Namespace}.IsAssignable_ReturnsFalseForDifferentTypesA");
            var target = compilation.GetTypeByMetadataName($"System.IDisposable");

            // Act
            var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(source, target);

            // Assert
            Assert.False(isAssignableFrom);
        }
Ejemplo n.º 10
0
        public async Task HasAttribute_ReturnsTrueIfTypeHasAttribute()
        {
            // Arrange
            var compilation = await GetCompilation();

            var attribute = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Mvc.ControllerAttribute");
            var testClass = compilation.GetTypeByMetadataName($"{Namespace}.{nameof(HasAttribute_ReturnsTrueIfTypeHasAttribute)}");

            // Act
            var hasAttribute = CodeAnalysisExtensions.HasAttribute(testClass, attribute, inherit: false);

            // Assert
            Assert.True(hasAttribute);
        }
Ejemplo n.º 11
0
        public async Task IsAssignable_ReturnsTrue_IfSourceAndDestinationAreTheSameInterface()
        {
            // Arrange
            var compilation = await GetCompilation(nameof(IsAssignable_ReturnsTrueIfTypeImplementsInterface));

            var source = compilation.GetTypeByMetadataName(typeof(IsAssignable_ReturnsTrueIfTypeImplementsInterface).FullName);
            var target = compilation.GetTypeByMetadataName(typeof(IsAssignable_ReturnsTrueIfTypeImplementsInterface).FullName);

            // Act
            var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(source, target);

            // Assert
            Assert.True(isAssignableFrom);
        }
Ejemplo n.º 12
0
        public async Task GetAttributes_OnTypeWithoutAttributes()
        {
            // Arrange
            var compilation = await GetCompilation();

            var attribute = compilation.GetTypeByMetadataName(typeof(ApiConventionTypeAttribute).FullName);
            var testClass = compilation.GetTypeByMetadataName(typeof(GetAttributes_OnTypeWithoutAttributesType).FullName);

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(testClass, attribute, inherit: true);

            // Assert
            Assert.Empty(attributes);
        }
Ejemplo n.º 13
0
        public async Task IsAssignable_ReturnsTrueIfTypesAreExact()
        {
            // Arrange
            var compilation = await GetCompilation();

            var source = compilation.GetTypeByMetadataName($"{Namespace}.IsAssignable_ReturnsTrueIfTypesAreExact");
            var target = compilation.GetTypeByMetadataName($"{Namespace}.IsAssignable_ReturnsTrueIfTypesAreExact");

            // Act
            var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(source, target);

            // Assert
            Assert.True(isAssignableFrom);
        }
Ejemplo n.º 14
0
        public async Task HasAttribute_ReturnsTrueForAttributesOnMethods()
        {
            // Arrange
            var compilation = await GetCompilation();

            var attribute = compilation.GetTypeByMetadataName($"{Namespace}.HasAttribute_ReturnsTrueForAttributesOnMethodsAttribute");
            var testClass = compilation.GetTypeByMetadataName($"{Namespace}.HasAttribute_ReturnsTrueForAttributesOnMethodsTest");
            var method    = (IMethodSymbol)testClass.GetMembers("SomeMethod").First();

            // Act
            var hasAttribute = CodeAnalysisExtensions.HasAttribute(method, attribute, inherit: false);

            // Assert
            Assert.True(hasAttribute);
        }
Ejemplo n.º 15
0
        public async Task HasAttribute_ReturnsTrueForAttributesOnProperties()
        {
            // Arrange
            var compilation = await GetCompilation();

            var attribute = compilation.GetTypeByMetadataName($"{Namespace}.HasAttribute_ReturnsTrueForAttributesOnPropertiesAttribute");
            var testClass = compilation.GetTypeByMetadataName($"{Namespace}.HasAttribute_ReturnsTrueForAttributesOnProperties");
            var property  = (IPropertySymbol)testClass.GetMembers("SomeProperty").First();

            // Act
            var hasAttribute = CodeAnalysisExtensions.HasAttribute(property, attribute, inherit: false);

            // Assert
            Assert.True(hasAttribute);
        }
Ejemplo n.º 16
0
        public async Task GetAttributes_OnMethodWithoutAttributes()
        {
            // Arrange
            var compilation = await GetCompilation();

            var attribute = compilation.GetTypeByMetadataName(typeof(ProducesResponseTypeAttribute).FullName);
            var testClass = compilation.GetTypeByMetadataName($"{Namespace}.{nameof(GetAttributes_OnMethodWithoutAttributesClass)}");
            var method    = (IMethodSymbol)testClass.GetMembers(nameof(GetAttributes_OnMethodWithoutAttributesClass.Method)).First();

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(method, attribute, inherit: true);

            // Assert
            Assert.Empty(attributes);
        }
Ejemplo n.º 17
0
        public async Task IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface()
        {
            // Arrange
            var compilation = await GetCompilation();

            var source = compilation.GetTypeByMetadataName($"{Namespace}.IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterface");
            var target = compilation.GetTypeByMetadataName($"{Namespace}.IsAssignable_ReturnsTrueIfAncestorTypeImplementsInterfaceTest");

            // Act
            var isAssignableFrom        = CodeAnalysisExtensions.IsAssignableFrom(source, target);
            var isAssignableFromDerived = CodeAnalysisExtensions.IsAssignableFrom(target, source);

            // Assert
            Assert.True(isAssignableFrom);
            Assert.False(isAssignableFromDerived); // Inverse shouldn't be true
        }
Ejemplo n.º 18
0
        public async Task GetAttributes_OnNewMethodOfNonVirtualBaseMethod()
        {
            // Arrange
            var compilation = await GetCompilation("GetAttributes_WithNewMethod");

            var attribute = compilation.GetTypeByMetadataName(typeof(ProducesResponseTypeAttribute).FullName);
            var testClass = compilation.GetTypeByMetadataName($"{Namespace}.{nameof(GetAttributes_WithNewMethodDerived)}");
            var method    = (IMethodSymbol)testClass.GetMembers(nameof(GetAttributes_WithNewMethodDerived.NotVirtualMethod)).First();

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(method, attribute, inherit: true);

            // Assert
            Assert.Collection(
                attributes,
                attributeData => Assert.Equal(401, attributeData.ConstructorArguments[0].Value));
        }
Ejemplo n.º 19
0
        public void GetAttributes_BaseTypeWithAttributes()
        {
            // Arrange
            var source = @"
using Microsoft.AspNetCore.Mvc;
namespace TestApp
{
    [ApiConventionType(typeof(object))]
    [ApiController]
    [ApiConventionType(typeof(string))]
    public class BaseType
    {
    }

    [ApiConventionType(typeof(int))]
    public class TestClass : BaseType
    {
    }
}";

            var compilation = TestCompilation.Create(source);
            var attribute   = compilation.GetTypeByMetadataName(typeof(ApiConventionTypeAttribute).FullName);
            var testClass   = compilation.GetTypeByMetadataName("TestApp.TestClass");

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(testClass, attribute, inherit: true);

            // Assert
            Assert.Collection(
                attributes,
                attributeData =>
            {
                Assert.Same(attribute, attributeData.AttributeClass);
                Assert.Equal(attributeData.ConstructorArguments[0].Value, compilation.GetSpecialType(SpecialType.System_Int32));
            },
                attributeData =>
            {
                Assert.Same(attribute, attributeData.AttributeClass);
                Assert.Equal(attributeData.ConstructorArguments[0].Value, compilation.GetSpecialType(SpecialType.System_Object));
            },
                attributeData =>
            {
                Assert.Same(attribute, attributeData.AttributeClass);
                Assert.Equal(attributeData.ConstructorArguments[0].Value, compilation.GetSpecialType(SpecialType.System_String));
            });
        }
Ejemplo n.º 20
0
        public async Task GetAttributesSymbolOverload_OnMethodSymbol()
        {
            // Arrange
            var compilation = await GetCompilation("GetAttributes_WithMethodOverridding");

            var attribute = compilation.GetTypeByMetadataName(typeof(ProducesResponseTypeAttribute).FullName);
            var testClass = compilation.GetTypeByMetadataName($"{Namespace}.{nameof(GetAttributes_WithInheritFalse_ReturnsAllAttributesOnCurrentActionClass)}");
            var method    = (IMethodSymbol)testClass.GetMembers(nameof(GetAttributes_WithInheritFalse_ReturnsAllAttributesOnCurrentActionClass.Method)).First();

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(symbol: method, attribute: attribute);

            // Assert
            Assert.Collection(
                attributes,
                attributeData => Assert.Equal(400, attributeData.ConstructorArguments[0].Value));
        }
Ejemplo n.º 21
0
        public async Task HasAttribute_ReturnsTrueForInterfaceContractOnAttribute()
        {
            // Arrange
            var compilation = await GetCompilation();

            var @interface   = compilation.GetTypeByMetadataName($"{Namespace}.IHasAttribute_ReturnsTrueForInterfaceContractOnAttribute");
            var testClass    = compilation.GetTypeByMetadataName($"{Namespace}.HasAttribute_ReturnsTrueForInterfaceContractOnAttributeTest");
            var derivedClass = compilation.GetTypeByMetadataName($"{Namespace}.HasAttribute_ReturnsTrueForInterfaceContractOnAttributeDerived");

            // Act
            var hasAttribute          = CodeAnalysisExtensions.HasAttribute(testClass, @interface, inherit: true);
            var hasAttributeOnDerived = CodeAnalysisExtensions.HasAttribute(testClass, @interface, inherit: true);

            // Assert
            Assert.True(hasAttribute);
            Assert.True(hasAttributeOnDerived);
        }
Ejemplo n.º 22
0
        public void IsAssignable_ReturnsFalseIfTypeDoesNotImplementInterface()
        {
            // Arrange
            var source = @"
namespace TestApp
{
    public class TypeA { }
}";

            var compilation = TestCompilation.Create(source);
            var sourceType  = compilation.GetTypeByMetadataName("TestApp.TypeA");
            var target      = compilation.GetTypeByMetadataName("System.IDisposable");

            // Act
            var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(sourceType, target);

            // Assert
            Assert.False(isAssignableFrom);
        }
Ejemplo n.º 23
0
        public void IsAssignable_ReturnsTrueIfTypesAreExact()
        {
            // Arrange
            var source = @"
namespace TestApp
{
    public class TestType  {  }
}";

            var compilation = TestCompilation.Create(source);
            var sourceType  = compilation.GetTypeByMetadataName("TestApp.TestType");
            var target      = compilation.GetTypeByMetadataName("TestApp.TestType");

            // Act
            var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(sourceType, target);

            // Assert
            Assert.True(isAssignableFrom);
        }
Ejemplo n.º 24
0
        public void IsAssignable_ReturnsTrue_IfSourceAndDestinationAreTheSameInterface()
        {
            // Arrange
            var source = @"
namespace TestApp
{
    public interface ITestInterface { }
}";

            var compilation = TestCompilation.Create(source);
            var sourceType  = compilation.GetTypeByMetadataName("TestApp.ITestInterface");
            var target      = compilation.GetTypeByMetadataName("TestApp.ITestInterface");

            // Act
            var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(sourceType, target);

            // Assert
            Assert.True(isAssignableFrom);
        }
Ejemplo n.º 25
0
        public async Task HasAttribute_ReturnsFalseIfSymbolDoesNotHaveAttribute()
        {
            // Arrange
            var compilation = await GetCompilation();

            var attribute    = compilation.GetTypeByMetadataName($"{Namespace}.HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttribute");
            var testClass    = compilation.GetTypeByMetadataName($"{Namespace}.HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttributeTest");
            var testMethod   = (IMethodSymbol)testClass.GetMembers("SomeMethod").First();
            var testProperty = (IPropertySymbol)testClass.GetMembers("SomeProperty").First();

            // Act
            var classHasAttribute    = CodeAnalysisExtensions.HasAttribute(testClass, attribute, inherit: false);
            var methodHasAttribute   = CodeAnalysisExtensions.HasAttribute(testMethod, attribute, inherit: false);
            var propertyHasAttribute = CodeAnalysisExtensions.HasAttribute(testProperty, attribute, inherit: false);

            // AssertControllerAttribute
            Assert.False(classHasAttribute);
            Assert.False(methodHasAttribute);
            Assert.False(propertyHasAttribute);
        }
Ejemplo n.º 26
0
        public void GetAttributes_OnNewMethodOfNonVirtualBaseMethod()
        {
            // Arrange
            var source = @"
using Microsoft.AspNetCore.Mvc;
namespace TestApp
{
    public class BaseClass
    {
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        public virtual void VirtualMethod() { }

        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        public virtual void NotVirtualMethod() { }
    }

    public class TestClass : BaseClass
    {
        [ProducesResponseType(400)]
        public new void VirtualMethod() { }

        [ProducesResponseType(401)]
        public new void NotVirtualMethod() { }
    }
}";

            var compilation = TestCompilation.Create(source);
            var attribute   = compilation.GetTypeByMetadataName(typeof(ProducesResponseTypeAttribute).FullName);
            var testClass   = compilation.GetTypeByMetadataName("TestApp.TestClass");
            var method      = (IMethodSymbol)testClass.GetMembers("NotVirtualMethod").First();

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(method, attribute, inherit: true);

            // Assert
            Assert.Collection(
                attributes,
                attributeData => Assert.Equal(401, attributeData.ConstructorArguments[0].Value));
        }
Ejemplo n.º 27
0
        public void IsAssignable_ReturnsFalseForDifferentTypes()
        {
            // Arrange
            var source = @"
namespace TestApp
{
    public class TypeA { }

    public class TypeB { }
}";

            var compilation = TestCompilation.Create(source);
            var sourceType  = compilation.GetTypeByMetadataName("TestApp.TypeA");
            var target      = compilation.GetTypeByMetadataName("TestApp.TypeB");

            // Act
            var isAssignableFrom = CodeAnalysisExtensions.IsAssignableFrom(sourceType, target);

            // Assert
            Assert.False(isAssignableFrom);
        }
Ejemplo n.º 28
0
        public void GetAttributes_OnTypeWithoutAttributes()
        {
            // Arrange
            var source = @"
using Microsoft.AspNetCore.Mvc;
namespace TestApp
{
    public class TestClass
    {
    }
}";

            var compilation = TestCompilation.Create(source);
            var attribute   = compilation.GetTypeByMetadataName(typeof(ApiConventionTypeAttribute).FullName);
            var testClass   = compilation.GetTypeByMetadataName("TestApp.TestClass");

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(testClass, attribute, inherit: true);

            // Assert
            Assert.Empty(attributes);
        }
Ejemplo n.º 29
0
        public void GetAttributes_OnMethodWithoutAttributes()
        {
            // Arrange
            var source = @"
namespace TestApp
{
    public class TestController
    {
        public void Method() { }
    }
}";

            var compilation = TestCompilation.Create(source);
            var attribute   = compilation.GetTypeByMetadataName(typeof(ProducesResponseTypeAttribute).FullName);
            var testClass   = compilation.GetTypeByMetadataName("TestApp.TestController");
            var method      = (IMethodSymbol)testClass.GetMembers("Method").First();

            // Act
            var attributes = CodeAnalysisExtensions.GetAttributes(method, attribute, inherit: true);

            // Assert
            Assert.Empty(attributes);
        }
Ejemplo n.º 30
0
        public void HasAttribute_ReturnsFalseIfSymbolDoesNotHaveAttribute()
        {
            // Arrange
            var source = @"
using Microsoft.AspNetCore.Mvc;
namespace TestApp
{
    public class HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttribute : Attribute { }

    [Controller]
    public class HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttributeTest
    {
        [NonAction]
        public void SomeMethod() { }

        [BindProperty]
        public string SomeProperty { get; set; }
    }
}";

            var compilation  = TestCompilation.Create(source);
            var attribute    = compilation.GetTypeByMetadataName("TestApp.HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttribute");
            var testClass    = compilation.GetTypeByMetadataName("TestApp.HasAttribute_ReturnsFalseIfTypeDoesNotHaveAttributeTest");
            var testMethod   = (IMethodSymbol)testClass.GetMembers("SomeMethod").First();
            var testProperty = (IPropertySymbol)testClass.GetMembers("SomeProperty").First();

            // Act
            var classHasAttribute    = CodeAnalysisExtensions.HasAttribute(testClass, attribute, inherit: false);
            var methodHasAttribute   = CodeAnalysisExtensions.HasAttribute(testMethod, attribute, inherit: false);
            var propertyHasAttribute = CodeAnalysisExtensions.HasAttribute(testProperty, attribute, inherit: false);

            // AssertControllerAttribute
            Assert.False(classHasAttribute);
            Assert.False(methodHasAttribute);
            Assert.False(propertyHasAttribute);
        }