-
Notifications
You must be signed in to change notification settings - Fork 129
Metaconstants as partial packets of values
This feature is experimental, starting in 1.3-alpha1.
You can instruct Midje to treat metaconstants like maps or records.
##Short version
Metaconstants can be made to include key/value pairs:
(fact
(fullname ...person...) => "Brian Marick"
(provided
...person... =contains=> {:given "Brian", :family "Marick"}))
Metaconstants can be used as background prerequisites:
(fact "`keys`, `values`, and `contains` work on metaconstants"
(against-background ..m.. =contains=> {:a 3, :b 4})
(keys ..m..) => [:a :b]
(vals ..m..) => [3 4]
(contains? ..m.. :a) => truthy
(contains? ..m.. :c) => falsey)
##The longer version
Metaconstants are tokens that let you describe only what's important to make a particular fact
true. Most often they're used with function prerequisites:
(fact (this 1) => 2
(provided (that 1) => 3)
Languages like Ruby and Smalltalk prevent you from direct access to values in an object. Clojure allows it; indeed, it's idiomatic to use keyword access with maps and records:
user> (def mymap {:a 1})
#'user/mymap
user> (:a mymap)
1
You could declare an accessor function:
user> (def get-a :a)
#'user/get-a
user> (get-a mymap)
1
In practice, people don't. In Clojure it's idiomatic to use keyword accessors to inform humans reading the code that it's talking about simple data: no lazy getters that reach over the network or into a database to fetch or calculate a simple value. I myself lean toward the Ruby style, but Midje should support idiomatic Clojure. Therefore, you can treat a metaconstant as a collection of key/value pairs, deferring until later whether it should be a map, a defrecord
, a deftype
, etc.
Setting a metaconstants values is done in the provided clause:
(fact
(:a ..mc..) => 5
(provided ..mc.. =contains=> {:a 5}))
It's also convenient to use an against-background clause to set up a metaconstant for an entire fact
:
(fact "keys, values, and contains work on metaconstants"
(against-background ..m.. =contains=> {:a 3, :b 4})
(keys ..m..) => [:a :b]
(vals ..m..) => [3 4]
(contains? ..m.. :a) => truthy
(contains? ..m.. :c) => falsey)