This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-03-14
Channels
- # aleph (4)
- # announcements (10)
- # babashka (21)
- # beginners (67)
- # biff (7)
- # calva (4)
- # clojure (40)
- # clojure-europe (11)
- # clojure-gamedev (17)
- # clojure-losangeles (3)
- # clojure-madison (1)
- # clojure-nl (1)
- # clojure-norway (78)
- # clojure-uk (3)
- # clojurescript (83)
- # core-typed (18)
- # cursive (1)
- # datalevin (2)
- # datomic (2)
- # gratitude (2)
- # hyperfiddle (56)
- # introduce-yourself (1)
- # london-clojurians (1)
- # matcher-combinators (10)
- # membrane (161)
- # polylith (16)
- # portal (4)
- # reitit (4)
- # releases (3)
- # ring (2)
- # shadow-cljs (9)
- # squint (2)
- # timbre (10)
- # xtdb (14)
- # yamlscript (1)
can i get some feedback, pls, on our temporal matcher, which relies on tick.core/=
?
(def TemporalMatcher
{:-matcher-for (fn ([this] this) ([this _] this))
:-match
(fn [expected actual]
(cond
(= :matcher-combinators.core/missing actual)
{:matcher-combinators.result/type :mismatch
:matcher-combinators.result/value (matcher-combinators.model/->Missing expected)
:matcher-combinators.result/weight 1}
(tick.core/= expected actual)
{:matcher-combinators.result/type :match
:matcher-combinators.result/value actual
:matcher-combinators.result/weight 0}
:else
{:matcher-combinators.result/type :mismatch
:matcher-combinators.result/value (matcher-combinators.model/->Mismatch expected actual)
:matcher-combinators.result/weight 1}))
:-base-name (fn [expected] (symbol (str (class expected) "-matcher")))})
(extend java.util.Date matcher-combinators.core/Matcher TemporalMatcher)
(extend java.time.Instant matcher-combinators.core/Matcher TemporalMatcher)
(extend java.time.ZonedDateTime matcher-combinators.core/Matcher TemporalMatcher)
(extend java.time.OffsetDateTime matcher-combinators.core/Matcher TemporalMatcher)
it allows loose matching, like
(clojure.test/is (match? (tick.core/zoned-date-time "2000-01-01T00:00:00Z") #inst "2000"))
this way we could simplify expected value construction and compare it with actual java.util.Date
s returned by Datomic.the precision difference between Date
and Instant
is still an issue in one direction though:
(let [i (t/instant)]
[(clojure.test/is (match? (t/inst i) i))
(clojure.test/is (match? i (t/inst i)))])
FAIL in () (test_harness.clj:3)
expected: (match? i (t/inst i))
actual: (mismatch
(expected #time/instant "2024-03-14T14:43:23.617862Z")
(actual #inst "2024-03-14T14:43:23.617-00:00"))
=> [true false]
is there some incubator/nursery for unofficial/community matchers? would it make sense to enable the wiki for https://github.com/nubank/matcher-combinators and put them there? (i was kinda expecting them to be there)
@gilvan.reis what are some real-world use-cases for m/nested-equals
?
i have the feeling that ppl who come from the nodejs world and got used to deep-equals
are missing an equivalent, because the regular equals
assertion has a very narrow usefulness.
transplanting this approach from such ecosystems goes against clojure's ethos of accepting open-ended maps.
i would worry to see extensive usage of m/nested-equals
in our code-base.
my initial impression is that it would lead to brittle tests, which mention a lot of details, which are irrelevant from the perspective of a test case, just to please this matcher.
in our test suite
"Elapsed time: 5361.217917 msecs"
=> #:kaocha.result{:count 361, :pass 1099, :error 0, :fail 0, :pending 7}
we use m/equals
34 times only, while match?
is used 588 time, according to my calculation:
rg m/equals . -c | awk -F: '{s+=$2}END{print s}'
rg '\(match\?' . -c | awk -F: '{s+=$2}END{print s}'
none of the expectations using m/equal
are using it in a nested manner.i know there are some upsides to closed-maps, eg. possibility to implement auto-completion or spell checking, but is there any other common problem domain which benefits for such inflexibility/rigidity or even straight out requires it?
Sorry for the delay, I was on vacation.
The m/nested-equals
is just a syntax sugar for (match-with [map? equals] expected)
that is used when you want that every value of a map (including nested maps) are equals to the expected.
> ppl who come from the nodejs world and got used to deep-equals
are missing an equivalent
I didn’t came from the nodejs world, but in my company we test many maps and many engineers uses m/equals
on maps expecting that every key and value were going to be strictly equals to the expected value.
The correct way to do this was already document on the library readme for some time, but this information were still being missed by many people.
So adding this syntax sugar is another approach to give visibility of this expected behavior of m/equals
and to reduce some code duplication when using the library in this scenario
i understood all that from previous messages already. my question is why are they trying to fully match every key? there are often keys, which are not important from the perspective of a test, eg. concrete database IDs or the exact creation or update dates and stuff like that.
> my question is why are they trying to fully match every key? We have a kind of function that we always want to return the exact map