Skip to content

Commit 47a7cb0

Browse files
authored
Test descendants (#834)
This closes #236.
1 parent 1355cb5 commit 47a7cb0

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
(ns clojure.core-test.descendants
2+
(:require [clojure.test :refer [are deftest is testing use-fixtures]]
3+
[clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists]]))
4+
5+
(when-var-exists descendants
6+
7+
; Some types for testing descendants by type
8+
(defprotocol TestDescendantsProtocol)
9+
(defrecord TestDescendantsRecord [] TestDescendantsProtocol)
10+
(deftype TestDescendantsType [] TestDescendantsProtocol)
11+
12+
; A global hierarchy for testing `descendants tag` and `descendants h tag`
13+
(def global-hierarchy [[TestDescendantsRecord ::record]
14+
[::t ::p-1]
15+
[::t ::p-2]
16+
[::p-1 'ns/p-0]
17+
[::p-2 ::root]
18+
['ns/p-0 ::root]])
19+
20+
(defn register-global-hierarchy []
21+
(doseq [[tag parent] global-hierarchy]
22+
(derive tag parent)))
23+
24+
(defn unregister-global-hierarchy []
25+
(doseq [[tag parent] global-hierarchy]
26+
(underive tag parent)))
27+
28+
(defn with-global-hierarchy [tests]
29+
(register-global-hierarchy)
30+
(tests)
31+
(unregister-global-hierarchy))
32+
33+
(use-fixtures :once with-global-hierarchy)
34+
35+
; A hierarchy for testing `descendants h tag`
36+
(def datatypes
37+
(-> (make-hierarchy)
38+
(derive TestDescendantsRecord ::datatype)
39+
(derive TestDescendantsType ::datatype)
40+
(derive TestDescendantsType ::mutable)))
41+
42+
; Another hierarchy for testing `descendants h tag`
43+
(def diamond
44+
(-> (make-hierarchy)
45+
(derive ::a ::root)
46+
(derive ::b ::a)
47+
(derive ::c ::a)
48+
(derive ::d ::b)
49+
(derive ::d ::c)))
50+
51+
(deftest test-descendants
52+
53+
(testing "descendants tag"
54+
55+
(testing "returns descendants by relationship globally defined with derive"
56+
(are [expected tag] (= expected (descendants tag))
57+
nil ::t
58+
#{::t ::p-1} 'ns/p-0
59+
#{::t ::p-1 ::p-2 'ns/p-0} ::root
60+
#{::t} ::p-2
61+
#{#?(:bb 'clojure.core_test.descendants/TestDescendantsRecord :default TestDescendantsRecord)} ::record))
62+
63+
(testing "cannot get descendants by type inheritance"
64+
(is (nil? (descendants TestDescendantsProtocol)))
65+
#?(:cljs (is (nil? (descendants js/Object)))
66+
:default (is (thrown? Exception (descendants Object)))))
67+
68+
(testing "does not throw on invalid tag"
69+
(are [tag] (nil? (descendants tag))
70+
nil
71+
"anything"
72+
42
73+
3.14
74+
true
75+
false
76+
[]
77+
{}
78+
#{}
79+
'())))
80+
81+
(testing "descendants h tag"
82+
83+
(testing "returns only descendants declared in h, whether the tag is in global hierarchy or not"
84+
(are [expected h tag] (= expected (descendants h tag))
85+
86+
; tag in h and not in global hierarchy
87+
nil diamond ::d
88+
#{::d} diamond ::b
89+
#{::b ::c ::d} diamond ::a
90+
#?(:bb #{'clojure.core_test.descendants/TestDescendantsRecord 'clojure.core_test.descendants/TestDescendantsType}
91+
:default #{TestDescendantsRecord TestDescendantsType}) datatypes ::datatype
92+
#?(:bb #{'clojure.core_test.descendants/TestDescendantsType}
93+
:default #{TestDescendantsType}) datatypes ::mutable
94+
95+
; tag in both h and global hierarchy, only descendants in h are returned
96+
#{::a ::b ::c ::d} diamond ::root
97+
98+
; tag not in h but in global hierarchy
99+
nil datatypes ::root
100+
nil datatypes ::p-1
101+
nil datatypes ::p-2
102+
103+
; tag neither in h nor in global hierarchy
104+
nil datatypes ::d
105+
nil datatypes ::b
106+
nil datatypes ::a))
107+
108+
(testing "cannot get descendants by type inheritance, whether the tag is in h or not"
109+
(are [h] #?(:cljs (nil? (descendants h js/Object))
110+
:default (thrown? Exception (descendants h Object)))
111+
; tag in h
112+
(derive (make-hierarchy) Object ::object)
113+
; tag not in h
114+
diamond
115+
datatypes))
116+
117+
(testing "does not throw on invalid tag or hierarchy"
118+
(are [invalid] (nil? (descendants invalid invalid))
119+
nil
120+
"anything"
121+
42
122+
3.14
123+
true
124+
false
125+
[]
126+
{}
127+
#{}
128+
'())))))

0 commit comments

Comments
 (0)