Skip to content

Commit 536b2cc

Browse files
committed
2 parents 63a0dc1 + c83825b commit 536b2cc

File tree

6 files changed

+130
-69
lines changed

6 files changed

+130
-69
lines changed

src/active/clojure/record_runtime.cljc

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,24 @@
149149

150150
; assumes that ?r, ?rtd are identifiers alerady
151151
(defmacro record-check-rtd!
152-
[?rtd ?r]
153-
`(when-not (and (record? ~?r)
154-
(identical? ~?rtd (.-rtd ~?r)))
155-
;; FIXME: more expressive exception
156-
(throw #?(:clj (new Error "not a record of the correct type")
157-
:cljs (js/Error. "not a record of the correct type")))))
152+
"Checks, if a given element is an rtd-record and if that's the case,
153+
if it has the same rtd as the given.
154+
155+
Note: To prevent reflection warnings, we had to add the record symbol,
156+
which has a type hint attached.
157+
The outer if condition is needed, because primitive types can't be type hinted."
158+
[^RecordTypeDescriptor ?rtd ^Record ?r]
159+
(let [error (if (:ns &env)
160+
`(js/Error. (str "Not a record of the correct type [[" (:name ~?rtd) "]]"))
161+
`(new Error (str "Not a record of the correct type [[" (:name ~?rtd) "]]")))
162+
record (vary-meta (gensym) assoc :tag `Record)]
163+
(if (or (symbol? ?r) (list? ?r))
164+
`(do
165+
(when-not (and (record? ~?r)
166+
(let [~record ~?r]
167+
(identical? ~?rtd (.-rtd ~record))))
168+
(throw ~error)))
169+
`(throw ~error))))
158170

159171
(defn record-get
160172
[^RecordTypeDescriptor rtd ^Record r ^long index]

src/active/clojure/sum_type.cljc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
(str "in " (:ns debug-info) ", line: " (:line debug-info) ", column: " (:column debug-info)))
1414

1515
#?(:clj
16-
(defn throw-illegal-argument-exception [msg]
17-
(throw (java.lang.IllegalArgumentException. msg))))
16+
(defn throw-illegal-argument-exception [^java.lang.String msg]
17+
(throw (new java.lang.IllegalArgumentException msg))))
1818

1919
#?(:clj
2020
(defn- metadata

test/active/clojure/record_runtime_test.clj

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
(ns active.clojure.record-runtime-test
2+
(:require #?(:clj [clojure.test :refer :all])
3+
[active.clojure.record-runtime :as r :include-macros true]
4+
#?(:cljs [active.clojure.cljs.record])
5+
#?(:cljs [cljs.test]))
6+
#?(:cljs
7+
(:require-macros [cljs.test :refer (is deftest run-tests testing)])))
8+
9+
(def rtd0 (r/make-record-type-descriptor `rtd0 nil []))
10+
(def rtd1 (r/make-record-type-descriptor `rtd1 nil [(r/make-record-field "f1")]))
11+
(def rtd2 (r/make-record-type-descriptor `rtd2 nil [(r/make-record-field "f1")
12+
(r/make-record-field "f2")]))
13+
(def rtd100 (r/make-record-type-descriptor `rtd100 nil
14+
(map #(str "f" %) (range 100))))
15+
16+
(deftest t-make-record-simple
17+
(let [r0 (r/make-record rtd0)
18+
r1 (r/make-record rtd1 1)
19+
r2 (r/make-record rtd2 1 2)]
20+
(is (r/record? r0))
21+
(is (r/record-of-type? r0 rtd0))
22+
(is (not (r/record-of-type? r0 rtd1)))
23+
(is (r/record? r1))
24+
(is (= 1 (r/record-get rtd1 r1 0)))
25+
(is (r/record? r2))
26+
(is (= 1 (r/record-get rtd2 r2 0)))
27+
(is (= 2 (r/record-get rtd2 r2 1)))))
28+
29+
(deftest t-make-record-100
30+
(let [r100 (apply r/make-record rtd100 (range 100))]
31+
(doseq [i (range 100)]
32+
(is (= i (r/record-get rtd100 r100 i))))))
33+
34+
(deftest t-record-update
35+
(let [r2 (r/make-record rtd2 1 2)
36+
r2a (r/record-update rtd2 r2 1 5)]
37+
(is (= 1 (r/record-get rtd2 r2a 0)))
38+
(is (= 5 (r/record-get rtd2 r2a 1)))))
39+
40+
(deftest t-record-check
41+
(let [r2 (r/make-record rtd2 1 2)]
42+
(is (thrown? #?(:clj Error :cljs js/Error)
43+
(r/record-get rtd0 r2 0)))
44+
(is (thrown? #?(:clj Error :cljs js/Error)
45+
(r/record-update rtd0 r2 0 :new)))))
46+
47+
(deftest to-string-test
48+
(let [r0 (r/make-record rtd0)
49+
r1 (r/make-record rtd1 1)
50+
r2 (r/make-record rtd2 1 2)]
51+
(testing "str / toString"
52+
(is (= "active.clojure.record-runtime-test/rtd0{}"
53+
(str r0)))
54+
(is (= "active.clojure.record-runtime-test/rtd1{:f1 1}"
55+
(str r1)))
56+
(is (= "active.clojure.record-runtime-test/rtd2{:f1 1, :f2 2}"
57+
(str r2))))
58+
(testing "pr-str / print-method"
59+
(is (= "active.clojure.record-runtime-test/rtd0{}"
60+
(pr-str r0)))
61+
(is (= "active.clojure.record-runtime-test/rtd1{:f1 1}"
62+
(pr-str r1)))
63+
(is (= "active.clojure.record-runtime-test/rtd2{:f1 1, :f2 2}"
64+
(pr-str r2))))))
65+
66+
67+
(defrecord NotRTDRecord [a b])
68+
(def rtd0-2 (r/make-record-type-descriptor `rtd0-2 nil []))
69+
(def rtd2-2 (r/make-record-type-descriptor `rtd2-2 nil [(r/make-record-field "f1")
70+
(r/make-record-field "f2")]))
71+
72+
(deftest record-check-rtd!-throws-when-wrong-record-type
73+
(testing "not even an rtd-record"
74+
(is (thrown-with-msg?
75+
#?(:clj Error :cljs js/Error)
76+
#"Not a record of the correct type \[\[active.clojure.record-runtime-test/rtd2]]"
77+
(r/record-check-rtd! ^RecordTypeDescriptor rtd2 4)))
78+
(is (thrown-with-msg?
79+
#?(:clj Error :cljs js/Error)
80+
#"Not a record of the correct type \[\[active.clojure.record-runtime-test/rtd2]]"
81+
(r/record-check-rtd! rtd2 "blub")))
82+
(is (thrown-with-msg?
83+
#?(:clj Error :cljs js/Error)
84+
#"Not a record of the correct type \[\[active.clojure.record-runtime-test/rtd2]]"
85+
(r/record-check-rtd! rtd2 (->NotRTDRecord 1 2)))))
86+
(testing "wrong rtd-record"
87+
(is (thrown-with-msg?
88+
#?(:clj Error :cljs js/Error)
89+
#"Not a record of the correct type \[\[active.clojure.record-runtime-test/rtd2]]"
90+
(r/record-check-rtd! rtd2 (r/make-record rtd0))))
91+
(is (thrown-with-msg?
92+
#?(:clj Error :cljs js/Error)
93+
#"Not a record of the correct type \[\[active.clojure.record-runtime-test/rtd2]]"
94+
(r/record-check-rtd! rtd2 (r/make-record rtd1))))
95+
(is (thrown-with-msg?
96+
#?(:clj Error :cljs js/Error)
97+
#"Not a record of the correct type \[\[active.clojure.record-runtime-test/rtd2]]"
98+
(r/record-check-rtd! rtd2 (r/make-record rtd2-2))))
99+
(is (thrown-with-msg?
100+
#?(:clj Error :cljs js/Error)
101+
#"Not a record of the correct type \[\[active.clojure.record-runtime-test/rtd0]]"
102+
(r/record-check-rtd! rtd0 (r/make-record rtd0-2)))))
103+
(testing "correct record, shouldnt throw"
104+
(is (nil? (r/record-check-rtd! rtd0 (r/make-record rtd0)))))
105+
(testing "correct record, shouldnt throw"
106+
(is (nil? (r/record-check-rtd! rtd2 (r/make-record rtd2 1 2))))))

test/active/clojure/test_deps.cljs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
[active.clojure.sum-type-test]
1111
[active.clojure.config-test]
1212
[active.clojure.macro-test]
13-
[active.clojure.functions-test]))
14-
13+
[active.clojure.functions-test]
14+
[active.clojure.record-runtime-test]))

test/active/clojure/test_runner.cljs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@
1414
'active.clojure.match-test
1515
'active.clojure.config-test
1616
'active.clojure.macro-test
17-
'active.clojure.functions-test)
17+
'active.clojure.functions-test
18+
'active.clojure.record-runtime-test)

0 commit comments

Comments
 (0)