From f789fb2387694a355dc92b34b7fb1468eb61ccd8 Mon Sep 17 00:00:00 2001 From: Sam Carlberg Date: Wed, 17 Apr 2019 18:56:23 -0400 Subject: [PATCH] Update to Java 11 (#932) * Update to Java 11 and use jpackage for building installers jpackage requires a version of JDK13 installed with jpackage from https://jdk.java.net/jpackage/ and passed with -Pjdk13=/path/to/jdk-13 Remove Grgit Update PMD to 6.7.0 for Java 11 support Disable errorprone Disable UI tests, since they no longer work when headless and are flaky otherwise. Can still be run with Java 8 * Remove dependency on Guava in annotation processor * Support running on JDK 8 to run UI tests * Roll shadow plugin back to 4.0.1 to avoid issues with :core:shadowjar * Add mac agent dedicated for UI tests and JaCoCo reports --- .travis.yml | 21 -- .../processor/ClassListProcessor.java | 19 +- appveyor.yml | 23 -- azure-pipelines.yml | 113 +++++-- build.gradle.kts | 66 +--- buildSrc/README.md | 4 + buildSrc/build.gradle.kts | 8 + buildSrc/src/main/kotlin/BuildType.kt | 32 ++ buildSrc/src/main/kotlin/JavaFXExtensions.kt | 26 ++ buildSrc/src/main/kotlin/JpackageExec.kt | 313 ++++++++++++++++++ .../src/main/kotlin/NativeConfigurations.kt | 89 +++++ buildSrc/src/main/kotlin/PlatformMapper.kt | 53 +++ buildSrc/src/main/kotlin/ktgit.kt | 45 +++ .../checkstyle/checkstyle.xml | 2 +- .../checkstyle/checkstyleSuppressions.xml | 0 core/core.gradle.kts | 2 - .../java/edu/wpi/grip/core/Connection.java | 2 +- .../wpi/grip/core/CoreCommandLineHelper.java | 28 +- .../edu/wpi/grip/core/GripCoreModule.java | 2 +- .../main/java/edu/wpi/grip/core/Pipeline.java | 12 +- .../main/java/edu/wpi/grip/core/Source.java | 14 +- .../src/main/java/edu/wpi/grip/core/Step.java | 2 +- .../grip/core/events/StopPipelineEvent.java | 2 - .../edu/wpi/grip/core/http/GripServer.java | 11 +- .../grip/core/metrics/BenchmarkRunner.java | 1 + .../wpi/grip/core/metrics/CsvExporter.java | 2 +- .../grip/core/operations/CVOperations.java | 1 + .../operations/PythonScriptOperation.java | 1 - .../operations/composite/BlurOperation.java | 1 + .../composite/CannyEdgeOperation.java | 3 + .../operations/composite/ContoursReport.java | 2 +- .../composite/FilterContoursOperation.java | 1 + .../composite/PublishVideoOperation.java | 2 +- .../composite/SaveImageOperation.java | 1 + .../composite/ThresholdOperation.java | 11 +- .../network/BooleanPublishable.java | 1 + .../network/MapNetworkPublisher.java | 4 +- .../network/ros/JavaToMessageConverter.java | 13 +- .../operations/network/ros/ROSManager.java | 9 +- ...FiveSourceOneDestinationCudaOperation.java | 1 + ...FourSourceOneDestinationCudaOperation.java | 1 + .../OneSourceOneDestinationCudaOperation.java | 1 + ...evenSourceOneDestinationCudaOperation.java | 2 + .../SixSourceOneDestinationCudaOperation.java | 2 + .../operations/templated/TemplateFactory.java | 1 + ...hreeSourceOneDestinationCudaOperation.java | 1 + .../TwoSourceOneDestinationCudaOperation.java | 1 + .../wpi/grip/core/serialization/Project.java | 5 +- .../core/serialization/SocketConverter.java | 16 +- .../core/serialization/StepConverter.java | 3 - .../wpi/grip/core/sockets/SocketHints.java | 3 + .../wpi/grip/core/sources/CameraSource.java | 7 +- .../grip/core/sources/ClassifierSource.java | 9 +- .../grip/core/sources/ImageFileSource.java | 2 +- .../core/sources/MultiImageFileSource.java | 3 +- .../grip/core/sources/VideoFileSource.java | 1 + .../wpi/grip/core/util/ExceptionWitness.java | 1 + .../grip/core/util/ImageLoadingUtility.java | 6 +- .../edu/wpi/grip/core/util/MetaInfReader.java | 10 +- .../edu/wpi/grip/core/util/SafeShutdown.java | 4 + .../util/service/AutoRestartingService.java | 1 + .../grip/core/CoreCommandLineHelperTest.java | 10 +- .../edu/wpi/grip/core/CoreSanityTest.java | 8 +- .../wpi/grip/core/ManualPipelineRunner.java | 1 + .../edu/wpi/grip/core/PipelineRunnerTest.java | 3 +- .../wpi/grip/core/cuda/CudaVerifierTest.java | 1 + .../core/http/HttpPipelineSwitcherTest.java | 1 + .../grip/core/metrics/CsvExporterTest.java | 2 +- .../core/operations/OperationsFactory.java | 2 + .../network/MapNetworkPublisherTest.java | 6 +- .../network/NetworkPublisherTest.java | 8 +- .../PublishAnnotatedOperationTest.java | 6 +- .../operations/opencv/AddOperationTest.java | 5 +- .../grip/core/sources/CameraSourceTest.java | 6 +- .../grip/core/sources/GrabberServiceTest.java | 6 +- .../grip/core/sources/MockCameraSource.java | 1 + .../sources/MultiImageFileSourceTest.java | 4 + .../wpi/grip/core/util/SafeShutdownTest.java | 1 + .../service/AutoRestartingServiceTest.java | 6 +- findBugsSuppressions.xml | 5 + pmd-ruleset.xml | 84 +++-- .../linux/GRIP.png | Bin .../macosx => installer-files/mac}/GRIP.icns | Bin ui/installer-files/win/GRIP-setup-icon.bmp | Bin 0 -> 6968 bytes .../win/file-associations.properties | 4 + ui/installer-files/win/grip_TP6_icon.ico | Bin 0 -> 140206 bytes ui/preloader/preloader.gradle.kts | 13 +- .../edu/wpi/grip/preloader/GripPreloader.java | 4 - .../java/edu/wpi/grip/preloader/Launch.java | 21 ++ ui/src/main/deploy/package/windows/GRIP.ico | Bin 370070 -> 0 bytes .../wpi/grip/ui/AboutDialogController.java | 7 +- .../edu/wpi/grip/ui/DeployController.java | 8 +- .../java/edu/wpi/grip/ui/GripUiModule.java | 1 + ui/src/main/java/edu/wpi/grip/ui/Launch.java | 26 ++ ui/src/main/java/edu/wpi/grip/ui/Main.java | 6 +- .../edu/wpi/grip/ui/MainWindowController.java | 8 +- .../grip/ui/analysis/AnalysisController.java | 2 +- .../grip/ui/codegeneration/CppTMethods.java | 3 - .../grip/ui/codegeneration/JavaTMethods.java | 3 - .../ui/codegeneration/PythonTMethods.java | 3 - .../grip/ui/codegeneration/data/TInput.java | 8 +- .../ui/codegeneration/data/TPipeline.java | 22 +- .../grip/ui/codegeneration/data/TSocket.java | 8 +- .../wpi/grip/ui/components/LogTextArea.java | 2 +- .../ui/components/PreviousNextButtons.java | 4 + .../ui/components/StartStoppableButton.java | 6 +- .../wpi/grip/ui/pipeline/AddSourceButton.java | 1 + .../ui/pipeline/OutputSocketController.java | 11 +- .../grip/ui/pipeline/PipelineController.java | 6 +- .../grip/ui/pipeline/SocketHandleView.java | 1 + .../wpi/grip/ui/pipeline/StepController.java | 2 + .../pipeline/input/InputSocketController.java | 1 + .../ListSpinnerInputSocketController.java | 6 +- .../grip/ui/preview/PreviewsController.java | 2 +- .../edu/wpi/grip/ui/util/GripPlatform.java | 2 +- .../edu/wpi/grip/ui/util/ImageConverter.java | 2 +- .../edu/wpi/grip/ui/util/SearchUtility.java | 6 +- .../java/edu/wpi/grip/ui/MainWindowTest.java | 2 + .../java/edu/wpi/grip/ui/PaletteTest.java | 2 + ui/src/test/java/edu/wpi/grip/ui/UiTests.java | 4 + .../AbstractGenerationTesting.java | 2 +- .../codegeneration/BlurGenerationTesting.java | 5 +- .../ConvexHullsGenerationTesting.java | 5 +- .../DesaturateGenerationTesting.java | 5 +- .../DistanceTransformGenerationTesting.java | 9 +- .../FilterContoursGenerationTesting.java | 5 +- .../FilterLinesGenerationTesting.java | 11 +- .../FindBlobsGenerationTesting.java | 13 +- .../FindContoursGenerationTesting.java | 5 +- .../FindLinesGenerationTesting.java | 13 +- .../ui/codegeneration/GripIconHSLSetup.java | 5 +- .../HSLThresholdGenerationTesting.java | 1 + .../ui/codegeneration/HSVThresholdSetup.java | 9 +- .../codegeneration/HSVThresholdTesting.java | 5 +- .../grip/ui/codegeneration/MaskTesting.java | 5 +- .../NewPointGenerationTesting.java | 5 +- .../NewSizeGenerationTesting.java | 5 +- .../NormalizeGenerationTesting.java | 5 +- .../codegeneration/RGBThresholdTesting.java | 6 +- .../grip/ui/codegeneration/ResizeTesting.java | 5 +- .../grip/ui/codegeneration/SwitchTesting.java | 12 +- .../ThresholdMovingTesting.java | 13 +- .../grip/ui/codegeneration/ValveTesting.java | 5 +- .../WatershedGenerationTesting.java | 5 +- .../grip/ui/codegeneration/cv/CVAbsDiff.java | 5 +- .../cv/CVAdaptiveThreshold.java | 5 +- .../wpi/grip/ui/codegeneration/cv/CVAdd.java | 5 +- .../ui/codegeneration/cv/CVAddWeighted.java | 5 +- .../ui/codegeneration/cv/CVApplyColorMap.java | 7 +- .../ui/codegeneration/cv/CVBitwiseAnd.java | 5 +- .../ui/codegeneration/cv/CVBitwiseNot.java | 5 +- .../ui/codegeneration/cv/CVBitwiseOr.java | 5 +- .../ui/codegeneration/cv/CVBitwiseXor.java | 5 +- .../grip/ui/codegeneration/cv/CVCanny.java | 5 +- .../grip/ui/codegeneration/cv/CVCompare.java | 5 +- .../grip/ui/codegeneration/cv/CVDilate.java | 5 +- .../grip/ui/codegeneration/cv/CVDivide.java | 5 +- .../grip/ui/codegeneration/cv/CVErode.java | 5 +- .../codegeneration/cv/CVExtractChannel.java | 5 +- .../wpi/grip/ui/codegeneration/cv/CVFlip.java | 5 +- .../ui/codegeneration/cv/CVGaussianBlur.java | 5 +- .../ui/codegeneration/cv/CVLaplacian.java | 5 +- .../wpi/grip/ui/codegeneration/cv/CVMax.java | 5 +- .../ui/codegeneration/cv/CVMedianBlur.java | 5 +- .../wpi/grip/ui/codegeneration/cv/CVMin.java | 5 +- .../grip/ui/codegeneration/cv/CVMultiply.java | 5 +- .../ui/codegeneration/cv/CVRectangle.java | 5 +- .../grip/ui/codegeneration/cv/CVResize.java | 5 +- .../grip/ui/codegeneration/cv/CVScaleAdd.java | 5 +- .../grip/ui/codegeneration/cv/CVSobel.java | 5 +- .../grip/ui/codegeneration/cv/CVSubtract.java | 5 +- .../ui/codegeneration/cv/CVThreshold.java | 5 +- .../ui/codegeneration/cv/CVTranspose.java | 5 +- .../grip/ui/codegeneration/cv/CVcvtColor.java | 5 +- .../tools/CppPipelineInterfacer.java | 9 +- .../ui/codegeneration/tools/HelperTools.java | 5 +- .../codegeneration/tools/PipelineCreator.java | 6 +- .../tools/PythonPipelineInterfacer.java | 16 +- .../ui/codegeneration/tools/TestLine.java | 23 +- .../ExceptionWitnessResponderButtonTest.java | 3 + .../grip/ui/components/LogTextAreaTest.java | 40 ++- .../components/PreviousNextButtonsTest.java | 3 + .../components/StartStoppableButtonTest.java | 3 + .../grip/ui/pipeline/AddSourceButtonTest.java | 4 + .../pipeline/OutputSocketControllerTest.java | 3 + .../wpi/grip/ui/pipeline/PipelineUITest.java | 3 + .../InputSocketControllerFactoryTest.java | 3 + .../preview/ImageSocketPreviewViewTest.java | 3 + .../PointSizeSocketPreviewViewTest.java | 4 + .../wpi/grip/ui/util/ControllerMapTest.java | 9 + .../wpi/grip/ui/util/GripPlatformTest.java | 5 + .../wpi/grip/ui/util/ImageConverterTest.java | 6 + ui/ui.gradle.kts | 252 ++++++++++---- 193 files changed, 1524 insertions(+), 583 deletions(-) create mode 100644 buildSrc/README.md create mode 100644 buildSrc/build.gradle.kts create mode 100644 buildSrc/src/main/kotlin/BuildType.kt create mode 100644 buildSrc/src/main/kotlin/JavaFXExtensions.kt create mode 100644 buildSrc/src/main/kotlin/JpackageExec.kt create mode 100644 buildSrc/src/main/kotlin/NativeConfigurations.kt create mode 100644 buildSrc/src/main/kotlin/PlatformMapper.kt create mode 100644 buildSrc/src/main/kotlin/ktgit.kt rename checkstyle.xml => config/checkstyle/checkstyle.xml (99%) rename checkstyleSuppressions.xml => config/checkstyle/checkstyleSuppressions.xml (100%) rename ui/{src/main/deploy/package => installer-files}/linux/GRIP.png (100%) rename ui/{src/main/deploy/package/macosx => installer-files/mac}/GRIP.icns (100%) create mode 100644 ui/installer-files/win/GRIP-setup-icon.bmp create mode 100644 ui/installer-files/win/file-associations.properties create mode 100644 ui/installer-files/win/grip_TP6_icon.ico create mode 100644 ui/preloader/src/main/java/edu/wpi/grip/preloader/Launch.java delete mode 100644 ui/src/main/deploy/package/windows/GRIP.ico create mode 100644 ui/src/main/java/edu/wpi/grip/ui/Launch.java create mode 100644 ui/src/test/java/edu/wpi/grip/ui/UiTests.java diff --git a/.travis.yml b/.travis.yml index 4b9b54328a..b33da6db2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,6 @@ addons: packages: # - gcc-4.8 # - g++-4.8 - - oracle-java8-installer # - python3 before_install: - .travis-scripts/install.sh @@ -29,13 +28,8 @@ before_install: then .travis-scripts/osx-opencv-install.sh; else .travis-scripts/linux-opencv-install.sh; fi -# Only do an assemble when we aren't building a pull request -install: - - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && ./gradlew jfxNative --no-daemon --stacktrace -Dscan || ./gradlew --stacktrace -Dscan ' script: - # Only run code generation tests on OSX -- linux requires sudo to install OpenCV dependencies, and that environment - # will not be able to run MainWindowTest.testDragOperationFromPaletteToPipeline - ./gradlew check --stacktrace -Pheadless=true -PlogTests; after_success: @@ -52,21 +46,6 @@ notifications: on_start: never # options: [always|never|change] default: always -env: - global: - secure: f90qqcA5inkHmYUK6WNITkSPbalpw+r+6nzykPdN30ahB8OUupYxoJxFknxw74raPQ69IgsDF+f8RihEBNIjH8TiMihkcwbkUGGfYaON+sVdvV/GgRQcUk0tm/wrWxRiB1qOYfsvU4sdyvFWBtAbeuhBH1JMLlQGaFjHTJOUwCjm3iEW0CKC9btsgcZIvIrHkP2KNHUMD2iBs6BJ4W448ElQTBBnaoInWUm/ecV+nNUX9yT1CpVWABVuioUkSWSm7eMiqYnvm4J9+LUh8+IMYyodO2hjPWlQ18yhmP9kSlGpQT6pRZjCRd394GE8plKxxWwp9CVXyUY/KQiYoNMRQaAiwuNnXrCi2Et1Fp8+MzQjpl+2CWbdtPwqGhKrGICfhPHvswNE2jM7VLAu/8Gn+ubhKuYfiibska5tXDBknrVbOiV1s9h3y3hI2WyyUg+T1ZsirhGVzMSmDk4HZnLUf7uEEMZEMQzLC0yk495TTZ2zihRnAkOXhNd24lHVwns2WSu0BKvawaDlfQinCbddKGNXE0cdkDvO9xk4IsbioRJ3w8DhBdL4HAEw/Gzx5N3xEVXgOAtwoP+zH2b3LIXQvP5pkuyna48R9L7Fc+EXUmejuRUmjQQMbsdLbx6Ci8gnd6Xq7CYvwry6t3R0GKuCwziuZNl44doHYR6MK7CDBWo= - -deploy: - provider: releases - api_key: - secure: bdjiFXG3VBcM1iyxeputsWA9vHxgLNcxRB1i0REDNAnIEvDWpAdVr1jPBejeiOEw9s+k6EItATvQ2I7Xp5iKnYaXn0NuHzM3OSY8WNVCc+gBTaQwkijPBqi/vEXaO502CscW+H2U26QZGS/jJiUuieeErtzCNcWmCv8SRc5NFOVYdSlhAmp+aPeu2YwuweiMZNVquYM2hx7murghOYSF5hQTKq4/zrziENVi78XZS8rJFmxwOGqNj1GBLul2F9poIPjzDbPVJLeXTJEY+N3aYGJ4GyZYf6p8ynDO/v043/GuOAyNfkgSwhCcTQlmLG/mm6P9CUMoDQR9klh2eDswgrIP4rGLwILg3035nqHqwgTIKVXfspni3P/65siS6lXV0M5flEkRysMBr1GQhaIEUM32ArreMzAtC2Vn2CviKG0TwLmxyd/7W3JdoX4KrHAcKBwbqFDImWw43S6N63oTUEw6GjrI+CndwgF9RNgr5SAyS28LFXViOJe7JlGVUNU33kMNpEJxzVREzkJsO8aicaZTrvDniFOfg2WhrAyhjxmh4/IOHDE6qgtxw+2+TUzMlwdzdxb90BeXg2XfMichmKfQYQFEmZntCZcoHHDG5jbCTyAvFuOv6tdPjpr69QjiEJhEbohw8CEwoGhy1kxxQcCDCfABrOTivJ39Ui8MC6k= - file_glob: true - file: "ui/build/jfx/native/*.{deb,pkg,dmg}" - skip_cleanup: true - on: - repo: WPIRoboticsProjects/GRIP - tags: true - before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock cache: diff --git a/annotation/src/main/java/edu/wpi/grip/annotation/processor/ClassListProcessor.java b/annotation/src/main/java/edu/wpi/grip/annotation/processor/ClassListProcessor.java index ccdcce4802..d7f1471b30 100644 --- a/annotation/src/main/java/edu/wpi/grip/annotation/processor/ClassListProcessor.java +++ b/annotation/src/main/java/edu/wpi/grip/annotation/processor/ClassListProcessor.java @@ -4,10 +4,10 @@ import edu.wpi.grip.annotation.operation.PublishableObject; import com.google.auto.service.AutoService; -import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.io.Writer; +import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -43,11 +43,16 @@ public class ClassListProcessor extends AbstractProcessor { public static final String PUBLISHABLES_FILE_NAME = "publishables"; public static final String XSTREAM_ALIASES_FILE_NAME = "xstream-aliases"; - private final Map fileNames = ImmutableMap.of( - Description.class.getName(), OPERATIONS_FILE_NAME, - PublishableObject.class.getName(), PUBLISHABLES_FILE_NAME, - "com.thoughtworks.xstream.annotations.XStreamAlias", XSTREAM_ALIASES_FILE_NAME - ); + private final Map fileNames = makeFileNamesMap(); + + private Map makeFileNamesMap() { + Map map = new HashMap<>(); + map.put(Description.class.getName(), ClassListProcessor.OPERATIONS_FILE_NAME); + map.put(PublishableObject.class.getName(), ClassListProcessor.PUBLISHABLES_FILE_NAME); + map.put("com.thoughtworks.xstream.annotations.XStreamAlias", + ClassListProcessor.XSTREAM_ALIASES_FILE_NAME); + return map; + } @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { @@ -90,7 +95,7 @@ private void createFile(String fileName, Iterable classNames) { private static final class TypeNameExtractor extends SimpleTypeVisitor8 { - static final TypeNameExtractor INSTANCE = new TypeNameExtractor(); + public static final TypeNameExtractor INSTANCE = new TypeNameExtractor(); @Override public String visitDeclared(DeclaredType t, Void o) { diff --git a/appveyor.yml b/appveyor.yml index 04ea307577..fe110e2241 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,31 +1,8 @@ -install: - - choco install -y InnoSetup - -build_script: - - gradlew.bat jfxNative --no-daemon --stacktrace - -# to run your custom scripts instead of automatic tests test_script: - gradlew.bat check --stacktrace -Pheadless=true -PlogTests -Dscan platform: - x64 -artifacts: - - path: ui\build\jfx\native\*.exe - - -deploy: - provider: GitHub - description: '' - auth_token: - secure: k0uhlsYxGoZkHVNNm4E+WnOiBfzsv4yLS+htlplR7JwzARqiAC2RU0cVnsIg1UF0 - artifact: /.*\.exe/ # upload all exe packages to release assets - draft: true - prerelease: true - on: - branch: master # release from master branch only - appveyor_repo_tag: true # deploy on tag push only - cache: - C:\Users\appveyor\.gradle diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6ae6b7408d..1580f01992 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -13,33 +13,33 @@ jobs: steps: - script: | - sudo add-apt-repository -y ppa:webupd8team/java - sudo apt-get update - echo debconf shared/accepted-oracle-license-v1-1 select true | sudo debconf-set-selections - echo debconf shared/accepted-oracle-license-v1-1 seen true | sudo debconf-set-selections - sudo apt-get install -y oracle-java8-installer - sudo apt-get install -y oracle-java8-set-default - export JAVA_HOME=/usr/lib/jvm/java-8-oracle - export PATH=$JAVA_HOME/bin:$PATH - displayName: 'Install Oracle JDK' + mkdir build + $ProgressPreference = 'SilentlyContinue' + wget "https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz" -O "build/jdk.tar.gz" + displayName: 'Download JDK' + - script: | + $ProgressPreference = 'SilentlyContinue' + wget "https://download.java.net/java/early_access/jpackage/30/openjdk-13-jpackage+30_linux-x64_bin.tar.gz" -O "build/jdk-13.tar.gz" + sudo mkdir /opt/java + sudo tar -xzvf build/jdk-13.tar.gz -C /opt/java + displayName: 'Download JDK 13' + - task: JavaToolInstaller@0 + inputs: + jdkSourceOption: localDirectory + jdkFile: 'build/jdk.tar.gz' + jdkDestinationDirectory: 'build/jdkinst' + jdkArchitectureOption: x64 - task: Gradle@2 inputs: workingDirectory: '' gradleWrapperFile: 'gradlew' - gradleOptions: '-Xmx3072m -Dorg.gradle.java.home=/usr/lib/jvm/java-8-oracle' - jdkUserInputPath: '/usr/lib/jvm/java-8-oracle' + gradleOptions: '-Xmx3072m' publishJUnitResults: false - tasks: 'check jacocoTestReport jacocoRootReport jfxNative -Pgeneration -PjniLocation=build/OpenCVJNI -Pheadless=true -PlogTests --stacktrace' - - - script: | - curl -s https://codecov.io/bash > .codecov - chmod +x .codecov - ./.codecov -t $(CODECOV_TOKEN) - displayName: 'Upload jacoco reports to codecov' + tasks: 'check :ui:jpackage -Pgeneration -PjniLocation=build/OpenCVJNI -Pheadless=true -PlogTests -Pjdk13=/opt/java/jdk-13 --stacktrace' - task: CopyFiles@2 inputs: - contents: 'ui/build/jfx/native/GRIP-*.deb' + contents: 'ui/build/installer/GRIP-*.deb' targetFolder: $(Build.ArtifactStagingDirectory) - task: PublishBuildArtifacts@1 @@ -54,19 +54,35 @@ jobs: - script: | choco install innosetup -y displayName: 'Install Inno Setup' + - powershell: | + mkdir build + $ProgressPreference = 'SilentlyContinue' + wget "https://download.java.net/java/ga/jdk11/openjdk-11_windows-x64_bin.zip" -O "build\jdk.zip" + displayName: 'Download JDK' + - powershell: | + $ProgressPreference = 'SilentlyContinue' + wget "https://download.java.net/java/early_access/jpackage/30/openjdk-13-jpackage+30_windows-x64_bin.zip" -O "build\jdk-13.zip" + Expand-Archive build\jdk-13.zip -DestinationPath build + displayName: 'Download JDK 13' + - task: JavaToolInstaller@0 + inputs: + jdkSourceOption: localDirectory + jdkFile: 'build/jdk.zip' + jdkDestinationDirectory: 'build/jdkinst' + jdkArchitectureOption: x64 - task: Gradle@2 inputs: workingDirectory: '' gradleWrapperFile: 'gradlew' gradleOptions: '-Xmx3072m' - jdkVersionOption: '1.8' + jdkVersionOption: '1.11' jdkArchitectureOption: 'x64' publishJUnitResults: true - tasks: 'check jacocoTestReport jacocoRootReport jfxNative -Pheadless=true -Pgeneration -PlogTests --stacktrace' + tasks: 'check :ui:jpackage -Pheadless=true -Pgeneration -PlogTests -Pjdk13=..\build\jdk-13 --stacktrace' - task: CopyFiles@2 inputs: - contents: 'ui\build\jfx\native\GRIP-*.exe' + contents: 'ui\build\installer\GRIP-*.exe' targetFolder: $(Build.ArtifactStagingDirectory) - task: PublishBuildArtifacts@1 @@ -81,19 +97,29 @@ jobs: - script: | choco install innosetup -y displayName: 'Install Inno Setup' + - powershell: | + mkdir build + $ProgressPreference = 'SilentlyContinue' + wget "https://github.com/wpilibsuite/frc-openjdk-windows/releases/download/v11.0.0u28-1/jdk-x86-11.0.0u28-1.zip" -O "build\jdk.zip" + displayName: 'Download JDK' + - task: JavaToolInstaller@0 + inputs: + jdkSourceOption: localDirectory + jdkFile: 'build/jdk.zip' + jdkDestinationDirectory: 'build/jdkinst' + jdkArchitectureOption: x86 - task: Gradle@2 inputs: workingDirectory: '' gradleWrapperFile: 'gradlew' gradleOptions: '-Xmx1024m' - jdkVersionOption: '1.8' - jdkArchitectureOption: 'x86' publishJUnitResults: false - tasks: 'check jacocoTestReport jacocoRootReport jfxNative -Pheadless=true -Pgeneration -PlogTests --stacktrace' + # TODO: run :ui:jpackage once we have a JDK 13 build for 32-bit Windows + tasks: 'check -Pheadless=true -Pgeneration -PlogTests --stacktrace' - task: CopyFiles@2 inputs: - contents: 'ui\build\jfx\native\GRIP-*.exe' + contents: 'ui\build\installer\GRIP-*.exe' targetFolder: $(Build.ArtifactStagingDirectory) - task: PublishBuildArtifacts@1 @@ -105,21 +131,50 @@ jobs: vmImage: 'xcode9-macos10.13' steps: + - script: | + mkdir build + wget "https://download.java.net/java/ga/jdk11/openjdk-11_osx-x64_bin.tar.gz" -O "build/jdk.tar.gz" + wget "https://download.java.net/java/early_access/jpackage/30/openjdk-13-jpackage+30_osx-x64_bin.tar.gz" -O "build/jdk-13.tar.gz" + sudo tar xzvf build/jdk-13.tar.gz -C /Library/Java/JavaVirtualMachines/ + sudo tar xvzf build/jdk.tar.gz -C /Library/Java/JavaVirtualMachines/ + export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home/ + displayName: 'Setup JDK' - task: Gradle@2 inputs: workingDirectory: '' gradleWrapperFile: 'gradlew' gradleOptions: '-Xmx3072m' - jdkVersionOption: '1.8' + jdkVersionOption: '1.11' jdkArchitectureOption: 'x64' publishJUnitResults: false - tasks: 'check jacocoTestReport jacocoRootReport jfxNative -Pheadless=true -Pgeneration -PlogTests --stacktrace' + tasks: 'check :ui:jpackage -Pheadless=true -Pgeneration -PlogTests -Pjdk13=/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/ --stacktrace' - task: CopyFiles@2 inputs: - contents: 'ui/build/jfx/native/*' + contents: 'ui/build/installer/*' targetFolder: $(Build.ArtifactStagingDirectory) - task: PublishBuildArtifacts@1 inputs: artifactName: 'MacInstaller' + + # JDK 8 agent for UI tests + - job: Mac_UI_Testing + pool: + vmImage: 'xcode9-macos10.13' + + steps: + - task: Gradle@2 + inputs: + workingDirectory: '' + gradleWrapperFile: 'gradlew' + gradleOptions: '-Xmx3072m' + jdkVersionOption: '1.8' + jdkArchitectureOption: 'x64' + publishJUnitResults: false + tasks: 'check jacocoTestReport jacocoRootReport -Pheadless=true -Pgeneration -PlogTests --stacktrace' + - script: | + curl -s https://codecov.io/bash > .codecov + chmod +x .codecov + ./.codecov -t $(CODECOV_TOKEN) + displayName: 'Upload jacoco reports to codecov' diff --git a/build.gradle.kts b/build.gradle.kts index 897bf80262..7edc513866 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,3 @@ -import org.ajoberstar.grgit.Grgit import com.github.spotbugs.SpotBugsTask buildscript { @@ -9,7 +8,6 @@ buildscript { } } dependencies { - classpath(group = "de.dynamicfiles.projects.gradle.plugins", name = "javafx-gradle-plugin", version = "8.8.2") classpath(group = "edu.wpi.first.wpilib.opencv", name = "opencv-installer", version = "2.0.0") } } @@ -19,11 +17,11 @@ plugins { `jacoco` `checkstyle` `pmd` - id("com.github.johnrengelman.shadow") version "4.0.3" + id("com.github.johnrengelman.shadow") version "4.0.1" id("com.google.osdetector") version "1.4.0" id("org.ajoberstar.grgit") version "2.0.0" apply false - id("net.ltgt.errorprone") version "0.0.16" - id("com.github.spotbugs") version "1.6.4" + //id("net.ltgt.errorprone") version "0.0.16" + id("com.github.spotbugs") version "1.7.1" id("com.gradle.build-scan") version "2.1" } @@ -48,21 +46,13 @@ fun javaSubprojects(action: Project.() -> Unit) { } } -var grgit: Grgit? = null -if (rootProject.file(".git").exists()) { - project.apply { - plugin("org.ajoberstar.grgit") - } - grgit = Grgit.open() -} - javaSubprojects { apply { plugin("java") plugin("org.gradle.jacoco") plugin("org.gradle.pmd") plugin("org.gradle.checkstyle") - plugin("net.ltgt.errorprone") + //plugin("net.ltgt.errorprone") plugin("com.github.spotbugs") } repositories { @@ -82,9 +72,11 @@ javaSubprojects { } } - version = getVersionName() + version = getGitVersion() dependencies { + "compile"(group = "javax.annotation", name = "javax.annotation-api", version = "1.3.2") + "annotationProcessor"(group = "javax.annotation", name = "javax.annotation-api", version = "1.3.2") "compile"(group = "com.google.code.findbugs", name = "annotations", version = "3.0.1") "testCompile"(group = "net.jodah", name = "concurrentunit", version = "0.4.2") "testCompile"(group = "org.hamcrest", name = "hamcrest-all", version = "1.3") @@ -94,7 +86,6 @@ javaSubprojects { } checkstyle { - configFile = rootDir.resolve("checkstyle.xml") toolVersion = "6.19" if (project.hasProperty("ignoreCheckstyle")) { isIgnoreFailures = true @@ -102,20 +93,21 @@ javaSubprojects { } pmd { - toolVersion = "5.6.0" + toolVersion = "6.7.0" isConsoleOutput = true val projectSourcesSets = this@javaSubprojects.sourceSets sourceSets = listOf(projectSourcesSets["main"], projectSourcesSets["test"]) reportsDir = buildDir.resolve("reports/pmd") ruleSetFiles = files(rootDir.resolve("pmd-ruleset.xml")) + ruleSets = emptyList() } - configurations["errorprone"].apply { - resolutionStrategy.force("com.google.errorprone:error_prone_core:2.3.2") - } +// configurations["errorprone"].apply { +// resolutionStrategy.force("com.google.errorprone:error_prone_core:2.3.2") +// } spotbugs { - toolVersion = "3.1.7" + toolVersion = "3.1.12" val javaSources = this@javaSubprojects.sourceSets sourceSets = setOf(javaSources["main"], javaSources["test"]) excludeFilter = file("$rootDir/findBugsSuppressions.xml") @@ -153,6 +145,10 @@ javaSubprojects { source(tasks.named("compileJava").map { it.source }) } + tasks.withType().configureEach { + sourceCompatibility = "8" + } + } tasks.register("jacocoRootReport") { @@ -175,31 +171,3 @@ tasks.register("jacocoRootReport") { csv.isEnabled = false } } - -fun Project.getGitCommit(): String { - return grgit?.head()?.abbreviatedId ?: "" -} - -fun Project.getGitDescribe(): String { - return grgit?.describe() ?: "v0.0.0" -} - -fun Project.getGitDescribeAbbrev(): String { - return grgit?.tag?.list()?.last()?.name ?: "v0.0.0" -} - -fun Project.getVersionName(): String { - if (project.hasProperty("vers")) { - val vers: String by properties - return vers - } - return getGitDescribe() -} - -fun Project.getVersionSimple(): String { - if (project.hasProperty("vers")) { - val vers: String by properties - return vers - } - return getGitDescribeAbbrev() -} diff --git a/buildSrc/README.md b/buildSrc/README.md new file mode 100644 index 0000000000..ef317b997b --- /dev/null +++ b/buildSrc/README.md @@ -0,0 +1,4 @@ +# buildsrc + +This directory contains shared code for all subproject buildscripts to reduce code duplication. All subproject build +scripts load the Kotlin files in `src/main/kotlin` automatically. diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000000..9418ad1e6e --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + `kotlin-dsl` +} + +repositories { + // See https://github.com/gradle/kotlin-dsl/issues/1033 + jcenter() +} diff --git a/buildSrc/src/main/kotlin/BuildType.kt b/buildSrc/src/main/kotlin/BuildType.kt new file mode 100644 index 0000000000..7c9a4f3ee7 --- /dev/null +++ b/buildSrc/src/main/kotlin/BuildType.kt @@ -0,0 +1,32 @@ +enum class BuildType { + + /** + * Building with JDK 8. Useful for running UI tests, since it's the only version on which + * testfx will work properly, but nothing else. + */ + JDK_8, + + /** + * Building on JDK 11, and allows the possibility of building a native installer package + */ + JDK_11; + + companion object { + val current by lazy { + if (org.gradle.internal.jvm.Jvm.current().javaVersion?.isJava11Compatible ?: true) { + JDK_11 + } else { + JDK_8 + } + } + + /** + * Checks if the current JDK is Java 11 (or newer). + */ + val isJdk11 by lazy { + println("Build JDK is $current") + current == JDK_11 + } + } + +} diff --git a/buildSrc/src/main/kotlin/JavaFXExtensions.kt b/buildSrc/src/main/kotlin/JavaFXExtensions.kt new file mode 100644 index 0000000000..22a9046848 --- /dev/null +++ b/buildSrc/src/main/kotlin/JavaFXExtensions.kt @@ -0,0 +1,26 @@ +import NativePlatforms.WIN32 +import org.gradle.api.artifacts.dsl.DependencyHandler + +/** + * Generates a dependency on a JavaFX artifact. The artifact name is prepended with `"javafx-"`, so `name` should be + * something like `"base"` instead of `"javafx-base"` or `"graphics"` vs `"javafx-graphics"`. This generates a + * platform-specific dependency, so this should only be used as a `compileOnly` dependency _except_ in the app project, + * which wants the dependencies as `compile` or `runtime` dependencies so they can be included in the fatjar + * distribution. + */ +internal fun DependencyHandler.javafx(name: String, platform: NativePlatforms, version: String = "11") = + when (platform) { + WIN32 -> add(platform, "edu.wpi.first.openjfx:javafx-$name:$version:${javaFxClassifier(platform)}") + else -> add(platform, "org.openjfx:javafx-$name:$version:${javaFxClassifier(platform)}") + } + +/** + * Generates dependencies for all platform-specific configurations on a JavaFX artifact. The artifact name is + * prepended with `"javafx-"`, so `name` should be something like `"base"` instead of `"javafx-base"` or `"graphics"` + * vs `"javafx-graphics"`. + */ +fun DependencyHandler.javafx(name: String) { + forEachPlatform { + javafx(name = name, platform = it) + } +} diff --git a/buildSrc/src/main/kotlin/JpackageExec.kt b/buildSrc/src/main/kotlin/JpackageExec.kt new file mode 100644 index 0000000000..19261ed949 --- /dev/null +++ b/buildSrc/src/main/kotlin/JpackageExec.kt @@ -0,0 +1,313 @@ +import org.gradle.api.DefaultTask +import org.gradle.api.logging.LogLevel +import org.gradle.api.provider.HasMultipleValues +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.* +import org.gradle.internal.os.OperatingSystem +import org.gradle.kotlin.dsl.listProperty +import org.gradle.kotlin.dsl.property +import java.io.FileFilter + +/** + * Runs the `jpackage` tool (tentatively to be introduced in Java 13) to generate an installer + * for the current operating system. `jpackage` cannot generate an installer for a different OS than + * the one running the build. + * + * Because JDK 13 has not yet been released, and because `jpackage` is not yet included in the + * early-access builds, a compatible JDK must be downloaded from + * [https://jdk.java.net/jpackage/](https://jdk.java.net/jpackage/). The location of the JDK must be + * specified with [jdkHome] (eg `/opt/java/jdk-13/`) + * + */ +open class JpackageExec : DefaultTask() { + + private val objectFactory = project.objects + + private fun stringProperty() = objectFactory.property() + + /** + * The JDK_HOME directory containing a JDK with the jpackage tool. + */ + @get:InputDirectory + val jdkHome = objectFactory.directoryProperty() + + /** + * The location of a prebuilt runtime image generated from `jlink`. If not specified, the task + * will generate an image with all JDK modules included. + */ + @get:InputDirectory + @get:Optional + val runtimeImage = objectFactory.directoryProperty() + + /** + * Java arguments to pass to the virtual machine. + */ + @get:Input + @get:Optional + val jvmArgs = objectFactory.listProperty() + + /** + * Whether or not the jpackage execution should be verbose (ie print to stdout). Defaults to + * `false` if not specified. + */ + @get:Input + @get:Optional + val verbose = objectFactory.property() + + /** + * The output directory into which the installer should be generated. + */ + @get:OutputDirectory + val outputDir = objectFactory.directoryProperty() + + /** + * The input directory of files to bundle into the installer. Typically, this should contain + * the dependency JAR files of the application. + */ + @get:InputDirectory + val inputDir = objectFactory.directoryProperty() + + /** + * Path to override jpackage resources. Icons, template files, and other resources of jpackage + * can be over-ridden by adding replacement resources to this directory. + */ + @get:InputDirectory + @get:Optional + val resourceDir = objectFactory.directoryProperty() + + /** + * An icon file to use for the application and installer. This can be a file or a file name. + */ + @get:InputFile + @get:Optional + val icon = objectFactory.property() + + /** + * The main JAR file. This file must be present in the [inputDir]. + */ + @get:InputFile + val mainJar = objectFactory.fileProperty() + + /** + * The name of the main class in the [mainJar]. + */ + @get:Input + val mainClassName = stringProperty() + + /** + * The name of the application (e.g. "GRIP"). + */ + @get:Input + val applicationName = stringProperty() + + /** + * A description of the application (e.g. "GRIP Computer Vision Engine"). + */ + @get:Input + @get:Optional + val applicationDescription = stringProperty() + + /** + * The version of the application. This must be a semver-compliant version string, e.g. + * `"1.5.2"`. Extra build information such as `"SNAPSHOT"`, `"RC1"`, etc. must be ommited + * from the string. A full version string may be specified with [fullApplicationVersion] + * to use to rename the installer packages with the full version information. + */ + @get:Input + val applicationVersion = stringProperty() + + /** + * A full version string to use to name the installer packages. This is _only_ used for naming + * the installer executable - the version of the application as seen by the OS will be the one + * specified with [applicationVersion]. + */ + @get:Input + @get:Optional + val fullApplicationVersion = stringProperty() + + /** + * Copyright for the application. + */ + @get:Input + @get:Optional + val copyright = stringProperty() + + /** + * Path to the license file. + */ + @get:InputFile + @get:Optional + val licenseFile = objectFactory.fileProperty() + + /** + * The name of the application vendor (e.g. "Worcester Polytechnic Institute"). + */ + @get:Input + @get:Optional + val applicationVendor = stringProperty() + + /** + * A machine-readable identifier string in reverse-DNS format (e.g. "edu.wpi.grip"). + */ + @get:Input + @get:Optional + val identifier = stringProperty() + + /** + * A properties file containing key-value pairs for file association integration. + * Currently broken on Linux and Mac. + */ + @get:InputFile + @get:Optional + val fileAssociations = objectFactory.fileProperty() + + /** + * The type of installer to generate. Windows supports "exe" (requires InnoSetup) and "msi". + * Mac supports "dmg" and "pkg". Linux supports "deb" and "rpm". + */ + @get:Input + val installerType = stringProperty() + + /** + * Windows-specific. A constant UUID to use for Windows to identify version upgrades. + */ + @get:Input + @get:Optional + val winUpgradeUuid = stringProperty() + + /** + * Windows-specific. The name to use for the application in its Windows registry entries. + */ + @get:Input + @get:Optional + val winRegistryName = stringProperty() + + /** + * Windows-specific. Allows the application to be installed in the Windows start menu. + */ + @get:Input + @get:Optional + val addToWindowsMenu = objectFactory.property() + + /** + * Windows-specific. Adds a shortcut to the user's desktop. + */ + @get:Input + @get:Optional + val addWindowsDesktopShortcut = objectFactory.property() + + /** + * Mac-specific. An identifier to use for the App Store. + */ + @get:Input + @get:Optional + val macBundleIdentifier = stringProperty() + + @TaskAction + fun exec() { + project.exec { + val args = mutableListOf() + args.add(jdkHome.file("bin/jpackage").get().asFile.absolutePath) + args.add("create-installer") + + runtimeImage.ifPresent { dir -> + args.addAll("--runtime-image", dir.asFile.absolutePath) + } + if (verbose.getOrElse(false)) { + args.add("--verbose") + } + jvmArgs.ifPresent { jvmArgs -> + args.add("--jvm-args") + args.add(jvmArgs.joinToString(separator = " ", prefix = "\"", postfix = "\"")) + } + args.addAll("--input", inputDir.get().asFile.absolutePath) + resourceDir.ifPresent { dir -> + args.addAll("--resource-dir", dir.asFile.absolutePath) + } + args.addAll("--output", outputDir.get().asFile.absolutePath) + icon.ifPresent { iconFile -> + args.addAll("--icon", iconFile.toString()) + } + args.addAll("--main-jar", mainJar.get().asFile.absolutePath) + args.addAll("--main-class", mainClassName.get()) + + args.addAll("--name", applicationName.get()) + applicationDescription.ifPresent { description -> + args.addAll("--description", description) + } + args.addAll("--app-version", applicationVersion.get()) + copyright.ifPresent { + args.addAll("--copyright", it) + } + licenseFile.ifPresent { file -> + args.addAll("--license-file", file.asFile.absolutePath) + } + applicationVendor.ifPresent { vendor -> + args.addAll("--vendor", vendor) + } + identifier.ifPresent { id -> + args.addAll("--identifier", id) + } + fileAssociations.ifPresent { propsFile -> + args.addAll("--file-associations", propsFile.asFile.absolutePath) + } + args.addAll("--installer-type", installerType.get()) + + when (OperatingSystem.current()) { + OperatingSystem.WINDOWS -> { + winUpgradeUuid.ifPresent { uuid -> + args.addAll("--win-upgrade-uuid", uuid) + } + winRegistryName.ifPresent { name -> + args.addAll("--win-registry-name", name) + } + if (addToWindowsMenu.getOrElse(false)) { + args.add("--win-menu") + } + if (addWindowsDesktopShortcut.getOrElse(false)) { + args.add("--win-shortcut") + } + } + OperatingSystem.MAC_OS -> { + macBundleIdentifier.ifPresent { id -> + args.addAll("--mac-bundle-identifier", id) + } + } + OperatingSystem.LINUX -> { + // No linux-specific properties yet + } + } + + setCommandLine(args) + } + + fullApplicationVersion.ifPresent { version -> + logger.log(LogLevel.INFO, "Renaming installer packages") + val packageFileFilter = FileFilter { file -> + listOf("exe", "dmg", "pkg", "deb", "rpm").any { + file.extension == it + } + } + val packageFiles = outputDir.get().asFile.listFiles(packageFileFilter) + packageFiles.forEach { packageFile -> + val newName = "GRIP-${version}.${packageFile.extension}" + logger.log(LogLevel.DEBUG, "Renaming ${packageFile.name} to $newName") + packageFile.renameTo(packageFile.resolveSibling(newName)) + } + } + } +} + +inline fun MutableList.addAll(vararg items: T) { + items.forEach(this::add) +} + +inline fun Provider.ifPresent(action: (T) -> Unit) { + if (isPresent) { + action(get()) + } +} + +inline fun HasMultipleValues.setAll(vararg items: T) { + set(items.asList()) +} diff --git a/buildSrc/src/main/kotlin/NativeConfigurations.kt b/buildSrc/src/main/kotlin/NativeConfigurations.kt new file mode 100644 index 0000000000..9b7290cc90 --- /dev/null +++ b/buildSrc/src/main/kotlin/NativeConfigurations.kt @@ -0,0 +1,89 @@ +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.gradle.api.artifacts.dsl.DependencyHandler +import org.gradle.kotlin.dsl.project + +enum class NativePlatforms(val platformName: String) { + WIN32("win32"), + WIN64("win64"), + MAC("mac64"), + LINUX("linux64"); + + companion object { + fun forName(platformName: String): NativePlatforms { + return values().find { it.platformName == platformName } ?: throw NoSuchElementException(platformName) + } + } +} + +/** + * Adds a dependency to the configuration for the given platform. + */ +fun DependencyHandler.add(platform: NativePlatforms, dependencyNotation: Any) = add(platform.platformName, dependencyNotation) + +/** + * Creates a [Configuration] for the given platform. If the given platform is also the current platform (i.e. the + * operating system running the Gradle build), then the `compileOnly`, `runtimeOnly`, and `testCompile` configurations + * will extend from the native configuration for purposes of being able to run the application and tests. + */ +internal fun Project.nativeConfig(platform: NativePlatforms): Configuration { + val configuration = configurations.create(platform.platformName) + if (platform == currentPlatform) { + configurations.getByName("compileOnly").extendsFrom(configuration) + configurations.getByName("runtimeOnly").extendsFrom(configuration) + configurations.getByName("testCompile").extendsFrom(configuration) + } + return configuration +} + +/** + * Creates all the native configurations for the project. + */ +fun Project.createNativeConfigurations() = forEachPlatform { platform -> nativeConfig(platform) } + +/** + * Adds a dependency on a native (platform-specific) artifact. + * + * @param group the group ID of the artifact + * @param name the name of the artifact + * @param version the version of the artifact (wildcards are supported) + * @param classifierFunction a function that takes a native platform and returns the classifier + * for the platform-specific artifact to resolve + */ +fun DependencyHandler.native(group: String, name: String, version: String, classifierFunction: (NativePlatforms) -> String) { + forEachPlatform { + add(it, "$group:$name:$version:${classifierFunction(it)}") + } +} + +/** + * Adds a dependency on a project that has dependencies on native libraries. The native dependencies for the project + * will be added to the same native dependency configuration for this project. The project's `compile` configuration + * will also be copied to this project's. Additionally, the project's native dependencies corresponding to the build + * platform project will be added to this project's `compileOnly`, `runtime`, and `testCompile` configurations to allow + * the app's `run` task and all projects' test suites to be able to compile and run. + * + * @param path the path to the project, e.g. `":plugins:networktables"` + */ +fun DependencyHandler.nativeProject(path: String) { + forEachPlatform { + nativeProject(path, it) + } +} + +internal fun DependencyHandler.nativeProject(path: String, platform: NativePlatforms) { + add(platform, project(path, platform.platformName)) + add("compile", project(path, "compile")) + if (platform == currentPlatform) { + add("compileOnly", project(path)) + add("runtime", project(path)) + add("testCompile", project(path)) + } +} + +/** + * Performs some action for all supported native platforms. + */ +fun forEachPlatform(action: (NativePlatforms) -> Unit) { + NativePlatforms.values().forEach(action) +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/PlatformMapper.kt b/buildSrc/src/main/kotlin/PlatformMapper.kt new file mode 100644 index 0000000000..d813106a4c --- /dev/null +++ b/buildSrc/src/main/kotlin/PlatformMapper.kt @@ -0,0 +1,53 @@ +import NativePlatforms.* + +/** + * The platform performing the build. This is in the format `""`, e.g. `win32`, `mac64`, `linux64`. + */ +val currentPlatform: NativePlatforms by lazy { + val osName = System.getProperty("os.name") + val os: String = when { + osName.contains("windows", true) -> "win" + osName.contains("mac", true) -> "mac" + osName.contains("linux", true) -> "linux" + else -> throw UnsupportedOperationException("Unknown OS: $osName") + } + val osArch = System.getProperty("os.arch") + val arch: String = if (osArch.contains("x86_64") || osArch.contains("amd64")) { + "64" + } else if (osArch.contains("x86")) { + "32" + } else { + throw UnsupportedOperationException(osArch) + } + NativePlatforms.forName(os + arch) +} + +/** + * Generates a classifier string for a platform-specific WPILib native library. + */ +fun wpilibClassifier(platform: NativePlatforms) = when (platform) { + WIN32 -> "windowsx86" + WIN64 -> "windowsx86-64" + MAC -> "osxx86-64" + LINUX -> "linuxx86-64" +} + +/** + * Generates a classifier string for a platform-specific JavaCPP native library. + */ +fun javaCppClassifier(platform: NativePlatforms) = when (platform) { + WIN32 -> "windows-x86" + WIN64 -> "windows-x86_64" + MAC -> "macosx-x86_64" + LINUX -> "linux-x86_64" +} + +/** + * Generates a classifier string for a platform-specific JavaFX artifact. + */ +fun javaFxClassifier(platform: NativePlatforms) = when (platform) { + WIN32 -> "win32" + WIN64 -> "win" + MAC -> "mac" + LINUX -> "linux" +} diff --git a/buildSrc/src/main/kotlin/ktgit.kt b/buildSrc/src/main/kotlin/ktgit.kt new file mode 100644 index 0000000000..d33e8b6cb5 --- /dev/null +++ b/buildSrc/src/main/kotlin/ktgit.kt @@ -0,0 +1,45 @@ +import org.gradle.api.Project +import java.io.OutputStream + +/** + * Gets the project version from git by running `git describe --tags`. If no .git directory is + * present (like when the project is downloaded in a ZIP file), the version falls back to "v0.0.0". + */ +fun Project.getGitVersion(): String { + val DEFAULT_VERSION_STRING = "v0.0.0" + + if (rootDir.resolve(".git").exists()) { + StringOutputStream().use { + project.exec { + setWorkingDir(project.rootDir) + setCommandLine("git", "describe", "--tags") + setStandardOutput(it) + } + return it.toString().takeWhile { !it.isWhitespace() } + } + } else { + System.err.println("No .git directory found! Falling back to $DEFAULT_VERSION_STRING") + return DEFAULT_VERSION_STRING + } +} + +private class StringOutputStream : OutputStream() { + private val buf = StringBuffer() + + override fun write(b: ByteArray) { + this.buf.append(String(b)) + } + + override fun write(b: ByteArray, off: Int, len: Int) { + this.buf.append(String(b, off, len)) + } + + override fun write(b: Int) { + val bytes = byteArrayOf(b.toByte()) + this.buf.append(String(bytes)) + } + + override fun toString(): String { + return this.buf.toString() + } +} diff --git a/checkstyle.xml b/config/checkstyle/checkstyle.xml similarity index 99% rename from checkstyle.xml rename to config/checkstyle/checkstyle.xml index e028697d6b..cb03501a8d 100644 --- a/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -22,7 +22,7 @@ - + diff --git a/checkstyleSuppressions.xml b/config/checkstyle/checkstyleSuppressions.xml similarity index 100% rename from checkstyleSuppressions.xml rename to config/checkstyle/checkstyleSuppressions.xml diff --git a/core/core.gradle.kts b/core/core.gradle.kts index a1e1ce870d..6384fba1cb 100644 --- a/core/core.gradle.kts +++ b/core/core.gradle.kts @@ -1,6 +1,4 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import com.google.common.io.Files -import java.nio.charset.StandardCharsets plugins { id("java") diff --git a/core/src/main/java/edu/wpi/grip/core/Connection.java b/core/src/main/java/edu/wpi/grip/core/Connection.java index 405ad6835f..d3b6b40dd0 100644 --- a/core/src/main/java/edu/wpi/grip/core/Connection.java +++ b/core/src/main/java/edu/wpi/grip/core/Connection.java @@ -20,7 +20,7 @@ /** * A connection is a rule that causes one socket to update to always the value of another socket. */ -@XStreamAlias(value = "grip:Connection") +@XStreamAlias("grip:Connection") public class Connection { private final EventBus eventBus; diff --git a/core/src/main/java/edu/wpi/grip/core/CoreCommandLineHelper.java b/core/src/main/java/edu/wpi/grip/core/CoreCommandLineHelper.java index 139138b83f..d24487a090 100644 --- a/core/src/main/java/edu/wpi/grip/core/CoreCommandLineHelper.java +++ b/core/src/main/java/edu/wpi/grip/core/CoreCommandLineHelper.java @@ -156,14 +156,22 @@ void exit() { * @throws IOException if the file couldn't be loaded */ public void loadFile(CommandLine args, Project project) throws IOException { + File file; if (args.hasOption(FILE_OPTION)) { - String file = args.getOptionValue(FILE_OPTION); - try { - project.open(new File(file)); - } catch (IOException e) { - logger.log(Level.WARNING, "Invalid file: " + file, e); - throw e; - } + file = new File(args.getOptionValue(FILE_OPTION)); + } else if (args.getArgs().length > 0 && new File(args.getArgs()[0]).exists()) { + // If GRIP is set in the OS as the default app to open a file, its path will be passed as the + // first argument + file = new File(args.getArgs()[0]); + } else { + // No file specified + return; + } + try { + project.open(file); + } catch (IOException e) { + logger.log(Level.WARNING, "Invalid file: " + file, e); + throw e; } } @@ -181,13 +189,13 @@ public void setServerPort(CommandLine args, if (args.hasOption(PORT_OPTION)) { try { int port = Integer.parseInt(args.getOptionValue(PORT_OPTION)); - if (!GripServer.isPortValid(port)) { - logger.warning("Not a valid port: " + port); - } else { + if (GripServer.isPortValid(port)) { logger.info("Setting server port: " + port); AppSettings settings = settingsProvider.getAppSettings().clone(); settings.setServerPort(port); eventBus.post(new AppSettingsChangedEvent(settings)); + } else { + logger.warning("Not a valid port: " + port); } } catch (NumberFormatException e) { logger.warning("Not a valid port: " + args.getOptionValue(PORT_OPTION)); diff --git a/core/src/main/java/edu/wpi/grip/core/GripCoreModule.java b/core/src/main/java/edu/wpi/grip/core/GripCoreModule.java index 572e450b51..618e17a3d8 100644 --- a/core/src/main/java/edu/wpi/grip/core/GripCoreModule.java +++ b/core/src/main/java/edu/wpi/grip/core/GripCoreModule.java @@ -47,7 +47,7 @@ * A Guice {@link com.google.inject.Module} for GRIP's core package. This is where instances of * {@link Pipeline}, {@link Palette}, {@link Project}, etc... are created. */ -@SuppressWarnings("PMD.MoreThanOneLogger") +@SuppressWarnings({"PMD.MoreThanOneLogger", "PMD.CouplingBetweenObjects"}) public class GripCoreModule extends AbstractModule { private final EventBus eventBus; diff --git a/core/src/main/java/edu/wpi/grip/core/Pipeline.java b/core/src/main/java/edu/wpi/grip/core/Pipeline.java index fc09cdd8d6..13fd21b8c4 100644 --- a/core/src/main/java/edu/wpi/grip/core/Pipeline.java +++ b/core/src/main/java/edu/wpi/grip/core/Pipeline.java @@ -50,7 +50,7 @@ * connections, and for registering and unregistering them from the event bus when appropriate. */ @Singleton -@XStreamAlias(value = "grip:Pipeline") +@XStreamAlias("grip:Pipeline") public class Pipeline implements ConnectionValidator, SettingsProvider, StepIndexer { private final transient ReadWriteLock sourceLock = new ReentrantReadWriteLock(); @@ -106,7 +106,7 @@ public void clear() { .forEach(this.eventBus::post); } - private final R readSourcesSafely(Function, R> sourceListFunction) { + private R readSourcesSafely(Function, R> sourceListFunction) { return accessSafely(sourceLock.readLock(), Collections.unmodifiableList(sources), sourceListFunction); } @@ -126,7 +126,7 @@ public final ImmutableList getSources() { * @param The return type of the function * @return The value returned by the function. */ - private final R readStepsSafely(Function, R> stepListFunction) { + private R readStepsSafely(Function, R> stepListFunction) { return accessSafely(stepLock.readLock(), Collections.unmodifiableList(steps), stepListFunction); } @@ -271,15 +271,15 @@ private int indexBetween(@Nullable Step lower, @Nullable Step higher) { // If not in the list these can return -1 int lowerIndex = steps.indexOf(lower); int upperIndex = steps.indexOf(higher); - if (lowerIndex != -1 && upperIndex != -1) { + if (lowerIndex != -1 && upperIndex != -1) { // NOPMD assert lowerIndex <= upperIndex : "Upper step was before lower index"; int difference = Math.abs(upperIndex - lowerIndex); // Just in case // Place the step halfway between these two steps return lowerIndex + 1 + difference / 2; - } else if (lowerIndex != -1) { + } else if (lowerIndex != -1) { // NOPMD // Place it above the lower one return lowerIndex + 1; - } else if (upperIndex != -1) { + } else if (upperIndex != -1) { // NOPMD // Place it below the upper one return upperIndex; } else { diff --git a/core/src/main/java/edu/wpi/grip/core/Source.java b/core/src/main/java/edu/wpi/grip/core/Source.java index 2db67c2123..689ef8b117 100644 --- a/core/src/main/java/edu/wpi/grip/core/Source.java +++ b/core/src/main/java/edu/wpi/grip/core/Source.java @@ -115,19 +115,19 @@ public interface SourceFactory { public static class SourceFactoryImpl implements SourceFactory { @Inject - CameraSource.Factory cameraFactory; + private CameraSource.Factory cameraFactory; @Inject - ImageFileSource.Factory imageFactory; + private ImageFileSource.Factory imageFactory; @Inject - MultiImageFileSource.Factory multiImageFactory; + private MultiImageFileSource.Factory multiImageFactory; @Inject - HttpSource.Factory httpFactory; + private HttpSource.Factory httpFactory; @Inject - NetworkTableEntrySource.Factory networkTableEntryFactory; + private NetworkTableEntrySource.Factory networkTableEntryFactory; @Inject - ClassifierSource.Factory fileSourceFactory; + private ClassifierSource.Factory fileSourceFactory; @Inject - VideoFileSource.Factory videoFileSourceFactory; + private VideoFileSource.Factory videoFileSourceFactory; @Override public Source create(Class type, Properties properties) throws IOException { diff --git a/core/src/main/java/edu/wpi/grip/core/Step.java b/core/src/main/java/edu/wpi/grip/core/Step.java index 1820dff556..aa190fa4e2 100644 --- a/core/src/main/java/edu/wpi/grip/core/Step.java +++ b/core/src/main/java/edu/wpi/grip/core/Step.java @@ -23,7 +23,7 @@ * A step is an instance of an operation in a pipeline. A step contains a list of input and output * sockets, and it runs the operation whenever one of the input sockets changes. */ -@XStreamAlias(value = "grip:Step") +@XStreamAlias("grip:Step") public class Step { private static final Logger logger = Logger.getLogger(Step.class.getName()); private static final String MISSING_SOCKET_MESSAGE_END = " must have a value to run this step."; diff --git a/core/src/main/java/edu/wpi/grip/core/events/StopPipelineEvent.java b/core/src/main/java/edu/wpi/grip/core/events/StopPipelineEvent.java index 4293c30a58..b5b00de61d 100644 --- a/core/src/main/java/edu/wpi/grip/core/events/StopPipelineEvent.java +++ b/core/src/main/java/edu/wpi/grip/core/events/StopPipelineEvent.java @@ -4,6 +4,4 @@ * This event is posted to tell the pipeline to stop executing. */ public class StopPipelineEvent { - public StopPipelineEvent() { - } } diff --git a/core/src/main/java/edu/wpi/grip/core/http/GripServer.java b/core/src/main/java/edu/wpi/grip/core/http/GripServer.java index 4e82ddeff0..b3e99d3b73 100644 --- a/core/src/main/java/edu/wpi/grip/core/http/GripServer.java +++ b/core/src/main/java/edu/wpi/grip/core/http/GripServer.java @@ -217,17 +217,10 @@ public void stop() { */ public void restart() { try { - if (state == State.RUNNING) { - try { - server.stop(); - } catch (Exception ex) { - throw new GripServerException("Could not stop Jetty server", ex); - } - state = State.STOPPED; - } + stop(); server = serverFactory.create(port); start(); - } catch (GripServerException | IllegalStateException ex) { + } catch (IllegalStateException ex) { throw new GripServerException("Could not restart GripServer", ex); } } diff --git a/core/src/main/java/edu/wpi/grip/core/metrics/BenchmarkRunner.java b/core/src/main/java/edu/wpi/grip/core/metrics/BenchmarkRunner.java index 0051f76454..b749c670ba 100644 --- a/core/src/main/java/edu/wpi/grip/core/metrics/BenchmarkRunner.java +++ b/core/src/main/java/edu/wpi/grip/core/metrics/BenchmarkRunner.java @@ -33,6 +33,7 @@ public class BenchmarkRunner { /** * State flag. */ + @SuppressWarnings("PMD.LinguisticNaming") private final AtomicBoolean isBenchmarking = new AtomicBoolean(false); /** diff --git a/core/src/main/java/edu/wpi/grip/core/metrics/CsvExporter.java b/core/src/main/java/edu/wpi/grip/core/metrics/CsvExporter.java index 240d392bd2..39691ff498 100644 --- a/core/src/main/java/edu/wpi/grip/core/metrics/CsvExporter.java +++ b/core/src/main/java/edu/wpi/grip/core/metrics/CsvExporter.java @@ -74,7 +74,7 @@ public void addRow(List data) { public void addRow(Object... data) { checkNotNull(data, "data"); if (Arrays.stream(data).anyMatch(Objects::isNull)) { - throw new NullPointerException("Data elements cannot be null"); + throw new IllegalArgumentException("Data elements cannot be null"); } checkArgument(data.length == numCols, "Wrong number of data elements"); dataRows++; diff --git a/core/src/main/java/edu/wpi/grip/core/operations/CVOperations.java b/core/src/main/java/edu/wpi/grip/core/operations/CVOperations.java index 7df0d45a75..3f8427cad3 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/CVOperations.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/CVOperations.java @@ -72,6 +72,7 @@ public class CVOperations { private final ImmutableList imgprocOperation; @Inject + @SuppressWarnings("PMD.ExcessiveMethodLength") CVOperations(EventBus eventBus, InputSocket.Factory isf, OutputSocket.Factory osf) { this.eventBus = eventBus; final TemplateFactory templateFactory = new TemplateFactory(isf, osf); diff --git a/core/src/main/java/edu/wpi/grip/core/operations/PythonScriptOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/PythonScriptOperation.java index 28dd25caaf..45369dd7d1 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/PythonScriptOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/PythonScriptOperation.java @@ -48,7 +48,6 @@ * with more information about what the operation does. */ public class PythonScriptOperation implements Operation { - private static final String DEFAULT_NAME = "Python Operation"; private static final Logger logger = Logger.getLogger(PythonScriptOperation.class.getName()); diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/BlurOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/BlurOperation.java index 326bf7b9c6..43f09fd0ce 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/BlurOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/BlurOperation.java @@ -78,6 +78,7 @@ public List getOutputSockets() { } @Override + @SuppressWarnings("PMD.ExcessiveMethodLength") public void perform() { final MatWrapper input = inputSocket.getValue().get(); if (input.empty()) { diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/CannyEdgeOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/CannyEdgeOperation.java index 52c52fe124..3c561e1d8f 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/CannyEdgeOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/CannyEdgeOperation.java @@ -11,6 +11,8 @@ import com.google.common.collect.ImmutableList; import com.google.inject.Inject; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import org.bytedeco.javacpp.opencv_cudaimgproc.CannyEdgeDetector; import java.util.List; @@ -70,6 +72,7 @@ public List getOutputSockets() { } @Override + @SuppressFBWarnings(value = "RCN", justification = "False positive (there is no nullcheck)") public void perform() { double lowThresh = lowThreshSocket.getValue().get().doubleValue(); double highThresh = highThreshSocket.getValue().get().doubleValue(); diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/ContoursReport.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/ContoursReport.java index 91003d08dd..555ddc1058 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/ContoursReport.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/ContoursReport.java @@ -158,7 +158,7 @@ public synchronized double[] getSolidity() { @AutoValue public abstract static class Contour { - static Contour create(double area, double centerX, double centerY, double width, double + public static Contour create(double area, double centerX, double centerY, double width, double height, double solidity) { return new AutoValue_ContoursReport_Contour(area, centerX, centerY, width, height, solidity); } diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java index fcea9698b1..7afbf03ab7 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java @@ -33,6 +33,7 @@ summary = "Find contours matching certain criteria", category = OperationCategory.FEATURE_DETECTION, iconName = "find-contours") +@SuppressWarnings("PMD.TooManyFields") public class FilterContoursOperation implements Operation { private final SocketHint contoursHint = new SocketHint.Builder<>(ContoursReport diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java index 2131766fe9..367827b39b 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/PublishVideoOperation.java @@ -80,7 +80,7 @@ public class PublishVideoOperation implements Operation { final int fps = socketInputStream.readInt(); final int compression = socketInputStream.readInt(); - final int size = socketInputStream.readInt(); + final int size = socketInputStream.readInt(); // NOPMD unused: consumes next int if (compression != -1) { logger.warning("Dashboard video should be in HW mode"); diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/SaveImageOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/SaveImageOperation.java index 90b2f9f130..c83db14a05 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/SaveImageOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/SaveImageOperation.java @@ -31,6 +31,7 @@ @Description(name = "Save Images to Disk", summary = "Save image periodically to local disk", iconName = "publish-video") +@SuppressWarnings("PMD.TooManyFields") public class SaveImageOperation implements Operation { private final SocketHint inputHint diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/ThresholdOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/ThresholdOperation.java index 3016b4fe0d..fb7ad6ff84 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/ThresholdOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/ThresholdOperation.java @@ -14,17 +14,16 @@ public abstract class ThresholdOperation> implem * @param index The index of the data array that should be inspected * @param value The value that should be assigned to the mat regardless of being reallocated * @param input The input matrix that the dataArray element should be compared against - * * @return Either the old mat with the value assigned or a newly created Matrix. */ protected Mat reallocateMatIfInputSizeOrWidthChanged(final Mat[] dataArray, final int index, final Scalar value, final Mat input) { - if (dataArray[index].size().width() != input.size().width() - || dataArray[index].size().height() != input.size().height() - || dataArray[index].type() != input.type()) { - return dataArray[index] = new Mat(input.size(), input.type(), value); - } else { + if (dataArray[index].size().width() == input.size().width() + && dataArray[index].size().height() == input.size().height() + && dataArray[index].type() == input.type()) { return dataArray[index].put(value); + } else { + return dataArray[index] = new Mat(input.size(), input.type(), value); } } } diff --git a/core/src/main/java/edu/wpi/grip/core/operations/network/BooleanPublishable.java b/core/src/main/java/edu/wpi/grip/core/operations/network/BooleanPublishable.java index 3c81b2acd6..7fb0aa478e 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/network/BooleanPublishable.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/network/BooleanPublishable.java @@ -17,6 +17,7 @@ public BooleanPublishable(Boolean bool) { this.bool = bool; } + @SuppressWarnings("PMD.BooleanGetMethodName") @PublishValue(weight = 1) public boolean getValue() { return bool; diff --git a/core/src/main/java/edu/wpi/grip/core/operations/network/MapNetworkPublisher.java b/core/src/main/java/edu/wpi/grip/core/operations/network/MapNetworkPublisher.java index 6c25171d6e..a08ee58896 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/network/MapNetworkPublisher.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/network/MapNetworkPublisher.java @@ -36,9 +36,9 @@ public final void publish(Map publishMap) { + "list: " + key)); } checkNamePresent(); - if (!publishMapCopy.containsKey("") && !keys.isEmpty()) { + if (!publishMapCopy.containsKey("") && !keys.isEmpty()) { // NOPMD doPublish(publishMapCopy); - } else if (!publishMapCopy.keySet().isEmpty()) { + } else if (!publishMapCopy.keySet().isEmpty()) { // NOPMD doPublishSingle(publishMapCopy.get("")); } else { doPublish(); diff --git a/core/src/main/java/edu/wpi/grip/core/operations/network/ros/JavaToMessageConverter.java b/core/src/main/java/edu/wpi/grip/core/operations/network/ros/JavaToMessageConverter.java index 0cda4e8179..266bd95176 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/network/ros/JavaToMessageConverter.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/network/ros/JavaToMessageConverter.java @@ -67,8 +67,9 @@ protected void doConvert(LinesReport linesReport, grip_msgs.Lines linesMsg, Mess public static final JavaToMessageConverter CONTOURS = new JavaToMessageConverter(grip_msgs.Contours._TYPE) { @Override - void doConvert(ContoursReport contoursReport, grip_msgs.Contours contoursMsg, MessageFactory - messageFactory) { + public void doConvert(ContoursReport contoursReport, + grip_msgs.Contours contoursMsg, + MessageFactory messageFactory) { final List reportContours = contoursReport.getProcessedContours(); final List contours = reportContours .stream() @@ -101,7 +102,7 @@ void doConvert(ContoursReport contoursReport, grip_msgs.Contours contoursMsg, Me }; protected final TypeToken rosType; protected final TypeToken javaType; - private final java.lang.String type; + private final String type; private JavaToMessageConverter(String type) { this.type = checkNotNull(type, "type cannot be null"); @@ -111,14 +112,14 @@ private JavaToMessageConverter(String type) { }; } - public final java.lang.String getType() { + public final String getType() { return type; } /* * Should not be called directly */ - abstract void doConvert(J javaType, M message, MessageFactory messageFactory); + protected abstract void doConvert(J javaType, M message, MessageFactory messageFactory); /** * Takes a java type and a message that type maps to and adds the data to the message. @@ -145,7 +146,7 @@ private SimpleConverter(String type, BiConsumer messageDataAssigner) { } @Override - void doConvert(J javaType, M message, MessageFactory messageFactory) { + public void doConvert(J javaType, M message, MessageFactory messageFactory) { messageDataAssigner.accept(message, javaType); } } diff --git a/core/src/main/java/edu/wpi/grip/core/operations/network/ros/ROSManager.java b/core/src/main/java/edu/wpi/grip/core/operations/network/ros/ROSManager.java index 5a7a3dfc3a..a28b42ace9 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/network/ros/ROSManager.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/network/ros/ROSManager.java @@ -45,12 +45,12 @@ public ROSNetworkPublisher create(C conver */ private static class GripPublisherNode extends AbstractNodeMain { private static final GraphName GRIP_ROOT = GraphName.of("GRIP/publisher"); - private final java.lang.String publishType; + private final String publishType; private final SinglePermitSemaphore semaphore = new SinglePermitSemaphore(); private final GraphName nodeName; private volatile Optional publishMe = Optional.empty(); - public GripPublisherNode(java.lang.String publishType, GraphName nodeName) { + public GripPublisherNode(String publishType, GraphName nodeName) { super(); this.publishType = publishType; this.nodeName = GRIP_ROOT.join(nodeName); @@ -89,7 +89,7 @@ public void publish(ROSMessagePublisher.Converter o) { private static final class ROSNetworkPublisher extends ROSMessagePublisher { private final C converter; - private Optional name = Optional.empty(); + private Optional name = Optional.empty(); private Optional publisherExecutor = Optional.empty(); protected ROSNetworkPublisher(C converter) { @@ -102,8 +102,7 @@ private GripPublisherNode createNewPublisher() { } @Override - protected void publishNameChanged(Optional oldName, java.lang.String - newName) { + protected void publishNameChanged(Optional oldName, String newName) { name = Optional.of(newName); // If there is already an executor, shut it down, we'll need to recreate it publisherExecutor.ifPresent(executorPair -> executorPair.nodeMainExecutor.shutdown()); diff --git a/core/src/main/java/edu/wpi/grip/core/operations/templated/FiveSourceOneDestinationCudaOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/templated/FiveSourceOneDestinationCudaOperation.java index 4abb81ce7c..2f3b2e0204 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/templated/FiveSourceOneDestinationCudaOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/templated/FiveSourceOneDestinationCudaOperation.java @@ -9,6 +9,7 @@ import java.util.List; +@SuppressWarnings("PMD.GenericsNaming") final class FiveSourceOneDestinationCudaOperation extends CudaOperation { private final InputSocket input1; diff --git a/core/src/main/java/edu/wpi/grip/core/operations/templated/FourSourceOneDestinationCudaOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/templated/FourSourceOneDestinationCudaOperation.java index f69cbc4419..d4004f8187 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/templated/FourSourceOneDestinationCudaOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/templated/FourSourceOneDestinationCudaOperation.java @@ -9,6 +9,7 @@ import java.util.List; +@SuppressWarnings("PMD.GenericsNaming") final class FourSourceOneDestinationCudaOperation extends CudaOperation { private final InputSocket input1; diff --git a/core/src/main/java/edu/wpi/grip/core/operations/templated/OneSourceOneDestinationCudaOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/templated/OneSourceOneDestinationCudaOperation.java index 68cc21728f..42a9b3f28a 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/templated/OneSourceOneDestinationCudaOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/templated/OneSourceOneDestinationCudaOperation.java @@ -9,6 +9,7 @@ import java.util.List; +@SuppressWarnings("PMD.GenericsNaming") final class OneSourceOneDestinationCudaOperation extends CudaOperation { private final InputSocket input1; diff --git a/core/src/main/java/edu/wpi/grip/core/operations/templated/SevenSourceOneDestinationCudaOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/templated/SevenSourceOneDestinationCudaOperation.java index b7429dd41e..dfb5f2a0b3 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/templated/SevenSourceOneDestinationCudaOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/templated/SevenSourceOneDestinationCudaOperation.java @@ -9,6 +9,7 @@ import java.util.List; +@SuppressWarnings("PMD.GenericsNaming") final class SevenSourceOneDestinationCudaOperation extends CudaOperation { @@ -22,6 +23,7 @@ final class SevenSourceOneDestinationCudaOperation output; private final Performer performer; + @SuppressWarnings("PMD.ExcessiveParameterList") SevenSourceOneDestinationCudaOperation(InputSocket.Factory isf, OutputSocket.Factory osf, SocketHint t1SocketHint, diff --git a/core/src/main/java/edu/wpi/grip/core/operations/templated/SixSourceOneDestinationCudaOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/templated/SixSourceOneDestinationCudaOperation.java index a426027a43..7a648b6737 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/templated/SixSourceOneDestinationCudaOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/templated/SixSourceOneDestinationCudaOperation.java @@ -9,6 +9,7 @@ import java.util.List; +@SuppressWarnings("PMD.GenericsNaming") final class SixSourceOneDestinationCudaOperation extends CudaOperation { private final InputSocket input1; @@ -20,6 +21,7 @@ final class SixSourceOneDestinationCudaOperation exte private final OutputSocket output; private final Performer performer; + @SuppressWarnings("PMD.ExcessiveParameterList") SixSourceOneDestinationCudaOperation(InputSocket.Factory isf, OutputSocket.Factory osf, SocketHint t1SocketHint, diff --git a/core/src/main/java/edu/wpi/grip/core/operations/templated/TemplateFactory.java b/core/src/main/java/edu/wpi/grip/core/operations/templated/TemplateFactory.java index 31a4862bd9..6b151bca46 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/templated/TemplateFactory.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/templated/TemplateFactory.java @@ -23,6 +23,7 @@ public final class TemplateFactory { /* * Intentionally package private */ + @SuppressWarnings("PMD.DefaultPackage") static final String ASSERTION_MESSAGE = "Output must be present for this operation to complete " + "correctly."; private final InputSocket.Factory isf; diff --git a/core/src/main/java/edu/wpi/grip/core/operations/templated/ThreeSourceOneDestinationCudaOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/templated/ThreeSourceOneDestinationCudaOperation.java index bee043b757..df40702348 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/templated/ThreeSourceOneDestinationCudaOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/templated/ThreeSourceOneDestinationCudaOperation.java @@ -9,6 +9,7 @@ import java.util.List; +@SuppressWarnings("PMD.GenericsNaming") final class ThreeSourceOneDestinationCudaOperation extends CudaOperation { private final InputSocket input1; diff --git a/core/src/main/java/edu/wpi/grip/core/operations/templated/TwoSourceOneDestinationCudaOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/templated/TwoSourceOneDestinationCudaOperation.java index 02381f100b..ab99db363e 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/templated/TwoSourceOneDestinationCudaOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/templated/TwoSourceOneDestinationCudaOperation.java @@ -9,6 +9,7 @@ import java.util.List; +@SuppressWarnings("PMD.GenericsNaming") final class TwoSourceOneDestinationCudaOperation extends CudaOperation { private final InputSocket input1; diff --git a/core/src/main/java/edu/wpi/grip/core/serialization/Project.java b/core/src/main/java/edu/wpi/grip/core/serialization/Project.java index 3d29a48f22..b68c951298 100644 --- a/core/src/main/java/edu/wpi/grip/core/serialization/Project.java +++ b/core/src/main/java/edu/wpi/grip/core/serialization/Project.java @@ -85,7 +85,7 @@ public void setFile(Optional file) { * Load the project from a file. */ public void open(File file) throws IOException { - try (final InputStreamReader reader = new InputStreamReader(new FileInputStream(file), + try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) { this.open(reader); } @@ -140,7 +140,7 @@ public boolean trySave(File file) { * Save the project to a file. */ public void save(File file) throws IOException { - try (final Writer writer = new OutputStreamWriter(new FileOutputStream(file), + try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) { this.save(writer); } @@ -179,6 +179,7 @@ public void set(boolean b) { consumers.parallelStream().forEach(c -> c.accept(b)); } + @SuppressWarnings("PMD.BooleanGetMethodName") public boolean get() { return b; } diff --git a/core/src/main/java/edu/wpi/grip/core/serialization/SocketConverter.java b/core/src/main/java/edu/wpi/grip/core/serialization/SocketConverter.java index 060f3a9012..9d287da1cb 100644 --- a/core/src/main/java/edu/wpi/grip/core/serialization/SocketConverter.java +++ b/core/src/main/java/edu/wpi/grip/core/serialization/SocketConverter.java @@ -112,7 +112,7 @@ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext co // different things // (such as connections) can reference sockets in the pipeline. Socket socket; - if (reader.getAttribute(STEP_ATTRIBUTE) != null) { + if (reader.getAttribute(STEP_ATTRIBUTE) != null) { // NOPMD final int stepIndex = Integer.parseInt(reader.getAttribute(STEP_ATTRIBUTE)); final int socketIndex = Integer.parseInt(reader.getAttribute(SOCKET_ATTRIBUTE)); @@ -120,7 +120,7 @@ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext co socket = (direction == Socket.Direction.INPUT) ? step.getInputSockets().get(socketIndex) : step.getOutputSockets().get(socketIndex); - } else if (reader.getAttribute(SOURCE_ATTRIBUTE) != null) { + } else if (reader.getAttribute(SOURCE_ATTRIBUTE) != null) { // NOPMD final int sourceIndex = Integer.parseInt(reader.getAttribute(SOURCE_ATTRIBUTE)); final int socketIndex = Integer.parseInt(reader.getAttribute(SOCKET_ATTRIBUTE)); @@ -162,12 +162,14 @@ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext co private Class getDeserializedType(Socket socket) { final Class socketType = socket.getSocketHint().getType(); - if (!socketType.isInterface() && !Modifier.isAbstract(socketType.getModifiers())) { + if (socketType.isInterface() || Modifier.isAbstract(socketType.getModifiers())) { + if (socketType.equals(List.class)) { + return ArrayList.class; // NOPMD + } else if (socketType.equals(Number.class)) { + return Double.class; + } + } else { return socketType; - } else if (socketType.equals(List.class)) { - return ArrayList.class; - } else if (socketType.equals(Number.class)) { - return Double.class; } throw new ConversionException("Not sure what concrete class to use for socket with type " diff --git a/core/src/main/java/edu/wpi/grip/core/serialization/StepConverter.java b/core/src/main/java/edu/wpi/grip/core/serialization/StepConverter.java index 8ea4961496..6aab689d66 100644 --- a/core/src/main/java/edu/wpi/grip/core/serialization/StepConverter.java +++ b/core/src/main/java/edu/wpi/grip/core/serialization/StepConverter.java @@ -8,7 +8,6 @@ import edu.wpi.grip.core.sockets.OutputSocket; import edu.wpi.grip.core.sockets.Socket; -import com.google.common.eventbus.EventBus; import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; @@ -30,8 +29,6 @@ public class StepConverter implements Converter { private static final String NAME_ATTRIBUTE = "name"; - @Inject - private EventBus eventBus; @Inject private Palette palette; @Inject diff --git a/core/src/main/java/edu/wpi/grip/core/sockets/SocketHints.java b/core/src/main/java/edu/wpi/grip/core/sockets/SocketHints.java index 50924e6876..f097965b11 100644 --- a/core/src/main/java/edu/wpi/grip/core/sockets/SocketHints.java +++ b/core/src/main/java/edu/wpi/grip/core/sockets/SocketHints.java @@ -5,6 +5,8 @@ import com.google.common.reflect.TypeToken; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import org.bytedeco.javacpp.opencv_core.Point; import org.bytedeco.javacpp.opencv_core.Size; @@ -83,6 +85,7 @@ private static SocketHint.Builder> createNumberListSocketHintBuilde /* PRIVATE PARTIALLY CONSTRUCTED BUILDERS BELOW */ + @SuppressFBWarnings(value = "UPM", justification = "False positive") private static SocketHint.Builder createNumberSocketHintBuilder(final String identifier, final Number number, final Number[] domain) { diff --git a/core/src/main/java/edu/wpi/grip/core/sources/CameraSource.java b/core/src/main/java/edu/wpi/grip/core/sources/CameraSource.java index f22da6a2df..ed1eb9aed1 100644 --- a/core/src/main/java/edu/wpi/grip/core/sources/CameraSource.java +++ b/core/src/main/java/edu/wpi/grip/core/sources/CameraSource.java @@ -45,7 +45,7 @@ /** * Provides a way to generate a constantly updated {@link Mat} from a camera. */ -@XStreamAlias(value = "grip:Camera") +@XStreamAlias("grip:Camera") public class CameraSource extends Source implements RestartableService { /** @@ -86,6 +86,7 @@ public class CameraSource extends Source implements RestartableService { private final OutputSocket frameOutputSocket; private final OutputSocket frameRateOutputSocket; private final Supplier grabberSupplier; + @SuppressWarnings("PMD.LinguisticNaming") private final AtomicBoolean isNewFrame = new AtomicBoolean(false); private final Mat currentFrameTransferMat = new Mat(); private final AutoRestartingService cameraService; @@ -144,11 +145,11 @@ public class CameraSource extends Source implements RestartableService { final String deviceNumberProperty = properties.getProperty(DEVICE_NUMBER_PROPERTY); final String addressProperty = properties.getProperty(ADDRESS_PROPERTY); - if (deviceNumberProperty != null) { + if (deviceNumberProperty != null) { // NOPMD final int deviceNumber = Integer.parseInt(deviceNumberProperty); this.name = "Webcam " + deviceNumber; this.grabberSupplier = () -> grabberFactory.create(deviceNumber); - } else if (addressProperty != null) { + } else if (addressProperty != null) { // NOPMD this.name = "IP Camera " + new URL(addressProperty).getHost(); this.grabberSupplier = () -> { try { diff --git a/core/src/main/java/edu/wpi/grip/core/sources/ClassifierSource.java b/core/src/main/java/edu/wpi/grip/core/sources/ClassifierSource.java index 78d8c1805a..ec59e4b431 100644 --- a/core/src/main/java/edu/wpi/grip/core/sources/ClassifierSource.java +++ b/core/src/main/java/edu/wpi/grip/core/sources/ClassifierSource.java @@ -6,7 +6,6 @@ import edu.wpi.grip.core.util.ExceptionWitness; import com.google.common.collect.ImmutableList; -import com.google.common.eventbus.EventBus; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -35,8 +34,7 @@ public class ClassifierSource extends Source { private final OutputSocket classifierSocket; @AssistedInject - protected ClassifierSource(EventBus eventBus, - OutputSocket.Factory osf, + protected ClassifierSource(OutputSocket.Factory osf, ExceptionWitness.Factory exceptionWitnessFactory, @Assisted String filePath) { super(exceptionWitnessFactory); @@ -45,11 +43,10 @@ protected ClassifierSource(EventBus eventBus, } @AssistedInject - protected ClassifierSource(EventBus eventBus, - OutputSocket.Factory osf, + protected ClassifierSource(OutputSocket.Factory osf, ExceptionWitness.Factory exceptionWitnessFactory, @Assisted Properties properties) { - this(eventBus, osf, exceptionWitnessFactory, properties.getProperty(FILE_PATH_PROPERTY)); + this(osf, exceptionWitnessFactory, properties.getProperty(FILE_PATH_PROPERTY)); } @Override diff --git a/core/src/main/java/edu/wpi/grip/core/sources/ImageFileSource.java b/core/src/main/java/edu/wpi/grip/core/sources/ImageFileSource.java index db3808d5f4..aa297be305 100644 --- a/core/src/main/java/edu/wpi/grip/core/sources/ImageFileSource.java +++ b/core/src/main/java/edu/wpi/grip/core/sources/ImageFileSource.java @@ -30,7 +30,7 @@ /** * Provides a way to generate a {@link Mat} from an image on the filesystem. */ -@XStreamAlias(value = "grip:ImageFile") +@XStreamAlias("grip:ImageFile") public final class ImageFileSource extends Source { private static final String PATH_PROPERTY = "path"; diff --git a/core/src/main/java/edu/wpi/grip/core/sources/MultiImageFileSource.java b/core/src/main/java/edu/wpi/grip/core/sources/MultiImageFileSource.java index 9553f60cd3..5bd52fa48c 100644 --- a/core/src/main/java/edu/wpi/grip/core/sources/MultiImageFileSource.java +++ b/core/src/main/java/edu/wpi/grip/core/sources/MultiImageFileSource.java @@ -34,7 +34,7 @@ * A Source that supports multiple images. They can be toggled using {@link * MultiImageFileSource#next()} and {@link MultiImageFileSource#previous()} */ -@XStreamAlias(value = "grip:MultiImageFile") +@XStreamAlias("grip:MultiImageFile") public final class MultiImageFileSource extends Source implements PreviousNext { private static final String INDEX_PROPERTY = "index"; private static final String SIZE_PROPERTY = "numImages"; @@ -174,6 +174,7 @@ protected boolean updateOutputSockets() { .map(m -> !currentImage.get().equals(m)) .orElse(false)) { outputSocket.getValue().ifPresent(m -> currentImage.ifPresent(m::set)); + outputSocket.flagChanged(); return true; } else { return false; diff --git a/core/src/main/java/edu/wpi/grip/core/sources/VideoFileSource.java b/core/src/main/java/edu/wpi/grip/core/sources/VideoFileSource.java index 4b7321aa0c..4fa33157cb 100644 --- a/core/src/main/java/edu/wpi/grip/core/sources/VideoFileSource.java +++ b/core/src/main/java/edu/wpi/grip/core/sources/VideoFileSource.java @@ -47,6 +47,7 @@ public class VideoFileSource extends Source implements Pausable { private final OutputSocket imageSocket; private final OutputSocket fpsSocket; private final Mat workingMat = new Mat(); + @SuppressWarnings("PMD.LinguisticNaming") private final AtomicBoolean isNewFrame = new AtomicBoolean(false); private FFmpegFrameGrabber frameGrabber; private final OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); diff --git a/core/src/main/java/edu/wpi/grip/core/util/ExceptionWitness.java b/core/src/main/java/edu/wpi/grip/core/util/ExceptionWitness.java index 178976bac3..82a50797b1 100644 --- a/core/src/main/java/edu/wpi/grip/core/util/ExceptionWitness.java +++ b/core/src/main/java/edu/wpi/grip/core/util/ExceptionWitness.java @@ -33,6 +33,7 @@ public class ExceptionWitness { private final EventBus eventBus; private final Object origin; + @SuppressWarnings("PMD.LinguisticNaming") private final AtomicBoolean isExceptionState = new AtomicBoolean(false); @Inject diff --git a/core/src/main/java/edu/wpi/grip/core/util/ImageLoadingUtility.java b/core/src/main/java/edu/wpi/grip/core/util/ImageLoadingUtility.java index 4eb0cad062..b8191ad451 100644 --- a/core/src/main/java/edu/wpi/grip/core/util/ImageLoadingUtility.java +++ b/core/src/main/java/edu/wpi/grip/core/util/ImageLoadingUtility.java @@ -29,10 +29,10 @@ public static void loadImage(String path, final int flags, Mat dst) throws IOExc checkNotNull(path, "The path can not be null"); checkNotNull(dst, "The destination Mat can not be null"); final Mat img = opencv_imgcodecs.imread(path, flags); - if (img != null && !img.empty() && !img.isNull()) { - img.copyTo(dst); - } else { + if (img == null || img.empty() || img.isNull()) { throw new IOException("Error loading image " + path); + } else { + img.copyTo(dst); } } diff --git a/core/src/main/java/edu/wpi/grip/core/util/MetaInfReader.java b/core/src/main/java/edu/wpi/grip/core/util/MetaInfReader.java index 333df2cbf9..d63ed54154 100644 --- a/core/src/main/java/edu/wpi/grip/core/util/MetaInfReader.java +++ b/core/src/main/java/edu/wpi/grip/core/util/MetaInfReader.java @@ -19,6 +19,10 @@ */ public final class MetaInfReader { + private MetaInfReader() { + throw new UnsupportedOperationException("This is a utility class!"); + } + /** * Reads all classes from the appropriate registry file. * @@ -103,10 +107,10 @@ static Class classForNameOrNull(String name) { @VisibleForTesting static String stripComment(String line) { int index = line.indexOf('#'); - if (index != -1) { - return line.substring(0, index); - } else { + if (index == -1) { return line; + } else { + return line.substring(0, index); } } diff --git a/core/src/main/java/edu/wpi/grip/core/util/SafeShutdown.java b/core/src/main/java/edu/wpi/grip/core/util/SafeShutdown.java index d1b063e2b9..1274063e9b 100644 --- a/core/src/main/java/edu/wpi/grip/core/util/SafeShutdown.java +++ b/core/src/main/java/edu/wpi/grip/core/util/SafeShutdown.java @@ -65,6 +65,10 @@ public void run() { }); } + private SafeShutdown() { + throw new UnsupportedOperationException("This is a utility class!"); + } + /** * Shutdown's the VM in such a way that flags that the vm is stopping. This is so that we don't * run the normal exception handling code when shutting down the application. diff --git a/core/src/main/java/edu/wpi/grip/core/util/service/AutoRestartingService.java b/core/src/main/java/edu/wpi/grip/core/util/service/AutoRestartingService.java index 4397edf498..eee5ac4e83 100644 --- a/core/src/main/java/edu/wpi/grip/core/util/service/AutoRestartingService.java +++ b/core/src/main/java/edu/wpi/grip/core/util/service/AutoRestartingService.java @@ -30,6 +30,7 @@ public class AutoRestartingService implements RestartableServ private final ServiceRestartPolicy policy; private final Supplier delegateFactory; private final ConcurrentMap listeners; + @SuppressWarnings("PMD.LinguisticNaming") private final AtomicBoolean shouldContinueRestarting = new AtomicBoolean(false); private final Set addedListeners = new HashSet<>(); private S delegate; diff --git a/core/src/test/java/edu/wpi/grip/core/CoreCommandLineHelperTest.java b/core/src/test/java/edu/wpi/grip/core/CoreCommandLineHelperTest.java index 55a978ce7a..dd92677456 100644 --- a/core/src/test/java/edu/wpi/grip/core/CoreCommandLineHelperTest.java +++ b/core/src/test/java/edu/wpi/grip/core/CoreCommandLineHelperTest.java @@ -8,7 +8,7 @@ public class CoreCommandLineHelperTest { private static class MockHelper extends CoreCommandLineHelper { @Override - void exit() { + public void exit() { // NOP } } @@ -19,13 +19,13 @@ public void testHelp() { boolean[] exited = {false}; MockHelper m = new MockHelper() { @Override - void printHelpAndExit() { + public void printHelpAndExit() { printed[0] = true; super.printHelpAndExit(); } @Override - void exit() { + public void exit() { exited[0] = true; } }; @@ -50,13 +50,13 @@ public void testVersion() { boolean[] exited = {false}; MockHelper m = new MockHelper() { @Override - void printVersionAndExit() { + public void printVersionAndExit() { printed[0] = true; super.printVersionAndExit(); } @Override - void exit() { + public void exit() { exited[0] = true; } }; diff --git a/core/src/test/java/edu/wpi/grip/core/CoreSanityTest.java b/core/src/test/java/edu/wpi/grip/core/CoreSanityTest.java index b52c95e84e..c7bece9380 100644 --- a/core/src/test/java/edu/wpi/grip/core/CoreSanityTest.java +++ b/core/src/test/java/edu/wpi/grip/core/CoreSanityTest.java @@ -47,15 +47,15 @@ public CoreSanityTest() { setDefault(Step.class, new MockStep()); setDistinctValues(Description.class, - A.class.getAnnotation(Description.class), - B.class.getAnnotation(Description.class)); + OperationA.class.getAnnotation(Description.class), + OperationB.class.getAnnotation(Description.class)); } @Description(name = "A", summary = "A") - private static class A { + private static class OperationA { } @Description(name = "B", summary = "B") - private static class B { + private static class OperationB { } } diff --git a/core/src/test/java/edu/wpi/grip/core/ManualPipelineRunner.java b/core/src/test/java/edu/wpi/grip/core/ManualPipelineRunner.java index 2f6e17c740..0a1569d56b 100644 --- a/core/src/test/java/edu/wpi/grip/core/ManualPipelineRunner.java +++ b/core/src/test/java/edu/wpi/grip/core/ManualPipelineRunner.java @@ -24,6 +24,7 @@ public PipelineRunner startAsync() { } @SuppressWarnings("PMD.UselessOverridingMethod") + @Override public void runPipeline() { super.runPipeline(); } diff --git a/core/src/test/java/edu/wpi/grip/core/PipelineRunnerTest.java b/core/src/test/java/edu/wpi/grip/core/PipelineRunnerTest.java index 48ae07d2b6..12b9c4f8ac 100644 --- a/core/src/test/java/edu/wpi/grip/core/PipelineRunnerTest.java +++ b/core/src/test/java/edu/wpi/grip/core/PipelineRunnerTest.java @@ -98,7 +98,7 @@ public void testRunEmptyPipelineSucceeds() { } @Test - public void testRunSimplePipeline_WithSourcesAndSteps() throws IOException { + public void testRunSimplePipelineWithSourcesAndSteps() throws IOException { final EventBus eventBus = new EventBus(); final MockSource source = new MockSource(); final MockStep step = new MockStep(); @@ -400,6 +400,7 @@ static class FailureListener extends Service.Listener { private Service.State failedFrom = null; private Throwable failure = null; + @Override public synchronized void failed(Service.State from, Throwable failure) { this.failedFrom = from; this.failure = failure; diff --git a/core/src/test/java/edu/wpi/grip/core/cuda/CudaVerifierTest.java b/core/src/test/java/edu/wpi/grip/core/cuda/CudaVerifierTest.java index 020bc26c2e..9ef8ed490e 100644 --- a/core/src/test/java/edu/wpi/grip/core/cuda/CudaVerifierTest.java +++ b/core/src/test/java/edu/wpi/grip/core/cuda/CudaVerifierTest.java @@ -39,6 +39,7 @@ public NonExitingVerifier(AccelerationMode accelerationMode, CudaDetector cudaDe } @Override + @SuppressWarnings("PMD.DefaultPackage") void exit() { exitCount++; } diff --git a/core/src/test/java/edu/wpi/grip/core/http/HttpPipelineSwitcherTest.java b/core/src/test/java/edu/wpi/grip/core/http/HttpPipelineSwitcherTest.java index e5090dd11e..f975abf26b 100644 --- a/core/src/test/java/edu/wpi/grip/core/http/HttpPipelineSwitcherTest.java +++ b/core/src/test/java/edu/wpi/grip/core/http/HttpPipelineSwitcherTest.java @@ -38,6 +38,7 @@ public void setUp() { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testNotPost() throws IOException { project = new Project() { @Override diff --git a/core/src/test/java/edu/wpi/grip/core/metrics/CsvExporterTest.java b/core/src/test/java/edu/wpi/grip/core/metrics/CsvExporterTest.java index 857c12982f..4dbc88ab92 100644 --- a/core/src/test/java/edu/wpi/grip/core/metrics/CsvExporterTest.java +++ b/core/src/test/java/edu/wpi/grip/core/metrics/CsvExporterTest.java @@ -56,7 +56,7 @@ public void testNullVarargsRow() { exporter.addRow((Object[]) null); } - @Test(expected = NullPointerException.class) + @Test(expected = IllegalArgumentException.class) public void testNullDataElement() { exporter = new CsvExporter(2, "foo", "bar"); exporter.addRow(null, null); diff --git a/core/src/test/java/edu/wpi/grip/core/operations/OperationsFactory.java b/core/src/test/java/edu/wpi/grip/core/operations/OperationsFactory.java index ab369fae72..bff78c1bfc 100644 --- a/core/src/test/java/edu/wpi/grip/core/operations/OperationsFactory.java +++ b/core/src/test/java/edu/wpi/grip/core/operations/OperationsFactory.java @@ -18,6 +18,7 @@ import java.util.Optional; +@SuppressWarnings("PMD.UseUtilityClass") public class OperationsFactory { public static Operations create(EventBus eventBus, Injector injector) { @@ -50,6 +51,7 @@ public static CVOperations createCV(EventBus eventBus) { private static class MockROSMessagePublisher extends ROSMessagePublisher { + @SuppressWarnings("PMD.UnusedFormalParameter") public MockROSMessagePublisher(C converter) { } diff --git a/core/src/test/java/edu/wpi/grip/core/operations/network/MapNetworkPublisherTest.java b/core/src/test/java/edu/wpi/grip/core/operations/network/MapNetworkPublisherTest.java index df3a3653ed..1fb45c4473 100644 --- a/core/src/test/java/edu/wpi/grip/core/operations/network/MapNetworkPublisherTest.java +++ b/core/src/test/java/edu/wpi/grip/core/operations/network/MapNetworkPublisherTest.java @@ -74,7 +74,7 @@ protected void doPublishSingle(Double value) { @Test public void testPublisherCallsCorrectDoPublishWhenNoKeysAreProvidedAndMapIsNotEmpty() { - final double EXPECTED_VALUE = Math.PI; + final double expected = Math.PI; boolean[] doPublishSingleValueWasCalled = {false}; final DoubleMapPublisher doubleMapPublisher = new DoubleMapPublisher(new HashSet<>()) { @@ -92,11 +92,11 @@ protected void doPublish(Map publishMap) { @Override protected void doPublishSingle(Double value) { doPublishSingleValueWasCalled[0] = true; - assertEquals("Should have published the expected value", EXPECTED_VALUE, value, 0.001); + assertEquals("Should have published the expected value", expected, value, 0.001); } }; doubleMapPublisher.setName("Don't care"); - doubleMapPublisher.publish(ImmutableMap.of("", EXPECTED_VALUE)); + doubleMapPublisher.publish(ImmutableMap.of("", expected)); assertTrue("doPublish with a single value should have been called", doPublishSingleValueWasCalled[0]); } diff --git a/core/src/test/java/edu/wpi/grip/core/operations/network/NetworkPublisherTest.java b/core/src/test/java/edu/wpi/grip/core/operations/network/NetworkPublisherTest.java index 0a64d9b9fa..2c8a447b69 100644 --- a/core/src/test/java/edu/wpi/grip/core/operations/network/NetworkPublisherTest.java +++ b/core/src/test/java/edu/wpi/grip/core/operations/network/NetworkPublisherTest.java @@ -10,19 +10,19 @@ public class NetworkPublisherTest { @Test public void testThatNameChangeIsCalledInitiallyButNotAgainIfNameIsSame() { - final String NAME = "QUACKERY!"; + final String name = "QUACKERY!"; final int[] publishNameChangedCallCount = {0}; final TestNetworkPublisher publisher = new TestNetworkPublisher() { @Override protected void publishNameChanged(Optional oldName, String newName) { publishNameChangedCallCount[0]++; - assertEquals("Name was not the new name", NAME, newName); + assertEquals("Name was not the new name", name, newName); } }; - publisher.setName(NAME); + publisher.setName(name); assertEquals("publishNameChanged was called an unexpected number of times", 1, publishNameChangedCallCount[0]); - publisher.setName(NAME); + publisher.setName(name); assertEquals("publishNameChanged should not have been called agian", 1, publishNameChangedCallCount[0]); } diff --git a/core/src/test/java/edu/wpi/grip/core/operations/network/PublishAnnotatedOperationTest.java b/core/src/test/java/edu/wpi/grip/core/operations/network/PublishAnnotatedOperationTest.java index 9cda0f64f0..d29b79cc4e 100644 --- a/core/src/test/java/edu/wpi/grip/core/operations/network/PublishAnnotatedOperationTest.java +++ b/core/src/test/java/edu/wpi/grip/core/operations/network/PublishAnnotatedOperationTest.java @@ -85,7 +85,7 @@ public void testPublishableWithNoAnnoatedMethods() { @Test @SuppressWarnings("unchecked") public void testPublishSimpleReportReturnsExpectedValues() { - final String PUBLISHER_NAME = "PUBLISH QUACKERY!"; + final String publisherName = "PUBLISH QUACKERY!"; final boolean[] publishNameChangedRan = {false}; final boolean[] doPublishRan = {false}; class TestMapNetworkPublisher extends MapNetworkPublisher { @@ -95,7 +95,7 @@ public TestMapNetworkPublisher(Set keys) { @Override protected void publishNameChanged(Optional oldName, String newName) { - assertEquals("Name was not what was expected", newName, PUBLISHER_NAME); + assertEquals("Name was not what was expected", newName, publisherName); assertFalse("There was an old name when there shouldn't have been", oldName.isPresent()); publishNameChangedRan[0] = true; } @@ -137,7 +137,7 @@ public MapNetworkPublisher create(Set keys) { final List inputSockets = testPublishAnnotatedOperation.getInputSockets(); inputSockets.get(0).setValue(new SimpleReport()); - inputSockets.get(1).setValue(PUBLISHER_NAME); + inputSockets.get(1).setValue(publisherName); testPublishAnnotatedOperation.perform(); diff --git a/core/src/test/java/edu/wpi/grip/core/operations/opencv/AddOperationTest.java b/core/src/test/java/edu/wpi/grip/core/operations/opencv/AddOperationTest.java index 3b89f0ccbd..cf802536ef 100644 --- a/core/src/test/java/edu/wpi/grip/core/operations/opencv/AddOperationTest.java +++ b/core/src/test/java/edu/wpi/grip/core/operations/opencv/AddOperationTest.java @@ -19,12 +19,11 @@ public class AddOperationTest { - EventBus eventBus; - AddOperation addition; + private AddOperation addition; @Before public void setUp() throws Exception { - this.eventBus = new EventBus(); + EventBus eventBus = new EventBus(); this.addition = new AddOperation(eventBus); } diff --git a/core/src/test/java/edu/wpi/grip/core/sources/CameraSourceTest.java b/core/src/test/java/edu/wpi/grip/core/sources/CameraSourceTest.java index 2eaac028cc..91db12e00b 100644 --- a/core/src/test/java/edu/wpi/grip/core/sources/CameraSourceTest.java +++ b/core/src/test/java/edu/wpi/grip/core/sources/CameraSourceTest.java @@ -170,7 +170,7 @@ public void testStartingTwiceShouldThrowIllegalState() throws Exception { @Test public void testEnsureThatGrabberIsReinitializedWhenStartThrowsException() throws IOException, TimeoutException { - final String GRABBER_START_MESSAGE = "This is expected to fail this way"; + final String message = "This is expected to fail this way"; Waiter waiter1 = new Waiter(); Waiter waiter2 = new Waiter(); Waiter waiter3 = new Waiter(); @@ -186,7 +186,7 @@ public void start() throws Exception { if (!waiterQueue.isEmpty()) { waiterQueue.poll().resume(); } - throw new FrameGrabber.Exception(GRABBER_START_MESSAGE); + throw new FrameGrabber.Exception(message); } }; } @@ -203,7 +203,7 @@ public FrameGrabber create(String addressProperty) throws MalformedURLException public void failed(Service.State from, Throwable failure) { failedWaiter.assertNotNull(failure); failedWaiter.assertNotNull(failure.getCause()); - failedWaiter.assertEquals(GRABBER_START_MESSAGE, failure.getCause().getMessage()); + failedWaiter.assertEquals(message, failure.getCause().getMessage()); failedWaiter.resume(); } }, MoreExecutors.directExecutor()); diff --git a/core/src/test/java/edu/wpi/grip/core/sources/GrabberServiceTest.java b/core/src/test/java/edu/wpi/grip/core/sources/GrabberServiceTest.java index 0eccf4a3fb..4ebf45a5f3 100644 --- a/core/src/test/java/edu/wpi/grip/core/sources/GrabberServiceTest.java +++ b/core/src/test/java/edu/wpi/grip/core/sources/GrabberServiceTest.java @@ -166,7 +166,7 @@ public Mat convert(Frame frame) { @Test public void testEnsureThatUpdaterIsRunEvenIfExceptionIsThrownInShutDown() { - final String STOP_EXCEPTION = "This should be thrown but then caught"; + final String message = "This should be thrown but then caught"; final boolean[] updateWasCalled = {false}; final GrabberService grabberService = createSimpleGrabberService( @@ -174,7 +174,7 @@ public void testEnsureThatUpdaterIsRunEvenIfExceptionIsThrownInShutDown() { @Override @SuppressWarnings("PMD.SignatureDeclareThrowsException") public void stop() throws Exception { - throw new FrameGrabber.Exception(STOP_EXCEPTION); + throw new FrameGrabber.Exception(message); } }, new SimpleUpdater() { @Override @@ -193,7 +193,7 @@ public void updatesComplete() { } catch (GrabberService.GrabberServiceException e) { assertTrue("updatesComplete was not called", updateWasCalled[0]); assertThat(e.getCause()).isNotNull(); - assertThat(e.getCause()).hasMessage(STOP_EXCEPTION); + assertThat(e.getCause()).hasMessage(message); assertThat(e.getCause()).isInstanceOf(FrameGrabber.Exception.class); } } diff --git a/core/src/test/java/edu/wpi/grip/core/sources/MockCameraSource.java b/core/src/test/java/edu/wpi/grip/core/sources/MockCameraSource.java index 7d9e62554f..6541e5b9f0 100644 --- a/core/src/test/java/edu/wpi/grip/core/sources/MockCameraSource.java +++ b/core/src/test/java/edu/wpi/grip/core/sources/MockCameraSource.java @@ -33,6 +33,7 @@ public MockCameraSource stopAsync() { return this; } + @Override public boolean isRunning() { return started; } diff --git a/core/src/test/java/edu/wpi/grip/core/sources/MultiImageFileSourceTest.java b/core/src/test/java/edu/wpi/grip/core/sources/MultiImageFileSourceTest.java index 8aee0d99f5..52df2074f5 100644 --- a/core/src/test/java/edu/wpi/grip/core/sources/MultiImageFileSourceTest.java +++ b/core/src/test/java/edu/wpi/grip/core/sources/MultiImageFileSourceTest.java @@ -52,6 +52,7 @@ public void createMultiImageFileSourceWithTextFile() throws IOException { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testNextValue() throws Exception { source.next(); OutputSocket outputSocket = source.getOutputSockets().get(0); @@ -60,6 +61,7 @@ public void testNextValue() throws Exception { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testPreviousValue() throws Exception { source.previous(); @@ -69,6 +71,7 @@ public void testPreviousValue() throws Exception { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testConstructedWithIndex() { sourceWithIndexSet.updateOutputSockets(); OutputSocket outputSocket = sourceWithIndexSet.getOutputSockets().get(0); @@ -76,6 +79,7 @@ public void testConstructedWithIndex() { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testLoadFromProperties() throws Exception { final Properties properties = sourceWithIndexSet.getProperties(); final MultiImageFileSource newSource = new MultiImageFileSource( diff --git a/core/src/test/java/edu/wpi/grip/core/util/SafeShutdownTest.java b/core/src/test/java/edu/wpi/grip/core/util/SafeShutdownTest.java index 0e3aed0af4..23db7cd6b3 100644 --- a/core/src/test/java/edu/wpi/grip/core/util/SafeShutdownTest.java +++ b/core/src/test/java/edu/wpi/grip/core/util/SafeShutdownTest.java @@ -15,6 +15,7 @@ public class SafeShutdownTest { protected static void setUpSecurityManager() { oldManager = System.getSecurityManager(); System.setSecurityManager(new SecurityManager() { + @Override public void checkPermission(Permission permission) { if (permission.getName().contains("exitVM")) { throw new IllegalStateException(SHUTDOWN_EXCEPTION_MESSAGE); diff --git a/core/src/test/java/edu/wpi/grip/core/util/service/AutoRestartingServiceTest.java b/core/src/test/java/edu/wpi/grip/core/util/service/AutoRestartingServiceTest.java index f96a65a5ed..d89594c612 100644 --- a/core/src/test/java/edu/wpi/grip/core/util/service/AutoRestartingServiceTest.java +++ b/core/src/test/java/edu/wpi/grip/core/util/service/AutoRestartingServiceTest.java @@ -13,6 +13,7 @@ import org.junit.rules.Timeout; import java.util.LinkedList; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -193,6 +194,7 @@ public void testListenerGetsAddedToRunningService() throws InterruptedException restartingService.addListener(new Service.Listener() { + @Override public void starting() { startingListener[0] = true; } @@ -222,7 +224,7 @@ public void stopping(Service.State from) { * Records all instances of the object returned by {@link Supplier#get()} */ private static class RecordingSupplier implements Supplier { - private final LinkedList services = new LinkedList<>(); + private final List services = new LinkedList<>(); private final Supplier serviceSupplier; private RecordingSupplier(Supplier serviceSupplier) { @@ -232,7 +234,7 @@ private RecordingSupplier(Supplier serviceSupplier) { @Override public S get() { final S instance = serviceSupplier.get(); - services.push(instance); + services.add(instance); return instance; } } diff --git a/findBugsSuppressions.xml b/findBugsSuppressions.xml index 9380ff5aeb..50a55812d9 100644 --- a/findBugsSuppressions.xml +++ b/findBugsSuppressions.xml @@ -17,4 +17,9 @@ + + + + + diff --git a/pmd-ruleset.xml b/pmd-ruleset.xml index bd92a94192..fb198ecb8b 100644 --- a/pmd-ruleset.xml +++ b/pmd-ruleset.xml @@ -3,39 +3,67 @@ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd"> - - - - - - - - - - - + + The PMD RuleSet for GRIP. + + + + + + + + + + - - - + + + + - - + + + + + + + + + + + + + + + - - + + + + - - - - - - + + + + - - + + + + - - + + + + + + + + + + + + + diff --git a/ui/src/main/deploy/package/linux/GRIP.png b/ui/installer-files/linux/GRIP.png similarity index 100% rename from ui/src/main/deploy/package/linux/GRIP.png rename to ui/installer-files/linux/GRIP.png diff --git a/ui/src/main/deploy/package/macosx/GRIP.icns b/ui/installer-files/mac/GRIP.icns similarity index 100% rename from ui/src/main/deploy/package/macosx/GRIP.icns rename to ui/installer-files/mac/GRIP.icns diff --git a/ui/installer-files/win/GRIP-setup-icon.bmp b/ui/installer-files/win/GRIP-setup-icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7391fbf7b720d7d99708f7c12290475d757e999c GIT binary patch literal 6968 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 N-rdP6RqjYR{~t`I`XvAW literal 0 HcmV?d00001 diff --git a/ui/preloader/preloader.gradle.kts b/ui/preloader/preloader.gradle.kts index cd81a32b35..2c3f59f42b 100644 --- a/ui/preloader/preloader.gradle.kts +++ b/ui/preloader/preloader.gradle.kts @@ -2,8 +2,19 @@ plugins { `application` } +createNativeConfigurations() + +dependencies { + if (BuildType.isJdk11) { + javafx("base") + javafx("controls") + javafx("fxml") + javafx("graphics") + } +} + application { - mainClassName = "edu.wpi.grip.preloader.GripPreloader" + mainClassName = "edu.wpi.grip.preloader.Launch" } tasks.named("run") { diff --git a/ui/preloader/src/main/java/edu/wpi/grip/preloader/GripPreloader.java b/ui/preloader/src/main/java/edu/wpi/grip/preloader/GripPreloader.java index 79e02616bb..29c39876b4 100644 --- a/ui/preloader/src/main/java/edu/wpi/grip/preloader/GripPreloader.java +++ b/ui/preloader/src/main/java/edu/wpi/grip/preloader/GripPreloader.java @@ -29,10 +29,6 @@ public final class GripPreloader extends Preloader { private Stage preloaderStage; - public static void main(String[] args) { - launch(args); - } - @Override public void start(Stage preloaderStage) throws IOException { final StackPane root = FXMLLoader.load(GripPreloader.class.getResource("Preloader.fxml")); diff --git a/ui/preloader/src/main/java/edu/wpi/grip/preloader/Launch.java b/ui/preloader/src/main/java/edu/wpi/grip/preloader/Launch.java new file mode 100644 index 0000000000..e9a15dec42 --- /dev/null +++ b/ui/preloader/src/main/java/edu/wpi/grip/preloader/Launch.java @@ -0,0 +1,21 @@ +package edu.wpi.grip.preloader; + +import javafx.application.Application; + +public final class Launch { + + private Launch() { + } + + /** + * Main entry point for launching GRIP. We use an explicit main method in a separate class to + * allow the JavaFX application to be launched without needing to go through the JVM's + * module reflection (which fails when JavaFX is not on the module path - i.e. ALWAYS). + */ + public static void main(String[] args) { + // JavaFX 11+ uses GTK3 by default, and has problems on some display servers + // This flag forces JavaFX to use GTK2 + System.setProperty("jdk.gtk.version", "2"); + Application.launch(GripPreloader.class, args); + } +} diff --git a/ui/src/main/deploy/package/windows/GRIP.ico b/ui/src/main/deploy/package/windows/GRIP.ico deleted file mode 100644 index 9fb434309dceab458f030d654c7eb033213ff00a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370070 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 also allows us to specify GTK2 on Linux systems, since JavaFX defaults to GTK3 and + * is thus broken on most distros. + */ + public static void main(String[] args) { + // JavaFX 11+ uses GTK3 by default, and has problems on some display servers + // This flag forces JavaFX to use GTK2 + System.setProperty("jdk.gtk.version", "2"); + LauncherImpl.launchApplication(Main.class, GripPreloader.class, args); + } +} diff --git a/ui/src/main/java/edu/wpi/grip/ui/Main.java b/ui/src/main/java/edu/wpi/grip/ui/Main.java index 2975d965cb..9d6ecc0581 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/Main.java +++ b/ui/src/main/java/edu/wpi/grip/ui/Main.java @@ -73,10 +73,6 @@ public class Main extends Application { private final UICommandLineHelper commandLineHelper = new UICommandLineHelper(); private CommandLine parsedArgs; - public static void main(String[] args) { - launch(args); - } - @Override public void init() throws IOException { Loggers.setupLoggers(); @@ -195,7 +191,7 @@ public final void onUnexpectedThrowableEvent(UnexpectedThrowableEvent event) { event.handleSafely((throwable, message, isFatal) -> { // Check this so we can avoid entering the the platform wait // if the program is shutting down. - if (!SafeShutdown.isStopping()) { + if (!SafeShutdown.isStopping()) { // NOPMD // This should still use PlatformImpl PlatformImpl.runAndWait(() -> { // WARNING! Do not post any events from within this! It could result in a deadlock! diff --git a/ui/src/main/java/edu/wpi/grip/ui/MainWindowController.java b/ui/src/main/java/edu/wpi/grip/ui/MainWindowController.java index 00eb1ea063..cdf5bbde6a 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/MainWindowController.java +++ b/ui/src/main/java/edu/wpi/grip/ui/MainWindowController.java @@ -1,7 +1,6 @@ package edu.wpi.grip.ui; import edu.wpi.grip.core.GripFileManager; -import edu.wpi.grip.core.Palette; import edu.wpi.grip.core.Pipeline; import edu.wpi.grip.core.PipelineRunner; import edu.wpi.grip.core.events.AppSettingsChangedEvent; @@ -60,6 +59,7 @@ /** * The Controller for the application window. */ +@SuppressWarnings("PMD.TooManyFields") public class MainWindowController { @FXML @@ -97,8 +97,6 @@ public class MainWindowController { @Inject private StartStoppableButton.Factory startStoppableButtonFactory; @Inject - private Palette palette; - @Inject private Project project; private Stage aboutDialogStage; @@ -144,7 +142,7 @@ private boolean showConfirmationDialogAndWait() { dialog.setHeaderText("Save the current project first?"); dialog.getDialogPane().getButtonTypes().setAll(save, dontSave, cancel); - if (!dialog.showAndWait().isPresent()) { + if (!dialog.showAndWait().isPresent()) { // NOPMD return false; } else if (dialog.getResult().equals(cancel)) { return false; @@ -398,7 +396,7 @@ private void updateElapsedTimeLabel(long elapsed) { elapsedTimeLabel.setText( String.format("Ran in %.1f ms (%.1f fps)", elapsed / 1e3, - elapsed != 0 ? (1e6 / elapsed) : Double.NaN)); + elapsed == 0 ? Double.NaN : (1e6 / elapsed))); } @FXML diff --git a/ui/src/main/java/edu/wpi/grip/ui/analysis/AnalysisController.java b/ui/src/main/java/edu/wpi/grip/ui/analysis/AnalysisController.java index cddfa3f135..64b3e3f529 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/analysis/AnalysisController.java +++ b/ui/src/main/java/edu/wpi/grip/ui/analysis/AnalysisController.java @@ -316,7 +316,7 @@ private static class TimeView extends HBox { getChildren().addAll(progressBar, text); } - void update(double time, double relativeAmount, double hotness) { + public void update(double time, double relativeAmount, double hotness) { text.setText(String.format("%.1fms", time / 1e3)); progressBar.setProgress(relativeAmount); if (hotness > 0) { diff --git a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/CppTMethods.java b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/CppTMethods.java index dfe5e3fc73..fd80ddf562 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/CppTMethods.java +++ b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/CppTMethods.java @@ -8,9 +8,6 @@ import org.apache.commons.lang3.text.WordUtils; public class CppTMethods extends TemplateMethods { - public CppTMethods() { - super(); - } @Override public String name(String name) { diff --git a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/JavaTMethods.java b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/JavaTMethods.java index b6b59198b2..b7b7838bf5 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/JavaTMethods.java +++ b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/JavaTMethods.java @@ -6,9 +6,6 @@ import com.google.common.base.CaseFormat; public class JavaTMethods extends TemplateMethods { - public JavaTMethods() { - super(); - } @Override public String name(String name) { diff --git a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/PythonTMethods.java b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/PythonTMethods.java index e3a67ef856..b064489827 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/PythonTMethods.java +++ b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/PythonTMethods.java @@ -6,9 +6,6 @@ import com.google.common.base.CaseFormat; public class PythonTMethods extends TemplateMethods { - public PythonTMethods() { - super(); - } @Override public String name(String name) { diff --git a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TInput.java b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TInput.java index fe2c9fbb11..74f5e045af 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TInput.java +++ b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TInput.java @@ -32,15 +32,15 @@ public TInput(String type, String name, String value) { * @return returns the value of the output in the form of a string. */ public String value() { - if (value != null) { - return value; - } else { + if (value == null) { return connectedOutput.name(); + } else { + return value; } } @Override - String baseTypeHelper(String type) { + protected String baseTypeHelper(String type) { if ("Integer".equals(type)) { return "int"; } diff --git a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TPipeline.java b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TPipeline.java index c504e3b539..959d198d98 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TPipeline.java +++ b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TPipeline.java @@ -118,19 +118,17 @@ private void set(List pipeSteps) { .append('_') .append(TemplateMethods.parseSocketName(input)); String name = nameBuilder.toString(); - if (!input.getConnections().isEmpty()) { - if (connections.containsKey(input)) { - tInput = new TInput(type, name, connections.get(input)); - } else { - tInput = null; - for (Object con : input.getConnections()) { - // Connections is a set. Should only have one element - tInput = createInput(type, name, - "Connection" + ((Connection) con).getOutputSocket().toString()); - } - } - } else { + if (input.getConnections().isEmpty()) { tInput = createInput(type, name, TemplateMethods.parseSocketValue(input)); + } else if (connections.containsKey(input)) { + tInput = new TInput(type, name, connections.get(input)); + } else { + tInput = null; + for (Object con : input.getConnections()) { + // Connections is a set. Should only have one element + tInput = createInput(type, name, + "Connection" + ((Connection) con).getOutputSocket().toString()); + } } tStep.addInput(tInput); } diff --git a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TSocket.java b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TSocket.java index 890e03dd83..4284c922e3 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TSocket.java +++ b/ui/src/main/java/edu/wpi/grip/ui/codegeneration/data/TSocket.java @@ -46,10 +46,10 @@ public String name() { * @return The type of the socket. */ public String baseType() { - if (!mutable()) { - return type; - } else { + if (mutable()) { return baseTypeHelper(type); + } else { + return type; } } @@ -58,7 +58,7 @@ public String baseType() { * @param type the original type * @return the baseType */ - String baseTypeHelper(String type) { + protected String baseTypeHelper(String type) { return type; } diff --git a/ui/src/main/java/edu/wpi/grip/ui/components/LogTextArea.java b/ui/src/main/java/edu/wpi/grip/ui/components/LogTextArea.java index b4b7ba466e..958b678150 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/components/LogTextArea.java +++ b/ui/src/main/java/edu/wpi/grip/ui/components/LogTextArea.java @@ -34,7 +34,7 @@ public void addLineToLog(String data) { if (fullLog.length() + data.length() >= MAX_STRING_LENGTH && !full) { full = true; fullLog.append("[ERROR] Too much output to display. Discarding the rest."); - } else if (!full) { + } else if (!full) { // NOPMD fullLog.append(data).append('\n'); } else { return; diff --git a/ui/src/main/java/edu/wpi/grip/ui/components/PreviousNextButtons.java b/ui/src/main/java/edu/wpi/grip/ui/components/PreviousNextButtons.java index d1cd86fbca..e86eb5b7bd 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/components/PreviousNextButtons.java +++ b/ui/src/main/java/edu/wpi/grip/ui/components/PreviousNextButtons.java @@ -3,6 +3,8 @@ import edu.wpi.grip.core.PreviousNext; import edu.wpi.grip.ui.util.DPIUtility; +import com.google.common.annotations.VisibleForTesting; + import org.controlsfx.control.SegmentedButton; import java.util.function.Consumer; @@ -74,11 +76,13 @@ private NonTogglingToggleButton(Node graphic, String message, Consumer { setDisable(true); event.consume(); - if (!isSelected()) { - this.service.startAsync(); - } else { + if (isSelected()) { this.service.stopAsync(); + } else { + this.service.startAsync(); } }); diff --git a/ui/src/main/java/edu/wpi/grip/ui/pipeline/AddSourceButton.java b/ui/src/main/java/edu/wpi/grip/ui/pipeline/AddSourceButton.java index b3f0e4a573..9f6321638a 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/pipeline/AddSourceButton.java +++ b/ui/src/main/java/edu/wpi/grip/ui/pipeline/AddSourceButton.java @@ -72,6 +72,7 @@ public class AddSourceButton extends MenuButton { private Optional activeDialog = Optional.empty(); @Inject + @SuppressWarnings("PMD.ExcessiveMethodLength") AddSourceButton(EventBus eventBus, MultiImageFileSource.Factory multiImageSourceFactory, ImageFileSource.Factory imageSourceFactory, diff --git a/ui/src/main/java/edu/wpi/grip/ui/pipeline/OutputSocketController.java b/ui/src/main/java/edu/wpi/grip/ui/pipeline/OutputSocketController.java index 56f3315fd6..c1531be6b0 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/pipeline/OutputSocketController.java +++ b/ui/src/main/java/edu/wpi/grip/ui/pipeline/OutputSocketController.java @@ -93,19 +93,19 @@ public SocketHandleView getHandle() { @Subscribe public void onSocketChanged(SocketChangedEvent event) { if (event.isRegarding(this.socket)) { - if (!this.socket.getValue().isPresent()) { + if (!this.socket.getValue().isPresent()) { // NOPMD // No value handlePreview(false); - } else if (!(this.socket.getValue().get() instanceof MatWrapper)) { - // There is a non-image value, which can always be previewed - handlePreview(true); - } else { + } else if (this.socket.getValue().get() instanceof MatWrapper) { // Only allow the image to be previewed if it's previewable boolean previewable = this.socket.getValue() .map(MatWrapper.class::cast) .map(ImageBasedPreviewView::isPreviewable) .get(); handlePreview(previewable); + } else { + // There is a non-image value, which can always be previewed + handlePreview(true); } } } @@ -134,6 +134,7 @@ public void onSocketPreviewChangedEvent(SocketPreviewChangedEvent event) { * Disable user input while benchmarking. */ @Subscribe + @SuppressWarnings("PMD.UnusedPrivateMethod") private void onBenchmarkEvent(BenchmarkEvent e) { Platform.runLater(() -> handle.setDisable(e.isStart())); } diff --git a/ui/src/main/java/edu/wpi/grip/ui/pipeline/PipelineController.java b/ui/src/main/java/edu/wpi/grip/ui/pipeline/PipelineController.java index d2bdd99d2e..6611f55f18 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/pipeline/PipelineController.java +++ b/ui/src/main/java/edu/wpi/grip/ui/pipeline/PipelineController.java @@ -413,10 +413,10 @@ public void onConnectionRemoved(ConnectionRemovedEvent event) { * Simple class for returning two steps. */ private static final class StepPair { - final Step lower; - final Step higher; + public final Step lower; + public final Step higher; - StepPair(@Nullable Step lower, @Nullable Step higher) { + public StepPair(@Nullable Step lower, @Nullable Step higher) { this.lower = lower; this.higher = higher; } diff --git a/ui/src/main/java/edu/wpi/grip/ui/pipeline/SocketHandleView.java b/ui/src/main/java/edu/wpi/grip/ui/pipeline/SocketHandleView.java index 08646d7c4a..8e9e3948bf 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/pipeline/SocketHandleView.java +++ b/ui/src/main/java/edu/wpi/grip/ui/pipeline/SocketHandleView.java @@ -46,6 +46,7 @@ public class SocketHandleView extends Button { false); @Inject + @SuppressWarnings("PMD.ExcessiveMethodLength") SocketHandleView(EventBus eventBus, Pipeline pipeline, Connection.Factory connectionFactory, diff --git a/ui/src/main/java/edu/wpi/grip/ui/pipeline/StepController.java b/ui/src/main/java/edu/wpi/grip/ui/pipeline/StepController.java index 91404538be..13c0bd6978 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/pipeline/StepController.java +++ b/ui/src/main/java/edu/wpi/grip/ui/pipeline/StepController.java @@ -51,6 +51,7 @@ * A JavaFX control that shows a step in the pipeline. This control shows the name of the operation * as well as a list of input sockets and output sockets. */ +@SuppressWarnings("PMD.TooManyFields") @ParametrizedController(url = "Step.fxml") public class StepController implements Controller { @@ -218,6 +219,7 @@ private void finished(TimerEvent event) { } @Subscribe + @SuppressWarnings("PMD.UnusedPrivateMethod") private void onBenchmark(BenchmarkEvent e) { Platform.runLater(() -> { deleteButton.setDisable(e.isStart()); diff --git a/ui/src/main/java/edu/wpi/grip/ui/pipeline/input/InputSocketController.java b/ui/src/main/java/edu/wpi/grip/ui/pipeline/input/InputSocketController.java index 9354ea543d..febc0feb62 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/pipeline/input/InputSocketController.java +++ b/ui/src/main/java/edu/wpi/grip/ui/pipeline/input/InputSocketController.java @@ -110,6 +110,7 @@ private ObjectProperty contentProperty() { * Disable user input while benchmarking. */ @Subscribe + @SuppressWarnings("PMD.UnusedPrivateMethod") private void onBenchmarkEvent(BenchmarkEvent e) { Platform.runLater(() -> { handle.setDisable(e.isStart()); diff --git a/ui/src/main/java/edu/wpi/grip/ui/pipeline/input/ListSpinnerInputSocketController.java b/ui/src/main/java/edu/wpi/grip/ui/pipeline/input/ListSpinnerInputSocketController.java index c2efb8332f..ae96ed8c6a 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/pipeline/input/ListSpinnerInputSocketController.java +++ b/ui/src/main/java/edu/wpi/grip/ui/pipeline/input/ListSpinnerInputSocketController.java @@ -5,7 +5,6 @@ import edu.wpi.grip.ui.pipeline.SocketHandleView; import edu.wpi.grip.ui.util.GripPlatform; -import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; @@ -35,8 +34,9 @@ public class ListSpinnerInputSocketController extends InputSocketController socket) { + ListSpinnerInputSocketController(SocketHandleView.Factory socketHandleViewFactory, + GripPlatform platform, + @Assisted InputSocket socket) { super(socketHandleViewFactory, socket); this.platform = platform; diff --git a/ui/src/main/java/edu/wpi/grip/ui/preview/PreviewsController.java b/ui/src/main/java/edu/wpi/grip/ui/preview/PreviewsController.java index db11035818..c3fbaf3794 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/preview/PreviewsController.java +++ b/ui/src/main/java/edu/wpi/grip/ui/preview/PreviewsController.java @@ -48,7 +48,7 @@ public class PreviewsController { private static final int PREVIEW_PADDING = 50; @FXML - void initialize() { + private void initialize() { scrollPane.heightProperty().addListener((obs, o, n) -> resizePreviews(n.intValue())); } diff --git a/ui/src/main/java/edu/wpi/grip/ui/util/GripPlatform.java b/ui/src/main/java/edu/wpi/grip/ui/util/GripPlatform.java index a855a39b74..89fdb6ecc6 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/util/GripPlatform.java +++ b/ui/src/main/java/edu/wpi/grip/ui/util/GripPlatform.java @@ -60,10 +60,10 @@ public void runAsSoonAsPossible(Runnable action) { public void onJavaFXRunnerEvent(JavaFXRunnerEvent event) throws InterruptedException { assert !Platform.isFxApplicationThread() : "This should never be run on the application " + "thread. This can cause a deadlock!"; - final Thread callingThread = Thread.currentThread(); if (Thread.interrupted()) { throw new InterruptedException("Interrupted in onJavaFXRunnerEvent"); } + final Thread callingThread = Thread.currentThread(); // queue on JavaFX thread and wait for completion final CountDownLatch doneLatch = new CountDownLatch(1); diff --git a/ui/src/main/java/edu/wpi/grip/ui/util/ImageConverter.java b/ui/src/main/java/edu/wpi/grip/ui/util/ImageConverter.java index c5e19d7f36..41143398f2 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/util/ImageConverter.java +++ b/ui/src/main/java/edu/wpi/grip/ui/util/ImageConverter.java @@ -141,7 +141,7 @@ public Image convert(Mat mat, int desiredHeight) { * * @return A JavaFX image, or null for empty */ - Image convert(Mat mat) { + public Image convert(Mat mat) { return convert(mat, mat.rows()); } diff --git a/ui/src/main/java/edu/wpi/grip/ui/util/SearchUtility.java b/ui/src/main/java/edu/wpi/grip/ui/util/SearchUtility.java index 5347e93986..71601d3c22 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/util/SearchUtility.java +++ b/ui/src/main/java/edu/wpi/grip/ui/util/SearchUtility.java @@ -7,7 +7,11 @@ /** * Utility for fuzzy text searching. */ -public class SearchUtility { +public final class SearchUtility { + + private SearchUtility() { + throw new UnsupportedOperationException("This is a utility class!"); + } /** * Returns true if query if approximately a substring of text, not taking into account diff --git a/ui/src/test/java/edu/wpi/grip/ui/MainWindowTest.java b/ui/src/test/java/edu/wpi/grip/ui/MainWindowTest.java index f666107040..17430227d0 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/MainWindowTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/MainWindowTest.java @@ -21,6 +21,7 @@ import org.junit.After; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import org.testfx.matcher.base.NodeMatchers; import org.testfx.util.WaitForAsyncUtils; @@ -34,6 +35,7 @@ import static org.testfx.api.FxAssert.verifyThat; @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") +@Category(UiTests.class) public class MainWindowTest extends ApplicationTest { private static final String STEP_NOT_ADDED_MSG = "Step was not added to pipeline"; private final GripCoreTestModule testModule = new GripCoreTestModule(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/PaletteTest.java b/ui/src/test/java/edu/wpi/grip/ui/PaletteTest.java index 0d16758a77..07fb8aef0d 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/PaletteTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/PaletteTest.java @@ -20,6 +20,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import org.testfx.util.WaitForAsyncUtils; @@ -33,6 +34,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +@Category(UiTests.class) public class PaletteTest extends ApplicationTest { private final GripCoreTestModule testModule = new GripCoreTestModule(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/UiTests.java b/ui/src/test/java/edu/wpi/grip/ui/UiTests.java new file mode 100644 index 0000000000..1ef7dadffb --- /dev/null +++ b/ui/src/test/java/edu/wpi/grip/ui/UiTests.java @@ -0,0 +1,4 @@ +package edu.wpi.grip.ui; + +public interface UiTests { +} diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/AbstractGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/AbstractGenerationTesting.java index f5378331a5..e9cbc925d3 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/AbstractGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/AbstractGenerationTesting.java @@ -42,7 +42,7 @@ import static org.junit.Assert.fail; @Category(GenerationTesting.class) -@SuppressWarnings("PMD.JUnit4TestShouldUseTestAnnotation") +@SuppressWarnings({"PMD.JUnit4TestShouldUseTestAnnotation", "PMD.AvoidUsingNativeCode"}) public class AbstractGenerationTesting { private static final Logger logger = Logger.getLogger(AbstractGenerationTesting.class.getName()); private GripCoreTestModule testModule; diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/BlurGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/BlurGenerationTesting.java index 80b231a3c6..49176abe70 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/BlurGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/BlurGenerationTesting.java @@ -23,10 +23,11 @@ import static org.junit.Assert.assertTrue; @Category(GenerationTesting.class) +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class BlurGenerationTesting extends AbstractGenerationTesting { private final Double blurRatio = new Double(10.0); - void generatePipeline(String blurType) { + private void generatePipeline(String blurType) { Step step = gen.addStep( new OperationMetaData(OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); @@ -77,7 +78,7 @@ public void bilateralFilterTest() { }, (pip) -> pipelineTest(pip), "BilateralFilterTest"); } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(0).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ConvexHullsGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ConvexHullsGenerationTesting.java index 38797b37f0..ad7115fdc0 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ConvexHullsGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ConvexHullsGenerationTesting.java @@ -30,6 +30,7 @@ import static org.junit.Assert.assertTrue; @Category(GenerationTesting.class) +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class ConvexHullsGenerationTesting extends AbstractGenerationTesting { private static final boolean externalBool = false; private final List hVal = new ArrayList(); @@ -45,7 +46,7 @@ public ConvexHullsGenerationTesting() { lVal.add(new Double(101.0)); } - void generatePipeline() { + private void generatePipeline() { Step step0 = gen.addStep(new OperationMetaData( OperationDescription.from(HSLThresholdOperation.class), () -> new HSLThresholdOperation(isf, osf))); @@ -95,7 +96,7 @@ public void convexHullsTest() { }, (pip) -> pipelineTest(pip), "ConvexHullsTest"); } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(2).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/DesaturateGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/DesaturateGenerationTesting.java index 08a7e2f106..a31e7bb7b1 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/DesaturateGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/DesaturateGenerationTesting.java @@ -20,9 +20,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class DesaturateGenerationTesting extends AbstractGenerationTesting { - void generatePipeline() { + private void generatePipeline() { Step desat = gen.addStep(new OperationMetaData( OperationDescription.from(DesaturateOperation.class), () -> new DesaturateOperation(isf, osf))); @@ -43,7 +44,7 @@ public void desaturationTest() { }, (pip) -> pipelineTest(pip), "DesatTest"); } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { new ManualPipelineRunner(eventBus, pipeline).runPipeline(); Optional out = pipeline.getSteps().get(0).getOutputSockets().get(0).getValue(); assertTrue("Output is not present", out.isPresent()); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/DistanceTransformGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/DistanceTransformGenerationTesting.java index 57ebb55167..574992d0cc 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/DistanceTransformGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/DistanceTransformGenerationTesting.java @@ -24,10 +24,11 @@ import static org.junit.Assert.assertTrue; @Category(GenerationTesting.class) +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class DistanceTransformGenerationTesting extends AbstractGenerationTesting { - String distType; - String maskSize; - static String[][] params = new String[9][2]; + private String distType; + private String maskSize; + private static String[][] params = new String[9][2]; static { String[] type = {"CV_DIST_L1", "CV_DIST_L2", "CV_DIST_C"}; @@ -70,7 +71,7 @@ public void distanceTransformTest(int num) { ("DistTrans" + distType + maskSize + "Test").replace(" ", "").replace("_", "")); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { new ManualPipelineRunner(eventBus, pipeline).runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); assertTrue("Pipeline did not process", out.isPresent()); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FilterContoursGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FilterContoursGenerationTesting.java index 6e7f6610b2..1600e643ad 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FilterContoursGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FilterContoursGenerationTesting.java @@ -32,6 +32,7 @@ import static org.junit.Assert.assertTrue; @Category(GenerationTesting.class) +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class FilterContoursGenerationTesting extends AbstractGenerationTesting { private static final boolean externalBool = false; private final List hVal = new ArrayList(); @@ -47,7 +48,7 @@ public FilterContoursGenerationTesting() { lVal.add(new Double(101.0)); } - void generatePipeline(String socketName, Object value) { + private void generatePipeline(String socketName, Object value) { Step step0 = gen.addStep(new OperationMetaData( OperationDescription.from(HSLThresholdOperation.class), () -> new HSLThresholdOperation(isf, osf))); @@ -140,7 +141,7 @@ public void filterContoursMaxRatioTest() { }, (pip) -> pipelineTest(pip), "FilterContoursMaxRatioTest"); } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(2).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FilterLinesGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FilterLinesGenerationTesting.java index 8833838a06..be4bc91c7f 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FilterLinesGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FilterLinesGenerationTesting.java @@ -30,6 +30,7 @@ import static org.junit.Assume.assumeFalse; @Category(GenerationTesting.class) +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class FilterLinesGenerationTesting extends AbstractGenerationTesting { private final List angleVal = Arrays.asList(160.0, 200.0); private static final int minLength = 30; @@ -53,7 +54,7 @@ public void ignoreIfWindows() { System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("windows")); } - void generatePipeline() { + private void generatePipeline() { Step step0 = gen.addStep(new OperationMetaData( OperationDescription.from(HSLThresholdOperation.class), () -> new HSLThresholdOperation(isf, osf))); @@ -107,7 +108,7 @@ public void filterLinesTest() { } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out2 = pipeline.getSteps().get(2).getOutputSockets().get(0).getValue(); @@ -121,9 +122,9 @@ void pipelineTest(PipelineInterfacer pip) { List genLin = (List) pip.getOutput("Filter_Lines_Output", GenType.LINES); assertTrue("Number of lines is not the same. grip: " + linOut.getLines().size() + " gen: " + genLin.size(), (linOut.getLines().size() - genLin.size()) < 5); - for (int i = 0; i < genLin.size(); i++) { - assertTrue("griplin does not contain: " + genLin.get(i), - TestLine.containsLin(genLin.get(i), gripLin)); + for (TestLine testLine : genLin) { + assertTrue("griplin does not contain: " + testLine, + TestLine.containsLin(testLine, gripLin)); } } diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindBlobsGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindBlobsGenerationTesting.java index 3779a0a0dc..92bb1b22cc 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindBlobsGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindBlobsGenerationTesting.java @@ -26,6 +26,7 @@ import static org.junit.Assert.assertTrue; @Category(GenerationTesting.class) +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class FindBlobsGenerationTesting extends AbstractGenerationTesting { private final List hVal = new ArrayList(); private final List sVal = new ArrayList(); @@ -40,7 +41,7 @@ public FindBlobsGenerationTesting() { lVal.add(new Double(101.0)); } - void generatePipeline(boolean darkBool, double minArea, List circularity) { + private void generatePipeline(boolean darkBool, double minArea, List circularity) { Step step0 = gen.addStep(new OperationMetaData( OperationDescription.from(HSLThresholdOperation.class), () -> new HSLThresholdOperation(isf, osf))); @@ -101,7 +102,7 @@ public void findSomeBlobsTest() { } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out1 = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); @@ -118,10 +119,10 @@ void pipelineTest(PipelineInterfacer pip) { } } - public boolean containsBlob(List blobs, KeyPoint blob) { - for (int i = 0; i < blobs.size(); i++) { - if ((blobs.get(i).x - blob.pt.x) <= 20 && (blobs.get(i).y - blob.pt.y) <= 20 - && (blobs.get(i).size - blob.size) <= 10) { + private boolean containsBlob(List blobs, KeyPoint blob) { + for (BlobsReport.Blob blob1 : blobs) { + if ((blob1.x - blob.pt.x) <= 20 && (blob1.y - blob.pt.y) <= 20 + && (blob1.size - blob.size) <= 10) { return true; } } diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindContoursGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindContoursGenerationTesting.java index 6a0447107e..4b6d40dbd2 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindContoursGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindContoursGenerationTesting.java @@ -31,6 +31,7 @@ import static org.junit.Assert.assertTrue; @Category(GenerationTesting.class) +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class FindContoursGenerationTesting extends AbstractGenerationTesting { private final List hVal = new ArrayList(); private final List sVal = new ArrayList(); @@ -45,7 +46,7 @@ public FindContoursGenerationTesting() { lVal.add(new Double(101.0)); } - void generatePipeline(boolean externalBool) { + private void generatePipeline(boolean externalBool) { Step step0 = gen.addStep(new OperationMetaData( OperationDescription.from(HSLThresholdOperation.class), () -> new HSLThresholdOperation(isf, osf))); @@ -94,7 +95,7 @@ public void findContoursExternalTest() { } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out1 = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindLinesGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindLinesGenerationTesting.java index 15181339bd..51c8acbcb8 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindLinesGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/FindLinesGenerationTesting.java @@ -23,14 +23,13 @@ import java.util.List; import java.util.Locale; import java.util.Optional; -import java.util.logging.Logger; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeFalse; @Category(GenerationTesting.class) +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class FindLinesGenerationTesting extends AbstractGenerationTesting { - private static final Logger logger = Logger.getLogger(FindLinesGenerationTesting.class.getName()); private final List hVal = new ArrayList(); private final List sVal = new ArrayList(); @@ -51,7 +50,7 @@ public void ignoreIfWindows() { System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("windows")); } - void generatePipeline() { + private void generatePipeline() { Step step0 = gen.addStep(new OperationMetaData( OperationDescription.from(HSLThresholdOperation.class), () -> new HSLThresholdOperation(isf, osf))); @@ -90,7 +89,7 @@ public void findLinesTest() { } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out1 = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); @@ -103,9 +102,9 @@ void pipelineTest(PipelineInterfacer pip) { assertTrue( "Number of lines is not the same. grip: " + gripLin.size() + " gen: " + genLin.size(), (linOut.getLines().size() - genLin.size()) < 5); - for (int idx = 0; idx < genLin.size(); idx++) { - assertTrue("griplin does not contain: " + genLin.get(idx), - TestLine.containsLin(genLin.get(idx), gripLin)); + for (TestLine testLine : genLin) { + assertTrue("griplin does not contain: " + testLine, + TestLine.containsLin(testLine, gripLin)); } } diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/GripIconHSLSetup.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/GripIconHSLSetup.java index 5ddbc9a7cb..1eb24d17c7 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/GripIconHSLSetup.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/GripIconHSLSetup.java @@ -11,11 +11,14 @@ import java.util.Arrays; import java.util.List; -public class GripIconHSLSetup { +public final class GripIconHSLSetup { private static final List defaultHVal; private static final List defaultSVal; private static final List defaultLVal; + private GripIconHSLSetup() { + } + static { defaultHVal = Arrays.asList(0.0d, 49.0d); defaultSVal = Arrays.asList(0.0d, 41.0d); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSLThresholdGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSLThresholdGenerationTesting.java index c04b639513..7bfa3e8404 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSLThresholdGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSLThresholdGenerationTesting.java @@ -16,6 +16,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class HSLThresholdGenerationTesting extends AbstractGenerationTesting { // H 0-49 // S 0-41 diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSVThresholdSetup.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSVThresholdSetup.java index 84c35deeb0..2fbe3013a8 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSVThresholdSetup.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSVThresholdSetup.java @@ -11,8 +11,13 @@ import java.util.Arrays; import java.util.List; -public class HSVThresholdSetup { - static void setup(AbstractGenerationTesting caller) { +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") +public final class HSVThresholdSetup { + + private HSVThresholdSetup() { + } + + public static void setup(AbstractGenerationTesting caller) { List hVal = Arrays.asList(50.0d, 180.0d); List sVal = Arrays.asList(0.0d, 255.0d); List vVal = Arrays.asList(0.0d, 255.0d); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSVThresholdTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSVThresholdTesting.java index 8e5f00ca53..3ad0feb0d0 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSVThresholdTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/HSVThresholdTesting.java @@ -14,9 +14,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class HSVThresholdTesting extends AbstractGenerationTesting { - void set() { + private void set() { HSVThresholdSetup.setup(this); } @@ -28,7 +29,7 @@ public void hsvTest() { }, (pip) -> validate(pip), "HSVThresholdTesting"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { new ManualPipelineRunner(eventBus, pipeline).runPipeline(); Optional out = pipeline.getSteps().get(0).getOutputSockets().get(0).getValue(); assertTrue("Pipeline did not process", out.isPresent()); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/MaskTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/MaskTesting.java index a2fbfdd832..3228642206 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/MaskTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/MaskTesting.java @@ -20,9 +20,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class MaskTesting extends AbstractGenerationTesting { - void set() { + private void set() { HSVThresholdSetup.setup(this); Step mask = gen.addStep( new OperationMetaData(OperationDescription.from(MaskOperation.class), @@ -46,7 +47,7 @@ public void maskTest() { }, (pip) -> validate(pip), "MaskGripIconTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { new ManualPipelineRunner(eventBus, pipeline).runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); assertTrue("Pipeline did not process", out.isPresent()); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NewPointGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NewPointGenerationTesting.java index 2293081f0a..f4793430ae 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NewPointGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NewPointGenerationTesting.java @@ -17,9 +17,10 @@ import static junit.framework.TestCase.assertSame; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class NewPointGenerationTesting extends AbstractGenerationTesting { - void generatePipeline(double x, double y) { + private void generatePipeline(double x, double y) { Step desat = gen.addStep(new OperationMetaData( OperationDescription.from(NewPointOperation.class), () -> new NewPointOperation(isf, osf))); @@ -40,7 +41,7 @@ public void newPointTest() { }, (pip) -> pipelineTest(pip), "newPointTest"); } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { new ManualPipelineRunner(eventBus, pipeline).runPipeline(); Optional out = pipeline.getSteps().get(0).getOutputSockets().get(0).getValue(); assertTrue("Output is not present", out.isPresent()); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NewSizeGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NewSizeGenerationTesting.java index 799f13f811..bdfd156829 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NewSizeGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NewSizeGenerationTesting.java @@ -17,9 +17,10 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class NewSizeGenerationTesting extends AbstractGenerationTesting { - void generatePipeline(double width, double height) { + private void generatePipeline(double width, double height) { Step desat = gen.addStep( new OperationMetaData(OperationDescription.from(NewSizeOperation.class), () -> new NewSizeOperation(isf, osf))); @@ -40,7 +41,7 @@ public void newSizeTest() { }, (pip) -> pipelineTest(pip), "newSizeTest"); } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { new ManualPipelineRunner(eventBus, pipeline).runPipeline(); Optional out = pipeline.getSteps().get(0).getOutputSockets().get(0).getValue(); assertTrue("Output is not present", out.isPresent()); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NormalizeGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NormalizeGenerationTesting.java index c3936b72e3..bfcebc4ffa 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NormalizeGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/NormalizeGenerationTesting.java @@ -22,9 +22,10 @@ import static org.junit.Assert.assertTrue; @Category(GenerationTesting.class) +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class NormalizeGenerationTesting extends AbstractGenerationTesting { - void generatePipeline(String type, double minVal, double maxVal) { + private void generatePipeline(String type, double minVal, double maxVal) { Step step = gen.addStep(new OperationMetaData( OperationDescription.from(NormalizeOperation.class), () -> new NormalizeOperation(isf, osf))); @@ -76,7 +77,7 @@ public void normMinMaxTest() { }, (pip) -> pipelineTest(pip), "NORM_MINMAXTest"); } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(0).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/RGBThresholdTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/RGBThresholdTesting.java index 3ec4993a85..dd36655015 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/RGBThresholdTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/RGBThresholdTesting.java @@ -22,10 +22,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -@SuppressWarnings("PMD.JUnitSpelling") +@SuppressWarnings({"PMD.JUnitSpelling", "PMD.JUnitTestsShouldIncludeAssert"}) public class RGBThresholdTesting extends AbstractGenerationTesting { - boolean setup() { + private boolean setup() { final Step rgb = gen.addStep( new OperationMetaData(OperationDescription.from(RGBThresholdOperation.class), () -> new RGBThresholdOperation(isf, osf))); @@ -49,7 +49,7 @@ boolean setup() { return true; } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(0).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ResizeTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ResizeTesting.java index ff79516a90..4744801e79 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ResizeTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ResizeTesting.java @@ -20,9 +20,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class ResizeTesting extends AbstractGenerationTesting { - void setup(String interp) { + private void setup(String interp) { Step resize = gen.addStep( new OperationMetaData(OperationDescription.from(ResizeOperation.class), () -> new ResizeOperation(isf, osf))); @@ -82,7 +83,7 @@ public void areaTest() { }, (pip) -> pipelineTest(pip), "ResizeAreaTest"); } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(0).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/SwitchTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/SwitchTesting.java index 5dcb1189a0..4482dead8d 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/SwitchTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/SwitchTesting.java @@ -17,20 +17,21 @@ import static junit.framework.TestCase.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class SwitchTesting extends AbstractGenerationTesting { private static final int onTrueSourceNum = 0; private static final int onFalseSourceNum = 1; @Inject - ExceptionWitness.Factory ewf; + private ExceptionWitness.Factory ewf; - boolean setupNum(double onTrue, double onFalse, Boolean initVal) { + private boolean setupNum(double onTrue, double onFalse, Boolean initVal) { MockNumberSource srcTrue = new MockNumberSource(ewf, onTrue, osf); MockNumberSource srcFalse = new MockNumberSource(ewf, onFalse, osf); return setup(srcTrue, srcFalse, initVal); } - boolean setup(Source onTrue, Source onFalse, Boolean initVal) { + private boolean setup(Source onTrue, Source onFalse, Boolean initVal) { Step step = gen.addStep( new OperationMetaData(OperationDescription.from(SwitchOperation.class), () -> new SwitchOperation(isf, osf))); @@ -65,7 +66,10 @@ public void testNumberFalseInit() { (pip) -> validateNum(pip, onTrue, onFalse, initVal), "SwitchNumFalseTest"); } - void validateNum(PipelineInterfacer pip, Double switchUp, Double offSwitch, Boolean initVal) { + private void validateNum(PipelineInterfacer pip, + Double switchUp, + Double offSwitch, + Boolean initVal) { pip.setNumSource(onTrueSourceNum, switchUp); pip.setNumSource(onFalseSourceNum, offSwitch); pip.process(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ThresholdMovingTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ThresholdMovingTesting.java index 130d4fc76b..566e091933 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ThresholdMovingTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ThresholdMovingTesting.java @@ -21,8 +21,9 @@ import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class ThresholdMovingTesting extends AbstractGenerationTesting { - ThresholdSwitch[] threshs = null; + private ThresholdSwitch[] threshs = null; /** * Sets up the pipeline with given number of moving thresholds. @@ -98,7 +99,7 @@ public void threeThreshMoving() { }, (pip) -> validate(pip, threshs), "ThreshMovingThreeTest"); } - void validate(PipelineInterfacer pip, ThresholdSwitch[] threshs) { + private void validate(PipelineInterfacer pip, ThresholdSwitch[] threshs) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); @@ -123,14 +124,14 @@ void validate(PipelineInterfacer pip, ThresholdSwitch[] threshs) { assertMatWithin(genMat, gripMat, 5.0); } } else { - Mat genMat = (Mat) pip.getOutput("Threshold_Moving_Output", GenType.IMAGE); + pip.getOutput("Threshold_Moving_Output", GenType.IMAGE); } } - static class ThresholdSwitch { - Step swi; - Step thresh; + private static final class ThresholdSwitch { + public final Step swi; + public final Step thresh; public ThresholdSwitch(Step swi, Step thresh) { this.swi = swi; diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ValveTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ValveTesting.java index 83bf9c3240..d943f7d0d6 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ValveTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/ValveTesting.java @@ -17,12 +17,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class ValveTesting extends AbstractGenerationTesting { @Inject - ExceptionWitness.Factory ewf; + private ExceptionWitness.Factory ewf; - boolean setup(Number value) { + private boolean setup(Number value) { Step valve = gen.addStep( new OperationMetaData(OperationDescription.from(ValveOperation.class), () -> new ValveOperation(isf, osf))); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/WatershedGenerationTesting.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/WatershedGenerationTesting.java index 1bf0fb8829..847ddf2732 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/WatershedGenerationTesting.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/WatershedGenerationTesting.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class WatershedGenerationTesting extends AbstractGenerationTesting { private static final boolean externalBool = false; private final List hVal = new ArrayList(); @@ -39,7 +40,7 @@ public WatershedGenerationTesting() { lVal.add(new Double(101.0)); } - void generatePipeline() { + private void generatePipeline() { Step step0 = gen.addStep(new OperationMetaData( OperationDescription.from(HSLThresholdOperation.class), () -> new HSLThresholdOperation(isf, osf))); @@ -92,7 +93,7 @@ public void watershedTest() { }, (pip) -> pipelineTest(pip), "WatershedTest"); } - void pipelineTest(PipelineInterfacer pip) { + private void pipelineTest(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(2).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAbsDiff.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAbsDiff.java index 0a90de1bb5..825b1b45f0 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAbsDiff.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAbsDiff.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVAbsDiff extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); @@ -50,7 +51,7 @@ public void absDiffTest() { test(() -> set(), (pip) -> validate(pip), "AbsDiffTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAdaptiveThreshold.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAdaptiveThreshold.java index 69711f815b..5e30a495b5 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAdaptiveThreshold.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAdaptiveThreshold.java @@ -23,9 +23,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVAdaptiveThreshold extends AbstractGenerationTesting { - boolean setup(AdaptiveThresholdTypesEnum adaptMethod, + private boolean setup(AdaptiveThresholdTypesEnum adaptMethod, CVOperations.CVAdaptThresholdTypesEnum threshMethod) { Step desat = gen.addStep(new OperationMetaData( OperationDescription.from(DesaturateOperation.class), @@ -76,7 +77,7 @@ public void binaryInvGaussianTest() { (pip) -> validate(pip), "cvBinaryInvGaussianATTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAdd.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAdd.java index ab776dd4ee..90a2cd6ff1 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAdd.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAdd.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVAdd extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -49,7 +50,7 @@ public void cvAddTest() { test(() -> set(), (pip) -> validate(pip), "CvAddTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAddWeighted.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAddWeighted.java index 1abd4780b2..bea4556727 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAddWeighted.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVAddWeighted.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVAddWeighted extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -52,7 +53,7 @@ public void cvAddWeightedTest() { test(() -> set(), (pip) -> validate(pip), "CvAddWeightedTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVApplyColorMap.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVApplyColorMap.java index 336122b6cf..2df7726548 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVApplyColorMap.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVApplyColorMap.java @@ -18,9 +18,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVApplyColorMap extends AbstractGenerationTesting { - boolean set(ColormapTypesEnum map) { + private boolean set(ColormapTypesEnum map) { Step step = gen.addStep(opUtil.getMetaData("CV applyColorMap")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -95,11 +96,11 @@ public void testParula() { helpTest(ColormapTypesEnum.COLORMAP_PARULA, "ParulaTest"); } - void helpTest(ColormapTypesEnum map, String testName) { + private void helpTest(ColormapTypesEnum map, String testName) { test(() -> set(map), (pip) -> validate(pip), "cvColorMap" + testName); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseAnd.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseAnd.java index 1c39cd5789..3f5706b798 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseAnd.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseAnd.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVBitwiseAnd extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -49,7 +50,7 @@ public void cvBitwiseAndTest() { test(() -> set(), (pip) -> validate(pip), "CvBitwiseAndTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseNot.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseNot.java index 2384fd1058..27013e6314 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseNot.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseNot.java @@ -17,9 +17,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVBitwiseNot extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step step = gen.addStep(opUtil.getMetaData("CV bitwiseNot")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -32,7 +33,7 @@ public void notTest() { test(() -> set(), (pip) -> validate(pip), "BitwiseNotTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseOr.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseOr.java index d11905336c..9d6255adce 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseOr.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseOr.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVBitwiseOr extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -49,7 +50,7 @@ public void cvBitwiseOrTest() { test(() -> set(), (pip) -> validate(pip), "CvBitwiseOrTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseXor.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseXor.java index f3c7ca009f..97fac0d751 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseXor.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVBitwiseXor.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVBitwiseXor extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -49,7 +50,7 @@ public void cvBitwiseXorTest() { test(() -> set(), (pip) -> validate(pip), "CvBitwiseXorTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVCanny.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVCanny.java index f0778af5a7..e7211249bc 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVCanny.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVCanny.java @@ -17,6 +17,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVCanny extends AbstractGenerationTesting { private static final double thresh1 = 50; private static final double thresh2 = 60; @@ -24,7 +25,7 @@ public class CVCanny extends AbstractGenerationTesting { private static final boolean grad = true; - boolean set() { + private boolean set() { Step step = gen.addStep(opUtil.getMetaData("CV canny")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -42,7 +43,7 @@ public void cannyTest() { test(() -> set(), (pip) -> validate(pip), "cvcannyTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVCompare.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVCompare.java index 68f8df7ffb..3af03b0e51 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVCompare.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVCompare.java @@ -22,9 +22,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVCompare extends AbstractGenerationTesting { - boolean set(CmpTypesEnum val) { + private boolean set(CmpTypesEnum val) { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -76,7 +77,7 @@ public void cvCompareNeTest() { test(() -> set(CmpTypesEnum.CMP_NE), (pip) -> validate(pip), "CvCmpNeTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVDilate.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVDilate.java index cab248134f..f96de6a1e6 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVDilate.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVDilate.java @@ -17,11 +17,12 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVDilate extends AbstractGenerationTesting { private static final double iterations = 4; - boolean setup(String type) { + private boolean setup(String type) { Step step = gen.addStep(opUtil.getMetaData("CV dilate")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -77,7 +78,7 @@ public void dilateIsoTest() { } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVDivide.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVDivide.java index 82c6e65dda..dfd4adc5e3 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVDivide.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVDivide.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVDivide extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -50,7 +51,7 @@ public void cvDivideTest() { test(() -> set(), (pip) -> validate(pip), "CvDivideTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVErode.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVErode.java index dfa2a8e04c..39c7a4dd9b 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVErode.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVErode.java @@ -17,11 +17,12 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVErode extends AbstractGenerationTesting { private static final double iterations = 4; - boolean setup(String type) { + private boolean setup(String type) { Step step = gen.addStep(opUtil.getMetaData("CV erode")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -77,7 +78,7 @@ public void erodeIsoTest() { } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVExtractChannel.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVExtractChannel.java index a02028029d..6332751e92 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVExtractChannel.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVExtractChannel.java @@ -17,9 +17,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVExtractChannel extends AbstractGenerationTesting { - boolean setup(int channel) { + private boolean setup(int channel) { Step step = gen.addStep(opUtil.getMetaData("CV extractChannel")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -43,7 +44,7 @@ public void extractTwoTest() { test(() -> setup(2), (pip) -> validate(pip), "extractTwoTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVFlip.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVFlip.java index 5d5a687f09..adaba4398f 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVFlip.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVFlip.java @@ -18,9 +18,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVFlip extends AbstractGenerationTesting { - boolean setup(FlipCode flip) { + private boolean setup(FlipCode flip) { Step step = gen.addStep(opUtil.getMetaData("CV flip")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -45,7 +46,7 @@ public void bothAxesTest() { } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVGaussianBlur.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVGaussianBlur.java index 91f3b5543d..8498cb8a6b 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVGaussianBlur.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVGaussianBlur.java @@ -21,13 +21,14 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVGaussianBlur extends AbstractGenerationTesting { private static final double width = 15; private static final double height = 1; private static final double sigmax = 3; private static final double sigmay = 41; - boolean setup(String type) { + private boolean setup(String type) { Step step0 = gen.addStep(new OperationMetaData( OperationDescription.from(NewSizeOperation.class), () -> new NewSizeOperation(isf, osf))); for (InputSocket sock : step0.getInputSockets()) { @@ -86,7 +87,7 @@ public void gaussianIsoTest() { } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVLaplacian.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVLaplacian.java index 91a64f66f0..d38c998d81 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVLaplacian.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVLaplacian.java @@ -17,12 +17,13 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVLaplacian extends AbstractGenerationTesting { private static final double ksize = 5; private static final double scale = 1; private static final double delta = 50; - boolean setup(String type) { + private boolean setup(String type) { Step step = gen.addStep(opUtil.getMetaData("CV laplacian")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -80,7 +81,7 @@ public void laplIsoTest() { } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMax.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMax.java index 7bb4db2d94..98bd34f0e8 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMax.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMax.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVMax extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -49,7 +50,7 @@ public void cvMaxTest() { test(() -> set(), (pip) -> validate(pip), "CvMaxTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMedianBlur.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMedianBlur.java index 028cb3d55e..219ee25c95 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMedianBlur.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMedianBlur.java @@ -17,9 +17,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVMedianBlur extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step step = gen.addStep(opUtil.getMetaData("CV MedianBlur")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -32,7 +33,7 @@ public void medianBlurTest() { test(() -> set(), (pip) -> validate(pip), "medianBlurTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMin.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMin.java index ede9a9487d..428cf923f7 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMin.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMin.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVMin extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -49,7 +50,7 @@ public void cvMinTest() { test(() -> set(), (pip) -> validate(pip), "CvMinTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMultiply.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMultiply.java index 04da96ed5d..4692f1907a 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMultiply.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVMultiply.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVMultiply extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); loadImage(Files.gompeiJpegFile); @@ -50,7 +51,7 @@ public void cvMultiplyTest() { test(() -> set(), (pip) -> validate(pip), "CvMultiplyTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVRectangle.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVRectangle.java index 3a174311df..fb2ff83285 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVRectangle.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVRectangle.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVRectangle extends AbstractGenerationTesting { private static final double x0 = 20; private static final double y0 = 40; @@ -31,7 +32,7 @@ public class CVRectangle extends AbstractGenerationTesting { private static final double shift = 3; - boolean setup(String type) { + private boolean setup(String type) { Step step0 = gen.addStep(new OperationMetaData( OperationDescription.from(NewPointOperation.class), () -> new NewPointOperation(isf, osf))); @@ -89,7 +90,7 @@ public void rectFTest() { } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVResize.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVResize.java index 5e2c18c109..b1c5a40156 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVResize.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVResize.java @@ -17,11 +17,12 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVResize extends AbstractGenerationTesting { private static final double fx = 0.26; private static final double fy = 0.24; - boolean set() { + private boolean set() { Step step = gen.addStep(opUtil.getMetaData("CV resize")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -36,7 +37,7 @@ public void cvResizeTest() { test(() -> set(), (pip) -> validate(pip), "CVResize"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVScaleAdd.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVScaleAdd.java index 082f5c1a72..16b361fede 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVScaleAdd.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVScaleAdd.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVScaleAdd extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); @@ -51,7 +52,7 @@ public void cvScaleAddTest() { test(() -> set(), (pip) -> validate(pip), "CvScaleAddTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVSobel.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVSobel.java index 747baff9f7..427c78f148 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVSobel.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVSobel.java @@ -17,6 +17,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVSobel extends AbstractGenerationTesting { private static final double dx = 1; private static final double dy = 1; @@ -24,7 +25,7 @@ public class CVSobel extends AbstractGenerationTesting { private static final double scale = 10; private static final double delta = 100; - boolean setup(String type) { + private boolean setup(String type) { Step step = gen.addStep(opUtil.getMetaData("CV sobel")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -84,7 +85,7 @@ public void sobelIsoTest() { } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVSubtract.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVSubtract.java index a521dc1ab9..70db83842c 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVSubtract.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVSubtract.java @@ -21,9 +21,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVSubtract extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step blur = gen.addStep(new OperationMetaData( OperationDescription.from(BlurOperation.class), () -> new BlurOperation(isf, osf))); @@ -50,7 +51,7 @@ public void cvSubtractTest() { test(() -> set(), (pip) -> validate(pip), "CvSubtractTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); Optional out = pipeline.getSteps().get(1).getOutputSockets().get(0).getValue(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVThreshold.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVThreshold.java index 702d68e340..2d50695587 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVThreshold.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVThreshold.java @@ -21,11 +21,12 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVThreshold extends AbstractGenerationTesting { private static final double thresh = 50; private static final double maxval = 200; - boolean setup(String type) { + private boolean setup(String type) { Step desat = gen.addStep(new OperationMetaData( OperationDescription.from(DesaturateOperation.class), () -> new DesaturateOperation(isf, osf))); @@ -81,7 +82,7 @@ public void thresholdTriTest() { test(() -> setup("THRESH_TRIANGLE"), (pip) -> validate(pip), "cvThresholdTriangleTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVTranspose.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVTranspose.java index 132fa0eaec..537b88afab 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVTranspose.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVTranspose.java @@ -17,9 +17,10 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVTranspose extends AbstractGenerationTesting { - boolean set() { + private boolean set() { Step step = gen.addStep(opUtil.getMetaData("CV Transpose")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -32,7 +33,7 @@ public void transposeTest() { test(() -> set(), (pip) -> validate(pip), "TransposeTest"); } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVcvtColor.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVcvtColor.java index 3d389efa82..94f33930ca 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVcvtColor.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/cv/CVcvtColor.java @@ -17,10 +17,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public class CVcvtColor extends AbstractGenerationTesting { - boolean setup(String code) { + private boolean setup(String code) { Step step = gen.addStep(opUtil.getMetaData("CV cvtColor")); loadImage(Files.gompeiJpegFile); OutputSocket imgOut = pipeline.getSources().get(0).getOutputSockets().get(0); @@ -40,7 +41,7 @@ public void cvtColor1Test() { } - void validate(PipelineInterfacer pip) { + private void validate(PipelineInterfacer pip) { ManualPipelineRunner runner = new ManualPipelineRunner(eventBus, pipeline); runner.runPipeline(); pip.setMatSource(0, Files.gompeiJpegFile.file); diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/CppPipelineInterfacer.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/CppPipelineInterfacer.java index 1337a5b9a6..2f53741442 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/CppPipelineInterfacer.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/CppPipelineInterfacer.java @@ -19,7 +19,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -@SuppressWarnings("PMD.UseLocaleWithCaseConversions") +@SuppressWarnings({"PMD.UseLocaleWithCaseConversions", "PMD.AvoidUsingNativeCode"}) public class CppPipelineInterfacer implements PipelineInterfacer { private static File codeDir; private final CppTMethods tMeth; @@ -36,7 +36,6 @@ public class CppPipelineInterfacer implements PipelineInterfacer { public CppPipelineInterfacer(String libName) { tMeth = new CppTMethods(); try { - String libBase = codeDir.getAbsolutePath() + File.separator + libName; if (System.getProperty("os.name").toLowerCase().contains("windows")) { Process cmake = new ProcessBuilder("cmake", "CMakeLists.txt", "-DNAME=" + libName, "-G", "Visual Studio 14 2015 Win64").directory(codeDir).start(); @@ -174,6 +173,7 @@ public void setNumSource(int num, Number val) { @Override public native void process(); + @SuppressWarnings("PMD.LinguisticNaming") private native void getMatNative(String name, long addr); private native double getDouble(String name); @@ -184,12 +184,14 @@ public void setNumSource(int num, Number val) { private native void init(String libName); - private native void dispose(); + private native void dispose(); // NOPMD private native double[] getSizeOrPoint(String name, boolean size); + @SuppressWarnings("PMD.LinguisticNaming") private native void getBlobs(String name, long retAddr); + @SuppressWarnings("PMD.LinguisticNaming") private native int getNumContours(String name); private native double[][] getLines(String name); @@ -201,6 +203,7 @@ public void setNumSource(int num, Number val) { * @param addrs an array of nativeAddresses of MatOfPoint objects. Note the size of addrs should * be the number returned from getNumContours. */ + @SuppressWarnings("PMD.LinguisticNaming") private native void getContours(String name, long[] addrs); private long nativeHandle; //NOPMD diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/HelperTools.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/HelperTools.java index aa9a918fcc..3a48d028e4 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/HelperTools.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/HelperTools.java @@ -24,9 +24,12 @@ import static org.junit.Assert.assertTrue; import static org.opencv.core.CvType.CV_8UC; -public class HelperTools { +public final class HelperTools { private static final Logger logger = Logger.getLogger(HelperTools.class.getName()); + private HelperTools() { + } + /** * Calculates the average per pixel difference between two Mats. If two Mats are perfectly equal * this will be 0. Less than 10 is a good value for similar images. diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/PipelineCreator.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/PipelineCreator.java index 59905922d9..f08bb05e80 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/PipelineCreator.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/PipelineCreator.java @@ -15,9 +15,13 @@ import static org.junit.Assert.fail; -public class PipelineCreator { +@SuppressWarnings("PMD.AvoidUsingNativeCode") +public final class PipelineCreator { private static final Logger logger = Logger.getLogger(PipelineCreator.class.getName()); + private PipelineCreator() { + } + static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/PythonPipelineInterfacer.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/PythonPipelineInterfacer.java index 44b85640cc..5d19c62786 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/PythonPipelineInterfacer.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/PythonPipelineInterfacer.java @@ -20,6 +20,7 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -34,10 +35,10 @@ public class PythonPipelineInterfacer implements PipelineInterfacer { private final StringBuilder str; //NOPMD private BufferedWriter out; - static File codeDir = null; + private static File codeDir = null; private final PythonTMethods tMeth; - static String pythonCmd; - static final String newLine = System.lineSeparator(); + private static String pythonCmd; + private static final String newLine = System.lineSeparator(); private static final String outputFile = "output.txt"; private static final Logger logger = Logger.getLogger(PythonPipelineInterfacer.class.getName()); @@ -68,7 +69,8 @@ public PythonPipelineInterfacer(String className) { .append("pipe = ").append(className).append('.') .append(className).append("()").append(newLine); try { - out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("testing.py"), "UTF-8")); + out = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream("testing.py"), StandardCharsets.UTF_8)); } catch (IOException e) { fail("Could not write the testing python file"); logger.log(Level.WARNING, e.getMessage(), e); @@ -252,10 +254,10 @@ private Object getOutputNum(String name) throws IOException { temp.append("print (pipe.").append(name).append(')').append(newLine); BufferedReader in = runProcess(temp.toString()); final String input = in.readLine(); - if (input != null && !input.equals("None")) { - return Double.parseDouble(input); - } else { + if (input == null || input.equals("None")) { return null; + } else { + return Double.parseDouble(input); } } diff --git a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/TestLine.java b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/TestLine.java index 8bb4bac145..6ea14adb68 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/TestLine.java +++ b/ui/src/test/java/edu/wpi/grip/ui/codegeneration/tools/TestLine.java @@ -17,6 +17,7 @@ public abstract class TestLine { public abstract Point getPoint2(); + @Override public String toString() { StringBuilder bld = new StringBuilder(24); bld.append("P1: ").append(pointToStr(getPoint1())).append(" P2: ") @@ -30,27 +31,15 @@ protected final String pointToStr(Point p) { } public static boolean containsLin(TestLine line, List lines) { - for (int i = 0; i < lines.size(); i++) { - if ((lines.get(i).getPoint1().x - line.getPoint1().x) <= 2 - && (lines.get(i).getPoint1().y - line.getPoint1().y) <= 2 - && (lines.get(i).getPoint2().x - line.getPoint2().x) <= 2 - && (lines.get(i).getPoint2().y - line.getPoint2().y) <= 2) { + for (TestLine line1 : lines) { + if ((line1.getPoint1().x - line.getPoint1().x) <= 2 + && (line1.getPoint1().y - line.getPoint1().y) <= 2 + && (line1.getPoint2().x - line.getPoint2().x) <= 2 + && (line1.getPoint2().y - line.getPoint2().y) <= 2) { return true; } } return false; } - private static String errorMessage(TestLine grip, TestLine gen) { - StringBuilder bld = new StringBuilder(22); - bld.append("Grip was:").append(grip.toString()) - .append("\nGen was:").append(gen.toString()).append('\n'); - return bld.toString(); - } - - private static double angleDif(double alpha, double beta) { - double diff = Math.abs(alpha - beta) % 360.0; - diff = diff > 180 ? 360.0 - diff : diff; - return diff; - } } diff --git a/ui/src/test/java/edu/wpi/grip/ui/components/ExceptionWitnessResponderButtonTest.java b/ui/src/test/java/edu/wpi/grip/ui/components/ExceptionWitnessResponderButtonTest.java index 2755857ad3..956fd831d0 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/components/ExceptionWitnessResponderButtonTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/components/ExceptionWitnessResponderButtonTest.java @@ -2,11 +2,13 @@ import edu.wpi.grip.core.util.ExceptionWitness; import edu.wpi.grip.core.util.MockExceptionWitness; +import edu.wpi.grip.ui.UiTests; import com.google.common.eventbus.EventBus; import org.junit.Ignore; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import org.testfx.matcher.base.NodeMatchers; import org.testfx.util.WaitForAsyncUtils; @@ -20,6 +22,7 @@ import static org.testfx.api.FxAssert.verifyThat; @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") +@Category(UiTests.class) public class ExceptionWitnessResponderButtonTest extends ApplicationTest { private ExceptionWitness witness; diff --git a/ui/src/test/java/edu/wpi/grip/ui/components/LogTextAreaTest.java b/ui/src/test/java/edu/wpi/grip/ui/components/LogTextAreaTest.java index ab2d2e0d27..6e8983ac49 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/components/LogTextAreaTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/components/LogTextAreaTest.java @@ -1,8 +1,11 @@ package edu.wpi.grip.ui.components; +import edu.wpi.grip.ui.UiTests; + import org.apache.commons.lang3.StringUtils; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import javafx.scene.Scene; @@ -11,6 +14,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +@Category(UiTests.class) public class LogTextAreaTest extends ApplicationTest { private LogTextArea logTextArea; @@ -23,36 +27,36 @@ public void start(Stage stage) { @Test public void testAddFirstLine() { - final String FIRST_LINE = "First Line Of Text"; - logTextArea.addLineToLog(FIRST_LINE); - assertEquals("First line wasn't added", FIRST_LINE + "\n", logTextArea.getText()); + final String firstLine = "First Line Of Text"; + logTextArea.addLineToLog(firstLine); + assertEquals("First line wasn't added", firstLine + "\n", logTextArea.getText()); } @Test public void testAddTwoLines() { - final String FIRST_LINE = "First Line Of Text"; - final String SECOND_LINE = "Second line of text"; - logTextArea.addLineToLog(FIRST_LINE); - logTextArea.addLineToLog(SECOND_LINE); - assertEquals("Second line wasn't added", FIRST_LINE + "\n" + SECOND_LINE + "\n", logTextArea + final String firstLine = "First Line Of Text"; + final String secondLine = "Second line of text"; + logTextArea.addLineToLog(firstLine); + logTextArea.addLineToLog(secondLine); + assertEquals("Second line wasn't added", firstLine + "\n" + secondLine + "\n", logTextArea .getText()); } @Test public void testAddingReallyLongLineOfText() { - final String INITIAL_TEXT = StringUtils.rightPad("Initial string", LogTextArea + final String initialLength = StringUtils.rightPad("Initial string", LogTextArea .MAX_STRING_LENGTH - 3, "Long\n"); - logTextArea.addLineToLog(INITIAL_TEXT); - assertEquals("Text was not added to logger", INITIAL_TEXT + "\n", logTextArea.getText()); + logTextArea.addLineToLog(initialLength); + assertEquals("Text was not added to logger", initialLength + "\n", logTextArea.getText()); } @Test public void testAddingStringThatIsTooLong() { - final String INITIAL_TEXT = StringUtils.rightPad("Initial string", LogTextArea + final String initialText = StringUtils.rightPad("Initial string", LogTextArea .MAX_STRING_LENGTH, "Long\n"); - logTextArea.addLineToLog(INITIAL_TEXT); + logTextArea.addLineToLog(initialText); assertNotEquals("The initial text should not have been appended as it was too long", - INITIAL_TEXT + "\n", logTextArea.getText()); + initialText + "\n", logTextArea.getText()); } @Test @@ -67,10 +71,10 @@ public void testAddingStringToFullLog() { @Test public void testScrollIsMaintainedWhenScrollIsPaused() { logTextArea.setPausedScroll(true); - final double INITIAL_SCROLL = logTextArea.getScrollTop(); - final String LONG_TEXT = StringUtils.rightPad("InitialString", 500, "Text\n"); - logTextArea.addLineToLog(LONG_TEXT); - assertEquals("The log should not have scrolled", INITIAL_SCROLL, logTextArea.getScrollTop(), + final double initialScroll = logTextArea.getScrollTop(); + final String longText = StringUtils.rightPad("InitialString", 500, "Text\n"); + logTextArea.addLineToLog(longText); + assertEquals("The log should not have scrolled", initialScroll, logTextArea.getScrollTop(), 0.001); } diff --git a/ui/src/test/java/edu/wpi/grip/ui/components/PreviousNextButtonsTest.java b/ui/src/test/java/edu/wpi/grip/ui/components/PreviousNextButtonsTest.java index 6772999e73..ba8450e9c6 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/components/PreviousNextButtonsTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/components/PreviousNextButtonsTest.java @@ -1,9 +1,11 @@ package edu.wpi.grip.ui.components; import edu.wpi.grip.core.PreviousNext; +import edu.wpi.grip.ui.UiTests; import org.junit.Ignore; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import org.testfx.matcher.base.NodeMatchers; import org.testfx.util.WaitForAsyncUtils; @@ -15,6 +17,7 @@ import static junit.framework.TestCase.assertEquals; import static org.testfx.api.FxAssert.verifyThat; +@Category(UiTests.class) public class PreviousNextButtonsTest extends ApplicationTest { private MockPreviousNext previousNext; diff --git a/ui/src/test/java/edu/wpi/grip/ui/components/StartStoppableButtonTest.java b/ui/src/test/java/edu/wpi/grip/ui/components/StartStoppableButtonTest.java index bb19ba5b03..352bca689b 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/components/StartStoppableButtonTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/components/StartStoppableButtonTest.java @@ -3,10 +3,12 @@ import edu.wpi.grip.core.util.service.AutoRestartingService; import edu.wpi.grip.core.util.service.RestartableService; import edu.wpi.grip.core.util.service.ServiceRestartPolicy; +import edu.wpi.grip.ui.UiTests; import com.google.common.util.concurrent.AbstractIdleService; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import org.testfx.matcher.base.NodeMatchers; import org.testfx.util.WaitForAsyncUtils; @@ -20,6 +22,7 @@ import static junit.framework.TestCase.assertTrue; import static org.testfx.api.FxAssert.verifyThat; +@Category(UiTests.class) public class StartStoppableButtonTest extends ApplicationTest { private RestartableService restartableService; diff --git a/ui/src/test/java/edu/wpi/grip/ui/pipeline/AddSourceButtonTest.java b/ui/src/test/java/edu/wpi/grip/ui/pipeline/AddSourceButtonTest.java index da5334fcdd..70125c85c1 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/pipeline/AddSourceButtonTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/pipeline/AddSourceButtonTest.java @@ -2,11 +2,13 @@ import edu.wpi.grip.core.sources.CameraSource; import edu.wpi.grip.core.sources.MockCameraSource; +import edu.wpi.grip.ui.UiTests; import com.google.common.eventbus.EventBus; import org.junit.After; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import org.testfx.framework.junit.ApplicationTest; @@ -31,6 +33,7 @@ public class AddSourceButtonTest { /** * Tests what happens when a source is created and started successfully */ + @Category(UiTests.class) public static class AddSourceViewNoExceptionsTest extends ApplicationTest { private EventBus eventBus; @@ -139,6 +142,7 @@ private MockCameraSource assignLastCreated(MockCameraSource source) { /** * Tests what happens when the source being created and startedthrows an exception. */ + @Category(UiTests.class) public static class AddSourceViewWithExceptionsTest extends ApplicationTest { private EventBus eventBus; private AddSourceButton addSourceView; diff --git a/ui/src/test/java/edu/wpi/grip/ui/pipeline/OutputSocketControllerTest.java b/ui/src/test/java/edu/wpi/grip/ui/pipeline/OutputSocketControllerTest.java index 2c2246e5e9..239b58c1ba 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/pipeline/OutputSocketControllerTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/pipeline/OutputSocketControllerTest.java @@ -1,11 +1,13 @@ package edu.wpi.grip.ui.pipeline; import edu.wpi.grip.core.sockets.MockOutputSocket; +import edu.wpi.grip.ui.UiTests; import edu.wpi.grip.ui.util.TestAnnotationFXMLLoader; import com.google.common.eventbus.EventBus; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import org.testfx.util.WaitForAsyncUtils; @@ -17,6 +19,7 @@ import static org.junit.Assert.assertTrue; +@Category(UiTests.class) public class OutputSocketControllerTest extends ApplicationTest { private MockOutputSocket outputSocket; diff --git a/ui/src/test/java/edu/wpi/grip/ui/pipeline/PipelineUITest.java b/ui/src/test/java/edu/wpi/grip/ui/pipeline/PipelineUITest.java index e918a032b0..80480bb103 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/pipeline/PipelineUITest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/pipeline/PipelineUITest.java @@ -16,6 +16,7 @@ import edu.wpi.grip.core.sockets.OutputSocket; import edu.wpi.grip.core.util.MockExceptionWitness; import edu.wpi.grip.ui.GripUiModule; +import edu.wpi.grip.ui.UiTests; import edu.wpi.grip.ui.util.StyleClassNameUtility; import edu.wpi.grip.ui.util.TestAnnotationFXMLLoader; import edu.wpi.grip.util.GripCoreTestModule; @@ -31,6 +32,7 @@ import org.junit.After; import org.junit.Ignore; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import org.testfx.matcher.base.NodeMatchers; import org.testfx.util.WaitForAsyncUtils; @@ -50,6 +52,7 @@ import static org.testfx.api.FxAssert.verifyThat; import static org.testfx.api.FxAssert.verifyThatIter; +@Category(UiTests.class) public class PipelineUITest extends ApplicationTest { private GripCoreTestModule testModule; diff --git a/ui/src/test/java/edu/wpi/grip/ui/pipeline/input/InputSocketControllerFactoryTest.java b/ui/src/test/java/edu/wpi/grip/ui/pipeline/input/InputSocketControllerFactoryTest.java index dbd072d1fb..9e1d3ad9ea 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/pipeline/input/InputSocketControllerFactoryTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/pipeline/input/InputSocketControllerFactoryTest.java @@ -7,6 +7,7 @@ import edu.wpi.grip.core.operations.network.MockGripNetworkModule; import edu.wpi.grip.core.sockets.InputSocket; import edu.wpi.grip.ui.GripUiModule; +import edu.wpi.grip.ui.UiTests; import edu.wpi.grip.util.GripCoreTestModule; import com.google.common.eventbus.EventBus; @@ -16,6 +17,7 @@ import org.junit.After; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.testfx.framework.junit.ApplicationTest; @@ -32,6 +34,7 @@ @RunWith(Parameterized.class) +@Category(UiTests.class) public class InputSocketControllerFactoryTest extends ApplicationTest { private final OperationMetaData operationMeta; diff --git a/ui/src/test/java/edu/wpi/grip/ui/preview/ImageSocketPreviewViewTest.java b/ui/src/test/java/edu/wpi/grip/ui/preview/ImageSocketPreviewViewTest.java index a1b06f1b36..d446161b7e 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/preview/ImageSocketPreviewViewTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/preview/ImageSocketPreviewViewTest.java @@ -5,6 +5,7 @@ import edu.wpi.grip.core.sockets.OutputSocket; import edu.wpi.grip.core.sockets.SocketHint; import edu.wpi.grip.ui.GripUiModule; +import edu.wpi.grip.ui.UiTests; import edu.wpi.grip.ui.util.MockGripPlatform; import edu.wpi.grip.util.Files; import edu.wpi.grip.util.GripCoreTestModule; @@ -16,6 +17,7 @@ import org.junit.After; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import org.testfx.matcher.base.NodeMatchers; import org.testfx.util.WaitForAsyncUtils; @@ -25,6 +27,7 @@ import static org.testfx.api.FxAssert.verifyThat; +@Category(UiTests.class) public class ImageSocketPreviewViewTest extends ApplicationTest { private static final String identifier = "image"; private GripCoreTestModule testModule; diff --git a/ui/src/test/java/edu/wpi/grip/ui/preview/PointSizeSocketPreviewViewTest.java b/ui/src/test/java/edu/wpi/grip/ui/preview/PointSizeSocketPreviewViewTest.java index 4cf60c20b1..6c8b16c221 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/preview/PointSizeSocketPreviewViewTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/preview/PointSizeSocketPreviewViewTest.java @@ -4,6 +4,7 @@ import edu.wpi.grip.core.sockets.OutputSocket; import edu.wpi.grip.core.sockets.SocketHint; import edu.wpi.grip.ui.GripUiModule; +import edu.wpi.grip.ui.UiTests; import edu.wpi.grip.ui.util.MockGripPlatform; import edu.wpi.grip.util.GripCoreTestModule; @@ -16,6 +17,7 @@ import org.bytedeco.javacpp.opencv_core.Size; import org.junit.After; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import org.testfx.framework.junit.ApplicationTest; @@ -30,6 +32,7 @@ @RunWith(Enclosed.class) public class PointSizeSocketPreviewViewTest { + @Category(UiTests.class) public static class PointSocketPreviewViewTest extends ApplicationTest { private static final String identifier = "testPoint"; private static final int value1 = 1; @@ -71,6 +74,7 @@ public void tearDown() { } } + @Category(UiTests.class) public static class SizeSocketPreviewViewTest extends ApplicationTest { private static final String identifier = "testSize"; private static final int value1 = 1; diff --git a/ui/src/test/java/edu/wpi/grip/ui/util/ControllerMapTest.java b/ui/src/test/java/edu/wpi/grip/ui/util/ControllerMapTest.java index ff6ab75196..0b39e65b30 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/util/ControllerMapTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/util/ControllerMapTest.java @@ -1,10 +1,12 @@ package edu.wpi.grip.ui.util; import edu.wpi.grip.ui.Controller; +import edu.wpi.grip.ui.UiTests; import com.google.common.base.Throwables; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import java.util.Arrays; @@ -15,6 +17,7 @@ import static org.junit.Assert.assertEquals; +@Category(UiTests.class) public class ControllerMapTest extends ApplicationTest { private static final String SIZE_OF_CONTROLLER_NOT_SAME_STRING = @@ -31,6 +34,7 @@ public void start(Stage stage) { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testRemoveWithController() throws Exception { interact(() -> { final MockController mockController = new MockController(); @@ -42,6 +46,7 @@ public void testRemoveWithController() throws Exception { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testRemoveWithPane() throws Exception { interact(() -> { final MockController mockController = new MockController(); @@ -53,6 +58,7 @@ public void testRemoveWithPane() throws Exception { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testAdd() throws Exception { interact(() -> { mockPane.controllerMap.add(new MockController()); @@ -61,6 +67,7 @@ public void testAdd() throws Exception { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testAddAll() throws Exception { interact(() -> { mockPane.controllerMap.addAll(new MockController(), new MockController()); @@ -69,6 +76,7 @@ public void testAddAll() throws Exception { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testAddAll1() throws Exception { interact(() -> { mockPane.controllerMap.addAll(Arrays.asList(new MockController(), new MockController())); @@ -77,6 +85,7 @@ public void testAddAll1() throws Exception { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testGetWithPane() throws Exception { interact(() -> { final MockController mockController = new MockController(); diff --git a/ui/src/test/java/edu/wpi/grip/ui/util/GripPlatformTest.java b/ui/src/test/java/edu/wpi/grip/ui/util/GripPlatformTest.java index 5b30a80874..beb1331d5a 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/util/GripPlatformTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/util/GripPlatformTest.java @@ -1,5 +1,7 @@ package edu.wpi.grip.ui.util; +import edu.wpi.grip.ui.UiTests; + import com.google.common.eventbus.EventBus; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -9,6 +11,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.junit.rules.Timeout; import org.testfx.framework.junit.ApplicationTest; @@ -20,6 +23,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +@Category(UiTests.class) public class GripPlatformTest extends ApplicationTest { @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", @@ -60,6 +64,7 @@ public void testRunAsSoonAsPossibleRunsInCorrectThreadWhenNotCalledFromFXThread( } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testRunAsSoonAsPossibleWhenCalledFromFXThread() { interact(() -> { // This will be running in the JavaFX thread final boolean[] hasRun = {false}; diff --git a/ui/src/test/java/edu/wpi/grip/ui/util/ImageConverterTest.java b/ui/src/test/java/edu/wpi/grip/ui/util/ImageConverterTest.java index 85776e41c9..a6dbd50023 100644 --- a/ui/src/test/java/edu/wpi/grip/ui/util/ImageConverterTest.java +++ b/ui/src/test/java/edu/wpi/grip/ui/util/ImageConverterTest.java @@ -1,11 +1,13 @@ package edu.wpi.grip.ui.util; import edu.wpi.grip.core.util.ImageLoadingUtility; +import edu.wpi.grip.ui.UiTests; import edu.wpi.grip.util.Files; import edu.wpi.grip.util.ImageWithData; import org.bytedeco.javacpp.opencv_core.Mat; import org.junit.Test; +import org.junit.experimental.categories.Category; import org.testfx.framework.junit.ApplicationTest; import java.net.URLDecoder; @@ -22,6 +24,7 @@ import static org.junit.Assert.assertEquals; +@Category(UiTests.class) public class ImageConverterTest extends ApplicationTest { private static final ImageWithData gompeiImage = Files.gompeiJpegFile; private static final ImageWithData imageFile = Files.imageFile; @@ -36,6 +39,7 @@ public void start(Stage stage) { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testConvertImage() throws Exception { Mat mat = new Mat(); ImageLoadingUtility.loadImage( @@ -54,6 +58,7 @@ public void testConvertInWrongThreadThrowsIllegalState() { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testConvertImageSwitch() throws Exception { Mat gompeiMat = new Mat(); Mat imageMat = new Mat(); @@ -71,6 +76,7 @@ public void testConvertImageSwitch() throws Exception { } @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void testConvertSingleChanelImage() throws Exception { final Mat gompeiMat = new Mat(); ImageLoadingUtility.loadImage( diff --git a/ui/ui.gradle.kts b/ui/ui.gradle.kts index 95016c7d23..962dc89d17 100644 --- a/ui/ui.gradle.kts +++ b/ui/ui.gradle.kts @@ -1,12 +1,9 @@ -import de.dynamicfiles.projects.gradle.plugins.javafx.JavaFXGradlePluginExtension -import de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxNativeTask import edu.wpi.first.wpilib.opencv.installer.Installer -import java.io.File -import java.io.FileFilter +import org.gradle.internal.jvm.Jvm +import org.gradle.internal.os.OperatingSystem plugins { `application` - id("javafx-gradle-plugin") id("com.google.osdetector") } @@ -17,6 +14,8 @@ if (!(project.hasProperty("generation") || project.hasProperty("genonly"))) { } } +createNativeConfigurations() + val withCuda = project.hasProperty("cuda") || project.hasProperty("WITH_CUDA") if (withCuda) { @@ -27,42 +26,69 @@ dependencies { compile(project(":core")) compile(project(":ui:preloader")) //ideProvider project(path= ":core", configuration= "compile") - compile(group = "org.controlsfx", name = "controlsfx", version = "8.40.11") + + if (BuildType.isJdk11) { + compile(group = "org.controlsfx", name = "controlsfx", version = "11.0.0-RC2") + } else { + compile(group = "org.controlsfx", name = "controlsfx", version = "8.40.14") + } compile(group = "com.hierynomus", name = "sshj", version = "0.16.0") compile(group = "org.apache.velocity", name = "velocity", version = "1.7") + if (BuildType.isJdk11) { + javafx("base") + javafx("controls") + javafx("fxml") + javafx("graphics") + } + val coreTestOutput = project(":core").dependencyProject.sourceSets["test"].output testCompile(files(coreTestOutput)) testCompile(files(coreTestOutput.resourcesDir)) + + // Note: testfx is ONLY usable on JDK 8, so we have to use the versions testCompile(group = "org.testfx", name = "testfx-core", version = "4.0.5-alpha") testCompile(group = "org.testfx", name = "testfx-junit", version = "4.0.5-alpha") testRuntime(group = "org.testfx", name = "openjfx-monocle", version = "1.8.0_20") testCompile(group = "org.opencv", name = "opencv-java", version = "3.1.0") } -if (System.getProperty("os.name").toLowerCase().contains("linux")) { - tasks.named("jfxNative") { - dependsOn(":ui:linuxLauncher:linuxLauncherExecutable") - } -} - tasks.named("compileTestJava") { dependsOn(":core:testClasses") } /* - * Allows you to run the UI tests in headless mode by calling gradle with the -Pheadless=true argument + * Allows you to run the UI tests in headless mode by calling gradle with the -Pheadless argument */ if (project.hasProperty("headless")) { - println("Running UI Tests Headless") - tasks.withType() { + println("Running UI tests headless (if supported by current JDK)") + tasks.withType { jvmArgs = listOf( "-Djava.awt.headless=true", "-Dtestfx.robot=glass", "-Dtestfx.headless=true", "-Dprism.order=sw", - "-Dprism.text=t2k" + "-Dprism.text=t2k", + "-Dheadless.geometry=1600x1200-32" ) + if (BuildType.isJdk11) { + println("UI tests do not work properly when headless, and are disabled until fixed in JavaFX and TestFX") + useJUnit { + excludeCategories("edu.wpi.grip.ui.UiTests") + } + } + } +} + +/* + * TestFX is flaky on Java >= 10, and is completely broken in headless mode on Java 10+. JavaFX 13 + * should fix the issue, but won't be publicly available for a while. + */ +if (BuildType.isJdk11) { + tasks.withType { + useJUnit { + excludeCategories("edu.wpi.grip.ui.UiTests") + } } } @@ -161,62 +187,170 @@ if (project.hasProperty("generation") || project.hasProperty("genonly")) { } } -val arch = osdetector.arch.replace("x86_64", "x64") +tasks.register("cleanInstaller") { + group = "Installer generation" + description = "Deletes old installer files for the GRIP application installer." + delete(buildDir.resolve("installer")) +} -jfx { - mainClass = "edu.wpi.grip.ui.Main" - preLoader = "edu.wpi.grip.preloader.GripPreloader" +tasks.register("collectDependencies") { + group = "Installer generation" + description = "Collects dependencies into a single directory for jpackage." + from( + configurations["compile"], + configurations["runtime"], + configurations["runtimeClasspath"], + project.projectDir.resolve("installer-files"), + tasks.named("jar"), + project("preloader").tasks.named("jar") + ) + into(buildDir.resolve("installerInput")) +} - identifier = "GRIP" - appName = "GRIP" - vendor = "Worcester Polytechnic Institute" - nativeReleaseVersion = "$version-$arch" +if (BuildType.isJdk11) { + /** + * Build a Java 11 runtime image with jlink. Otherwise a Java 13 image would be generated by + * jpackage, which is not ideal given that Java 13 is not yet stable. + * + * This task regenerates the jlink image every time it is invoked. + */ + tasks.register("jlink") { + group = "Installer generation" + description = "Generates a runtime image for a native installer." - jfxMainAppJarName = "${jfx.appName}-${jfx.nativeReleaseVersion}.jar" + val outputDir = project.buildDir.resolve("jlink").absolutePath + outputs.file(outputDir) + delete(outputDir) - // -XX:-OmitStackTraceInFastThrow prevents the JIT from eating stack traces that get thrown a lot - // This is slower but means we actually get the stack traces instead of - // having them become one line like `java.lang.ArrayIndexOutOfBoundsException` - // and as such, would be useless. - // See= https://plumbr.eu/blog/java/on-a-quest-for-missing-stacktraces - // -Xmx limits the heap size. This prevents memory use from ballooning with a lot - // of JavaCV native objects being allocated hanging around waiting to get GC"d. - // -XX:MaxNewSize limits the size of the eden space to force minor GCs to run more often. - // This causes old mats (which take up little space on the heap but a lot of native memory) to get deallocated - // and free up native memory quicker, limiting the memory the app takes up. - jvmArgs = listOf("-XX:-OmitStackTraceInFastThrow", "-Xmx200m", "-XX:MaxNewSize=32m") + val modules = listOf( + "java.base", + "java.desktop", + "java.datatransfer", + "java.logging", + "java.management", + "java.naming", + "java.prefs", + "java.scripting", + "java.sql", + "java.xml", + "jdk.dynalink", + "jdk.scripting.nashorn", + "jdk.unsupported" + ) - bundleArguments = mapOf( - "linux.launcher.url" to file("linuxLauncher/build/exe/linuxLauncher/linuxLauncher").toURI().toURL().toExternalForm() - ) -} + setCommandLine( + Jvm.current().javaHome.resolve("bin/jlink").absolutePath, + "--add-modules", modules.joinToString(separator = ","), + "--output", outputDir, + "--no-header-files", + "--compress=2", + "--no-man-pages", + "--strip-debug" + ) + } -tasks.named("jfxNative") { - dependsOn(":core:jar") + tasks.register("jpackage") { + group = "Installer generation" + description = "Generates a native installer for the GRIP application." - // The JavaFX plugin removes all but numeric characters after the app name in the file - // name, so we restore the full name of the file here - doLast { - logger.log(LogLevel.INFO, "Renaming installer packages") - val packageFileFilter = FileFilter { file -> - listOf("exe", "dmg", "pkg", "deb", "rpm").any { - file.extension == it - } + // TODO: Since Gradle does not run on JDK 13, we need to pass in the JDK home as part of the build process + // See https://github.com/gradle/gradle/issues/8681 + if (!project.properties.containsKey("jdk13")) { + logger.error("The path to a valid JDK 13 installation with jpackage must be provided with -Pjdk13=/path/to/jdk-13") + return@register } - val packageFiles = buildDir.resolve("jfx/native").listFiles(packageFileFilter) - packageFiles.forEach { packageFile -> - val newName: String = jfx.jfxMainAppJarName.replace(Regex("""\.jar$"""), ".${packageFile.extension}") - logger.log(LogLevel.DEBUG, "Renaming ${packageFile.name} to $newName") - packageFile.renameTo(packageFile.resolveSibling(newName)) + + val cleanInstaller: Delete by tasks + val collectDependencies: Copy by tasks + val jlink by tasks + dependsOn(cleanInstaller, collectDependencies, jlink) + + val jdk13: String = project.property("jdk13").toString() + + jdkHome.set(File(jdk13)) + runtimeImage.set(jlink.outputs.files.singleFile) + verbose.set(true) + outputDir.set(buildDir.resolve("installer")) + inputDir.set(collectDependencies.destinationDir) + + jvmArgs.setAll("-Xmx200M") + + mainJar.set(collectDependencies.destinationDir.resolve("ui-${project.version}.jar")) + mainClassName.set("edu.wpi.grip.ui.Launch") + + applicationName.set("GRIP") + applicationDescription.set("GRIP Computer Vision Engine") + + val projectVersion = "${project.version}" + applicationVersion.set(projectVersion.drop(1).takeWhile { it != '-' }) // 'v1.5.2-abfa51a' -> '1.5.2' + fullApplicationVersion.set(projectVersion) + copyright.set("Copyright (c) 2015-2019 WPI") + licenseFile.set(rootDir.resolve("LICENSE.txt")) + applicationVendor.set("Worcester Polytechnic Institute") + identifier.set("edu.wpi.grip") + + configureForCurrentOs() + + winUpgradeUuid.set("d74b4d69-a88a-47ef-b972-9a7911cf7af1") + winRegistryName.set("edu.wpi.grip") + addToWindowsMenu.set(true) + addWindowsDesktopShortcut.set(true) + + macBundleIdentifier.set("edu.wpi.grip") + } +} else { + tasks.register("jpackage") { + doLast { + throw UnsupportedOperationException("jpackage can only be run when using JDK 11") } } } application { - mainClassName = jfx.mainClass + mainClassName = "edu.wpi.grip.ui.Launch" } -val jfx: JavaFXGradlePluginExtension - get() = extensions.getByType(JavaFXGradlePluginExtension::class.java) +/** + * Gets the installer type to use for the current operating system. Windows uses `.exe`, mac `.dmg`, + * and linux `.deb`. + */ +fun installerTypeForCurrentOs() = when (OperatingSystem.current()) { + OperatingSystem.WINDOWS -> "exe" + OperatingSystem.MAC_OS -> "dmg" + OperatingSystem.LINUX -> "deb" + else -> throw UnsupportedOperationException("Unsupported OS") +} + +/** + * The base directory for installer files. + */ +val installerFilesBaseDir by lazy { + projectDir.resolve("installer-files") +} -fun jfx(configuration: JavaFXGradlePluginExtension.() -> Unit) = jfx.apply(configuration) +/** + * Configures a jpackage task for the current operating system. + */ +fun JpackageExec.configureForCurrentOs() { + when (OperatingSystem.current()) { + OperatingSystem.WINDOWS -> { + val installerFileDir = installerFilesBaseDir.resolve("win") + resourceDir.set(installerFileDir) + icon.set(installerFileDir.resolve("grip_TP6_icon.ico")) + fileAssociations.set(installerFileDir.resolve("file-associations.properties")) + installerType.set("exe") + } + OperatingSystem.MAC_OS -> { + val installerFileDir = installerFilesBaseDir.resolve("mac") + resourceDir.set(installerFileDir) + icon.set(installerFileDir.resolve("GRIP.icns")) + installerType.set("dmg") + } + OperatingSystem.LINUX -> { + val installerFileDir = installerFilesBaseDir.resolve("linux") + resourceDir.set(installerFileDir) + icon.set(installerFileDir.resolve("GRIP.png")) + installerType.set("deb") + } + } +}