initial tests for clojure.core/merge-with#896
Conversation
They are yeah, @jeaye disabled them for the time being, that being said noting how they fail is always nice for their respective maintainers to be aware of (and potentially fixed) |
E-A-Griffin
left a comment
There was a problem hiding this comment.
Could you use the following reader conditional order: https://github.com/E-A-Griffin/clojure-test-suite/blob/e00fe2b8ff87fcf02020664cc57f11bbf4448904/doc/writing-tests.md#reader-conditional-order? This PR isn't merged yet but @jeaye and I agreed on it prior so going to try to maintain it going forward
| (testing "zero arg behavior" | ||
| ;; NOTE: clojurescript differs from the rest here, bug? | ||
| #?(:clj (is (p/thrown? (merge-with))) | ||
| :cljs (is (nil? (merge-with))) ; TODO how to suppress warning |
There was a problem hiding this comment.
What is this TODO for?
There was a problem hiding this comment.
When I run bb test-cljs, everything passes but the output contains this verbose warning:
...
Ran 223 tests containing 4957 assertions.
0 failures, 0 errors.
===============================================
[:test] Build completed. (324 files, 323 compiled, 1 warnings, 4.22s)
------ WARNING #1 - :fn-arity --------------------------------------------------
File: /Users/matthew/projects/clojure-test-suite/test/clojure/core_test/merge_with.cljc:15:30
--------------------------------------------------------------------------------
12 | (testing "zero arg behavior"
13 | ;; NOTE: clojurescript differs from the rest here, bug?
14 | #?(:clj (is (p/thrown? (merge-with)))
15 | :cljs (is (nil? (merge-with))) ; TODO how to suppress warning
------------------------------------^-------------------------------------------
Wrong number of args (0) passed to cljs.core/merge-with
--------------------------------------------------------------------------------
16 | :default (is (p/thrown? (merge-with)))))
17 |
18 | (testing "`nil`ish behavior"
19 | (is (nil? (merge-with second-arg nil)))
--------------------------------------------------------------------------------
Since we're explicitly testing the zero-args case, is there a way to silence this?
|
I think |
|
Thanks for the review @E-A-Griffin ! The reader conditional ordering actually matters, TIL. I added tests for The cljs zero-arg case is the only real question mark. I've noted the difference in the top PR description. The warning still bothers me though, hoping to find a way to suppress that. |
There was a problem hiding this comment.
Pull request overview
Adds a new clojure.core compliance/characterization test namespace covering merge-with, with some dialect-conditional expectations (notably ClojureScript’s zero-arg behavior).
Changes:
- Introduces a new
merge-withtest file with coverage for nil handling, collision semantics, fold direction, duplicate-key invocation, sorted-map preservation, and nested-map merging. - Adds negative tests around non-map inputs and exception behavior (with dialect conditionals).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| (:require [clojure.test :as t :refer [deftest is testing]] | ||
| [clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists] :as p])) | ||
|
|
||
| (defn second-arg [_a b] b) |
There was a problem hiding this comment.
We can delete this fn and just use second.
There was a problem hiding this comment.
second takes one arg and returns the 2nd element. I guess we could write #(second [%1 %2]) but not sure if that's an improvement.
There was a problem hiding this comment.
@perrygeo , right, this is not the same. second-arg is being used as the merge function and it is overwriting the first arg with the second during the merge.
| (:require [clojure.test :as t :refer [deftest is testing]] | ||
| [clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists] :as p])) | ||
|
|
||
| (defn second-arg [_a b] b) |
There was a problem hiding this comment.
@perrygeo , right, this is not the same. second-arg is being used as the merge function and it is overwriting the first arg with the second during the merge.
| (testing "zero arg behavior" | ||
| #?(:cljs (is (nil? (merge-with))) | ||
| :clj (is (p/thrown? (merge-with))))) | ||
|
|
There was a problem hiding this comment.
There's a missing case here, I think: (merge-with second-arg)
That is, no maps, just the required merge function present.
| (deftest test-merge-with | ||
| (testing "`merge-with`" | ||
|
|
||
| (testing "zero arg behavior" |
There was a problem hiding this comment.
Let's be clear that there is no zero-arg case for the function legitimately. The doc string shows f as a required arg, so the CLJ case is throwing because it's short args.
| {:a 1} {:a 2} {:b 3})))) | ||
|
|
||
| (testing "sorted" | ||
| (let [result (merge-with + |
There was a problem hiding this comment.
I would also try this where the first arg is a sorted map and the second is a regular hash map, to validate that the sorting behavior accrues with the first argument. I'd also test it with three maps, where the first is sorted to validate how the sorting behavior is propagated through the folding-in of the later maps.
| (testing "falsey values still trigger f on collision" | ||
| (is (= {:a false} (merge-with second-arg {:a true} {:a false}))) | ||
| (is (= {:a nil} (merge-with second-arg {:a true} {:a nil})))) |
There was a problem hiding this comment.
I'm not sure what this is supposed to be testing. The keys are both :a and the value doesn't participate in the decision to merge or not.
| (testing "metadata progation, when keys are equal but not identical" | ||
| (is (= {:meta1 true} | ||
| (meta (ffirst (merge-with + {^:meta1 {} 1} {^:meta2 {} 2})))))) |
There was a problem hiding this comment.
This is good. I would add a test with metadata on the values as well and make sure that it's preserved through the merge and through the merge function.
Testing
clojure.core/merge-withManually tested with
Dialect Differences
nilin the zero-arg case. Clojure etc throw an exception.nilon(merge-with second-arg nil {}), rest return{}Anything else I can do to improve this? Let me know. This is a really fun way to get to know the clojure standard library!
Resolves #361