Write generalized spec generation macro
This add `gen-spec` which provides a fairly general macro for creating `test.check` specifications for vector instructions. It takes a string used to generate specification names, a function used to check the state after running the function under test, and a list of keywords indicating types for arguments generated by `test.check` and passed to the check function. Keywords like `:integer` and `:string` are associated with "simple" generators such as `gen/small-integer` and `gen/string`. The keyword `:vector` is used to generate a vector of items whose type is specified by the `generator` argument to `generator-for-arg-type`. This allows us to loop over all of the supported vector item types in the macro and generate a separate specification for each type. We moved the `value-type` argument for the `check` functions to the front to simplify passing in the value type arguments, which can vary in number.
This commit is contained in:
parent
b41c35582a
commit
d30f7c195e
@ -190,7 +190,7 @@
|
|||||||
The order of concatenation is that the top of the stack will be
|
The order of concatenation is that the top of the stack will be
|
||||||
_second_ in the concatenation, i.e., its elements will come _after_
|
_second_ in the concatenation, i.e., its elements will come _after_
|
||||||
the elements in the vector one below it in the stack."
|
the elements in the vector one below it in the stack."
|
||||||
[first-vect second-vect value-type]
|
[value-type first-vect second-vect]
|
||||||
(let [stack-type (keyword (str "vector_" value-type))
|
(let [stack-type (keyword (str "vector_" value-type))
|
||||||
start-state (state/push-to-stack
|
start-state (state/push-to-stack
|
||||||
(state/push-to-stack state/empty-state
|
(state/push-to-stack state/empty-state
|
||||||
@ -210,7 +210,7 @@
|
|||||||
second-vect# (gen/vector ~generator)]
|
second-vect# (gen/vector ~generator)]
|
||||||
(check-concat first-vect# second-vect# ~value-type))))))
|
(check-concat first-vect# second-vect# ~value-type))))))
|
||||||
|
|
||||||
(concat-spec)
|
; (concat-spec)
|
||||||
|
|
||||||
;;; vector/_subvec
|
;;; vector/_subvec
|
||||||
|
|
||||||
@ -229,7 +229,7 @@
|
|||||||
the given values on the integer stack.
|
the given values on the integer stack.
|
||||||
It then runs the vector/_subvec instruction, and confirms that the
|
It then runs the vector/_subvec instruction, and confirms that the
|
||||||
result (on the :vector_<value-type> stack) is the expected value."
|
result (on the :vector_<value-type> stack) is the expected value."
|
||||||
[vect start stop value-type]
|
[value-type vect start stop]
|
||||||
(let [stack-type (keyword (str "vector_" value-type))
|
(let [stack-type (keyword (str "vector_" value-type))
|
||||||
start-state (state/push-to-stack
|
start-state (state/push-to-stack
|
||||||
(state/push-to-stack
|
(state/push-to-stack
|
||||||
@ -254,4 +254,37 @@
|
|||||||
stop# gen/small-integer]
|
stop# gen/small-integer]
|
||||||
(check-subvec vect# start# stop# ~value-type))))))
|
(check-subvec vect# start# stop# ~value-type))))))
|
||||||
|
|
||||||
(subvec-spec)
|
; (subvec-spec)
|
||||||
|
|
||||||
|
(defn generator-for-arg-type
|
||||||
|
[arg-type generator]
|
||||||
|
(case arg-type
|
||||||
|
:boolean 'gen/boolean
|
||||||
|
:integer 'gen/small-integer
|
||||||
|
:float 'gen/double
|
||||||
|
:string 'gen/string
|
||||||
|
; This is for "generic" vectors where the element is provided by
|
||||||
|
; the `generator` argument.
|
||||||
|
:vector `(gen/vector ~generator)
|
||||||
|
:vector_boolean '(gen/vector gen/boolean)
|
||||||
|
:vector_integer '(gen/vector gen/small-integer)
|
||||||
|
:vector_float '(gen/vector gen/double)
|
||||||
|
:vector_string '(gen/vector gen/string)
|
||||||
|
))
|
||||||
|
|
||||||
|
(defmacro gen-specs
|
||||||
|
[spec-name check-fn & arg-types]
|
||||||
|
(let [symbol-names (repeatedly (count arg-types) gensym)]
|
||||||
|
`(do ~@(for [[generator value-type] gen-type-pairs
|
||||||
|
:let [name (symbol (str spec-name "-spec-" value-type))]]
|
||||||
|
`(defspec ~name
|
||||||
|
(prop/for-all
|
||||||
|
[~@(mapcat
|
||||||
|
(fn [symbol-name arg-type]
|
||||||
|
[symbol-name (generator-for-arg-type arg-type generator)])
|
||||||
|
symbol-names
|
||||||
|
arg-types) ]
|
||||||
|
(~check-fn ~value-type ~@symbol-names)))))))
|
||||||
|
|
||||||
|
(gen-specs "concat" check-concat :vector :vector)
|
||||||
|
(gen-specs "subvec" check-subvec :vector :integer :integer)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user