001: package org.mvel.tests.main;
002:
003: import junit.framework.TestCase;
004: import org.mvel.Interpreter;
005: import org.mvel.MVEL;
006: import org.mvel.tests.main.res.Bar;
007: import org.mvel.tests.main.res.Base;
008: import org.mvel.tests.main.res.Foo;
009: import org.mvel.tests.main.res.PDFFieldUtil;
010: import org.mvel.util.FastList;
011:
012: import java.io.Serializable;
013: import java.util.Calendar;
014: import java.util.HashMap;
015: import java.util.Map;
016:
017: public class ParserUnitTest extends TestCase {
018:
019: Foo foo = new Foo();
020: Map<String, Object> map = new HashMap<String, Object>();
021: Base base = new Base();
022:
023: public ParserUnitTest() {
024: foo.setBar(new Bar());
025: map.put("foo", foo);
026: map.put("a", null);
027: map.put("b", null);
028: map.put("c", "cat");
029: map.put("BWAH", "");
030:
031: // map.put("misc", new MiscTestClass());
032:
033: map.put("pi", "3.14");
034: map.put("hour", "60");
035: map.put("zero", 0);
036:
037: map.put("doubleTen", new Double(10));
038:
039: map.put("variable_with_underscore", "HELLO");
040:
041: map.put("testImpl", new TestInterface() {
042:
043: public String getName() {
044: return "FOOBAR!";
045: }
046:
047: public boolean isFoo() {
048: return true;
049: }
050: });
051:
052: }
053:
054: public static interface TestInterface {
055: public String getName();
056:
057: public boolean isFoo();
058: }
059:
060: public void testPassThru() {
061: assertEquals("poopy", parse("poopy"));
062: }
063:
064: public void testPassThru2() {
065: assertEquals("foo@bar.com", Interpreter
066: .eval("foo@bar.com", map));
067: }
068:
069: public void testMethodOnValue() {
070: assertEquals("DOG", parse("@{foo.bar.name.toUpperCase()}"));
071: }
072:
073: public void testSimpleProperty() {
074: assertEquals("dog", parse("@{foo.bar.name}"));
075: }
076:
077: public void testThroughInterface() {
078: assertEquals("FOOBAR!", parseDirect("testImpl.name"));
079: }
080:
081: public void testBooleanOperator() {
082: assertEquals(true, parse("@{foo.bar.woof == true}"));
083: }
084:
085: public void testBooleanOperator2() {
086: assertEquals(false, parse("@{foo.bar.woof == false}"));
087: }
088:
089: public void testTextComparison() {
090: assertEquals(true, parse("@{foo.bar.name == 'dog'}"));
091: }
092:
093: public void testNETextComparison() {
094: assertEquals(true, parse("@{foo.bar.name != 'foo'}"));
095: }
096:
097: public void testTextComparison2() {
098: assertEquals(false, parseDirect("null == foo.bar.name"));
099: }
100:
101: public void testNENumbers() {
102: assertEquals(true, parseDirect("10 != 9"));
103: }
104:
105: public void testNENumbers2() {
106: assertEquals(true, parseDirect("10 != null"));
107: }
108:
109: public void testNENumbers3() {
110: assertEquals(true, parseDirect("null != 10"));
111: }
112:
113: public void testShortPathExpression() {
114: assertEquals(null,
115: parseDirect("3 > 4 && foo.toUC('test'); foo.register"));
116: }
117:
118: public void testShortPathExpression2() {
119: assertEquals(true, parseDirect("4 > 3 || foo.toUC('test')"));
120: }
121:
122: public void testChor() {
123: assertEquals("cat", parse("@{a or b or c}"));
124: }
125:
126: public void testChorWithLiteral() {
127: assertEquals("fubar", parse("@{a or 'fubar'}"));
128: }
129:
130: public void testNullCompare() {
131: assertEquals(true, parse("@{c != null}"));
132: }
133:
134: public void testAnd() {
135: assertEquals(
136: true,
137: parse("@{c != null && foo.bar.name == 'dog' && foo.bar.woof}"));
138: }
139:
140: public void testMath() {
141: assertEquals(188.4, parse("@{pi * hour}"));
142: }
143:
144: public void testMath2() {
145: assertEquals(10d / 4d, parseDirect("10 / 4"));
146: }
147:
148: public void testMath3() {
149: assertEquals(10 + 1 - 1, parseDirect("10 + 1 - 1"));
150: }
151:
152: public void testTemplating() {
153: assertEquals("dogDOGGIE133.5",
154: parse("@{foo.bar.name}DOGGIE@{hour*2.225+1-1}"));
155: }
156:
157: public void testComplexAnd() {
158: assertEquals(
159: true,
160: parse("@{(pi * hour) > 0 && foo.happy() == 'happyBar'}"));
161: }
162:
163: public void testGthan() {
164: assertEquals(true, (boolean) parseBooleanMode("hour>0"));
165: }
166:
167: public void testModulus() {
168: assertEquals(38392 % 2, parse("@{38392 % 2}"));
169: }
170:
171: public void testLessThan() {
172: assertEquals(true, parse("@{pi < 3.15}"));
173: assertEquals(true, parse("@{pi <= 3.14}"));
174: assertEquals(false, parse("@{pi > 3.14}"));
175: assertEquals(true, parse("@{pi >= 3.14}"));
176: }
177:
178: public void testMethodAccess() {
179: assertEquals("happyBar", parse("@{foo.happy()}"));
180: }
181:
182: public void testMethodAccess2() {
183: assertEquals("FUBAR", parse("@{foo.toUC('fubar')}"));
184: }
185:
186: public void testMethodAccess3() {
187: assertEquals(true, parse("@{equalityCheck(c, 'cat')}"));
188: }
189:
190: public void testMethodAccess4() {
191: assertEquals(null, parse("@{readBack(null)}"));
192: }
193:
194: public void testMethodAccess5() {
195: assertEquals("nulltest",
196: parse("@{appendTwoStrings(null, 'test')}"));
197: }
198:
199: public void testMethodAccess6() {
200: assertEquals(false, parse("@{!foo.bar.isWoof()}"));
201: }
202:
203: public void testNegation() {
204: assertEquals(true, parse("@{!fun && !fun}"));
205: }
206:
207: public void testNegation2() {
208: assertEquals(false, parse("@{fun && !fun}"));
209: }
210:
211: public void testNegation3() {
212: assertEquals(true, parse("@{!(fun && fun)}"));
213: }
214:
215: public void testNegation4() {
216: assertEquals(false, parse("@{(fun && fun)}"));
217: }
218:
219: public void testMultiStatement() {
220: assertEquals(true, parse("@{populate(); barfoo == 'sarah'}"));
221: }
222:
223: public void testAssignment() {
224: assertEquals(
225: true,
226: parseDirect("populate(); blahfoo = barfoo; blahfoo == 'sarah'"));
227: }
228:
229: public void testAssignment2() {
230: assertEquals("sarah", parse("@{populate(); blahfoo = barfoo}"));
231: }
232:
233: public void testOr() {
234: assertEquals(true, parse("@{fun || true}"));
235: }
236:
237: public void testLiteralPassThrough() {
238: assertEquals(true, parse("@{true}"));
239: }
240:
241: public void testLiteralPassThrough2() {
242: assertEquals(false, parse("@{false}"));
243: }
244:
245: public void testLiteralPassThrough3() {
246: assertEquals(null, parse("@{null}"));
247: }
248:
249: public void testControlLoop() {
250: assertEquals("HappyHappy!JoyJoy!",
251: parse("@foreach{list as fun}" + "@{fun}" + "@end{}"));
252: }
253:
254: public void testControlLoopMultiple() {
255: for (int i = 0; i < 100; i++) {
256: testControlLoop();
257: }
258: }
259:
260: public void testControlLoop2() {
261: assertEquals("HappyHappy!JoyJoy!", parse("@foreach{list}"
262: + "@{item}" + "@end{}"));
263: }
264:
265: public void testControlLoop3() {
266: assertEquals("HappyHappy!JoyJoy!", parse("@foreach{ list }"
267: + "@{item}" + "@end{}"));
268: }
269:
270: public void testIfStatement() {
271: assertEquals("sarah", parse("@if{'fun' == 'fun'}sarah@end{}"));
272: }
273:
274: public void testIfStatement2() {
275: assertEquals("poo",
276: parse("@if{'fun' == 'bar'}sarah@else{}poo@end{}"));
277: }
278:
279: public void testRegEx() {
280: assertEquals(true, parse("@{foo.bar.name ~= '[a-z].+'}"));
281: }
282:
283: public void testRegExNegate() {
284: assertEquals(false, parse("@{!(foo.bar.name ~= '[a-z].+')}"));
285: }
286:
287: public void testRegEx2() {
288: assertEquals(
289: true,
290: parse("@{foo.bar.name ~= '[a-z].+' && foo.bar.name != null}"));
291: }
292:
293: public void testBlank() {
294: assertEquals(true, parse("@{'' == empty}"));
295: }
296:
297: public void testBlank2() {
298: assertEquals(true, parse("@{BWAH == empty}"));
299: }
300:
301: public void testBooleanModeOnly2() {
302: assertEquals(false, (Object) MVEL.evalToBoolean("BWAH", base,
303: map));
304: }
305:
306: public void testBooleanModeOnly4() {
307: assertEquals(true, (Object) MVEL.evalToBoolean(
308: "hour == (hour + 0)", base, map));
309: }
310:
311: public void testBooleanModeOnly5() {
312: assertEquals(false, (Object) MVEL.evalToBoolean(
313: "!foo.bar.isFoo(this.foo)", base, map));
314: }
315:
316: public void testBooleanModeOnly6() {
317: for (int i = 0; i < 25; i++) {
318: testBooleanModeOnly5();
319: }
320: }
321:
322: public void testTernary() {
323: assertEquals("foobie", parse("@{zero==0?'foobie':zero}"));
324: }
325:
326: public void testTernary2() {
327: assertEquals("blimpie", parse("@{zero==1?'foobie':'blimpie'}"));
328: }
329:
330: public void testTernary3() {
331: assertEquals("foobiebarbie",
332: parse("@{zero==1?'foobie':'foobie'+'barbie'}"));
333: }
334:
335: public void testTernary4() {
336: assertEquals("no", parse("@{ackbar ? 'yes' : 'no'}"));
337: }
338:
339: public void testStrAppend() {
340: assertEquals("foobarcar", parse("@{'foo' + 'bar' + 'car'}"));
341: }
342:
343: public void testStrAppendForce() {
344: assertEquals("11", parseDirect("1 # 1"));
345: }
346:
347: public void testStrAppend2() {
348: assertEquals("foobarcar1", parse("@{'foobar' + 'car' + 1}"));
349: }
350:
351: public void testInstanceCheck1() {
352: assertEquals(true, parse("@{c is 'java.lang.String'}"));
353: }
354:
355: public void testInstanceCheck2() {
356: assertEquals(false, parse("@{pi is 'java.lang.Integer'}"));
357: }
358:
359: public void testConversionCheck() {
360: assertEquals(true,
361: parseDirect("pi convertable_to java.math.BigDecimal"));
362: }
363:
364: public void testConversionCheck2() {
365: assertEquals(true,
366: parseDirect("pi convertable_to java.lang.Integer"));
367: }
368:
369: public void testBitwiseOr1() {
370: assertEquals(6, parse("@{2 | 4}"));
371: }
372:
373: public void testBitwiseOr2() {
374: assertEquals(true, parse("@{(2 | 1) > 0}"));
375: }
376:
377: public void testBitwiseOr3() {
378: assertEquals(true, parse("@{(2 | 1) == 3}"));
379: }
380:
381: public void testBitwiseAnd1() {
382: assertEquals(2, parse("@{2 & 3}"));
383: }
384:
385: public void testShiftLeft() {
386: assertEquals(4, parse("@{2 << 1}"));
387: }
388:
389: public void testUnsignedShiftLeft() {
390: assertEquals(2, parse("@{-2 <<< 0}"));
391: }
392:
393: public void testShiftRight() {
394: assertEquals(128, parse("@{256 >> 1}"));
395: }
396:
397: public void testUnsignedRightShift() {
398: assertEquals(-5 >>> 2, parseDirect("-5 >>> 2"));
399: }
400:
401: public void testXOR() {
402: assertEquals(3, parse("@{1 ^ 2}"));
403: }
404:
405: public void testContains1() {
406: assertEquals(true, parse("@{list contains 'Happy!'}"));
407: }
408:
409: public void testContains2() {
410: assertEquals(false, parse("@{list contains 'Foobie'}"));
411: }
412:
413: public void testContains3() {
414: assertEquals(true, parse("@{sentence contains 'fox'}"));
415: }
416:
417: public void testContains4() {
418: assertEquals(false, parse("@{sentence contains 'mike'}"));
419: }
420:
421: public void testContains5() {
422: assertEquals(true, parse("@{!(sentence contains 'mike')}"));
423: }
424:
425: public void testInvert() {
426: assertEquals(~10, parseDirect("~10"));
427: }
428:
429: public void testInvert2() {
430: assertEquals(~(10 + 1), parseDirect("~(10 + 1)"));
431: }
432:
433: public void testInvert3() {
434: assertEquals(~10 + (1 + ~50), parseDirect("~10 + (1 + ~50)"));
435: }
436:
437: public void testNumericInteroperability() {
438: assertEquals(true, parseDirect("doubleTen > 5"));
439: }
440:
441: public void testExpression10() {
442: assertEquals(true, parse("@{10 + 1 > 5 && 10 + 1 < 20}"));
443: }
444:
445: public void testArrayAccess() {
446: assertEquals("dog", parseDirect("testArray[0].bar.name"));
447: }
448:
449: public void testArrayCreation() {
450: assertEquals(
451: "foobie",
452: parseDirect("a = {{'foo', 'bar'}, {'foobie', 'barbie'}}; a[1][0]"));
453: }
454:
455: public void testArrayCreation2() {
456: assertEquals(5, parseDirect("a = {1,3,5}; a[2]"));
457: }
458:
459: public void testTokenMethodAccess() {
460: assertEquals(String.class, parse("@{a = 'foo'; a.getClass()}"));
461: }
462:
463: public void testVariableAccess() {
464: assertEquals("HELLO", parseDirect("variable_with_underscore"));
465: }
466:
467: public void testMapAccess3() {
468: assertEquals("happyBar", parseDirect("funMap.foo_bar.happy()"));
469: }
470:
471: public void testMapAccess4() {
472: assertEquals("happyBar", parseDirect("funMap['foo'].happy()"));
473: }
474:
475: public void testMapAsMethodParm() {
476: assertEquals("happyBar",
477: parseDirect("readBack(funMap.foo_bar.happy())"));
478: }
479:
480: public void testComplexExpression() {
481: assertEquals(
482: "bar",
483: parseDirect("a = 'foo'; b = 'bar'; c = 'jim'; list = {a,b,c}; list[1]"));
484: }
485:
486: public void testComplexExpression2() {
487: assertEquals(
488: "foobar",
489: parseDirect("x = 'bar'; y = 'foo'; array = {y,x}; array[0] + array[1]"));
490: }
491:
492: public void testListCreation() {
493: assertEquals(
494: "foobar",
495: parseDirect("test = ['apple', 'pear', 'foobar']; test[2]"));
496: }
497:
498: public void testListCreation2() {
499: assertEquals(FastList.class, parseDirect("[\"test\"]")
500: .getClass());
501: }
502:
503: public void testListCreation3() {
504: assertEquals(FastList.class, parseDirect("[66]").getClass());
505: }
506:
507: public void testListCreationWithCall() {
508: assertEquals(1, parseDirect("[\"apple\"].size()"));
509: }
510:
511: public void testArrayCreationWithLength() {
512: assertEquals(2, parse("@{Array.getLength({'foo', 'bar'})}"));
513: }
514:
515: public void testMapCreation() {
516: assertEquals(
517: "sarah",
518: parse("@{map = ['mike':'sarah','tom':'jacquelin']; map['mike']}"));
519: }
520:
521: public void testProjectionSupport() {
522: assertEquals(true, parse("@{(name in things) contains 'Bob'}"));
523: }
524:
525: public void testProjectionSupport2() {
526: assertEquals(3, parse("@{(name in things).size()}"));
527: }
528:
529: public void testStaticMethodFromLiteral() {
530: assertEquals(
531: String.class.getName(),
532: parse("@{String.valueOf(Class.forName('java.lang.String').getName())}"));
533: }
534:
535: public void testMethodCallsEtc() {
536: parseDirect("title = 1; " + "frame = new javax.swing.JFrame; "
537: + "label = new javax.swing.JLabel; "
538: + "title = title + 1;" + "frame.setTitle(title);"
539: + "label.setText('this is a test of mvel');"
540: + "frame.setVisible(true);");
541: }
542:
543: public void testObjectInstantiation() {
544: assertEquals("foobie",
545: parse("@{new java.lang.String('foobie')}"));
546: }
547:
548: public void testObjectInstantiationWithMethodCall() {
549: assertEquals("foobie",
550: parse("@{new String('foobie').toString()}"));
551: }
552:
553: public void testObjectInstantiation2() {
554: parse("@{new String() is String}");
555: }
556:
557: public void testObjectInstantiation3() {
558: parseDirect("new java.text.SimpleDateFormat('yyyy').format(new java.util.Date(System.currentTimeMillis()))");
559: }
560:
561: public void testArrayCoercion() {
562: assertEquals("gonk", parse("@{funMethod( {'gonk', 'foo'} )}"));
563: }
564:
565: public void testArrayCoercion2() {
566: assertEquals(10, parseDirect("sum({2,2,2,2,2})"));
567: }
568:
569: public void testMapAccess() {
570: assertEquals("dog", parse("@{funMap['foo'].bar.name}"));
571: }
572:
573: public void testMapAccess2() {
574: assertEquals("dog", parse("@{funMap.foo.bar.name}"));
575: }
576:
577: public void testSoundex() {
578: assertTrue((Boolean) parse("@{'foobar' soundslike 'fubar'}"));
579: }
580:
581: public void testSoundex2() {
582: assertFalse((Boolean) parse("@{'flexbar' soundslike 'fubar'}"));
583: }
584:
585: public void testThisReference() {
586: assertEquals(true, parse("@{this}") instanceof Base);
587: }
588:
589: public void testThisReference2() {
590: assertEquals(true, parseDirect("this.funMap") instanceof Map);
591: }
592:
593: public void testThisReference3() {
594: assertEquals(true,
595: parseDirect("this is 'org.mvel.tests.main.res.Base'"));
596: }
597:
598: public void testStringEscaping() {
599: assertEquals("\"Mike Brock\"",
600: parse("@{\"\\\"Mike Brock\\\"\"}"));
601: }
602:
603: public void testStringEscaping2() {
604: assertEquals("MVEL's Parser is Fast",
605: parse("@{'MVEL\\'s Parser is Fast'}"));
606: }
607:
608: public void testThisReferenceInConstructor() {
609: assertEquals("101", parseDirect("new String(this.number)"));
610: }
611:
612: public void testChainedMethodCallOnConstructor() {
613: assertEquals(String.class,
614: parseDirect("new String('foo').getClass()"));
615: }
616:
617: public void testThisReferenceInMethodCall() {
618: assertEquals(101, parseDirect("Integer.parseInt(this.number)"));
619: }
620:
621: public void testInlineVarAssignment() {
622: assertTrue((Boolean) parseDirect("x = ((a = 100) + (b = 200) + (c = 300)); (a == 100 && b == 200 && c == 300 && x == 600)"));
623: }
624:
625: public void testEvalToBoolean() {
626: assertEquals(true, (boolean) MVEL
627: .evalToBoolean("true ", "true"));
628: assertEquals(true, (boolean) MVEL
629: .evalToBoolean("true ", "true"));
630: }
631:
632: // public void testCompiledListStructures() {
633: // Serializable compiled = ExpressionParser.compileExpression("[\"test\", \"yeolpass\"] contains \"yeolpass\"");
634: // assertEquals(true, ExpressionParser.executeExpression(compiled));
635: // }
636:
637: // public void testCompiledMapStructures() {
638: // Serializable compiled = ExpressionParser.compileExpression("['foo':'bar'] contains 'foo'");
639: // ExpressionParser.executeExpression(compiled, null, null, Boolean.class);
640: // }
641:
642: public void testCompiledMethodCall() {
643: Serializable compiled = MVEL.compileExpression("c.getClass()");
644: assertEquals(String.class, MVEL.executeExpression(compiled,
645: base, map));
646: }
647:
648: public void testStaticNamespaceCall() {
649: assertEquals(java.util.ArrayList.class,
650: parseDirect("java.util.ArrayList"));
651: }
652:
653: public void testStaticNamespaceClassWithMethod() {
654: assertEquals("FooBar",
655: parseDirect("java.lang.String.valueOf('FooBar')"));
656: }
657:
658: public void testStaticNamespaceClassWithField() {
659: assertEquals(String.CASE_INSENSITIVE_ORDER,
660: parseDirect("java.lang.String.CASE_INSENSITIVE_ORDER"));
661: }
662:
663: public Object parse(String ex) {
664: return Interpreter.parse(ex, base, map);
665: }
666:
667: public Object parseDirect(String ex) {
668: // return compiledExecute(ex);
669: return MVEL.eval(ex, base, map);
670: }
671:
672: public Boolean parseBooleanMode(String ex) {
673: return MVEL.evalToBoolean(ex, base, map);
674: }
675:
676: public Object compiledExecute(String ex) {
677: Serializable compiled = MVEL.compileExpression(ex);
678: return MVEL.executeExpression(compiled, base, map);
679: }
680:
681: public void calculateAge() {
682: System.out.println("Calculating the Age");
683: Calendar c1 = Calendar.getInstance();
684: c1.set(1999, 0, 10); // 1999 jan 20
685: Map objectMap = new HashMap(1);
686: Map propertyMap = new HashMap(1);
687: propertyMap.put("GEBDAT", c1.getTime());
688: objectMap.put("EV_VI_ANT1", propertyMap);
689: System.out.println(new PDFFieldUtil()
690: .calculateAge(c1.getTime()));
691: System.out
692: .println(MVEL
693: .eval(
694: "new org.mvel.tests.main.res.PDFFieldUtil().calculateAge(EV_VI_ANT1.GEBDAT) >= 25 ? 'X' : ''",
695: null, objectMap));
696: }
697:
698: // public void testToList() {
699: // String text = "misc.toList(foo.bar.name, 'hello', 42, ['key1' : 'value1', c : [ foo.bar.age, 'car', 42 ]], [42, [c : 'value1']] )";
700: // List list = null; //(List) parseDirect(text);
701: //
702: // Object expr = ExpressionParser.compileExpression( text );
703: // list = ( List ) ExpressionParser.executeExpression(expr, null, map);
704: //
705: // int count = 10000000;
706: // long start = System.currentTimeMillis();
707: // for ( int i = 0; i < count; i++ ) {
708: // list = ( List ) ExpressionParser.executeExpression(expr, null, map);
709: // }
710: // long end = System.currentTimeMillis();
711: // System.out.println( end - start);
712: //
713: // assertSame( "dog", list.compileAccessor( 0 ) );
714: // assertEquals( "hello", list.compileAccessor( 1 ) );
715: // assertEquals( new Integer( 42 ), list.compileAccessor( 2 ) );
716: // Map map = ( Map ) list.compileAccessor( 3 );
717: // assertEquals( "value1", map.compileAccessor( "key1" ) );
718: //
719: // List nestedList = ( List ) map.compileAccessor( "cat" );
720: // assertEquals( new Integer(14), nestedList.compileAccessor( 0 ) );
721: // assertEquals( "car", nestedList.compileAccessor( 1 ) );
722: // assertEquals( new BigDecimal(42), nestedList.compileAccessor( 2 ) );
723: //
724: // nestedList = (List) list.compileAccessor( 4 );
725: // assertEquals( new BigDecimal(42), nestedList.compileAccessor( 0 ) );
726: // map = ( Map ) nestedList.compileAccessor( 1 );
727: // assertEquals( "value1", map.compileAccessor( "cat" ) );
728: // }
729: //
730: // public class MiscTestClass {
731: // public List toList(Object object1, String string, int integer, Map map, List list) {
732: // List l = new ArrayList();
733: // l.add(object1);
734: // l.add(string);
735: // l.add(new Integer(integer));
736: // l.add(map);
737: // l.add(list);
738: // return l;
739: // }
740: // }
741: }
|