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

Last change on this file since 10378 was 10225, checked in by Don-vip, 8 years ago

Use Utils.setObjectsAccessible in unit tests

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