Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions test/clojure/core_test/mapcat.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
(ns clojure.core-test.mapcat
(:require [clojure.test :as t :refer [deftest testing is are]]
[clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists]]))


(when-var-exists mapcat
(deftest common-cases
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick but why isn't the test name based on the var it's testing?

(testing "nil input"
(is (nil? (seq (mapcat identity nil)))))
(testing "concatenation"
(is (= [1 2 3 4] (mapcat identity [[1 2] '(3 4)]))))
(testing "function producing seqs"
(is (= [0 0 1 0 1 2] (mapcat #(range %) [1 2 3]))))
(testing "empty results contribute nothing"
(is (= [2] (mapcat (fn [x] (if (odd? x) [] [x])) [1 2 3]))))
(testing "strings"
(is (= [\a \b \c] (mapcat identity ["ab" "" "c"]))))
(testing "as transducer"
(is (= [1 1 2 2 3 3] (transduce (mapcat #(repeat 2 %)) conj [] [1 2 3]))))
(testing "into with transducer"
(is (= [0 0 1 1 2 2] (into [] (mapcat #(repeat 2 %)) (range 3)))))
(testing "incorrect shape"
(is (thrown? #?(:cljs :default :clj Exception :cljr Exception)
(mapcat identity 5))))
(testing "infinite input laziness"
(is (= [0 0 1 1 2] (take 5 (mapcat #(repeat 2 %) (range))))))
(testing "empty collection input"
(is (= [] (mapcat identity []))))
(testing "single element producing empty sequence"
(is (= [] (mapcat (constantly []) [42]))))
(testing "single element producing seq"
(is (= [99] (mapcat list [99]))))
(testing "function returns a string (seqable)"
(is (= [\h \i] (mapcat identity ["hi"]))))
(testing "flatten key/value pairs"
(is (= [:a 1 :b 2 :c 3] (mapcat identity {:a 1 :b 2 :c 3}))))
(testing "function returns nil"
(is (= [] (mapcat (constantly nil) [1 2 3]))))
(testing "two collections zipped, function applied to pairs"
(is (= [2 2 4 4 6 6] (mapcat (fn [x y] [(* 2 x) (* 2 y)]) [1 2 3] [1 2 3]))))
(testing "one collection shorter than the other"
(is (= [2 4] (mapcat (fn [x y] [(* x y)]) [1 2] [2 2 2]))))
(testing "works lazily on infinite input"
(is (= [0 1 2 3 4 5] (->> (mapcat (fn [x] [x]) (range)) (take 6)))))
(testing "function sometimes returns []"
(is (= [1 3 5] (mapcat #(if (odd? %) [%] []) (range 1 6)))))
(testing "function sometimes returns nil"
(is (= [2 4] (mapcat #(if (even? %) [%] nil) (range 1 5)))))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapcat has a variadic arity, which we should test by passing many sequences. The most we're doing, in these tests, is two sequences.

(testing "non-seqable second arg"
(is (thrown? #?(:cljs :default :clj Exception :cljr Exception)
(mapcat identity 5))))
(testing "non-function first arg"
(is (thrown? #?(:cljs :default :clj Exception :cljr Exception)
(mapcat 42 [1 2]))))))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add one more negative test for when the result of mapping isn't a concatable data structure, e.g.

(mapcat identity (range 2))
;; => Exception