Removed CatchAll and Fallback from DecisionTree
This commit is contained in:
parent
2ab24aa0f4
commit
ef0ea537e2
|
|
@ -10,7 +10,5 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
public Dictionary<object, DecisionTreeNode<TItem>> Branches { get; set; }
|
public Dictionary<object, DecisionTreeNode<TItem>> Branches { get; set; }
|
||||||
|
|
||||||
public DecisionTreeNode<TItem> Fallback { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,18 +5,11 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
{
|
{
|
||||||
internal struct DecisionCriterionValue
|
internal struct DecisionCriterionValue
|
||||||
{
|
{
|
||||||
private readonly bool _isCatchAll;
|
|
||||||
private readonly object _value;
|
private readonly object _value;
|
||||||
|
|
||||||
public DecisionCriterionValue(object value, bool isCatchAll)
|
public DecisionCriterionValue(object value)
|
||||||
{
|
{
|
||||||
_value = value;
|
_value = value;
|
||||||
_isCatchAll = isCatchAll;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsCatchAll
|
|
||||||
{
|
|
||||||
get { return _isCatchAll; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Value
|
public object Value
|
||||||
|
|
|
||||||
|
|
@ -16,19 +16,12 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
|
|
||||||
public bool Equals(DecisionCriterionValue x, DecisionCriterionValue y)
|
public bool Equals(DecisionCriterionValue x, DecisionCriterionValue y)
|
||||||
{
|
{
|
||||||
return x.IsCatchAll == y.IsCatchAll || InnerComparer.Equals(x.Value, y.Value);
|
return InnerComparer.Equals(x.Value, y.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetHashCode(DecisionCriterionValue obj)
|
public int GetHashCode(DecisionCriterionValue obj)
|
||||||
{
|
{
|
||||||
if (obj.IsCatchAll)
|
return InnerComparer.GetHashCode(obj.Value);
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return InnerComparer.GetHashCode(obj.Value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +153,6 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
foreach (var criterion in criteria.OrderByDescending(c => c.Value.Count))
|
foreach (var criterion in criteria.OrderByDescending(c => c.Value.Count))
|
||||||
{
|
{
|
||||||
var reducedBranches = new Dictionary<object, DecisionTreeNode<TItem>>(comparer.InnerComparer);
|
var reducedBranches = new Dictionary<object, DecisionTreeNode<TItem>>(comparer.InnerComparer);
|
||||||
DecisionTreeNode<TItem> fallback = null;
|
|
||||||
|
|
||||||
foreach (var branch in criterion.Value)
|
foreach (var branch in criterion.Value)
|
||||||
{
|
{
|
||||||
|
|
@ -172,24 +171,16 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
childContext.CurrentCriteria.Add(criterion.Key);
|
childContext.CurrentCriteria.Add(criterion.Key);
|
||||||
|
|
||||||
var newBranch = GenerateNode(childContext, comparer, branch.Value);
|
var newBranch = GenerateNode(childContext, comparer, branch.Value);
|
||||||
if (branch.Key.IsCatchAll)
|
reducedBranches.Add(branch.Key.Value, newBranch);
|
||||||
{
|
|
||||||
fallback = newBranch;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reducedBranches.Add(branch.Key.Value, newBranch);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reducedBranches.Count > 0 || fallback != null)
|
if (reducedBranches.Count > 0)
|
||||||
{
|
{
|
||||||
var newCriterion = new DecisionCriterion<TItem>()
|
var newCriterion = new DecisionCriterion<TItem>()
|
||||||
{
|
{
|
||||||
Key = criterion.Key,
|
Key = criterion.Key,
|
||||||
Branches = reducedBranches,
|
Branches = reducedBranches,
|
||||||
Fallback = fallback,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
reducedCriteria.Add(newCriterion);
|
reducedCriteria.Add(newCriterion);
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ namespace Microsoft.AspNet.Routing.Internal
|
||||||
var results = new Dictionary<string, DecisionCriterionValue>(StringComparer.OrdinalIgnoreCase);
|
var results = new Dictionary<string, DecisionCriterionValue>(StringComparer.OrdinalIgnoreCase);
|
||||||
foreach (var kvp in item.RequiredLinkValues)
|
foreach (var kvp in item.RequiredLinkValues)
|
||||||
{
|
{
|
||||||
results.Add(kvp.Key, new DecisionCriterionValue(kvp.Value ?? string.Empty, isCatchAll: false));
|
results.Add(kvp.Key, new DecisionCriterionValue(kvp.Value ?? string.Empty));
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
var items = new List<Item>();
|
var items = new List<Item>();
|
||||||
|
|
||||||
var item = new Item();
|
var item = new Item();
|
||||||
item.Criteria.Add("area", new DecisionCriterionValue(value: "Admin", isCatchAll: false));
|
item.Criteria.Add("area", new DecisionCriterionValue(value: "Admin"));
|
||||||
item.Criteria.Add("controller", new DecisionCriterionValue(value: "Users", isCatchAll: false));
|
item.Criteria.Add("controller", new DecisionCriterionValue(value: "Users"));
|
||||||
item.Criteria.Add("action", new DecisionCriterionValue(value: "AddUser", isCatchAll: false));
|
item.Criteria.Add("action", new DecisionCriterionValue(value: "AddUser"));
|
||||||
items.Add(item);
|
items.Add(item);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -60,7 +60,6 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
|
|
||||||
var area = Assert.Single(tree.Criteria);
|
var area = Assert.Single(tree.Criteria);
|
||||||
Assert.Equal("area", area.Key);
|
Assert.Equal("area", area.Key);
|
||||||
Assert.Null(area.Fallback);
|
|
||||||
|
|
||||||
var admin = Assert.Single(area.Branches);
|
var admin = Assert.Single(area.Branches);
|
||||||
Assert.Equal("Admin", admin.Key);
|
Assert.Equal("Admin", admin.Key);
|
||||||
|
|
@ -68,7 +67,6 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
|
|
||||||
var controller = Assert.Single(admin.Value.Criteria);
|
var controller = Assert.Single(admin.Value.Criteria);
|
||||||
Assert.Equal("controller", controller.Key);
|
Assert.Equal("controller", controller.Key);
|
||||||
Assert.Null(controller.Fallback);
|
|
||||||
|
|
||||||
var users = Assert.Single(controller.Branches);
|
var users = Assert.Single(controller.Branches);
|
||||||
Assert.Equal("Users", users.Key);
|
Assert.Equal("Users", users.Key);
|
||||||
|
|
@ -76,7 +74,6 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
|
|
||||||
var action = Assert.Single(users.Value.Criteria);
|
var action = Assert.Single(users.Value.Criteria);
|
||||||
Assert.Equal("action", action.Key);
|
Assert.Equal("action", action.Key);
|
||||||
Assert.Null(action.Fallback);
|
|
||||||
|
|
||||||
var addUser = Assert.Single(action.Branches);
|
var addUser = Assert.Single(action.Branches);
|
||||||
Assert.Equal("AddUser", addUser.Key);
|
Assert.Equal("AddUser", addUser.Key);
|
||||||
|
|
@ -91,13 +88,13 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
var items = new List<Item>();
|
var items = new List<Item>();
|
||||||
|
|
||||||
var item1 = new Item();
|
var item1 = new Item();
|
||||||
item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store", isCatchAll: false));
|
item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store"));
|
||||||
item1.Criteria.Add("action", new DecisionCriterionValue(value: "Buy", isCatchAll: false));
|
item1.Criteria.Add("action", new DecisionCriterionValue(value: "Buy"));
|
||||||
items.Add(item1);
|
items.Add(item1);
|
||||||
|
|
||||||
var item2 = new Item();
|
var item2 = new Item();
|
||||||
item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store", isCatchAll: false));
|
item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store"));
|
||||||
item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout", isCatchAll: false));
|
item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout"));
|
||||||
items.Add(item2);
|
items.Add(item2);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -108,14 +105,12 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
|
|
||||||
var action = Assert.Single(tree.Criteria);
|
var action = Assert.Single(tree.Criteria);
|
||||||
Assert.Equal("action", action.Key);
|
Assert.Equal("action", action.Key);
|
||||||
Assert.Null(action.Fallback);
|
|
||||||
|
|
||||||
var buy = action.Branches["Buy"];
|
var buy = action.Branches["Buy"];
|
||||||
Assert.Empty(buy.Matches);
|
Assert.Empty(buy.Matches);
|
||||||
|
|
||||||
var controller = Assert.Single(buy.Criteria);
|
var controller = Assert.Single(buy.Criteria);
|
||||||
Assert.Equal("controller", controller.Key);
|
Assert.Equal("controller", controller.Key);
|
||||||
Assert.Null(controller.Fallback);
|
|
||||||
|
|
||||||
var store = Assert.Single(controller.Branches);
|
var store = Assert.Single(controller.Branches);
|
||||||
Assert.Equal("Store", store.Key);
|
Assert.Equal("Store", store.Key);
|
||||||
|
|
@ -127,7 +122,6 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
|
|
||||||
controller = Assert.Single(checkout.Criteria);
|
controller = Assert.Single(checkout.Criteria);
|
||||||
Assert.Equal("controller", controller.Key);
|
Assert.Equal("controller", controller.Key);
|
||||||
Assert.Null(controller.Fallback);
|
|
||||||
|
|
||||||
store = Assert.Single(controller.Branches);
|
store = Assert.Single(controller.Branches);
|
||||||
Assert.Equal("Store", store.Key);
|
Assert.Equal("Store", store.Key);
|
||||||
|
|
@ -142,17 +136,17 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
var items = new List<Item>();
|
var items = new List<Item>();
|
||||||
|
|
||||||
var item1 = new Item();
|
var item1 = new Item();
|
||||||
item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store", isCatchAll: false));
|
item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store"));
|
||||||
item1.Criteria.Add("action", new DecisionCriterionValue(value: "Buy", isCatchAll: false));
|
item1.Criteria.Add("action", new DecisionCriterionValue(value: "Buy"));
|
||||||
items.Add(item1);
|
items.Add(item1);
|
||||||
|
|
||||||
var item2 = new Item();
|
var item2 = new Item();
|
||||||
item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store", isCatchAll: false));
|
item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store"));
|
||||||
item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout", isCatchAll: false));
|
item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout"));
|
||||||
items.Add(item2);
|
items.Add(item2);
|
||||||
|
|
||||||
var item3 = new Item();
|
var item3 = new Item();
|
||||||
item3.Criteria.Add("action", new DecisionCriterionValue(value: "Buy", isCatchAll: false));
|
item3.Criteria.Add("action", new DecisionCriterionValue(value: "Buy"));
|
||||||
items.Add(item3);
|
items.Add(item3);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -163,66 +157,11 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
|
|
||||||
var action = Assert.Single(tree.Criteria);
|
var action = Assert.Single(tree.Criteria);
|
||||||
Assert.Equal("action", action.Key);
|
Assert.Equal("action", action.Key);
|
||||||
Assert.Null(action.Fallback);
|
|
||||||
|
|
||||||
var buy = action.Branches["Buy"];
|
var buy = action.Branches["Buy"];
|
||||||
Assert.Same(item3, Assert.Single(buy.Matches));
|
Assert.Same(item3, Assert.Single(buy.Matches));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void BuildTree_WithCatchAll()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var items = new List<Item>();
|
|
||||||
|
|
||||||
var item1 = new Item();
|
|
||||||
item1.Criteria.Add("country", new DecisionCriterionValue(value: "CA", isCatchAll: false));
|
|
||||||
item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store", isCatchAll: false));
|
|
||||||
item1.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout", isCatchAll: false));
|
|
||||||
items.Add(item1);
|
|
||||||
|
|
||||||
var item2 = new Item();
|
|
||||||
item2.Criteria.Add("country", new DecisionCriterionValue(value: "US", isCatchAll: false));
|
|
||||||
item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store", isCatchAll: false));
|
|
||||||
item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout", isCatchAll: false));
|
|
||||||
items.Add(item2);
|
|
||||||
|
|
||||||
var item3 = new Item();
|
|
||||||
item3.Criteria.Add("country", new DecisionCriterionValue(value: null, isCatchAll: true));
|
|
||||||
item3.Criteria.Add("controller", new DecisionCriterionValue(value: "Store", isCatchAll: false));
|
|
||||||
item3.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout", isCatchAll: false));
|
|
||||||
items.Add(item3);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var tree = DecisionTreeBuilder<Item>.GenerateTree(items, new ItemClassifier());
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Empty(tree.Matches);
|
|
||||||
|
|
||||||
var country = Assert.Single(tree.Criteria);
|
|
||||||
Assert.Equal("country", country.Key);
|
|
||||||
|
|
||||||
var fallback = country.Fallback;
|
|
||||||
Assert.NotNull(fallback);
|
|
||||||
|
|
||||||
var controller = Assert.Single(fallback.Criteria);
|
|
||||||
Assert.Equal("controller", controller.Key);
|
|
||||||
Assert.Null(controller.Fallback);
|
|
||||||
|
|
||||||
var store = Assert.Single(controller.Branches);
|
|
||||||
Assert.Equal("Store", store.Key);
|
|
||||||
Assert.Empty(store.Value.Matches);
|
|
||||||
|
|
||||||
var action = Assert.Single(store.Value.Criteria);
|
|
||||||
Assert.Equal("action", action.Key);
|
|
||||||
Assert.Null(action.Fallback);
|
|
||||||
|
|
||||||
var checkout = Assert.Single(action.Branches);
|
|
||||||
Assert.Equal("Checkout", checkout.Key);
|
|
||||||
Assert.Empty(checkout.Value.Criteria);
|
|
||||||
Assert.Same(item3, Assert.Single(checkout.Value.Matches));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BuildTree_WithDivergentCriteria()
|
public void BuildTree_WithDivergentCriteria()
|
||||||
{
|
{
|
||||||
|
|
@ -230,17 +169,17 @@ namespace Microsoft.AspNet.Routing.DecisionTree
|
||||||
var items = new List<Item>();
|
var items = new List<Item>();
|
||||||
|
|
||||||
var item1 = new Item();
|
var item1 = new Item();
|
||||||
item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store", isCatchAll: false));
|
item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store"));
|
||||||
item1.Criteria.Add("action", new DecisionCriterionValue(value: "Buy", isCatchAll: false));
|
item1.Criteria.Add("action", new DecisionCriterionValue(value: "Buy"));
|
||||||
items.Add(item1);
|
items.Add(item1);
|
||||||
|
|
||||||
var item2 = new Item();
|
var item2 = new Item();
|
||||||
item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store", isCatchAll: false));
|
item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store"));
|
||||||
item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout", isCatchAll: false));
|
item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout"));
|
||||||
items.Add(item2);
|
items.Add(item2);
|
||||||
|
|
||||||
var item3 = new Item();
|
var item3 = new Item();
|
||||||
item3.Criteria.Add("stub", new DecisionCriterionValue(value: "Bleh", isCatchAll: false));
|
item3.Criteria.Add("stub", new DecisionCriterionValue(value: "Bleh"));
|
||||||
items.Add(item3);
|
items.Add(item3);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue