2017-04-13 6 views
1

우리가 모두 데이터를 생성 할 수 있습니다이 사양에서 clojure.spec/merge생성기는

(require '[clojure.spec  :as spec] 
     '[clojure.spec.gen :as gen]) 

(spec/def :animal/kind string?) 
(spec/def :animal/says string?) 
(spec/def :animal/common (spec/keys :req [:animal/kind :animal/says])) 
(spec/def :dog/tail? boolean?) 
(spec/def :dog/breed string?) 
(spec/def :animal/dog (spec/merge :animal/common 
            (spec/keys :req [:dog/tail? :dog/breed]))) 

에 대한 사양 Guide Clojure의에 주어진 예를 살펴 차례로을 확인할 수 있습니다 :

(gen/generate (spec/gen :animal/dog)) 
=> {:animal/kind "bB", :animal/says "z9C0T465Q8OPXn5dUB8Wqk8K5Jnn", 
    :dog/tail? false, :dog/breed "B2MLQnj"} 

(spec/valid? :animal/dog 
      {:animal/kind "bB", :animal/says "z9C0T465Q8OPXn5dUB8Wqk8K5Jnn", 
       :dog/tail? false, :dog/breed "B2MLQnj"}) 
=> true 

그러나 우리는 대신지도의 명명 된 인수의 순서에 대한이되도록 약간

(spec/def :animal/common (spec/keys* :req [:animal/kind :animal/says])) 
(spec/def :animal/dog (spec/merge :animal/common 
            (spec/keys* :req [:dog/tail? :dog/breed]))) 
0과 같은 사양을 수정한다면

(spec/valid? :animal/dog 
      '(:animal/kind "dog" 
       :animal/says "woof" 
       :dog/tail? true 
       :dog/breed "retriever")) 
=> true 

그러나 우리는 데이터를 생성 할 수있는 능력을 상실 할 :

, 우리는 여전히 사양에 대해 데이터의 유효성을 검사 할 수

(gen/generate (spec/gen :animal/dog)) 

; 1. Unhandled clojure.lang.ExceptionInfo 
; Couldn't satisfy such-that predicate after 100 tries. 

이가 내 옆에 오류 스펙의 구현 오류입니다 , 아니면 그냥 clojure.spec/merge가 작동하도록 의도 된 것입니까? 발전기를 연결하여이 문제를 해결할 수 있습니까?

답변

1

spec/merge의 구현을 살펴보면지도를 생성하는 데 특별한 경우가 있지만 키/값 쌍 시퀀스를 생성하지는 않습니다. 나는 아직 알파 상태이고 심지어 API가 안정적이지 않기 때문에 이것이 완벽하게 구현 된 것은 아니라고 생각합니다. 자신의 발전기를 공급하는 것이 트릭을하는 것처럼 보입니다. 예 :

(gen/generate (spec/gen :animal/dog {:animal/dog #(clojure.test.check.generators/return '(:animal/kind "2qAW61r3030B", :animal/says "7k", :dog/tail? true, :dog/breed "00Y8C9T25cRrSQsnjOn26a"))}))