Skip to content

Commit

Permalink
QoL improvement: typecheck just one test (#335)
Browse files Browse the repository at this point in the history
(on unix only, because I don't know how to write a bat script)
  • Loading branch information
kelloggm authored Jul 26, 2024
1 parent ac79474 commit e7091e4
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 18 deletions.
6 changes: 5 additions & 1 deletion DEVELOPERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ if the test input is in a package, there must be a corresponding file structure
here.
* the expected test output. It is stored in `src/test/resources/$testname/expected`.
It must be an independently-compilable Java program; our CI system checks this requirement
by running the `./gradlew expectedTestOutputsMustCompile` command.
by running the `./gradlew expectedTestOutputsMustCompile` command. Since this command takes
some time to complete, you can use `./gradlew checkExpectedOutputCompilesFor -PtestName="x"`
to run check that some specific test "x" compiles ("x" should be the all-lower-case name of
the test, since this script uses the test name to find the right "expected" directory). Note
that the `checkExpectedOutputCompilesFor` Gradle task only works on Unix systems.

You can run all of the tests via `./gradlew test`. When debugging a specific
test, I usually use a command like this one (replacing `MethodRef2Test` with the
Expand Down
14 changes: 13 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,26 @@ task requireJavadoc(type: JavaExec) {
}

task expectedTestOutputsMustCompile(type: Exec) {
// TODO: should this task run in CI, or as part of the regular tests?
if (System.getProperty('os.name').toLowerCase().startsWith('windows')) {
commandLine "cmd", "/c", "typecheck_test_outputs.bat"
} else {
commandLine "sh", "typecheck_test_outputs.sh"
}
}

// run via e.g.: ./gradlew checkExpectedOutputCompilesFor -PtestName="onefilesimple"
task checkExpectedOutputCompilesFor(type: Exec) {
if (project.hasProperty("testName")) {
workingDir("src/test/resources")
if (System.getProperty('os.name').toLowerCase().startsWith('windows')) {
// TODO: fix this
print "checkExpectedOutputCompilesFor is not supported on Windows"
} else {
commandLine "sh", "../../../typecheck_one_test.sh", project.property("testName")
}
}
}

tasks.compileJava {
// uncomment for testing
// options.errorprone.enabled = false
Expand Down
28 changes: 28 additions & 0 deletions typecheck_one_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/sh

## This script runs javac on a single expected test output. If the test output
## is compilable, it exits with code 0. If not, it exits with code 1. In all other
# cases (e.g., if a cd command fails), it exits with code 2. It includes
## logic for skipping test cases that don't need to compile, etc. It should be
## run in the directory src/test/resources.

testcase=$1

if [ "${testcase}" = "shared" ]; then exit 0; fi
# https://bugs.openjdk.org/browse/JDK-8319461 wasn't actually fixed (this test is based on that bug)
if [ "${testcase}" = "superinterfaceextends" ]; then exit 0; fi
# incomplete handling of method references: https://github.com/njit-jerse/specimin/issues/291
# this test exists to check that no crash occurs, not that Specimin produces the correct output
if [ "${testcase}" = "methodref2" ]; then exit 0; fi
cd "${testcase}/expected/" || exit 2
# javac relies on word splitting
# shellcheck disable=SC2046
javac -classpath "../../shared/checker-qual-3.42.0.jar" $(find . -name "*.java") \
|| { echo "Running javac on ${testcase}/expected issues one or more errors, which are printed above."; \
find . -name "*.class" -exec rm {} \; ; exit 1; }

# clean up
find . -name "*.class" -exec rm {} \;

cd ../.. || exit 2
exit 0
24 changes: 8 additions & 16 deletions typecheck_test_outputs.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh

# This script runs javac on all of the expected test outputs under src/test/resources.
# It returns 2 if any of them fail to compile, 1 if there are any malformed test directories,
# It returns 1 if any of them fail to compile, 2 if there are any malformed test directories,
# and 0 if all of them do compile.
#
# It is desirable that all of the expected test outputs compile, because Specimin
Expand All @@ -11,26 +11,18 @@ returnval=0

cd src/test/resources || exit 1
for testcase in * ; do
if [ "${testcase}" = "shared" ]; then continue; fi
# https://bugs.openjdk.org/browse/JDK-8319461 wasn't actually fixed (this test is based on that bug)
if [ "${testcase}" = "superinterfaceextends" ]; then continue; fi
# incomplete handling of method references: https://github.com/njit-jerse/specimin/issues/291
# this test exists to check that no crash occurs, not that Specimin produces the correct output
if [ "${testcase}" = "methodref2" ]; then continue; fi
cd "${testcase}/expected/" || exit 1
# javac relies on word splitting
# shellcheck disable=SC2046
javac -classpath "../../shared/checker-qual-3.42.0.jar" $(find . -name "*.java") \
|| { echo "Running javac on ${testcase}/expected issues one or more errors, which are printed above."; returnval=2; }
cd ../.. || exit 1
sh ../../../typecheck_one_test.sh "${testcase}"
# update overall return value
test_retval=$?
if [ ! "${test_retval}" = 0 ]; then
returnval=1
fi
done

if [ "${returnval}" = 0 ]; then
echo "All expected test outputs compiled successfully."
elif [ "${returnval}" = 2 ]; then
elif [ "${returnval}" = 1 ]; then
echo "Some expected test outputs do not compile successfully. See the above error output for details."
fi

find . -name "*.class" -exec rm {} \;

exit ${returnval}

0 comments on commit e7091e4

Please sign in to comment.