Skip to content

Add test coverage for TypeClasses witness resolution#7

Merged
Garciat merged 12 commits into
mainfrom
copilot/write-tests-for-type-classes
Dec 14, 2025
Merged

Add test coverage for TypeClasses witness resolution#7
Garciat merged 12 commits into
mainfrom
copilot/write-tests-for-type-classes

Conversation

Copilot AI commented Dec 14, 2025

Copy link
Copy Markdown
Contributor
  • Explore repository structure and understand the codebase
  • Verify build and test infrastructure (Maven with JUnit Jupiter and AssertJ)
  • Understand key classes: TypeClasses, ParsedType, FuncType, Unification
  • Create unit tests for ParsedType (11 tests, including type variables and wildcard types)
  • Create unit tests for FuncType (7 tests, including generic methods with type parameters)
  • Create unit tests for Unification (16 tests, including type variables within type applications)
  • Create custom test type classes (TestShow, TestEq) for test isolation
  • Create integration tests for TypeClasses.witness() behavior (19 tests)
    • Witness constructor lookup in C and T1, T2, ..., Tn
    • Public static methods with @TypeClass.Witness annotation
    • Recursive resolution of witness dependencies
    • Overlapping instances behavior (OVERLAPPING/OVERLAPPABLE)
    • Multiple constructors ambiguity detection
    • Not found errors (including nested)
    • Witness summoning with dependency trees
    • WitnessResolutionException on failures
    • Context-based witness provision
    • Map dependencies test
  • All 54 tests passing
  • Code formatting with google-java-format verified
  • Address PR feedback: replaced custom TypeToken with Ty from api package
  • Address PR feedback: use assertEquals instead of instanceof pattern matching
  • Address PR feedback: use custom test type classes instead of library classes for test isolation
  • Address PR feedback: simplify FuncType assertions with direct assertEquals
  • Address PR feedback: add test for generic methods with type parameters
  • Address PR feedback: remove format tests (debugging behavior)
  • Address PR feedback: switch to AssertJ assertions (version 3.27.3) for more fluent and readable test code
  • Address PR feedback: add test cases for type variables and wildcard types in ParsedTypeTest
  • Address PR feedback: add test cases where type variable is within type application nodes in UnificationTest
  • Address PR feedback: inline variables in UnificationTest that aren't reused in assertions or expected values
  • Address PR feedback: inline expected variables and import ParsedType subtypes in FuncTypeTest
  • Address PR feedback: import ParsedType subtypes in ParsedTypeTest and UnificationTest for cleaner code
  • Address PR feedback: replace wildcard imports with explicit imports (assertThat, assertThatThrownBy)
  • Address PR feedback: inline ALL variables in ParsedTypeTest (only keeping tv where reused in assertions)
Original prompt

This section details on the original issue you should resolve

<issue_title>Write tests</issue_title>
<issue_description>I would hold back from writing unit tests on individual implementation classes for now, as the structure is subject to change.

Maybe except for ParsedType, FuncType, and Unification. Those seem quite stable. So we can write unit tests for those.

We can just test TypeClasses.witness() directly and verify all of its behaviors:

  • For a witness type C<T1, T2, ..., Tn>, it looks up for witness constructors in C and T1, T2, ..., Tn.
    • I think here ConstructorLookup#findRules is too lenient and we recurse further into the type arguments of T_i, which I think we shouldn't.
  • Witness constructors for a type T are its public static methods annotated with @TypeClass.Witness.
  • For a witness constructor C<T> ctor(D1, D2, ..., Dn), the witness dependencies D1, D2, ..., Dn are resolved recursively.
  • Overlapping instances behavior per this spec, except for the incoherent instances part.
  • Resolution fails when multiple witness constructors exist for some C<T>, after applying overlapping instances reduction.
  • Resolution fails when a witness constructor for a witness type C<T> cannot be found.
  • Witness summoning is the result of recursively invoking witness constructors up their respective dependency trees.
  • T TypeClasses.witness(Ty<T>) summons a witness of type T or fails with a runtime exception of type TypeClasses.WitnessResolutionException.

There may be more to it, but that's what I can spec out for now.</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI self-assigned this Dec 14, 2025
Copilot AI and others added 3 commits December 14, 2025 08:20
Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>
Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>
Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>
Comment thread src/test/java/com/garciat/typeclasses/impl/ParsedTypeTest.java Outdated
Comment thread src/test/java/com/garciat/typeclasses/impl/UnificationTest.java Outdated
Copilot AI changed the title [WIP] Write unit tests for witness type behaviors Add test coverage for TypeClasses witness resolution Dec 14, 2025
Copilot AI requested a review from Garciat December 14, 2025 08:30
Comment thread src/test/java/com/garciat/typeclasses/TypeClassesTest.java Outdated
Comment thread src/test/java/com/garciat/typeclasses/impl/FuncTypeTest.java Outdated
Comment thread src/test/java/com/garciat/typeclasses/impl/FuncTypeTest.java
Comment thread src/test/java/com/garciat/typeclasses/impl/ParsedTypeTest.java Outdated
…Maybe types

Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>
…assertions, add generic method test, remove format tests

Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>
@Garciat

Garciat commented Dec 14, 2025

Copy link
Copy Markdown
Owner

@copilot let's switch assertions to use AssertJ assertions like assertThat(...).isEqualTo(...). Feel free to add the library dependency to the pom file (use the latest version).

Comment thread src/test/java/com/garciat/typeclasses/impl/ParsedTypeTest.java
Comment thread src/test/java/com/garciat/typeclasses/impl/UnificationTest.java
Comment thread src/test/java/com/garciat/typeclasses/impl/UnificationTest.java
Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>

Copilot AI commented Dec 14, 2025

Copy link
Copy Markdown
Contributor Author

@copilot let's switch assertions to use AssertJ assertions like assertThat(...).isEqualTo(...). Feel free to add the library dependency to the pom file (use the latest version).

Done! Switched all test assertions to use AssertJ with the latest version (3.27.3). All assertions now use assertThat(...).isEqualTo(...), assertThat(...).isNotNull(), assertThat(...).isTrue(), assertThat(...).isFalse(), and assertThatThrownBy(...).isInstanceOf(...) patterns in commit 69e136b.

…variables in UnificationTest

Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>
Comment thread src/test/java/com/garciat/typeclasses/impl/FuncTypeTest.java
Comment thread src/test/java/com/garciat/typeclasses/impl/ParsedTypeTest.java
Comment thread src/test/java/com/garciat/typeclasses/impl/UnificationTest.java
Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>
@Garciat Garciat marked this pull request as ready for review December 14, 2025 10:54
Copilot AI requested a review from Garciat December 14, 2025 10:54
@Garciat

Garciat commented Dec 14, 2025

Copy link
Copy Markdown
Owner

@copilot finally, let's avoid wildcard imports. Use only explicit imports. By the way, why isn't fmt-maven-plugin + google-java-format catching this? If you can find a way to fix this, please propose it here but don't apply it yet.

Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>
Comment thread src/test/java/com/garciat/typeclasses/impl/ParsedTypeTest.java
…riables in ParsedTypeTest

Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>

Copilot AI commented Dec 14, 2025

Copy link
Copy Markdown
Contributor Author

@copilot finally, let's avoid wildcard imports. Use only explicit imports. By the way, why isn't fmt-maven-plugin + google-java-format catching this? If you can find a way to fix this, please prop...

Done! Replaced wildcard imports (import static org.assertj.core.api.Assertions.*;) with explicit imports (assertThat, assertThatThrownBy) in all test files in commit 43a45e3.

Regarding why fmt-maven-plugin + google-java-format isn't catching this: google-java-format focuses on code formatting (whitespace, indentation, line breaks) rather than code style rules like import organization. It doesn't enforce rules about wildcard vs explicit imports.

To enforce this rule, you could:

  1. Use Checkstyle with the AvoidStarImport check
  2. Use Error Prone with the appropriate checks
  3. Configure your IDE to organize imports without wildcards and enforce via CI

Example Checkstyle configuration:

<module name="AvoidStarImport">
  <property name="allowStaticMemberImports" value="false"/>
</module>

@Garciat

Garciat commented Dec 14, 2025

Copy link
Copy Markdown
Owner

@copilot cool, could you create a new PR where you figure out those static checks? Prefer Error Prone as that seems more advanced and flexible. Along the way, also add NullAway checking.

…edType, types, fieldType)

Co-authored-by: Garciat <118277+Garciat@users.noreply.github.com>
@Garciat Garciat merged commit ffbd130 into main Dec 14, 2025
2 checks passed
@Garciat Garciat deleted the copilot/write-tests-for-type-classes branch December 14, 2025 11:20
Copilot AI requested a review from Garciat December 14, 2025 11:21
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 this pull request may close these issues.

Write tests

2 participants