diff --git a/src/Microsoft.AspNetCore.Routing/Internal/DfaGraphWriter.cs b/src/Microsoft.AspNetCore.Routing/Internal/DfaGraphWriter.cs index eb2d2f10ec..5a42cf493b 100644 --- a/src/Microsoft.AspNetCore.Routing/Internal/DfaGraphWriter.cs +++ b/src/Microsoft.AspNetCore.Routing/Internal/DfaGraphWriter.cs @@ -64,9 +64,12 @@ namespace Microsoft.AspNetCore.Routing.Internal // We can safely index into visited because this is a post-order traversal, // all of the children of this node are already in the dictionary. - foreach (var literal in node.Literals) + if (node.Literals != null) { - writer.WriteLine($"{label} -> {visited[literal.Value]} [label=\"/{literal.Key}\"]"); + foreach (var literal in node.Literals) + { + writer.WriteLine($"{label} -> {visited[literal.Value]} [label=\"/{literal.Key}\"]"); + } } if (node.Parameters != null) @@ -79,9 +82,12 @@ namespace Microsoft.AspNetCore.Routing.Internal writer.WriteLine($"{label} -> {visited[node.CatchAll]} [label=\"/**\"]"); } - foreach (var policy in node.PolicyEdges) + if (node.PolicyEdges != null) { - writer.WriteLine($"{label} -> {visited[policy.Value]} [label=\"{policy.Key}\"]"); + foreach (var policy in node.PolicyEdges) + { + writer.WriteLine($"{label} -> {visited[policy.Value]} [label=\"{policy.Key}\"]"); + } } writer.WriteLine($"{label} [label=\"{node.Label}\"]"); diff --git a/src/Microsoft.AspNetCore.Routing/Matching/DfaMatcherBuilder.cs b/src/Microsoft.AspNetCore.Routing/Matching/DfaMatcherBuilder.cs index abe57ab1e7..1573178b13 100644 --- a/src/Microsoft.AspNetCore.Routing/Matching/DfaMatcherBuilder.cs +++ b/src/Microsoft.AspNetCore.Routing/Matching/DfaMatcherBuilder.cs @@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Routing.Matching for (var j = 0; j < parents.Count; j++) { var parent = parents[j]; - parent.Matches.Add(endpoint); + parent.AddMatch(endpoint); } } @@ -139,15 +139,17 @@ namespace Microsoft.AspNetCore.Routing.Matching var part = segment.Parts[0]; if (segment.IsSimple && part is RoutePatternLiteralPart literalPart) { + DfaNode next = null; var literal = literalPart.Content; - if (!parent.Literals.TryGetValue(literal, out var next)) + if (parent.Literals == null || + !parent.Literals.TryGetValue(literal, out next)) { next = new DfaNode() { PathDepth = parent.PathDepth + 1, Label = parent.Label + literal + "/", }; - parent.Literals.Add(literal, next); + parent.AddLiteral(literal, next); } nextParents.Add(next); @@ -157,7 +159,10 @@ namespace Microsoft.AspNetCore.Routing.Matching // A catch all should traverse all literal nodes as well as parameter nodes // we don't need to create the parameter node here because of ordering // all catchalls will be processed after all parameters. - nextParents.AddRange(parent.Literals.Values); + if (parent.Literals != null) + { + nextParents.AddRange(parent.Literals.Values); + } if (parent.Parameters != null) { nextParents.Add(parent.Parameters); @@ -181,7 +186,7 @@ namespace Microsoft.AspNetCore.Routing.Matching parent.CatchAll.CatchAll = parent.CatchAll; } - parent.CatchAll.Matches.Add(endpoint); + parent.CatchAll.AddMatch(endpoint); } else if (segment.IsSimple && part.IsParameter) { @@ -195,7 +200,10 @@ namespace Microsoft.AspNetCore.Routing.Matching } // A parameter should traverse all literal nodes as well as the parameter node - nextParents.AddRange(parent.Literals.Values); + if (parent.Literals != null) + { + nextParents.AddRange(parent.Literals.Values); + } nextParents.Add(parent.Parameters); } else @@ -213,7 +221,10 @@ namespace Microsoft.AspNetCore.Routing.Matching }; } - nextParents.AddRange(parent.Literals.Values); + if (parent.Literals != null) + { + nextParents.AddRange(parent.Literals.Values); + } nextParents.Add(parent.Parameters); } } @@ -311,7 +322,7 @@ namespace Microsoft.AspNetCore.Routing.Matching List states, List<(JumpTableBuilder pathBuilder, PolicyJumpTableBuilder policyBuilder)> tableBuilders) { - node.Matches.Sort(_comparer); + node.Matches?.Sort(_comparer); var stateIndex = states.Count; @@ -321,15 +332,18 @@ namespace Microsoft.AspNetCore.Routing.Matching var pathBuilder = new JumpTableBuilder(); tableBuilders.Add((pathBuilder, null)); - foreach (var kvp in node.Literals) + if (node.Literals != null) { - if (kvp.Key == null) + foreach (var kvp in node.Literals) { - continue; - } + if (kvp.Key == null) + { + continue; + } - var transition = Transition(kvp.Value); - pathBuilder.AddEntry(kvp.Key, transition); + var transition = Transition(kvp.Value); + pathBuilder.AddEntry(kvp.Key, transition); + } } if (node.Parameters != null && @@ -360,7 +374,7 @@ namespace Microsoft.AspNetCore.Routing.Matching pathBuilder.ExitDestination = pathBuilder.DefaultDestination; } - if (node.PolicyEdges.Count > 0) + if (node.PolicyEdges != null && node.PolicyEdges.Count > 0) { var policyBuilder = new PolicyJumpTableBuilder(node.NodeBuilder); tableBuilders[stateIndex] = (pathBuilder, policyBuilder); @@ -384,7 +398,7 @@ namespace Microsoft.AspNetCore.Routing.Matching // endpoint. internal Candidate[] CreateCandidates(IReadOnlyList endpoints) { - if (endpoints.Count == 0) + if (endpoints == null || endpoints.Count == 0) { return Array.Empty(); } @@ -502,7 +516,8 @@ namespace Microsoft.AspNetCore.Routing.Matching private int[] GetGroupLengths(DfaNode node) { - if (node.Matches.Count == 0) + var nodeMatches = node.Matches; + if (nodeMatches == null || nodeMatches.Count == 0) { return Array.Empty(); } @@ -510,16 +525,16 @@ namespace Microsoft.AspNetCore.Routing.Matching var groups = new List(); var length = 1; - var exemplar = node.Matches[0]; + var exemplar = nodeMatches[0]; - for (var i = 1; i < node.Matches.Count; i++) + for (var i = 1; i < nodeMatches.Count; i++) { - if (!_comparer.Equals(exemplar, node.Matches[i])) + if (!_comparer.Equals(exemplar, nodeMatches[i])) { groups.Add(length); length = 0; - exemplar = node.Matches[i]; + exemplar = nodeMatches[i]; } length++; @@ -561,7 +576,7 @@ namespace Microsoft.AspNetCore.Routing.Matching private void ApplyPolicies(DfaNode node) { - if (node.Matches.Count == 0) + if (node.Matches == null || node.Matches.Count == 0) { return; } @@ -578,7 +593,7 @@ namespace Microsoft.AspNetCore.Routing.Matching for (var j = 0; j < work.Count; j++) { var parent = work[j]; - if (!nodeBuilder.AppliesToNode(parent.Matches)) + if (!nodeBuilder.AppliesToNode(parent.Matches ?? (IReadOnlyList)Array.Empty())) { // This node-builder doesn't care about this node, so add it to the list // to be processed by the next node-builder. @@ -588,7 +603,7 @@ namespace Microsoft.AspNetCore.Routing.Matching // This node-builder does apply to this node, so we need to create new nodes for each edge, // and then attach them to the parent. - var edges = nodeBuilder.GetEdges(parent.Matches); + var edges = nodeBuilder.GetEdges(parent.Matches ?? (IReadOnlyList)Array.Empty()); for (var k = 0; k < edges.Count; k++) { var edge = edges[k]; @@ -598,17 +613,20 @@ namespace Microsoft.AspNetCore.Routing.Matching Label = parent.Label + " " + edge.State.ToString(), }; - next.Matches.AddRange(edge.Endpoints); + if (edge.Endpoints.Count > 0) + { + next.AddMatches(edge.Endpoints); + } nextWork.Add(next); - parent.PolicyEdges.Add(edge.State, next); + parent.AddPolicyEdge(edge.State, next); } // Associate the node-builder so we can build a jump table later. parent.NodeBuilder = nodeBuilder; // The parent no longer has matches, it's not considered a terminal node. - parent.Matches.Clear(); + parent.Matches?.Clear(); } work = nextWork; diff --git a/src/Microsoft.AspNetCore.Routing/Matching/DfaNode.cs b/src/Microsoft.AspNetCore.Routing/Matching/DfaNode.cs index e68c4909f7..f3f916b8e5 100644 --- a/src/Microsoft.AspNetCore.Routing/Matching/DfaNode.cs +++ b/src/Microsoft.AspNetCore.Routing/Matching/DfaNode.cs @@ -14,13 +14,6 @@ namespace Microsoft.AspNetCore.Routing.Matching [DebuggerDisplay("{DebuggerToString(),nq}")] internal class DfaNode { - public DfaNode() - { - Literals = new Dictionary(StringComparer.OrdinalIgnoreCase); - Matches = new List(); - PolicyEdges = new Dictionary(); - } - // The depth of the node. The depth indicates the number of segments // that must be processed to arrive at this node. // @@ -30,9 +23,9 @@ namespace Microsoft.AspNetCore.Routing.Matching // Just for diagnostics and debugging public string Label { get; set; } - public List Matches { get; } + public List Matches { get; private set; } - public Dictionary Literals { get; } + public Dictionary Literals { get; private set; } public DfaNode Parameters { get; set; } @@ -40,13 +33,58 @@ namespace Microsoft.AspNetCore.Routing.Matching public INodeBuilderPolicy NodeBuilder { get; set; } - public Dictionary PolicyEdges { get; } + public Dictionary PolicyEdges { get; private set; } + + public void AddPolicyEdge(object state, DfaNode node) + { + if (PolicyEdges == null) + { + PolicyEdges = new Dictionary(); + } + + PolicyEdges.Add(state, node); + } + + public void AddLiteral(string literal, DfaNode node) + { + if (Literals == null) + { + Literals = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + + Literals.Add(literal, node); + } + + public void AddMatch(Endpoint endpoint) + { + if (Matches == null) + { + Matches = new List(); + } + + Matches.Add(endpoint); + } + + public void AddMatches(IEnumerable endpoints) + { + if (Matches == null) + { + Matches = new List(endpoints); + } + else + { + Matches.AddRange(endpoints); + } + } public void Visit(Action visitor) { - foreach (var kvp in Literals) + if (Literals != null) { - kvp.Value.Visit(visitor); + foreach (var kvp in Literals) + { + kvp.Value.Visit(visitor); + } } // Break cycles @@ -61,9 +99,12 @@ namespace Microsoft.AspNetCore.Routing.Matching CatchAll.Visit(visitor); } - foreach (var kvp in PolicyEdges) + if (PolicyEdges != null) { - kvp.Value.Visit(visitor); + foreach (var kvp in PolicyEdges) + { + kvp.Value.Visit(visitor); + } } visitor(this); @@ -76,9 +117,12 @@ namespace Microsoft.AspNetCore.Routing.Matching builder.Append(" d:"); builder.Append(PathDepth); builder.Append(" m:"); - builder.Append(Matches.Count); + builder.Append(Matches?.Count ?? 0); builder.Append(" c: "); - builder.Append(string.Join(", ", Literals.Select(kvp => $"{kvp.Key}->({FormatNode(kvp.Value)})"))); + if (Literals != null) + { + builder.Append(string.Join(", ", Literals.Select(kvp => $"{kvp.Key}->({FormatNode(kvp.Value)})"))); + } return builder.ToString(); // DfaNodes can be self-referential, don't traverse cycles. diff --git a/test/Microsoft.AspNetCore.Routing.Tests/Matching/DfaMatcherBuilderTest.cs b/test/Microsoft.AspNetCore.Routing.Tests/Matching/DfaMatcherBuilderTest.cs index a9071c7962..10c0aec62e 100644 --- a/test/Microsoft.AspNetCore.Routing.Tests/Matching/DfaMatcherBuilderTest.cs +++ b/test/Microsoft.AspNetCore.Routing.Tests/Matching/DfaMatcherBuilderTest.cs @@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Routing.Matching // Assert Assert.Same(endpoint, Assert.Single(root.Matches)); Assert.Null(root.Parameters); - Assert.Empty(root.Literals); + Assert.Null(root.Literals); } [Fact] @@ -46,21 +46,21 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); Assert.Equal("a", next.Key); var a = next.Value; - Assert.Empty(a.Matches); + Assert.Null(a.Matches); Assert.Null(a.Parameters); next = Assert.Single(a.Literals); Assert.Equal("b", next.Key); var b = next.Value; - Assert.Empty(b.Matches); + Assert.Null(b.Matches); Assert.Null(b.Parameters); next = Assert.Single(b.Literals); @@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var c = next.Value; Assert.Same(endpoint, Assert.Single(c.Matches)); Assert.Null(c.Parameters); - Assert.Empty(c.Literals); + Assert.Null(c.Literals); } [Fact] @@ -85,21 +85,21 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); - Assert.Empty(root.Literals); + Assert.Null(root.Matches); + Assert.Null(root.Literals); var a = root.Parameters; - Assert.Empty(a.Matches); - Assert.Empty(a.Literals); + Assert.Null(a.Matches); + Assert.Null(a.Literals); var b = a.Parameters; - Assert.Empty(b.Matches); - Assert.Empty(b.Literals); + Assert.Null(b.Matches); + Assert.Null(b.Literals); var c = b.Parameters; Assert.Same(endpoint, Assert.Single(c.Matches)); Assert.Null(c.Parameters); - Assert.Empty(c.Literals); + Assert.Null(c.Literals); } [Fact] @@ -115,21 +115,21 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); - Assert.Empty(root.Literals); + Assert.Null(root.Matches); + Assert.Null(root.Literals); var a = root.Parameters; // The catch all can match a path like '/a' Assert.Same(endpoint, Assert.Single(a.Matches)); - Assert.Empty(a.Literals); + Assert.Null(a.Literals); Assert.Null(a.Parameters); // Catch-all nodes include an extra transition that loops to process // extra segments. var catchAll = a.CatchAll; Assert.Same(endpoint, Assert.Single(catchAll.Matches)); - Assert.Empty(catchAll.Literals); + Assert.Null(catchAll.Literals); Assert.Same(catchAll, catchAll.Parameters); Assert.Same(catchAll, catchAll.CatchAll); } @@ -148,13 +148,13 @@ namespace Microsoft.AspNetCore.Routing.Matching // Assert Assert.Same(endpoint, Assert.Single(root.Matches)); - Assert.Empty(root.Literals); + Assert.Null(root.Literals); // Catch-all nodes include an extra transition that loops to process // extra segments. var catchAll = root.CatchAll; Assert.Same(endpoint, Assert.Single(catchAll.Matches)); - Assert.Empty(catchAll.Literals); + Assert.Null(catchAll.Literals); Assert.Same(catchAll, catchAll.Parameters); } @@ -174,19 +174,19 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); Assert.Equal("a", next.Key); var a = next.Value; - Assert.Empty(a.Matches); + Assert.Null(a.Matches); Assert.Equal(2, a.Literals.Count); var b1 = a.Literals["b1"]; - Assert.Empty(b1.Matches); + Assert.Null(b1.Matches); Assert.Null(b1.Parameters); next = Assert.Single(b1.Literals); @@ -195,10 +195,10 @@ namespace Microsoft.AspNetCore.Routing.Matching var c1 = next.Value; Assert.Same(endpoint1, Assert.Single(c1.Matches)); Assert.Null(c1.Parameters); - Assert.Empty(c1.Literals); + Assert.Null(c1.Literals); var b2 = a.Literals["b2"]; - Assert.Empty(b2.Matches); + Assert.Null(b2.Matches); Assert.Null(b2.Parameters); next = Assert.Single(b2.Literals); @@ -207,7 +207,59 @@ namespace Microsoft.AspNetCore.Routing.Matching var c2 = next.Value; Assert.Same(endpoint2, Assert.Single(c2.Matches)); Assert.Null(c2.Parameters); - Assert.Empty(c2.Literals); + Assert.Null(c2.Literals); + } + + [Fact] + public void BuildDfaTree_MultipleEndpoint_LiteralDifferentCase() + { + // Arrange + var builder = CreateDfaMatcherBuilder(); + + var endpoint1 = CreateEndpoint("a/b1/c"); + builder.AddEndpoint(endpoint1); + + var endpoint2 = CreateEndpoint("A/b2/c"); + builder.AddEndpoint(endpoint2); + + // Act + var root = builder.BuildDfaTree(); + + // Assert + Assert.Null(root.Matches); + Assert.Null(root.Parameters); + + var next = Assert.Single(root.Literals); + Assert.Equal("a", next.Key); + + var a = next.Value; + Assert.Null(a.Matches); + + Assert.Equal(2, a.Literals.Count); + + var b1 = a.Literals["b1"]; + Assert.Null(b1.Matches); + Assert.Null(b1.Parameters); + + next = Assert.Single(b1.Literals); + Assert.Equal("c", next.Key); + + var c1 = next.Value; + Assert.Same(endpoint1, Assert.Single(c1.Matches)); + Assert.Null(c1.Parameters); + Assert.Null(c1.Literals); + + var b2 = a.Literals["b2"]; + Assert.Null(b2.Matches); + Assert.Null(b2.Parameters); + + next = Assert.Single(b2.Literals); + Assert.Equal("c", next.Key); + + var c2 = next.Value; + Assert.Same(endpoint2, Assert.Single(c2.Matches)); + Assert.Null(c2.Parameters); + Assert.Null(c2.Literals); } [Fact] @@ -226,20 +278,20 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); Assert.Equal("a", next.Key); var a = next.Value; - Assert.Empty(a.Matches); + Assert.Null(a.Matches); next = Assert.Single(a.Literals); Assert.Equal("b", next.Key); var b = next.Value; - Assert.Empty(b.Matches); + Assert.Null(b.Matches); Assert.Null(b.Parameters); next = Assert.Single(b.Literals); @@ -251,10 +303,10 @@ namespace Microsoft.AspNetCore.Routing.Matching e => Assert.Same(endpoint1, e), e => Assert.Same(endpoint2, e)); Assert.Null(c1.Parameters); - Assert.Empty(c1.Literals); + Assert.Null(c1.Literals); var b2 = a.Parameters; - Assert.Empty(b2.Matches); + Assert.Null(b2.Matches); Assert.Null(b2.Parameters); next = Assert.Single(b2.Literals); @@ -263,7 +315,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var c2 = next.Value; Assert.Same(endpoint2, Assert.Single(c2.Matches)); Assert.Null(c2.Parameters); - Assert.Empty(c2.Literals); + Assert.Null(c2.Literals); } [Fact] @@ -282,18 +334,18 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); Assert.Equal("a", next.Key); var a = next.Value; - Assert.Empty(a.Matches); - Assert.Empty(a.Literals); + Assert.Null(a.Matches); + Assert.Null(a.Literals); var b = a.Parameters; - Assert.Empty(b.Matches); + Assert.Null(b.Matches); Assert.Null(b.Parameters); next = Assert.Single(b.Literals); @@ -305,7 +357,7 @@ namespace Microsoft.AspNetCore.Routing.Matching e => Assert.Same(endpoint1, e), e => Assert.Same(endpoint2, e)); Assert.Null(c.Parameters); - Assert.Empty(c.Literals); + Assert.Null(c.Literals); } [Fact] @@ -324,7 +376,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); @@ -349,7 +401,7 @@ namespace Microsoft.AspNetCore.Routing.Matching e => Assert.Same(endpoint1, e), e => Assert.Same(endpoint2, e)); Assert.Null(c1.Parameters); - Assert.Empty(c1.Literals); + Assert.Null(c1.Literals); var catchAll = a.CatchAll; Assert.Same(endpoint2, Assert.Single(catchAll.Matches)); @@ -373,7 +425,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); @@ -381,7 +433,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var a = next.Value; Assert.Same(endpoint2, Assert.Single(a.Matches)); - Assert.Empty(a.Literals); + Assert.Null(a.Literals); var b1 = a.Parameters; Assert.Same(endpoint2, Assert.Single(a.Matches)); @@ -396,7 +448,7 @@ namespace Microsoft.AspNetCore.Routing.Matching e => Assert.Same(endpoint1, e), e => Assert.Same(endpoint2, e)); Assert.Null(c1.Parameters); - Assert.Empty(c1.Literals); + Assert.Null(c1.Literals); var catchAll = a.CatchAll; Assert.Same(endpoint2, Assert.Single(catchAll.Matches)); @@ -417,7 +469,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); @@ -440,7 +492,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var test2_true = test1_0.PolicyEdges[true]; Assert.Same(endpoint1, Assert.Single(test2_true.Matches)); Assert.Null(test2_true.NodeBuilder); - Assert.Empty(test2_true.PolicyEdges); + Assert.Null(test2_true.PolicyEdges); } [Fact] @@ -462,7 +514,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); @@ -486,7 +538,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var test2_true = test1_0.PolicyEdges[true]; Assert.Same(endpoint1, Assert.Single(test2_true.Matches)); Assert.Null(test2_true.NodeBuilder); - Assert.Empty(test2_true.PolicyEdges); + Assert.Null(test2_true.PolicyEdges); var test1_1 = a.PolicyEdges[1]; Assert.Empty(test1_1.Matches); @@ -499,12 +551,12 @@ namespace Microsoft.AspNetCore.Routing.Matching test2_true = test1_1.PolicyEdges[true]; Assert.Same(endpoint2, Assert.Single(test2_true.Matches)); Assert.Null(test2_true.NodeBuilder); - Assert.Empty(test2_true.PolicyEdges); + Assert.Null(test2_true.PolicyEdges); var test2_false = test1_1.PolicyEdges[false]; Assert.Same(endpoint3, Assert.Single(test2_false.Matches)); Assert.Null(test2_false.NodeBuilder); - Assert.Empty(test2_false.PolicyEdges); + Assert.Null(test2_false.PolicyEdges); } [Fact] @@ -526,7 +578,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); @@ -543,12 +595,12 @@ namespace Microsoft.AspNetCore.Routing.Matching var test2_true = a.PolicyEdges[true]; Assert.Equal(new[] { endpoint1, endpoint2, }, test2_true.Matches); Assert.Null(test2_true.NodeBuilder); - Assert.Empty(test2_true.PolicyEdges); + Assert.Null(test2_true.PolicyEdges); var test2_false = a.PolicyEdges[false]; Assert.Equal(new[] { endpoint3, }, test2_false.Matches); Assert.Null(test2_false.NodeBuilder); - Assert.Empty(test2_false.PolicyEdges); + Assert.Null(test2_false.PolicyEdges); } [Fact] @@ -570,7 +622,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); @@ -587,12 +639,12 @@ namespace Microsoft.AspNetCore.Routing.Matching var test1_0 = a.PolicyEdges[0]; Assert.Equal(new[] { endpoint1, }, test1_0.Matches); Assert.Null(test1_0.NodeBuilder); - Assert.Empty(test1_0.PolicyEdges); + Assert.Null(test1_0.PolicyEdges); var test1_1 = a.PolicyEdges[1]; Assert.Equal(new[] { endpoint2, endpoint3, }, test1_1.Matches); Assert.Null(test1_1.NodeBuilder); - Assert.Empty(test1_1.PolicyEdges); + Assert.Null(test1_1.PolicyEdges); } [Fact] @@ -614,7 +666,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); @@ -632,12 +684,12 @@ namespace Microsoft.AspNetCore.Routing.Matching var test1_0 = a.PolicyEdges[0]; Assert.Equal(new[] { endpoint1, }, test1_0.Matches); Assert.Null(test1_0.NodeBuilder); - Assert.Empty(test1_0.PolicyEdges); + Assert.Null(test1_0.PolicyEdges); var test1_1 = a.PolicyEdges[1]; Assert.Equal(new[] { endpoint2, endpoint3, }, test1_1.Matches); Assert.Null(test1_1.NodeBuilder); - Assert.Empty(test1_1.PolicyEdges); + Assert.Null(test1_1.PolicyEdges); var nonRouteEndpoint = a.PolicyEdges[int.MaxValue]; Assert.Equal("MaxValueEndpoint", Assert.Single(nonRouteEndpoint.Matches).DisplayName); @@ -662,7 +714,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var root = builder.BuildDfaTree(); // Assert - Assert.Empty(root.Matches); + Assert.Null(root.Matches); Assert.Null(root.Parameters); var next = Assert.Single(root.Literals); @@ -671,7 +723,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var a = next.Value; Assert.Equal(new[] { endpoint1, endpoint2, endpoint3, }, a.Matches); Assert.Null(a.NodeBuilder); - Assert.Empty(a.PolicyEdges); + Assert.Null(a.PolicyEdges); } [Fact]