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    }