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 }