source: josm/trunk/test/unit/org/openstreetmap/josm/gui/TableCellRendererTest.java@ 12799

Last change on this file since 12799 was 12632, checked in by Don-vip, 7 years ago

see #15182 - fix unit tests

  • Property svn:eol-style set to native
File size: 4.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.junit.Assert.assertNotNull;
5
6import java.lang.reflect.Constructor;
7import java.lang.reflect.Modifier;
8import java.util.Arrays;
9import java.util.Collection;
10import java.util.Set;
11
12import javax.swing.JTable;
13import javax.swing.table.TableCellRenderer;
14
15import org.junit.Assert;
16import org.junit.Rule;
17import org.junit.Test;
18import org.openstreetmap.josm.testutils.JOSMTestRules;
19import org.openstreetmap.josm.tools.Utils;
20import org.reflections.Reflections;
21
22import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
23
24/**
25 * Checks if all classes implementing the {@link TableCellRenderer} interface do
26 * accept a null value as second parameter for
27 * {@link TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable,
28 * java.lang.Object, boolean, boolean, int, int)}.
29 *
30 * For unknown reason java sometimes call getTableCellRendererComponent method
31 * with value = null. Every implementation of {@code getTableCellRendererComponent}
32 * must fail gracefully when null is passed as value parameter.
33 *
34 * This test scans the classpath for classes implementing {@code TableCellRenderer},
35 * creates an instance and calls {@code getTableCellRendererComponent} with null
36 * value to check if a NPE is thrown.
37 *
38 * @see <a href="https://josm.openstreetmap.de/ticket/6301">#6301</a>
39 */
40public class TableCellRendererTest {
41
42 // list of classes that cannot be easily tested and are verified either manually or another unit tests
43 private static final Collection<String> SKIP_TEST = Arrays.asList(
44 "org.openstreetmap.josm.gui.dialogs.FilterDialog$BooleanRenderer",
45 "org.openstreetmap.josm.gui.dialogs.relation.SelectionTableCellRenderer"
46 );
47
48 /**
49 * Setup test.
50 */
51 @Rule
52 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
53 public JOSMTestRules test = new JOSMTestRules().platform().main();
54
55 /**
56 * Unit test of all table cell renderers against null values.
57 * @throws NoSuchMethodException no default constructor - to fix this, add a default constructor to the class
58 * or add the class to the SKIP_TEST list above
59 * @throws ReflectiveOperationException if an error occurs
60 */
61 @Test
62 public void testTableCellRenderer() throws ReflectiveOperationException {
63 Reflections reflections = new Reflections("org.openstreetmap.josm");
64 Set<Class<? extends TableCellRenderer>> renderers = reflections.getSubTypesOf(TableCellRenderer.class);
65 Assert.assertTrue(renderers.size() >= 10); // if it finds less than 10 classes, something is broken
66 JTable tbl = new JTable(2, 2);
67 for (Class<? extends TableCellRenderer> klass : renderers) {
68 if (Modifier.isAbstract(klass.getModifiers()) || SKIP_TEST.contains(klass.getName())) {
69 continue;
70 }
71 if (klass.isAnonymousClass()) {
72 continue;
73 }
74 assertNotNull(createInstance(klass).getTableCellRendererComponent(tbl, null, false, false, 0, 0));
75 }
76 }
77
78 /**
79 * Create an instance of a class assuming it has a no-args constructor.
80 * @param <T> the class or a super-type of the class
81 * @param klass the class
82 * @return an instance of the class
83 * @throws NoSuchMethodException no default constructor - to fix this, add a default constructor to the class
84 * or add the class to the SKIP_TEST list above
85 * @throws ReflectiveOperationException if an error occurs
86 */
87 private static <T> T createInstance(Class<? extends T> klass) throws ReflectiveOperationException {
88 boolean needOuterClass = klass.isMemberClass() && !Modifier.isStatic(klass.getModifiers());
89 Constructor<? extends T> c;
90 if (needOuterClass) {
91 c = klass.getDeclaredConstructor(klass.getDeclaringClass());
92 } else {
93 c = klass.getDeclaredConstructor();
94 }
95 Utils.setObjectsAccessible(c);
96 if (needOuterClass) {
97 return c.newInstance(createInstance(klass.getDeclaringClass()));
98 } else {
99 return c.newInstance();
100 }
101 }
102}
Note: See TracBrowser for help on using the repository browser.