218 lines
7.2 KiB
C#
218 lines
7.2 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.AspNetCore.Routing.DecisionTree
|
|
{
|
|
public class DecisionTreeBuilderTest
|
|
{
|
|
[Fact]
|
|
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);
|
|
}
|
|
|
|
[Fact]
|
|
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));
|
|
}
|
|
|
|
[Fact]
|
|
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));
|
|
}
|
|
|
|
[Fact]
|
|
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));
|
|
}
|
|
|
|
[Fact]
|
|
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));
|
|
}
|
|
|
|
[Fact]
|
|
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);
|
|
}
|
|
|
|
private class Item
|
|
{
|
|
public Item()
|
|
{
|
|
Criteria = new Dictionary<string, DecisionCriterionValue>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
public Dictionary<string, DecisionCriterionValue> Criteria { get; private set; }
|
|
}
|
|
|
|
private class ItemClassifier : IClassifier<Item>
|
|
{
|
|
public IEqualityComparer<object> ValueComparer => RouteValueEqualityComparer.Default;
|
|
|
|
public IDictionary<string, DecisionCriterionValue> GetCriteria(Item item)
|
|
{
|
|
return item.Criteria;
|
|
}
|
|
}
|
|
}
|
|
} |