Description
Currently, specs cannot compose directly, although if you have a sweet, you can combine all the children into a spec via the suite itself.
As a consequence of this design choice, it is not possible to have a binary composition operator on Spec
, which composes two specs into one.
Yet, if two specs could compose, then it would be simpler to break up mega-suites into smaller subsuites (e.g. val bigSuite = littleSweet + otherSuiite + yetAnotherSuite
), without having to unnecessarily nest them inside another suite just for purposes of composition.
In addition, if specs could compose together, then it would be possible to improve upon the syntax of test composition without MutableRunnableSpec
:
suite("LayerSpec") {
test("horizontal compose") {
} +
test ("vertical compose") {
} +
...
}
(The +
operator is a strawman proposal and anything could be chosen instead.)
This ticket is to add a binary composition operator to Spec
:
final case class Spec[-R, +E, +T](caseValue: SpecCase[R, E, T, Spec[R, E, T]]) { self =>
def + [R1 <: R, E1 >: E, T1 >: T](that: Spec[R1, E1, T1]): Spec[R1, E1, T1] = ...
}
This must be implemented by adding a new subtype to SpecCase
, which can store both left and right hand specs, and then adding support for this new subtype in all cases where SpecCase
is pattern-matched.
Possibly at the same time, we could refactor the SpecCase
type to be a bit more modular, maybe something like:
final case class LabeledCase[+Spec](label: String, spec: Spec) extends SpecCase[Any, Nothing, Nothing, Spec]
final case class MultipleCase[+Spec](specs: Vector[Spec]) extends SpecCase[Any, Nothing, Nothing, Spec]
final case class ManagedCase[-R, +E, +Self](managed: ZManaged[R, E, Nothing, Self)
extends SpecCase[R, E, Nothing, Spec]
final case class TestCase[-R, +E, +T](test: ZIO[R, E, T], annotations: TestAnnotationMap)
extends SpecCase[R, E, T, Nothing]
This way you pay for just the features you need.