Skip to content

Unit-test refactoring; removed some unused code too. #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 4, 2025
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,6 @@ fabric.properties
.idea/**/azureSettings.xml

# End of https://www.toptal.com/developers/gitignore/api/intellij

# Exclude local preference files generated by VSCode editors.
.vscode/
11 changes: 11 additions & 0 deletions lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,22 @@ tasks.named('jar') {

javadoc {
options.tags = [
// Converts `@apiNote` paragraph to "Note: " section in the generated javadoc
'apiNote:a:Api Note:',
// Converts `@implSpec` paragraph to "Implementation Requirements: " section in the generated javadoc
'implSpec:a:Implementation Requirements:'
]
}

// Generates Javadocs for test libraries under /build/docs/testjavadoc
// https://discuss.gradle.org/t/how-configure-gradle-to-generate-javadoc-for-testing-classes-junit/12764/6
task testJavadoc(type: Javadoc) {
source = sourceSets.test.allJava
classpath = sourceSets.test.compileClasspath
destinationDir = file("${buildDir}/docs/testjavadoc")
println (title == null ? '<null>' : title)
}

task sourceJar(type: Jar) {
from sourceSets.main.allJava
archiveClassifier = 'sources'
Expand Down
24 changes: 2 additions & 22 deletions lib/src/main/java/com/team2813/lib2813/util/InputValidation.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,12 @@
package com.team2813.lib2813.util;

import java.util.function.Function;
import java.util.function.IntFunction;

public class InputValidation {
private InputValidation() {
throw new AssertionError("non instantiable");
}

/**
* Check if a given value is between the bounds
*
* @param <T> the type to compare
* @param lower an object that {@code actual} should be comparatively less than or equal to
* @param upper an object that {@code actual} should be comparatively greater than or equal to
* @param actual the actual value
* @param throwable a function that takes the actual value and returns an unchecked exception
* @throws RuntimeException when actual is not between lower and upper, based on natural ordering.
* The exception thrown is provided by {@code throwable}
*/
static <T extends Comparable<T>> void checkBounds(
T lower, T upper, T actual, Function<? super T, ? extends RuntimeException> throwable) {
assert lower.compareTo(upper) <= 0;
if (!(lower.compareTo(actual) <= 0 && actual.compareTo(upper) <= 0)) {
throw throwable.apply(actual);
}
}

/**
* Check if the given value is in the bounds
*
Expand All @@ -37,10 +17,10 @@ static <T extends Comparable<T>> void checkBounds(
* @throws RuntimeException when the actual is not in between the bounds. exception is provided by
* {@code throwable}
*/
static void checkBounds(
private static void checkBounds(
int lower, int upper, int actual, IntFunction<? extends RuntimeException> throwable) {
assert lower <= upper;
if (!(lower <= actual && actual <= upper)) {
if (actual < lower || upper < actual) {
throw throwable.apply(actual);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ public class InvalidCanIdException extends RuntimeException {
*
* @serial an integer that is not between 0 and 62
*/
private int canId;
private final int canId;

public InvalidCanIdException(int canId) {
super(
String.format(
"%d is not a valid can id (a valid can id is between 0 and 62, inclusive)", canId));
this.canId = canId;
if (0 <= canId && canId <= 62) {
throw new IllegalArgumentException(
String.format("%s is a valid can id (it is between 0 and 62, inclusive)", canId));
Expand Down
29 changes: 0 additions & 29 deletions lib/src/test/java/com/team2813/lib2813/theories/Between.java

This file was deleted.

This file was deleted.

This file was deleted.

37 changes: 18 additions & 19 deletions lib/src/test/java/com/team2813/lib2813/util/ControlUtilsTest.java
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
package com.team2813.lib2813.util;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.function.ThrowingRunnable;

public class ControlUtilsTest {
@Test
public void deadbandValuesWithinDeadbandAreZeroed() {
// Keep test values in ascending order.
assertEquals(0.0, ControlUtils.deadband(-0.5, 0.5), 1e-9);
assertEquals(0.0, ControlUtils.deadband(-0.25, 0.5), 1e-9);
assertEquals(0.0, ControlUtils.deadband(0.0, 0.5), 1e-9);
assertEquals(0.0, ControlUtils.deadband(0.5, 0.5), 1e-9);
assertThat(ControlUtils.deadband(-0.5, 0.5)).isEqualTo(0.0);
assertThat(ControlUtils.deadband(-0.5, 0.5)).isEqualTo(0.0);
assertThat(ControlUtils.deadband(-0.25, 0.5)).isEqualTo(0.0);
assertThat(ControlUtils.deadband(0.0, 0.5)).isEqualTo(0.0);
assertThat(ControlUtils.deadband(0.5, 0.5)).isEqualTo(0.0);
}

@Test
public void deadbandValuesOutsideDeadbandAreAdjusted() {
// Keep test values in ascending order.
assertEquals(-1.0, ControlUtils.deadband(-1.0, 0.5), 1e-9);
assertEquals(-0.5, ControlUtils.deadband(-0.75, 0.5), 1e-9);
assertEquals(0.2, ControlUtils.deadband(0.6, 0.5), 1e-9);
assertEquals(0.5, ControlUtils.deadband(0.75, 0.5), 1e-9);
assertEquals(1.0, ControlUtils.deadband(1.0, 0.5), 1e-9);
assertThat(ControlUtils.deadband(-1.0, 0.5)).isWithin(1e-9).of(-1.0);
assertThat(ControlUtils.deadband(-0.75, 0.5)).isWithin(1e-9).of(-0.5);
assertThat(ControlUtils.deadband(0.6, 0.5)).isWithin(1e-9).of(0.2);
assertThat(ControlUtils.deadband(0.75, 0.5)).isWithin(1e-9).of(0.5);
assertThat(ControlUtils.deadband(1.0, 0.5)).isWithin(1e-9).of(1.0);
}

@Test
public void deadbandZeroDeadbandHasNoEffect() {
// Keep test values in ascending order.
assertEquals(-1.0, ControlUtils.deadband(-1.0, 0.0), 1e-9);
assertEquals(-0.5, ControlUtils.deadband(-0.5, 0.0), 1e-9);
assertEquals(-0.25, ControlUtils.deadband(-0.25, 0.0), 1e-9);
assertEquals(0.0, ControlUtils.deadband(0.0, 0.0), 1e-9);
assertEquals(0.5, ControlUtils.deadband(0.5, 0.0), 1e-9);
assertEquals(1.0, ControlUtils.deadband(1.0, 0.0), 1e-9);
assertThat(ControlUtils.deadband(-1.0, 0.0)).isEqualTo(-1.0);
assertThat(ControlUtils.deadband(-0.5, 0.0)).isEqualTo(-0.5);
assertThat(ControlUtils.deadband(-0.25, 0.0)).isEqualTo(-0.25);
assertThat(ControlUtils.deadband(0.0, 0.0)).isEqualTo(0.0);
assertThat(ControlUtils.deadband(0.5, 0.0)).isEqualTo(0.5);
assertThat(ControlUtils.deadband(1.0, 0.0)).isEqualTo(1.0);
}

/**
Expand All @@ -49,7 +48,7 @@ public void deadbandZeroDeadbandHasNoEffect() {
private void assertIllegalArgumentExceptionIsThrownContainingMessage(
ThrowingRunnable testExpression, String expectedMessage) {
Exception exception = assertThrows(IllegalArgumentException.class, testExpression);
assertThat(exception.getMessage(), CoreMatchers.containsString(expectedMessage));
assertThat(exception).hasMessageThat().contains(expectedMessage);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,35 @@
package com.team2813.lib2813.util;

import static org.junit.Assert.assertEquals;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;

import com.team2813.lib2813.theories.Between;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
import org.junit.Test;

@RunWith(Theories.class)
public class InputValidationTest {
private static <T> RuntimeException outOfBounds(T val) {
return new RuntimeException("Value was out of bounds");
}

@Theory
public void invalidCanID(
@Between(first = -50, last = -1) @Between(first = 63, last = 100) int canID) {
InvalidCanIdException expected = new InvalidCanIdException(canID);
InvalidCanIdException actual =
assertThrows(InvalidCanIdException.class, () -> InputValidation.checkCanId(canID));
assertEquals("Messages were not identical", expected, actual);
}

@Theory
public void genericInvalidTest(@Between(first = 0, last = 4) int unused) {
Integer min = Integer.valueOf(0);
Integer actual = Integer.valueOf(unused);
Integer max = Integer.valueOf(4);
InputValidation.checkBounds(min, max, actual, InputValidationTest::outOfBounds);
}
// Tests for the `InputValidation.checkCanId(...)` method.
public static class CheckCanIdTest {
@Test
public void invalidCanId() {
// Can IDs can only valid in the range [0, 62].
int[] invalidCanIds = {-50, -1, 63, 100};
for (int invalidCanId : invalidCanIds) {
InvalidCanIdException exception =
assertThrows(
InvalidCanIdException.class, () -> InputValidation.checkCanId(invalidCanId));
assertThat(exception.getCanId()).isEqualTo(invalidCanId);
assertThat(exception).hasMessageThat().contains("is not a valid can id");
}
}

@Theory
public void validCanID(@Between(first = 0, last = 62) int canID) {
assertEquals(canID, InputValidation.checkCanId(canID));
@Test
public void validCanID() {
// Can IDs can only valid in the range [0, 62].
int[] validCanIds = {0, 1, 10, 62};
for (int validCanId : validCanIds) {
int returnValue = InputValidation.checkCanId(validCanId);
assertWithMessage("Expected a valid CAN ID").that(returnValue).isEqualTo(validCanId);
}
}
}
}
Loading