Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

QoL improvement: typecheck just one test #335

Merged
merged 5 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}
Loading