Last active
February 28, 2018 05:32
-
-
Save jimrthy/21851c52a8cd6b04a31ed08b1d0a7f04 to your computer and use it in GitHub Desktop.
clojure.spec gen oddities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns indirect-spec-gen | |
(:require [clojure.spec.alpha :as s] | |
[clojure.spec.gen.alpha :as gen] | |
[clojure.test :refer (deftest is)])) | |
(def extension-length 16) | |
;; Need a byte array with 16 members | |
(s/def ::extension (s/and bytes? | |
#(= (count %) extension-length))) | |
;; Need to track one for the client, another for the server | |
(s/def ::srvr-xtn ::extension) | |
(s/def ::clnt-xtn ::extension) | |
;; Haven't seen this fail yet | |
(deftest transitive | |
(let [test-runs 40 | |
success-count | |
(reduce (fn [n m] | |
(try | |
(let [samples (gen/sample (s/gen (s/keys :req [::srvr-xtn | |
::clnt-xtn]) | |
;; This second parameter to s/gen lets me override the generators. | |
;; I think this is the key to the sometimes nature of my problem. | |
{::srvr-xtn #(gen/fmap byte-array (gen/vector (gen/choose -128 127) extension-length)) | |
::clnt-xtn #(gen/fmap byte-array (gen/vector (gen/choose -128 127) extension-length))}))] | |
(is samples) | |
(inc n)) | |
(catch Exception ex | |
(println ex "on sample" m) | |
n))) | |
0 | |
(range test-runs))] | |
(println success-count "successes out of" test-runs))) | |
(defn manual-check | |
[] | |
(gen/sample (s/gen (s/keys :req [::srvr-xtn | |
::clnt-xtn]) | |
{::srvr-xtn #(gen/fmap byte-array (gen/vector (gen/choose -128 127) extension-length)) | |
::clnt-xtn #(gen/fmap byte-array (gen/vector (gen/choose -128 127) extension-length))}))) | |
;; Calling this in this manner or from the REPL fails pretty much every time | |
(manual-check) | |
;; Repeatedly calling manual-check from inside a test passes | |
(deftest transitive-indirect | |
(let [test-runs 40 | |
success-count | |
(reduce (fn [n m] | |
(try | |
(let [samples (manual-check)] | |
(is samples) | |
(inc n)) | |
(catch Exception ex | |
(println ex "on sample" m) | |
n))) | |
0 | |
(range test-runs))] | |
(println success-count "successes out of" test-runs))) | |
;; Generating the "base" spec seems to always work | |
(deftest direct | |
(let [samples (gen/sample (s/gen ::extension | |
{::extension #(gen/fmap byte-array (gen/vector (gen/choose -128 127) extension-length))}))] | |
(is samples))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment