Do notation pipes for functions which easy to mock
Inspired by fp-ts/Effect bind Do-notation, but much more small and simple
Primarly created for easy mocking of functions, which allows to write tons of unit tests
gleam add klubok_gleam
import gleam/option.{None, Some}
import gleam/set
import klubok_gleam.{use_klubok2, eff}
type Cat {
Cat(name: String, age: Int)
}
fn cat_birthday(mock, only) {
// Make this function pipable
// Need to use correct arity by count of `eff` usage, 2 in this example
use <- use_klubok2(mock, only)
// This function mockable
use cat <- eff(fn() {
// some IO implementation which fetching cat
Cat("Barsik", 5)
})
// This function mockable
use aged_cat <- eff(fn() { Cat(..cat, age: cat.age + 1) })
aged_cat
}
pub fn main() {
// Pass Option.None to mock and only
// Should be used on production code
cat_birthday(None, None) // Cat("Barsik", 6)
// Mock first `eff` with another hardcoded cat
// Should be used in unit tests
cat_birthday(#(fn() { Cat("Marfa", 10) } |> Some, None) |> Some, None) // Cat("Marfa", 11)
// Call only second `eff` and first IO ignored
// Also our birthday fn is mocked and our cat is kiten again
//❗`only` is type unsafe and can lead to runtime errors when `Nil` passed instead of actual `eff` value
cat_birthday(
#(None, fn() { Cat("Barsik", 1) } |> Some) |> Some,
set.from_list([1]) |> Some
) // Cat("Barsik", 1)
}
Further documentation can be found at https://hexdocs.pm/klubok_gleam.
gleam run # Run the project
gleam test # Run the tests
- Klubok - TS implementation of Klubok