Module io.github.ascopes.jct


module io.github.ascopes.jct
A framework for performing exhaustive integration testing against Java compilers in modern Java libraries, with a focus on full JPMS support.

The Java Compiler Testing API has a number of facilities for assisting in testing anything related to the Java compiler. This includes Javac plugins and JSR-199 annotation processors.

All test cases are designed to be as stateless as possible, with facilities to produce managed test directories on RAM disks or in temporary locations within the host file system.

Integration test cases can be written to cross-compile against a range of Java compiler versions, with the ability to provide as much or as little configuration detail as you wish.

Compilation results are complimented with a suite of assertion facilities that extend the AssertJ API to assist in writing fluent and human-readable test cases for your code. Each of these assertions comes with specially-developed human-readable error messages and formatting.

Full JUnit5 integration is provided to streamline the development process, letting you focus on your code rather than flaky test environments and dependency management.

Any questions, feedback, or issues can be submitted on GitHub.

Releases can be found on Maven Central.

Common elements

  • JctCompiler - an encapsulation of the compiler API that can be interacted with to configure how the compiler runs.
  • JctCompilation - the result of calling compile() on a JctCompiler object. It holds information about whether the compilation succeeded, what was logged, and can be asserted upon to verify various conditions.
  • Workspace - a wrapper around a temporary file system that holds all the compiler inputs and outputs. This can be asserted upon to verify various conditions, and is designed to be created per test case to help keep your tests reproducible.

A simple example


    import static io.github.ascopes.jct.assertions.JctAssertions.assertThatCompilation;

    import io.github.ascopes.jct.compilers.JctCompiler;
    import io.github.ascopes.jct.junit.JavacCompilerTest;
    import io.github.ascopes.jct.workspaces.Workspaces;
    import org.example.processor.JsonSchemaAnnotationProcessor;
    import org.skyscreamer.jsonassert.JSONAssert;

    class JsonSchemaAnnotationProcessorTest {

      @JavacCompilerTest(minVersion=11, maxVersion=19)
      void theJsonSchemaIsCreatedFromTheInputCode(JctCompiler compiler) {

        try (var workspace = Workspaces.newWorkspace()) {
          // Given
          workspace
              .createSourcePathPackage()
              .createDirectory("org", "example", "tests")
              .copyContentsFrom("src", "test", "resources", "code", "schematest");

          // When
          var compilation = compiler
              .addAnnotationProcessors(new JsonSchemaAnnotationProcessor())
              .addAnnotationProcessorOptions("jsonschema.verbose=true")
              .failOnWarnings(true)
              .showDeprecationWarnings(true)
              .compile(workspace);

          // Then
          assertThatCompilation(compilation)
              .isSuccessfulWithoutWarnings();

          assertThatCompilation(compilation)
              .diagnostics().notes().singleElement()
              .message().isEqualTo(
                  "Creating JSON schema in Java %s for package org.example.tests",
                  compiler.getRelease()
              );

          assertThatCompilation(compilation)
              .classOutputPackages()
              .fileExists("json-schemas", "UserSchema.json").contents()
              .isNotEmpty()
              .satisfies(contents -> JSONAssert.assertEquals(...));
      }
    }