View Javadoc

1   /********************************************************************************
2    * DDTUnit, a Datadriven Approach to Unit- and Moduletesting
3    * Copyright (c) 2004, Joerg and Kai Gellien
4    * All rights reserved.
5    * 
6    * The Software is provided under the terms of the Common Public License 1.0
7    * as provided with the distribution of DDTUnit in the file cpl-v10.html.
8    * Redistribution and use in source and binary forms, with or without 
9    * modification, are permitted provided that the following conditions
10   * are met:
11   * 
12   *     + Redistributions of source code must retain the above copyright 
13   *       notice, this list of conditions and the following disclaimer. 
14   *       
15   *     + Redistributions in binary form must reproduce the above 
16   *       copyright notice, this list of conditions and the following 
17   *       disclaimer in the documentation and/or other materials provided 
18   *       with the distribution. 
19   *       
20   *     + Neither the name of the authors or DDTUnit, nor the 
21   *       names of its contributors may be used to endorse or promote 
22   *       products derived from this software without specific prior 
23   *       written permission. 
24   * 
25   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
26   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
27   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
28   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 
29   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
30   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
31   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
32   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
33   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
34   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
35   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36   ********************************************************************************/
37  package junitx.ddtunit.data;
38  
39  import java.util.Collection;
40  import java.util.Iterator;
41  
42  import junit.framework.AssertionFailedError;
43  import junitx.ddtunit.DDTException;
44  import junitx.framework.ArrayAssert;
45  import junitx.framework.Assert;
46  
47  /**
48   * Class contains all information to execute an assert action between actual and
49   * expected object.
50   * 
51   * @author jg
52   */
53  public class ObjectAsserter extends AssertObject {
54  
55      /**
56       * @param id of assert
57       * @param type of expected object
58       * @param action to process
59       */
60      public ObjectAsserter(String id, String type, String action) {
61          super(id, type, action);
62      }
63  
64      /**
65       * defines equals action analogue to JUnit assertEquals
66       */
67      public static final String ASSERT_ACTION_ISEQUAL = "ISEQUAL";
68  
69      /**
70       * defines equals action analogue to JUnit assertEquals
71       */
72      public static final String ASSERT_ACTION_ISNOTEQUAL = "ISNOTEQUAL";
73  
74      /**
75       * defines equals action analogue to JUnit assertSame
76       */
77      public static final String ASSERT_ACTION_ISSAME = "ISSAME";
78  
79      /**
80       * defines equals action analogue to JUnit assertEquals
81       */
82      public static final String ASSERT_ACTION_ISNOTSAME = "ISNOTSAME";
83  
84      /**
85       * defines equals action analogue to JUnit assertEquals
86       */
87      public static final String ASSERT_ACTION_ISNULL = "ISNULL";
88  
89      /**
90       * defines equals action analogue to JUnit assertEquals
91       */
92      public static final String ASSERT_ACTION_ISNOTNULL = "ISNOTNULL";
93  
94      private boolean validated = false;
95  
96      public static final String ASSERT_ACTION_ISTRUE = "ISTRUE";
97  
98      public static final String ASSERT_ACTION_ISFALSE = "ISFALSE";
99  
100     public static final String ASSERT_ACTION_ISGT = "ISGT";
101 
102     public static final String ASSERT_ACTION_ISNOTGT = "ISNOTGT";
103 
104     public static final String ASSERT_ACTION_ISLT = "ISLT";
105 
106     public static final String ASSERT_ACTION_ISNOTLT = "ISNOTLT";
107 
108     public static final String ASSERT_ACTION_ISCONTAINEDIN = "ISCONTAINEDIN";
109 
110     public static final String ASSERT_ACTION_ISNOTCONTAINEDIN = "ISNOTCONTAINEDIN";
111 
112     public static final String ASSERT_ACTION_ISINRANGE = "ISINRANGE";
113 
114     public static final String ASSERT_ACTION_ISNOTINRANGE = "ISNOTINRANGE";
115 
116     /**
117      * Validate expected object against actual object using assert action.
118      * 
119      * @param mark validation if set to true, else reprocessing is possible.
120      */
121     public void validate(boolean mark) {
122         if (!this.actualObjectSet) {
123             throw new DDTException("Actual object for assertion not provided");
124         } else if (ASSERT_ACTION_ISEQUAL.equals(this.action.toUpperCase())) {
125             this.markAsProcessed = mark;
126             isSameType();
127             if (this.getActualType() != null
128                     && this.getActualType().startsWith("[L")
129                     && this.getType().startsWith("[L")) {
130                 ArrayAssert.assertEquals("Wrong isEqual assert ("
131                         + this.getId() + ") on arrays", (Object[]) this
132                     .getValue(), (Object[]) this.getActualObject());
133             } else {
134                 if ("java.lang.String".equals(this.getActualType())
135                         && "java.lang.String".equals(this.getType())) {
136                     String actualText = (String) getActualObject();
137                     String expectedText = (String) getValue();
138                     String[] actual = null;
139                     String[] expected = null;
140                     if (actualText != null && actualText.indexOf("\r\n") > -1) {
141                         actual = actualText.split("\r\n");
142                     } else {
143                         actual = actualText.split("\n");
144                     }
145                     if (expectedText != null
146                             && expectedText.indexOf("\r\n") > -1) {
147                         expected = expectedText.split("\r\n");
148                     } else {
149                         expected = expectedText.split("\n");
150                     }
151                     ArrayAssert.assertEquals(
152                         "Wrong isEqual assert on (multiline) string", expected,
153                         actual);
154                 } else {
155                     Assert.assertEquals("Wrong isEqual assert (" + this.getId()
156                             + ")", this.getValue(), getActualObject());
157                 }
158             }
159         } else if (ASSERT_ACTION_ISNOTEQUAL.equals(this.action.toUpperCase())) {
160             this.markAsProcessed = mark;
161             Assert.assertNotEquals("Wrong isNotEqual assert (" + this.getId()
162                     + ")", this.getValue(), getActualObject());
163         } else if (ASSERT_ACTION_ISSAME.equals(this.action.toUpperCase())) {
164             this.markAsProcessed = mark;
165             isSameType();
166             Assert.assertSame("Wrong isSame assert (" + this.getId() + ")",
167                 this.getValue(), getActualObject());
168         } else if (ASSERT_ACTION_ISNOTSAME.equals(this.action.toUpperCase())) {
169             this.markAsProcessed = mark;
170             Assert.assertNotSame("Wrong isNotSame assert (" + this.getId()
171                     + ")", this.getValue(), getActualObject());
172         } else if (ASSERT_ACTION_ISNULL.equals(this.action.toUpperCase())) {
173             this.markAsProcessed = mark;
174             isSameType();
175             Assert.assertNull("Object should be null on assert ("
176                     + this.getId() + ")", getActualObject());
177         } else if (ASSERT_ACTION_ISNOTNULL.equals(this.action.toUpperCase())) {
178             this.markAsProcessed = mark;
179             isSameType();
180             Assert.assertNotNull("Object should not be null on assert ("
181                     + this.getId() + ")", getActualObject());
182         } else if (ASSERT_ACTION_ISTRUE.equals(this.action.toUpperCase())) {
183             this.markAsProcessed = mark;
184             if (Boolean.class.isInstance(getActualObject())) {
185                 isSameType();
186                 Assert.assertTrue("Object should be true on assert ("
187                         + this.getId() + ")", ((Boolean) getActualObject())
188                     .booleanValue());
189             } else {
190                 throw new UnsupportedOperationException(
191                         "Wrong type used under assert action 'ISTRUE':"
192                                 + getActualObject());
193             }
194         } else if (ASSERT_ACTION_ISFALSE.equals(this.action.toUpperCase())) {
195             this.markAsProcessed = mark;
196             if (Boolean.class.isInstance(getActualObject())) {
197                 isSameType();
198                 Assert.assertFalse("Object should be false on assert ("
199                         + this.getId() + ")", ((Boolean) getActualObject())
200                     .booleanValue());
201             } else {
202                 throw new UnsupportedOperationException(
203                         "Wrong type used under assert action 'ISFALSE':"
204                                 + getActualObject());
205             }
206         } else if (ASSERT_ACTION_ISGT.equals(this.action.toUpperCase())
207                 || ASSERT_ACTION_ISNOTGT.equals(this.action.toUpperCase())
208                 || ASSERT_ACTION_ISLT.equals(this.action.toUpperCase())
209                 || ASSERT_ACTION_ISNOTLT.equals(this.action.toUpperCase())
210                 || ASSERT_ACTION_ISINRANGE.equals(this.action.toUpperCase())
211                 || ASSERT_ACTION_ISNOTINRANGE.equals(this.action.toUpperCase())) {
212             this.markAsProcessed = mark;
213             // if doing range checks do not check expected and actual types
214             if (!(this.getValue() instanceof IRange)) {
215                 isSameType();
216             }
217             if (Comparable.class.isInstance(this.actualObject)) {
218                 if (ASSERT_ACTION_ISGT.equals(this.action.toUpperCase())) {
219                     if (((Comparable) this.getActualObject()).compareTo(this
220                         .getValue()) <= 0) {
221                         Assert.fail("Expected action: " + this.getAction()
222                                 + ". Got: " + this.getActualObject() + " <= "
223                                 + this.getValue() + " on assert ("
224                                 + this.getId() + ")");
225                     }
226                 } else if (ASSERT_ACTION_ISNOTGT.equals(this.action
227                     .toUpperCase())) {
228                     if (((Comparable) this.getActualObject()).compareTo(this
229                         .getValue()) > 0) {
230                         Assert.fail("Expected action: " + this.getAction()
231                                 + ". Got: " + this.getActualObject() + " > "
232                                 + this.getValue() + "on assert ("
233                                 + this.getId() + ")");
234                     }
235                 } else if (ASSERT_ACTION_ISLT.equals(this.action.toUpperCase())) {
236                     if (((Comparable) this.getActualObject()).compareTo(this
237                         .getValue()) >= 0) {
238                         Assert.fail("Expected action: " + this.getAction()
239                                 + ". Got: " + this.getActualObject() + " >= "
240                                 + this.getValue() + " on assert ("
241                                 + this.getId() + ")");
242                     }
243                 } else if (ASSERT_ACTION_ISNOTLT.equals(this.action
244                     .toUpperCase())) {
245                     if (((Comparable) this.getActualObject()).compareTo(this
246                         .getValue()) >= 0) {
247                         Assert.fail("Expected action: " + this.getAction()
248                                 + ". Got: " + this.getActualObject() + " > "
249                                 + this.getValue() + " on assert ("
250                                 + this.getId() + ")");
251                     }
252                 } else if (ASSERT_ACTION_ISINRANGE.equals(this.action
253                     .toUpperCase())) {
254                     if (!((IRange) this.getValue()).isInRange((Comparable) this
255                         .getActualObject())) {
256                         Assert.fail("Expected action: " + this.getAction()
257                                 + ". Got: " + this.getActualObject()
258                                 + " not in " + this.getValue() + " on assert ("
259                                 + this.getId() + ")");
260                     }
261                 } else if (ASSERT_ACTION_ISNOTINRANGE.equals(this.action
262                     .toUpperCase())) {
263                     if (((IRange) this.getValue()).isInRange((Comparable) this
264                         .getActualObject())) {
265                         Assert.fail("Expected action: " + this.getAction()
266                                 + ". Got: " + this.getActualObject() + " in "
267                                 + this.getValue() + " on assert ("
268                                 + this.getId() + ")");
269                     }
270                 }
271             } else {
272                 throw new DDTException(
273                         "Asserted type does not implement Comparable interface: "
274                                 + this.getType());
275             }
276         } else if (ASSERT_ACTION_ISCONTAINEDIN
277             .equals(this.action.toUpperCase())
278                 || ASSERT_ACTION_ISNOTCONTAINEDIN.equals(this.action
279                     .toUpperCase())) {
280             this.markAsProcessed = mark;
281             boolean match = false;
282             RuntimeException assertEx = null;
283             if (ASSERT_ACTION_ISCONTAINEDIN.equals(this.action.toUpperCase())) {
284                 // actual type == array type do separate contain check
285                 if (this.getActualType().startsWith("[L")) {
286                     match = isArrayContainedinList(assertEx);
287                     if (!match) {
288                         throw assertEx;
289                     }
290                 } else {
291                     Assert.assertTrue(
292                         "Object should be member in List on assert ("
293                                 + this.getId() + ")", ((Collection) this
294                             .getValue()).contains(getActualObject()));
295                 }
296             } else {
297                 // actual type == array type do separate contain check
298                 if (this.getActualType().startsWith("[L")) {
299                     match = isArrayContainedinList(assertEx);
300                     if (match) {
301                         throw new AssertionFailedError(
302                                 "Array not found in expected list on assert ("
303                                         + this.getId() + ")");
304                     }
305                 } else {
306                     Assert.assertFalse(
307                         "Object should not be contained in List on assert ("
308                                 + this.getId() + ")", ((Collection) this
309                             .getValue()).contains(getActualObject()));
310                 }
311             }
312         } else {
313             throw new DDTException("Unsupported assert action \"" + this.action
314                     + "\"");
315         }
316     }
317 
318     /**
319      * Check if actual object array is contained in expected list of arrays.
320      * 
321      * @param assertEx is set if no match is found during check
322      * @return true, if match is found, false otherwise
323      */
324     private boolean isArrayContainedinList(RuntimeException assertEx) {
325         boolean match = false;
326         for (Iterator iter = ((Collection) this.getValue()).iterator(); iter
327             .hasNext();) {
328             Object array = iter.next();
329             try {
330                 ArrayAssert.assertEquals((Object[]) array, (Object[]) this
331                     .getActualObject());
332                 match = true;
333                 break;
334             } catch (RuntimeException ex) {
335                 // ignore error, there might be another match
336                 assertEx = ex;
337             }
338         }
339         return match;
340     }
341 
342     /**
343      * 
344      */
345     private void isSameType() {
346         Assert.assertEquals("Class type differs between assert objects, ",
347             getType(),
348             (this.actualObject != null ? getActualType() : getType()));
349     }
350 
351     /**
352      * @return true if this assertion is allready processed
353      */
354     public boolean isValidated() {
355         return validated;
356     }
357 
358     public Object clone() {
359         ObjectAsserter newObj = new ObjectAsserter(this.getId(),
360                 this.getType(), this.getAction());
361         newObj.setValue(this.getValue());
362         return newObj;
363     }
364 
365 }