2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.viewmodel.styles;
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertTrue;
27 import jalview.gui.JvOptionPane;
29 import java.awt.Color;
30 import java.lang.reflect.Field;
31 import java.util.Random;
33 import org.testng.AssertJUnit;
34 import org.testng.annotations.BeforeClass;
35 import org.testng.annotations.Test;
37 public class ViewStyleTest
40 @BeforeClass(alwaysRun = true)
41 public void setUpJvOptionPane()
43 JvOptionPane.setInteractiveMode(false);
44 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
47 Random r = new Random();
50 * This test uses reflection to set all fields on a ViewStyle, make a copy of
51 * it, and verify all fields match. This test should fail if a getter/setter
52 * pair are added to the class but missing in the copy constructor. Using
53 * reflection in the copy constructor itself is broken by obfuscation when the
56 * To prove this test works, simply comment out a line in the ViewStyle copy
57 * constructor, or add a new member field to ViewStyle.
59 * @throws IllegalAccessException
60 * @throws IllegalArgumentException
62 @Test(groups = { "Functional" })
63 public void testCopyConstructor()
64 throws IllegalArgumentException, IllegalAccessException
66 ViewStyle vs1 = new ViewStyle();
67 Field[] fields = ViewStyle.class.getDeclaredFields();
68 for (Field field : fields)
70 field.setAccessible(true);
71 if (!copyConstructorIgnores(field))
73 changeValue(vs1, field);
77 ViewStyle vs2 = new ViewStyle(vs1);
79 for (Field field1 : fields)
81 if (!copyConstructorIgnores(field1))
83 final Object value1 = field1.get(vs1);
84 final Object value2 = field1.get(vs2);
85 String msg = "Mismatch in " + field1.getName() + "(" + value1 + "/"
86 + value2 + ") - not set in copy constructor?";
87 assertEquals(msg, value1, value2);
90 assertEquals("Hashcode not equals", vs1.hashCode(), vs2.hashCode());
94 * Add tests here for any fields that we expect to be ignored by the copy
100 private boolean copyConstructorIgnores(Field field)
103 * ignore instrumentation added by jacoco for test coverage
105 if (field.isSynthetic())
109 if (field.getType().toString().contains("com_atlassian_clover"))
118 * Change the value of one field in a ViewStyle object
122 * @throws IllegalAccessException
124 protected void changeValue(ViewStyle vs, Field field)
125 throws IllegalAccessException
127 Class<?> type = field.getType();
129 if (type.equals(boolean.class) || type.equals(Boolean.class))
131 boolean value = (Boolean) field.get(vs);
132 // System.out.println("Setting " + field.getName() + " to " + !value);
133 field.set(vs, !value);
135 else if (type.equals(short.class) || type.equals(int.class)
136 || type.equals(long.class) || type.equals(float.class)
137 || type.equals(double.class))
139 final int value = (int) (1 + field.getDouble(vs));
140 // System.out.println("Setting " + field.getName() + " to " + value);
141 field.set(vs, value);
143 else if (type.equals(Integer.class))
145 field.set(vs, (int) (1 + getNumberValue(field, vs)));
147 else if (type.equals(Float.class))
149 field.set(vs, (float) (1f + getNumberValue(field, vs)));
151 else if (type.equals(Long.class))
153 field.set(vs, (long) (1L + getNumberValue(field, vs)));
155 else if (type.equals(Double.class))
157 field.set(vs, 1d + getNumberValue(field, vs));
159 else if (type.equals(Short.class))
161 field.set(vs, (short) (1 + getNumberValue(field, vs)));
163 else if (type.equals(Byte.class))
165 field.set(vs, (byte) (1 + getNumberValue(field, vs)));
167 else if (type.equals(Character.class))
169 field.set(vs, (char) (1 + getNumberValue(field, vs)));
171 else if (type.equals(String.class))
173 field.set(vs, "Joe" + field.get(vs));
175 else if (type.equals(Color.class))
178 Color.RED.equals(field.get(vs)) ? Color.BLACK : Color.RED);
182 AssertJUnit.fail("Unhandled field type (add to test): "
183 + field.getName() + ":" + type);
187 private double getNumberValue(Field field, ViewStyle vs)
188 throws IllegalArgumentException, IllegalAccessException
190 if (field.get(vs) == null)
194 return ((Number) field.get(vs)).doubleValue();
198 * Test that the equals method compares every field by changing them one by
199 * one in a cloned ViewStyle.
201 * This test will fail if a new field is added to ViewStyle but not to the
202 * comparisons in ViewStyle.equals().
204 * To confirm that this test works, temporarily comment out one of the field
205 * comparisons in ViewStyle.equals()
207 * @throws IllegalAccessException
208 * @throws IllegalArgumentException
210 @Test(groups = { "Functional" })
211 public void testEquals()
212 throws IllegalArgumentException, IllegalAccessException
214 ViewStyle vs1 = new ViewStyle();
215 ViewStyle vs2 = new ViewStyle(vs1);
217 assertFalse(vs1.equals(null));
218 assertFalse(vs1.equals(this));
219 assertTrue(vs1.equals(vs2));
220 assertTrue(vs2.equals(vs1));
222 Field[] fields = ViewStyle.class.getDeclaredFields();
223 for (Field field : fields)
225 if (!copyConstructorIgnores(field))
227 field.setAccessible(true);
228 Object oldValue = field.get(vs2);
229 changeValue(vs2, field);
230 assertFalse("equals method ignores " + field.getName(),
233 if (vs1.hashCode() == vs2.hashCode())
235 // uncomment next line to see which fields hashCode ignores
236 // System.out.println("hashCode ignores " + field.getName());
238 // restore original value before testing the next field
239 field.set(vs2, oldValue);