/test/clojure/test_clojure/data_structures.clj

https://github.com/warn4n/clojure · Clojure · 862 lines · 585 code · 166 blank · 111 comment · 48 complexity · 2efcd927b9412846ad0a57f736c2f0b1 MD5 · raw file

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