diff --git a/CHANGELOG.md b/CHANGELOG.md index e61cf2ac..923a6f9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * [#913](https://github.com/clojure-emacs/cider-nrepl/pull/913): Disable background warmup of `orchard.java` cache. * [#913](https://github.com/clojure-emacs/cider-nrepl/pull/913): Enable background warmup of Compliment cache. * [#914](https://github.com/clojure-emacs/cider-nrepl/pull/914): Remove javadoc section from the inspector output. +* [#917](https://github.com/clojure-emacs/cider-nrepl/pull/917): Sort printed maps in test output ## 0.52.1 (2025-02-24) diff --git a/src/cider/nrepl/middleware/test.clj b/src/cider/nrepl/middleware/test.clj index 63861f23..89579922 100644 --- a/src/cider/nrepl/middleware/test.clj +++ b/src/cider/nrepl/middleware/test.clj @@ -80,6 +80,24 @@ (str/starts-with? frame-cname class-name)))) first)))) +(defn deep-sorted-maps + "Recursively converts all nested maps to sorted maps." + [m] + (try + (walk/postwalk + (fn [x] + (if (map? x) + (with-meta (into (sorted-map) x) (meta x)) + x)) + m) + (catch Exception _ + ;; Maps with non-comparable keys aren't sortable so they should be returned as-is. + ;; Examples: + ;; {{} 1} + ;; {1 1 :a 1} + ;; {"a" 1 :a 1} + m))) + (defn- print-object "Print `object` using println for matcher-combinators results and pprint otherwise. The matcher-combinators library uses a custom print-method @@ -91,7 +109,8 @@ print-fn (if matcher-combinators-result? println pp/pprint) - result (with-out-str (print-fn object))] + ;; The output will contain sorted maps for better readability and diff comparisons. + result (with-out-str (print-fn (deep-sorted-maps object)))] ;; Replace extra newlines at the end, as sometimes returned by matchers-combinators: (str/replace result #"\n\n+$" "\n"))) diff --git a/test/clj/cider/nrepl/middleware/test_test.clj b/test/clj/cider/nrepl/middleware/test_test.clj index ecf4297b..76551121 100644 --- a/test/clj/cider/nrepl/middleware/test_test.clj +++ b/test/clj/cider/nrepl/middleware/test_test.clj @@ -280,7 +280,10 @@ The `988` value reflects that it times things correctly for a slow test.") "pprint is chosen, as indicated by quoted strings and newlines") (is (= "{:a \"b\", :c \"42\"}\n" (#'test/print-object (with-meta {:a "b" :c "42"} {:type ::mismatch}))) - "pprint is chosen, because :type does not match matchers-combinators keyword"))) + "pprint is chosen, because :type does not match matchers-combinators keyword")) + (testing "maps are printed with sorted keys" + (is (= "{:a 1, :b 2, :c 3, :d {x 1, y 2, z 3}}\n" + (#'test/print-object {:b 2 :c 3 :a 1 :d {'z 3 'y 2 'x 1}}))))) (deftest test-result-test (testing "It passes `:error`s to `test/*test-error-handler*`"