Exemple #1
0
        public async Task Pubternal_type_in_nested_namespace_field___warning_GF0001()
        {
            string library = @"
namespace gfoidl.Internal.Services
{
    public class Bar
    {
        public void Do() { }
    }
}";

            TestSource code = TestSource.Read(@"
using gfoidl.Internal.Services;

namespace MyProgram
{
    internal class Worker
    {
        private /*MM*/Bar _bar = new Bar();
    }
}");
            Diagnostic[] diagnostics    = await this.GetDiagnosticsWithProjectReference(code.Source, library);
            DiagnosticLocation expected = code.DefaultMarkerLocation;

            Assert.Multiple(() =>
            {
                Assert.AreEqual(1, diagnostics.Length);

                Diagnostic diagnostic = diagnostics[0];
                Assert.AreEqual("GF0001", diagnostic.Id);
                Assert.IsTrue(diagnostic.Location.IsInSource);
                Assert.That(diagnostic.Location, Is.EqualTo(expected));
            });
        }
Exemple #2
0
    public async Task DiagnosticsAreReturned_ForNotFoundNullActionResults()
    {
        // Arrange
        var source           = @"
using Microsoft.AspNetCore.Mvc;

namespace Test
{
    [ApiController]
    [Route(""[controller]"")]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public ActionResult<string> Test()
        {
            return NotFound(null);
        }
    }
}";
        var testSource       = TestSource.Read(source);
        var expectedLocation = testSource.DefaultMarkerLocation;

        // Act
        var result = await Executor.GetDiagnosticsAsync(testSource.Source);

        // Assert
        Assert.Contains(result, d => d.Id == ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode.Id);
    }
Exemple #3
0
    public async Task DiagnosticsAreReturned_ForIncompleteActionResults()
    {
        // Arrange
        var source           = @"
using Microsoft.AspNetCore.Mvc;

namespace Test
{
    [ApiController]
    [Route(""[controller]/[action]"")
    public class TestController : ControllerBase
    {
        public IActionResult Get(int id)
        {
            if (id == 0)
            {
                return /*MM*/NotFound();
            }

            return;
        }
    }
}";
        var testSource       = TestSource.Read(source);
        var expectedLocation = testSource.DefaultMarkerLocation;

        // Act
        var result = await Executor.GetDiagnosticsAsync(testSource.Source);

        // Assert
        var diagnostic = Assert.Single(result, d => d.Id == ApiDiagnosticDescriptors.API1000_ActionReturnsUndocumentedStatusCode.Id);

        AnalyzerAssert.DiagnosticLocation(expectedLocation, diagnostic.Location);
    }
        public async Task StartupAnalyzer_WorksWithOtherMethodsInProgram()
        {
            // Arrange
            var source = TestSource.Read(@"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        builder.Services.AddMvc();
        var app = builder.Build();
        app.UseStaticFiles();
        app.UseMiddleware<AuthorizationMiddleware>();
        /*MM*/app.UseMvc();
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
        });
        app.Run();
    }

    private static void MethodA()
    {
    }

    private static void MethodB()
    {
    }
}");

            // Act
            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);

            // Assert
            var optionsAnalysis = Assert.Single(Analyses.OfType <OptionsAnalysis>());

            Assert.False(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));

            var middlewareAnalysis = Assert.Single(Analyses.OfType <MiddlewareAnalysis>());

            Assert.Collection(
                middlewareAnalysis.Middleware,
                item => Assert.Equal("UseStaticFiles", item.UseMethod.Name),
                item => Assert.Equal("UseMiddleware", item.UseMethod.Name),
                item => Assert.Equal("UseMvc", item.UseMethod.Name),
                item => Assert.Equal("UseRouting", item.UseMethod.Name),
                item => Assert.Equal("UseEndpoints", item.UseMethod.Name));

            Assert.Collection(
                diagnostics,
                diagnostic =>
            {
                Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
                AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
                Assert.Contains("inside 'Main", diagnostic.GetMessage());
            });
        }
Exemple #5
0
        public async Task Local___warning_GF0001()
        {
            string library = @"
namespace MyLib.Internal
{
    public class Bar
    {
        public void Do() { }
    }
}";

            TestSource code = TestSource.Read(@"
using MyLib.Internal;

namespace MyProgram
{
    internal class Worker
    {
        public void Do()
        {
            /*MM*/Bar bar = new Bar();
        }
    }
}");

            Diagnostic[] diagnostics = await this.GetDiagnosticsWithProjectReference(code.Source, library);

            Assert.AreEqual(0, diagnostics.Length);
        }
Exemple #6
0
        public async Task Pubternal_type_in_nested_namespace_field___warning_GF0001()
        {
            string library = @"
namespace MyLib.Internal.Services
{
    public class Bar
    {
        public void Do() { }
    }
}";

            TestSource code = TestSource.Read(@"
using MyLib.Internal.Services;

namespace MyProgram
{
    internal class Worker
    {
        private /*MM*/Bar _bar = new Bar();
    }
}");

            Diagnostic[] diagnostics = await this.GetDiagnosticsWithProjectReference(code.Source, library);

            Assert.AreEqual(0, diagnostics.Length);
        }
Exemple #7
0
        public async Task Local_declared_as_var___no_warning_or_error()
        {
            string library = @"
namespace MyLib.Services
{
    public class Bar
    {
        public void Do() { }
    }
}";

            TestSource code = TestSource.Read(@"
using MyLib.Services;

namespace MyProgram
{
    internal class Worker
    {
        public void Do()
        {
            var bar = new Bar();
        }
    }
}");

            Diagnostic[] diagnostics = await this.GetDiagnosticsWithProjectReference(code.Source, library);

            Assert.AreEqual(0, diagnostics.Length);
        }
Exemple #8
0
        public async Task Issue_1_used_to_hide_pubternals___warning_GF0001()
        {
            string library = @"
namespace gfoidl.Internal
{
    public abstract class Base
    {
        private static readonly Bar s_bar = new Bar();

        public static Bar Default => s_bar;

        public abstract void Do();
    }

    public sealed class Bar : Base
    {
        public override void Do() { }
    }
}";

            TestSource code = TestSource.Read(@"
using gfoidl.Internal;

namespace MyProgram
{
    internal class Worker
    {
        public void Work()
        {
            /*M0*/Base./*M1*/Default.Do();
        }
    }
}", "M0", "M1");
            Diagnostic[] diagnostics      = await this.GetDiagnosticsWithProjectReference(code.Source, library);
            DiagnosticLocation expectedM0 = code.MarkerLocations["M0"];
            DiagnosticLocation expectedM1 = code.MarkerLocations["M1"];

            Assert.Multiple(() =>
            {
                Assert.AreEqual(2, diagnostics.Length);

                Diagnostic diagnostic = diagnostics[0];
                Assert.AreEqual("GF0001", diagnostic.Id);
                Assert.IsTrue(diagnostic.Location.IsInSource);
                Assert.That(diagnostic.Location, Is.EqualTo(expectedM0));

                diagnostic = diagnostics[1];
                Assert.AreEqual("GF0001", diagnostic.Id);
                Assert.IsTrue(diagnostic.Location.IsInSource);
                Assert.That(diagnostic.Location, Is.EqualTo(expectedM1));
            });
        }
Exemple #9
0
        public static TestSource Read(string testClassName, string testMethod)
        {
            var filePath = Path.Combine(ProjectDirectory, "TestFiles", testClassName, testMethod + ".cs");

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"TestFile {testMethod} could not be found at {filePath}.", filePath);
            }

            var fileContent = File.ReadAllText(filePath);

            return(TestSource.Read(fileContent));
        }
        public TestSource Read(string source)
        {
            var filePath = Path.Combine(ProjectDirectory, "TestFiles", GetType().Name, source);

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"TestFile {source} could not be found at {filePath}.", filePath);
            }

            var fileContent = File.ReadAllText(filePath);

            return(TestSource.Read(fileContent));
        }
Exemple #11
0
        public async Task DefinitionOfPubternalCrossAssemblyProducesPUB0002(string member)
        {
            var code = TestSource.Read($@"
using A.Internal.Namespace;
namespace A
{{
    internal class T
    {{
        {member}
    }}
}}");

            var diagnostic = Assert.Single(await GetDiagnosticWithProjectReference(code.Source));

            Assert.Equal("PUB0002", diagnostic.Id);
            AnalyzerAssert.DiagnosticLocation(code.DefaultMarkerLocation, diagnostic.Location);
        }
Exemple #12
0
        public TestSource Read(string source)
        {
            if (!source.EndsWith(".cs", StringComparison.Ordinal))
            {
                source = source + ".cs";
            }

            var filePath = Path.Combine(AppContext.BaseDirectory, "TestFiles", GetType().Name, source);

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"TestFile {source} could not be found at {filePath}.", filePath);
            }

            var fileContent = File.ReadAllText(filePath);

            return(TestSource.Read(fileContent));
        }
Exemple #13
0
        public async Task Issue_1_used_to_hide_pubternals___no_warning_or_error()
        {
            string library = @"
namespace MyLib
{
    using MyLib.Internal;

    public abstract class Base
    {
        private static readonly Bar s_bar = new Bar();

        public static Bar Default => s_bar;

        public abstract void Do();
    }
}

namespace MyLib.Internal
{
    public sealed class Bar : Base
    {
        public override void Do() { }
    }
}";

            TestSource code = TestSource.Read(@"
using MyLib;

namespace MyProgram
{
    internal class Worker
    {
        public void Work()
        {
            Base.Default.Do();
        }
    }
}");

            Diagnostic[] diagnostics = await this.GetDiagnosticsWithProjectReference(code.Source, library);

            Assert.AreEqual(0, diagnostics.Length);
        }
        public async Task StartupAnalyzer_AuthNoRouting()
        {
            // Arrange
            var source = TestSource.Read(@"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authorization;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseAuthorization();
app.Run();");

            // Act
            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);

            // Assert
            var middlewareAnalysis = Assert.Single(Analyses.OfType <MiddlewareAnalysis>());

            Assert.Single(middlewareAnalysis.Middleware);
            Assert.Empty(diagnostics);
        }
Exemple #15
0
 private TestSource GetSourceFromNamespaceDeclaration(string namespaceDefinition)
 {
     return(TestSource.Read("using A.Internal.Namespace;" + InternalDefinitions + namespaceDefinition));
 }
        internal override TestSource GetSource(string scenario)
        {
            string source = null;

            switch (scenario)
            {
            case "StartupSignatures_Standard":     //passes
                source = @"using Microsoft.AspNetCore.Builder;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet(""/"", () => ""Hello World!"");
app.Run();";
                break;

            case "StartupSignatures_MoreVariety":     //passes
                source = @"using Microsoft.AspNetCore.Builder;
var app = WebApplication.Create(args);
app.MapGet(""/"", () => ""Hello World!"");
app.Run();";
                break;

            case "MvcOptions_UseMvcWithDefaultRouteAndEndpointRoutingDisabled":     //passes
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMvc(options => options.EnableEndpointRouting = false);
var app = builder.Build();
app.UseMvcWithDefaultRoute();
app.Run();";
                break;

            case "MvcOptions_UseMvcWithDefaultRouteAndAddMvcOptionsEndpointRoutingDisabled":     //passes
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMvc().AddMvcOptions(options => options.EnableEndpointRouting = false);
var app = builder.Build();
app.UseMvcWithDefaultRoute();
app.Run();";
                break;

            case "MvcOptions_UseMvc":     //passes (fails)
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMvc();
var app = builder.Build();
/*MM*/app.UseMvc();
app.Run();";
                break;

            case "MvcOptions_UseMvcAndConfiguredRoutes":     //passes (fails)
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMvc();
var app = builder.Build();
/*MM*/app.UseMvc(routes =>
{
    routes.MapRoute(""Name"", ""Template"");
});
app.Run();";
                break;

            case "MvcOptions_UseMvcWithDefaultRoute":     //passes (fails)
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMvc();
var app = builder.Build();
/*MM*/app.UseMvcWithDefaultRoute();
app.Run();";
                break;

            case "MvcOptions_UseMvcWithOtherMiddleware":     //passes (fails)
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authorization;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMvc();
var app = builder.Build();
app.UseStaticFiles();
app.UseMiddleware<AuthorizationMiddleware>();
/*MM*/app.UseMvc();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
});
app.Run();";
                break;

            case "MvcOptions_UseMvcMultiple":     //passes (fails)
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authorization;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMvc();
var app = builder.Build();
/*MM1*/app.UseMvcWithDefaultRoute();
app.UseStaticFiles();
app.UseMiddleware<AuthorizationMiddleware>();
/*MM2*/app.UseMvc();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
});
/*MM3*/app.UseMvc();
app.Run();";
                break;

            case "UseAuthConfiguredCorrectly":     //passes
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authorization;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(r => {});
app.Run();";
                break;

            case "UseAuthConfiguredCorrectlyChained":     //passes
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseRouting()
    .UseAuthorization()
    .UseEndpoints(r => {});
app.Run();";
                break;

            case "UseAuthMultipleTimes":     //passes
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseRouting();
app.UseAuthorization();
app.UseAuthorization();
app.UseEndpoints(r => {});
app.Run();";
                break;

            case "UseAuthBeforeUseRouting":     //passes (fails)
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseFileServer();
/*MM*/app.UseAuthorization();
app.UseRouting();
app.UseEndpoints(r => {});
app.Run();";
                break;

            case "UseAuthBeforeUseRoutingChained":     //passes (fails)
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseFileServer()
    .UseAuthorization()
    .UseRouting()
    .UseEndpoints(r => {});
app.Run();";
                break;

            case "UseAuthAfterUseEndpoints":     //passes (fails)
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(r => { });
/*MM*/app.UseAuthorization();
app.Run();";
                break;

            case "UseAuthFallbackPolicy":     //passes
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseAuthorization();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(r => { });
app.Run();";
                break;

            case "ConfigureServices_BuildServiceProvider":
                source = @"using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
/*MM1*/builder.Services.BuildServiceProvider();
var app = builder.Build();
app.Run();";
                break;
            }

            return(source is not null?TestSource.Read(source) : null);
        }