001 package org.kuali.rice.krms.framework;
002
003 import static junit.framework.Assert.assertFalse;
004 import static junit.framework.Assert.assertNotNull;
005 import static junit.framework.Assert.assertTrue;
006
007 import java.util.Arrays;
008 import java.util.Collection;
009 import java.util.Collections;
010 import java.util.HashMap;
011 import java.util.List;
012 import java.util.Map;
013
014 import org.junit.Before;
015 import org.junit.Test;
016 import org.kuali.rice.krms.api.engine.EngineResults;
017 import org.kuali.rice.krms.api.engine.ExecutionOptions;
018 import org.kuali.rice.krms.api.engine.ExecutionFlag;
019 import org.kuali.rice.krms.api.engine.SelectionCriteria;
020 import org.kuali.rice.krms.api.engine.Term;
021 import org.kuali.rice.krms.api.engine.TermResolver;
022 import org.kuali.rice.krms.api.engine.TermSpecification;
023 import org.kuali.rice.krms.framework.engine.Action;
024 import org.kuali.rice.krms.framework.engine.Agenda;
025 import org.kuali.rice.krms.framework.engine.BasicAgenda;
026 import org.kuali.rice.krms.framework.engine.BasicAgendaTree;
027 import org.kuali.rice.krms.framework.engine.BasicAgendaTreeEntry;
028 import org.kuali.rice.krms.framework.engine.BasicContext;
029 import org.kuali.rice.krms.framework.engine.BasicRule;
030 import org.kuali.rice.krms.framework.engine.CollectionOfComparablesTermBasedProposition;
031 import org.kuali.rice.krms.framework.engine.CollectionOperator;
032 import org.kuali.rice.krms.framework.engine.ComparisonOperator;
033 import org.kuali.rice.krms.framework.engine.Context;
034 import org.kuali.rice.krms.framework.engine.ContextProvider;
035 import org.kuali.rice.krms.framework.engine.Proposition;
036 import org.kuali.rice.krms.framework.engine.ProviderBasedEngine;
037 import org.kuali.rice.krms.framework.engine.ResultLogger;
038 import org.kuali.rice.krms.framework.engine.Rule;
039 import org.kuali.rice.krms.framework.engine.TermResolutionEngineImpl;
040
041 public class CollectionOfComparablesTermBasedPropositionTest {
042 private static final ResultLogger LOG = ResultLogger.getInstance();
043
044
045 @Before
046 public void setUp() {
047 ActionMock.resetActionsFired();
048 }
049
050 @Test
051 public void allPropositionTest() {
052
053 // True cases:
054
055 // this can be read as "for the collection (100, 1000), all elements are greater than 1"
056 assertRuleTrue(Arrays.asList(100f, 1000f), CollectionOperator.ALL, ComparisonOperator.GREATER_THAN, 1f);
057
058 assertRuleTrue(Arrays.asList(100f), CollectionOperator.ALL, ComparisonOperator.GREATER_THAN, 1f);
059 // This can bend the intuition a bit, but this behavior is correct -- see Wikipedia's entry on the empty set
060 assertRuleTrue(Arrays.<Float>asList(), CollectionOperator.ALL, ComparisonOperator.GREATER_THAN, 1f);
061
062 // False cases:
063 assertRuleFalse(Arrays.asList(100f, 1000f), CollectionOperator.ALL, ComparisonOperator.GREATER_THAN, 10000f);
064 assertRuleFalse(Arrays.asList(100f, 1000f), CollectionOperator.ALL, ComparisonOperator.GREATER_THAN, 500f);
065 assertRuleFalse(Arrays.asList(1000f, 100f), CollectionOperator.ALL, ComparisonOperator.GREATER_THAN, 500f);
066 assertRuleFalse(Arrays.asList(100f), CollectionOperator.ALL, ComparisonOperator.GREATER_THAN, 10000f);
067
068 }
069
070 @Test
071 public void oneOrMorePropositionTest() {
072
073 // True cases:
074
075 // this can be read as "for the collection (100, 1000), one or more elements are greater than 500"
076 assertRuleTrue(Arrays.asList(100f, 1000f), CollectionOperator.ONE_OR_MORE, ComparisonOperator.GREATER_THAN, 500f);
077 assertRuleTrue(Arrays.asList(1000f, 100f), CollectionOperator.ONE_OR_MORE, ComparisonOperator.GREATER_THAN, 500f);
078 assertRuleTrue(Arrays.asList(1000f), CollectionOperator.ONE_OR_MORE, ComparisonOperator.GREATER_THAN, 500f);
079
080 // False cases:
081 assertRuleFalse(Arrays.asList(1000f, 2000f), CollectionOperator.ONE_OR_MORE, ComparisonOperator.GREATER_THAN, 5000f);
082 assertRuleFalse(Arrays.asList(2000f, 1000f), CollectionOperator.ONE_OR_MORE, ComparisonOperator.GREATER_THAN, 5000f);
083 assertRuleFalse(Arrays.asList(1000f), CollectionOperator.ONE_OR_MORE, ComparisonOperator.GREATER_THAN, 5000f);
084 assertRuleFalse(Arrays.<Float>asList(), CollectionOperator.ONE_OR_MORE, ComparisonOperator.GREATER_THAN, 5000f);
085
086 }
087
088 @Test
089 public void nonePropositionTest() {
090
091 // True cases:
092
093 // this can be read as "for the collection (100, 1000), none of the elements are greater than 5000"
094 assertRuleTrue(Arrays.asList(100f, 1000f), CollectionOperator.NONE, ComparisonOperator.GREATER_THAN, 5000f);
095 assertRuleTrue(Arrays.asList(1000f), CollectionOperator.NONE, ComparisonOperator.GREATER_THAN, 5000f);
096 assertRuleTrue(Arrays.<Float>asList(), CollectionOperator.NONE, ComparisonOperator.GREATER_THAN, 5000f);
097
098 // False cases:
099 assertRuleFalse(Arrays.asList(1000f, 7000f), CollectionOperator.NONE, ComparisonOperator.GREATER_THAN, 5000f);
100 assertRuleFalse(Arrays.asList(7000f, 1000f), CollectionOperator.NONE, ComparisonOperator.GREATER_THAN, 5000f);
101 assertRuleFalse(Arrays.asList(7000f), CollectionOperator.NONE, ComparisonOperator.GREATER_THAN, 5000f);
102
103 }
104
105 /**
106 * @param agenda
107 */
108 private void execute(Agenda agenda, TermResolver ... termResolvers) {
109 Map<String, String> contextQualifiers = new HashMap<String, String>();
110 contextQualifiers.put("docTypeName", "Proposal");
111
112 List<TermResolver<?>> testResolvers = Arrays.<TermResolver<?>>asList(termResolvers);
113
114 Context context = new BasicContext(Arrays.asList(agenda), testResolvers);
115 ContextProvider contextProvider = new ManualContextProvider(context);
116
117 SelectionCriteria selectionCriteria = SelectionCriteria.createCriteria("test", null, contextQualifiers, Collections.EMPTY_MAP);
118
119 ProviderBasedEngine engine = new ProviderBasedEngine();
120 engine.setContextProvider(contextProvider);
121 engine.setTermResolutionEngine(new TermResolutionEngineImpl());
122
123 // Set execution options to log execution
124 ExecutionOptions executionOptions = new ExecutionOptions().setFlag(ExecutionFlag.LOG_EXECUTION, true);
125
126 LOG.init();
127 EngineResults results = engine.execute(selectionCriteria, new HashMap<Term, Object>(), executionOptions);
128 assertNotNull(results);
129 }
130
131 private void assertRuleTrue(List<Float> termValue,
132 CollectionOperator collectionOper,
133 ComparisonOperator comparisonOper, Float compareValue) {
134 assertRule(termValue, collectionOper, comparisonOper, compareValue, true);
135 }
136
137 private void assertRuleFalse(List<Float> termValue,
138 CollectionOperator collectionOper,
139 ComparisonOperator comparisonOper, Float compareValue) {
140 assertRule(termValue, collectionOper, comparisonOper, compareValue, false);
141 }
142
143 private void assertRule(List<Float> termValue,
144 CollectionOperator collectionOper,
145 ComparisonOperator comparisonOper, Float compareValue, boolean assertTrue) {
146
147 boolean actionFired = executeTestAgenda(termValue, collectionOper, comparisonOper, compareValue).actionFired();
148
149 if (assertTrue) {
150 assertTrue(actionFired);
151 } else {
152 assertFalse(actionFired);
153 }
154
155 ActionMock.resetActionsFired();
156 }
157
158 /**
159 * This method ...
160 *
161 * @param termValue
162 * @param collectionOper
163 * @param comparisonOper
164 * @param compareValue
165 * @return
166 */
167 private ActionMock executeTestAgenda(List<Float> termValue,
168 CollectionOperator collectionOper,
169 ComparisonOperator comparisonOper, Float compareValue) {
170 Term expensesTerm = new Term(new TermSpecification("expenses","Collection<Float>"));
171 TermResolver<Collection<Float>> expensesResolver = new TermResolverMock<Collection<Float>>(expensesTerm.getSpecification(), termValue);
172
173 Proposition prop1 = new CollectionOfComparablesTermBasedProposition(collectionOper, comparisonOper, expensesTerm, compareValue);
174 ActionMock prop1Action = new ActionMock("prop1Action");
175
176 Rule rule = new BasicRule("ALL", prop1, Collections.<Action>singletonList(prop1Action));
177
178 BasicAgendaTree agendaTree = new BasicAgendaTree(new BasicAgendaTreeEntry(rule));
179 Agenda agenda = new BasicAgenda("test", new HashMap<String, String>(), agendaTree);
180
181 execute(agenda, expensesResolver);
182 return prop1Action;
183 }
184
185 }