From 2e5fece594fd2098cdf83290370620d50b36f83a Mon Sep 17 00:00:00 2001 From: Austin Shalit Date: Thu, 24 May 2018 20:39:15 -0400 Subject: [PATCH] Add utility class tests (#871) Checks for classes that only have static methods. --- .../wpi/first/wpilibj/RobotController.java | 1 + .../first/wpilibj/livewindow/LiveWindow.java | 4 + .../smartdashboard/SmartDashboard.java | 4 + .../first/wpilibj/RobotControllerTest.java | 14 ++++ .../wpi/first/wpilibj/UtilityClassTest.java | 73 +++++++++++++++++++ .../wpilibj/livewindow/LiveWindowTest.java | 16 ++++ .../smartdashboard/SmartDashboardTest.java | 16 ++++ 7 files changed, 128 insertions(+) create mode 100644 wpilibj/src/test/java/edu/wpi/first/wpilibj/RobotControllerTest.java create mode 100644 wpilibj/src/test/java/edu/wpi/first/wpilibj/UtilityClassTest.java create mode 100644 wpilibj/src/test/java/edu/wpi/first/wpilibj/livewindow/LiveWindowTest.java create mode 100644 wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboardTest.java diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotController.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotController.java index 5a2b52f3b0..7883b38467 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotController.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotController.java @@ -18,6 +18,7 @@ import edu.wpi.first.wpilibj.hal.PowerJNI; */ public final class RobotController { private RobotController() { + throw new UnsupportedOperationException("This is a utility class!"); } /** diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java index a0d65203da..5ed193258c 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java @@ -45,6 +45,10 @@ public class LiveWindow { private static boolean liveWindowEnabled = false; private static boolean telemetryEnabled = true; + private LiveWindow() { + throw new UnsupportedOperationException("This is a utility class!"); + } + public static synchronized boolean isEnabled() { return liveWindowEnabled; } diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboard.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboard.java index e8ab5fd634..791c47709f 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboard.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboard.java @@ -51,6 +51,10 @@ public class SmartDashboard { HLUsageReporting.reportSmartDashboard(); } + private SmartDashboard() { + throw new UnsupportedOperationException("This is a utility class!"); + } + /** * Maps the specified key to the specified value in this table. The key can not be null. The value * can be retrieved by calling the get method with a key that is equal to the original key. diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/RobotControllerTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/RobotControllerTest.java new file mode 100644 index 0000000000..055488ad16 --- /dev/null +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/RobotControllerTest.java @@ -0,0 +1,14 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2018 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.wpilibj; + +public class RobotControllerTest extends UtilityClassTest { + public RobotControllerTest() { + super(RobotController.class); + } +} diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/UtilityClassTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/UtilityClassTest.java new file mode 100644 index 0000000000..0814a5ddad --- /dev/null +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/UtilityClassTest.java @@ -0,0 +1,73 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2018 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.wpilibj; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +@SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod") +public abstract class UtilityClassTest { + @Before + public void setup() { + UnitTestUtility.setupMockBase(); + } + + private final Class m_clazz; + + protected UtilityClassTest(Class clazz) { + m_clazz = clazz; + } + + @Test + public void testSingleConstructor() { + assertEquals("More than one constructor defined", 1, + m_clazz.getDeclaredConstructors().length); + } + + @Test + public void testConstructorPrivate() { + Constructor constructor = m_clazz.getDeclaredConstructors()[0]; + + assertFalse("Constructor is not private", constructor.isAccessible()); + } + + @Test(expected = InvocationTargetException.class) + public void testConstructorReflection() throws Throwable { + Constructor constructor = m_clazz.getDeclaredConstructors()[0]; + constructor.setAccessible(true); + constructor.newInstance(); + } + + @Test + public void testPublicMethodsStatic() { + List failures = new ArrayList<>(); + for (Method method : m_clazz.getDeclaredMethods()) { + int modifiers = method.getModifiers(); + if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) { + failures.add(method.toString()); + } + } + + if (!failures.isEmpty()) { + fail("Found public methods that are not static: " + + Arrays.toString(failures.toArray())); + } + } +} diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/livewindow/LiveWindowTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/livewindow/LiveWindowTest.java new file mode 100644 index 0000000000..e7a90eaadd --- /dev/null +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/livewindow/LiveWindowTest.java @@ -0,0 +1,16 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2018 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.wpilibj.livewindow; + +import edu.wpi.first.wpilibj.UtilityClassTest; + +public class LiveWindowTest extends UtilityClassTest { + public LiveWindowTest() { + super(LiveWindow.class); + } +} diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboardTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboardTest.java new file mode 100644 index 0000000000..99d90ed848 --- /dev/null +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboardTest.java @@ -0,0 +1,16 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2018 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.wpilibj.smartdashboard; + +import edu.wpi.first.wpilibj.UtilityClassTest; + +public class SmartDashboardTest extends UtilityClassTest { + public SmartDashboardTest() { + super(SmartDashboard.class); + } +}