001: /*
002: * $Id: TestValidWhen.java 504715 2007-02-07 22:10:26Z bayard $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts.validator;
022:
023: import junit.framework.Test;
024: import junit.framework.TestCase;
025: import junit.framework.TestSuite;
026:
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029: import org.apache.commons.validator.util.ValidatorUtils;
030: import org.apache.struts.validator.validwhen.ValidWhenLexer;
031: import org.apache.struts.validator.validwhen.ValidWhenParser;
032:
033: import java.io.StringReader;
034:
035: /**
036: * Unit tests for the ValidWhen Parser/Lexer.
037: */
038: public class TestValidWhen extends TestCase {
039: /**
040: * All logging goes through this logger
041: */
042: private static Log log = LogFactory.getLog(TestValidWhen.class);
043: protected PojoBean testBean;
044:
045: /**
046: * Defines the testcase name for JUnit.
047: *
048: * @param theName the testcase's name.
049: */
050: public TestValidWhen(String theName) {
051: super (theName);
052: }
053:
054: /**
055: * Start the tests.
056: *
057: * @param theArgs the arguments. Not used
058: */
059: public static void main(String[] theArgs) {
060: junit.awtui.TestRunner.main(new String[] { TestValidWhen.class
061: .getName() });
062: }
063:
064: /**
065: * @return a test suite (<code>TestSuite</code>) that includes all methods
066: * starting with "test"
067: */
068: public static Test suite() {
069: // All methods starting with "test" will be executed in the test suite.
070: return new TestSuite(TestValidWhen.class);
071: }
072:
073: public void setUp() {
074: testBean = new PojoBean(123, 789);
075: testBean.setStringValue1("ABC");
076: testBean.setStringValue2(null);
077: testBean.setBeans(new PojoBean[] { new PojoBean(11, 12),
078: new PojoBean(21, 22), new PojoBean(31, 42),
079: new PojoBean(41, 52), new PojoBean(51, 62) });
080: testBean.setMapped("testKey", "mappedValue");
081: }
082:
083: public void tearDown() {
084: testBean = null;
085: }
086:
087: /**
088: * Test Operators.
089: */
090: public void testProperty() {
091: // *this*
092: doParse("(*this* == 123)", testBean, 0, "intValue1", true);
093:
094: // Named property
095: doParse("(intValue2 == 789)", testBean, 0, "intValue1", true);
096:
097: // Indexed Property
098: doParse("(beans[].intValue1 == 21)", testBean, 1, "intValue1",
099: true);
100: doParse("(beans[1].intValue1 == 21)", testBean, 4, "intValue1",
101: true);
102:
103: // Mapped Property - *** NOT SUPPORTED ***
104: // doParse("(mapped(mappedValue) == 'testKey')", testBean , 0, "mappedValue", true);
105: }
106:
107: /**
108: * Test Operators.
109: */
110: public void testOperators() {
111: // Equal
112: doParse("(*this* == 123)", testBean, 0, "intValue1", true);
113:
114: // Not Equal
115: doParse("(*this* != 456)", testBean, 0, "intValue1", true);
116:
117: // Less Than
118: doParse("(*this* < 456)", testBean, 0, "intValue1", true);
119:
120: // Greater Than
121: doParse("(*this* > 100)", testBean, 0, "intValue1", true);
122:
123: // Less Than Equal
124: doParse("(*this* <= 123)", testBean, 0, "intValue1", true);
125:
126: // Greater Than Equal
127: doParse("(*this* >= 123)", testBean, 0, "intValue1", true);
128: }
129:
130: /**
131: * Test String values.
132: */
133: public void testString() {
134: doParse("(*this* != '--')", "XX", 0, "stringValue1", true);
135: doParse("(*this* == '--')", "--", 0, "stringValue1", true);
136:
137: String testValue = "dsgUOLMdLsdL";
138:
139: // single quote
140: doParse("(*this* == '" + testValue + "')", testValue, 0,
141: "stringValue1", true);
142:
143: // double quote
144: doParse("(*this* == \"" + testValue + "\")", testValue, 0,
145: "stringValue1", true);
146:
147: // obscure characters
148: doParse("(*this* == \":\")", ":", 0, "stringValue1", true);
149: doParse("(*this* == \"foo:bar\")", "foo:bar", 0,
150: "stringValue1", true);
151: }
152:
153: /**
154: * Test Numeric values.
155: */
156: public void testNumeric() {
157: // Test Zero
158: PojoBean numberBean = new PojoBean(0, -50);
159:
160: doParse("(intValue1 == 0)", numberBean, 0, "intValue1", true);
161: doParse("(intValue2 != 0)", numberBean, 0, "intValue2", true);
162: doParse("(integerValue1 == 0)", numberBean, 0, "integerValue1",
163: true);
164: doParse("(integerValue2 != 0)", numberBean, 0, "integerValue2",
165: true);
166:
167: // int
168: doParse("(intValue1 == 123)", testBean, 0, "intValue1", true);
169:
170: // Integer
171: doParse("(integerValue1 == 123)", testBean, 0, "integerValue1",
172: true);
173:
174: // Negative Numbers
175: doParse("((intValue2 < -10) and (intValue2 > -60))",
176: numberBean, 0, "intValue2", true);
177: doParse("((integerValue2 < -10) and (integerValue2 > -60))",
178: numberBean, 0, "integerValue2", true);
179:
180: // Hex
181: doParse("(integerValue1 == 0x7B)", testBean, 0,
182: "integerValue1", true);
183:
184: // Octal
185: doParse("(integerValue1 == 0173)", testBean, 0,
186: "integerValue1", true);
187:
188: // Test 'String' numbers
189: PojoBean stringBean = new PojoBean("11", "2");
190:
191: doParse("(stringValue1 > stringValue2)", stringBean, 0,
192: "stringValue1", true);
193: doParse("(stringValue1 < stringValue2)", stringBean, 0,
194: "stringValue1", false);
195: }
196:
197: /**
198: * Test Null.
199: */
200: public void testNull() {
201: // Not Null
202: doParse("(*this* != null)", testBean, 0, "stringValue1", true);
203:
204: // Null
205: doParse("(*this* == null)", testBean, 0, "stringValue2", true);
206: }
207:
208: /**
209: * Test Joined expressions ('and' or 'or')
210: */
211: public void testJoined() {
212: // Join with 'or'
213: doParse("((*this* == 'ABC') or (stringValue2 == null))",
214: testBean, 0, "stringValue1", true);
215: doParse("((*this* != 'ABC') or (stringValue2 == null))",
216: testBean, 0, "stringValue1", true);
217: doParse("((*this* == 'ABC') or (stringValue2 != null))",
218: testBean, 0, "stringValue1", true);
219: doParse("((*this* != 'ABC') or (stringValue2 != null))",
220: testBean, 0, "stringValue1", false);
221:
222: // Join with 'and'
223: doParse("((*this* == 'ABC') and (stringValue2 == null))",
224: testBean, 0, "stringValue1", true);
225: doParse("((*this* != 'ABC') and (stringValue2 == null))",
226: testBean, 0, "stringValue1", false);
227: doParse("((*this* == 'ABC') and (stringValue2 != null))",
228: testBean, 0, "stringValue1", false);
229: doParse("((*this* != 'ABC') and (stringValue2 != null))",
230: testBean, 0, "stringValue1", false);
231: }
232:
233: /**
234: * Parse the expression and check that the expected result (either true or
235: * false) occurs - fail if an exception is thrown opr the wrong result
236: * occurs.
237: *
238: * @param test Test expression
239: * @param bean Test Bean
240: * @param index index value
241: * @param property Bean property
242: * @param expected Expected Result
243: */
244: private void doParse(String test, Object bean, int index,
245: String property, boolean expected) {
246: boolean result = false;
247:
248: try {
249: result = doParse(test, bean, index, property);
250: } catch (Exception ex) {
251: log.error("Parsing " + test + " for property '" + property
252: + "'", ex);
253: fail("Parsing " + test + " threw " + ex);
254: }
255:
256: if (expected) {
257: assertTrue(test + " didn't return TRUE for " + property,
258: result);
259: } else {
260: assertFalse(test + " didn't return FALSE for " + property,
261: result);
262: }
263: }
264:
265: /**
266: * Parse the expression and check that an Exception is throw. Failes if no
267: * expection is thrown.
268: *
269: * @param test Test expression
270: * @param bean Test Bean
271: * @param index index value
272: * @param property Bean property
273: */
274: private void doParseFail(String test, Object bean, int index,
275: String property) {
276: try {
277: boolean result = doParse(test, bean, index, property);
278:
279: fail("Parsing " + test
280: + " didn't throw exception as expected " + result);
281: } catch (Exception expected) {
282: // ignore exception - expected result
283: }
284: }
285:
286: /**
287: * Parse the expression returning the result
288: *
289: * @param test Test expression
290: * @param bean Test Bean
291: * @param index index value
292: * @param property Bean property
293: */
294: private boolean doParse(String test, Object bean, int index,
295: String property) throws Exception {
296: if (bean == null) {
297: throw new NullPointerException(
298: "Bean is null for property '" + property + "'");
299: }
300:
301: String value = String.class.isInstance(bean) ? (String) bean
302: : ValidatorUtils.getValueAsString(bean, property);
303:
304: ValidWhenLexer lexer = new ValidWhenLexer(
305: new StringReader(test));
306:
307: ValidWhenParser parser = new ValidWhenParser(lexer);
308:
309: parser.setForm(bean);
310: parser.setIndex(index);
311: parser.setValue(value);
312:
313: parser.expression();
314:
315: return parser.getResult();
316: }
317: }
|