Behavior Specification DSL for validation testing.
Data-first DSL for declarative validation testing with reusable scenarios. All core functions are pure; only test expansion emits side-effectful deftest forms.
Example usage:
;; Define a scenario (def email-required-scenario {:name "email-required-missing" :description "User email is required" :module :user :schema-key :User :base {:name "Test User" :email "test@example.com"} :mutations [(remove-field :email)] :action validate-user-fn :assertions [{:expect :failure :codes #{:user.email/required} :snapshot? true}]})
;; Compile to test functions (compile-scenarios [email-required-scenario] {}) ;; => [["email-required-missing" (fn [] ...)]]
;; Or use macro for deftest generation (defbehavior-suite user-validation-tests [email-required-scenario email-format-scenario])
Behavior Specification DSL for validation testing.
Data-first DSL for declarative validation testing with reusable scenarios.
All core functions are pure; only test expansion emits side-effectful deftest forms.
Example usage:
;; Define a scenario
(def email-required-scenario
{:name "email-required-missing"
:description "User email is required"
:module :user
:schema-key :User
:base {:name "Test User" :email "test@example.com"}
:mutations [(remove-field :email)]
:action validate-user-fn
:assertions [{:expect :failure
:codes #{:user.email/required}
:snapshot? true}]})
;; Compile to test functions
(compile-scenarios [email-required-scenario] {})
;; => [["email-required-missing" (fn [] ...)]]
;; Or use macro for deftest generation
(defbehavior-suite user-validation-tests
[email-required-scenario
email-format-scenario])(compile-scenarios scenarios opts)Compile scenarios into test function pairs.
Pure function that produces [test-name test-fn] pairs. Test functions perform clojure.test assertions when called.
Args: scenarios - Vector of scenario maps opts - Options map (currently unused)
Returns: Vector of [test-name test-fn] pairs.
Example: (compile-scenarios [{:name "test-1" :action ... :assertions [...]}] {}) ;; => [["test-1" (fn [] ...)]]
Compile scenarios into test function pairs.
Pure function that produces [test-name test-fn] pairs.
Test functions perform clojure.test assertions when called.
Args:
scenarios - Vector of scenario maps
opts - Options map (currently unused)
Returns:
Vector of [test-name test-fn] pairs.
Example:
(compile-scenarios [{:name "test-1" :action ... :assertions [...]}] {})
;; => [["test-1" (fn [] ...)]](defbehavior-suite suite-name scenarios)(defbehavior-suite suite-name scenarios opts)Define a test suite from behavior scenarios.
Generates a deftest for each scenario in the suite.
Args: suite-name - Symbol for the test suite name scenarios - Vector of scenario maps (evaluated) opts - Optional options map
Example: (defbehavior-suite user-validation-tests [{:name "email-required" :action validate-user :base {:name "Test"} :mutations [(remove-field :email)] :assertions [{:expect :failure :codes #{:user.email/required}}]}] {:module :user})
Define a test suite from behavior scenarios.
Generates a deftest for each scenario in the suite.
Args:
suite-name - Symbol for the test suite name
scenarios - Vector of scenario maps (evaluated)
opts - Optional options map
Example:
(defbehavior-suite user-validation-tests
[{:name "email-required"
:action validate-user
:base {:name "Test"}
:mutations [(remove-field :email)]
:assertions [{:expect :failure :codes #{:user.email/required}}]}]
{:module :user})(execute-scenario scenario _opts)Execute a scenario and return results.
Pure function that produces data describing test results. Does not perform side effects or assertions.
Args: scenario - Scenario map opts - Options (currently unused, for future extension)
Returns: Execution result map: {:scenario-name str :input data :result validation-result :assertions [{:passed? bool :message str}] :all-passed? bool}
Execute a scenario and return results.
Pure function that produces data describing test results.
Does not perform side effects or assertions.
Args:
scenario - Scenario map
opts - Options (currently unused, for future extension)
Returns:
Execution result map:
{:scenario-name str
:input data
:result validation-result
:assertions [{:passed? bool :message str}]
:all-passed? bool}(missing-required-field-template field-key rule-code base-data action-fn)Create a scenario for testing missing required field.
Args: field-key - Keyword for the field rule-code - Expected validation error code keyword base-data - Base valid data action-fn - Validation function
Returns: Scenario map.
Example: (missing-required-field-template :email :user.email/required {:name "Test" :email "test@ex.com"} validate-user)
Create a scenario for testing missing required field.
Args:
field-key - Keyword for the field
rule-code - Expected validation error code keyword
base-data - Base valid data
action-fn - Validation function
Returns:
Scenario map.
Example:
(missing-required-field-template
:email
:user.email/required
{:name "Test" :email "test@ex.com"}
validate-user)(out-of-range field-path direction boundary)Create a mutation that sets a numeric field out of range.
Args: field-path - Keyword or vector path to field direction - :above or :below boundary - The boundary value
Returns: Mutation function.
Example: ((out-of-range :age :below 18) {:age 25}) ;; => {:age 17}
Create a mutation that sets a numeric field out of range.
Args:
field-path - Keyword or vector path to field
direction - :above or :below
boundary - The boundary value
Returns:
Mutation function.
Example:
((out-of-range :age :below 18) {:age 25})
;; => {:age 17}(remove-field field-path)Create a mutation that removes a field from the data.
Args: field-path - Keyword or vector path to field
Returns: Mutation function.
Example: ((remove-field :email) {:name "Test" :email "test@ex.com"}) ;; => {:name "Test"}
((remove-field [:address :city]) {:address {:city "NY" :zip "10001"}}) ;; => {:address {:zip "10001"}}
Create a mutation that removes a field from the data.
Args:
field-path - Keyword or vector path to field
Returns:
Mutation function.
Example:
((remove-field :email) {:name "Test" :email "test@ex.com"})
;; => {:name "Test"}
((remove-field [:address :city]) {:address {:city "NY" :zip "10001"}})
;; => {:address {:zip "10001"}}(replace-type field-path wrong-type)Create a mutation that replaces a field with wrong type.
Args: field-path - Keyword or vector path to field wrong-type - Keyword indicating wrong type (:string, :number, :map, :vector, :boolean)
Returns: Mutation function.
Example: ((replace-type :age :string) {:age 25}) ;; => {:age "not-a-number"}
Create a mutation that replaces a field with wrong type.
Args:
field-path - Keyword or vector path to field
wrong-type - Keyword indicating wrong type (:string, :number, :map, :vector, :boolean)
Returns:
Mutation function.
Example:
((replace-type :age :string) {:age 25})
;; => {:age "not-a-number"}(set-field field-path value)Create a mutation that sets a field to a specific value.
Args: field-path - Keyword or vector path to field value - Value to set
Returns: Mutation function.
Example: ((set-field :email "invalid") {:name "Test" :email "valid@ex.com"}) ;; => {:name "Test" :email "invalid"}
Create a mutation that sets a field to a specific value.
Args:
field-path - Keyword or vector path to field
value - Value to set
Returns:
Mutation function.
Example:
((set-field :email "invalid") {:name "Test" :email "valid@ex.com"})
;; => {:name "Test" :email "invalid"}(valid-data-template name base-data action-fn)Create a scenario for testing valid data.
Args: name - Scenario name base-data - Valid data action-fn - Validation function
Returns: Scenario map.
Create a scenario for testing valid data. Args: name - Scenario name base-data - Valid data action-fn - Validation function Returns: Scenario map.
(wrong-format-template field-key rule-code invalid-val base-data action-fn)Create a scenario for testing wrong format.
Args: field-key - Keyword for the field rule-code - Expected validation error code keyword invalid-val - Invalid value for the field base-data - Base valid data action-fn - Validation function
Returns: Scenario map.
Create a scenario for testing wrong format. Args: field-key - Keyword for the field rule-code - Expected validation error code keyword invalid-val - Invalid value for the field base-data - Base valid data action-fn - Validation function Returns: Scenario map.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |