|
| 1 | +(ns clojure.core-test.min-key |
| 2 | + (:require [clojure.test :as t :refer [are deftest is testing]] |
| 3 | + [clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists]])) |
| 4 | + |
| 5 | + |
| 6 | +(when-var-exists min-key |
| 7 | + (defn my-abs [x] |
| 8 | + (if (< x 0) |
| 9 | + (- x) |
| 10 | + x)) |
| 11 | + |
| 12 | + (defn my-sqr [x] |
| 13 | + (* x x)) |
| 14 | + |
| 15 | + ;; to help with nan testing |
| 16 | + (defn =-or-NaN? [x y] |
| 17 | + (or (= x y) |
| 18 | + (and (NaN? x) (NaN? y)))) |
| 19 | + |
| 20 | + (deftest test-min-key |
| 21 | + ;; adapted from `min.cljc` |
| 22 | + (testing "numeric ordering" |
| 23 | + (are [expected f col] (= expected (apply min-key f col)) |
| 24 | + 1 identity [1 2] |
| 25 | + 1 identity [1 3 2] |
| 26 | + 1N identity [1N 2N] |
| 27 | + 1N identity [2N 1N 3N] |
| 28 | + 1N identity [1N 2] |
| 29 | + 1 identity [1 2N] |
| 30 | + 1.0 identity [1.0 2.0] |
| 31 | + 1 identity [1 2.0] |
| 32 | + 1.0 identity [1.0 2] |
| 33 | + #?@(:cljs [] |
| 34 | + :default |
| 35 | + [1/2 identity [1/2 2/2] |
| 36 | + 1/2 identity [1/2 2/2 3/2] |
| 37 | + 1/2 identity [1/2 1] |
| 38 | + 1/2 identity [1/2 1 2N]]))) |
| 39 | + |
| 40 | + ;; NaN ordering weirdness because `(<= ##NaN 1)` and `(<= 1 ##NaN)` are both false |
| 41 | + (testing "IEEE754 special cases" |
| 42 | + (are [expected f col] (=-or-NaN? expected (apply min-key f col)) |
| 43 | + ##-Inf identity [##-Inf ##Inf] |
| 44 | + 1 identity [1 ##Inf] |
| 45 | + ##-Inf identity [1 ##-Inf] |
| 46 | + ;; testing every permutation of -Inf, 1, and NaN |
| 47 | + #?@(:lpy |
| 48 | + [##NaN identity [##NaN 1] |
| 49 | + 1 identity [1 ##NaN] |
| 50 | + ##NaN identity [##NaN ##-Inf 1] |
| 51 | + ##NaN identity [##NaN 1 ##-Inf]] |
| 52 | + :default |
| 53 | + [1 identity [##NaN 1] |
| 54 | + ##NaN identity [1 ##NaN] |
| 55 | + ##-Inf identity [##NaN ##-Inf 1] |
| 56 | + ##-Inf identity [##NaN 1 ##-Inf]]) |
| 57 | + #?@(:lpy |
| 58 | + [##-Inf identity [##-Inf 1 ##NaN] |
| 59 | + ##-Inf identity [##-Inf ##NaN 1] |
| 60 | + ##-Inf identity [1 ##-Inf ##NaN] |
| 61 | + ##-Inf identity [1 ##NaN ##-Inf]] |
| 62 | + :cljs |
| 63 | + [##NaN identity [##-Inf 1 ##NaN] |
| 64 | + 1 identity [##-Inf ##NaN 1] |
| 65 | + ##NaN identity [1 ##-Inf ##NaN] |
| 66 | + ##-Inf identity [1 ##NaN ##-Inf]] |
| 67 | + :default |
| 68 | + [##-Inf identity [##-Inf 1 ##NaN] |
| 69 | + ##NaN identity [##-Inf ##NaN 1] |
| 70 | + ##-Inf identity [1 ##-Inf ##NaN] |
| 71 | + ##NaN identity [1 ##NaN ##-Inf]]))) |
| 72 | + |
| 73 | + (testing "single argument" |
| 74 | + (is (= 1 (min-key identity 1))) |
| 75 | + (is (= 2 (min-key identity 2))) |
| 76 | + (is (= "x" (min-key identity "x"))) |
| 77 | + (is (= 1 (min-key nil 1)))) |
| 78 | + |
| 79 | + (testing "multi argument" |
| 80 | + (are [expected f col] (= expected (apply min-key f col)) |
| 81 | + -3 inc [-3 -1 2] |
| 82 | + 1 identity [1 2 3 4 5] |
| 83 | + 1 identity [5 4 3 2 1] |
| 84 | + 1 identity [1 2 3 4 1] |
| 85 | + ##-Inf identity [1 2 3 4 5 ##-Inf] |
| 86 | + -1 my-abs [-3 -1 2] |
| 87 | + -1 my-sqr [-3 -1 2 4])) |
| 88 | + |
| 89 | + (testing "multiple types" |
| 90 | + (are [expected f col] (= expected (apply min-key f col)) |
| 91 | + "a" count ["a" "bb" "ccc"] |
| 92 | + "c" count ["a" "bb" "c"] |
| 93 | + "a" (constantly 5) [nil 1 {:k 2} [3] '(4) #{5} "a"] |
| 94 | + {:val 2} :val [{:val 2} {:val 3} {:val 4}] |
| 95 | + #?@(:lpy |
| 96 | + ["x" identity ["x" "y"] |
| 97 | + "x" identity ["y" "x" "z"] |
| 98 | + [1] identity [[1] [2]] |
| 99 | + [1] identity [[2] [1] [3]] |
| 100 | + #{1} identity [#{1} #{2}] |
| 101 | + #{2} identity [#{2} #{1} #{3}]] |
| 102 | + :cljs |
| 103 | + ["x" identity ["x" "y"] |
| 104 | + "x" identity ["y" "x" "z"] |
| 105 | + [1] identity [[1] [2]] |
| 106 | + [1] identity [[2] [1] [3]] |
| 107 | + {:val 1} identity [{:val 1} {:val 2}] |
| 108 | + {:val 1} identity [{:val 2} {:val 1} {:val 3}] |
| 109 | + #{1} identity [#{1} #{2}] |
| 110 | + #{1} identity [#{2} #{1} #{3}] |
| 111 | + nil identity [nil nil]] |
| 112 | + :default []))) |
| 113 | + |
| 114 | + (testing "negative cases" |
| 115 | + (are [f col] (thrown? #?(:cljs js/Error :default Exception) (apply min-key f col)) |
| 116 | + nil [1 2] |
| 117 | + nil [2 1 3] |
| 118 | + #?@(:cljs [] |
| 119 | + :lpy |
| 120 | + [identity [{:val 1} {:val 2}] |
| 121 | + identity [{:val 2} {:val 1} {:val 3}]] |
| 122 | + :default |
| 123 | + [identity ["x" "y"] |
| 124 | + identity ["y" "x" "z"] |
| 125 | + identity [[1] [2]] |
| 126 | + identity [[2] [1] [3]] |
| 127 | + identity [{:val 1} {:val 2}] |
| 128 | + identity [{:val 2} {:val 1} {:val 3}] |
| 129 | + identity [#{1} #{2}] |
| 130 | + identity [#{2} #{1} #{3}]]))))) |
0 commit comments