View Javadoc

1   /**
2    * Copyright 2010 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  
16  package org.kuali.student.common.messagebuilder.impl;
17  
18  import java.util.HashMap;
19  import java.util.Map;
20  
21  import org.apache.velocity.tools.generic.DateTool;
22  import org.junit.Assert;
23  import org.junit.Before;
24  import org.junit.Test;
25  import org.kuali.student.common.messagebuilder.MessageBuilder;
26  import org.kuali.student.common.messagebuilder.MessageTreeBuilder;
27  import org.kuali.student.common.messagebuilder.booleanmessage.BooleanMessage;
28  import org.kuali.student.common.messagebuilder.booleanmessage.MessageContainer;
29  import org.kuali.student.common.messagebuilder.booleanmessage.ast.BooleanFunctionResult;
30  import org.kuali.student.common.messagebuilder.booleanmessage.ast.BooleanMessageImpl;
31  import org.kuali.student.common.messagebuilder.impl.MessageBuilderImpl;
32  import org.kuali.student.common.messagebuilder.impl.exceptions.MessageBuilderException;
33  
34  public class MessageBuilderImplTest {
35      private MessageBuilder builder;
36  
37  	@Before
38  	public void setUp() throws Exception {
39  		BooleanOperators bo = new BooleanOperators();
40  		MessageTreeBuilder tnmBuilder = new SuccessFailureMessageBuilder(bo);
41  		builder = new MessageBuilderImpl("en", tnmBuilder);
42  	}
43  
44  	@Test
45  	public void testBuildMessage1_InvalidBooleanExpression() throws Exception {
46  		MessageContainer messageContainer = new MessageContainer();
47  		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, "Message 1 is true");
48  		BooleanMessage bm2 = new BooleanMessageImpl("M2", true, "Message 2 is true");
49  		BooleanMessage bm3 = new BooleanMessageImpl("M3", true, "Message 3 is true");
50  		messageContainer.addMessage(bm1);
51  		messageContainer.addMessage(bm2);
52  		messageContainer.addMessage(bm3);
53  
54  		try {
55  			builder.buildMessage("M1**M2**M3", messageContainer);
56  			Assert.fail("Building message should have failed due to boolean expression syntax error");
57  		} catch(MessageBuilderException e) {
58  			Assert.assertTrue(e.getMessage().startsWith("Building message failed: Boolean Function Parser Error. Invalid Boolean Expression: 'M1**M2**M3'"));
59  		}
60  	}
61  
62  	@Test
63  	public void testBuildMessage1_True() throws Exception {
64  		MessageContainer messageContainer = new MessageContainer();
65  		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, "Message 1 is true");
66  		BooleanMessage bm2 = new BooleanMessageImpl("M2", true, "Message 2 is true");
67  		BooleanMessage bm3 = new BooleanMessageImpl("M3", true, "Message 3 is true");
68  		messageContainer.addMessage(bm1);
69  		messageContainer.addMessage(bm2);
70  		messageContainer.addMessage(bm3);
71  		
72  		String message = builder.buildMessage("M1*M2*M3", messageContainer);
73  		Assert.assertEquals("Message 1 is true AND Message 2 is true AND Message 3 is true", message);
74  	}
75  
76  	@Test
77  	public void testBuildMessage2_True() throws Exception {
78  		MessageContainer messageContainer = new MessageContainer();
79  		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, "Message 1 is true");
80  		BooleanMessage bm2 = new BooleanMessageImpl("M2", false, "Message 2 is false");
81  		BooleanMessage bm3 = new BooleanMessageImpl("M3", true, "Message 3 is true");
82  		messageContainer.addMessage(bm1);
83  		messageContainer.addMessage(bm2);
84  		messageContainer.addMessage(bm3);
85  		
86  		String message = builder.buildMessage("(M1*M2)+M3", messageContainer);
87  		Assert.assertEquals("Message 3 is true", message);
88  	}
89  
90  	@Test
91  	public void testBuildMessage3_False() throws Exception {
92  		MessageContainer messageContainer = new MessageContainer();
93  		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, "Message 1 is true");
94  		BooleanMessage bm2 = new BooleanMessageImpl("M2", false, "Must have CHEM 101");
95  		messageContainer.addMessage(bm1);
96  		messageContainer.addMessage(bm2);
97  		
98  		String message = builder.buildMessage("M1*M2", messageContainer);
99  		Assert.assertEquals("Must have CHEM 101", message);
100 	}
101 
102 	@Test
103 	public void testBuildMessage4_False() throws Exception {
104 		MessageContainer messageContainer = new MessageContainer();
105 		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, "Requirement Fulfilled 1");
106 		BooleanMessage bm2 = new BooleanMessageImpl("M2", false, "Must have CHEM 101");
107 		BooleanMessage bm3 = new BooleanMessageImpl("M3", false, "Must have PHYS 101");
108 		messageContainer.addMessage(bm1);
109 		messageContainer.addMessage(bm2);
110 		messageContainer.addMessage(bm3);
111 		
112 		BooleanFunctionResult result = builder.build("(M1*M2)+M3", messageContainer);
113 		Assert.assertFalse(result.getResult());
114 		Assert.assertEquals("Must have CHEM 101 OR Must have PHYS 101", result.getMessage());
115 	}
116 
117 	@Test
118 	public void testBuildMessage5_True() throws Exception {
119 		MessageContainer messageContainer = new MessageContainer();
120 		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, "Message 1 is true");
121 		BooleanMessage bm2 = new BooleanMessageImpl("M2", true, "Message 2 is true");
122 		BooleanMessage bm3 = new BooleanMessageImpl("M3", false, "Message 3 is false");
123 		messageContainer.addMessage(bm1);
124 		messageContainer.addMessage(bm2);
125 		messageContainer.addMessage(bm3);
126 		
127 		// result = True : M1*M2+M3 = T and T or F -> (M1*M2)+M3 (T and T) or F
128 		String bf = "M1*M2+M3";
129 		BooleanFunctionResult result = builder.build(bf, messageContainer);
130 		// Order of boolean operation: AND before OR, operations inside parentheses before anything else
131 		Assert.assertEquals(bf, result.getBooleanFunction());
132 		Assert.assertTrue(result.getResult());
133 		Assert.assertEquals("Message 1 is true AND Message 2 is true", result.getMessage());
134 	}
135 
136 	@Test
137 	public void testBuildMessage6() throws Exception {
138 		MessageContainer messageContainer = new MessageContainer();
139 		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, "Message 1 is true");
140 		BooleanMessage bm2 = new BooleanMessageImpl("M2", true, "Message 2 is true");
141 		BooleanMessage bm3 = new BooleanMessageImpl("M3", false, "Message 3 is false");
142 		BooleanMessage bm4 = new BooleanMessageImpl("M4", false, "Message 4 is false");
143 		messageContainer.addMessage(bm1);
144 		messageContainer.addMessage(bm2);
145 		messageContainer.addMessage(bm3);
146 		messageContainer.addMessage(bm4);
147 		
148 		BooleanFunctionResult result1 = builder.build("M1*M2+M3*M4", messageContainer);
149 		BooleanFunctionResult result2 = builder.build("(M1*M2)+(M3*M4)", messageContainer);
150 		BooleanFunctionResult result3 = builder.build("((M1*M2)+M3)*M4", messageContainer);
151 		
152 		// Order of boolean operation: ANDs before ORs and 
153 		// operations inside parentheses before anything else.
154 		// result1 = True  : T and T or F and F
155 		// result2 = True  : (T and T) or (F and F)
156 		// result3 = False : ((T and T) or F) and F
157 		Assert.assertEquals("M1*M2+M3*M4", result1.getBooleanFunction());
158 		Assert.assertEquals("(M1*M2)+(M3*M4)", result2.getBooleanFunction());
159 		Assert.assertEquals("((M1*M2)+M3)*M4", result3.getBooleanFunction());
160 		Assert.assertTrue(result1.getResult());
161 		Assert.assertTrue(result2.getResult());
162 		Assert.assertFalse(result3.getResult());
163 		Assert.assertTrue(result1.getResult() == result2.getResult());
164 		Assert.assertFalse(result1.getResult() == result3.getResult());
165 		Assert.assertFalse(result2.getResult() == result3.getResult());
166 		Assert.assertTrue(result1.getMessage().equals(result2.getMessage()));
167 		Assert.assertFalse(result1.getMessage().equals(result3.getMessage()));
168 		Assert.assertFalse(result2.getMessage().equals(result3.getMessage()));
169 	}
170 
171 	@Test
172 	public void testBuildMessage7() throws Exception {
173 		MessageContainer messageContainer = new MessageContainer();
174 		BooleanMessage bm1 = new BooleanMessageImpl("A", true, "A is true");
175 		BooleanMessage bm2 = new BooleanMessageImpl("B", true, "B is true");
176 		BooleanMessage bm3 = new BooleanMessageImpl("C", true, "C is true");
177 		messageContainer.addMessage(bm1);
178 		messageContainer.addMessage(bm2);
179 		messageContainer.addMessage(bm3);
180 		
181 		String message = builder.buildMessage("(A*B)+(A*C)+(B*C)", messageContainer);
182 		Assert.assertEquals("(A is true AND B is true) OR (A is true AND C is true) OR (B is true AND C is true)", message);
183 	}
184 
185 	@Test
186 	public void testBuildMessage8() throws Exception {
187 		MessageContainer messageContainer = new MessageContainer();
188 		BooleanMessage bm1 = new BooleanMessageImpl("A", true, "A");
189 		BooleanMessage bm2 = new BooleanMessageImpl("B", true, "B");
190 		BooleanMessage bm3 = new BooleanMessageImpl("C", true, "C");
191 		BooleanMessage bm4 = new BooleanMessageImpl("D", true, "D");
192 		messageContainer.addMessage(bm1);
193 		messageContainer.addMessage(bm2);
194 		messageContainer.addMessage(bm3);
195 		messageContainer.addMessage(bm4);
196 		
197 		String message = builder.buildMessage("A*(B+C+D)", messageContainer);
198 		Assert.assertEquals("A AND (B OR C OR D)", message);
199 	}
200 	
201 	@Test
202 	public void testBuildMessage9() throws Exception {
203 		MessageContainer messageContainer = new MessageContainer();
204 		BooleanMessage bm1 = new BooleanMessageImpl("A", true, "A");
205 		BooleanMessage bm2 = new BooleanMessageImpl("B", true, "B");
206 		BooleanMessage bm3 = new BooleanMessageImpl("C", true, "C");
207 		BooleanMessage bm4 = new BooleanMessageImpl("D", true, "D");
208 		messageContainer.addMessage(bm1);
209 		messageContainer.addMessage(bm2);
210 		messageContainer.addMessage(bm3);
211 		messageContainer.addMessage(bm4);
212 		
213 		String message = builder.buildMessage("A*(B+(C+D))", messageContainer);
214 		Assert.assertEquals("A AND (B OR C OR D)", message);
215 	}
216 	
217 	@Test
218 	public void testBuildMessage10() throws Exception {
219 		MessageContainer messageContainer = new MessageContainer();
220 		BooleanMessage bm1 = new BooleanMessageImpl("A", true, "A");
221 		BooleanMessage bm2 = new BooleanMessageImpl("B", true, "B");
222 		BooleanMessage bm3 = new BooleanMessageImpl("C", true, "C");
223 		BooleanMessage bm4 = new BooleanMessageImpl("D", true, "D");
224 		messageContainer.addMessage(bm1);
225 		messageContainer.addMessage(bm2);
226 		messageContainer.addMessage(bm3);
227 		messageContainer.addMessage(bm4);
228 		
229 		String message = builder.buildMessage("(A*(B+C))+D", messageContainer);
230 		Assert.assertEquals("(A AND (B OR C)) OR D", message);
231 	}
232 	
233 	@Test
234 	public void testBuildMessage11() throws Exception {
235 		MessageContainer messageContainer = new MessageContainer();
236 		BooleanMessage bm1 = new BooleanMessageImpl("A", true, "A");
237 		BooleanMessage bm2 = new BooleanMessageImpl("B", true, "B");
238 		BooleanMessage bm3 = new BooleanMessageImpl("C", false, "C");
239 		BooleanMessage bm4 = new BooleanMessageImpl("D", false, "D");
240 		messageContainer.addMessage(bm1);
241 		messageContainer.addMessage(bm2);
242 		messageContainer.addMessage(bm3);
243 		messageContainer.addMessage(bm4);
244 		
245 		String message = builder.buildMessage("(A*(B+C))+D", messageContainer);
246 		Assert.assertEquals("A AND B", message);
247 	}
248 	
249 	@Test
250 	public void testBuildMessage12() throws Exception {
251 		MessageContainer messageContainer = new MessageContainer();
252 		BooleanMessage bm1 = new BooleanMessageImpl("A", true, "A");
253 		BooleanMessage bm2 = new BooleanMessageImpl("B", true, "B");
254 		BooleanMessage bm3 = new BooleanMessageImpl("C", true, "C");
255 		BooleanMessage bm4 = new BooleanMessageImpl("D", true, "D");
256 		messageContainer.addMessage(bm1);
257 		messageContainer.addMessage(bm2);
258 		messageContainer.addMessage(bm3);
259 		messageContainer.addMessage(bm4);
260 		
261 		String message = builder.buildMessage("(A*B)+(C+D)", messageContainer);
262 		Assert.assertEquals("(A AND B) OR C OR D", message);
263 	}
264 	
265 	@Test
266 	public void testBuildMessage13() throws Exception {
267 		MessageContainer messageContainer = new MessageContainer();
268 		BooleanMessage bm1 = new BooleanMessageImpl("A", true, "A");
269 		BooleanMessage bm2 = new BooleanMessageImpl("B", false, "B");
270 		BooleanMessage bm3 = new BooleanMessageImpl("C", false, "C");
271 		BooleanMessage bm4 = new BooleanMessageImpl("D", false, "D");
272 		messageContainer.addMessage(bm1);
273 		messageContainer.addMessage(bm2);
274 		messageContainer.addMessage(bm3);
275 		messageContainer.addMessage(bm4);
276 		
277 		String message = builder.buildMessage("(A*B)+(C+D)", messageContainer);
278 		Assert.assertEquals("B OR C OR D", message);
279 	}
280 	
281 	@Test
282 	public void testBuildMessageTemplate1_NullContextMap_True() throws Exception {
283 		MessageContainer messageContainer = new MessageContainer();
284 		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, "Message 1 is true");
285 		BooleanMessage bm2 = new BooleanMessageImpl("M2", true, "Message 2 is true");
286 		BooleanMessage bm3 = new BooleanMessageImpl("M3", true, "Message 3 is true");
287 		messageContainer.addMessage(bm1);
288 		messageContainer.addMessage(bm2);
289 		messageContainer.addMessage(bm3);
290 		
291 		BooleanFunctionResult result = builder.build("M1*M2*M3", messageContainer, null);
292 		Assert.assertEquals("Message 1 is true AND Message 2 is true AND Message 3 is true", result.getMessage());
293 	}
294 
295 	@Test
296 	public void testBuildMessageTemplate2_NullContextMap_False() throws Exception {
297 		MessageContainer messageContainer = new MessageContainer();
298 		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, "Message 1 is true");
299 		BooleanMessage bm2 = new BooleanMessageImpl("M2", false, "Message 2 is false");
300 		BooleanMessage bm3 = new BooleanMessageImpl("M3", true, "Message 3 is true");
301 		messageContainer.addMessage(bm1);
302 		messageContainer.addMessage(bm2);
303 		messageContainer.addMessage(bm3);
304 		
305 		BooleanFunctionResult result = builder.build("M1*M2*M3", messageContainer, null);
306 		Assert.assertEquals("Message 2 is false", result.getMessage());
307 	}
308 
309 	@Test
310 	public void testBuildMessageTemplate3_True() throws Exception {
311 		Map<String, Object> map = new HashMap<String, Object>();
312 		map.put("expectedValue", "100");
313 		map.put("resultValue", "60");
314 
315 		MessageContainer messageContainer = new MessageContainer();
316 		String successMsg1 = "Date created $dateTool.get('yyyy-MM-dd')";
317 		String successMsg2 = "#set( $difference = ( $mathTool.toNumber($expectedValue) - $mathTool.toNumber($resultValue)) )" +
318 				"expectedValue=$expectedValue, resultValue=$resultValue, difference=$difference";
319 		BooleanMessage bm1 = new BooleanMessageImpl("M1", true, successMsg1);
320 		BooleanMessage bm2 = new BooleanMessageImpl("M2", true, successMsg2);
321 		messageContainer.addMessage(bm1);
322 		messageContainer.addMessage(bm2);
323 		
324 		BooleanFunctionResult result = builder.build("M1*M2", messageContainer, map);
325 		Assert.assertEquals("Date created " + new DateTool().get("yyyy-MM-dd") + 
326 				" AND expectedValue=100, resultValue=60, difference=40", result.getMessage());
327 	}
328 
329 	@Test
330 	public void testBuildMessageTemplate4_False() throws Exception {
331 		Map<String, Object> map = new HashMap<String, Object>();
332 		map.put("expectedValue", "100");
333 		map.put("resultValue", "60");
334 
335 		MessageContainer messageContainer = new MessageContainer();
336 		String failureMsg1 = "Date created $dateTool.get('yyyy-MM-dd')";
337 		String failureMsg2 = "#set( $difference = ( $mathTool.toNumber($expectedValue) - $mathTool.toNumber($resultValue)) )" +
338 				"expectedValue=$expectedValue, resultValue=$resultValue, difference=$difference";
339 		BooleanMessage bm1 = new BooleanMessageImpl("M1", false, failureMsg1);
340 		BooleanMessage bm2 = new BooleanMessageImpl("M2", false, failureMsg2);
341 		messageContainer.addMessage(bm1);
342 		messageContainer.addMessage(bm2);
343 		
344 		BooleanFunctionResult result = builder.build("M1*M2", messageContainer, map);
345 		Assert.assertEquals("Date created " + new DateTool().get("yyyy-MM-dd") + 
346 				" AND expectedValue=100, resultValue=60, difference=40", result.getMessage());
347 	}
348 
349 	@Test
350 	public void testBuildMessageTemplate5_False_Exception() throws Exception {
351 		Map<String, Object> map = new HashMap<String, Object>();
352 		map.put("expectedValue", "100");
353 		map.put("resultValue", "60");
354 
355 		MessageContainer messageContainer = new MessageContainer();
356 		String failureMsg1 = "Date created $dateTool.get('yyyy-MM-dd HH:mm:ss z')";
357 		// VTL syntax error
358 		String failureMsg2 = "#set( $difference = expectedValue=$expectedValue, resultValue=$resultValue, difference=$difference";
359 		BooleanMessage bm1 = new BooleanMessageImpl("M1", false, failureMsg1);
360 		BooleanMessage bm2 = new BooleanMessageImpl("M2", false, failureMsg2);
361 		messageContainer.addMessage(bm1);
362 		messageContainer.addMessage(bm2);
363 
364 		try {
365 			builder.build("M1*M2", messageContainer, map);
366 			Assert.fail("Building message should have failed due to VTL syntax error");
367 		} catch(MessageBuilderException e) {
368 			Assert.assertTrue(true);
369 		}
370 	}
371 }