Skip to content

Conversation

@jafingerhut
Copy link
Contributor

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.

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.
@jafingerhut
Copy link
Contributor Author

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))
Copy link
Member

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))))
Copy link
Member

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})))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants