Skip to content

Commit

Permalink
More tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanLarsson committed Dec 31, 2018
1 parent dfa9b5c commit ca61816
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 88 deletions.
40 changes: 40 additions & 0 deletions AspNetCoreAnalyzers.Tests/ASP009LowercaseUrlsTests/CodeFix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,45 @@ public IActionResult GetId(string id)
}".AssertReplace("\"api/orders/{id}\"", after);
AnalyzerAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, code, fixedCode);
}

[TestCase("\"api/↓Orders\"", "\"api/orders\"")]
public void WhenRouteAttribute(string before, string after)
{
var code = @"
namespace ValidCode
{
using Microsoft.AspNetCore.Mvc;
[Route(""api/Orders"")]
[ApiController]
public class OrdersController : Controller
{
[HttpGet(""{id}"")]
public IActionResult GetId(string id)
{
return this.Ok(id);
}
}
}".AssertReplace("\"api/Orders\"", before);

var fixedCode = @"
namespace ValidCode
{
using Microsoft.AspNetCore.Mvc;
[Route(""api/orders"")]
[ApiController]
public class OrdersController : Controller
{
[HttpGet(""{id}"")]
public IActionResult GetId(string id)
{
return this.Ok(id);
}
}
}".AssertReplace("\"api/orders\"", after);
AnalyzerAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, code, fixedCode);
}
}
}
}
181 changes: 93 additions & 88 deletions AspNetCoreAnalyzers/Analyzers/AttributeAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,117 +34,119 @@ private static void Handle(SyntaxNodeAnalysisContext context)
{
if (!context.IsExcludedFromAnalysis() &&
context.Node is AttributeSyntax attribute &&
context.ContainingSymbol is IMethodSymbol method &&
attribute.TryFirstAncestor(out MethodDeclarationSyntax methodDeclaration) &&
TryGetTemplate(attribute, context, out var template))
{
using (var pairs = GetPairs(template, method))
if (context.ContainingSymbol is IMethodSymbol method &&
attribute.TryFirstAncestor(out MethodDeclarationSyntax methodDeclaration))
{
if (pairs.TrySingle(x => x.Route == null, out var withMethodParameter) &&
methodDeclaration.TryFindParameter(withMethodParameter.Symbol.Name, out var parameterSyntax) &&
pairs.TrySingle(x => x.Symbol == null, out var withTemplateParameter) &&
withTemplateParameter.Route is TemplateParameter templateParameter)
using (var pairs = GetPairs(template, method))
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP001ParameterSymbolName.Descriptor,
parameterSyntax.Identifier.GetLocation(),
ImmutableDictionary<string, string>.Empty.Add(
nameof(NameSyntax),
templateParameter.Name.ToString())));

context.ReportDiagnostic(
Diagnostic.Create(
ASP002RouteParameterName.Descriptor,
templateParameter.Name.GetLocation(),
ImmutableDictionary<string, string>.Empty.Add(
nameof(Text),
withMethodParameter.Symbol.Name)));
}
else if (pairs.Count(x => x.Route == null) > 1 &&
pairs.Count(x => x.Symbol == null) > 1)
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP001ParameterSymbolName.Descriptor,
methodDeclaration.ParameterList.GetLocation()));
}

if (pairs.TryFirst(x => x.Symbol == null, out _) &&
!pairs.TryFirst(x => x.Route == null, out _))
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP007MissingParameter.Descriptor,
methodDeclaration.ParameterList.GetLocation()));
}

foreach (var pair in pairs)
{
if (HasWrongType(pair, out var typeName, out var constraintLocation, out var text) &&
methodDeclaration.TryFindParameter(pair.Symbol?.Name, out parameterSyntax))
if (pairs.TrySingle(x => x.Route == null, out var withMethodParameter) &&
methodDeclaration.TryFindParameter(withMethodParameter.Symbol.Name, out var parameterSyntax) &&
pairs.TrySingle(x => x.Symbol == null, out var withTemplateParameter) &&
withTemplateParameter.Route is TemplateParameter templateParameter)
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP003ParameterSymbolType.Descriptor,
parameterSyntax.Type.GetLocation(),
ImmutableDictionary<string, string>.Empty.Add(nameof(TypeSyntax), typeName)));
ASP001ParameterSymbolName.Descriptor,
parameterSyntax.Identifier.GetLocation(),
ImmutableDictionary<string, string>.Empty.Add(
nameof(NameSyntax),
templateParameter.Name.ToString())));

context.ReportDiagnostic(
Diagnostic.Create(
ASP004RouteParameterType.Descriptor,
constraintLocation,
text == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), text)));
ASP002RouteParameterName.Descriptor,
templateParameter.Name.GetLocation(),
ImmutableDictionary<string, string>.Empty.Add(
nameof(Text),
withMethodParameter.Symbol.Name)));
}
}

foreach (var segment in template.Path)
{
if (HasWrongSyntax(segment, out var location, out var syntax))
else if (pairs.Count(x => x.Route == null) > 1 &&
pairs.Count(x => x.Symbol == null) > 1)
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP005ParameterSyntax.Descriptor,
location,
syntax == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), syntax)));
ASP001ParameterSymbolName.Descriptor,
methodDeclaration.ParameterList.GetLocation()));
}

if (HasWrongRegexSyntax(segment, out location, out syntax))
if (pairs.TryFirst(x => x.Symbol == null, out _) &&
!pairs.TryFirst(x => x.Route == null, out _))
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP006ParameterRegex.Descriptor,
location,
syntax == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), syntax)));
ASP007MissingParameter.Descriptor,
methodDeclaration.ParameterList.GetLocation()));
}

if (HasInvalidName(segment, out location, out var name))
foreach (var pair in pairs)
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP008ValidRouteParameterName.Descriptor,
location,
name == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), name)));
if (HasWrongType(pair, out var typeName, out var constraintLocation, out var text) &&
methodDeclaration.TryFindParameter(pair.Symbol?.Name, out parameterSyntax))
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP003ParameterSymbolType.Descriptor,
parameterSyntax.Type.GetLocation(),
ImmutableDictionary<string, string>.Empty.Add(nameof(TypeSyntax), typeName)));

context.ReportDiagnostic(
Diagnostic.Create(
ASP004RouteParameterType.Descriptor,
constraintLocation,
text == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), text)));
}
}
}
}

if (IsUpperCase(segment, out var lowercase))
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP009LowercaseUrl.Descriptor,
segment.Span.GetLocation(),
lowercase == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), lowercase)));
}
foreach (var segment in template.Path)
{
if (HasWrongSyntax(segment, out var location, out var syntax))
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP005ParameterSyntax.Descriptor,
location,
syntax == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), syntax)));
}

if (HasWrongRegexSyntax(segment, out location, out syntax))
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP006ParameterRegex.Descriptor,
location,
syntax == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), syntax)));
}

if (HasInvalidName(segment, out location, out var name))
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP008ValidRouteParameterName.Descriptor,
location,
name == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), name)));
}

if (IsUpperCase(segment, out var lowercase))
{
context.ReportDiagnostic(
Diagnostic.Create(
ASP009LowercaseUrl.Descriptor,
segment.Span.GetLocation(),
lowercase == null
? ImmutableDictionary<string, string>.Empty
: ImmutableDictionary<string, string>.Empty.Add(nameof(Text), lowercase)));
}
}
}
Expand All @@ -158,9 +160,12 @@ argument.Expression is LiteralExpressionSyntax literal &&
literal.IsKind(SyntaxKind.StringLiteralExpression) &&
(Attribute.IsType(attribute, KnownSymbol.HttpDeleteAttribute, context.SemanticModel, context.CancellationToken) ||
Attribute.IsType(attribute, KnownSymbol.HttpGetAttribute, context.SemanticModel, context.CancellationToken) ||
Attribute.IsType(attribute, KnownSymbol.HttpHeadAttribute, context.SemanticModel, context.CancellationToken) ||
Attribute.IsType(attribute, KnownSymbol.HttpOptionsAttribute, context.SemanticModel, context.CancellationToken) ||
Attribute.IsType(attribute, KnownSymbol.HttpPatchAttribute, context.SemanticModel, context.CancellationToken) ||
Attribute.IsType(attribute, KnownSymbol.HttpPostAttribute, context.SemanticModel, context.CancellationToken) ||
Attribute.IsType(attribute, KnownSymbol.HttpPutAttribute, context.SemanticModel, context.CancellationToken)) &&
Attribute.IsType(attribute, KnownSymbol.HttpPutAttribute, context.SemanticModel, context.CancellationToken) ||
Attribute.IsType(attribute, KnownSymbol.RouteAttribute, context.SemanticModel, context.CancellationToken)) &&
UrlTemplate.TryParse(literal, out template))
{
return true;
Expand Down

0 comments on commit ca61816

Please sign in to comment.