/// <summary> /// Creates a new <see cref="ActionSelectionDecisionTree"/>. /// </summary> /// <param name="actions">The <see cref="ActionDescriptorCollection"/>.</param> public ActionSelectionDecisionTree(ActionDescriptorCollection actions) { Version = actions.Version; _root = DecisionTreeBuilder <ActionDescriptor> .GenerateTree( actions.Items, new ActionDescriptorClassifier()); }
/// <summary> /// Creates a new <see cref="ActionSelectionDecisionTree"/>. /// </summary> /// <param name="actions">The <see cref="ActionDescriptorCollection"/>.</param> public ActionSelectionDecisionTree(ActionDescriptorCollection actions) { Version = actions.Version; var conventionalRoutedActions = actions.Items.Where(a => a.AttributeRouteInfo?.Template == null).ToArray(); _root = DecisionTreeBuilder <ActionDescriptor> .GenerateTree( conventionalRoutedActions, new ActionDescriptorClassifier()); }
public void BuildTree_WithMultipleItems() { // Arrange var items = new List <Item>(); var item1 = new Item(); item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store")); item1.Criteria.Add("action", new DecisionCriterionValue(value: "Buy")); items.Add(item1); var item2 = new Item(); item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store")); item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout")); items.Add(item2); // Act var tree = DecisionTreeBuilder <Item> .GenerateTree(items, new ItemClassifier()); // Assert Assert.Empty(tree.Matches); var action = Assert.Single(tree.Criteria); Assert.Equal("action", action.Key); var buy = action.Branches["Buy"]; Assert.Empty(buy.Matches); var controller = Assert.Single(buy.Criteria); Assert.Equal("controller", controller.Key); var store = Assert.Single(controller.Branches); Assert.Equal("Store", store.Key); Assert.Empty(store.Value.Criteria); Assert.Same(item1, Assert.Single(store.Value.Matches)); var checkout = action.Branches["Checkout"]; Assert.Empty(checkout.Matches); controller = Assert.Single(checkout.Criteria); Assert.Equal("controller", controller.Key); store = Assert.Single(controller.Branches); Assert.Equal("Store", store.Key); Assert.Empty(store.Value.Criteria); Assert.Same(item2, Assert.Single(store.Value.Matches)); }
public void BuildTree_Empty() { // Arrange var items = new List <Item>(); // Act var tree = DecisionTreeBuilder <Item> .GenerateTree(items, new ItemClassifier()); // Assert Assert.Empty(tree.Criteria); Assert.Empty(tree.Matches); }
public void BuildTree_TrivialMatch() { // Arrange var items = new List <Item>(); var item = new Item(); items.Add(item); // Act var tree = DecisionTreeBuilder <Item> .GenerateTree(items, new ItemClassifier()); // Assert Assert.Empty(tree.Criteria); Assert.Same(item, Assert.Single(tree.Matches)); }
public void BuildTree_WithMultipleCriteria() { // Arrange var items = new List <Item>(); var item = new Item(); item.Criteria.Add("area", new DecisionCriterionValue(value: "Admin")); item.Criteria.Add("controller", new DecisionCriterionValue(value: "Users")); item.Criteria.Add("action", new DecisionCriterionValue(value: "AddUser")); items.Add(item); // Act var tree = DecisionTreeBuilder <Item> .GenerateTree(items, new ItemClassifier()); // Assert Assert.Empty(tree.Matches); var area = Assert.Single(tree.Criteria); Assert.Equal("area", area.Key); var admin = Assert.Single(area.Branches); Assert.Equal("Admin", admin.Key); Assert.Empty(admin.Value.Matches); var controller = Assert.Single(admin.Value.Criteria); Assert.Equal("controller", controller.Key); var users = Assert.Single(controller.Branches); Assert.Equal("Users", users.Key); Assert.Empty(users.Value.Matches); var action = Assert.Single(users.Value.Criteria); Assert.Equal("action", action.Key); var addUser = Assert.Single(action.Branches); Assert.Equal("AddUser", addUser.Key); Assert.Empty(addUser.Value.Criteria); Assert.Same(item, Assert.Single(addUser.Value.Matches)); }
public LinkGenerationDecisionTree(IReadOnlyList <OutboundMatch> entries) { // We split up the entries into: // 1. attribute routes - these go into the tree // 2. conventional routes - these are a list var attributedEntries = new List <OutboundMatch>(); _conventionalEntries = new List <OutboundMatch>(); // Anything with a RoutePattern.RequiredValueAny as a RequiredValue is a conventional route. // This is because RequiredValueAny acts as a wildcard, whereas an attribute route entry // is denormalized to contain an exact set of required values. // // We will only see conventional routes show up here for endpoint routing. for (var i = 0; i < entries.Count; i++) { var isAttributeRoute = true; var entry = entries[i]; foreach (var kvp in entry.Entry.RequiredLinkValues) { if (RoutePattern.IsRequiredValueAny(kvp.Value)) { isAttributeRoute = false; break; } } if (isAttributeRoute) { attributedEntries.Add(entry); } else { _conventionalEntries.Add(entry); } } _root = DecisionTreeBuilder <OutboundMatch> .GenerateTree( attributedEntries, new OutboundMatchClassifier()); }
public LinkGenerationDecisionTree(IReadOnlyList <OutboundMatch> entries) { _root = DecisionTreeBuilder <OutboundMatch> .GenerateTree( entries, new OutboundMatchClassifier()); _knownValues = new Dictionary <string, HashSet <object> >(StringComparer.OrdinalIgnoreCase); for (var i = 0; i < entries.Count; i++) { var entry = entries[i]; foreach (var kvp in entry.Entry.RequiredLinkValues) { if (!_knownValues.TryGetValue(kvp.Key, out var values)) { values = new HashSet <object>(RouteValueEqualityComparer.Default); _knownValues.Add(kvp.Key, values); } values.Add(kvp.Value ?? string.Empty); } } }
public void BuildTree_WithDivergentCriteria() { // Arrange var items = new List <Item>(); var item1 = new Item(); item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store")); item1.Criteria.Add("action", new DecisionCriterionValue(value: "Buy")); items.Add(item1); var item2 = new Item(); item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store")); item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout")); items.Add(item2); var item3 = new Item(); item3.Criteria.Add("stub", new DecisionCriterionValue(value: "Bleh")); items.Add(item3); // Act var tree = DecisionTreeBuilder <Item> .GenerateTree(items, new ItemClassifier()); // Assert Assert.Empty(tree.Matches); var action = tree.Criteria[0]; Assert.Equal("action", action.Key); var stub = tree.Criteria[1]; Assert.Equal("stub", stub.Key); }
public void BuildTree_WithInteriorMatch() { // Arrange var items = new List <Item>(); var item1 = new Item(); item1.Criteria.Add("controller", new DecisionCriterionValue(value: "Store")); item1.Criteria.Add("action", new DecisionCriterionValue(value: "Buy")); items.Add(item1); var item2 = new Item(); item2.Criteria.Add("controller", new DecisionCriterionValue(value: "Store")); item2.Criteria.Add("action", new DecisionCriterionValue(value: "Checkout")); items.Add(item2); var item3 = new Item(); item3.Criteria.Add("action", new DecisionCriterionValue(value: "Buy")); items.Add(item3); // Act var tree = DecisionTreeBuilder <Item> .GenerateTree(items, new ItemClassifier()); // Assert Assert.Empty(tree.Matches); var action = Assert.Single(tree.Criteria); Assert.Equal("action", action.Key); var buy = action.Branches["Buy"]; Assert.Same(item3, Assert.Single(buy.Matches)); }
public LinkGenerationDecisionTree(IReadOnlyList <OutboundMatch> entries) { _root = DecisionTreeBuilder <OutboundMatch> .GenerateTree( entries, new OutboundMatchClassifier()); }
public LinkGenerationDecisionTree(IReadOnlyList <TreeRouteLinkGenerationEntry> entries) { _root = DecisionTreeBuilder <TreeRouteLinkGenerationEntry> .GenerateTree( entries, new AttributeRouteLinkGenerationEntryClassifier()); }