(require '[clojure.test.check.generators :as gen])
(def ACTIONS
{:create-new-user #{}
:edit-user #{:create-new-user}
:create-new-board #{:create-new-user}
:edit-board #{:create-new-board}
:create-new-anonymous-comment #{:create-new-board}
:create-new-signed-comment #{:create-new-board}
:edit-comment-text #{:create-new-anonymous-comment :create-new-signed-comment}
:edit-comment-text-and-flip-anonymity #{:create-new-anonymous-comment :create-new-signed-comment}
:flip-anonymity #{:create-new-anonymous-comment :create-new-signed-comment}
:vote-comment-up #{:create-new-anonymous-comment :create-new-signed-comment}
:vote-comment-down #{:create-new-anonymous-comment :create-new-signed-comment}})
(def actions (-> ACTIONS keys vec gen/elements gen/vector))
(defn filter-actions-into-logical-order [as]
(let [seen (atom #{})]
(filter
(fn [v]
(let [required (get ACTIONS v)
valid? (or (some? (some required @seen))
(and (empty? @seen) (= v :create-new-user)))]
(when valid?
(swap! seen conj v)
true)))
as)))
(def ordered-actions (gen/fmap #(-> % filter-actions-into-logical-order vec) actions))
作为两个生成器的示例:
# (last (gen/sample actions 100))
[:edit-user :vote-comment-down :flip-anonymity :vote-comment-down :vote-comment-down :vote-comment-up :edit-user :create-new-anonymous-comment :edit-board :create-new-signed-comment :vote-comment-up :edit-comment-text-and-flip-anonymity :edit-user :create-new-signed-comment :edit-user :edit-user :vote-comment-down :edit-user :vote-comment-down :create-new-user :vote-comment-down :create-new-user :create-new-user :edit-comment-text-and-flip-anonymity :create-new-user :edit-comment-text-and-flip-anonymity :create-new-anonymous-comment :edit-comment-text :create-new-board :vote-comment-down :flip-anonymity :create-new-signed-comment :vote-comment-up :create-new-user :create-new-signed-comment :edit-user :create-new-user :create-new-board :vote-comment-down :create-new-board :create-new-board :create-new-board :edit-board :edit-comment-text-and-flip-anonymity :edit-user :edit-comment-text :create-new-signed-comment :vote-comment-up :edit-comment-text-and-flip-anonymity :flip-anonymity :create-new-anonymous-comment :create-new-anonymous-comment :edit-board :create-new-signed-comment :edit-comment-text-and-flip-anonymity :edit-board :vote-comment-up :edit-comment-text :create-new-board :edit-comment-text-and-flip-anonymity :create-new-board :vote-comment-down :edit-comment-text-and-flip-anonymity :vote-comment-up :create-new-user :vote-comment-up :edit-comment-text :edit-board :edit-comment-text-and-flip-anonymity :flip-anonymity :edit-board :create-new-anonymous-comment :flip-anonymity :create-new-signed-comment :edit-user :edit-comment-text-and-flip-anonymity :edit-comment-text :edit-comment-text :create-new-user :flip-anonymity :edit-user :vote-comment-up :edit-user :create-new-user :edit-comment-text :edit-comment-text :flip-anonymity :edit-comment-text :edit-board :flip-anonymity :edit-board :edit-comment-text :edit-user :create-new-user :flip-anonymity]
# (last (gen/sample ordered-actions 100))
[:create-new-user :edit-user :edit-user :create-new-board :edit-board :edit-user :create-new-anonymous-comment :edit-comment-text :edit-board :edit-user :edit-user :vote-comment-up :edit-comment-text :create-new-signed-comment :edit-comment-text :create-new-board :edit-comment-text :edit-comment-text :edit-comment-text :vote-comment-up :vote-comment-up :edit-board :edit-comment-text-and-flip-anonymity :create-new-signed-comment :create-new-anonymous-comment :create-new-signed-comment :edit-user :create-new-anonymous-comment :edit-board :create-new-board :create-new-anonymous-comment :create-new-board :flip-anonymity :create-new-anonymous-comment :edit-board :vote-comment-up :vote-comment-down :edit-board :edit-comment-text :edit-user :edit-comment-text :flip-anonymity :create-new-signed-comment :vote-comment-up :edit-comment-text-and-flip-anonymity :vote-comment-up :create-new-signed-comment :edit-comment-text :create-new-signed-comment :create-new-anonymous-comment :edit-board :create-new-anonymous-comment]
ACTIONS
是一个映射,其中键是操作的名称,值是该操作的(或基于)依赖项。举个例子,你必须:create-new-user
先做任何事,你必须:create-new-board
先做:edit-board
,你必须至少有一个:create-new-*-comment
,然后才能做:edit-comment-text
。
上面的代码似乎工作,但它是丑陋的。1)我不喜欢filter-actions-into-logical-order
代码必须有一个特定的例外:create-new-user
。2)我不喜欢这样,我基本上是在随机操作列表中,并对其进行过滤,直到这些操作变得有序为止。
我想知道其他人如何使用 test.check 生成这样的一系列动作?当然必须有一种方法可以只使用生成器吗?