public async Task ShouldEvaluateMethod_ReturnsFalse_IfMethodReturnTypeIsInvalid()
        {
            // Arrange
            var source      = @"
using Microsoft.AspNetCore.Mvc;

namespace TestNamespace
{
    [ApiController]
    public class TestController : ControllerBase
    {
        public DoesNotExist Get(int id)
        {
            if (id == 0)
            {
                return NotFound();
            }

            return new DoesNotExist(id);
        }
    }
}";
            var project     = DiagnosticProject.Create(GetType().Assembly, new[] { source });
            var compilation = await project.GetCompilationAsync();

            var symbolCache = new ApiControllerSymbolCache(compilation);
            var method      = (IMethodSymbol)compilation.GetTypeByMetadataName("TestNamespace.TestController").GetMembers("Get").First();

            // Act
            var result = ApiConventionAnalyzer.ShouldEvaluateMethod(symbolCache, method);

            // Assert
            Assert.False(result);
        }
        public async Task GetDefaultStatusCode_ReturnsValueDefinedUsingHttpStatusCast()
        {
            // Arrange
            var compilation = await GetCompilation();

            var attribute = compilation.GetTypeByMetadataName(typeof(TestActionResultUsingHttpStatusCodeCast).FullName).GetAttributes()[0];

            // Act
            var actual = ApiConventionAnalyzer.GetDefaultStatusCode(attribute);

            // Assert
            Assert.Equal(302, actual);
        }
        public async Task InspectReturnExpression_ReturnsNull_ForReturnTypeIf201StatusCodeIsDeclared()
        {
            // Arrange
            var compilation = await GetCompilation();

            var returnType = compilation.GetTypeByMetadataName(typeof(ApiConventionAnalyzerBaseModel).FullName);
            var context    = GetContext(compilation, new[] { 201 });

            // Act
            var diagnostic = ApiConventionAnalyzer.InspectReturnExpression(context, returnType, Location.None);

            // Assert
            Assert.Null(diagnostic);
        }
        public async Task InspectReturnExpression_DoesNotReturnDiagnostic_IfDeclaredAndActualReturnTypeAreIActionResult()
        {
            // Arrange
            var compilation = await GetCompilation();

            var context          = GetContext(compilation, new[] { 404 });
            var actualReturnType = compilation.GetTypeByMetadataName(typeof(IActionResult).FullName);

            // Act
            var diagnostic = ApiConventionAnalyzer.InspectReturnExpression(context, actualReturnType, Location.None);

            // Assert
            Assert.Null(diagnostic);
        }
        public async Task InspectReturnExpression_DoesNotReturnDiagnostic_IfReturnTypeDoesNotHaveStatusCodeAttribute()
        {
            // Arrange
            var compilation = await GetCompilation();

            var context          = GetContext(compilation, new[] { 200, 404 });
            var actualReturnType = compilation.GetTypeByMetadataName(typeof(EmptyResult).FullName);

            // Act
            var diagnostic = ApiConventionAnalyzer.InspectReturnExpression(context, actualReturnType, Location.None);

            // Assert
            Assert.Null(diagnostic);
        }
        public async Task ShouldEvaluateMethod_ReturnsFalse_IfContainingTypeIsNotAction()
        {
            // Arrange
            var compilation = await GetCompilation();

            var symbolCache = new ApiControllerSymbolCache(compilation);
            var type        = compilation.GetTypeByMetadataName(typeof(ApiConventionAnalyzerTest_NotAction).FullName);
            var method      = (IMethodSymbol)type.GetMembers(nameof(ApiConventionAnalyzerTest_NotAction.Index)).First();

            // Act
            var result = ApiConventionAnalyzer.ShouldEvaluateMethod(symbolCache, method);

            // Assert
            Assert.False(result);
        }
        public async Task InspectReturnExpression_ReturnsDiagnostic_If200IsNotDocumented()
        {
            // Arrange
            var compilation = await GetCompilation();

            var context          = GetContext(compilation, new[] { 404 });
            var actualReturnType = compilation.GetTypeByMetadataName(typeof(ApiConventionAnalyzerDerivedModel).FullName);

            // Act
            var diagnostic = ApiConventionAnalyzer.InspectReturnExpression(context, actualReturnType, Location.None);

            // Assert
            Assert.NotNull(diagnostic);
            Assert.Same(DiagnosticDescriptors.MVC1005_ActionReturnsUndocumentedSuccessResult, diagnostic.Descriptor);
        }
        public async Task InspectReturnExpression_ReturnsDiagnostic_IfReturnTypeIsActionResultReturningUndocumentedStatusCode()
        {
            // Arrange
            var compilation = await GetCompilation();

            var declaredReturnType = compilation.GetTypeByMetadataName(typeof(ApiConventionAnalyzerBaseModel).FullName);
            var context            = GetContext(compilation, new[] { 200, 404 });
            var actualReturnType   = compilation.GetTypeByMetadataName(typeof(BadRequestObjectResult).FullName);

            // Act
            var diagnostic = ApiConventionAnalyzer.InspectReturnExpression(context, actualReturnType, Location.None);

            // Assert
            Assert.NotNull(diagnostic);
            Assert.Same(DiagnosticDescriptors.MVC1004_ActionReturnsUndocumentedStatusCode, diagnostic.Descriptor);
        }