Something between =, == and identical?

Hi folks,

I’m after something like =, == and identical? but neither of those work like I want to.

I would like to write tests that report difference between [1 2 3] and '(1 2 3). Is that possible without using vector??

This doesn’t what I need:

(identical? '(1) '(1))

And same for:

(== '(1) '(1))

So I’m using = but sometime it is annoying. For example when output is '([1 2] [3 4]). If something happens and output turns into '((1 2) (3 4)) I would like to know that without testing (first (vector? ....

Thank you.

Can you give an example of what test you want to use?

Maybe something like:

(defn same? [& body]
  (and (apply = body)
       (->> body (map type) (apply =))))

#_=> (same? '(1) [1])
1 Like

Hello @foobar.

Do you want following to be equal or not?

    (list (list 1 2) (list 3 4))
    (list (map identity [1 2]) (map identity [3 4]))

both printed as ((1 2) (3 4)) but elements has different type.

Welcome :slight_smile:

Very similar, very recent thread might be of interest: Equality is a Problem

Regarding why identical? and == aren’t what you want, and this topic in general, Clojure - Equality is good reading if you haven’t yet seen it.

Thank you John.

I want to use it in clojure.test only since I understand that I should rather have code that can work with any collection rather than relying on vector / list.

Good point, thank you Serioga. For testing I’d like to have fn that distinguish between vector, set and everything else (list or what it returned from seq / map). I had a thought about something like (= (str ...) (str ...)) but that would be just sooo wrong ;-).

Thank you Dave. I googled that one and read it. I don’t remember the blog post from the second link but I spent enough time in Clojure (I’m NOT expert but I think I know core principles) to understand that I should not rely on data types. I should rely just on shape of my data. But I was hoping that specifically for clojure.test testing there will be something more than those three functions I know.

1 Like

Martin, I suggest to be specific in your tests. You can validate data shape and contents separately like

;; Spec can be used as well to test data shape

(defn valid-elem? [x]
  (and (vector? x)
       (= 2 (count x))))

(defn valid-seq? [xs]
  (and (seq xs)
       (every? valid-elem? xs)))

(let [xs '([1 2] [3 4])]
  (and (valid-seq? xs)
       (= '([1 2] [3 4]) xs)))
#_=> true

(let [xs '('(1 2) '(3 4))]
  (and (valid-seq? xs)
       (= '([1 2] [3 4]) xs)))
#_=> false