Если я правильно понял clojure.spec/fdef
, это позволяет нам делать спецификации, подобные описанным в вопросе.
(spec/fdef ::predicate-1
:args (spec/cat :arg any?)
:ret boolean?)
Что мы можем проверить, передав несколько примеров, которые, как мы знаем, должны пройти или не пройти тест:
(spec/valid? ::predicate-1 boolean?) => true
(spec/valid? ::predicate-1 (fn [a] 5)) => false
(spec/valid? ::predicate-1 (fn [a] true)) => true
(spec/valid? ::predicate-1 (fn [a b] true))=> false
(spec/valid? ::predicate-1 #(= 10 %)) => true
(spec/valid? ::predicate-1 (fn [a] nil)) => false
Для определения №. 2:
(spec/fdef ::predicate-2
:args (spec/cat :arg any?)
:ret (spec/nilable boolean?))
(spec/valid? ::predicate-2 (fn [a] nil)) => true
И для №. 3 любая функция, которая принимает один аргумент, действительна, поскольку все в clojure либо истинно, либо ложно.
(spec/fdef ::predicate-3
:args (spec/cat :arg any?)
:ret any?)
(spec/valid? ::predicate-3 identity) => true
(spec/valid? ::predicate-3 str) => true
Одна интересная вещь, которую мы тогда, кажется, можем сделать, это заставить спецификацию генерировать для нас такие функции:
(let [p (gen/generate (spec/gen ::pedicate-1))]
(clojure.string/join
" " [(p 0) (p 1) (p -1) (p nil) (p 'a) (p :a) (p (fn [a] a))]))
=> "false true true false true false false"
И из этого мы, возможно, можем попытаться угадать, что делает сгенерированная функция. Но без возможности увидеть источник нам будет трудно проверить, была ли наша догадка верной или нет.
person
Rovanion
schedule
18.04.2017