Skip to content

Commit 27bdda5

Browse files
authored
Add tests for sort-by (#817)
* Add tests for `sort-by` * Remove some notes in comments * Tweak comment
1 parent 47a7cb0 commit 27bdda5

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
(ns clojure.core-test.sort-by
2+
(:require [clojure.test :as t :refer [deftest testing is are]]
3+
[clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists]]))
4+
5+
(when-var-exists sort-by
6+
;; Data for simple tests
7+
(def simple-vec-maps [{:a 2 :b 9}
8+
{:a 1 :b 10}
9+
{:a 4 :b 7}
10+
{:a 3 :b 8}])
11+
12+
;; Data for stable sorting
13+
(def stable-data [{:a 1 :b 11}
14+
{:a 1 :b 21}
15+
{:a 1 :b 39}
16+
{:a 1 :b 2}
17+
{:a 4 :b 5}
18+
{:a 2 :b 101}
19+
{:a 2 :b 71}
20+
{:a 2 :b 28}
21+
{:a 2 :b 99}
22+
{:a 4 :b 210}
23+
{:a 3 :b 113}
24+
{:a 3 :b 412}
25+
{:a 3 :b 135}
26+
{:a 3 :b 314}
27+
{:a 4 :b 215}])
28+
29+
(deftest test-sort-by
30+
(testing "sort-by artity-2"
31+
(testing "key-fn is `identity`"
32+
(are [expected x] (= expected (sort x) (sort-by identity x))
33+
;; cases from `sort` tests, since (sort ...) = (sort-by identity ...)
34+
'() nil
35+
'(1 2 3 4) [3 1 2 4]
36+
'(nil 2 3 4) [3 nil 2 4]
37+
'(1 2 3 4) '(3 1 2 4)
38+
'(1 2 3 4) #{3 1 2 4}
39+
'([:a 1] [:b 2] [:c 3]) {:c 3 :b 2 :a 1}
40+
'([1] [2] [3] [4]) [[3] [1] [2] [4]]
41+
'("a" "b" "c" "d") ["b" "a" "c" "d"]
42+
'(\c \e \j \l \o \r \u) "clojure"))
43+
(testing "key-fn is keyword"
44+
(is (= (seq [{:a 4 :b 7}
45+
{:a 3 :b 8}
46+
{:a 2 :b 9}
47+
{:a 1 :b 10}])
48+
(sort-by :b simple-vec-maps)))
49+
(is (= (seq [{:a 1 :b 10}
50+
{:a 2 :b 9}
51+
{:a 3 :b 8}
52+
{:a 4 :b 7}])
53+
(sort-by :a simple-vec-maps)))
54+
;; test more complex key-fn and stability of sort-by
55+
;; :a + :b = 11 for all elements of simple-vec-maps
56+
(is (= (seq simple-vec-maps)
57+
(sort-by #(+ (:a %) (:b %)) simple-vec-maps)))
58+
;; If the key-fn returns the same value all the time we also
59+
;; expect no change. For instance, when the key-fn returns
60+
;; `nil` constantly because we use the wrong keyword or we
61+
;; navigate the structure of the element incorrectly.
62+
(is (= (seq simple-vec-maps)
63+
(sort-by :c simple-vec-maps)))))
64+
65+
(testing "sort-by artity-3"
66+
;; Use `compare`
67+
(is (= (seq [{:a 1 :b 10}
68+
{:a 2 :b 9}
69+
{:a 3 :b 8}
70+
{:a 4 :b 7}])
71+
(sort-by :a compare simple-vec-maps)))
72+
;; Reverse `compare`
73+
(is (= (seq [{:a 4 :b 7}
74+
{:a 3 :b 8}
75+
{:a 2 :b 9}
76+
{:a 1 :b 10}])
77+
(sort-by :a #(compare %2 %1) simple-vec-maps)))
78+
(is (= (seq [{:a 1 :b 10}
79+
{:a 2 :b 9}
80+
{:a 3 :b 8}
81+
{:a 4 :b 7}])
82+
(sort-by :a < simple-vec-maps)))
83+
(is (= (seq [{:a 4 :b 7}
84+
{:a 3 :b 8}
85+
{:a 2 :b 9}
86+
{:a 1 :b 10}])
87+
(sort-by :a > simple-vec-maps)))
88+
89+
;; Use `compare`
90+
(is (= (seq [{:a 4 :b 7}
91+
{:a 3 :b 8}
92+
{:a 2 :b 9}
93+
{:a 1 :b 10}])
94+
(sort-by :b compare simple-vec-maps)))
95+
;; Reverse `compare`
96+
(is (= (seq [{:a 1 :b 10}
97+
{:a 2 :b 9}
98+
{:a 3 :b 8}
99+
{:a 4 :b 7}])
100+
(sort-by :b #(compare %2 %1) simple-vec-maps)))
101+
(is (= (seq [{:a 4 :b 7}
102+
{:a 3 :b 8}
103+
{:a 2 :b 9}
104+
{:a 1 :b 10}])
105+
(sort-by :b < simple-vec-maps)))
106+
(is (= (seq [{:a 1 :b 10}
107+
{:a 2 :b 9}
108+
{:a 3 :b 8}
109+
{:a 4 :b 7}])
110+
(sort-by :b > simple-vec-maps))))
111+
112+
(testing "negative cases"
113+
;; key-fn is not a fn
114+
(is (thrown? #?(:cljs :default, :default Exception) (sort-by nil simple-vec-maps)))
115+
(is (thrown? #?(:cljs :default, :default Exception) (sort-by [] simple-vec-maps)))
116+
;; comparator is not a fn
117+
(is (thrown? #?(:cljs :default, :default Exception) (sort-by :a nil simple-vec-maps)))
118+
(is (thrown? #?(:cljs :default, :default Exception) (sort-by :a [] simple-vec-maps)))
119+
;; collection is not a collection
120+
(is (thrown? #?(:cljs :default, :default Exception) (sort-by :a 1)))
121+
(is (thrown? #?(:cljs :default, :default Exception) (sort-by :a true))))
122+
123+
(testing "stable sort"
124+
;; sort first by :b and then by :a results in runs of :a in
125+
;; order with all the :b's associated with a given :a being in
126+
;; order
127+
(is (= (seq [{:a 1, :b 2}
128+
{:a 1, :b 11}
129+
{:a 1, :b 21}
130+
{:a 1, :b 39}
131+
{:a 2, :b 28}
132+
{:a 2, :b 71}
133+
{:a 2, :b 99}
134+
{:a 2, :b 101}
135+
{:a 3, :b 113}
136+
{:a 3, :b 135}
137+
{:a 3, :b 314}
138+
{:a 3, :b 412}
139+
{:a 4, :b 5}
140+
{:a 4, :b 210}
141+
{:a 4, :b 215}])
142+
(->> stable-data
143+
(sort-by :b)
144+
(sort-by :a)))))))

0 commit comments

Comments
 (0)