Liking cljdoc? Tell your friends :D

hive-cppb.test

Reusable property-based test scaffolding for CPPB roles.

These helpers consume the :cppb/role metadata stamped onto vars by defcollector / defpromoter / defpipeline / defboundary (see hive-cppb.core) and produce clojure.test assertions that exercise the canonical laws each role is expected to obey.

Helpers are designed to be called from a caller's own test ns:

(require '[hive-cppb.test :as cppb-test]) (require '[clojure.test.check.generators :as gen])

(deftest add-totals-laws (cppb-test/promoter-laws #'add-totals (gen/hash-map :fetch-numbers (gen/vector gen/small-integer))))

Each helper is a regular function that runs clojure.test/is assertions inline, so it can be dropped into any deftest. They throw via the underlying assertion machinery if a law is violated.

Laws codify the CPPB principle: pure data flow with effects pushed to the boundary.

Reusable property-based test scaffolding for CPPB roles.

These helpers consume the `:cppb/role` metadata stamped onto vars by
`defcollector` / `defpromoter` / `defpipeline` / `defboundary` (see
`hive-cppb.core`) and produce `clojure.test` assertions that
exercise the canonical laws each role is expected to obey.

Helpers are designed to be called from a caller's own test ns:

  (require '[hive-cppb.test :as cppb-test])
  (require '[clojure.test.check.generators :as gen])

  (deftest add-totals-laws
    (cppb-test/promoter-laws #'add-totals
      (gen/hash-map :fetch-numbers (gen/vector gen/small-integer))))

Each helper is a regular function that runs `clojure.test/is` assertions
inline, so it can be dropped into any `deftest`. They throw via the
underlying assertion machinery if a law is violated.

Laws codify the CPPB principle: pure data flow with effects pushed to
the boundary.
raw docstring

boundary-contractclj

(boundary-contract boundary-var
                   &
                   {:keys [ok-gen err-gen num-tests]
                    :or {ok-gen gen/any-printable-equatable
                         err-gen (gen/map gen/keyword gen/small-integer)
                         num-tests default-num-tests}})

Assert the contract of a CPPB boundary.

Args: boundary-var — a var #'foo where foo was defined via defboundary

Options: :ok-gen — generator producing values to wrap in (r/ok ...) (default any) :err-gen — generator producing data maps for (r/err :test/x data) (default a small map) :num-tests — how many random inputs to sample (default 50)

Contract asserted:

  1. Boundary handles (r/ok value) without throwing.
  2. Boundary handles (r/err category data) without throwing.
  3. Boundary throws ex-info for non-Result inputs (defboundary's :else branch). We assert the throw and that the ex-data carries :cppb/role :boundary so callers can recognise it.
Assert the contract of a CPPB boundary.

Args:
  boundary-var  — a var #'foo where foo was defined via defboundary

Options:
  :ok-gen   — generator producing values to wrap in (r/ok ...) (default any)
  :err-gen  — generator producing data maps for (r/err :test/x data)
              (default a small map)
  :num-tests — how many random inputs to sample (default 50)

Contract asserted:

1. Boundary handles `(r/ok value)` without throwing.
2. Boundary handles `(r/err category data)` without throwing.
3. Boundary throws `ex-info` for non-Result inputs (defboundary's :else
   branch). We assert the throw and that the ex-data carries
   `:cppb/role :boundary` so callers can recognise it.
sourceraw docstring

pipeline-shapeclj

(pipeline-shape pipeline-var
                seed-gen
                &
                {:keys [num-tests] :or {num-tests default-num-tests}})

Assert structural laws of a CPPB pipeline.

Args: pipeline-var — a var #'foo where foo was defined via defpipeline seed-gen — a test.check generator producing seed inputs

Options: :num-tests — how many random seeds to sample (default 50)

Laws asserted:

  1. Result-shape: pipeline returns a hive-dsl Result for any seed.
  2. Determinism: same seed → same Result (assumes underlying collectors and promoters are pure, per CPPB invariant).

Short-circuit-on-error law (NOT asserted here — needs DI):

Asserting that the pipeline aborts on the first failing collector requires injecting a stub collector into the pipeline definition, which the current defpipeline does not support (collectors are resolved as closed-over symbols at macro-expansion time). The smoke test in core_test.clj covers this with hand-written failing fixtures.

Assert structural laws of a CPPB pipeline.

Args:
  pipeline-var — a var #'foo where foo was defined via defpipeline
  seed-gen     — a test.check generator producing seed inputs

Options:
  :num-tests — how many random seeds to sample (default 50)

Laws asserted:

1. Result-shape: pipeline returns a hive-dsl Result for any seed.
2. Determinism: same seed → same Result (assumes underlying collectors
   and promoters are pure, per CPPB invariant).

Short-circuit-on-error law (NOT asserted here — needs DI):

Asserting that the pipeline aborts on the *first* failing collector
requires injecting a stub collector into the pipeline definition, which
the current `defpipeline` does not support (collectors are resolved as
closed-over symbols at macro-expansion time). The smoke test in
`core_test.clj` covers this with hand-written failing fixtures.
sourceraw docstring

promoter-lawsclj

(promoter-laws promoter-var
               input-gen
               &
               {:keys [num-tests idempotent?]
                :or {num-tests default-num-tests}})

Assert the canonical laws of a CPPB promoter via property-based tests.

Args: promoter-var — a var #'foo where foo was defined via defpromoter input-gen — a test.check generator producing data values that the promoter accepts (i.e. the unwrapped accumulator map)

Options (kw-args, all optional): :num-tests — how many random inputs to sample (default 50) :idempotent? — if truthy (or if the var carries :cppb/idempotent metadata), assert (promoter (promoter data)) ≡ (promoter data) when both calls are :ok

Laws asserted:

  1. Result-shape: promoter always returns a hive-dsl Result.
  2. Determinism (purity): same input → same output across two invocations. Promoters are required by CPPB to be pure, so this is unconditional.
  3. Idempotence (opt-in): when enabled, applying the promoter to its own output yields the same Result.

Identity-on-err law (caller responsibility): when the pipeline sees an err Result it short-circuits before reaching the next promoter. Promoters themselves never receive err input, so we deliberately do not test that here — it is enforced by r/bind in defpipeline's expansion.

Assert the canonical laws of a CPPB promoter via property-based tests.

Args:
  promoter-var  — a var #'foo where foo was defined via defpromoter
  input-gen     — a test.check generator producing `data` values that the
                  promoter accepts (i.e. the unwrapped accumulator map)

Options (kw-args, all optional):
  :num-tests   — how many random inputs to sample (default 50)
  :idempotent? — if truthy (or if the var carries `:cppb/idempotent`
                 metadata), assert (promoter (promoter data)) ≡
                 (promoter data) when both calls are :ok

Laws asserted:

1. Result-shape: promoter always returns a hive-dsl Result.
2. Determinism (purity): same input → same output across two invocations.
   Promoters are required by CPPB to be pure, so this is unconditional.
3. Idempotence (opt-in): when enabled, applying the promoter to its own
   output yields the same Result.

Identity-on-err law (caller responsibility): when the *pipeline* sees an
err Result it short-circuits before reaching the next promoter. Promoters
themselves never receive err input, so we deliberately do not test that
here — it is enforced by `r/bind` in `defpipeline`'s expansion.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close