001: package org.drools.brms.server.util;
002:
003: import junit.framework.TestCase;
004:
005: import org.drools.brms.client.modeldriven.SuggestionCompletionEngine;
006: import org.drools.brms.client.modeldriven.brl.ActionFieldValue;
007: import org.drools.brms.client.modeldriven.brl.ActionInsertFact;
008: import org.drools.brms.client.modeldriven.brl.ActionInsertLogicalFact;
009: import org.drools.brms.client.modeldriven.brl.ActionRetractFact;
010: import org.drools.brms.client.modeldriven.brl.ActionUpdateField;
011: import org.drools.brms.client.modeldriven.brl.CompositeFactPattern;
012: import org.drools.brms.client.modeldriven.brl.CompositeFieldConstraint;
013: import org.drools.brms.client.modeldriven.brl.ConnectiveConstraint;
014: import org.drools.brms.client.modeldriven.brl.DSLSentence;
015: import org.drools.brms.client.modeldriven.brl.FactPattern;
016: import org.drools.brms.client.modeldriven.brl.ISingleFieldConstraint;
017: import org.drools.brms.client.modeldriven.brl.RuleAttribute;
018: import org.drools.brms.client.modeldriven.brl.RuleModel;
019: import org.drools.brms.client.modeldriven.brl.SingleFieldConstraint;
020:
021: public class BRDRLPersistenceTest extends TestCase {
022:
023: private BRLPersistence p;
024:
025: protected void setUp() throws Exception {
026: super .setUp();
027: p = BRDRLPersistence.getInstance();
028: }
029:
030: public void testGenerateEmptyDRL() {
031: String expected = "rule \"null\"\n\tdialect \"mvel\"\n\twhen\n\tthen\nend\n";
032:
033: final String drl = p.marshal(new RuleModel());
034:
035: assertNotNull(drl);
036: assertEquals(expected, drl);
037: }
038:
039: public void testBasics() {
040: String expected = "rule \"my rule\"\n\tno-loop true\n\tdialect \"mvel\"\n\twhen\n\t\tPerson( )\n"
041: + "\t\tAccident( )\n\tthen\n\t\tinsert( new Report() );\nend\n";
042: final RuleModel m = new RuleModel();
043: m.addLhsItem(new FactPattern("Person"));
044: m.addLhsItem(new FactPattern("Accident"));
045: m.addAttribute(new RuleAttribute("no-loop", "true"));
046:
047: m.addRhsItem(new ActionInsertFact("Report"));
048: m.name = "my rule";
049:
050: final String drl = p.marshal(m);
051: assertEquals(expected, drl);
052: }
053:
054: public void testMoreComplexRendering() {
055: final RuleModel m = getComplexModel();
056: String expected = "rule \"Complex Rule\"\n"
057: + "\tno-loop true\n" + "\tsalience -10\n"
058: + "\tagenda-group \"aGroup\"\n"
059: + "\tdialect \"mvel\"\n" + "\twhen\n"
060: + "\t\t>p1 : Person( f1 : age < 42 )\n"
061: + "\t\t>not Cancel( )\n" + "\tthen\n"
062: + "\t\t>p1.setStatus( \"rejected\" );\n"
063: + "\t\t>update( p1 );\n" + "\t\t>retract( p1 );\n"
064: + "\t\tSend an email to administrator\n" + "end\n";
065:
066: final String drl = p.marshal(m);
067:
068: assertEquals(expected, drl);
069:
070: }
071:
072: public void testFieldBindingWithNoConstraints() {
073: //to satisfy JBRULES-850
074: RuleModel m = getModelWithNoConstraints();
075: String s = BRDRLPersistence.getInstance().marshal(m);
076: //System.out.println(s);
077: assertTrue(s.indexOf("Person( f1 : age)") != -1);
078: }
079:
080: //
081: // public void testRoundTrip() {
082: // final RuleModel m = getComplexModel();
083: //
084: // final String xml = BRXMLPersistence.getInstance().marshal( m );
085: //
086: // final RuleModel m2 = BRXMLPersistence.getInstance().unmarshal( xml );
087: // assertNotNull( m2 );
088: // assertEquals( m.name,
089: // m2.name );
090: // assertEquals( m.lhs.length,
091: // m2.lhs.length );
092: // assertEquals( m.rhs.length,
093: // m2.rhs.length );
094: // assertEquals( 1,
095: // m.attributes.length );
096: //
097: // final RuleAttribute at = m.attributes[0];
098: // assertEquals( "no-loop",
099: // at.attributeName );
100: // assertEquals( "true",
101: // at.value );
102: //
103: // final String newXML = BRXMLPersistence.getInstance().marshal( m2 );
104: // assertEquals( xml,
105: // newXML );
106: //
107: // }
108: //
109:
110: private RuleModel getModelWithNoConstraints() {
111: final RuleModel m = new RuleModel();
112: m.name = "Complex Rule";
113: final FactPattern pat = new FactPattern();
114: pat.boundName = "p1";
115: pat.factType = "Person";
116: final SingleFieldConstraint con = new SingleFieldConstraint();
117: con.fieldBinding = "f1";
118: con.fieldName = "age";
119: // con.operator = "<";
120: // con.value = "42";
121: pat.addConstraint(con);
122:
123: m.addLhsItem(pat);
124:
125: return m;
126: }
127:
128: private RuleModel getComplexModel() {
129: final RuleModel m = new RuleModel();
130: m.name = "Complex Rule";
131:
132: m.addAttribute(new RuleAttribute("no-loop", "true"));
133: m.addAttribute(new RuleAttribute("salience", "-10"));
134: m.addAttribute(new RuleAttribute("agenda-group", "aGroup"));
135:
136: final FactPattern pat = new FactPattern();
137: pat.boundName = "p1";
138: pat.factType = "Person";
139: final SingleFieldConstraint con = new SingleFieldConstraint();
140: con.fieldBinding = "f1";
141: con.fieldName = "age";
142: con.operator = "<";
143: con.value = "42";
144: pat.addConstraint(con);
145:
146: m.addLhsItem(pat);
147:
148: final CompositeFactPattern comp = new CompositeFactPattern(
149: "not");
150: comp.addFactPattern(new FactPattern("Cancel"));
151: m.addLhsItem(comp);
152:
153: final ActionUpdateField set = new ActionUpdateField();
154: set.variable = "p1";
155: set.addFieldValue(new ActionFieldValue("status", "rejected",
156: SuggestionCompletionEngine.TYPE_STRING));
157: m.addRhsItem(set);
158:
159: final ActionRetractFact ret = new ActionRetractFact("p1");
160: m.addRhsItem(ret);
161:
162: final DSLSentence sen = new DSLSentence();
163: sen.sentence = "Send an email to {administrator}";
164:
165: m.addRhsItem(sen);
166: return m;
167: }
168:
169: // public void testLoadEmpty() {
170: // RuleModel m = BRXMLPersistence.getInstance().unmarshal( null );
171: // assertNotNull( m );
172: //
173: // m = BRXMLPersistence.getInstance().unmarshal( "" );
174: // assertNotNull( m );
175: // }
176:
177: public void testCompositeConstraints() {
178: RuleModel m = new RuleModel();
179: m.name = "with composite";
180:
181: FactPattern p1 = new FactPattern("Person");
182: p1.boundName = "p1";
183: m.addLhsItem(p1);
184:
185: FactPattern p = new FactPattern("Goober");
186: m.addLhsItem(p);
187: CompositeFieldConstraint comp = new CompositeFieldConstraint();
188: comp.compositeJunctionType = CompositeFieldConstraint.COMPOSITE_TYPE_OR;
189: p.addConstraint(comp);
190:
191: final SingleFieldConstraint X = new SingleFieldConstraint();
192: X.fieldName = "goo";
193: X.constraintValueType = SingleFieldConstraint.TYPE_LITERAL;
194: X.value = "foo";
195: X.operator = "==";
196: X.connectives = new ConnectiveConstraint[1];
197: X.connectives[0] = new ConnectiveConstraint();
198: X.connectives[0].constraintValueType = ConnectiveConstraint.TYPE_LITERAL;
199: X.connectives[0].operator = "|| ==";
200: X.connectives[0].value = "bar";
201: comp.addConstraint(X);
202:
203: final SingleFieldConstraint Y = new SingleFieldConstraint();
204: Y.fieldName = "goo2";
205: Y.constraintValueType = SingleFieldConstraint.TYPE_LITERAL;
206: Y.value = "foo";
207: Y.operator = "==";
208: comp.addConstraint(Y);
209:
210: CompositeFieldConstraint comp2 = new CompositeFieldConstraint();
211: comp2.compositeJunctionType = CompositeFieldConstraint.COMPOSITE_TYPE_AND;
212: final SingleFieldConstraint Q1 = new SingleFieldConstraint();
213: Q1.fieldName = "goo";
214: Q1.operator = "==";
215: Q1.value = "whee";
216: Q1.constraintValueType = ISingleFieldConstraint.TYPE_LITERAL;
217:
218: comp2.addConstraint(Q1);
219:
220: final SingleFieldConstraint Q2 = new SingleFieldConstraint();
221: Q2.fieldName = "gabba";
222: Q2.operator = "==";
223: Q2.value = "whee";
224: Q2.constraintValueType = ISingleFieldConstraint.TYPE_LITERAL;
225:
226: comp2.addConstraint(Q2);
227:
228: //now nest it
229: comp.addConstraint(comp2);
230:
231: final SingleFieldConstraint Z = new SingleFieldConstraint();
232: Z.fieldName = "goo3";
233: Z.constraintValueType = SingleFieldConstraint.TYPE_LITERAL;
234: Z.value = "foo";
235: Z.operator = "==";
236:
237: p.addConstraint(Z);
238:
239: ActionInsertFact ass = new ActionInsertFact("Whee");
240: m.addRhsItem(ass);
241:
242: String actual = BRDRLPersistence.getInstance().marshal(m);
243: String expected = "rule \"with composite\" "
244: + " \tdialect \"mvel\"\n when "
245: + "p1 : Person( ) "
246: + "Goober( goo == \"foo\" || == \"bar\" || goo2 == \"foo\" || ( goo == \"whee\" && gabba == \"whee\" ), goo3 == \"foo\" )"
247: + " then " + "insert( new Whee() );" + "end";
248: assertEqualsIgnoreWhitespace(expected, actual);
249:
250: }
251:
252: public void testFieldsDeclaredButNoConstraints() {
253: RuleModel m = new RuleModel();
254: m.name = "boo";
255:
256: FactPattern p = new FactPattern();
257: p.factType = "Person";
258:
259: //this isn't an effective constraint, so it should be ignored.
260: p.addConstraint(new SingleFieldConstraint("field1"));
261:
262: m.addLhsItem(p);
263:
264: String actual = BRDRLPersistence.getInstance().marshal(m);
265:
266: String expected = "rule \"boo\" \tdialect \"mvel\"\n when Person() then end";
267:
268: assertEqualsIgnoreWhitespace(expected, actual);
269:
270: SingleFieldConstraint con = (SingleFieldConstraint) p.constraintList.constraints[0];
271: con.fieldBinding = "q";
272:
273: //now it should appear, as we are binding a var to it
274:
275: actual = BRDRLPersistence.getInstance().marshal(m);
276:
277: expected = "rule \"boo\" dialect \"mvel\" when Person(q : field1) then end";
278:
279: assertEqualsIgnoreWhitespace(expected, actual);
280:
281: }
282:
283: public void testLiteralStrings() {
284:
285: RuleModel m = new RuleModel();
286: m.name = "test literal strings";
287:
288: FactPattern p = new FactPattern("Person");
289: SingleFieldConstraint con = new SingleFieldConstraint();
290: con.fieldName = "field1";
291: con.operator = "==";
292: con.value = "goo";
293: con.constraintValueType = SingleFieldConstraint.TYPE_LITERAL;
294: p.addConstraint(con);
295:
296: SingleFieldConstraint con2 = new SingleFieldConstraint();
297: con2.fieldName = "field2";
298: con2.operator = "==";
299: con2.value = "variableHere";
300: con2.constraintValueType = SingleFieldConstraint.TYPE_VARIABLE;
301: p.addConstraint(con2);
302:
303: m.addLhsItem(p);
304:
305: String result = BRDRLPersistence.getInstance().marshal(m);
306:
307: assertEqualsIgnoreWhitespace(
308: "rule \"test literal strings\""
309: + "\tdialect \"mvel\"\n when "
310: + " Person(field1 == \"goo\", field2 == variableHere)"
311: + " then " + "end", result);
312:
313: }
314:
315: private void assertEqualsIgnoreWhitespace(final String expected,
316: final String actual) {
317: final String cleanExpected = expected.replaceAll("\\s+", "");
318: final String cleanActual = actual.replaceAll("\\s+", "");
319:
320: assertEquals(cleanExpected, cleanActual);
321: }
322:
323: public void testReturnValueConstraint() {
324: RuleModel m = new RuleModel();
325: m.name = "yeah";
326:
327: FactPattern p = new FactPattern();
328:
329: SingleFieldConstraint con = new SingleFieldConstraint();
330: con.constraintValueType = SingleFieldConstraint.TYPE_RET_VALUE;
331: con.value = "someFunc(x)";
332: con.operator = "==";
333: con.fieldName = "goo";
334: p.factType = "Goober";
335:
336: p.addConstraint(con);
337: m.addLhsItem(p);
338:
339: String actual = BRDRLPersistence.getInstance().marshal(m);
340: //System.err.println(actual);
341:
342: String expected = "rule \"yeah\" "
343: + "\tdialect \"mvel\"\n when "
344: + "Goober( goo == ( someFunc(x) ) )" + " then " + "end";
345: assertEqualsIgnoreWhitespace(expected, actual);
346: }
347:
348: public void testConnective() {
349:
350: RuleModel m = new RuleModel();
351: m.name = "test literal strings";
352:
353: FactPattern p = new FactPattern("Person");
354: SingleFieldConstraint con = new SingleFieldConstraint();
355: con.fieldName = "field1";
356: con.operator = "==";
357: con.value = "goo";
358: con.constraintValueType = SingleFieldConstraint.TYPE_VARIABLE;
359: p.addConstraint(con);
360:
361: ConnectiveConstraint connective = new ConnectiveConstraint();
362: connective.constraintValueType = ISingleFieldConstraint.TYPE_LITERAL;
363: connective.operator = "|| ==";
364: connective.value = "blah";
365:
366: con.connectives = new ConnectiveConstraint[1];
367: con.connectives[0] = connective;
368:
369: m.addLhsItem(p);
370:
371: String result = BRDRLPersistence.getInstance().marshal(m);
372:
373: String expected = "rule \"test literal strings\" "
374: + "\tdialect \"mvel\"\n when "
375: + "Person( field1 == goo || == \"blah\" )" + " then "
376: + "end";
377: assertEqualsIgnoreWhitespace(expected, result);
378:
379: }
380:
381: public void testInvalidComposite() throws Exception {
382: RuleModel m = new RuleModel();
383: CompositeFactPattern com = new CompositeFactPattern("not");
384: m.addLhsItem(com);
385:
386: String s = BRDRLPersistence.getInstance().marshal(m);
387: assertNotNull(s);
388:
389: m.addLhsItem(new CompositeFactPattern("or"));
390: m.addLhsItem(new CompositeFactPattern("exists"));
391: s = BRDRLPersistence.getInstance().marshal(m);
392: assertNotNull(s);
393: }
394:
395: public void testAssertWithDSL() throws Exception {
396: RuleModel m = new RuleModel();
397: DSLSentence sen = new DSLSentence();
398: sen.sentence = "I CAN HAS DSL";
399: m.addRhsItem(sen);
400: ActionInsertFact ins = new ActionInsertFact("Shizzle");
401: ActionFieldValue val = new ActionFieldValue("goo", "42",
402: "Numeric");
403: ins.fieldValues = new ActionFieldValue[1];
404: ins.fieldValues[0] = val;
405: m.addRhsItem(ins);
406:
407: ActionInsertLogicalFact insL = new ActionInsertLogicalFact(
408: "Shizzle");
409: ActionFieldValue valL = new ActionFieldValue("goo", "42",
410: "Numeric");
411: insL.fieldValues = new ActionFieldValue[1];
412: insL.fieldValues[0] = valL;
413: m.addRhsItem(insL);
414:
415: String result = BRDRLPersistence.getInstance().marshal(m);
416: assertTrue(result.indexOf(">insert") > -1);
417: System.err.println(result);
418: assertTrue(result.indexOf(">insertLogical") > -1);
419: }
420:
421: public void testDefaultMVEL() {
422: RuleModel m = new RuleModel();
423:
424: String s = BRDRLPersistence.getInstance().marshal(m);
425: assertTrue(s.indexOf("mvel") > -1);
426:
427: m.addAttribute(new RuleAttribute("dialect", "goober"));
428: s = BRDRLPersistence.getInstance().marshal(m);
429: assertFalse(s.indexOf("mvel") > -1);
430: assertTrue(s.indexOf("goober") > -1);
431:
432: }
433:
434: }
|