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

Last change on this file since 17536 was 17275, checked in by Don-vip, 3 years ago

see #16567 - upgrade almost all tests to JUnit 5, except those depending on WiremockRule

See https://github.com/tomakehurst/wiremock/issues/684

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