3

举一个最小的例子,我有一张包含以下字段的地图。

{:name
 :password
 :confirm-password}

我已经为这个形状写了以下规格。

(s/def ::name string?)
;; password is a string and between 8 - 255 characters
(s/def ::password (s/and string? #(<= 8 (count %) 255))
;; How to write (s/def ::confirm-password)

(s/def ::sign-up-form (s/keys :req-un [::name
                                       ::password
                                       ::confirm-password])

我将如何编写::confirm-password规范来检查两个值是否相等?即我需要访问其他字段(密码)才能访问它。

我尝试过的一件事是在注册表单上编写规范以访问密钥以确保它们是相同的并且那种工作但问题是我失去了路径特异性。基本上,生成的规范/问题指向注册表单,而不是::confirm-password我理想中想要的。

4

1 回答 1

4

您可以s/and使用规范使用另一个谓词s/keys来检查两个键值之间的相等性:

(s/def ::sign-up-form
  (s/and
    (s/keys :req-un [::name
                     ::password
                     ::confirm-password])
    #(= (:password %) (:confirm-password %))))

这个匿名函数谓词接收规范的整个符合映射输出。s/keys

(s/explain ::sign-up-form
  {:name "Taylor"
   :password "weak pass"
   :confirm-password "weak pass!"})
;; val: {:name "Taylor", :password "weak pass", :confirm-password "weak pass!"} 
;;    fails spec: :sandbox.so/sign-up-form predicate: 
;;    (= (:password %) (:confirm-password %))
于 2018-01-23T20:32:29.207 回答