package com.blazebit.ai.decisiontree; import com.blazebit.ai.decisiontree.impl.NoopDecisionTree; import com.blazebit.ai.decisiontree.impl.SimpleAttributeSelector; import com.blazebit.ai.decisiontree.impl.SimpleAttributeValue; import com.blazebit.ai.decisiontree.impl.SimpleDecisionTree; import com.blazebit.ai.decisiontree.impl.SimpleDiscreteAttribute; import com.blazebit.ai.decisiontree.impl.SimpleExample; import com.blazebit.ai.decisiontree.impl.SimpleItem; import com.blazebit.collection.PatternTrie; import com.blazebit.collection.PatternTrie.ParameterizedValue; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.junit.Test; /** * * @author Christian Beikov */ public class PatternTrieDecisionTreeTest { interface Action { String getValue(Object... params); } class PathAction implements Action { final String value; public PathAction(String value) { this.value = value; } public String getValue(Object... params){ if(params == null){ return value; } StringBuilder sb = new StringBuilder(); sb.append(value); for(Object param : params) { sb.append('/').append(param); } return sb.toString(); } } @Test public void testCreate() { /* Split conditions like when(condition1).and(condition2).or(condition3) into * two examples, one is when(condition1).and(condition2) and the second is * when(condition3). This needs to be done since decision tree can only handle */ PatternTrie<DecisionTree<Action>> trie = new PatternTrie<DecisionTree<Action>>(); Set<ParameterizedValue<DecisionTree<Action>>> results; ParameterizedValue<DecisionTree<Action>> parameterizedResult; DecisionTree<Action> decisionTreeResult; Action actionResult; Set<Attribute> attributes; Set<AttributeValue> attributeValues; Set<Example<Action>> examples; Map<Attribute, AttributeValue> values; /* Simple test */ trie.add("/home", new NoopDecisionTree<Action>(new PathAction("/home"))); results = trie.resolve("/home"); assertEquals(1, results.size()); parameterizedResult = results.iterator().next(); assertEquals(0, parameterizedResult.getParameterNames().size()); decisionTreeResult = parameterizedResult.getValue(); assertNotNull(decisionTreeResult); actionResult = decisionTreeResult.applySingle(null); assertNotNull(actionResult); assertEquals("/home", actionResult.getValue()); /* Another simple test but with possible conflict with other rule */ trie.add("/projects", new NoopDecisionTree<Action>(new PathAction("/projects"))); results = trie.resolve("/projects"); assertEquals(1, results.size()); parameterizedResult = results.iterator().next(); assertEquals(0, parameterizedResult.getParameterNames().size()); decisionTreeResult = parameterizedResult.getValue(); assertNotNull(decisionTreeResult); actionResult = decisionTreeResult.applySingle(null); assertNotNull(actionResult); assertEquals("/projects", actionResult.getValue()); /* Another simple test */ trie.add("/about", new NoopDecisionTree<Action>(new PathAction("/about"))); results = trie.resolve("/about"); assertEquals(1, results.size()); parameterizedResult = results.iterator().next(); assertEquals(0, parameterizedResult.getParameterNames().size()); decisionTreeResult = parameterizedResult.getValue(); assertNotNull(decisionTreeResult); actionResult = decisionTreeResult.applySingle(null); assertNotNull(actionResult); assertEquals("/about", actionResult.getValue()); /* Trie only test */ trie.parameterized("/project/{projectName}", new NoopDecisionTree<Action>(new PathAction("/project"))) .matching("projectName", ".+") .add(); results = trie.resolve("/project/my-first-project"); assertEquals(1, results.size()); parameterizedResult = results.iterator().next(); assertEquals(1, parameterizedResult.getParameterNames().size()); decisionTreeResult = parameterizedResult.getValue(); assertNotNull(decisionTreeResult); actionResult = decisionTreeResult.applySingle(null); assertNotNull(actionResult); assertEquals("/project/my-first-project", actionResult.getValue(parameterizedResult.getParameter("projectName"))); /* Trie plus decision tree test */ attributes = new HashSet<Attribute>(); attributeValues = new HashSet<AttributeValue>(); attributeValues.add(new SimpleAttributeValue("http")); attributeValues.add(new SimpleAttributeValue("https")); attributes.add(new SimpleDiscreteAttribute("protocol", attributeValues)); examples = new HashSet<Example<Action>>(); values = new HashMap<Attribute, AttributeValue>(); values.put(attributes.iterator().next(), new SimpleAttributeValue("https")); examples.add(new SimpleExample<Action>(values, new PathAction("/news"))); decisionTreeResult = new SimpleDecisionTree<Action>(attributes, examples, new SimpleAttributeSelector<Action>()); trie.parameterized("/news/{newsTitle}", decisionTreeResult) .matching("newsTitle", ".+") .add(); results = trie.resolve("/news/my-first-entry"); assertEquals(1, results.size()); parameterizedResult = results.iterator().next(); assertEquals(1, parameterizedResult.getParameterNames().size()); decisionTreeResult = parameterizedResult.getValue(); assertNotNull(decisionTreeResult); actionResult = decisionTreeResult.applySingle(new SimpleItem(values)); assertNotNull(actionResult); assertEquals("/news/my-first-entry", actionResult.getValue(parameterizedResult.getParameter("newsTitle"))); } }