effect-ts-laws
v1.1.18
Published
Law testing using fast-check.
Downloads
260
Maintainers
Readme
A library for testing effect-ts typeclass laws using fast-check. API is documented here, and the laws are listed here.
About
Synopsis
Run all typeclass law tests relevant to the effect-ts Option
datatype:
import {Alternative, Applicative, getOptionalMonoid, Monad, Traversable} from '@effect/typeclass/data/Option'
import {Option as OP} from 'effect'
import {monoEquivalence, monoOrder, monoSemigroup, option} from 'effect-ts-laws'
import {testTypeclassLaws} from 'effect-ts-laws/vitest'
import {OptionTypeLambda} from 'effect/Option'
describe('@effect/typeclass/data/Option', () => {
testTypeclassLaws<OptionTypeLambda>({
getEquivalence: OP.getEquivalence,
getArbitrary: option,
})({
Alternative,
Applicative,
Equivalence: OP.getEquivalence(monoEquivalence),
Monad,
Monoid: getOptionalMonoid(monoSemigroup),
Order: OP.getOrder(monoOrder),
Traversable,
})
})
Vitest reporter shows test results for the Option
datatype:
You wrote a new datatype: MyTuple
, and an instance of the effect-ts
Covariant
typeclass. Lets test it for free:
import {Covariant as CO} from '@effect/typeclass'
import {Array as AR} from 'effect'
import {dual} from 'effect/Function'
import {TypeLambda} from 'effect/HKT'
import fc from 'fast-check'
import {testTypeclassLaws} from 'effect-ts-laws/vitest'
describe('MyTuple', () => {
type MyTuple<A> = [A]
interface MyTupleTypeLambda extends TypeLambda {
readonly type: MyTuple<this['Target']>
}
const map: CO.Covariant<MyTupleTypeLambda>['map'] = dual(
2,
<A, B>([a]: MyTuple<A>, ab: (a: A) => B): MyTuple<B> => [ab(a)],
)
const Covariant: CO.Covariant<MyTupleTypeLambda> = {
imap: CO.imap<MyTupleTypeLambda>(map),
map,
}
testTypeclassLaws<MyTupleTypeLambda>({
getEquivalence: AR.getEquivalence,
getArbitrary: fc.tuple,
})({Covariant})
})
fast-check
will try to find a counter example that breaks the laws. Because
it is quite impossible to find one in this case you should see:
Overview
Law testing is useful when you are building your own datatype and its
associated effect-ts
instances. Law tests help you verify your instances are
lawful. This is a library of the effect-ts
typeclass laws, and some law
testing infrastructure.
The implementation features:
effect-ts
datatype typeclass law tests. Because:- It could help
effect-ts
. - Serves as an excellent self-test suite and as an example for testing your own instances.
- See status for details on what is ready.
- It could help
- Randomness. Uses
fast-check
property testing. For parameterized type typeclass laws, all functions are randomly generated as well. - Minimal work to test instances for your own datatype: it can all be
done with single function that takes the instances under test and
a pair of functions:
getEquivalence
andgetArbitrary
.- Meaningful test coverage improvement for the price of writing two functions. You probably have them somewhere already.
Usage
To install, replace pnpm
with your package manager:
# Peer dependencies:
pnpm i effect-ts @effect/typeclass
pnpm i -D vitest fast-check @fast-check/vitest
# Install effect-ts-laws
pnpm i -D effect-ts-laws
API is documented here.
Project
Status
Matrix showing data-types (in columns) vs. typeclass law tests (in rows).
Each intersection of datatype and typeclass can be either:
ready (✅), not ready (❌), or not relevant (☐). First data row
show the typeclass laws implementation status, and first data column shows
datatype tests implementation status. Note Equivalence
and Order
are
both typeclasses and datatypes. You can also view this in an online
spreadsheet.
| | | Typeclass→ | | Equivalence | Order | Bounded | Semigroup | Monoid | Invariant | Contravariant | Covariant | SemiAlternative | Alternative | Applicative | Monad | Bicovariant | Traversable | Foldable | | --- | -------------------------------------------------- | ---------- | --- | ----------------------------------------------------------- | ----------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------ | ---------------------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- | -------- | | | | | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | | | | | | | | | | | | | | | | | | | | | | ↓Datatype | | | | | | | | | | | | | | | | | | | 1. | Array | ✅ | | ✅ | ✅ | ☐ | ✅ | ✅ | ✅ | ☐ | ✅ | ☐ | ☐ | ✅ | ✅ | ☐ | ✅ | ❌ | | 2. | BigDecimal | ✅ | | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 3. | BigInt | ✅ | | ✅ | ✅ | ☐ | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 4. | Boolean | ✅ | | ✅ | ✅ | ☐ | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 5. | Cause | ✅ | | ☐ | ☐ | ☐ | ☐ | ☐ | ✅ | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 6. | DateTime | ✅ | | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 7. | Duration | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 8. | Effect | ❌ | | ❌ | ❌ | ☐ | ❌ | ❌ | ❌ | ☐ | ❌ | ☐ | ☐ | ❌ | ❌ | ☐ | ❌ | ❌ | | 9. | Either | ✅ | | ✅ | ☐ | ☐ | ☐ | ☐ | ✅ | ☐ | ✅ | ✅ | ☐ | ✅ | ✅ | ✅ | ✅ | ❌ | | 10. | Equivalence | ❌ | | ☐ | ☐ | ☐ | ☐ | ☐ | ❌ | ❌ | ❌ | ☐ | ☐ | ❌ | ❌ | ☐ | ❌ | ❌ | | 11. | Identity | ✅ | | ☐ | ☐ | ☐ | ☐ | ☐ | ✅ | ☐ | ✅ | ☐ | ☐ | ✅ | ✅ | ☐ | ✅ | ❌ | | 12. | List | ✅ | | ✅ | ❌ | ☐ | ❌ | ❌ | ✅ | ☐ | ✅ | ☐ | ☐ | ❌ | ✅ | ☐ | ❌ | ❌ | | 13. | Number | ✅ | | ✅ | ✅ | ☐ | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 14. | Option | ✅ | | ✅ | ✅ | ☐ | ✅ | ✅ | ✅ | ☐ | ✅ | ✅ | ✅ | ✅ | ✅ | ☐ | ✅ | ❌ | | 15. | Order | ❌ | | ☐ | ☐ | ☐ | ☐ | ☐ | ❌ | ❌ | ❌ | ☐ | ☐ | ❌ | ❌ | ☐ | ❌ | ❌ | | 16. | Predicate | ✅ | | ☐ | ☐ | ☐ | ✅ | ✅ | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 17. | Record | ✅ | | ✅ | ☐ | ☐ | ☐ | ☐ | ✅ | ☐ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ✅ | ☐ | | 18. | String | ✅ | | ✅ | ✅ | ☐ | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 19. | Struct | ✅ | | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | | 20. | Tuple | ✅ | | ✅ | ✅ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ☐ | ✅ | ☐ | ☐ |
More Information
- API documentation.
- Catalog of laws.
README
for the arbitraries included.README
at the laws for typeclasses on concrete types.README
at the laws for typeclasses on parameterized types.README
at the typeclass laws self-tests.
Open Questions
- Rename to zio-style names? E.g.:
traverse
laws becomeforeach
laws? - Match the typeclass graph of effect-ts more accurately? E.g.: split
Product
laws out ofApplicative
. - What is the role of typeclass laws in
effect-ts
where typeclasses are deemphasized?
Roadmap
Tests
- [ ] More datatypes.
- [ ] Bicovariant should do Invariant laws twice.
- [ ] Schema decode/encode laws
- [ ] Sink Contravariant laws
Harness
- [ ] API should let you use any catalog
Composition
- [ ] Test composition flipped.
- [ ] Compose arbitrary instances in composition tests.
- [ ] Nest three levels.
- [ ] Brand composition: refine(b₂) ∘ refine(b₁) = refine.all(b₁, b₂).
Arbitraries
- [ ]
oneof
arbitrary chosen from built-in instances.
- [ ]
See Also
Based On
- fp-ts-laws by Giulio Canti
- Scala's Discipline