From 341a284effb43ebc67504ce3734ebc47834f75fd Mon Sep 17 00:00:00 2001 From: Dave Roberts Date: Tue, 21 Apr 2026 10:47:17 -0500 Subject: [PATCH 1/7] Add tests for `apply` --- test/clojure/core_test/apply.cljc | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 test/clojure/core_test/apply.cljc diff --git a/test/clojure/core_test/apply.cljc b/test/clojure/core_test/apply.cljc new file mode 100644 index 00000000..88e66cb8 --- /dev/null +++ b/test/clojure/core_test/apply.cljc @@ -0,0 +1,41 @@ +(ns clojure.core-test.apply + (:require [clojure.test :as t :refer [are deftest is testing]] + [clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists] :as p])) + +(when-var-exists apply + (deftest test-apply + (is (= 0 (apply + nil))) ; Apply + with no args + (is (= 0 (apply + '()))) + (is (= 0 (apply + []))) + (is (= 0 (apply + {}))) + (is (= 0 (apply + #{}))) ; map is a sequence of map entries + (is (= 0 (apply + ""))) ; string is a sequence of characters + + (is (= 1 (apply + 1 nil))) ; Apply + with 1 arg and empty seqeuence + (is (= 1 (apply + 1 '()))) + (is (= 1 (apply + 1 []))) + (is (= 1 (apply + 1 {}))) + (is (= 1 (apply + 1 #{}))) + (is (= 1 (apply + 1 ""))) + + (is (= 1 (apply + '(1)))) ; Zero non-sequence arg + (is (= 3 (apply + 1 '(2)))) ; One non-sequential arg + (is (= 6 (apply + 1 2 '(3)))) ; Two non-sequential args + (is (= 10 (apply + 1 2 3 '(4)))) ; Three non-sequential args + (is (= 15 (apply + 1 2 3 4 '(5)))) ; Four non-sequential args + (is (= 45 (apply + (range 10)))) ; All args as sequential + (is (= 10 (apply + 1 [2 3 4]))) + (is (= 10 (apply + 1 #{2 3 4}))) ; A set works but order not guaranteed + (is (= [[:a 1] [:b 2]] + (apply conj [] {:a 1, :b 2}))) + (is (= [\a \b \c] ; String is sequence of chars + (apply conj [] "abc"))) + + ;; Try various IFn things + (is (= 1 (apply {:a 1} [:a]))) ; apply map to key + (is (= 1 (apply :a [{:a 1}]))) ; apply keyword to map + (is (= 2 (apply [0 1 2 3 4] [2]))) ; apply vector to index + (is (p/thrown? (apply 2 [[0 1 2 3 4]]))) ; but numbers don't implement IFn + (is (= :a (apply #{:a :b :c} [:a]))) ; apply set to element + (is (= :a (apply :a [#{:a :b :c}]))) ; apply keyword to set + )) From ae6c72e8e8df24c8cb7ef1a2b619daf3b68bdda4 Mon Sep 17 00:00:00 2001 From: Dave Roberts Date: Tue, 21 Apr 2026 11:01:13 -0500 Subject: [PATCH 2/7] Fix: don't depend on order of map entries --- test/clojure/core_test/apply.cljc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/clojure/core_test/apply.cljc b/test/clojure/core_test/apply.cljc index 88e66cb8..69aa2563 100644 --- a/test/clojure/core_test/apply.cljc +++ b/test/clojure/core_test/apply.cljc @@ -26,8 +26,8 @@ (is (= 45 (apply + (range 10)))) ; All args as sequential (is (= 10 (apply + 1 [2 3 4]))) (is (= 10 (apply + 1 #{2 3 4}))) ; A set works but order not guaranteed - (is (= [[:a 1] [:b 2]] - (apply conj [] {:a 1, :b 2}))) + (is (= #{[:a 1] [:b 2]} ; Can't guarantee order of map entries + (apply conj #{} {:a 1, :b 2}))) (is (= [\a \b \c] ; String is sequence of chars (apply conj [] "abc"))) From 2a5378380a10b384e358dedc8eb868bdcdf9e3fb Mon Sep 17 00:00:00 2001 From: Dave Roberts Date: Tue, 21 Apr 2026 12:56:16 -0500 Subject: [PATCH 3/7] Fix comment and remove trailing white space --- test/clojure/core_test/apply.cljc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/clojure/core_test/apply.cljc b/test/clojure/core_test/apply.cljc index 69aa2563..bf1f436b 100644 --- a/test/clojure/core_test/apply.cljc +++ b/test/clojure/core_test/apply.cljc @@ -7,17 +7,17 @@ (is (= 0 (apply + nil))) ; Apply + with no args (is (= 0 (apply + '()))) (is (= 0 (apply + []))) - (is (= 0 (apply + {}))) - (is (= 0 (apply + #{}))) ; map is a sequence of map entries + (is (= 0 (apply + {}))) ; map is a sequence of map entries + (is (= 0 (apply + #{}))) (is (= 0 (apply + ""))) ; string is a sequence of characters - + (is (= 1 (apply + 1 nil))) ; Apply + with 1 arg and empty seqeuence (is (= 1 (apply + 1 '()))) (is (= 1 (apply + 1 []))) (is (= 1 (apply + 1 {}))) (is (= 1 (apply + 1 #{}))) (is (= 1 (apply + 1 ""))) - + (is (= 1 (apply + '(1)))) ; Zero non-sequence arg (is (= 3 (apply + 1 '(2)))) ; One non-sequential arg (is (= 6 (apply + 1 2 '(3)))) ; Two non-sequential args From fcf87d1e11d7c3179784b7d58d7d18a2304cdf39 Mon Sep 17 00:00:00 2001 From: Dave Roberts Date: Tue, 21 Apr 2026 12:56:33 -0500 Subject: [PATCH 4/7] New test: apply `apply` recursively --- test/clojure/core_test/apply.cljc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/clojure/core_test/apply.cljc b/test/clojure/core_test/apply.cljc index bf1f436b..340abd08 100644 --- a/test/clojure/core_test/apply.cljc +++ b/test/clojure/core_test/apply.cljc @@ -38,4 +38,6 @@ (is (p/thrown? (apply 2 [[0 1 2 3 4]]))) ; but numbers don't implement IFn (is (= :a (apply #{:a :b :c} [:a]))) ; apply set to element (is (= :a (apply :a [#{:a :b :c}]))) ; apply keyword to set - )) + + ;; apply recrusively + (is (= 10 (apply apply + [1 2 [3 4]]))))) From 44d7857b6dde6cd24ac7f28985c607fdb6221c3c Mon Sep 17 00:00:00 2001 From: Dave Roberts Date: Tue, 21 Apr 2026 12:58:02 -0500 Subject: [PATCH 5/7] Spell "sequence" correctly --- test/clojure/core_test/apply.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/clojure/core_test/apply.cljc b/test/clojure/core_test/apply.cljc index 340abd08..3c655cda 100644 --- a/test/clojure/core_test/apply.cljc +++ b/test/clojure/core_test/apply.cljc @@ -11,7 +11,7 @@ (is (= 0 (apply + #{}))) (is (= 0 (apply + ""))) ; string is a sequence of characters - (is (= 1 (apply + 1 nil))) ; Apply + with 1 arg and empty seqeuence + (is (= 1 (apply + 1 nil))) ; Apply + with 1 arg and empty sequence (is (= 1 (apply + 1 '()))) (is (= 1 (apply + 1 []))) (is (= 1 (apply + 1 {}))) From d50b36806b72ca1ea57106f2f480a1283f71bd5d Mon Sep 17 00:00:00 2001 From: Dave Roberts Date: Tue, 21 Apr 2026 13:17:47 -0500 Subject: [PATCH 6/7] Test whether an infinite sequence arg is realized --- test/clojure/core_test/apply.cljc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/clojure/core_test/apply.cljc b/test/clojure/core_test/apply.cljc index 3c655cda..f32be99e 100644 --- a/test/clojure/core_test/apply.cljc +++ b/test/clojure/core_test/apply.cljc @@ -40,4 +40,7 @@ (is (= :a (apply :a [#{:a :b :c}]))) ; apply keyword to set ;; apply recrusively - (is (= 10 (apply apply + [1 2 [3 4]]))))) + (is (= 10 (apply apply + [1 2 [3 4]]))) + + ;; validate that `apply` doesn't try to further evaluate its arguments. If the range + (is (= 3 (count (apply conj [] [1 2 (range)])))))) From 76334dedb711fccd96822870954f3efc9af4edfa Mon Sep 17 00:00:00 2001 From: Dave Roberts Date: Tue, 21 Apr 2026 13:21:03 -0500 Subject: [PATCH 7/7] Finish comment --- test/clojure/core_test/apply.cljc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/clojure/core_test/apply.cljc b/test/clojure/core_test/apply.cljc index f32be99e..88906110 100644 --- a/test/clojure/core_test/apply.cljc +++ b/test/clojure/core_test/apply.cljc @@ -42,5 +42,7 @@ ;; apply recrusively (is (= 10 (apply apply + [1 2 [3 4]]))) - ;; validate that `apply` doesn't try to further evaluate its arguments. If the range + ;; validate that `apply` doesn't try to further evaluate its + ;; arguments. If the infinite range is realized, we would expect + ;; an OOM Exception at some point. (is (= 3 (count (apply conj [] [1 2 (range)]))))))