diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..3b36a2b --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,51 @@ +# This is a basic workflow to build robot code. + +name: CI + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the main branch. +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # This grabs the WPILib docker container + container: wpilib/roborio-cross-ubuntu:2023-22.04 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v3 + + # Declares the repository safe and not under dubious ownership. + - name: Add repository to git safe directories + run: git config --global --add safe.directory $GITHUB_WORKSPACE + + # Grant execute permission for gradlew + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + # Runs a single command using the runners shell + - name: Compile and run tests on robot code + run: ./gradlew build + + # Runs JaCoCo test coverage + - name: Create Unit Test Coverage report + run: ./gradlew jacocoTestReport + + - name: Add coverage to PR + id: jacoco + uses: madrapps/jacoco-report@v1.3 + with: + paths: ${{ github.workspace }}/build/reports/jacoco/test/jacocoTestReport.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 40 + min-coverage-changed-files: 60 diff --git a/README.md b/README.md index c903da6..133bf95 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # tigerlib - FRC Java Programs: Now with 100% Less Boilerplate -[![](https://jitpack.io/v/itrt4176/tigerlib.svg)](https://jitpack.io/#itrt4176/tigerlib) +[![CI](https://github.com/limited/tigerlib/actions/workflows/main.yml/badge.svg?branch=develop&event=push)](https://github.com/limited/tigerlib/actions/workflows/main.yml) [![](https://jitpack.io/v/itrt4176/tigerlib.svg)](https://jitpack.io/#itrt4176/tigerlib) **THIS IS BETA SOFTWARE! USE WITH CAUTION** @@ -20,10 +20,10 @@ tigerlib is a library meant at reducing the year to year recreation of nearly id ```Gradle dependencies { ... - implementation 'com.github.itrt4176:tigerlib:v2022.1.0-rc1' + implementation 'com.github.itrt4176:tigerlib:v2023.1.0-beta1' } ``` ## Usage -Check our project wiki (*coming soon*) for tutorials and our [javadoc](https://javadoc.jitpack.io/com/github/itrt4176/tigerlib/v2022.1.0-rc1/javadoc/index.html) for the full API. \ No newline at end of file +Check our project wiki (*coming soon*) for tutorials and our [javadoc](https://javadoc.jitpack.io/com/github/itrt4176/tigerlib/v2022.1.0-rc1/javadoc/index.html) for the full API. diff --git a/build.gradle b/build.gradle index 572ce43..d06e605 100644 --- a/build.gradle +++ b/build.gradle @@ -2,13 +2,15 @@ plugins { id "edu.wpi.first.GradleRIO" version "2023.2.1" id "java-library" id "maven-publish" + id 'jacoco' } + repositories { mavenCentral() maven { url "https://frcmaven.wpi.edu/artifactory/release/" - } + } } version = "2023.1.0-beta1" @@ -17,13 +19,24 @@ group = "com.github.itrt4176" sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 - - // Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. // Also defines JUnit 4. dependencies { - compileOnly wpi.java.deps.wpilib() - compileOnly wpi.java.vendor.java() + implementation wpi.java.deps.wpilib() + implementation wpi.java.vendor.java() + + nativeDebug wpi.java.deps.wpilibJniDebug(wpi.platforms.desktop) + nativeDebug wpi.java.vendor.jniDebug(wpi.platforms.desktop) + simulationDebug wpi.sim.enableDebug() + + nativeRelease wpi.java.deps.wpilibJniRelease(wpi.platforms.desktop) + nativeRelease wpi.java.vendor.jniRelease(wpi.platforms.desktop) + simulationRelease wpi.sim.enableRelease() + + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2' + testImplementation "org.mockito:mockito-core:3.+" + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' } java { @@ -36,6 +49,33 @@ javadoc { options.links = ['https://docs.oracle.com/en/java/javase/17/docs/api/', 'https://github.wpilib.org/allwpilib/docs/release/java/'] } +test { + useJUnitPlatform() + systemProperty 'junit.jupiter.extensions.autodetection.enabled', 'true' + maxHeapSize = '1G' + + testLogging { + events "passed" + } + + finalizedBy jacocoTestReport // report is always generated after tests run +} + +wpi.java.configureExecutableTasks(jar) +wpi.java.configureTestTasks(test) + +jacoco { + toolVersion = "0.8.8" +} + +jacocoTestReport { + dependsOn test // tests are required to run before generating the report + reports { + xml.required = true + html.outputLocation = layout.buildDirectory.dir('jacocoHtml') + } +} + artifacts { archives sourcesJar archives javadocJar @@ -46,7 +86,7 @@ publishing { mavenJava(MavenPublication) { groupId = 'com.github.itrt4176' artifactId = 'tigerlib' - version = '2023.1.0-alpha' + version = '2023.1.0-beta1' from components.java } diff --git a/src/test/java/frc/tigerlib/interpolable/InterpolatingDoubleTest.java b/src/test/java/frc/tigerlib/interpolable/InterpolatingDoubleTest.java new file mode 100644 index 0000000..cf56c71 --- /dev/null +++ b/src/test/java/frc/tigerlib/interpolable/InterpolatingDoubleTest.java @@ -0,0 +1,54 @@ +package frc.tigerlib.interpolable; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.Test; + +public class InterpolatingDoubleTest { + + @Test + void testInterpolatePositives() { + InterpolatingDouble a = new InterpolatingDouble(0.0); + InterpolatingDouble b = new InterpolatingDouble(10.0); + assertEquals(5, a.interpolate(b, .5).value); + } + + @Test + void testInterpolateMixedSigns() { + InterpolatingDouble a = new InterpolatingDouble(3.0); + InterpolatingDouble b = new InterpolatingDouble(-3.0); + assertEquals(2.4, a.interpolate(b, .1).value); + } + + @Test + void testInverseInterpolateGood() { + InterpolatingDouble a = new InterpolatingDouble(0.0); + InterpolatingDouble b = new InterpolatingDouble(10.0); + InterpolatingDouble c = new InterpolatingDouble(5.0); + assertEquals(a.inverseInterpolate(b, c), .5); + } + + @Test + void testInverseInterpolateErrors() { + InterpolatingDouble a = new InterpolatingDouble(0.0); + InterpolatingDouble b = new InterpolatingDouble(10.0); + InterpolatingDouble c = new InterpolatingDouble(5.0); + assertEquals(b.inverseInterpolate(a, c), 0); + assertEquals(b.inverseInterpolate(a, c), 0); + } + + @Test + void testCompareMatch() { + InterpolatingDouble a = new InterpolatingDouble(3.0); + InterpolatingDouble b = new InterpolatingDouble(3.0); + assertEquals(a.compareTo(b), 0); + } + + @Test + void testCompareNotMatch() { + InterpolatingDouble a = new InterpolatingDouble(3.0); + InterpolatingDouble b = new InterpolatingDouble(5.0); + assertNotEquals(a.compareTo(b), 0); + } +} diff --git a/src/test/java/frc/tigerlib/subsystem/drive/DifferentialDriveSubsystemTest.java b/src/test/java/frc/tigerlib/subsystem/drive/DifferentialDriveSubsystemTest.java new file mode 100644 index 0000000..634f56d --- /dev/null +++ b/src/test/java/frc/tigerlib/subsystem/drive/DifferentialDriveSubsystemTest.java @@ -0,0 +1,35 @@ +package frc.tigerlib.subsystem.drive; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.Mockito; + +import edu.wpi.first.math.geometry.Rotation2d; +import edu.wpi.first.wpilibj.interfaces.Gyro; +import edu.wpi.first.wpilibj.motorcontrol.MotorController; + + +public class DifferentialDriveSubsystemTest { + + @Mock + private Gyro mockGyro = Mockito.mock(Gyro.class); + + + @Test + void testSetMotors() { + DifferentialDriveSubsystem driveSub = Mockito.mock(DifferentialDriveSubsystem.class, Mockito.CALLS_REAL_METHODS); + when(mockGyro.getRotation2d()).thenReturn(new Rotation2d()); + driveSub.setGyro(mockGyro); + + + MotorController l = Mockito.mock(MotorController.class); + MotorController r = Mockito.mock(MotorController.class); + + driveSub.setMotors(l, r); + verify(r).setInverted(true); + + } +} diff --git a/vendordeps/WPILibNewCommands.json b/vendordeps/WPILibNewCommands.json index d7bd9b0..02fd650 100644 --- a/vendordeps/WPILibNewCommands.json +++ b/vendordeps/WPILibNewCommands.json @@ -30,7 +30,7 @@ "windowsx86-64", "windowsx86", "linuxx86-64", - "osxx86-64" + "osxuniversal" ] } ]