Back
testing (clj)
(source)macro
(testing string & body)
Adds a new string to the list of testing contexts. May be nested,
but must occur inside a test function (deftest).
Examples
clojure
(ns clojure.test-clojure.transducers
(:require [clojure.string :as s]
[clojure.test :refer :all]
[clojure.test.check :as chk]
[clojure.test.check.generators :as gen]
[clojure.test.check.properties :as prop]
[clojure.test.check.clojure-test :as ctest]))
(deftest test-eduction
(testing "one xform"
(is (= [1 2 3 4 5]
(eduction (map inc) (range 5)))))
(testing "multiple xforms"
(is (= ["2" "4"]
(eduction (map inc) (filter even?) (map str) (range 5)))))
(testing "materialize at the end"
(is (= [1 1 1 1 2 2 2 3 3 4]
(->> (range 5)
(eduction (mapcat range) (map inc))
sort)))
(is (= [1 1 2 1 2 3 1 2 3 4]
(vec (->> (range 5)
(eduction (mapcat range) (map inc))
to-array))))
(is (= {1 4, 2 3, 3 2, 4 1}
(->> (range 5)
(eduction (mapcat range) (map inc))
frequencies)))
(is (= ["drib" "god" "hsif" "kravdraa" "tac"]
(->> ["cat" "dog" "fish" "bird" "aardvark"]
(eduction (map clojure.string/reverse))
(sort-by first)))))
(testing "expanding transducer with nils"
(is (= '(1 2 3 nil 4 5 6 nil)
(eduction cat [[1 2 3 nil] [4 5 6 nil]])))))
(deftest test-eduction-completion
(testing "eduction completes inner xformed reducing fn"
(is (= [[0 1 2] [3 4 5] [6 7]]
(into []
(comp cat (partition-all 3))
(eduction (partition-all 5) (range 8))))))
(testing "outer reducing fn completed only once"
(let [counter (atom 0)
;; outer rfn
rf (completing conj #(do (swap! counter inc)
(vec %)))
coll (eduction (map inc) (range 5))
res (transduce (map str) rf [] coll)]
(is (= 1 @counter))
(is (= ["1" "2" "3" "4" "5"] res)))))
(deftest test-interpose
(are [out in] (= out (sequence (interpose :s) in))
[] (range 0)
[0] (range 1)
[0 :s 1] (range 2)
[0 :s 1 :s 2] (range 3))
(testing "Can end reduction on separator or input"
(let [expected (interpose :s (range))]
(dotimes [i 10]
(is (= (take i expected)
(sequence (comp (interpose :s) (take i))
(range))))))))
clojure
(ns clojure.test-clojure.rt
(:require [clojure.string :as string]
clojure.set)
(:use clojure.test clojure.test-helper))
(deftest rt-print-prior-to-print-initialize
(testing "pattern literals"
(is (= "#\"foo\"" (bare-rt-print #"foo")))))
(deftest error-messages
(testing "binding a core var that already refers to something"
(should-print-err-message
#"WARNING: prefers already refers to: #'clojure.core/prefers in namespace: .*\r?\n"
(defn prefers [] (throw (RuntimeException. "rebound!")))))
(testing "reflection cannot resolve field"
(should-print-err-message
#"Reflection warning, .*:\d+:\d+ - reference to field blah can't be resolved\.\r?\n"
(defn foo [x] (.blah x))))
(testing "reflection cannot resolve field on known class"
(should-print-err-message
#"Reflection warning, .*:\d+:\d+ - reference to field blah on java\.lang\.String can't be resolved\.\r?\n"
(defn foo [^String x] (.blah x))))
(testing "reflection cannot resolve instance method because it is missing"
(should-print-err-message
#"Reflection warning, .*:\d+:\d+ - call to method zap on java\.lang\.String can't be resolved \(no such method\)\.\r?\n"
(defn foo [^String x] (.zap x 1))))
(testing "reflection cannot resolve instance method because it has incompatible argument types"
(should-print-err-message
#"Reflection warning, .*:\d+:\d+ - call to method getBytes on java\.lang\.String can't be resolved \(argument types: java\.util\.regex\.Pattern\)\.\r?\n"
(defn foo [^String x] (.getBytes x #"boom"))))
(testing "reflection cannot resolve instance method because it has unknown argument types"
(should-print-err-message
#"Reflection warning, .*:\d+:\d+ - call to method getBytes on java\.lang\.String can't be resolved \(argument types: unknown\)\.\r?\n"
(defn foo [^String x y] (.getBytes x y))))
(testing "reflection error prints correctly for nil arguments"
(should-print-err-message
#"Reflection warning, .*:\d+:\d+ - call to method divide on java\.math\.BigDecimal can't be resolved \(argument types: unknown, unknown\)\.\r?\n"
(defn foo [a] (.divide 1M a nil))))
(testing "reflection cannot resolve instance method because target class is unknown"
(should-print-err-message
#"Reflection warning, .*:\d+:\d+ - call to method zap can't be resolved \(target class is unknown\)\.\r?\n"
(defn foo [x] (.zap x 1))))
(testing "reflection cannot resolve static method"
(should-print-err-message
#"Reflection warning, .*:\d+:\d+ - call to static method valueOf on java\.lang\.Integer can't be resolved \(argument types: java\.util\.regex\.Pattern\)\.\r?\n"
(defn foo [] (Integer/valueOf #"boom"))))
(testing "reflection cannot resolve constructor"
(should-print-err-message
#"Reflection warning, .*:\d+:\d+ - call to java\.lang\.String ctor can't be resolved\.\r?\n"
(defn foo [] (String. 1 2 3)))))
(deftest ns-intern-policies
(testing "you can replace a core name, with warning"
(let [ns (temp-ns)
replacement (gensym)
e1 (with-err-string-writer (intern ns 'prefers replacement))]
(is (string/starts-with? e1 "WARNING"))
(is (= replacement @('prefers (ns-publics ns))))))
(testing "you can replace a defined alias"
(let [ns (temp-ns)
s (gensym)
v1 (intern ns 'foo s)
v2 (intern ns 'bar s)
e1 (with-err-string-writer (.refer ns 'flatten v1))
e2 (with-err-string-writer (.refer ns 'flatten v2))]
(is (string/starts-with? e1 "WARNING"))
(is (string/starts-with? e2 "WARNING"))
(is (= v2 (ns-resolve ns 'flatten)))))
(testing "you cannot replace an interned var"
(let [ns1 (temp-ns)
ns2 (temp-ns)
v1 (intern ns1 'foo 1)
v2 (intern ns2 'foo 2)
e1 (with-err-string-writer (.refer ns1 'foo v2))]
(is (string/starts-with? e1 "REJECTED"))
(is (= v1 (ns-resolve ns1 'foo))))))
clojure
(ns clojure.test-clojure.reader
(:use clojure.test)
(:use [clojure.instant :only [read-instant-date
read-instant-calendar
read-instant-timestamp]])
(:require clojure.walk
[clojure.edn :as edn]
[clojure.test.generative :refer (defspec)]
[clojure.test-clojure.generators :as cgen]
[clojure.edn :as edn])
(:import [clojure.lang BigInt Ratio]
java.io.File
java.util.TimeZone))
(deftest Strings
(is (= "abcde" (str \a \b \c \d \e)))
(is (= "abc
def" (str \a \b \c \newline \space \space \d \e \f)))
(let [f (temp-file "clojure.core-reader" "test")]
(doseq [source [:string :file]]
(testing (str "Valid string literals read from " (name source))
(are [x form] (= x (code-units
(read-from source f (str "\"" form "\""))))
[] ""
[34] "\\\""
[10] "\\n"
[0] "\\u0000"
[0xd7ff] "\\ud7ff"
[0xd800] "\\ud800"
[0xdfff] "\\udfff"
[0xe000] "\\ue000"
[0xffff] "\\uffff"
[4 49] "\\u00041"))
(testing (str "Errors reading string literals from " (name source))
(are [err msg form] (thrown-with-cause-msg? err msg
(read-from source f (str "\"" form "\"")))
Exception #"EOF while reading string" "\\"
Exception #"Unsupported escape character: \\o" "\\o"
(deftest t-Characters
(let [f (temp-file "clojure.core-reader" "test")]
(doseq [source [:string :file]]
(testing (str "Valid char literals read from " (name source))
(are [x form] (= x (read-from source f form))
(first "o") "\\o"
(char 0) "\\o0"
(char 0) "\\o000"
(char 047) "\\o47"
(char 0377) "\\o377"
(first "u") "\\u"
(first "A") "\\u0041"
(char 0) "\\u0000"
(char 0xd7ff) "\\ud7ff"
(char 0xe000) "\\ue000"
(char 0xffff) "\\uffff"))
(testing (str "Errors reading char literals from " (name source))
(are [err msg form] (thrown-with-cause-msg? err msg (read-from source f form))
Exception #"EOF while reading character" "\\"
Exception #"Unsupported character: \\00" "\\00"
Exception #"Unsupported character: \\0009" "\\0009"
(deftest Instants
(testing "Instants are read as java.util.Date by default"
(is (= java.util.Date (class #inst "2010-11-12T13:14:15.666"))))
(let [s "#inst \"2010-11-12T13:14:15.666-06:00\""]
(binding [*data-readers* {'inst read-instant-date}]
(testing "read-instant-date produces java.util.Date"
(is (= java.util.Date (class (read-string s)))))
(testing "java.util.Date instants round-trips"
(is (= (-> s read-string)
(-> s read-string pr-str read-string))))
(testing "java.util.Date instants round-trip throughout the year"
(doseq [month (range 1 13) day (range 1 29) hour (range 1 23)]
(let [s (format "#inst \"2010-%02d-%02dT%02d:14:15.666-06:00\"" month day hour)]
(is (= (-> s read-string)
(-> s read-string pr-str read-string))))))
(testing "java.util.Date handling DST in time zones"
(let [dtz (TimeZone/getDefault)]
(try
;; A timezone with DST in effect during 2010-11-12
(TimeZone/setDefault (TimeZone/getTimeZone "Australia/Sydney"))
(is (= (-> s read-string)
(-> s read-string pr-str read-string)))
(finally (TimeZone/setDefault dtz)))))
(testing "java.util.Date should always print in UTC"
(let [d (read-string s)
pstr (print-str d)
len (.length pstr)]
(is (= (subs pstr (- len 7)) "-00:00\"")))))
(binding [*data-readers* {'inst read-instant-calendar}]
(testing "read-instant-calendar produces java.util.Calendar"
(is (instance? java.util.Calendar (read-string s))))
(testing "java.util.Calendar round-trips"
(is (= (-> s read-string)
(-> s read-string pr-str read-string))))
(testing "java.util.Calendar remembers timezone in literal"
(is (= "#inst \"2010-11-12T13:14:15.666-06:00\""
(-> s read-string pr-str)))
(is (= (-> s read-string)
(-> s read-string pr-str read-string))))
(testing "java.util.Calendar preserves milliseconds"
(is (= 666 (-> s read-string
(.get java.util.Calendar/MILLISECOND)))))))
(let [s "#inst \"2010-11-12T13:14:15.123456789\""
s2 "#inst \"2010-11-12T13:14:15.123\""
s3 "#inst \"2010-11-12T13:14:15.123456789123\""]
(binding [*data-readers* {'inst read-instant-timestamp}]
(testing "read-instant-timestamp produces java.sql.Timestamp"
(is (= java.sql.Timestamp (class (read-string s)))))
(testing "java.sql.Timestamp preserves nanoseconds"
(is (= 123456789 (-> s read-string .getNanos)))
(is (= 123456789 (-> s read-string pr-str read-string .getNanos)))
;; truncate at nanos for s3
(is (= 123456789 (-> s3 read-string pr-str read-string .getNanos))))
(testing "java.sql.Timestamp should compare nanos"
(is (= (read-string s) (read-string s3)))
(is (not= (read-string s) (read-string s2)))))
(binding [*data-readers* {'inst read-instant-date}]
(testing "read-instant-date should truncate at milliseconds"
(is (= (read-string s) (read-string s2) (read-string s3))))))
(let [s "#inst \"2010-11-12T03:14:15.123+05:00\""
s2 "#inst \"2010-11-11T22:14:15.123Z\""]
(binding [*data-readers* {'inst read-instant-date}]
(testing "read-instant-date should convert to UTC"
(is (= (read-string s) (read-string s2)))))
(binding [*data-readers* {'inst read-instant-timestamp}]
(testing "read-instant-timestamp should convert to UTC"
(is (= (read-string s) (read-string s2)))))
(binding [*data-readers* {'inst read-instant-calendar}]
(testing "read-instant-calendar should preserve timezone"
(is (not= (read-string s) (read-string s2)))))))
(deftest unknown-tag
(let [my-unknown (fn [tag val] {:unknown-tag tag :value val})
throw-on-unknown (fn [tag val] (throw (RuntimeException. (str "No data reader function for tag " tag))))
my-uuid (partial my-unknown 'uuid)
u "#uuid \"550e8400-e29b-41d4-a716-446655440000\""
s "#never.heard.of/some-tag [1 2]" ]
(binding [*data-readers* {'uuid my-uuid}
*default-data-reader-fn* my-unknown]
(testing "Unknown tag"
(is (= (read-string s)
{:unknown-tag 'never.heard.of/some-tag
:value [1 2]})))
(testing "Override uuid tag"
(is (= (read-string u)
{:unknown-tag 'uuid
:value "550e8400-e29b-41d4-a716-446655440000"}))))
(binding [*default-data-reader-fn* throw-on-unknown]
(testing "Unknown tag with custom throw-on-unknown"
(are [err msg form] (thrown-with-msg? err msg (read-string form))
Exception #"No data reader function for tag foo" "#foo [1 2]"
Exception #"No data reader function for tag bar/foo" "#bar/foo [1 2]"
Exception #"No data reader function for tag bar.baz/foo" "#bar.baz/foo [1 2]")))
(testing "Unknown tag out-of-the-box behavior (like Clojure 1.4)"
(are [err msg form] (thrown-with-msg? err msg (read-string form))
Exception #"No reader function for tag foo" "#foo [1 2]"
Exception #"No reader function for tag bar/foo" "#bar/foo [1 2]"
Exception #"No reader function for tag bar.baz/foo" "#bar.baz/foo [1 2]"))))
(deftest preserve-read-cond-test
(let [x (read-string {:read-cond :preserve} "#?(:clj foo :cljs bar)" )]
(is (reader-conditional? x))
(is (not (:splicing? x)))
(is (= :foo (get x :no-such-key :foo)))
(is (= (:form x) '(:clj foo :cljs bar)))
(is (= x (reader-conditional '(:clj foo :cljs bar) false))))
(let [x (read-string {:read-cond :preserve} "#?@(:clj [foo])" )]
(is (reader-conditional? x))
(is (:splicing? x))
(is (= :foo (get x :no-such-key :foo)))
(is (= (:form x) '(:clj [foo])))
(is (= x (reader-conditional '(:clj [foo]) true))))
(is (thrown-with-msg? RuntimeException #"No reader function for tag"
(read-string {:read-cond :preserve} "#js {:x 1 :y 2}" )))
(let [x (read-string {:read-cond :preserve} "#?(:cljs #js {:x 1 :y 2})")
[platform tl] (:form x)]
(is (reader-conditional? x))
(is (tagged-literal? tl))
(is (= 'js (:tag tl)))
(is (= {:x 1 :y 2} (:form tl)))
(is (= :foo (get tl :no-such-key :foo)))
(is (= tl (tagged-literal 'js {:x 1 :y 2}))))
(testing "print form roundtrips"
(doseq [s ["#?(:clj foo :cljs bar)"
"#?(:cljs #js {:x 1, :y 2})"
"#?(:clj #clojure.test_clojure.reader.TestRecord [42 85])"]]
(is (= s (pr-str (read-string {:read-cond :preserve} s)))))))
(deftest reader-conditionals
(testing "basic read-cond"
(is (= '[foo-form]
(read-string {:read-cond :allow :features #{:foo}} "[#?(:foo foo-form :bar bar-form)]")))
(is (= '[bar-form]
(read-string {:read-cond :allow :features #{:bar}} "[#?(:foo foo-form :bar bar-form)]")))
(is (= '[foo-form]
(read-string {:read-cond :allow :features #{:foo :bar}} "[#?(:foo foo-form :bar bar-form)]")))
(is (= '[]
(read-string {:read-cond :allow :features #{:baz}} "[#?( :foo foo-form :bar bar-form)]"))))
(testing "environmental features"
(is (= "clojure" #?(:clj "clojure" :cljs "clojurescript" :default "default"))))
(testing "default features"
(is (= "default" #?(:clj-clr "clr" :cljs "cljs" :default "default"))))
(testing "splicing"
(is (= [] [#?@(:clj [])]))
(is (= [:a] [#?@(:clj [:a])]))
(is (= [:a :b] [#?@(:clj [:a :b])]))
(is (= [:a :b :c] [#?@(:clj [:a :b :c])]))
(is (= [:a :b :c] [#?@(:clj [:a :b :c])])))
(testing "nested splicing"
(is (= [:a :b :c :d :e]
[#?@(:clj [:a #?@(:clj [:b #?@(:clj [:c]) :d]):e])]))
(is (= '(+ 1 (+ 2 3))
'(+ #?@(:clj [1 (+ #?@(:clj [2 3]))]))))
(is (= '(+ (+ 2 3) 1)
'(+ #?@(:clj [(+ #?@(:clj [2 3])) 1]))))
(is (= [:a [:b [:c] :d] :e]
[#?@(:clj [:a [#?@(:clj [:b #?@(:clj [[:c]]) :d])] :e])])))
(testing "bypass unknown tagged literals"
(is (= [1 2 3] #?(:cljs #js [1 2 3] :clj [1 2 3])))
(is (= :clojure #?(:foo #some.nonexistent.Record {:x 1} :clj :clojure))))
(testing "error cases"
(is (thrown-with-msg? RuntimeException #"Feature should be a keyword" (read-string {:read-cond :allow} "#?((+ 1 2) :a)")))
(is (thrown-with-msg? RuntimeException #"even number of forms" (read-string {:read-cond :allow} "#?(:cljs :a :clj)")))
(is (thrown-with-msg? RuntimeException #"read-cond-splicing must implement" (read-string {:read-cond :allow} "#?@(:clj :a)")))
(is (thrown-with-msg? RuntimeException #"is reserved" (read-string {:read-cond :allow} "#?@(:foo :a :else :b)")))
(is (thrown-with-msg? RuntimeException #"must be a list" (read-string {:read-cond :allow} "#?[:foo :a :else :b]")))
(is (thrown-with-msg? RuntimeException #"Conditional read not allowed" (read-string {:read-cond :BOGUS} "#?[:clj :a :default nil]")))
(is (thrown-with-msg? RuntimeException #"Conditional read not allowed" (read-string "#?[:clj :a :default nil]")))
(is (thrown-with-msg? RuntimeException #"Reader conditional splicing not allowed at the top level" (read-string {:read-cond :allow} "#?@(:clj [1 2])")))
(is (thrown-with-msg? RuntimeException #"Reader conditional splicing not allowed at the top level" (read-string {:read-cond :allow} "#?@(:clj [1])")))
(is (thrown-with-msg? RuntimeException #"Reader conditional splicing not allowed at the top level" (read-string {:read-cond :allow} "#?@(:clj []) 1"))))
(testing "clj-1698-regression"
(let [opts {:features #{:clj} :read-cond :allow}]
(is (= 1 (read-string opts "#?(:cljs {'a 1 'b 2} :clj 1)")))
(is (= 1 (read-string opts "#?(:cljs (let [{{b :b} :a {d :d} :c} {}]) :clj 1)")))
(is (= '(def m {}) (read-string opts "(def m #?(:cljs ^{:a :b} {} :clj ^{:a :b} {}))")))
(is (= '(def m {}) (read-string opts "(def m #?(:cljs ^{:a :b} {} :clj ^{:a :b} {}))")))
(is (= 1 (read-string opts "#?(:cljs {:a #_:b :c} :clj 1)")))))
(testing "nil expressions"
(is (nil? #?(:default nil)))
(is (nil? #?(:foo :bar :clj nil)))
(is (nil? #?(:clj nil :foo :bar)))
(is (nil? #?(:foo :bar :default nil)))))
clojure
(ns clojure.test-clojure.protocols
(:use clojure.test clojure.test-clojure.protocols.examples)
(:require [clojure.test-clojure.protocols.more-examples :as other]
[clojure.set :as set]
clojure.test-helper)
(:import [clojure.test_clojure.protocols.examples ExampleInterface]))
(deftest protocols-test
(testing "protocol fns have useful metadata"
(let [common-meta {:ns (find-ns 'clojure.test-clojure.protocols.examples)
:protocol #'ExampleProtocol :tag nil}]
(are [m f] (= (merge common-meta m)
(meta (var f)))
{:name 'foo :arglists '([a]) :doc "method with one arg"} foo
{:name 'bar :arglists '([a b]) :doc "method with two args"} bar
{:name 'baz :arglists '([a] [a b]) :doc "method with multiple arities" :tag 'java.lang.String} baz
{:name 'with-quux :arglists '([a]) :doc "method name with a hyphen"} with-quux)))
(testing "protocol fns throw IllegalArgumentException if no impl matches"
(is (thrown-with-msg?
IllegalArgumentException
#"No implementation of method: :foo of protocol: #'clojure.test-clojure.protocols.examples/ExampleProtocol found for class: java.lang.Long"
(foo 10))))
(testing "protocols generate a corresponding interface using _ instead of - for method names"
(is (= ["bar" "baz" "baz" "foo" "with_quux"] (method-names clojure.test_clojure.protocols.examples.ExampleProtocol))))
(testing "protocol will work with instances of its interface (use for interop, not in Clojure!)"
(let [obj (proxy [clojure.test_clojure.protocols.examples.ExampleProtocol] []
(foo [] "foo!"))]
(is (= "foo!" (.foo obj)) "call through interface")
(is (= "foo!" (foo obj)) "call through protocol")))
(testing "you can implement just part of a protocol if you want"
(let [obj (reify ExampleProtocol
(baz [a b] "two-arg baz!"))]
(is (= "two-arg baz!" (baz obj nil)))
(is (thrown? AbstractMethodError (baz obj)))))
(testing "error conditions checked when defining protocols"
(is (thrown-with-cause-msg?
Exception
#"Definition of function m in protocol badprotdef must take at least one arg."
(eval '(defprotocol badprotdef (m [])))))
(is (thrown-with-cause-msg?
Exception
#"Function m in protocol badprotdef was redefined. Specify all arities in single definition."
(eval '(defprotocol badprotdef (m [this arg]) (m [this arg1 arg2]))))))
(testing "you can redefine a protocol with different methods"
(eval '(defprotocol Elusive (old-method [x])))
(eval '(defprotocol Elusive (new-method [x])))
(is (= :new-method (eval '(new-method (reify Elusive (new-method [x] :new-method))))))
(is (fails-with-cause? IllegalArgumentException #"No method of interface: .*\.Elusive found for function: old-method of protocol: Elusive \(The protocol method may have been defined before and removed\.\)"
(eval '(old-method (reify Elusive (new-method [x] :new-method))))))))
(deftest marker-tests
(testing "That a marker protocol has no methods"
(is (= '() (method-names clojure.test_clojure.protocols.examples.MarkerProtocol))))
(testing "That types with markers are reportedly satifying them."
(let [hm (HasMarkers.)
wgm (WillGetMarker.)]
(is (satisfies? MarkerProtocol hm))
(is (satisfies? MarkerProtocol2 hm))
(is (satisfies? MarkerProtocol wgm)))))
(deftype ExtendTestWidget [name])
(deftype HasProtocolInline []
ExampleProtocol
(foo [this] :inline))
(deftest extend-test
(testing "you can extend a protocol to a class"
(extend String ExampleProtocol
{:foo identity})
(is (= "pow" (foo "pow"))))
(testing "you can have two methods with the same name. Just use namespaces!"
(extend String other/SimpleProtocol
{:foo (fn [s] (.toUpperCase s))})
(is (= "POW" (other/foo "pow"))))
(testing "you can extend deftype types"
(extend
ExtendTestWidget
ExampleProtocol
{:foo (fn [this] (str "widget " (.name this)))})
(is (= "widget z" (foo (ExtendTestWidget. "z"))))))
(deftest record-marker-interfaces
(testing "record? and type? return expected result for IRecord and IType"
(let [r (TestRecord. 1 2)]
(is (record? r)))))
(deftest illegal-extending
(testing "you cannot extend a protocol to a type that implements the protocol inline"
(is (fails-with-cause? IllegalArgumentException #".*HasProtocolInline already directly implements interface"
(eval '(extend clojure.test_clojure.protocols.HasProtocolInline
clojure.test-clojure.protocols.examples/ExampleProtocol
{:foo (fn [_] :extended)})))))
(testing "you cannot extend to an interface"
(is (fails-with-cause? IllegalArgumentException #"interface clojure.test_clojure.protocols.examples.ExampleProtocol is not a protocol"
(eval '(extend clojure.test_clojure.protocols.HasProtocolInline
clojure.test_clojure.protocols.examples.ExampleProtocol
{:foo (fn [_] :extended)}))))))
(deftype ExtendsTestWidget []
ExampleProtocol)
#_(deftest extends?-test
(reload-example-protocols)
(testing "returns false if a type does not implement the protocol at all"
(is (false? (extends? other/SimpleProtocol ExtendsTestWidget))))
(testing "returns true if a type implements the protocol directly" ;; semantics changed 4/15/2010
(is (true? (extends? ExampleProtocol ExtendsTestWidget))))
(testing "returns true if a type explicitly extends protocol"
(extend
ExtendsTestWidget
other/SimpleProtocol
{:foo identity})
(is (true? (extends? other/SimpleProtocol ExtendsTestWidget)))))
(deftype ExtendersTestWidget [])
#_(deftest extenders-test
(reload-example-protocols)
(testing "a fresh protocol has no extenders"
(is (nil? (extenders ExampleProtocol))))
(testing "extending with no methods doesn't count!"
(deftype Something [])
(extend ::Something ExampleProtocol)
(is (nil? (extenders ExampleProtocol))))
(testing "extending a protocol (and including an impl) adds an entry to extenders"
(extend ExtendersTestWidget ExampleProtocol {:foo identity})
(is (= [ExtendersTestWidget] (extenders ExampleProtocol)))))
(deftype SatisfiesTestWidget []
ExampleProtocol)
#_(deftest satisifies?-test
(reload-example-protocols)
(let [whatzit (SatisfiesTestWidget.)]
(testing "returns false if a type does not implement the protocol at all"
(is (false? (satisfies? other/SimpleProtocol whatzit))))
(testing "returns true if a type implements the protocol directly"
(is (true? (satisfies? ExampleProtocol whatzit))))
(testing "returns true if a type explicitly extends protocol"
(extend
SatisfiesTestWidget
other/SimpleProtocol
{:foo identity})
(is (true? (satisfies? other/SimpleProtocol whatzit))))) )
(deftype ReExtendingTestWidget [])
#_(deftest re-extending-test
(reload-example-protocols)
(extend
ReExtendingTestWidget
ExampleProtocol
{:foo (fn [_] "first foo")
:baz (fn [_] "first baz")})
(testing "if you re-extend, the old implementation is replaced (not merged!)"
(extend
ReExtendingTestWidget
ExampleProtocol
{:baz (fn [_] "second baz")
:bar (fn [_ _] "second bar")})
(let [whatzit (ReExtendingTestWidget.)]
(is (thrown? IllegalArgumentException (foo whatzit)))
(is (= "second bar" (bar whatzit nil)))
(is (= "second baz" (baz whatzit))))))
(defrecord DefrecordObjectMethodsWidgetA [a])
(defrecord DefrecordObjectMethodsWidgetB [a])
(deftest defrecord-object-methods-test
(testing "= depends on fields and type"
(is (true? (= (DefrecordObjectMethodsWidgetA. 1) (DefrecordObjectMethodsWidgetA. 1))))
(is (false? (= (DefrecordObjectMethodsWidgetA. 1) (DefrecordObjectMethodsWidgetA. 2))))
(is (false? (= (DefrecordObjectMethodsWidgetA. 1) (DefrecordObjectMethodsWidgetB. 1))))))
(deftest defrecord-interfaces-test
(testing "java.util.Map"
(let [rec (r 1 2)]
(is (= 2 (.size rec)))
(is (= 3 (.size (assoc rec :c 3))))
(is (not (.isEmpty rec)))
(is (.isEmpty (EmptyRecord.)))
(is (.containsKey rec :a))
(is (not (.containsKey rec :c)))
(is (.containsValue rec 1))
(is (not (.containsValue rec 3)))
(is (= 1 (.get rec :a)))
(is (thrown? UnsupportedOperationException (.put rec :a 1)))
(is (thrown? UnsupportedOperationException (.remove rec :a)))
(is (thrown? UnsupportedOperationException (.putAll rec {})))
(is (thrown? UnsupportedOperationException (.clear rec)))
(is (= #{:a :b} (.keySet rec)))
(is (= #{1 2} (set (.values rec))))
(is (= #{[:a 1] [:b 2]} (.entrySet rec)))
))
(testing "IPersistentCollection"
(testing ".cons"
(let [rec (r 1 2)]
(are [x] (= rec (.cons rec x))
nil {})
(is (= (r 1 3) (.cons rec {:b 3})))
(is (= (r 1 4) (.cons rec [:b 4])))
(is (= (r 1 5) (.cons rec (MapEntry. :b 5))))))))
(deftest test-statics
(testing "that a record has its generated static methods"
(let [r1 (RecordToTestStatics1. 1)
r2 (RecordToTestStatics2. 1 2)
r3 (RecordToTestStatics3. 1 2 3)
rn (RecordToTestStatics3. 1 nil nil)]
(testing "that a record created with the ctor equals one by the static factory method"
(is (= r1 (RecordToTestStatics1/create {:a 1})))
(is (= r2 (RecordToTestStatics2/create {:a 1 :b 2})))
(is (= r3 (RecordToTestStatics3/create {:a 1 :b 2 :c 3})))
(is (= rn (RecordToTestStatics3/create {:a 1}))))
(testing "that a literal record equals one by the static factory method"
(is (= #clojure.test_clojure.protocols.RecordToTestStatics1{:a 1} (RecordToTestStatics1/create {:a 1})))
(is (= #clojure.test_clojure.protocols.RecordToTestStatics2{:a 1 :b 2} (RecordToTestStatics2/create {:a 1 :b 2})))
(is (= #clojure.test_clojure.protocols.RecordToTestStatics3{:a 1 :b 2 :c 3} (RecordToTestStatics3/create {:a 1 :b 2 :c 3})))
(is (= #clojure.test_clojure.protocols.RecordToTestStatics3{:a 1} (RecordToTestStatics3/create {:a 1})))
(is (= #clojure.test_clojure.protocols.RecordToTestStatics3{:a 1 :b nil :c nil} (RecordToTestStatics3/create {:a 1}))))))
(testing "that records and types have a sane generated basis method"
(let [rb (clojure.test_clojure.protocols.RecordToTestBasis/getBasis)
rbh (clojure.test_clojure.protocols.RecordToTestBasisHinted/getBasis)
rhg (clojure.test_clojure.protocols.RecordToTestHugeBasis/getBasis)
tb (clojure.test_clojure.protocols.TypeToTestBasis/getBasis)
tbh (clojure.test_clojure.protocols.TypeToTestBasisHinted/getBasis)]
(is (= '[a b c] rb))
(is (= '[a b c] rb))
(is (= '[a b c d e f g h i j k l m n o p q r s t u v w x y z] rhg))
(testing "that record basis hinting looks as we expect"
(is (= (:tag (meta (rbh 0))) 'String))
(is (= (:tag (meta (rbh 1))) 'Long))
(is (nil? (:tag (meta (rbh 2))))))
(testing "that type basis hinting looks as we expect"
(is (= (:tag (meta (tbh 0))) 'String))
(is (= (:tag (meta (tbh 1))) 'Long))
(is (nil? (:tag (meta (tbh 2)))))))))
(deftest test-record-factory-fns
(testing "if the definition of a defrecord generates the appropriate factory functions"
(let [r (RecordToTestFactories. 1 2 3)
r-n (RecordToTestFactories. nil nil nil)
huge (RecordToTestHugeFactories. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26)
r-a (map->RecordToTestA {:a 1 :b 2})
r-b (map->RecordToTestB {:a 1 :b 2})
r-d (RecordToTestDegenerateFactories.)]
(testing "that a record created with the ctor equals one by the positional factory fn"
(is (= r (->RecordToTestFactories 1 2 3)))
(is (= huge (->RecordToTestHugeFactories 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26))))
(testing "that a record created with the ctor equals one by the map-> factory fn"
(is (= r (map->RecordToTestFactories {:a 1 :b 2 :c 3})))
(is (= r-n (map->RecordToTestFactories {})))
(is (= r (map->RecordToTestFactories (map->RecordToTestFactories {:a 1 :b 2 :c 3}))))
(is (= r-n (map->RecordToTestFactories (map->RecordToTestFactories {}))))
(is (= r-d (map->RecordToTestDegenerateFactories {})))
(is (= r-d (map->RecordToTestDegenerateFactories
(map->RecordToTestDegenerateFactories {})))))
(testing "that ext maps work correctly"
(is (= (assoc r :xxx 42) (map->RecordToTestFactories {:a 1 :b 2 :c 3 :xxx 42})))
(is (= (assoc r :xxx 42) (map->RecordToTestFactories (map->RecordToTestFactories
{:a 1 :b 2 :c 3 :xxx 42}))))
(is (= (assoc r-n :xxx 42) (map->RecordToTestFactories {:xxx 42})))
(is (= (assoc r-n :xxx 42) (map->RecordToTestFactories (map->RecordToTestFactories
{:xxx 42}))))
(is (= (assoc r-d :xxx 42) (map->RecordToTestDegenerateFactories {:xxx 42})))
(is (= (assoc r-d :xxx 42) (map->RecordToTestDegenerateFactories
(map->RecordToTestDegenerateFactories {:xxx 42})))))
(testing "record equality"
(is (not= r-a r-b))
(is (= (into {} r-a) (into {} r-b)))
(is (not= (into {} r-a) r-b))
(is (= (map->RecordToTestA {:a 1 :b 2})
(map->RecordToTestA (map->RecordToTestB {:a 1 :b 2}))))
(is (= (map->RecordToTestA {:a 1 :b 2 :c 3})
(map->RecordToTestA (map->RecordToTestB {:a 1 :b 2 :c 3}))))
(is (= (map->RecordToTestA {:a 1 :d 4})
(map->RecordToTestA (map->RecordToTestDegenerateFactories {:a 1 :d 4}))))
(is (= r-n (map->RecordToTestFactories (java.util.HashMap.))))
(is (= r-a (map->RecordToTestA (into {} r-b))))
(is (= r-a (map->RecordToTestA r-b)))
(is (not= r-a (map->RecordToTestB r-a)))
(is (= r (assoc r-n :a 1 :b 2 :c 3)))
(is (not= r-a (assoc r-n :a 1 :b 2)))
(is (not= (assoc r-b :c 3 :d 4) (assoc r-n :a 1 :b 2 :c 3 :d 4)))
(is (= (into {} (assoc r-b :c 3 :d 4)) (into {} (assoc r-n :a 1 :b 2 :c 3 :d 4))))
(is (= (assoc r :d 4) (assoc r-n :a 1 :b 2 :c 3 :d 4))))
(testing "that factory functions have docstrings"
;; just test non-nil to avoid overspecifiying what's in the docstring
(is (false? (-> ->RecordToTestFactories var meta :doc nil?)))
(is (false? (-> map->RecordToTestFactories var meta :doc nil?))))
(testing "that a literal record equals one by the positional factory fn"
(is (= #clojure.test_clojure.protocols.RecordToTestFactories{:a 1 :b 2 :c 3} (->RecordToTestFactories 1 2 3)))
(is (= #clojure.test_clojure.protocols.RecordToTestFactories{:a 1 :b nil :c nil} (->RecordToTestFactories 1 nil nil)))
(is (= #clojure.test_clojure.protocols.RecordToTestFactories{:a [] :b {} :c ()} (->RecordToTestFactories [] {} ()))))
(testing "that a literal record equals one by the map-> factory fn"
(is (= #clojure.test_clojure.protocols.RecordToTestFactories{:a 1 :b 2 :c 3} (map->RecordToTestFactories {:a 1 :b 2 :c 3})))
(is (= #clojure.test_clojure.protocols.RecordToTestFactories{:a 1 :b nil :c nil} (map->RecordToTestFactories {:a 1})))
(is (= #clojure.test_clojure.protocols.RecordToTestFactories{:a nil :b nil :c nil} (map->RecordToTestFactories {})))))))
(deftest deftype-factory-fn
(testing "that the ->T factory is gen'd for a deftype and that it works"
(is (= (.a (TypeToTestFactory. 42)) (.a (->TypeToTestFactory 42))))
(is (compare-huge-types
(TypeToTestHugeFactories. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26)
(->TypeToTestHugeFactories 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26))))
(testing "that the generated factory checks arity constraints"
(is (thrown? clojure.lang.ArityException (->TypeToTestHugeFactories 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25)))
(is (thrown? clojure.lang.ArityException (->TypeToTestHugeFactories 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27)))))
(deftest test-ctor-literals
(testing "that constructor calls to print-dup'able classes are supported as literals"
(is (= "Hi" #java.lang.String["Hi"]))
(is (= 42 #java.lang.Long[42]))
(is (= 42 #java.lang.Long["42"]))
(is (= [:a 42] #clojure.lang.MapEntry[:a 42])))
(testing "that constructor literals are embeddable"
(is (= 42 #java.lang.Long[#java.lang.String["42"]])))
(testing "that constructor literals work for deftypes too"
(is (= (.a (TypeToTestFactory. 42)) (.a #clojure.test_clojure.protocols.TypeToTestFactory[42])))
(is (compare-huge-types
(TypeToTestHugeFactories. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26)
#clojure.test_clojure.protocols.TypeToTestHugeFactories[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]))))
(defrecord RecordToTestLiterals [a])
(defrecord TestNode [v l r])
(deftype TypeToTestLiterals [a])
(def lang-str "en")
(deftest exercise-literals
(testing "that ctor literals can be used in common 'places'"
(is (= (RecordToTestLiterals. ()) #clojure.test_clojure.protocols.RecordToTestLiterals[()]))
(is (= (.a (TypeToTestLiterals. ())) (.a #clojure.test_clojure.protocols.TypeToTestLiterals[()])))
(is (= (RecordToTestLiterals. 42) (into #clojure.test_clojure.protocols.RecordToTestLiterals[0] {:a 42})))
(is (= (RecordToTestLiterals. (RecordToTestLiterals. 42)) (RecordToTestLiterals. #clojure.test_clojure.protocols.RecordToTestLiterals[42])))
(is (= (RecordToTestLiterals. (RecordToTestLiterals. 42)) (->RecordToTestLiterals #clojure.test_clojure.protocols.RecordToTestLiterals[42])))
(is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
#clojure.test_clojure.protocols.RecordToTestLiterals[#clojure.test_clojure.protocols.RecordToTestLiterals[42]]))
(is (= (TestNode. 1
(TestNode. 2
(TestNode. 3
nil
nil)
nil)
(TestNode. 4
(TestNode. 5
(TestNode. 6
nil
nil)
nil)
(TestNode. 7
nil
nil)))
#clojure.test_clojure.protocols.TestNode{:v 1
:l #clojure.test_clojure.protocols.TestNode{:v 2
:l #clojure.test_clojure.protocols.TestNode{:v 3 :l nil :r nil}
:r nil}
:r #clojure.test_clojure.protocols.TestNode{:v 4
:l #clojure.test_clojure.protocols.TestNode{:v 5
:l #clojure.test_clojure.protocols.TestNode{:v 6 :l nil :r nil}
:r nil}
:r #clojure.test_clojure.protocols.TestNode{:v 7 :l nil :r nil}}})))
(testing "that records and types are evalable"
(is (= (RecordToTestLiterals. 42) (eval #clojure.test_clojure.protocols.RecordToTestLiterals[42])))
(is (= (RecordToTestLiterals. 42) (eval #clojure.test_clojure.protocols.RecordToTestLiterals{:a 42})))
(is (= (RecordToTestLiterals. 42) (eval (RecordToTestLiterals. 42))))
(is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
(eval #clojure.test_clojure.protocols.RecordToTestLiterals[#clojure.test_clojure.protocols.RecordToTestLiterals[42]])))
(is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
(eval #clojure.test_clojure.protocols.RecordToTestLiterals[#clojure.test_clojure.protocols.RecordToTestLiterals{:a 42}])))
(is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
(eval #clojure.test_clojure.protocols.RecordToTestLiterals{:a #clojure.test_clojure.protocols.RecordToTestLiterals[42]})))
(is (= 42 (.a (eval #clojure.test_clojure.protocols.TypeToTestLiterals[42])))))
(testing "that ctor literals only work with constants or statics"
(is (thrown? Exception (read-string "#java.util.Locale[(str 'en)]")))
(is (thrown? Exception (read-string "(let [s \"en\"] #java.util.Locale[(str 'en)])")))
(is (thrown? Exception (read-string "#clojure.test_clojure.protocols.RecordToTestLiterals{(keyword \"a\") 42}"))))
(testing "that ctors can have whitespace after class name but before {"
(is (= (RecordToTestLiterals. 42)
(read-string "#clojure.test_clojure.protocols.RecordToTestLiterals {:a 42}"))))
(testing "that the correct errors are thrown with malformed literals"
(is (thrown-with-msg?
Exception
#"Unreadable constructor form.*"
(read-string "#java.util.Locale(\"en\")")))
(is (thrown-with-msg?
Exception
#"Unexpected number of constructor arguments.*"
(read-string "#java.util.Locale[\"\" \"\" \"\" \"\"]")))
(is (thrown? Exception (read-string "#java.util.Nachos(\"en\")")))))
(defrecord RecordToTestPrinting [a b])
(deftest defrecord-printing
(testing "that the default printer gives the proper representation"
(let [r (RecordToTestPrinting. 1 2)]
(is (= "#clojure.test_clojure.protocols.RecordToTestPrinting{:a 1, :b 2}"
(pr-str r)))
(is (= "#clojure.test_clojure.protocols.RecordToTestPrinting[1, 2]"
(binding [*print-dup* true] (pr-str r))))
(is (= "#clojure.test_clojure.protocols.RecordToTestPrinting{:a 1, :b 2}"
(binding [*print-dup* true *verbose-defrecords* true] (pr-str r)))))))
(deftest test-record-and-type-field-names
(testing "that types and records allow names starting with double-underscore.
This is a regression test for CLJ-837."
(let [r (RecordToTest__. 1 2)
t (TypeToTest__. 3 4)]
(are [x y] (= x y)
1 (:__a r)
2 (:___b r)
3 (.__a t)
4 (.___b t)))))
(deftest hinting-test
(testing "that primitive hinting requiring no coercion works as expected"
(is (= (RecordToTestLongHint. 42) #clojure.test_clojure.protocols.RecordToTestLongHint{:a 42}))
(is (= (RecordToTestLongHint. 42) #clojure.test_clojure.protocols.RecordToTestLongHint[42]))
(is (= (RecordToTestLongHint. 42) (clojure.test_clojure.protocols.RecordToTestLongHint/create {:a 42})))
(is (= (RecordToTestLongHint. 42) (map->RecordToTestLongHint {:a 42})))
(is (= (RecordToTestLongHint. 42) (->RecordToTestLongHint 42)))
(is (= (.a (TypeToTestLongHint. 42)) (.a (->TypeToTestLongHint (long 42)))))
(testing "that invalid primitive types on hinted defrecord fields fails"
(is (thrown?
ClassCastException
(read-string "#clojure.test_clojure.protocols.RecordToTestLongHint{:a \"\"}")))
(is (thrown?
IllegalArgumentException
(read-string "#clojure.test_clojure.protocols.RecordToTestLongHint[\"\"]")))
(is (thrown?
IllegalArgumentException
(read-string "#clojure.test_clojure.protocols.TypeToTestLongHint[\"\"]")))
(is (thrown?
ClassCastException
(clojure.test_clojure.protocols.RecordToTestLongHint/create {:a ""})))
(is (thrown?
ClassCastException
(map->RecordToTestLongHint {:a ""})))
(is (thrown?
ClassCastException
(->RecordToTestLongHint "")))))
(testing "that primitive hinting requiring coercion works as expected"
(is (= (RecordToTestByteHint. 42) (clojure.test_clojure.protocols.RecordToTestByteHint/create {:a (byte 42)})))
(is (= (RecordToTestByteHint. 42) (map->RecordToTestByteHint {:a (byte 42)})))
(is (= (RecordToTestByteHint. 42) (->RecordToTestByteHint (byte 42))))
(is (= (.a (TypeToTestByteHint. 42)) (.a (->TypeToTestByteHint (byte 42))))))
(testing "that primitive hinting for non-numerics works as expected"
(is (= (RecordToTestBoolHint. true) #clojure.test_clojure.protocols.RecordToTestBoolHint{:a true}))
(is (= (RecordToTestBoolHint. true) #clojure.test_clojure.protocols.RecordToTestBoolHint[true]))
(is (= (RecordToTestBoolHint. true) (clojure.test_clojure.protocols.RecordToTestBoolHint/create {:a true})))
(is (= (RecordToTestBoolHint. true) (map->RecordToTestBoolHint {:a true})))
(is (= (RecordToTestBoolHint. true) (->RecordToTestBoolHint true))))
(testing "covariant hints -- deferred"))
(deftest reify-test
(testing "of an interface"
(let [s :foo
r (reify
java.util.List
(contains [_ o] (= s o)))]
(testing "implemented methods"
(is (true? (.contains r :foo)))
(is (false? (.contains r :bar))))
(testing "unimplemented methods"
(is (thrown? AbstractMethodError (.add r :baz))))))
(testing "of two interfaces"
(let [r (reify
java.util.List
(contains [_ o] (= :foo o))
java.util.Collection
(isEmpty [_] false))]
(is (true? (.contains r :foo)))
(is (false? (.contains r :bar)))
(is (false? (.isEmpty r)))))
(testing "you can't define a method twice"
(is (thrown? Exception
(eval '(reify
java.util.List
(size [_] 10)
java.util.Collection
(size [_] 20))))))
(testing "you can't define a method not on an interface/protocol/j.l.Object"
(is (thrown? Exception
(eval '(reify java.util.List (foo [_]))))))
(testing "of a protocol"
(let [r (reify
ExampleProtocol
(bar [this o] o)
(baz [this] 1)
(baz [this o] 2))]
(is (= :foo (.bar r :foo)))
(is (= 1 (.baz r)))
(is (= 2 (.baz r nil)))))
(testing "destructuring in method def"
(let [r (reify
ExampleProtocol
(bar [this [_ _ item]] item))]
(is (= :c (.bar r [:a :b :c])))))
(testing "methods can recur"
(let [r (reify
java.util.List
(get [_ index]
(if (zero? index)
:done
(recur (dec index)))))]
(is (= :done (.get r 0)))
(is (= :done (.get r 1)))))
(testing "disambiguating with type hints"
(testing "you must hint an overloaded method"
(is (thrown? Exception
(eval '(reify clojure.test_clojure.protocols.examples.ExampleInterface (hinted [_ o]))))))
(testing "hinting"
(let [r (reify
ExampleInterface
(hinted [_ ^int i] (inc i))
(hinted [_ ^String s] (str s s)))]
(is (= 2 (.hinted r 1)))
(is (= "xoxo" (.hinted r "xo")))))))
clojure
(ns clojure.test-clojure.numbers
(:use clojure.test
[clojure.test.generative :exclude (is)]
clojure.template)
(:require [clojure.data.generators :as gen]
[clojure.test-helper :as helper]))
(deftest test-ratios-simplify-to-ints-where-appropriate
(testing "negative denominator (assembla #275)"
(is (integer? (/ 1 -1/2)))
(is (integer? (/ 0 -1/2)))))
(deftest test-min-max
(testing "min/max on different numbers of floats and doubles"
(are [xmin xmax a]
(and (= (Float. xmin) (min (Float. a)))
(= (Float. xmax) (max (Float. a)))
(= xmin (min a))
(= xmax (max a)))
0.0 0.0 0.0)
(are [xmin xmax a b]
(and (= (Float. xmin) (min (Float. a) (Float. b)))
(= (Float. xmax) (max (Float. a) (Float. b)))
(= xmin (min a b))
(= xmax (max a b)))
-1.0 0.0 0.0 -1.0
-1.0 0.0 -1.0 0.0
0.0 1.0 0.0 1.0
0.0 1.0 1.0 0.0)
(are [xmin xmax a b c]
(and (= (Float. xmin) (min (Float. a) (Float. b) (Float. c)))
(= (Float. xmax) (max (Float. a) (Float. b) (Float. c)))
(= xmin (min a b c))
(= xmax (max a b c)))
-1.0 1.0 0.0 1.0 -1.0
-1.0 1.0 0.0 -1.0 1.0
-1.0 1.0 -1.0 1.0 0.0))
(testing "min/max preserves type of winner"
(is (= java.lang.Long (class (max 10))))
(is (= java.lang.Long (class (max 1.0 10))))
(is (= java.lang.Long (class (max 10 1.0))))
(is (= java.lang.Long (class (max 10 1.0 2.0))))
(is (= java.lang.Long (class (max 1.0 10 2.0))))
(is (= java.lang.Long (class (max 1.0 2.0 10))))
(is (= java.lang.Double (class (max 1 2 10.0 3 4 5))))
(is (= java.lang.Long (class (min 10))))
(is (= java.lang.Long (class (min 1.0 -10))))
(is (= java.lang.Long (class (min -10 1.0))))
(is (= java.lang.Long (class (min -10 1.0 2.0))))
(is (= java.lang.Long (class (min 1.0 -10 2.0))))
(is (= java.lang.Long (class (min 1.0 2.0 -10))))
(is (= java.lang.Double (class (min 1 2 -10.0 3 4 5))))))
(deftest clj-868
(testing "min/max: NaN is contagious"
(letfn [(fnan? [^Float x] (Float/isNaN x))
(dnan? [^double x] (Double/isNaN x))]
(are [minmax]
(are [nan? nan zero]
(every? nan? (map minmax
[ nan zero zero]
[zero nan zero]
[zero zero nan]))
fnan? Float/NaN (Float. 0.0)
dnan? Double/NaN 0.0)
min
max))))
(deftest unchecked-inc-overflow
(testing "max value overflows to min value"
(is (= Long/MIN_VALUE (unchecked-inc Long/MAX_VALUE)))
(is (= Long/MIN_VALUE (unchecked-inc (Long/valueOf Long/MAX_VALUE))))))
(deftest unchecked-dec-overflow
(testing "min value overflows to max value"
(is (= Long/MAX_VALUE (unchecked-dec Long/MIN_VALUE)))
(is (= Long/MAX_VALUE (unchecked-dec (Long/valueOf Long/MIN_VALUE))))))
(deftest unchecked-negate-overflow
(testing "negating min value overflows to min value itself"
(is (= Long/MIN_VALUE (unchecked-negate Long/MIN_VALUE)))
(is (= Long/MIN_VALUE (unchecked-negate (Long/valueOf Long/MIN_VALUE))))))
(deftest unchecked-add-overflow
(testing "max value overflows to min value"
(is (= Long/MIN_VALUE (unchecked-add Long/MAX_VALUE 1)))
(is (= Long/MIN_VALUE (unchecked-add Long/MAX_VALUE (Long/valueOf 1))))
(is (= Long/MIN_VALUE (unchecked-add (Long/valueOf Long/MAX_VALUE) 1)))
(is (= Long/MIN_VALUE (unchecked-add (Long/valueOf Long/MAX_VALUE) (Long/valueOf 1)))))
(testing "adding min value to min value results in zero"
(is (= 0 (unchecked-add Long/MIN_VALUE Long/MIN_VALUE)))
(is (= 0 (unchecked-add Long/MIN_VALUE (Long/valueOf Long/MIN_VALUE))))
(is (= 0 (unchecked-add (Long/valueOf Long/MIN_VALUE) Long/MIN_VALUE)))
(is (= 0 (unchecked-add (Long/valueOf Long/MIN_VALUE) (Long/valueOf Long/MIN_VALUE))))))
(deftest unchecked-subtract-overflow
(testing "min value overflows to max-value"
(is (= Long/MAX_VALUE (unchecked-subtract Long/MIN_VALUE 1)))
(is (= Long/MAX_VALUE (unchecked-subtract Long/MIN_VALUE (Long/valueOf 1))))
(is (= Long/MAX_VALUE (unchecked-subtract (Long/valueOf Long/MIN_VALUE) 1)))
(is (= Long/MAX_VALUE (unchecked-subtract (Long/valueOf Long/MIN_VALUE) (Long/valueOf 1)))))
(testing "negating min value overflows to min value itself"
(is (= Long/MIN_VALUE (unchecked-subtract 0 Long/MIN_VALUE)))
(is (= Long/MIN_VALUE (unchecked-subtract 0 (Long/valueOf Long/MIN_VALUE))))
(is (= Long/MIN_VALUE (unchecked-subtract (Long/valueOf 0) Long/MIN_VALUE)))
(is (= Long/MIN_VALUE (unchecked-subtract (Long/valueOf 0) (Long/valueOf Long/MIN_VALUE))))))
(deftest unchecked-multiply-overflow
(testing "two times max value results in -2"
(is (= -2 (unchecked-multiply Long/MAX_VALUE 2)))
(is (= -2 (unchecked-multiply Long/MAX_VALUE (Long/valueOf 2))))
(is (= -2 (unchecked-multiply (Long/valueOf Long/MAX_VALUE) 2)))
(is (= -2 (unchecked-multiply (Long/valueOf Long/MAX_VALUE) (Long/valueOf 2)))))
(testing "two times min value results in 0"
(is (= 0 (unchecked-multiply Long/MIN_VALUE 2)))
(is (= 0 (unchecked-multiply Long/MIN_VALUE (Long/valueOf 2))))
(is (= 0 (unchecked-multiply (Long/valueOf Long/MIN_VALUE) 2)))
(is (= 0 (unchecked-multiply (Long/valueOf Long/MIN_VALUE) (Long/valueOf 2))))))
(deftest test-nan-as-operand
(testing "All numeric operations with NaN as an operand produce NaN as a result"
(let [nan Double/NaN
onan (cast Object Double/NaN)]
(are [x] (Double/isNaN x)
(+ nan 1)
(+ nan 0)
(+ nan 0.0)
(+ 1 nan)
(+ 0 nan)
(+ 0.0 nan)
(+ nan nan)
(- nan 1)
(- nan 0)
(- nan 0.0)
(- 1 nan)
(- 0 nan)
(- 0.0 nan)
(- nan nan)
(* nan 1)
(* nan 0)
(* nan 0.0)
(* 1 nan)
(* 0 nan)
(* 0.0 nan)
(* nan nan)
(/ nan 1)
(/ nan 0)
(/ nan 0.0)
(/ 1 nan)
(/ 0 nan)
(/ 0.0 nan)
(/ nan nan)
(+ onan 1)
(+ onan 0)
(+ onan 0.0)
(+ 1 onan)
(+ 0 onan)
(+ 0.0 onan)
(+ onan onan)
(- onan 1)
(- onan 0)
(- onan 0.0)
(- 1 onan)
(- 0 onan)
(- 0.0 onan)
(- onan onan)
(* onan 1)
(* onan 0)
(* onan 0.0)
(* 1 onan)
(* 0 onan)
(* 0.0 onan)
(* onan onan)
(/ onan 1)
(/ onan 0)
(/ onan 0.0)
(/ 1 onan)
(/ 0 onan)
(/ 0.0 onan)
(/ onan onan)
(+ nan onan)
(+ onan nan)
(- nan onan)
(- onan nan)
(* nan onan)
(* onan nan)
(/ nan onan)
(/ onan nan) ))))
clojure
(ns clojure.test-clojure.java-interop
(:use clojure.test)
(:require [clojure.data :as data]
[clojure.inspector]
[clojure.pprint :as pp]
[clojure.set :as set]
[clojure.test-clojure.proxy.examples :as proxy-examples])
(:import java.util.Base64
(java.util.concurrent.atomic AtomicLong AtomicInteger)))
(deftest test-proxy-chain
(testing "That the proxy functions can chain"
(are [x y] (= x y)
(-> (get-proxy-class Object)
construct-proxy
(init-proxy {})
(update-proxy {"toString" (fn [_] "chain chain chain")})
str)
"chain chain chain"
(deftest test-proxy-non-serializable
(testing "That proxy classes refuse serialization and deserialization"
;; Serializable listed directly in interface list:
(is (thrown? java.io.NotSerializableException
(-> (java.io.ByteArrayOutputStream.)
(java.io.ObjectOutputStream.)
(.writeObject (proxy [Object java.io.Serializable] [])))))
;; Serializable included via inheritence:
(is (thrown? java.io.NotSerializableException
(-> (java.io.ByteArrayOutputStream.)
(java.io.ObjectOutputStream.)
(.writeObject (clojure.inspector/list-model nil)))))
;; Deserialization also prohibited:
(let [java-version (System/getProperty "java.specification.version")
serialized-proxy (get serialized-proxies java-version)]
(if serialized-proxy
(is (thrown? java.io.NotSerializableException
(-> serialized-proxy
decode-base64
java.io.ByteArrayInputStream. java.io.ObjectInputStream.
.readObject)))
(println "WARNING: Missing serialized proxy for Java" java-version "in test/clojure/test_clojure/java_interop.clj")))))
clojure
(ns ^{:doc "Tests for clojure.core/gen-class"
:author "Stuart Halloway, Daniel Solano Gómez"}
clojure.test-clojure.genclass
(:use clojure.test clojure.test-helper)
(:require clojure.test_clojure.genclass.examples)
(:import [clojure.test_clojure.genclass.examples
ExampleClass
ExampleAnnotationClass
ProtectedFinalTester
ArrayDefInterface
ArrayGenInterface]
(deftest name-munging
(testing "mapping from Java fields to Clojure vars"
(is (= #'clojure.test-clojure.genclass.examples/-foo-Object-int
(get-field ExampleClass 'foo_Object_int__var)))
(is (= #'clojure.test-clojure.genclass.examples/-toString
(get-field ExampleClass 'toString__var)))))
;todo - fix this, it depends on the order of things out of a hash-map
#_(deftest test-annotations
(let [annot-class ExampleAnnotationClass
foo-method (.getDeclaredMethod annot-class "foo" (into-array [String]))]
(testing "Class annotations:"
(is (= 2 (count (.getDeclaredAnnotations annot-class))))
(testing "@Deprecated"
(let [deprecated (.getAnnotation annot-class Deprecated)]
(is deprecated)))
(testing "@Target([])"
(let [resource (.getAnnotation annot-class Target)]
(is (= 0 (count (.value resource)))))))
(testing "Method annotations:"
(testing "@Deprecated void foo(String):"
(is (= 1 (count (.getDeclaredAnnotations foo-method))))
(is (.getAnnotation foo-method Deprecated))))
(testing "Parameter annotations:"
(let [param-annots (.getParameterAnnotations foo-method)]
(is (= 1 (alength param-annots)))
(let [first-param-annots (aget param-annots 0)]
(is (= 2 (alength first-param-annots)))
(testing "void foo(@Retention(…) String)"
(let [retention (aget first-param-annots 0)]
(is (instance? Retention retention))
(= RetentionPolicy/SOURCE (.value retention))))
(testing "void foo(@Target(…) String)"
(let [target (aget first-param-annots 1)]
(is (instance? Target target))
(is (= [ElementType/TYPE ElementType/PARAMETER] (seq (.value target)))))))))))
(deftest protected-final-access
(let [obj (ProtectedFinalTester.)]
(testing "Protected final method visibility"
(is (thrown? IllegalArgumentException (.findSystemClass obj "java.lang.String"))))
(testing "Allow exposition of protected final method."
(is (= String (.superFindSystemClass obj "java.lang.String"))))))
(deftest interface-array-type-hints
(let [array-types {:ints (class (int-array 0))
:bytes (class (byte-array 0))
:shorts (class (short-array 0))
:chars (class (char-array 0))
:longs (class (long-array 0))
:floats (class (float-array 0))
:doubles (class (double-array 0))
:booleans (class (boolean-array 0))
:maps (class (into-array java.util.Map []))}
array-types (assoc array-types
:maps-2d (class (into-array (:maps array-types) [])))
method-with-name (fn [name methods] (first (filter #(= name (.getName %)) methods)))
parameter-type (fn [method] (first (.getParameterTypes method)))
return-type (fn [method] (.getReturnType method))]
(testing "definterface"
(let [method-with-name #(method-with-name % (.getMethods ArrayDefInterface))]
(testing "sugar primitive array hints"
(are [name type] (= (type array-types)
(parameter-type (method-with-name name)))
"takesByteArray" :bytes
"takesCharArray" :chars
"takesShortArray" :shorts
"takesIntArray" :ints
"takesLongArray" :longs
"takesFloatArray" :floats
"takesDoubleArray" :doubles
"takesBooleanArray" :booleans))
(testing "raw primitive array hints"
(are [name type] (= (type array-types)
(return-type (method-with-name name)))
"returnsByteArray" :bytes
"returnsCharArray" :chars
"returnsShortArray" :shorts
"returnsIntArray" :ints
"returnsLongArray" :longs
"returnsFloatArray" :floats
"returnsDoubleArray" :doubles
"returnsBooleanArray" :booleans))))
(testing "gen-interface"
(let [method-with-name #(method-with-name % (.getMethods ArrayGenInterface))]
(testing "sugar primitive array hints"
(are [name type] (= (type array-types)
(parameter-type (method-with-name name)))
"takesByteArray" :bytes
"takesCharArray" :chars
"takesShortArray" :shorts
"takesIntArray" :ints
"takesLongArray" :longs
"takesFloatArray" :floats
"takesDoubleArray" :doubles
"takesBooleanArray" :booleans))
(testing "raw primitive array hints"
(are [name type] (= (type array-types)
(return-type (method-with-name name)))
"returnsByteArray" :bytes
"returnsCharArray" :chars
"returnsShortArray" :shorts
"returnsIntArray" :ints
"returnsLongArray" :longs
"returnsFloatArray" :floats
"returnsDoubleArray" :doubles
"returnsBooleanArray" :booleans))))))
clojure
(ns clojure.test-clojure.data-structures
(:use clojure.test
[clojure.test.generative :exclude (is)])
(:require [clojure.test-clojure.generators :as cgen]
[clojure.data.generators :as gen]
[clojure.string :as string])
(:import [java.util Collection]))
(deftest test-map-entry?
(testing "map-entry? = false"
(are [entry]
(false? (map-entry? entry))
nil 5 #{1 2} '(1 2) {:a 1} [] [0] [1 2 3]))
(testing "map-entry? = true"
(are [entry]
(true? (map-entry? entry))
(first (doto (java.util.HashMap.) (.put "x" 1))))))
(deftest trailing-map-destructuring
(let [sample-map {:a 1 :b 2}
add (fn [& {:keys [a b]}] (+ a b))
addn (fn [n & {:keys [a b]}] (+ n a b))]
(testing "that kwargs are applied properly given a map in place of the key/val pairs"
(is (= 3 (add :a 1 :b 2)))
(is (= 3 (add {:a 1 :b 2})))
(is (= 13 (addn 10 :a 1 :b 2)))
(is (= 13 (addn 10 {:a 1 :b 2})))
(is (= 103 ((partial addn 100) :a 1 {:b 2})))
(is (= 103 ((partial addn 100 :a 1) {:b 2})))
(is (= 107 ((partial addn 100 :a 1) {:a 5 :b 2}))))
(testing "built maps"
(let [{:as m1} (list :a 1 :b 2)
{:as m2} (list :a 1 :b 2 {:c 3})
{:as m3} (list :a 1 :b 2 {:a 0})
{:keys [a4] :as m4} (list nil)]
(= m1 {:a 1 :b 2})
(= m2 {:a 1 :b 2 :c 3})
(= m3 {:a 0 :b 2})
(= m1 (seq-to-map-for-destructuring (list :a 1 :b 2)))
(= m2 (seq-to-map-for-destructuring (list :a 1 :b 2 {:c 3})))
(= m3 (seq-to-map-for-destructuring (list :a 1 :b 2 {:a 0})))
(= a4 nil)))))
clojure
(ns clojure.test-clojure.compilation
(:import (clojure.lang Compiler Compiler$CompilerException))
(:require [clojure.test.generative :refer (defspec)]
[clojure.data.generators :as gen]
[clojure.test-clojure.compilation.line-number-examples :as line])
(:use clojure.test
[clojure.test-helper :only (should-not-reflect should-print-err-message)]))
(deftest test-embedded-constants
(testing "Embedded constants"
(is (eval `(= Boolean/TYPE ~Boolean/TYPE)))
(is (eval `(= Byte/TYPE ~Byte/TYPE)))
(is (eval `(= Character/TYPE ~Character/TYPE)))
(is (eval `(= Double/TYPE ~Double/TYPE)))
(is (eval `(= Float/TYPE ~Float/TYPE)))
(is (eval `(= Integer/TYPE ~Integer/TYPE)))
(is (eval `(= Long/TYPE ~Long/TYPE)))
(is (eval `(= Short/TYPE ~Short/TYPE)))))
(deftest test-compiler-resolution
(testing "resolve nonexistent class create should return nil (assembla #262)"
(is (nil? (resolve 'NonExistentClass.))))
(testing "resolve nonexistent class should return nil"
(is (nil? (resolve 'NonExistentClass.Name)))))
(deftest test-no-recur-across-try
(testing "don't recur to function from inside try"
(is (thrown? Compiler$CompilerException
(eval '(fn [x] (try (recur 1)))))))
(testing "don't recur to loop from inside try"
(is (thrown? Compiler$CompilerException
(eval '(loop [x 5]
(try (recur 1)))))))
(testing "don't recur to loop from inside of catch inside of try"
(is (thrown? Compiler$CompilerException
(eval '(loop [x 5]
(try
(catch Exception e
(recur 1))))))))
(testing "don't recur to loop from inside of finally inside of try"
(is (thrown? Compiler$CompilerException
(eval '(loop [x 5]
(try
(finally
(recur 1))))))))
(testing "don't get confused about what the recur is targeting"
(is (thrown? Compiler$CompilerException
(eval '(loop [x 5]
(try (fn [x]) (recur 1)))))))
(testing "don't allow recur across binding"
(is (thrown? Compiler$CompilerException
(eval '(fn [x] (binding [+ *] (recur 1)))))))
(testing "allow loop/recur inside try"
(is (= 0 (eval '(try (loop [x 3]
(if (zero? x) x (recur (dec x)))))))))
(testing "allow loop/recur fully inside catch"
(is (= 3 (eval '(try
(throw (Exception.))
(catch Exception e
(loop [x 0]
(if (< x 3) (recur (inc x)) x))))))))
(testing "allow loop/recur fully inside finally"
(is (= "012" (eval '(with-out-str
(try
:return-val-discarded-because-of-with-out-str
(finally (loop [x 0]
(when (< x 3)
(print x)
(recur (inc x)))))))))))
(testing "allow fn/recur inside try"
(is (= 0 (eval '(try
((fn [x]
(if (zero? x)
x
(recur (dec x))))
3)))))))
(deftest test-CLJ-671-regression
(testing "that the presence of hints does not cause the compiler to infinitely loop"
(letfn [(gcd [x y]
(loop [x (long x) y (long y)]
(if (== y 0)
x
(recur y ^Long(rem x y)))))]
(is (= 4 (gcd 8 100))))))
(deftest CLJ-1184-do-in-non-list-test
(testing "do in a vector throws an exception"
(is (thrown? Compiler$CompilerException
(eval '[do 1 2 3]))))
(testing "do in a set throws an exception"
(is (thrown? Compiler$CompilerException
(eval '#{do}))))
;; compile uses a separate code path so we have to call it directly
;; to test it
(letfn [(compile [s]
(spit "test/clojure/bad_def_test.clj" (str "(ns clojure.bad-def-test)\n" s))
(try
(binding [*compile-path* "test"]
(clojure.core/compile 'clojure.bad-def-test))
(finally
(doseq [f (.listFiles (java.io.File. "test/clojure"))
:when (re-find #"bad_def_test" (str f))]
(.delete f)))))]
(testing "do in a vector throws an exception in compilation"
(is (thrown? Compiler$CompilerException (compile "[do 1 2 3]"))))
(testing "do in a set throws an exception in compilation"
(is (thrown? Compiler$CompilerException (compile "#{do}"))))))
(deftest test-fnexpr-type-hint
(testing "CLJ-1378: FnExpr should be allowed to override its reported class with a type hint."
(is (thrown? Compiler$CompilerException
(load-string "(.submit (java.util.concurrent.Executors/newCachedThreadPool) #())")))
(is (try (load-string "(.submit (java.util.concurrent.Executors/newCachedThreadPool) ^Runnable #())")
(catch Compiler$CompilerException e nil)))))
(deftest clj-1568
(let [compiler-fails-at?
(fn [row col source]
(let [path (name (gensym "clj-1568.example-"))]
(try
(Compiler/load (java.io.StringReader. source) path "clj-1568.example")
nil
(catch Compiler$CompilerException e
(let [data (ex-data e)]
(= [path row col]
[(:clojure.error/source data) (:clojure.error/line data) (:clojure.error/column data)]))))))]
(testing "with error in the initial form"
(are [row col source] (compiler-fails-at? row col source)
;; note that the spacing of the following string is important
1 4 " (.foo nil)"
2 18 "
(/ 1 0)"))
(testing "with error in an non-initial form"
(are [row col source] (compiler-fails-at? row col source)
;; note that the spacing of the following string is important
3 18 "(:foo {})
(deftest CLJ-1250-this-clearing
(testing "clearing during try/catch/finally"
(let [closed-over-in-catch (let [x :foo]
(fn []
(try
(throw (Exception. "boom"))
(catch Exception e
x)))) ;; x should remain accessible to the fn
a (atom nil)
closed-over-in-finally (fn []
(try
:ret
(finally
(reset! a :run))))]
(is (= :foo (closed-over-in-catch)))
(is (= :ret (closed-over-in-finally)))
(is (= :run @a))))
(testing "no clearing when loop not in return context"
(let [x (atom 5)
bad (fn []
(loop [] (System/getProperties))
(swap! x dec)
(when (pos? @x)
(recur)))]
(is (nil? (bad))))))
(deftest clj-1714
(testing "CLJ-1714 Classes shouldn't have their static initialisers called simply by type hinting or importing"
;; ClassWithFailingStaticInitialiser will throw if its static initialiser is called
(is (eval '(fn [^compilation.ClassWithFailingStaticInitialiser c])))
(is (eval '(import (compilation ClassWithFailingStaticInitialiser))))))
(deftest CLJ-2284
(testing "CLJ-2284 Can call static methods on interfaces"
(is (= 42 (compilation.JDK8InterfaceMethods/staticMethod0 42)))
(is (= "test" (compilation.JDK8InterfaceMethods/staticMethod1 "test")))
(is (= 1 (if (compilation.JDK8InterfaceMethods/staticMethod2 true) 1 2)))))
(deftest CLJ-2580
(testing "CLJ-2580 Correctly calculate exit branches of case"
(is (zero? (let [d (case nil :x nil 0)] d)))
(is (nil? (let [d (case nil :x 0 nil)] d)))))
clj-kondo/clj-kondo
(ns feature-syntax
(:require [clojure.test :as t]))
(t/deftest foo-test
#?(:clj
(t/testing "foo"
(prn :x))
(t/testing "bar"
(prn :y))))
jakemcc/test-refresh
(ns lein2.sample-report
(:require [clojure.test :as t]))
(defmethod my-report :error [m]
(t/with-test-out
(t/inc-report-counter :error)
(println "\nERROR in" (t/testing-vars-str m))
(when-let [message (:message m)] (println message))
(println "expected:" (pr-str (:expected m)))
(println " actual:" (pr-str (:actual m)))
(println)))
(defmethod my-report :fail [m]
(t/with-test-out
(t/inc-report-counter :fail)
(println "\nFAIL in" (t/testing-vars-str m))
(when-let [message (:message m)] (println message))
(println "expected:" (pr-str (:expected m)))
(println " actual:" (pr-str (:actual m)))
(println)))
nubank/state-flow
(ns state-flow.labs.cljtest
(:require [clojure.test :as ctest]
[state-flow.core :as core]
[state-flow.state :as state]))
(defmacro testing
"state-flow's equivalent to clojure test's `testing`"
[desc & body]
`(core/flow ~desc
[full-desc# (core/current-description)]
(state/wrap-fn #(do ~(with-meta `(ctest/testing ~desc ~@body)
(meta &form))))))
metosin/testit
(ns example.eventually-arrow-example
(:require [clojure.test :refer :all]
[testit.core :refer :all]
[testit.eventually :refer [*eventually-timeout-ms*]]))
(deftest ^:slow eventually-example
(testing "Left-side will match right side eventually"
(let [a (atom -1)]
(future
(Thread/sleep 100)
(reset! a 1))
(fact
(deref a) =eventually=> pos?)))
(testing "You can change the timeout from it's default of 1sec"
(binding [*eventually-timeout-ms* 2000]
(let [a (atom -1)]
(future
(Thread/sleep 1500)
(reset! a 1))
(fact
(deref a) =eventually=> pos?)))))
lambdaisland/kaocha-cljs
(repl-do (fn [repl-env env opts]
(repl/eval-cljs repl-env env '(require '[clojure.test :as test]))))
(repl-do (fn [repl-env env opts]
(repl/eval-cljs repl-env env '(cljs.test/set-env! (cljs.test/empty-env :cljs.test/pprint)))))
"{:report-counters {:test 0, :pass 0, :fail 0, :error 0}, :testing-vars (), :testing-contexts (), :formatter #object[cljs$pprint$pprint], :reporter :cljs.test/default}"