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

Burst constructor with value class parameter fails #93

Closed
swankjesse opened this issue Jan 25, 2025 · 1 comment · Fixed by #94
Closed

Burst constructor with value class parameter fails #93

swankjesse opened this issue Jan 25, 2025 · 1 comment · Fixed by #94

Comments

@swankjesse
Copy link
Collaborator

swankjesse commented Jan 25, 2025

Here’s a test class that accepts a value class as a parameter:

@Burst
class CoffeeTest(
  private val espresso: Espresso = burstValues(...),
) {
  @Test
  fun test() {
    println("running $espresso")
  }
}

@JvmInline
value class Espresso private constructor(private val ordinal: Int) { ... }

It fails like this:

CoffeeTest[jvm] > initializationError[jvm] FAILED
    java.lang.IllegalArgumentException: Test class can only have one constructor
        at org.junit.runners.model.TestClass.<init>(TestClass.java:48)
        at org.junit.runners.JUnit4.<init>(JUnit4.java:23)
        at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
        at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)

As a side-effect of some value class implementation details, the compiler generates an extra constructor overload. Unfortunately that overload is generated after Burst does its edits.

The JUnit API expects a single public constructor.

I can’t think of an easy way to make this work.

@swankjesse
Copy link
Collaborator Author

Okay, I think there’s a simple enough fix...

If any constructor parameter is a value class, we treat it as if there’s no default specialization. That’ll send us into a code path that marks the class as abstract and causes JUnit to ignore both constructors.

      // There's no default specialization. Make the class abstract so JUnit skips it.
      original.modality = Modality.ABSTRACT

swankjesse pushed a commit that referenced this issue Jan 25, 2025
…ameter

An implementation detail of the Kotlin compiler gets in our way.

Closes: #93
swankjesse added a commit that referenced this issue Jan 27, 2025
…ameter (#94)

An implementation detail of the Kotlin compiler gets in our way.

Closes: #93

Co-authored-by: Jesse Wilson <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant