Codebase list test-check-clojure / 78dee58
clojure_test.{[clj cljs] -> cljc} Nicolas Berger authored 8 years ago Gary Fredericks committed 8 years ago
6 changed file(s) with 273 addition(s) and 435 deletion(s). Raw diff Collapse all Expand all
+0
-155
src/main/clojure/clojure/test/check/clojure_test.clj less more
0 ; Copyright (c) Rich Hickey, Reid Draper, and contributors.
1 ; All rights reserved.
2 ; The use and distribution terms for this software are covered by the
3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 ; which can be found in the file epl-v10.html at the root of this distribution.
5 ; By using this software in any fashion, you are agreeing to be bound by
6 ; the terms of this license.
7 ; You must not remove this notice, or any other, from this software.
8
9 (ns clojure.test.check.clojure-test
10 (:require [clojure.test :as ct]))
11
12 (defn assert-check
13 [{:keys [result] :as m}]
14 (prn m)
15 (if (instance? Throwable result)
16 (throw result)
17 (ct/is result)))
18
19 (def ^:dynamic *default-test-count* 100)
20
21 (defn process-options
22 {:no-doc true}
23 [options]
24 (cond (nil? options) {:num-tests *default-test-count*}
25 (number? options) {:num-tests options}
26 (map? options) (if (:num-tests options)
27 options
28 (assoc options :num-tests *default-test-count*))
29 :else (throw (ex-info (str "Invalid defspec options: " (pr-str options))
30 {:bad-options options}))))
31
32 (defmacro defspec
33 "Defines a new clojure.test test var that uses `quick-check` to verify
34 [property] with the given [args] (should be a sequence of generators),
35 [default-times] times by default. You can call the function defined as [name]
36 with no arguments to trigger this test directly (i.e., without starting a
37 wider clojure.test run), with a single argument that will override
38 [default-times], or with a map containing any of the keys
39 [:seed :max-size :num-tests]."
40 {:arglists '([name property] [name num-tests? property] [name options? property])}
41 ([name property] `(defspec ~name nil ~property))
42 ([name options property]
43 ;; consider my shame for introducing a cyclical dependency like this...
44 ;; Don't think we'll know what the solution is until clojure.test.check
45 ;; integration with another test framework is attempted.
46 (require 'clojure.test.check)
47 `(defn ~(vary-meta name assoc
48 ::defspec true
49 :test `#(clojure.test.check.clojure-test/assert-check
50 (assoc (~name) :test-var (str '~name))))
51 ([] (let [options# (process-options ~options)]
52 (apply ~name (:num-tests options#) (apply concat options#))))
53 ([~'times & {:keys [~'seed ~'max-size] :as ~'quick-check-opts}]
54 (apply
55 clojure.test.check/quick-check
56 ~'times
57 (vary-meta ~property assoc :name (str '~property))
58 (apply concat ~'quick-check-opts))))))
59
60 (def ^:dynamic *report-trials*
61 "Controls whether property trials should be reported via clojure.test/report.
62 Valid values include:
63
64 * false - no reporting of trials (default)
65 * a function - will be passed a clojure.test/report-style map containing
66 :clojure.test.check/property and :clojure.test.check/trial slots
67 * true - provides quickcheck-style trial reporting (dots) via
68 `trial-report-dots`
69
70 (Note that all reporting requires running `quick-check` within the scope of a
71 clojure.test run (via `test-ns`, `test-all-vars`, etc.)
72
73 Reporting functions offered by clojure.test.check include `trial-report-dots` and
74 `trial-report-periodic` (which prints more verbose trial progress information
75 every `*trial-report-period*` milliseconds."
76 false)
77
78 (def ^:dynamic *report-shrinking*
79 "If true, a verbose report of the property being tested, the
80 failing return value, and the arguments provoking that failure is emitted
81 prior to the start of the shrinking search."
82 false)
83
84 (def ^:dynamic *trial-report-period*
85 "Milliseconds between reports emitted by `trial-report-periodic`."
86 10000)
87
88 (def ^:private last-trial-report (atom 0))
89
90 (let [begin-test-var-method (get-method ct/report :begin-test-var)]
91 (defmethod ct/report :begin-test-var [m]
92 (reset! last-trial-report (System/currentTimeMillis))
93 (when begin-test-var-method (begin-test-var-method m))))
94
95 (defn- get-property-name
96 [{property-fun ::property :as report-map}]
97 (or (-> property-fun meta :name) (ct/testing-vars-str report-map)))
98
99 (defn trial-report-periodic
100 "Intended to be bound as the value of `*report-trials*`; will emit a verbose
101 status every `*trial-report-period*` milliseconds, like this one:
102
103 Passing trial 3286 / 5000 for (your-test-var-name-here) (:)"
104 [m]
105 (let [t (System/currentTimeMillis)]
106 (when (> (- t *trial-report-period*) @last-trial-report)
107 (ct/with-test-out
108 (println "Passing trial" (-> m ::trial first) "/" (-> m ::trial second)
109 "for" (get-property-name m)))
110 (reset! last-trial-report t))))
111
112 (defn trial-report-dots
113 "Intended to be bound as the value of `*report-trials*`; will emit a single
114 dot every 1000 trials reported."
115 [{[so-far total] ::trial}]
116 (when (pos? so-far)
117 (when (zero? (mod so-far 1000))
118 (print ".")
119 (flush))
120 (when (== so-far total) (println))))
121
122 (defmethod ct/report ::trial [m]
123 (when-let [trial-report-fn (and *report-trials*
124 (if (true? *report-trials*)
125 trial-report-dots
126 *report-trials*))]
127 (trial-report-fn m)))
128
129 (defmethod ct/report ::shrinking [m]
130 (when *report-shrinking*
131 (ct/with-test-out
132 (println "Shrinking" (get-property-name m)
133 "starting with parameters" (pr-str (::params m))))))
134
135 (defn report-trial
136 [property-fun so-far num-tests]
137 (ct/report {:type ::trial
138 ::property property-fun
139 ::trial [so-far num-tests]}))
140
141 (defn report-failure
142 [property-fun result trial-number failing-params]
143 ;; TODO this is wrong, makes it impossible to clojure.test quickchecks that
144 ;; should fail...
145 #_(ct/report (if (instance? Throwable result)
146 {:type :error
147 :message (.getMessage result)
148 :actual result}
149 {:type :fail
150 :expected true
151 :actual result}))
152 (ct/report {:type ::shrinking
153 ::property property-fun
154 ::params (vec failing-params)}))
0 ; Copyright (c) Rich Hickey, Reid Draper, and contributors.
1 ; All rights reserved.
2 ; The use and distribution terms for this software are covered by the
3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 ; which can be found in the file epl-v10.html at the root of this distribution.
5 ; By using this software in any fashion, you are agreeing to be bound by
6 ; the terms of this license.
7 ; You must not remove this notice, or any other, from this software.
8
9 (ns clojure.test.check.clojure-test
10 (:require #?(:clj [clojure.test :as ct]
11 :cljs [cljs.test :as ct :include-macros true])))
12
13 (defn exception-like? [v]
14 (instance? #?(:clj Throwable :cljs js/Error) v))
15
16 (defn assert-check
17 [{:keys [result] :as m}]
18 (prn m)
19 (if (exception-like? result)
20 (throw result)
21 (ct/is result)))
22
23 (def ^:dynamic *default-test-count* 100)
24
25 (defn process-options
26 {:no-doc true}
27 [options]
28 (cond (nil? options) {:num-tests *default-test-count*}
29 (number? options) {:num-tests options}
30 (map? options) (if (:num-tests options)
31 options
32 (assoc options :num-tests *default-test-count*))
33 :else (throw (ex-info (str "Invalid defspec options: " (pr-str options))
34 {:bad-options options}))))
35
36 #?(:clj
37 (defmacro defspec
38 "Defines a new clojure.test test var that uses `quick-check` to verify
39 [property] with the given [args] (should be a sequence of generators),
40 [default-times] times by default. You can call the function defined as [name]
41 with no arguments to trigger this test directly (i.e., without starting a
42 wider clojure.test run), with a single argument that will override
43 [default-times], or with a map containing any of the keys
44 [:seed :max-size :num-tests]."
45 {:arglists '([name property] [name num-tests? property] [name options? property])}
46 ([name property] `(defspec ~name nil ~property))
47 ([name options property]
48 ;; consider my shame for introducing a cyclical dependency like this...
49 ;; Don't think we'll know what the solution is until clojure.test.check
50 ;; integration with another test framework is attempted.
51 (require 'clojure.test.check)
52 `(defn ~(vary-meta name assoc
53 ::defspec true
54 :test `#(clojure.test.check.clojure-test/assert-check
55 (assoc (~name) :test-var (str '~name))))
56 ([] (let [options# (process-options ~options)]
57 (apply ~name (:num-tests options#) (apply concat options#))))
58 ([~'times & {:keys [~'seed ~'max-size] :as ~'quick-check-opts}]
59 (apply
60 clojure.test.check/quick-check
61 ~'times
62 (vary-meta ~property assoc :name (str '~property))
63 (apply concat ~'quick-check-opts)))))))
64
65 (def ^:dynamic *report-trials*
66 "Controls whether property trials should be reported via clojure.test/report.
67 Valid values include:
68
69 * false - no reporting of trials (default)
70 * a function - will be passed a clojure.test/report-style map containing
71 :clojure.test.check/property and :clojure.test.check/trial slots
72 * true - provides quickcheck-style trial reporting (dots) via
73 `trial-report-dots`
74
75 (Note that all reporting requires running `quick-check` within the scope of a
76 clojure.test run (via `test-ns`, `test-all-vars`, etc.)
77
78 Reporting functions offered by clojure.test.check include `trial-report-dots` and
79 `trial-report-periodic` (which prints more verbose trial progress information
80 every `*trial-report-period*` milliseconds."
81 false)
82
83 (def ^:dynamic *report-shrinking*
84 "If true, a verbose report of the property being tested, the
85 failing return value, and the arguments provoking that failure is emitted
86 prior to the start of the shrinking search."
87 false)
88
89 (def ^:dynamic *trial-report-period*
90 "Milliseconds between reports emitted by `trial-report-periodic`."
91 10000)
92
93 (def ^:private last-trial-report (atom 0))
94
95 (defn get-current-time-millis []
96 #?(:clj (System/currentTimeMillis)
97 :cljs (.valueOf (js/Date.))))
98
99 (let [begin-test-var-method (get-method ct/report #?(:clj :begin-test-var
100 :cljs [::ct/default :begin-test-var]))]
101 (defmethod ct/report #?(:clj :begin-test-var
102 :cljs [::ct/default :begin-test]) [m]
103 (reset! last-trial-report (get-current-time-millis))
104 (when begin-test-var-method (begin-test-var-method m))))
105
106 (defn- get-property-name
107 [{property-fun ::property :as report-map}]
108 (or (-> property-fun meta :name) (ct/testing-vars-str report-map)))
109
110 (defn with-test-out* [f]
111 #?(:clj (ct/with-test-out (f))
112 :cljs (f)))
113
114 (defn trial-report-periodic
115 "Intended to be bound as the value of `*report-trials*`; will emit a verbose
116 status every `*trial-report-period*` milliseconds, like this one:
117
118 Passing trial 3286 / 5000 for (your-test-var-name-here) (:)"
119 [m]
120 (let [t (get-current-time-millis)]
121 (when (> (- t *trial-report-period*) @last-trial-report)
122 (with-test-out*
123 (fn []
124 (println "Passing trial"
125 (-> m ::trial first) "/" (-> m ::trial second)
126 "for" (get-property-name m))))
127 (reset! last-trial-report t))))
128
129 (defn trial-report-dots
130 "Intended to be bound as the value of `*report-trials*`; will emit a single
131 dot every 1000 trials reported."
132 [{[so-far total] ::trial}]
133 (when (pos? so-far)
134 (when (zero? (mod so-far 1000))
135 (print ".")
136 (flush))
137 (when (== so-far total) (println))))
138
139 (defmethod ct/report #?(:clj ::trial :cljs [::ct/default ::trial]) [m]
140 (when-let [trial-report-fn (and *report-trials*
141 (if (true? *report-trials*)
142 trial-report-dots
143 *report-trials*))]
144 (trial-report-fn m)))
145
146 (defmethod ct/report #?(:clj ::shrinking :cljs [::ct/default ::shrinking]) [m]
147 (when *report-shrinking*
148 (with-test-out*
149 (fn []
150 (println "Shrinking" (get-property-name m)
151 "starting with parameters" (pr-str (::params m)))))))
152
153 (defn report-trial
154 [property-fun so-far num-tests]
155 (ct/report {:type ::trial
156 ::property property-fun
157 ::trial [so-far num-tests]}))
158
159 (defn report-failure
160 [property-fun result trial-number failing-params]
161 ;; TODO this is wrong, makes it impossible to clojure.test quickchecks that
162 ;; should fail...
163 #_(ct/report (if (exception-like? result)
164 {:type :error
165 :message (.getMessage result)
166 :actual result}
167 {:type :fail
168 :expected true
169 :actual result}))
170 (ct/report {:type ::shrinking
171 ::property property-fun
172 ::params (vec failing-params)}))
+0
-127
src/main/clojure/clojure/test/check/clojure_test.cljs less more
0 ; Copyright (c) Rich Hickey, Reid Draper, and contributors.
1 ; All rights reserved.
2 ; The use and distribution terms for this software are covered by the
3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 ; which can be found in the file epl-v10.html at the root of this distribution.
5 ; By using this software in any fashion, you are agreeing to be bound by
6 ; the terms of this license.
7 ; You must not remove this notice, or any other, from this software.
8
9 (ns clojure.test.check.clojure-test
10 (:require-macros clojure.test.check.clojure-test)
11 (:require [cljs.test :as ct :include-macros true]))
12
13 (defn- assert-check
14 [{:keys [result] :as m}]
15 (prn m)
16 (if (instance? js/Error result)
17 (throw result)
18 (ct/is result)))
19
20 (def ^:dynamic *default-test-count* 100)
21
22 (defn process-options
23 {:no-doc true}
24 [options]
25 (cond (nil? options) {:num-tests *default-test-count*}
26 (number? options) {:num-tests options}
27 (map? options) (if (:num-tests options)
28 options
29 (assoc options :num-tests *default-test-count*))
30 :else (throw (ex-info (str "Invalid defspec options: " (pr-str options))
31 {:bad-options options}))))
32
33 (def ^:dynamic *report-trials*
34 "Controls whether property trials should be reported via clojure.test/report.
35 Valid values include:
36
37 * false - no reporting of trials (default)
38 * a function - will be passed a clojure.test/report-style map containing
39 :clojure.test.check/property and :clojure.test.check/trial slots
40 * true - provides quickcheck-style trial reporting (dots) via
41 `trial-report-dots`
42
43 (Note that all reporting requires running `quick-check` within the scope of a
44 clojure.test run (via `test-ns`, `test-all-vars`, etc.)
45
46 Reporting functions offered by clojure.test.check include `trial-report-dots` and
47 `trial-report-periodic` (which prints more verbose trial progress information
48 every `*trial-report-period*` milliseconds."
49 false)
50
51 (def ^:dynamic *report-shrinking*
52 "If true, a verbose report of the property being tested, the
53 failing return value, and the arguments provoking that failure is emitted
54 prior to the start of the shrinking search."
55 false)
56
57 (def ^:dynamic *trial-report-period*
58 "Milliseconds between reports emitted by `trial-report-periodic`."
59 10000)
60
61 (def ^:private last-trial-report (atom 0))
62
63 (let [begin-test-var-method (get-method ct/report [::ct/default :begin-test-var])]
64 (defmethod ct/report [::ct/default :begin-test-var] [m]
65 (reset! last-trial-report (.valueOf (js/Date.)))
66 (when begin-test-var-method (begin-test-var-method m))))
67
68 (defn- get-property-name
69 [{property-fun ::property :as report-map}]
70 (or (-> property-fun meta :name) (ct/testing-vars-str report-map)))
71
72 (defn trial-report-periodic
73 "Intended to be bound as the value of `*report-trials*`; will emit a verbose
74 status every `*trial-report-period*` milliseconds, like this one:
75
76 Passing trial 3286 / 5000 for (your-test-var-name-here) (:)"
77 [m]
78 (let [t (.valueOf (js/Date.))]
79 (when (> (- t *trial-report-period*) @last-trial-report)
80 (println "Passing trial" (-> m ::trial first) "/" (-> m ::trial second)
81 "for" (get-property-name m))
82 (reset! last-trial-report t))))
83
84 (defn trial-report-dots
85 "Intended to be bound as the value of `*report-trials*`; will emit a single
86 dot every 1000 trials reported."
87 [{[so-far total] ::trial}]
88 (when (pos? so-far)
89 (when (zero? (mod so-far 1000))
90 (print ".")
91 (flush))
92 (when (== so-far total) (println))))
93
94 (defmethod ct/report [::ct/default ::trial] [m]
95 (when-let [trial-report-fn (and *report-trials*
96 (if (true? *report-trials*)
97 trial-report-dots
98 *report-trials*))]
99 (trial-report-fn m)))
100
101 (defmethod ct/report [::ct/default ::shrinking] [m]
102 (when *report-shrinking*
103 (println "Shrinking" (get-property-name m)
104 "starting with parameters" (pr-str (::params m)))))
105
106 (defn report-trial
107 [property-fun so-far num-tests]
108 (ct/report {:type ::trial
109 ::property property-fun
110 ::trial [so-far num-tests]}))
111
112 (defn report-failure
113 [property-fun result trial-number failing-params]
114 ;; TODO this is wrong, makes it impossible to clojure.test quickchecks that
115 ;; should fail...
116 #_(ct/report (if (instance? Throwable result)
117 {:type :error
118 :message (.getMessage result)
119 :actual result}
120 {:type :fail
121 :expected true
122 :actual result}))
123 (ct/report {:type ::shrinking
124 ::property property-fun
125 ::params (vec failing-params)}))
126
+0
-72
src/test/clojure/clojure/test/check/clojure_test_test.clj less more
0 ; Copyright (c) Rich Hickey, Reid Draper, and contributors.
1 ; All rights reserved.
2 ; The use and distribution terms for this software are covered by the
3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 ; which can be found in the file epl-v10.html at the root of this distribution.
5 ; By using this software in any fashion, you are agreeing to be bound by
6 ; the terms of this license.
7 ; You must not remove this notice, or any other, from this software.
8
9 (ns clojure.test.check.clojure-test-test
10 (:use clojure.test)
11 (:require [clojure.test.check.generators :as gen]
12 [clojure.test.check.properties :as prop]
13 [clojure.test.check.clojure-test :as ct :refer (defspec)]))
14
15 (defspec default-trial-counts
16 (prop/for-all* [gen/int] (constantly true)))
17
18 (defspec trial-counts 5000
19 (prop/for-all* [gen/int] (constantly true)))
20
21 (defspec long-running-spec 1000
22 (prop/for-all* [] #(do (Thread/sleep 1) true)))
23
24 (defn- vector-elements-are-unique*
25 [v]
26 (== (count v) (count (distinct v))))
27
28 (def ^:private vector-elements-are-unique
29 (prop/for-all*
30 [(gen/vector gen/int)]
31 vector-elements-are-unique*))
32
33 (defspec this-is-supposed-to-fail 100 vector-elements-are-unique)
34
35 (defn- capture-test-var
36 [v]
37 (doto (with-out-str (binding [*test-out* *out*] (test-var v)))
38 println))
39
40 (defn test-ns-hook
41 []
42 (is (-> (capture-test-var #'default-trial-counts)
43 read-string
44 :num-tests
45 (= ct/*default-test-count*)))
46
47 (is (-> (capture-test-var #'trial-counts)
48 read-string
49 (select-keys [:test-var :result :num-tests])
50 (= {:test-var "trial-counts", :result true, :num-tests 5000})))
51
52 (binding [ct/*report-trials* true]
53 (let [output (capture-test-var #'trial-counts)]
54 (is (re-matches #"(?s)\.{5}.+" output))))
55
56 (binding [ct/*report-trials* ct/trial-report-periodic
57 ct/*trial-report-period* 500]
58 (is (re-seq
59 #"(Passing trial \d{3} / 1000 for .+\n)+"
60 (capture-test-var #'long-running-spec))))
61
62 (let [[report-counters stdout]
63 (binding [ct/*report-shrinking* true
64 ; need to keep the failure of this-is-supposed-to-fail from
65 ; affecting the clojure.test.check test run
66 *report-counters* (ref *initial-report-counters*)]
67 [*report-counters* (capture-test-var #'this-is-supposed-to-fail)])]
68 (is (== 1 (:fail @report-counters)))
69 (is (re-seq
70 #"(?s)Shrinking vector-elements-are-unique starting with parameters \[\[.+"
71 stdout))))
0 ; Copyright (c) Rich Hickey, Reid Draper, and contributors.
1 ; All rights reserved.
2 ; The use and distribution terms for this software are covered by the
3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 ; which can be found in the file epl-v10.html at the root of this distribution.
5 ; By using this software in any fashion, you are agreeing to be bound by
6 ; the terms of this license.
7 ; You must not remove this notice, or any other, from this software.
8
9 (ns clojure.test.check.clojure-test-test
10 #?(:clj (:use clojure.test))
11 (:require #?@(:cljs
12 [[cljs.test :as test :refer [test-var] :refer-macros [is]]
13 [cljs.reader :refer [read-string]]])
14 [clojure.test.check.generators :as gen]
15 [clojure.test.check.properties :as prop #?@(:cljs [:include-macros true])]
16 [clojure.test.check.clojure-test :as ct #?@(:clj [:refer (defspec)]
17 :cljs [:refer-macros (defspec)])]))
18
19 (defspec default-trial-counts
20 (prop/for-all* [gen/int] (constantly true)))
21
22 (defspec trial-counts 5000
23 (prop/for-all* [gen/int] (constantly true)))
24
25 ;; NOTE: No Thread/sleep in JS, so no :cljs version - David
26 #?(:clj
27 (defspec long-running-spec 1000
28 (prop/for-all* [] #(do (Thread/sleep 1) true))))
29
30 (defn- vector-elements-are-unique*
31 [v]
32 (== (count v) (count (distinct v))))
33
34 (def ^:private vector-elements-are-unique
35 (prop/for-all*
36 [(gen/vector gen/int)]
37 vector-elements-are-unique*))
38
39 (defspec this-is-supposed-to-fail 100 vector-elements-are-unique)
40
41 (defn- capture-test-var
42 [v]
43 (doto (with-out-str #?(:clj (binding [*test-out* *out*] (test-var v))
44 :cljs (test-var v)))
45 println))
46
47 (defn test-ns-hook
48 []
49 (is (-> (capture-test-var #'default-trial-counts)
50 read-string
51 :num-tests
52 (= ct/*default-test-count*)))
53
54 (is (-> (capture-test-var #'trial-counts)
55 read-string
56 (select-keys [:test-var :result :num-tests])
57 (= {:test-var "trial-counts", :result true, :num-tests 5000})))
58
59 (binding [ct/*report-trials* true]
60 (let [output (capture-test-var #'trial-counts)]
61 (is (re-matches #?(:clj #"(?s)\.{5}.+"
62 :cljs #"\.{5}[\s\S]+")
63 output))))
64
65 ;; NOTE: No Thread/sleep in JS - David
66 #?(:clj
67 (binding [ct/*report-trials* ct/trial-report-periodic
68 ct/*trial-report-period* 500]
69 (is (re-seq
70 #"(Passing trial \d{3} / 1000 for .+\n)+"
71 (capture-test-var #'long-running-spec)))))
72
73 (let [[report-counters stdout]
74 #?(:clj
75 (binding [ct/*report-shrinking* true
76 ; need to keep the failure of this-is-supposed-to-fail from
77 ; affecting the clojure.test.check test run
78 *report-counters* (ref *initial-report-counters*)]
79 (let [out (capture-test-var #'this-is-supposed-to-fail)]
80 [@*report-counters* out]))
81
82 :cljs
83 (binding [ct/*report-shrinking* true]
84 ;; need to keep the failure of this-is-supposed-to-fail from
85 ;; affecting the clojure.test.check test run
86 (let [restore-env (test/get-current-env)
87 _ (test/set-env! (test/empty-env))
88 report-str (capture-test-var #'this-is-supposed-to-fail)
89 env (test/get-current-env)]
90 (test/set-env! restore-env)
91 [(:report-counters env) report-str])))]
92 (is (== 1 (:fail report-counters)))
93 (is (re-seq
94 #?(:clj
95 #"(?s)Shrinking vector-elements-are-unique starting with parameters \[\[.+"
96
97 :cljs
98 #"Shrinking vector-elements-are-unique starting with parameters \[\[[\s\S]+")
99 stdout))))
+0
-81
src/test/clojure/clojure/test/check/clojure_test_test.cljs less more
0 ; Copyright (c) Rich Hickey, Reid Draper, and contributors.
1 ; All rights reserved.
2 ; The use and distribution terms for this software are covered by the
3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 ; which can be found in the file epl-v10.html at the root of this distribution.
5 ; By using this software in any fashion, you are agreeing to be bound by
6 ; the terms of this license.
7 ; You must not remove this notice, or any other, from this software.
8
9 (ns clojure.test.check.clojure-test-test
10 (:require [cljs.test :as test :refer [test-var] :refer-macros [is]]
11 [clojure.test.check.generators :as gen]
12 [clojure.test.check.properties :as prop :include-macros true]
13 [clojure.test.check.clojure-test :as ct :refer-macros [defspec]]
14 [cljs.reader :refer [read-string]]))
15
16 (defspec default-trial-counts
17 (prop/for-all* [gen/int] (constantly true)))
18
19 (defspec trial-counts 5000
20 (prop/for-all* [gen/int] (constantly true)))
21
22 ;; NOTE: No Thread/sleep in JS - David
23 ;; (defspec long-running-spec 1000
24 ;; (prop/for-all* [] #(do (Thread/sleep 1) true)))
25
26 (defn- vector-elements-are-unique*
27 [v]
28 (== (count v) (count (distinct v))))
29
30 (def ^:private vector-elements-are-unique
31 (prop/for-all*
32 [(gen/vector gen/int)]
33 vector-elements-are-unique*))
34
35 (defspec this-is-supposed-to-fail 100 vector-elements-are-unique)
36
37 (defn- capture-test-var
38 [v]
39 (doto (with-out-str (test-var v))
40 print))
41
42 (defn test-ns-hook
43 []
44 (let [out-str (capture-test-var #'default-trial-counts)
45 num-tests (-> out-str
46 read-string
47 :num-tests)]
48 (is (= num-tests ct/*default-test-count*)))
49
50 (is (-> (capture-test-var #'trial-counts)
51 read-string
52 (select-keys [:test-var :result :num-tests])
53 (= {:test-var "trial-counts", :result true, :num-tests 5000})))
54
55 (binding [ct/*report-trials* true]
56 (let [output (capture-test-var #'trial-counts)]
57 (is (re-matches #"\.{5}[\s\S]+" output))))
58
59 ;; NOTE: No Thread/sleep in JS - David
60 ;; (binding [ct/*report-trials* ct/trial-report-periodic
61 ;; ct/*trial-report-period* 500]
62 ;; (is (re-seq
63 ;; #"(Passing trial \d{3} / 1000 for .+\n)+"
64 ;; (capture-test-var #'long-running-spec))))
65
66 (let [[report-counters report-str]
67 (binding [ct/*report-shrinking* true]
68 ;; need to keep the failure of this-is-supposed-to-fail from
69 ;; affecting the clojure.test.check test run
70 (let [restore-env (test/get-current-env)
71 _ (test/set-env! (test/empty-env))
72 report-str (capture-test-var #'this-is-supposed-to-fail)
73 env (test/get-current-env)]
74 (test/set-env! restore-env)
75 [(:report-counters env) report-str]))]
76 (is (== 1 (:fail report-counters)))
77 (is (re-seq
78 #"Shrinking vector-elements-are-unique starting with parameters \[\[[\s\S]+"
79 report-str))))
80