Mercurial > lasercutter
comparison src/clojure/test_clojure/data_structures.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
9:35cf337adfcf | 10:ef7dbbd6452c |
---|---|
1 ; Copyright (c) Rich Hickey. 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 ; Author: Frantisek Sodomka | |
10 | |
11 | |
12 (ns clojure.test-clojure.data-structures | |
13 (:use clojure.test)) | |
14 | |
15 | |
16 ;; *** Helper functions *** | |
17 | |
18 (defn diff [s1 s2] | |
19 (seq (reduce disj (set s1) (set s2)))) | |
20 | |
21 | |
22 ;; *** General *** | |
23 | |
24 (defstruct equality-struct :a :b) | |
25 | |
26 (deftest test-equality | |
27 ; nil is not equal to any other value | |
28 (are [x] (not (= nil x)) | |
29 true false | |
30 0 0.0 | |
31 \space | |
32 "" #"" | |
33 () [] #{} {} | |
34 (lazy-seq nil) ; SVN 1292: fixed (= (lazy-seq nil) nil) | |
35 (lazy-seq ()) | |
36 (lazy-seq []) | |
37 (lazy-seq {}) | |
38 (lazy-seq #{}) | |
39 (lazy-seq "") | |
40 (lazy-seq (into-array [])) | |
41 (new Object) ) | |
42 | |
43 ; numbers equality across types (see tests below - NOT IMPLEMENTED YET) | |
44 | |
45 ; ratios | |
46 (is (= 1/2 0.5)) | |
47 (is (= 1/1000 0.001)) | |
48 (is (not= 2/3 0.6666666666666666)) | |
49 | |
50 ; vectors equal other seqs by items equality | |
51 (are [x y] (= x y) | |
52 '() [] ; regression fixed in r1208; was not equal | |
53 '(1) [1] | |
54 '(1 2) [1 2] | |
55 | |
56 [] '() ; same again, but vectors first | |
57 [1] '(1) | |
58 [1 2] '(1 2) ) | |
59 (is (not= [1 2] '(2 1))) ; order of items matters | |
60 | |
61 ; list and vector vs. set and map | |
62 (are [x y] (not= x y) | |
63 ; only () equals [] | |
64 () #{} | |
65 () {} | |
66 [] #{} | |
67 [] {} | |
68 #{} {} | |
69 ; only '(1) equals [1] | |
70 '(1) #{1} | |
71 [1] #{1} ) | |
72 | |
73 ; sorted-map, hash-map and array-map - classes differ, but content is equal | |
74 | |
75 ;; TODO: reimplement all-are with new do-template? | |
76 ;; (all-are (not= (class _1) (class _2)) | |
77 ;; (sorted-map :a 1) | |
78 ;; (hash-map :a 1) | |
79 ;; (array-map :a 1)) | |
80 ;; (all-are (= _1 _2) | |
81 ;; (sorted-map) | |
82 ;; (hash-map) | |
83 ;; (array-map)) | |
84 ;; (all-are (= _1 _2) | |
85 ;; (sorted-map :a 1) | |
86 ;; (hash-map :a 1) | |
87 ;; (array-map :a 1)) | |
88 ;; (all-are (= _1 _2) | |
89 ;; (sorted-map :a 1 :z 3 :c 2) | |
90 ;; (hash-map :a 1 :z 3 :c 2) | |
91 ;; (array-map :a 1 :z 3 :c 2)) | |
92 | |
93 ; struct-map vs. sorted-map, hash-map and array-map | |
94 (are [x] (and (not= (class (struct equality-struct 1 2)) (class x)) | |
95 (= (struct equality-struct 1 2) x)) | |
96 (sorted-map-by compare :a 1 :b 2) | |
97 (sorted-map :a 1 :b 2) | |
98 (hash-map :a 1 :b 2) | |
99 (array-map :a 1 :b 2)) | |
100 | |
101 ; sorted-set vs. hash-set | |
102 (is (not= (class (sorted-set 1)) (class (hash-set 1)))) | |
103 (are [x y] (= x y) | |
104 (sorted-set-by <) (hash-set) | |
105 (sorted-set-by < 1) (hash-set 1) | |
106 (sorted-set-by < 3 2 1) (hash-set 3 2 1) | |
107 (sorted-set) (hash-set) | |
108 (sorted-set 1) (hash-set 1) | |
109 (sorted-set 3 2 1) (hash-set 3 2 1) )) | |
110 | |
111 | |
112 ;; *** Collections *** | |
113 | |
114 (deftest test-count | |
115 (are [x y] (= x y) | |
116 (count nil) 0 | |
117 | |
118 (count ()) 0 | |
119 (count '(1)) 1 | |
120 (count '(1 2 3)) 3 | |
121 | |
122 (count []) 0 | |
123 (count [1]) 1 | |
124 (count [1 2 3]) 3 | |
125 | |
126 (count #{}) 0 | |
127 (count #{1}) 1 | |
128 (count #{1 2 3}) 3 | |
129 | |
130 (count {}) 0 | |
131 (count {:a 1}) 1 | |
132 (count {:a 1 :b 2 :c 3}) 3 | |
133 | |
134 (count "") 0 | |
135 (count "a") 1 | |
136 (count "abc") 3 | |
137 | |
138 (count (into-array [])) 0 | |
139 (count (into-array [1])) 1 | |
140 (count (into-array [1 2 3])) 3 | |
141 | |
142 (count (java.util.ArrayList. [])) 0 | |
143 (count (java.util.ArrayList. [1])) 1 | |
144 (count (java.util.ArrayList. [1 2 3])) 3 | |
145 | |
146 (count (java.util.HashMap. {})) 0 | |
147 (count (java.util.HashMap. {:a 1})) 1 | |
148 (count (java.util.HashMap. {:a 1 :b 2 :c 3})) 3 ) | |
149 | |
150 ; different types | |
151 (are [x] (= (count [x]) 1) | |
152 nil true false | |
153 0 0.0 "" \space | |
154 () [] #{} {} )) | |
155 | |
156 | |
157 (deftest test-conj | |
158 ; doesn't work on strings or arrays | |
159 (is (thrown? ClassCastException (conj "" \a))) | |
160 (is (thrown? ClassCastException (conj (into-array []) 1))) | |
161 | |
162 (are [x y] (= x y) | |
163 (conj nil 1) '(1) | |
164 (conj nil 3 2 1) '(1 2 3) | |
165 | |
166 (conj nil nil) '(nil) | |
167 (conj nil nil nil) '(nil nil) | |
168 (conj nil nil nil 1) '(1 nil nil) | |
169 | |
170 ; list -> conj puts the item at the front of the list | |
171 (conj () 1) '(1) | |
172 (conj () 1 2) '(2 1) | |
173 | |
174 (conj '(2 3) 1) '(1 2 3) | |
175 (conj '(2 3) 1 4 3) '(3 4 1 2 3) | |
176 | |
177 (conj () nil) '(nil) | |
178 (conj () ()) '(()) | |
179 | |
180 ; vector -> conj puts the item at the end of the vector | |
181 (conj [] 1) [1] | |
182 (conj [] 1 2) [1 2] | |
183 | |
184 (conj [2 3] 1) [2 3 1] | |
185 (conj [2 3] 1 4 3) [2 3 1 4 3] | |
186 | |
187 (conj [] nil) [nil] | |
188 (conj [] []) [[]] | |
189 | |
190 ; map -> conj expects another (possibly single entry) map as the item, | |
191 ; and returns a new map which is the old map plus the entries | |
192 ; from the new, which may overwrite entries of the old. | |
193 ; conj also accepts a MapEntry or a vector of two items (key and value). | |
194 (conj {} {}) {} | |
195 (conj {} {:a 1}) {:a 1} | |
196 (conj {} {:a 1 :b 2}) {:a 1 :b 2} | |
197 (conj {} {:a 1 :b 2} {:c 3}) {:a 1 :b 2 :c 3} | |
198 (conj {} {:a 1 :b 2} {:a 3 :c 4}) {:a 3 :b 2 :c 4} | |
199 | |
200 (conj {:a 1} {:a 7}) {:a 7} | |
201 (conj {:a 1} {:b 2}) {:a 1 :b 2} | |
202 (conj {:a 1} {:a 7 :b 2}) {:a 7 :b 2} | |
203 (conj {:a 1} {:a 7 :b 2} {:c 3}) {:a 7 :b 2 :c 3} | |
204 (conj {:a 1} {:a 7 :b 2} {:b 4 :c 5}) {:a 7 :b 4 :c 5} | |
205 | |
206 (conj {} (first {:a 1})) {:a 1} ; MapEntry | |
207 (conj {:a 1} (first {:b 2})) {:a 1 :b 2} | |
208 (conj {:a 1} (first {:a 7})) {:a 7} | |
209 (conj {:a 1} (first {:b 2}) (first {:a 5})) {:a 5 :b 2} | |
210 | |
211 (conj {} [:a 1]) {:a 1} ; vector | |
212 (conj {:a 1} [:b 2]) {:a 1 :b 2} | |
213 (conj {:a 1} [:a 7]) {:a 7} | |
214 (conj {:a 1} [:b 2] [:a 5]) {:a 5 :b 2} | |
215 | |
216 (conj {} {nil {}}) {nil {}} | |
217 (conj {} {{} nil}) {{} nil} | |
218 (conj {} {{} {}}) {{} {}} | |
219 | |
220 ; set | |
221 (conj #{} 1) #{1} | |
222 (conj #{} 1 2 3) #{1 2 3} | |
223 | |
224 (conj #{2 3} 1) #{3 1 2} | |
225 (conj #{3 2} 1) #{1 2 3} | |
226 | |
227 (conj #{2 3} 2) #{2 3} | |
228 (conj #{2 3} 2 3) #{2 3} | |
229 (conj #{2 3} 4 1 2 3) #{1 2 3 4} | |
230 | |
231 (conj #{} nil) #{nil} | |
232 (conj #{} #{}) #{#{}} )) | |
233 | |
234 | |
235 ;; *** Lists and Vectors *** | |
236 | |
237 (deftest test-peek | |
238 ; doesn't work for sets and maps | |
239 (is (thrown? ClassCastException (peek #{1}))) | |
240 (is (thrown? ClassCastException (peek {:a 1}))) | |
241 | |
242 (are [x y] (= x y) | |
243 (peek nil) nil | |
244 | |
245 ; list = first | |
246 (peek ()) nil | |
247 (peek '(1)) 1 | |
248 (peek '(1 2 3)) 1 | |
249 | |
250 (peek '(nil)) nil ; special cases | |
251 (peek '(1 nil)) 1 | |
252 (peek '(nil 2)) nil | |
253 (peek '(())) () | |
254 (peek '(() nil)) () | |
255 (peek '(() 2 nil)) () | |
256 | |
257 ; vector = last | |
258 (peek []) nil | |
259 (peek [1]) 1 | |
260 (peek [1 2 3]) 3 | |
261 | |
262 (peek [nil]) nil ; special cases | |
263 (peek [1 nil]) nil | |
264 (peek [nil 2]) 2 | |
265 (peek [[]]) [] | |
266 (peek [[] nil]) nil | |
267 (peek [[] 2 nil]) nil )) | |
268 | |
269 | |
270 (deftest test-pop | |
271 ; doesn't work for sets and maps | |
272 (is (thrown? ClassCastException (pop #{1}))) | |
273 (is (thrown? ClassCastException (pop #{:a 1}))) | |
274 | |
275 ; collection cannot be empty | |
276 (is (thrown? IllegalStateException (pop ()))) | |
277 (is (thrown? IllegalStateException (pop []))) | |
278 | |
279 (are [x y] (= x y) | |
280 (pop nil) nil | |
281 | |
282 ; list - pop first | |
283 (pop '(1)) () | |
284 (pop '(1 2 3)) '(2 3) | |
285 | |
286 (pop '(nil)) () | |
287 (pop '(1 nil)) '(nil) | |
288 (pop '(nil 2)) '(2) | |
289 (pop '(())) () | |
290 (pop '(() nil)) '(nil) | |
291 (pop '(() 2 nil)) '(2 nil) | |
292 | |
293 ; vector - pop last | |
294 (pop [1]) [] | |
295 (pop [1 2 3]) [1 2] | |
296 | |
297 (pop [nil]) [] | |
298 (pop [1 nil]) [1] | |
299 (pop [nil 2]) [nil] | |
300 (pop [[]]) [] | |
301 (pop [[] nil]) [[]] | |
302 (pop [[] 2 nil]) [[] 2] )) | |
303 | |
304 | |
305 ;; *** Lists (IPersistentList) *** | |
306 | |
307 (deftest test-list | |
308 (are [x] (list? x) | |
309 () | |
310 '() | |
311 (list) | |
312 (list 1 2 3) ) | |
313 | |
314 ; order is important | |
315 (are [x y] (not (= x y)) | |
316 (list 1 2) (list 2 1) | |
317 (list 3 1 2) (list 1 2 3) ) | |
318 | |
319 (are [x y] (= x y) | |
320 '() () | |
321 (list) '() | |
322 (list 1) '(1) | |
323 (list 1 2) '(1 2) | |
324 | |
325 ; nesting | |
326 (list 1 (list 2 3) (list 3 (list 4 5 (list 6 (list 7))))) | |
327 '(1 (2 3) (3 (4 5 (6 (7))))) | |
328 | |
329 ; different data structures | |
330 (list true false nil) | |
331 '(true false nil) | |
332 (list 1 2.5 2/3 "ab" \x 'cd :kw) | |
333 '(1 2.5 2/3 "ab" \x cd :kw) | |
334 (list (list 1 2) [3 4] {:a 1 :b 2} #{:c :d}) | |
335 '((1 2) [3 4] {:a 1 :b 2} #{:c :d}) | |
336 | |
337 ; evaluation | |
338 (list (+ 1 2) [(+ 2 3) 'a] (list (* 2 3) 8)) | |
339 '(3 [5 a] (6 8)) | |
340 | |
341 ; special cases | |
342 (list nil) '(nil) | |
343 (list 1 nil) '(1 nil) | |
344 (list nil 2) '(nil 2) | |
345 (list ()) '(()) | |
346 (list 1 ()) '(1 ()) | |
347 (list () 2) '(() 2) )) | |
348 | |
349 | |
350 ;; *** Maps (IPersistentMap) *** | |
351 | |
352 (deftest test-find | |
353 (are [x y] (= x y) | |
354 (find {} :a) nil | |
355 | |
356 (find {:a 1} :a) [:a 1] | |
357 (find {:a 1} :b) nil | |
358 | |
359 (find {:a 1 :b 2} :a) [:a 1] | |
360 (find {:a 1 :b 2} :b) [:b 2] | |
361 (find {:a 1 :b 2} :c) nil | |
362 | |
363 (find {} nil) nil | |
364 (find {:a 1} nil) nil | |
365 (find {:a 1 :b 2} nil) nil )) | |
366 | |
367 | |
368 (deftest test-contains? | |
369 ; contains? is designed to work preferably on maps and sets | |
370 (are [x y] (= x y) | |
371 (contains? {} :a) false | |
372 (contains? {} nil) false | |
373 | |
374 (contains? {:a 1} :a) true | |
375 (contains? {:a 1} :b) false | |
376 (contains? {:a 1} nil) false | |
377 | |
378 (contains? {:a 1 :b 2} :a) true | |
379 (contains? {:a 1 :b 2} :b) true | |
380 (contains? {:a 1 :b 2} :c) false | |
381 (contains? {:a 1 :b 2} nil) false | |
382 | |
383 ; sets | |
384 (contains? #{} 1) false | |
385 (contains? #{} nil) false | |
386 | |
387 (contains? #{1} 1) true | |
388 (contains? #{1} 2) false | |
389 (contains? #{1} nil) false | |
390 | |
391 (contains? #{1 2 3} 1) true | |
392 (contains? #{1 2 3} 3) true | |
393 (contains? #{1 2 3} 10) false | |
394 (contains? #{1 2 3} nil) false) | |
395 | |
396 ; numerically indexed collections (e.g. vectors and Java arrays) | |
397 ; => test if the numeric key is WITHIN THE RANGE OF INDEXES | |
398 (are [x y] (= x y) | |
399 (contains? [] 0) false | |
400 (contains? [] -1) false | |
401 (contains? [] 1) false | |
402 | |
403 (contains? [1] 0) true | |
404 (contains? [1] -1) false | |
405 (contains? [1] 1) false | |
406 | |
407 (contains? [1 2 3] 0) true | |
408 (contains? [1 2 3] 2) true | |
409 (contains? [1 2 3] 3) false | |
410 (contains? [1 2 3] -1) false | |
411 | |
412 ; arrays | |
413 (contains? (into-array []) 0) false | |
414 (contains? (into-array []) -1) false | |
415 (contains? (into-array []) 1) false | |
416 | |
417 (contains? (into-array [1]) 0) true | |
418 (contains? (into-array [1]) -1) false | |
419 (contains? (into-array [1]) 1) false | |
420 | |
421 (contains? (into-array [1 2 3]) 0) true | |
422 (contains? (into-array [1 2 3]) 2) true | |
423 (contains? (into-array [1 2 3]) 3) false | |
424 (contains? (into-array [1 2 3]) -1) false) | |
425 | |
426 ; 'contains?' operates constant or logarithmic time, | |
427 ; it WILL NOT perform a linear search for a value. | |
428 (are [x] (= x false) | |
429 (contains? '(1 2 3) 0) | |
430 (contains? '(1 2 3) 1) | |
431 (contains? '(1 2 3) 3) | |
432 (contains? '(1 2 3) 10) | |
433 (contains? '(1 2 3) nil) | |
434 (contains? '(1 2 3) ()) )) | |
435 | |
436 | |
437 (deftest test-keys | |
438 (are [x y] (= x y) ; other than map data structures | |
439 (keys ()) nil | |
440 (keys []) nil | |
441 (keys #{}) nil | |
442 (keys "") nil ) | |
443 | |
444 (are [x y] (= x y) | |
445 ; (class {:a 1}) => clojure.lang.PersistentArrayMap | |
446 (keys {}) nil | |
447 (keys {:a 1}) '(:a) | |
448 (diff (keys {:a 1 :b 2}) '(:a :b)) nil ; (keys {:a 1 :b 2}) '(:a :b) | |
449 | |
450 ; (class (sorted-map :a 1)) => clojure.lang.PersistentTreeMap | |
451 (keys (sorted-map)) nil | |
452 (keys (sorted-map :a 1)) '(:a) | |
453 (diff (keys (sorted-map :a 1 :b 2)) '(:a :b)) nil ; (keys (sorted-map :a 1 :b 2)) '(:a :b) | |
454 | |
455 ; (class (hash-map :a 1)) => clojure.lang.PersistentHashMap | |
456 (keys (hash-map)) nil | |
457 (keys (hash-map :a 1)) '(:a) | |
458 (diff (keys (hash-map :a 1 :b 2)) '(:a :b)) nil )) ; (keys (hash-map :a 1 :b 2)) '(:a :b) | |
459 | |
460 | |
461 (deftest test-vals | |
462 (are [x y] (= x y) ; other than map data structures | |
463 (vals ()) nil | |
464 (vals []) nil | |
465 (vals #{}) nil | |
466 (vals "") nil ) | |
467 | |
468 (are [x y] (= x y) | |
469 ; (class {:a 1}) => clojure.lang.PersistentArrayMap | |
470 (vals {}) nil | |
471 (vals {:a 1}) '(1) | |
472 (diff (vals {:a 1 :b 2}) '(1 2)) nil ; (vals {:a 1 :b 2}) '(1 2) | |
473 | |
474 ; (class (sorted-map :a 1)) => clojure.lang.PersistentTreeMap | |
475 (vals (sorted-map)) nil | |
476 (vals (sorted-map :a 1)) '(1) | |
477 (diff (vals (sorted-map :a 1 :b 2)) '(1 2)) nil ; (vals (sorted-map :a 1 :b 2)) '(1 2) | |
478 | |
479 ; (class (hash-map :a 1)) => clojure.lang.PersistentHashMap | |
480 (vals (hash-map)) nil | |
481 (vals (hash-map :a 1)) '(1) | |
482 (diff (vals (hash-map :a 1 :b 2)) '(1 2)) nil )) ; (vals (hash-map :a 1 :b 2)) '(1 2) | |
483 | |
484 | |
485 (deftest test-key | |
486 (are [x] (= (key (first (hash-map x :value))) x) | |
487 nil | |
488 false true | |
489 0 42 | |
490 0.0 3.14 | |
491 2/3 | |
492 0M 1M | |
493 \c | |
494 "" "abc" | |
495 'sym | |
496 :kw | |
497 () '(1 2) | |
498 [] [1 2] | |
499 {} {:a 1 :b 2} | |
500 #{} #{1 2} )) | |
501 | |
502 | |
503 (deftest test-val | |
504 (are [x] (= (val (first (hash-map :key x))) x) | |
505 nil | |
506 false true | |
507 0 42 | |
508 0.0 3.14 | |
509 2/3 | |
510 0M 1M | |
511 \c | |
512 "" "abc" | |
513 'sym | |
514 :kw | |
515 () '(1 2) | |
516 [] [1 2] | |
517 {} {:a 1 :b 2} | |
518 #{} #{1 2} )) | |
519 | |
520 (deftest test-get | |
521 (let [m {:a 1, :b 2, :c {:d 3, :e 4}, :f nil, :g false, nil {:h 5}}] | |
522 (is (thrown? IllegalArgumentException (get-in {:a 1} 5))) | |
523 (are [x y] (= x y) | |
524 (get m :a) 1 | |
525 (get m :e) nil | |
526 (get m :e 0) 0 | |
527 (get m :b 0) 2 | |
528 (get m :f 0) nil | |
529 | |
530 (get-in m [:c :e]) 4 | |
531 (get-in m '(:c :e)) 4 | |
532 (get-in m [:c :x]) nil | |
533 (get-in m [:f]) nil | |
534 (get-in m [:g]) false | |
535 (get-in m [:h]) nil | |
536 (get-in m []) m | |
537 (get-in m nil) m | |
538 | |
539 (get-in m [:c :e] 0) 4 | |
540 (get-in m '(:c :e) 0) 4 | |
541 (get-in m [:c :x] 0) 0 | |
542 (get-in m [:b] 0) 2 | |
543 (get-in m [:f] 0) nil | |
544 (get-in m [:g] 0) false | |
545 (get-in m [:h] 0) 0 | |
546 (get-in m [:x :y] {:y 1}) {:y 1} | |
547 (get-in m [] 0) m | |
548 (get-in m nil 0) m))) | |
549 | |
550 ;; *** Sets *** | |
551 | |
552 (deftest test-hash-set | |
553 (are [x] (set? x) | |
554 #{} | |
555 #{1 2} | |
556 (hash-set) | |
557 (hash-set 1 2) ) | |
558 | |
559 ; order isn't important | |
560 (are [x y] (= x y) | |
561 #{1 2} #{2 1} | |
562 #{3 1 2} #{1 2 3} | |
563 (hash-set 1 2) (hash-set 2 1) | |
564 (hash-set 3 1 2) (hash-set 1 2 3) ) | |
565 | |
566 | |
567 (are [x y] (= x y) | |
568 ; equal classes | |
569 (class #{}) (class (hash-set)) | |
570 (class #{1 2}) (class (hash-set 1 2)) | |
571 | |
572 ; creating | |
573 (hash-set) #{} | |
574 (hash-set 1) #{1} | |
575 (hash-set 1 2) #{1 2} | |
576 | |
577 ; nesting | |
578 (hash-set 1 (hash-set 2 3) (hash-set 3 (hash-set 4 5 (hash-set 6 (hash-set 7))))) | |
579 #{1 #{2 3} #{3 #{4 5 #{6 #{7}}}}} | |
580 | |
581 ; different data structures | |
582 (hash-set true false nil) | |
583 #{true false nil} | |
584 (hash-set 1 2.5 2/3 "ab" \x 'cd :kw) | |
585 #{1 2.5 2/3 "ab" \x 'cd :kw} | |
586 (hash-set (list 1 2) [3 4] {:a 1 :b 2} #{:c :d}) | |
587 #{'(1 2) [3 4] {:a 1 :b 2} #{:c :d}} | |
588 | |
589 ; evaluation | |
590 (hash-set (+ 1 2) [(+ 2 3) :a] (hash-set (* 2 3) 8)) | |
591 #{3 [5 :a] #{6 8}} | |
592 | |
593 ; special cases | |
594 (hash-set nil) #{nil} | |
595 (hash-set 1 nil) #{1 nil} | |
596 (hash-set nil 2) #{nil 2} | |
597 (hash-set #{}) #{#{}} | |
598 (hash-set 1 #{}) #{1 #{}} | |
599 (hash-set #{} 2) #{#{} 2} )) | |
600 | |
601 | |
602 (deftest test-sorted-set | |
603 ; only compatible types can be used | |
604 (is (thrown? ClassCastException (sorted-set 1 "a"))) | |
605 (is (thrown? ClassCastException (sorted-set '(1 2) [3 4]))) | |
606 | |
607 ; creates set? | |
608 (are [x] (set? x) | |
609 (sorted-set) | |
610 (sorted-set 1 2) ) | |
611 | |
612 ; equal and unique | |
613 (are [x] (and (= (sorted-set x) #{x}) | |
614 (= (sorted-set x x) (sorted-set x))) | |
615 nil | |
616 false true | |
617 0 42 | |
618 0.0 3.14 | |
619 2/3 | |
620 0M 1M | |
621 \c | |
622 "" "abc" | |
623 'sym | |
624 :kw | |
625 () ; '(1 2) | |
626 [] [1 2] | |
627 {} ; {:a 1 :b 2} | |
628 #{} ; #{1 2} | |
629 ) | |
630 ; cannot be cast to java.lang.Comparable | |
631 (is (thrown? ClassCastException (sorted-set '(1 2) '(1 2)))) | |
632 (is (thrown? ClassCastException (sorted-set {:a 1 :b 2} {:a 1 :b 2}))) | |
633 (is (thrown? ClassCastException (sorted-set #{1 2} #{1 2}))) | |
634 | |
635 (are [x y] (= x y) | |
636 ; generating | |
637 (sorted-set) #{} | |
638 (sorted-set 1) #{1} | |
639 (sorted-set 1 2) #{1 2} | |
640 | |
641 ; sorting | |
642 (seq (sorted-set 5 4 3 2 1)) '(1 2 3 4 5) | |
643 | |
644 ; special cases | |
645 (sorted-set nil) #{nil} | |
646 (sorted-set 1 nil) #{nil 1} | |
647 (sorted-set nil 2) #{nil 2} | |
648 (sorted-set #{}) #{#{}} )) | |
649 | |
650 | |
651 (deftest test-sorted-set-by | |
652 ; only compatible types can be used | |
653 ; NB: not a ClassCastException, but a RuntimeException is thrown, | |
654 ; requires discussion on whether this should be symmetric with test-sorted-set | |
655 (is (thrown? Exception (sorted-set-by < 1 "a"))) | |
656 (is (thrown? Exception (sorted-set-by < '(1 2) [3 4]))) | |
657 | |
658 ; creates set? | |
659 (are [x] (set? x) | |
660 (sorted-set-by <) | |
661 (sorted-set-by < 1 2) ) | |
662 | |
663 ; equal and unique | |
664 (are [x] (and (= (sorted-set-by compare x) #{x}) | |
665 (= (sorted-set-by compare x x) (sorted-set-by compare x))) | |
666 nil | |
667 false true | |
668 0 42 | |
669 0.0 3.14 | |
670 2/3 | |
671 0M 1M | |
672 \c | |
673 "" "abc" | |
674 'sym | |
675 :kw | |
676 () ; '(1 2) | |
677 [] [1 2] | |
678 {} ; {:a 1 :b 2} | |
679 #{} ; #{1 2} | |
680 ) | |
681 ; cannot be cast to java.lang.Comparable | |
682 ; NB: not a ClassCastException, but a RuntimeException is thrown, | |
683 ; requires discussion on whether this should be symmetric with test-sorted-set | |
684 (is (thrown? Exception (sorted-set-by compare '(1 2) '(1 2)))) | |
685 (is (thrown? Exception (sorted-set-by compare {:a 1 :b 2} {:a 1 :b 2}))) | |
686 (is (thrown? Exception (sorted-set-by compare #{1 2} #{1 2}))) | |
687 | |
688 (are [x y] (= x y) | |
689 ; generating | |
690 (sorted-set-by >) #{} | |
691 (sorted-set-by > 1) #{1} | |
692 (sorted-set-by > 1 2) #{1 2} | |
693 | |
694 ; sorting | |
695 (seq (sorted-set-by < 5 4 3 2 1)) '(1 2 3 4 5) | |
696 | |
697 ; special cases | |
698 (sorted-set-by compare nil) #{nil} | |
699 (sorted-set-by compare 1 nil) #{nil 1} | |
700 (sorted-set-by compare nil 2) #{nil 2} | |
701 (sorted-set-by compare #{}) #{#{}} )) | |
702 | |
703 | |
704 (deftest test-set | |
705 ; set? | |
706 (are [x] (set? (set x)) | |
707 () '(1 2) | |
708 [] [1 2] | |
709 #{} #{1 2} | |
710 {} {:a 1 :b 2} | |
711 (into-array []) (into-array [1 2]) | |
712 "" "abc" ) | |
713 | |
714 ; unique | |
715 (are [x] (= (set [x x]) #{x}) | |
716 nil | |
717 false true | |
718 0 42 | |
719 0.0 3.14 | |
720 2/3 | |
721 0M 1M | |
722 \c | |
723 "" "abc" | |
724 'sym | |
725 :kw | |
726 () '(1 2) | |
727 [] [1 2] | |
728 {} {:a 1 :b 2} | |
729 #{} #{1 2} ) | |
730 | |
731 ; conversion | |
732 (are [x y] (= (set x) y) | |
733 () #{} | |
734 '(1 2) #{1 2} | |
735 | |
736 [] #{} | |
737 [1 2] #{1 2} | |
738 | |
739 #{} #{} ; identity | |
740 #{1 2} #{1 2} ; identity | |
741 | |
742 {} #{} | |
743 {:a 1 :b 2} #{[:a 1] [:b 2]} | |
744 | |
745 (into-array []) #{} | |
746 (into-array [1 2]) #{1 2} | |
747 | |
748 "" #{} | |
749 "abc" #{\a \b \c} )) | |
750 | |
751 | |
752 (deftest test-disj | |
753 ; doesn't work on lists, vectors or maps | |
754 (is (thrown? ClassCastException (disj '(1 2) 1))) | |
755 (is (thrown? ClassCastException (disj [1 2] 1))) | |
756 (is (thrown? ClassCastException (disj {:a 1} :a))) | |
757 | |
758 ; identity | |
759 (are [x] (= (disj x) x) | |
760 nil | |
761 #{} | |
762 #{1 2 3} | |
763 ; different data types | |
764 #{nil | |
765 false true | |
766 0 42 | |
767 0.0 3.14 | |
768 2/3 | |
769 0M 1M | |
770 \c | |
771 "" "abc" | |
772 'sym | |
773 :kw | |
774 [] [1 2] | |
775 {} {:a 1 :b 2} | |
776 #{} #{1 2}} ) | |
777 | |
778 ; type identity | |
779 (are [x] (= (class (disj x)) (class x)) | |
780 (hash-set) | |
781 (hash-set 1 2) | |
782 (sorted-set) | |
783 (sorted-set 1 2) ) | |
784 | |
785 (are [x y] (= x y) | |
786 (disj nil :a) nil | |
787 (disj nil :a :b) nil | |
788 | |
789 (disj #{} :a) #{} | |
790 (disj #{} :a :b) #{} | |
791 | |
792 (disj #{:a} :a) #{} | |
793 (disj #{:a} :a :b) #{} | |
794 (disj #{:a} :c) #{:a} | |
795 | |
796 (disj #{:a :b :c :d} :a) #{:b :c :d} | |
797 (disj #{:a :b :c :d} :a :d) #{:b :c} | |
798 (disj #{:a :b :c :d} :a :b :c) #{:d} | |
799 (disj #{:a :b :c :d} :d :a :c :b) #{} | |
800 | |
801 (disj #{nil} :a) #{nil} | |
802 (disj #{nil} #{}) #{nil} | |
803 (disj #{nil} nil) #{} | |
804 | |
805 (disj #{#{}} nil) #{#{}} | |
806 (disj #{#{}} #{}) #{} | |
807 (disj #{#{nil}} #{nil}) #{} )) | |
808 | |
809 | |
810 ;; *** Queues *** | |
811 | |
812 (deftest test-queues | |
813 (let [EMPTY clojure.lang.PersistentQueue/EMPTY] | |
814 (are [x y] (= x y) | |
815 EMPTY EMPTY | |
816 (into EMPTY (range 50)) (into EMPTY (range 50)) | |
817 (range 5) (into EMPTY (range 5)) | |
818 (range 1 6) (-> EMPTY | |
819 (into (range 6)) | |
820 pop)) | |
821 (are [x y] (not= x y) | |
822 (range 5) (into EMPTY (range 6)) | |
823 (range 6) (into EMPTY (range 5)) | |
824 (range 0 6) (-> EMPTY | |
825 (into (range 6)) | |
826 pop) | |
827 (range 1 6) (-> EMPTY | |
828 (into (range 7)) | |
829 pop)))) | |
830 |