package laws
The laws package provides functionality for describing laws as values. The
fundamental abstraction is a set of ZLaws[Caps, R]. These laws model the
laws that instances having a capability of type Caps are expected to
satisfy. A capability Caps[_] is an abstraction describing some
functionality that is common across different data types and obeys certain
laws. For example, we can model the capability of two values of a type being
compared for equality as follows:
trait Equal[-A] { def equal(a1: A, a2: A): Boolean }
Definitions of equality are expected to obey certain laws:
- Reflexivity -
a1 === a1 - Symmetry -
a1 === a2 ==> a2 === a1 - Transitivity -
(a1 === a2) && (a2 === a3) ==> (a1 === a3)
These laws define what the capabilities mean and ensure that it is safe to abstract across different instances with the same capability.
Using ZIO Test, we can represent these laws as values. To do so, we define
each law using one of the ZLaws constructors. For example:
val transitivityLaw = ZLaws.Laws3[Equal]("transitivityLaw") { def apply[A: Equal](a1: A, a2: A, a3: A): TestResult = ??? }
We can then combine laws using the + operator:
val reflexivityLaw: = ??? val symmetryLaw: = ??? val equalLaws = reflexivityLaw + symmetryLaw + transitivityLaw
Laws have a run method that takes a generator of values of type A and
checks that those values satisfy the laws. In addition, objects can extend
ZLawful to provide an even more convenient syntax for users to check that
instances satisfy certain laws.
object Equal extends Lawful[Equal] object Hash extends Lawful[Hash] object Ord extends Lawful[Ord] checkAllLaws(Equal + Hash + Ord)(Gen.int)
Note that capabilities compose seamlessly because of contravariance. We can combine laws describing different capabilities to construct a set of laws requiring that instances having all of the capabilities satisfy each of the laws.
- Alphabetic
- By Inheritance
- laws
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Type Members
- trait GenF[-R, F[_]] extends AnyRef
A
GenFknows how to construct a generator ofF[A]values given a generator ofAvalues for anyA.A
GenFknows how to construct a generator ofF[A]values given a generator ofAvalues for anyA. For example, aGenFofListvalues knows how to generate lists with elements given a generator of elements of that type. You can think ofGenFas a "recipe" for building generators for parameterized types. - trait GenF2[-R, F[_, _]] extends AnyRef
A
GenFknows how to construct a generator ofF[A,B]values given a generator ofAand generator ofBvalues.A
GenFknows how to construct a generator ofF[A,B]values given a generator ofAand generator ofBvalues. For example, aGenF2ofFunction1values knows how to generate functions A => B with elements given a generator of elements of that typeB. - type Lawful[-Caps[_]] = ZLawful[Caps, Any]
- type Lawful2[-CapsBoth[_, _], -CapsLeft[_], -CapsRight[_]] = ZLawful2[CapsBoth, CapsLeft, CapsRight, Any]
- type Laws[-Caps[_]] = ZLaws[Caps, Any]
- type Laws2[-CapsBoth[_, _], -CapsLeft[_], -CapsRight[_]] = ZLaws2[CapsBoth, CapsLeft, CapsRight, Any]
- trait ZLawful[-Caps[_], -R] extends AnyRef
ZLawful[Caps, R]describes a capability that is expected to satisfy a set of laws.ZLawful[Caps, R]describes a capability that is expected to satisfy a set of laws. Lawful instances can be combined using+to describe a set of capabilities and all of the laws that those capabilities are expected to satisfy.trait Equal[-A] { def equal(a1: A, a2: A): Boolean } object Equal extends Lawful[Equal] { val laws = ??? }
- trait ZLawful2[-CapsBoth[_, _], -CapsLeft[_], -CapsRight[_], -R] extends AnyRef
- abstract class ZLaws[-Caps[_], -R] extends AnyRef
ZLaws[Caps, R]represents a set of laws that values with capabilitiesCapsare expected to satisfy.ZLaws[Caps, R]represents a set of laws that values with capabilitiesCapsare expected to satisfy. Laws can be run by providing a generator of values of a typeAwith the required capabilities to return a test result. Laws can be combined using+to produce a set of laws that require both sets of laws to be satisfied. - abstract class ZLaws2[-CapsBoth[_, _], -CapsLeft[_], -CapsRight[_], -R] extends AnyRef
Value Members
- def checkAllLaws[CapsF[_[_]], Caps[_], R, R1 <: R, F[_], A](lawful: Invariant[CapsF, Caps, R])(genF: GenF[R1, F], gen: Gen[R1, A])(implicit arg0: CapsF[F], arg1: Caps[A], trace: Trace): ZIO[R1, Nothing, TestResult]
Checks that all values generated by a the specified generator satisfy the expected behavior of the lawful instance.
- def checkAllLaws[CapsF[_[-_]], Caps[_], R, R1 <: R, F[-_], A](lawful: Contravariant[CapsF, Caps, R])(genF: GenF[R1, F], gen: Gen[R1, A])(implicit arg0: CapsF[F], arg1: Caps[A], trace: Trace): ZIO[R1, Nothing, TestResult]
Checks that all values generated by a the specified generator satisfy the expected behavior of the lawful instance.
- def checkAllLaws[CapsF[_[+_]], Caps[_], R, R1 <: R, F[+_], A](lawful: Covariant[CapsF, Caps, R])(genF: GenF[R1, F], gen: Gen[R1, A])(implicit arg0: CapsF[F], arg1: Caps[A], trace: Trace): ZIO[R1, Nothing, TestResult]
- def checkAllLaws[CapsBoth[_, _], CapsLeft[_], CapsRight[_], R, R1 <: R, A, B](lawful: ZLawful2[CapsBoth, CapsLeft, CapsRight, R])(a: Gen[R1, A], b: Gen[R1, B])(implicit arg0: CapsLeft[A], arg1: CapsRight[B], CapsBoth: CapsBoth[A, B], trace: Trace): ZIO[R1, Nothing, TestResult]
Checks that all values generated by a the specified generator satisfy the expected behavior of the lawful instance.
- def checkAllLaws[Caps[_], R, R1 <: R, A](lawful: ZLawful[Caps, R])(gen: Gen[R1, A])(implicit arg0: Caps[A], trace: Trace): ZIO[R1, Nothing, TestResult]
Checks that all values generated by a the specified generator satisfy the expected behavior of the lawful instance.
- object GenF
- object GenF2 extends FunctionVariants
- object LawfulF
- object LawfulF2
- object Laws
- object Laws2
- object LawsF
- object LawsF2
- object ZLawfulF
ZLawfulF[CapsF, Caps, R]describes a set of laws that a parameterized typeF[A]with capabilitiesCapsFis expected to satisfy with respect to all typesAthat have capabilitiesCaps.ZLawfulF[CapsF, Caps, R]describes a set of laws that a parameterized typeF[A]with capabilitiesCapsFis expected to satisfy with respect to all typesAthat have capabilitiesCaps. Lawful instances can be combined using+to describe a set of capabilities and all of the laws that those capabilities are expected to satisfy. - object ZLawfulF2
- object ZLaws
- object ZLaws2
- object ZLawsF
ZLaws[CapsF, Caps, R]describes a set of laws that a parameterized typeF[A]with capabilitiesCapsFis expected to satisfy with respect to all typesAthat have capabilitiesCaps.ZLaws[CapsF, Caps, R]describes a set of laws that a parameterized typeF[A]with capabilitiesCapsFis expected to satisfy with respect to all typesAthat have capabilitiesCaps. Laws can be run by providing aGenFthat is capable of generatingF[A]values given a generator ofAvalues and a generator of values of some typeA. Laws can be combined using+to produce a set of laws that require both sets of laws to be satisfied. - object ZLawsF2