|
| 1 | +(ns clojure.core-test.merge |
| 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 clojure.core/merge |
| 6 | + (deftest test-merge |
| 7 | + (testing "`merge`" |
| 8 | + (testing "`nil` and empty map behavior" |
| 9 | + (is (nil? (merge))) |
| 10 | + (is (nil? (merge nil))) |
| 11 | + (is (nil? (merge nil nil))) |
| 12 | + (is (nil? (merge nil nil nil))) |
| 13 | + |
| 14 | + (is (= {} (merge {}))) |
| 15 | + (is (= {} (merge {} nil))) |
| 16 | + (is (= {} (merge nil {}))) |
| 17 | + (is (= {} (merge nil {} nil))) |
| 18 | + |
| 19 | + (is (= {[2 3] :foo} (merge {[2 3] :foo} nil {}))) |
| 20 | + (is (= {1 11} (merge {1 11} {} nil)))) |
| 21 | + |
| 22 | + (testing "lattermost mapping wins" |
| 23 | + (is (= {:a "aaaaa"} (merge {:a "a"} {:a "aaaaa"}))) |
| 24 | + (is (= {:a "a" :b "b"} (merge {:a "aaaa"} {:a "a" :b "b"}))) |
| 25 | + (is (= {:a "a" :b "b"} (merge {:a "aaaa"} |
| 26 | + {:a "a" :b "bbbb"} |
| 27 | + {:a "a" :b "b"}))) |
| 28 | + (is (= {:a nil :b "b" :c "c"} (merge {:a "aaaa"} |
| 29 | + {:a "a" :b "bbbb" :c "c"} |
| 30 | + {:a nil :b "b"}))) |
| 31 | + (is (= {:x 1 :y 10 :z 100} (merge {:x 1 :y 5555} |
| 32 | + {:y 10 :z 100})))) |
| 33 | + |
| 34 | + (testing "nested maps are replaced, not 'deep-merged'" |
| 35 | + (is (= {:ceo {:name "Alice"}, |
| 36 | + :cto {:name "Brenda"}} |
| 37 | + (merge {:ceo {:salary 1000000}} ; salary values are overwritten |
| 38 | + {:cto {:salary 500000}} |
| 39 | + {:ceo {:name "Alice"}} |
| 40 | + {:cto {:name "Brenda"}})))) |
| 41 | + |
| 42 | + (testing "map entries are accepted in position 2+, per `conj`" |
| 43 | + (is (= {:a "a", :b "b"} (merge {:a nil} |
| 44 | + (first {:a "a"}) |
| 45 | + {:b "b"})))) |
| 46 | + |
| 47 | + (testing "vectors in position 2+ are treated as map-entries, per `conj`" |
| 48 | + (is (thrown? #?(:cljs :default, :clj java.lang.IllegalArgumentException, :clr Exception) |
| 49 | + (merge {} []))) |
| 50 | + (is (thrown? #?(:cljs :default, :clj java.lang.IllegalArgumentException, :clr Exception) |
| 51 | + (merge {} [:foo]))) |
| 52 | + (is (= {:foo "foo"} (merge {} [:foo "foo"]))) |
| 53 | + (is (= {"x" 1} (merge {} ["x" 1]))) |
| 54 | + (is (= {'x 10, 'y 10} (merge {'x 10} ['y 10]))) |
| 55 | + (testing "In CLJS (unlike other dialects) vectors with >2 arguments are treated as map-entries (where the latter values are ignored)" |
| 56 | + #?(:cljs (is (= {:foo :bar} (merge {} [:foo :bar :baz]))), |
| 57 | + :clj (is (thrown? java.lang.IllegalArgumentException (merge {} [:foo :bar :baz]))), |
| 58 | + :clr (is (thrown? Exception (merge {} [:foo :bar :baz]))))) |
| 59 | + |
| 60 | + (is (= {:foo "foo", :bar "bar"} (merge {} [:foo "foo"] [:bar "bar"]))) |
| 61 | + (is (= {'x 10, 'y 10, 'z 10} (merge {'x 10} ['y 10] ['z 10]))) |
| 62 | + (testing "In CLJS (unlike other dialects) vectors with >2 arguments are treated as map-entries (where the latter values are ignored)" |
| 63 | + #?(:cljs (is (= {:foo :bar} (merge {} [:foo :bar :baz :bar]))), |
| 64 | + :clj (is (thrown? java.lang.IllegalArgumentException (merge {} [:foo :bar :baz :bar]))), |
| 65 | + :clr (is (thrown? Exception (merge {} [:foo :bar :baz :bar])))))) |
| 66 | + |
| 67 | + (testing "atomic values in position 2+ throw" |
| 68 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 69 | + (merge {} 1))) |
| 70 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 71 | + (merge {} 1 2))) |
| 72 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 73 | + (merge {} :foo))) |
| 74 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 75 | + (merge {} "str")))) |
| 76 | + |
| 77 | + (testing "undefined `merge` behavior on non-maps" |
| 78 | + ;; Behavior for non-map input is undefined. We intentionally do not test |
| 79 | + ;; it closely. |
| 80 | + (is (any? (merge '(1 2 3) 1))) |
| 81 | + (is (any? (merge [1 2] 3 4 5))) |
| 82 | + (is (any? (merge [] nil {} 1 {:a "c"}))) |
| 83 | + (is (any? (merge (first {:a "a"}) {:b "b"} {:c "c"}))) |
| 84 | + (is (= [:foo] (merge [:foo]))) |
| 85 | + (is (= :foo (merge :foo))) |
| 86 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 87 | + (merge :foo :bar))) |
| 88 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 89 | + (merge 100 :foo))) |
| 90 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 91 | + (merge "str" :foo))) |
| 92 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 93 | + (merge nil (range)))) |
| 94 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 95 | + (merge {} '(1 2)))) |
| 96 | + (is (thrown? #?(:cljs :default, :clj Exception, :clr Exception) |
| 97 | + (merge {} 1 2))))))) |
0 commit comments