Create collections on DfaNode as needed (#779)

This commit is contained in:
James Newton-King 2018-09-06 12:58:57 +12:00 committed by GitHub
parent a777a4cdd5
commit 0f5d471dfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 224 additions and 104 deletions

View File

@ -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}\"]");

View File

@ -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<DfaState> 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<Endpoint> endpoints)
{
if (endpoints.Count == 0)
if (endpoints == null || endpoints.Count == 0)
{
return Array.Empty<Candidate>();
}
@ -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<int>();
}
@ -510,16 +525,16 @@ namespace Microsoft.AspNetCore.Routing.Matching
var groups = new List<int>();
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<Endpoint>)Array.Empty<Endpoint>()))
{
// 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<Endpoint>)Array.Empty<Endpoint>());
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;

View File

@ -14,13 +14,6 @@ namespace Microsoft.AspNetCore.Routing.Matching
[DebuggerDisplay("{DebuggerToString(),nq}")]
internal class DfaNode
{
public DfaNode()
{
Literals = new Dictionary<string, DfaNode>(StringComparer.OrdinalIgnoreCase);
Matches = new List<Endpoint>();
PolicyEdges = new Dictionary<object, DfaNode>();
}
// 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<Endpoint> Matches { get; }
public List<Endpoint> Matches { get; private set; }
public Dictionary<string, DfaNode> Literals { get; }
public Dictionary<string, DfaNode> 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<object, DfaNode> PolicyEdges { get; }
public Dictionary<object, DfaNode> PolicyEdges { get; private set; }
public void AddPolicyEdge(object state, DfaNode node)
{
if (PolicyEdges == null)
{
PolicyEdges = new Dictionary<object, DfaNode>();
}
PolicyEdges.Add(state, node);
}
public void AddLiteral(string literal, DfaNode node)
{
if (Literals == null)
{
Literals = new Dictionary<string, DfaNode>(StringComparer.OrdinalIgnoreCase);
}
Literals.Add(literal, node);
}
public void AddMatch(Endpoint endpoint)
{
if (Matches == null)
{
Matches = new List<Endpoint>();
}
Matches.Add(endpoint);
}
public void AddMatches(IEnumerable<Endpoint> endpoints)
{
if (Matches == null)
{
Matches = new List<Endpoint>(endpoints);
}
else
{
Matches.AddRange(endpoints);
}
}
public void Visit(Action<DfaNode> 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.

View File

@ -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]