Small fixes for ordered map equiv and equals methods#42
Small fixes for ordered map equiv and equals methods#42jafingerhut wants to merge 1 commit intoclj-commons:masterfrom
Conversation
There are test cases added that fail without these changes. (= ordered-map some-record-with-same-keys) returns true without these changes, for example, whereas Clojure's built-in maps are never = to any record, by design, since records are distinct types. (.equals ordered-map something-else) currently uses = to compare corresponding values in the maps, but other Clojure persistent maps use .equals to compare corresponding values.
|
This is identical to #34 except that it should have no merge conflicts, because I removed the part of the changes on file project.clj. Similar updates to project.clj have been made independently of that earlier PR. |
| IPersistentMap | ||
| (equiv [this other] | ||
| (and (instance? Map other) | ||
| (or (not (map? other)) (instance? MapEquivalence other)) |
There was a problem hiding this comment.
Can you explain this line a bit more? What is the purpose of checking for (not (map? other))?
Should this be (or (map? other) (instance? MapEquivalence other)), i.e. checking if other is an IPersistentMap or if it is MapEquivalent? Either way, it could be good to add a comment here explaining the purpose of this line?
| ;; collections intentionally have different result for | ||
| ;; clojure.core/hash than otherwise = non-persistent collections. | ||
| (if (and b-persistent? (not (record? b))) | ||
| (is (= (hash omap) (hash b)) msg)))) |
There was a problem hiding this comment.
I tried transforming this into a macro, but I think I actually preferred the error messages in Cursive showing up on the is assertions that failed, rather than on is-same-collection. What do you think?
(defmacro is-same-collection [omap b]
`(let [msg# (format "(class omap)=%s (class b)=%s omap=%s b=%s"
(.getName (class ~omap)) (.getName (class ~b)) ~omap ~b)
b-persistent?# (map? ~b)
should-be-=?# (not (record? ~b))]
(is (= (count ~omap) (count ~b) (.size ~omap) (.size ~b)) msg#)
(is (= (= ~omap ~b) should-be-=?#) msg#)
(is (= (= ~b ~omap) should-be-=?#) msg#)
(is (.equals ^Object ~omap ~b) msg#)
(is (.equals ^Object ~b ~omap) msg#)
(is (= (.hashCode ^Object ~omap) (.hashCode ^Object ~b)) msg#)
;; At least while CLJ-1372 is unresolved, Clojure persistent
;; collections intentionally have different result for
;; clojure.core/hash than otherwise = non-persistent collections.
(if (and b-persistent?# (not (record? ~b)))
(is (= (hash ~omap) (hash ~b)) msg#))))
(deftest map-collection-tests
(is-same-collection (ordered-map) {})
(is-same-collection (ordered-map) (hash-map))
(is-same-collection (ordered-map) (array-map))
(is-same-collection (ordered-map) (sorted-map))
(is-same-collection (ordered-map) (sorted-map-by <))
(is-same-collection (ordered-map) (ordered-map))
(is-same-collection (ordered-map) (->EmptyRec1))
(is-same-collection (ordered-map) (java.util.HashMap.))
(is (= false (.equals {1 17N} (java.util.HashMap. {1 17}))))
(is (= false (.equals (ordered-map 1 17N) (java.util.HashMap. {1 17})))))
There are test cases added that fail without these changes. (=
ordered-map some-record-with-same-keys) returns true without these
changes, for example, whereas Clojure's built-in maps are never = to
any record, by design, since records are distinct types.
(.equals ordered-map something-else) currently uses = to compare
corresponding values in the maps, but other Clojure persistent maps
use .equals to compare corresponding values.