#clojure #clojure.spec #test.check
#clojure #clojure.spec #test.check
Вопрос:
Есть ли способ переопределить генератор для основной функции предиката при вызове clojure.spec.test.alpha/check
?
Можно переопределить генератор предикатов по пути внутри s/gen
:
(gen/generate
(s/gen
(s/cat :s string?)
{[:s] #(gen/return "xyz")}))
Но эта опция не существует для test/check
:
(defn xyz [s] s)
(s/fdef xyz
:args (s/cat :s string?)
:ret string?)
;; throws
(test/check
`xyz
{:gen {[:args :s] #(gen/return "xyz")}})
Имя или символ должны быть указаны, но как называется для string?
спецификации? Я пробовал использовать символы, оба ‘string? и `строка? но это тоже не сработало.
Переопределение генератора путем обертывания string?
с s/with-gen
помощью inside s/fdef
приводит к отображению кода генератора внутри документов функции… это влияет на удобочитаемость imo.
Определение новой спецификации ::string
только для этой цели кажется неправильным.
Ответ №1:
(ns so.spec
(:require [clojure.spec.gen.alpha :as gen]
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as st]))
(defn xyz [s]
; only to make sure it gets called
(prn s)
s)
(s/def ::xyz-arguments (s/cat :s string?))
(s/fdef xyz
:args ::xyz-arguments
:ret string?)
(st/check
'so.spec/xyz
{:gen {::xyz-arguments #(gen/return '("xyz"))}})
Комментарии:
1. Да, как я отметил в своем вопросе, вы также могли бы сделать
(s/def ::string string?)
, а затем использовать(s/cat :s ::string)
внутриs/fdef
и::string
при переопределении… но я надеялся на более простое решение.2. Извините, я не прочитал последнюю часть. Я предполагаю, что нет, если только не существует какого-то хитрого способа создать спецификацию с помощью генератора аргументов.
[:args :s]
не сработает, потому что это должен быть символ или ключевое слово.