001: /*
002: * Copyright 2005 JBoss Inc
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.drools.reteoo;
018:
019: import java.util.Collection;
020: import java.util.LinkedList;
021:
022: import junit.framework.Assert;
023:
024: import org.drools.DroolsTestCase;
025: import org.drools.RuleBaseConfiguration;
026: import org.drools.RuleBaseFactory;
027: import org.drools.base.ClassObjectType;
028: import org.drools.common.DefaultFactHandle;
029: import org.drools.common.PropagationContextImpl;
030: import org.drools.rule.Collect;
031: import org.drools.rule.Pattern;
032: import org.drools.rule.Rule;
033: import org.drools.spi.MockConstraint;
034: import org.drools.spi.ObjectType;
035: import org.drools.spi.PropagationContext;
036: import org.drools.spi.Tuple;
037:
038: /**
039: * @author etirelli
040: *
041: */
042: public class CollectNodeTest extends DroolsTestCase {
043: Rule rule;
044: PropagationContext contextAssert;
045: PropagationContext contextRetract;
046: ReteooWorkingMemory workingMemory;
047: MockObjectSource objectSource;
048: MockTupleSource tupleSource;
049: MockTupleSink sink;
050: BetaNode node;
051: BetaMemory memory;
052: MockConstraint constraint = new MockConstraint();
053: Collect collect;
054:
055: /* (non-Javadoc)
056: * @see junit.framework.TestCase#setUp()
057: */
058: protected void setUp() throws Exception {
059: super .setUp();
060: this .rule = new Rule("test-rule");
061: this .contextAssert = new PropagationContextImpl(0,
062: PropagationContext.ASSERTION, null, null);
063: this .contextRetract = new PropagationContextImpl(0,
064: PropagationContext.RETRACTION, null, null);
065: this .workingMemory = new ReteooWorkingMemory(1,
066: (ReteooRuleBase) RuleBaseFactory.newRuleBase());
067:
068: this .tupleSource = new MockTupleSource(4);
069: this .objectSource = new MockObjectSource(4);
070: this .sink = new MockTupleSink();
071:
072: final ObjectType srcObjType = new ClassObjectType(String.class);
073: final Pattern sourcePattern = new Pattern(0, srcObjType);
074: final ObjectType resultObjType = new ClassObjectType(
075: LinkedList.class);
076: final Pattern resultPattern = new Pattern(1, resultObjType);
077: this .collect = new Collect(sourcePattern, resultPattern);
078:
079: this .node = new CollectNode(15, this .tupleSource,
080: this .objectSource, this .collect);
081:
082: this .node.addTupleSink(this .sink);
083:
084: this .memory = (BetaMemory) this .workingMemory
085: .getNodeMemory(this .node);
086:
087: // check memories are empty
088: assertEquals(0, this .memory.getTupleMemory().size());
089: assertEquals(0, this .memory.getFactHandleMemory().size());
090: }
091:
092: /* (non-Javadoc)
093: * @see junit.framework.TestCase#tearDown()
094: */
095: protected void tearDown() throws Exception {
096: super .tearDown();
097: }
098:
099: public void testUpdateNewNode() {
100: this .node.updateSink(this .sink, this .contextAssert,
101: this .workingMemory);
102: Assert.assertEquals("No tuple should be propagated", 0,
103: this .sink.getAsserted().size());
104:
105: this .node.assertTuple(new ReteTuple(this .workingMemory
106: .getFactHandleFactory().newFactHandle("cheese")),
107: this .contextAssert, this .workingMemory);
108: this .node.assertTuple(new ReteTuple(this .workingMemory
109: .getFactHandleFactory().newFactHandle("other cheese")),
110: this .contextAssert, this .workingMemory);
111:
112: Assert.assertEquals("Two tuples should have been propagated",
113: 2, this .sink.getAsserted().size());
114:
115: final MockTupleSink otherSink = new MockTupleSink();
116:
117: this .node.addTupleSink(otherSink);
118: this .node.updateSink(otherSink, this .contextAssert,
119: this .workingMemory);
120:
121: Assert.assertEquals("Two tuples should have been propagated",
122: 2, otherSink.getAsserted().size());
123: }
124:
125: public void testAssertTuple() {
126: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
127: .getFactHandleFactory().newFactHandle("cheese");
128: final ReteTuple tuple0 = new ReteTuple(f0);
129:
130: // assert tuple, should add one to left memory
131: this .node.assertTuple(tuple0, this .contextAssert,
132: this .workingMemory);
133: // check memories
134: assertEquals(1, this .memory.getTupleMemory().size());
135: assertEquals(0, this .memory.getFactHandleMemory().size());
136: Assert
137: .assertTrue(
138: "An empty collection should be propagated",
139: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
140: .getAsserted().get(0))[0]).get(1))
141: .getObject()).isEmpty());
142:
143: // assert tuple, should add left memory
144: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
145: .getFactHandleFactory().newFactHandle("other cheese");
146:
147: final ReteTuple tuple1 = new ReteTuple(f1);
148: this .node.assertTuple(tuple1, this .contextAssert,
149: this .workingMemory);
150: assertEquals(2, this .memory.getTupleMemory().size());
151: Assert
152: .assertTrue(
153: "An empty collection should be propagated",
154: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
155: .getAsserted().get(1))[0]).get(1))
156: .getObject()).isEmpty());
157:
158: assertTrue(this .memory.getTupleMemory().contains(tuple0));
159: assertTrue(this .memory.getTupleMemory().contains(tuple1));
160:
161: Assert.assertEquals("Two tuples should have been propagated",
162: 2, this .sink.getAsserted().size());
163: }
164:
165: public void testAssertTupleWithObjects() {
166: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
167: .getFactHandleFactory().newFactHandle("cheese");
168: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
169: .getFactHandleFactory().newFactHandle("other cheese");
170:
171: final ReteTuple tuple0 = new ReteTuple(f0);
172:
173: this .node.assertObject(f0, this .contextAssert,
174: this .workingMemory);
175: this .node.assertObject(f1, this .contextAssert,
176: this .workingMemory);
177:
178: // assert tuple, should add one to left memory
179: this .node.assertTuple(tuple0, this .contextAssert,
180: this .workingMemory);
181: // check memories
182: assertEquals(1, this .memory.getTupleMemory().size());
183: assertEquals(2, this .memory.getFactHandleMemory().size());
184: Assert
185: .assertEquals(
186: "Wrong number of elements in matching objects list ",
187: 2,
188: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
189: .getAsserted().get(0))[0]).get(1))
190: .getObject()).size());
191:
192: // assert tuple, should add left memory
193: final ReteTuple tuple1 = new ReteTuple(f1);
194: this .node.assertTuple(tuple1, this .contextAssert,
195: this .workingMemory);
196: assertEquals(2, this .memory.getTupleMemory().size());
197: Assert
198: .assertEquals(
199: "Wrong number of elements in matching objects list ",
200: 2,
201: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
202: .getAsserted().get(1))[0]).get(1))
203: .getObject()).size());
204:
205: assertTrue(this .memory.getTupleMemory().contains(tuple0));
206: assertTrue(this .memory.getTupleMemory().contains(tuple1));
207:
208: Assert.assertEquals("Two tuples should have been propagated",
209: 2, this .sink.getAsserted().size());
210: }
211:
212: public void testRetractTuple() {
213: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
214: .getFactHandleFactory().newFactHandle("cheese");
215:
216: final ReteTuple tuple0 = new ReteTuple(f0);
217:
218: // assert tuple, should add one to left memory
219: this .node.assertTuple(tuple0, this .contextAssert,
220: this .workingMemory);
221: // check memories
222: assertEquals(1, this .memory.getTupleMemory().size());
223: assertEquals(0, this .memory.getFactHandleMemory().size());
224: Assert
225: .assertTrue(
226: "An empty collection should be propagated",
227: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
228: .getAsserted().get(0))[0]).get(1))
229: .getObject()).isEmpty());
230:
231: this .node.retractTuple(tuple0, this .contextRetract,
232: this .workingMemory);
233: assertEquals(0, this .memory.getTupleMemory().size());
234: assertEquals(1, this .sink.getRetracted().size());
235: assertEquals(1, this .sink.getAsserted().size());
236: }
237:
238: public void testAssertObject() {
239: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
240: .getFactHandleFactory().newFactHandle("cheese");
241: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
242: .getFactHandleFactory().newFactHandle("other cheese");
243:
244: final ReteTuple tuple0 = new ReteTuple(f0);
245:
246: // assert tuple, should add one to left memory
247: this .node.assertTuple(tuple0, this .contextAssert,
248: this .workingMemory);
249:
250: // check memory
251: assertEquals(1, this .memory.getTupleMemory().size());
252: assertEquals(1, this .sink.getAsserted().size());
253: Assert
254: .assertTrue(
255: "An empty collection should be propagated",
256: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
257: .getAsserted().get(0))[0]).get(1))
258: .getObject()).isEmpty());
259:
260: this .node.assertObject(f0, this .contextAssert,
261: this .workingMemory);
262: assertEquals(1, this .memory.getFactHandleMemory().size());
263: assertEquals(2, this .sink.getAsserted().size());
264: Assert
265: .assertEquals(
266: "Wrong number of elements in matching objects list ",
267: 1,
268: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
269: .getAsserted().get(1))[0]).get(1))
270: .getObject()).size());
271:
272: this .node.assertObject(f1, this .contextAssert,
273: this .workingMemory);
274:
275: assertEquals(2, this .memory.getFactHandleMemory().size());
276: assertEquals(3, this .sink.getAsserted().size());
277: Assert
278: .assertEquals(
279: "Wrong number of elements in matching objects list ",
280: 2,
281: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
282: .getAsserted().get(2))[0]).get(1))
283: .getObject()).size());
284:
285: }
286:
287: public void testRetractObject() {
288: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
289: .getFactHandleFactory().newFactHandle("cheese");
290: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
291: .getFactHandleFactory().newFactHandle("other cheese");
292:
293: final ReteTuple tuple0 = new ReteTuple(f0);
294:
295: this .node.assertObject(f0, this .contextAssert,
296: this .workingMemory);
297: this .node.assertObject(f1, this .contextAssert,
298: this .workingMemory);
299: assertEquals(2, this .memory.getFactHandleMemory().size());
300:
301: // assert tuple, should add one to left memory
302: this .node.assertTuple(tuple0, this .contextAssert,
303: this .workingMemory);
304:
305: // check memory
306: assertEquals(1, this .memory.getTupleMemory().size());
307: assertEquals(0, this .sink.getRetracted().size());
308: assertEquals(1, this .sink.getAsserted().size());
309: Assert
310: .assertEquals(
311: "Wrong number of elements in matching objects list ",
312: 2,
313: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
314: .getAsserted().get(0))[0]).get(1))
315: .getObject()).size());
316:
317: this .node.retractObject(f1, this .contextRetract,
318: this .workingMemory);
319: assertEquals(1, this .memory.getFactHandleMemory().size());
320: assertEquals(1, this .sink.getRetracted().size());
321: assertEquals(2, this .sink.getAsserted().size());
322: Assert
323: .assertEquals(
324: "Wrong number of elements in matching objects list ",
325: 1,
326: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
327: .getAsserted().get(1))[0]).get(1))
328: .getObject()).size());
329:
330: this .node.retractObject(f0, this .contextRetract,
331: this .workingMemory);
332: assertEquals(0, this .memory.getFactHandleMemory().size());
333: assertEquals(2, this .sink.getRetracted().size());
334: assertEquals(3, this .sink.getAsserted().size());
335: Assert
336: .assertEquals(
337: "Wrong number of elements in matching objects list ",
338: 0,
339: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
340: .getAsserted().get(2))[0]).get(1))
341: .getObject()).size());
342:
343: }
344:
345: public void testMemory() {
346: final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory(
347: 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase());
348:
349: final MockObjectSource objectSource = new MockObjectSource(1);
350: final MockTupleSource tupleSource = new MockTupleSource(1);
351:
352: final CollectNode collectNode = new CollectNode(2, tupleSource,
353: objectSource, this .collect);
354:
355: final BetaMemory memory = (BetaMemory) workingMemory
356: .getNodeMemory(collectNode);
357:
358: assertNotNull(memory);
359: }
360:
361: public void testAssertTupleSequentialMode() {
362: RuleBaseConfiguration conf = new RuleBaseConfiguration();
363: conf.setSequential(true);
364:
365: this .workingMemory = new ReteooWorkingMemory(1,
366: (ReteooRuleBase) RuleBaseFactory.newRuleBase(conf));
367:
368: this .memory = (BetaMemory) this .workingMemory
369: .getNodeMemory(this .node);
370:
371: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
372: .getFactHandleFactory().newFactHandle("cheese");
373: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
374: .getFactHandleFactory().newFactHandle("other cheese");
375:
376: final ReteTuple tuple0 = new ReteTuple(f0);
377:
378: this .node.assertObject(f0, this .contextAssert,
379: this .workingMemory);
380: this .node.assertObject(f1, this .contextAssert,
381: this .workingMemory);
382:
383: // assert tuple, should not add to left memory, since we are in sequential mode
384: this .node.assertTuple(tuple0, this .contextAssert,
385: this .workingMemory);
386: // check memories
387: assertNull(this .memory.getTupleMemory());
388: assertEquals(2, this .memory.getFactHandleMemory().size());
389: Assert
390: .assertEquals(
391: "Wrong number of elements in matching objects list ",
392: 2,
393: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
394: .getAsserted().get(0))[0]).get(1))
395: .getObject()).size());
396:
397: // assert tuple, should not add to left memory, since we are in sequential mode
398: final ReteTuple tuple1 = new ReteTuple(f1);
399: this .node.assertTuple(tuple1, this .contextAssert,
400: this .workingMemory);
401: assertNull(this .memory.getTupleMemory());
402: Assert
403: .assertEquals(
404: "Wrong number of elements in matching objects list ",
405: 2,
406: ((Collection) ((DefaultFactHandle) ((Tuple) ((Object[]) this .sink
407: .getAsserted().get(1))[0]).get(1))
408: .getObject()).size());
409:
410: Assert.assertEquals("Two tuples should have been propagated",
411: 2, this.sink.getAsserted().size());
412: }
413:
414: }
|