expect causes ClassCastException with sorted-map
xfthhxk opened this issue · 4 comments
First of all thank-you for this library! I've been happily using it for years :)
Using a sorted-map with non-keyword keys causes a ClassCastException. The issue originates in ->test-report when x is a map and the code is trying to lookup the keys ::e/more, ::e/in-flag, ::e/from-each-flag. In my case the map is a sorted map with integer keys, and comparison between Keyword and Long causes Clojure to throw an error.
Happy to help look into this and put together a PR if it makes sense. Wanted to get your input/guidance first though.
;; throws ClassCastException
(expect (sorted-map 1 2) (sorted-map 1 2))
(expect {1 2} (sorted-map 1 2))
(expect {"a" 1} (sorted-map "a" 1))
;; no errors. works as expected with keyword keys
(expect {:a 1} (sorted-map :a 1))
;; no issues with sorted sets
(expect (sorted-set 1) (sorted-set 1 2))
(expect #{1} (sorted-set 1))1. Unhandled java.lang.ClassCastException
class java.lang.Long cannot be cast to class clojure.lang.Keyword
(java.lang.Long is in module java.base of loader 'bootstrap';
clojure.lang.Keyword is in unnamed module of loader 'app')
Keyword.java: 122 clojure.lang.Keyword/compareTo
Util.java: 153 clojure.lang.Util/compare
RT.java: 283 clojure.lang.RT$DefaultComparator/compare
PersistentTreeMap.java: 330 clojure.lang.PersistentTreeMap/doCompare
PersistentTreeMap.java: 317 clojure.lang.PersistentTreeMap/entryAt
PersistentTreeMap.java: 297 clojure.lang.PersistentTreeMap/valAt
PersistentTreeMap.java: 302 clojure.lang.PersistentTreeMap/valAt
KeywordLookupSite.java: 45 clojure.lang.KeywordLookupSite$1/get
test.clj: 46 expectations.clojure.test/->test-report
test.clj: 36 expectations.clojure.test/->test-report
REPL: 24 user/eval70863Thanks for the bug report and repro case. That's an interesting one... Sorted maps are strange because normally (get data :x) returns nil if data is not something you can get a key from, but in the case of a sorted map, if the key type doesn't match, you get an exception instead.
I expect to be doing some OSS work over the next few days (since I'll be on vacation) so I'll get a fix out for this.
I just tried to reproduce this with your examples and they work. What version of Expectations are you using?
Can you create a small GitHub repo with the bare minimum repro case in it, with instructions on how to run it?
Here's what I tried:
(! 603)-> clojure -M:test:rebel
Downloading: com/bhauman/rebel-readline/maven-metadata.xml from clojars
[Rebel readline] Type :repl/help for online help info
user=> (require '[expectations.clojure.test :refer :all])
nil
user=> (expect (sorted-map 1 2) {1 2})
true
user=> (expect {1 2} (sorted-map 1 2))
true
user=> (expect {"a" 1} (sorted-map "a" 1))
true
user=> (defexpect repro
#_=> (expect {1 2} (sorted-map 1 2)))
#'user/repro
user=> (run-tests *ns*)
Testing user
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
{:test 1, :pass 1, :fail 0, :error 0, :type :summary}
user=> "trying to lookup the keys ::e/more, ::e/in-flag, ::e/from-each-flag." -- those flags do not exist in this library, only in Classic Expectations. But your stacktrace references this library so it seems you are mixing the two libraries?
Just realized the same thing. Updated to the new version and things are working as expected. Sorry about the noise.