sageserpent-open / americium

Generation of test case data for Scala and Java, in the spirit of QuickCheck. When your test fails, it gives you a minimised failing test case and a way of reproducing the failure immediately.
MIT License
15 stars 1 forks source link

Annoying type signatures for `.sets`, `.maps` etc. #61

Closed sageserpent-open closed 1 year ago

sageserpent-open commented 1 year ago

As of 1.12.0, Trials has the following methods for building trials of sets and maps:

  def sets: Trials[Set[_ <: Case]]

  def sortedSets(implicit
      ordering: Ordering[_ >: Case]
  ): Trials[SortedSet[_ <: Case]]

  def maps[Value](values: Trials[Value]): Trials[Map[_ <: Case, Value]]

  def sortedMaps[Value](values: Trials[Value])(implicit
      ordering: Ordering[_ >: Case]
  ): Trials[SortedMap[_ <: Case, Value]]

I can't remember now just why the wildcard types were thought necessary, other than that this may have been forced due to the odd lack of covariance in the Scala Set and Map classes - or was it to work with the Java API?

Whatever the reason - it is annoying having to workaround the wildcard types, either by propagating them around test code, or doing .asInstanceOf to cast to the real type.

Worth a spike to see what the problem was and if it can be sorted out...

sageserpent-open commented 1 year ago

Spike tried - have cutover Trials.sets/sortedSets/maps/sortedMaps in the Scala API.

Tests pass, and tried a client project against a snapshot version of Americium ...

Screenshot 2023-06-16 at 16 04 42

Works nicely, generating the correct test cases.

Delivering this as-is for the next release, 1.13.0 .

sageserpent-open commented 1 year ago

The new API looks like this:

  def sets[CovarianceFudge >: Case]: Trials[Set[CovarianceFudge]]

  def sortedSets[CovarianceFudge >: Case](implicit
      ordering: Ordering[CovarianceFudge]
  ): Trials[SortedSet[CovarianceFudge]]

  def maps[CovarianceFudge >: Case, Value](values: Trials[Value]): Trials[Map[CovarianceFudge, Value]]

  def sortedMaps[CovarianceFudge >: Case, Value](values: Trials[Value])(implicit
      ordering: Ordering[CovarianceFudge]
  ): Trials[SortedMap[CovarianceFudge, Value]]

The idea is not to specify the type parameter CovarianceFudge - it will be inferred to be Case, which is what the client code wants, but having the type bound CovarianceFudge >: Case sidesteps the problem that was being worked around in the past - namely that Set and Map are invariant in the key type parameter, but Trials is covariant in its Case type parameter.

This has gone out in release 1.13.0, Git commit SHA 1ffdf8c6fc79c46ab3e0607e5225dc6dd27a4b3c.

sageserpent-open commented 1 year ago

There is a similar problem in getting the Java form of the API from a Scala Trials via Trials.javaApi. May as well fix that under this ticket as well...

sageserpent-open commented 1 year ago

The fix went out in release 1.13.1, Git commit SHA 24ac99e1b9ee98ae4f6bb0d5b40016a7e1f1519e.