-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Small fixes for ordered map equiv and equals methods #42
base: master
Are you sure you want to change the base?
Small fixes for ordered map equiv and equals methods #42
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. |
@@ -50,6 +50,7 @@ | |||
IPersistentMap | |||
(equiv [this other] | |||
(and (instance? Map other) | |||
(or (not (map? other)) (instance? MapEquivalence other)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.