File: set_test.clj

package info (click to toggle)
ordered-clojure 1.15.12-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212 kB
  • sloc: makefile: 22; sh: 19
file content (178 lines) | stat: -rw-r--r-- 6,087 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
(ns flatland.ordered.set-test
  (:use clojure.test
        [flatland.ordered.set :only [ordered-set]]
        [flatland.ordered.common :only [compact]])
  (:import (flatland.ordered.set OrderedSet)))

(deftest implementations
  (let [s (ordered-set)]
    (testing "Interfaces marked as implemented"
      (are [class] (instance? class s)
           clojure.lang.IPersistentSet
           clojure.lang.IPersistentCollection
           clojure.lang.Counted
           java.util.Set))
    (testing "Behavior smoke testing"
      (testing "Most operations don't change type"
        (are [object] (= (class object) (class s))
             (conj s 1 2)
             (disj s 1)
             (into s #{1 2})))
      (testing "Seq-oriented operations return nil when empty"
        (are [object] (nil? object)
             (seq s)
             (rseq s)))
      (testing "Metadata"
        (is (nil? (seq (meta s))))
        (is (= 10 (-> s
                      (with-meta {:size 10})
                      meta
                      :size)))
        (is (= {:succeeded true}
               (-> s
                   (vary-meta assoc :succeeded true)
                   meta)))
        (is (= {:meta :here}
               (-> s
                   (with-meta {:meta :here})
                   (conj :a)
                   (empty)
                   (meta))))
        (testing "Metadata doesn't affect other properties"
          (let [m (with-meta s {:a 1})]
            (is (instance? OrderedSet m))
            (is (= m s))))
        (testing "Metadata behaves like set's metadata"
          (let [meta-map {:meta 1}
                s1 (with-meta #{} meta-map)
                s2 (with-meta s meta-map)]
            (is (= (meta (conj s1 1 2))
                   (meta (conj s2 1 2))))))))))

(deftest equality
  (let [empty (ordered-set)
        one-item (conj empty 1)]
    (testing "Basic symmetric equality"
      (is (= #{} empty))
      (is (= empty #{}))
      (is (= #{1} one-item))
      (is (= one-item #{1})))
    (testing "Order-insensitive comparisons"
      (let [one-way (into empty [1 2 3 4])
            other-way (into empty [3 4 1 2])
            unsorted #{1 2 3 4}]
        (is (= one-way other-way))
        (is (= one-way unsorted))
        (is (= other-way unsorted))))))

(deftest ordering
  (let [values [[:first 10]
                [:second 20]
                [:third 30]]
        s (into (ordered-set) values)]
    (testing "Seq behaves like seq of a vector"
      (is (= (seq values) (seq s))))
    (testing "New values get added at the end"
      (let [entry [:fourth 40]]
        (is (= (seq (conj values entry))
               (seq (conj s entry))))))
    (testing "Re-adding keys leaves them in the same place"
      (is (= (seq s)
             (seq (conj s [:second 20])))))
    (testing "Large number of keys still sorted"
      (let [ints (range 5000)
            ordered (into s ints)]
        (= (seq ints) (seq ordered))))))

(deftest reversing
  (let [source (vec (range 1000))
        s (into (sorted-set) source)]
    (is (= (rseq s) (rseq source)))))

(deftest set-features
  (let [s (ordered-set :a 1 :b 2 :c 3)]
    (testing "Keyword lookup"
      (is (= :a (:a s))))
    (testing "IFn support"
      (is (= :b (s :b))))
    (testing "Falsy lookup support"
      (is (= false (#{false 1} false))))
    (testing "Ordered disj"
      (is (= #{:a 1 2 3} (disj s :b :c))))))

(deftest object-features
  (let [s (ordered-set 'a 1 :b 2)]
    (is (= "#{a 1 :b 2}" (str s)))))

(deftest transient-support
  (let [s (ordered-set 1 2 7 8)]
    (testing "Basic transient conj!"
      (let [t (transient s)
            t (conj! t 4) ; add 4
            t (conj! t 4) ; do nothing, 4's already there
            t (conj! t 1) ; should do nothing
            p (persistent! t)]
        (is (= p (conj s 4)))))
    (testing "Transients still keep order"
      (let [t (transient s)
            t (conj! t 0)
            t (conj! t 1)
            p (persistent! t)]
        (is (= (concat (seq s) '(0)) ; adding 0 (at the end) but not 1
               (seq p)))))
    (testing "Transients can disj!"
      (let [k (first s)
            t (transient s)
            t (disj! t k)]
        (is (= (persistent! t)
               (disj s k)))))
    (testing "Can lookup in transients"
      (let [t (transient s)]
        (is (.contains t (first s)))))))

(deftest print-and-read-ordered
  (let [s (ordered-set 1 2 9 8 7 5)]
    (is (= "#ordered/set (1 2 9 8 7 5)"
           (pr-str s)))
    (let [o (read-string (pr-str s))]
      (is (= OrderedSet (type o)))
      (is (= '(1 2 9 8 7 5)
             (seq o))))))

(deftest print-read-eval-ordered
  (is (= (seq (eval (read-string "#ordered/set (1 2 9 8 7 5)")))
         '(1 2 9 8 7 5)))
  (is (= (seq (eval (read-string "#ordered/set ([1 2] [3 4] [5 6] [1 9] [7 8])")))
         '([1 2] [3 4] [5 6] [1 9] [7 8]))))

(deftest compacting
  (let [s1 (ordered-set :a :b :c)
        s2 (disj s1 :b)
        s3 (compact s2)
        s4 (disj s3 :c)]
    (is (= s2 (ordered-set :a :c)))
    (is (= s3 s2))
    (is (= s4 (ordered-set :a)))))

(deftest same-hash
  (let [m1 (ordered-set :a :b :c)
        m2 (hash-set :a :b :c)]
    (is (= (hash m1) (hash m2)))
    (is (= (.hashCode m1) (.hashCode m2)))
    (is (= (hash (ordered-set)) (hash (hash-set))))
    (is (= (.hashCode (ordered-set)) (.hashCode (hash-set))))
    (is (= (hash (ordered-set nil)) (hash (hash-set nil))))
    (is (= (.hashCode (ordered-set nil)) (.hashCode (hash-set nil))))
    (is (= (.hashCode (ordered-set nil :a {:b nil})) (.hashCode (hash-set nil :a {:b nil}))))))

(deftest nil-and-false-hashes
  (is (not= (.hashCode (ordered-set nil)) (.hashCode (hash-set false))))
  (is (not= (.hashCode (ordered-set false)) (.hashCode (hash-set nil))))
  (is (= (.hashCode (ordered-set false nil)) (.hashCode (hash-set nil false)))))

(deftest nil-hash-code-npe
  ;; No assertions here; just check that it doesn't NPE
  ;; See: https://github.com/amalloy/ordered/issues/27
  (are [contents] (.hashCode (apply ordered-set contents))
    [nil]
    [nil :a]))