1 package net.sf.openrocket.rocketcomponent;
3 import static org.junit.Assert.*;
5 import java.lang.reflect.Method;
6 import java.util.Iterator;
7 import java.util.regex.Pattern;
9 import net.sf.openrocket.util.BugException;
11 public class ComponentCompare {
13 private static final Pattern GETTER_PATTERN = Pattern.compile("^(is|get)[A-Z].*+");
15 private static final String[] IGNORED_METHODS = {
16 "getClass", "getChildCount", "getChildren", "getNextComponent", "getID",
17 "getPreviousComponent", "getParent", "getRocket", "getRoot", "getStage",
18 "getStageNumber", "getComponentName",
19 // Rocket specific methods:
20 "getModID", "getMassModID", "getAerodynamicModID", "getTreeModID", "getFunctionalModID",
21 "getMotorConfigurationIDs", "getDefaultConfiguration"
26 * Check whether the two components are <em>equal</em>. Two components are considered
27 * equal if they are of the same type and all of their getXXX() and isXXX() methods
28 * return equal values.
30 * @param c1 the first component to compare.
31 * @param c2 the second component to compare.
33 public static void assertEquality(RocketComponent c1, RocketComponent c2) {
34 assertEquals(c1.getClass(), c2.getClass());
36 // Same class + similar == equal
37 assertSimilarity(c1, c2);
42 public static void assertDeepEquality(RocketComponent c1, RocketComponent c2) {
43 assertEquality(c1, c2);
45 Iterator<RocketComponent> i1 = c1.iterator();
46 Iterator<RocketComponent> i2 = c2.iterator();
47 while (i1.hasNext()) {
48 assertTrue("iterator continues", i2.hasNext());
49 RocketComponent comp1 = i1.next();
50 RocketComponent comp2 = i2.next();
51 assertDeepEquality(comp1, comp2);
53 assertFalse("iterator end", i2.hasNext());
58 public static void assertDeepSimilarity(RocketComponent c1, RocketComponent c2,
59 boolean allowNameDifference) {
60 assertSimilarity(c1, c2, allowNameDifference);
62 Iterator<RocketComponent> i1 = c1.iterator();
63 Iterator<RocketComponent> i2 = c2.iterator();
64 while (i1.hasNext()) {
65 assertTrue("iterator continues", i2.hasNext());
66 RocketComponent comp1 = i1.next();
67 RocketComponent comp2 = i2.next();
68 assertDeepSimilarity(comp1, comp2, allowNameDifference);
70 assertFalse("iterator end", i2.hasNext());
76 * Check whether the two components are <em>similar</em>. Two components are similar
77 * if each of the getXXX and isXXX methods that both object types have return
78 * equal values. This does not check whether the two components are of the same type.
80 * @param c1 the first component.
81 * @param c2 the second component.
83 public static void assertSimilarity(RocketComponent c1, RocketComponent c2) {
84 assertSimilarity(c1, c2, false);
88 * Check whether the two components are <em>similar</em>, allowing a name difference.
90 * @param c1 the first component.
91 * @param c2 the second component.
92 * @param allowNameDifference whether to allow the components to have different names.
94 public static void assertSimilarity(RocketComponent c1, RocketComponent c2,
95 boolean allowNameDifference) {
96 Class<? extends RocketComponent> class1 = c1.getClass();
97 Class<? extends RocketComponent> class2 = c2.getClass();
99 mainloop: for (Method m1 : class1.getMethods()) {
100 // Check for getter method
101 String name = m1.getName();
102 if (!GETTER_PATTERN.matcher(name).matches())
105 // Ignore methods that take parameters
106 if (m1.getParameterTypes().length != 0)
109 // Ignore specific getters
110 for (String ignore : IGNORED_METHODS) {
111 if (name.equals(ignore))
114 if (allowNameDifference && name.equals("getName"))
118 // Check for method in other class
121 m2 = class2.getMethod(name);
122 } catch (NoSuchMethodException e) {
126 // System.out.println("Testing results of method " + name);
129 Object result1, result2;
131 result1 = m1.invoke(c1);
132 result2 = m2.invoke(c2);
133 } catch (Exception e) {
134 throw new BugException("Error executing method " + name, e);
137 if (result1 != null && result2 != null &&
138 result1.getClass().isArray() && result2.getClass().isArray()) {
139 assertArrayEquals("Comparing result of method " + name,
140 (Object[]) result1, (Object[]) result2);
142 assertEquals("Comparing result of method " + name, result1, result2);