Skip to content

Commit e75098a

Browse files
authored
test atom (#102)
* test atom * throwing is expected despite cljs bug * test ratios in all dialects EXCEPT cljs * chill out a bit with execution time * not just clj dialect * let broken cljs behavior pass for now
1 parent ac1649c commit e75098a

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

test/clojure/core_test/atom.cljc

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
(ns clojure.core-test.atom
2+
(:require clojure.core
3+
[clojure.test :as t :refer [deftest testing is are]]
4+
[clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists]]))
5+
6+
(when-var-exists clojure.core/atom
7+
(deftest test-atom
8+
(testing "What happens when the input is nil?"
9+
(let [nil-atm (atom nil)
10+
nil-atm2 (atom nil nil nil)
11+
nil-atm3 (apply atom (take 11 (repeat nil)))]
12+
#?(:cljs (is (every? #(satisfies? cljs.core/IAtom %) [nil-atm nil-atm2 nil-atm3]))
13+
:clj (is (every? (partial instance? clojure.lang.Atom) [nil-atm nil-atm2 nil-atm3])))
14+
(is (every? nil? (map deref [nil-atm nil-atm2 nil-atm3])))))
15+
16+
(testing "metadata"
17+
(are [v m] (let [the-atom (atom v :meta m)]
18+
(and (= v (deref the-atom))
19+
(= m (meta the-atom))))
20+
;; metadata can be a map or nil
21+
nil nil
22+
nil {}
23+
nil {:foo "foo"})
24+
(when-var-exists clojure.core/sorted-map
25+
(is (= {:a "a"} (meta (atom nil :meta (sorted-map :a "a"))))))
26+
(when-var-exists clojure.core/array-map
27+
(is (= {:a "a"} (meta (atom nil :meta (array-map :a "a"))))))
28+
(when-var-exists clojure.core/hash-map
29+
(is (= {:a "a"} (meta (atom nil :meta (hash-map :a "a"))))))
30+
#?(:cljs (is (= 5 (meta (atom nil :meta 5)))),
31+
:default (is (thrown? Exception (atom nil :meta 5))))
32+
#?(:cljs (is (= #{} (meta (atom nil :meta #{})))),
33+
:default (is (thrown? Exception (atom nil :meta #{}))))
34+
#?(:cljs (is (= [] (meta (atom nil :meta (vector))))),
35+
:default (is (thrown? Exception (atom nil :meta (vector))))))
36+
37+
(testing "validator-fn"
38+
;; Docstring: "If the new state is unacceptable, the validate-fn should
39+
;; return false or throw an exception." Read this as _logical_ false,
40+
;; including `nil` as well as `false`:
41+
(testing "all new vals permitted with nil validator"
42+
(let [atm (atom {} :validator nil)]
43+
(is (= {} (deref atm)))
44+
(is (= {:foo "foo"} (swap! atm assoc :foo "foo")))
45+
(is (= {:foo "foo"} (deref atm)))
46+
(is (= {"bar" :bar} (reset! atm {"bar" :bar})))
47+
(is (= {"bar" :bar} (deref atm)))
48+
(is (= 3 (reset! atm 3)))
49+
(is (= 3 (deref atm)))
50+
(is (= nil (reset! atm nil)))
51+
(is (= nil (deref atm)))))
52+
53+
(testing "all new vals permitted with always-truthy validator"
54+
(let [atm (atom {} :validator (constantly true))]
55+
(is (= {} (deref atm)))
56+
(is (= {:foo "foo"} (swap! atm assoc :foo "foo")))
57+
(is (= {:foo "foo"} (deref atm)))
58+
(is (= {"bar" :bar} (reset! atm {"bar" :bar})))
59+
(is (= {"bar" :bar} (deref atm)))
60+
(is (= 3 (reset! atm 3)))
61+
(is (= 3 (deref atm))))
62+
63+
(let [atm (atom {} :validator (constantly :some-val))]
64+
(is (= {} (deref atm)))
65+
(is (= {:foo "foo"} (swap! atm assoc :foo "foo")))
66+
(is (= {:foo "foo"} (deref atm)))
67+
(is (= {"bar" :bar} (reset! atm {"bar" :bar})))
68+
(is (= {"bar" :bar} (deref atm)))
69+
(is (= 3 (reset! atm 3)))
70+
(is (= 3 (deref atm)))))
71+
72+
(testing "always-falsey validator can't initialize atom"
73+
#?(:cljs (testing "Broken but current behavior due to CLJS-3447"
74+
;; FIXME when https://clojure.atlassian.net/browse/CLJS-3447 is fixed
75+
(is (= {} (deref (atom {} :validator (constantly nil)))))),
76+
:default (is (thrown? Exception (atom {} :validator (constantly nil)))))
77+
#?(:cljs (testing "Broken but current behavior due to CLJS-3447"
78+
;; FIXME when https://clojure.atlassian.net/browse/CLJS-3447 is fixed
79+
(is (= {} (deref (atom {} :validator (constantly false)))))),
80+
:default (is (thrown? Exception (atom {} :validator (constantly false)))))
81+
#?(:cljs (testing "Broken but current behavior due to CLJS-3447"
82+
;; FIXME when https://clojure.atlassian.net/browse/CLJS-3447 is fixed
83+
(is (= {} (deref (atom {} :validator #(when true (throw (ex-info "boom" {})))))))),
84+
:default (is (thrown? Exception (atom {} :validator #(when true (throw (ex-info "boom" {}))))))))
85+
86+
(testing "conditional validators are obeyed at creation, swap! and reset!"
87+
#?(:cljs (testing "Broken but current behavior due to CLJS-3447"
88+
;; FIXME when https://clojure.atlassian.net/browse/CLJS-3447 is fixed
89+
(is (= #{} (deref (atom #{} :validator (fn [v] (some string? v))))))),
90+
:default (is (thrown? Exception (atom #{} :validator (fn [v] (some string? v))))))
91+
(let [some-strings (atom #{"str"} :validator (fn [v] (some string? v)))]
92+
(is (= #{"str" :not-a-string} (swap! some-strings conj :not-a-string)))
93+
(is (thrown? #?(:cljs :default :clj Exception :cljr Exception)
94+
(swap! some-strings disj "str")))
95+
(is (= #{"str"} (swap! some-strings disj :not-a-string)))
96+
(is (thrown? #?(:cljs :default :clj Exception :cljr Exception)
97+
(reset! some-strings #{})))
98+
(is (thrown? #?(:cljs :default :clj Exception :cljr Exception)
99+
(reset! some-strings :neither-string-nor-set)))
100+
(is (= #{"str"} (deref some-strings)))
101+
(is (= #{"some other string"} (reset! some-strings #{"some other string"})))
102+
(is (= #{"some other string"} (deref some-strings))))
103+
104+
(let [all-strings (atom #{} :validator (fn [v] (every? string? v)))]
105+
(is (= #{"str"} (swap! all-strings conj "str")))
106+
(is (= #{} (swap! all-strings disj "str")))
107+
(is (thrown? #?(:cljs :default :clj Exception :cljr Exception)
108+
(reset! all-strings :neither-string-nor-set)))
109+
(is (thrown? #?(:cljs :default :clj Exception :cljr Exception)
110+
(reset! all-strings #{:not-a-string})))
111+
(is (= #{"new string"} (reset! all-strings #{"new string"})))
112+
(is (= #{"new string"} (deref all-strings))))))
113+
114+
(testing "metadata and validator function together"
115+
(let [m {:foo "foo"}
116+
vf even?
117+
the-atom (atom 0 :validator vf :meta m)
118+
the-atom2 (atom 0 :meta m :validator vf)]
119+
(is (= vf (get-validator the-atom)))
120+
(is (= m (meta the-atom)))
121+
(is (= vf (get-validator the-atom2)))
122+
(is (= m (meta the-atom2)))))
123+
124+
(testing "atom accepts all values"
125+
(are [v] (let [the-atom (atom v)]
126+
(and (= v (deref the-atom))
127+
#?(:cljs (is (satisfies? cljs.core/IAtom the-atom))
128+
:clj (is (instance? clojure.lang.Atom the-atom)))))
129+
'sym
130+
`sym
131+
"string"
132+
1
133+
1.0
134+
#?(:cljs "cljs is the only (?) Clojure dialect that doesn't support ratios"
135+
:default 111/7)
136+
\newline
137+
nil
138+
true
139+
false
140+
##Inf
141+
:kw
142+
:ns/kw
143+
'(one two three)
144+
[1 2 3]
145+
{:k "value"}
146+
(zipmap (take 100 (range))
147+
(cycle ['foo 'bar 'baz 'qux]))
148+
(set (range 0 334 3)))
149+
(testing "infinite sequence"
150+
(let [r (range)]
151+
(is (= r (deref (atom r)))))))))

0 commit comments

Comments
 (0)