Fork me on GitHub
#announcements
<
2021-06-11
>
seancorfield16:06:48

Expectations — an expressive, clojure.test-compatible testing library — has a prerelease of 2.0.0 available: https://cljdoc.org/d/com.github.seancorfield/expectations/2.0.0-alpha2/doc/readme — the main changes from the previous version (1.2.1) are: - improve “drop-in” compatibility with clojure.test (by re-exporting several clojure.test features so you don’t need to require that as well as Expectations) - provide cljs.test-style fixtures (hash map with :before and :after functions) in addition to the regular clojure.test fixtures - provide standalone (self-hosted) ClojureScript compatibility (via planck, thanks to @kkinear) — previously, Expectations was Clojure-only - moves to com.github.seancorfield/expectations (formerly expectations/clojure-test) Follow-up in #expectations for specifics or #testing for general stuff.

🎉 18
👏 5
🚀 4
Cam Saul23:06:41

Out of curiosity, are you still using Expectations yourself? We recently finished migrating ~60k lines of expectations-based tests in Metabase to clojure.test earlier this year, mostly because there's better tooling around it. This was easy to accomplish piecemeal by writing removing the dependency on expectations and writing (expect ...) https://github.com/metabase/metabase/blob/release-x.38.x/test/expectations.cljthat expanded out to a

(deftest some-name-based-on-test-hash
  (expect= expected actual))
and then defining a clojure.test/assert-expr impl for expect= . The main reason I'm asking is it looks like the migration path from expectations 1 -> expectations 2 seems like it would be about the same amount of work as migrating directly over to clojure.test . So if I were to convert another project using Expectations 1 (I still have a few around actually), would it really make sense to convert it to Expectations 2 instead of just converting it to clojure.test?

seancorfield00:06:08

@U42REFCKA This is not the original Expectations. This is the clojure.test-compatible version. All of the clojure.test tooling works with this version of Expectations.

seancorfield00:06:40

lein test, Cursive’s test runner, Polylith’s test runner, Cognitect’s test-runner all work with this. And you can mix’n’match “old school” clojure.test assertions and the more expressive expect expressions.

seancorfield00:06:27

“it looks like the migration path from expectations 1 -> expectations 2 seems like it would be about the same amount of work as migrating directly over to `clojure.test`.” — not sure what gives you that impression? Did you actually check out the docs?

seancorfield00:06:22

(and, yes, we use this version of Expectations very heavily at World Singles Networks with standard clojure.test runnners)

Cam Saul00:06:25

Right, I understand that. It just seems like the main benefit of upgrading from the class Expectations lib -> Expectations 2 is that is uses clojure.test under the hood, but with the syntax changes it seems you'd have to rewrite everything either way. Example: a classic Expectations test might look like

(expect
 1000
 (inc 999))
I could rewrite that as clojure.test as
(deftest my-test
  (is (= 1000
         (inc 999)))
or as
(defexpect my-test
  (expect 1000
          (inc 999)))
the effort involved in migrating such a test seems roughly equivalent. For a few cases where Expectations has different semantics, you could just write your own assert-expr that behaves the same way as Expectations used to, e.g. for comparison against regexes or Exception classes, so for converting several hundred or thousand tests it wouldn't make a huge difference.

seancorfield00:06:02

We switched from (classic) Expectations to the clojure.test-compatible version that I developed ages ago. This is the 2.0 version of that library. Migrating to the clojure.test-compatible version was simply a matter of wrapping each namespace’s set of (expect ..) forms in a single (deftest some-name ..) form.

Cam Saul00:06:12

Gotcha. I'm just trying to understand (as the maintainer of a few libraries that still use classic expectations-style tests) if migrating to this Expectations 2 lib would be easier than migrating to clojure.test . And whether this Expectations 2 lib is intended more as a stepping stone to eventually migrating to clojure.test entirely or not

seancorfield00:06:26

No, you don’t need to migrate to clojure.test. Just wrap (deftest some-name ..) around a big group of (expect ..) forms, and switch from the old Expectations require to this new one. It’s a trivial migration, and can be done one ns at a time.

seancorfield00:06:23

(that’s how we migrated)

Cam Saul00:06:11

ok, gotcha. that makes sense. thanks

seancorfield00:06:38

The README link I posted explains why this version exists and what the differences are from the “classic” Expectations. And shows a mix’n’match example:

(deftest mixed
  (is (= 2 (+ 1 1)))
  (expect even? (+ 1 1)))

seancorfield00:06:13

We’ve been using this version for about two and a half years at work. Happy to help you migrate any of your existing libraries from “classic” Expectations to this version — so you get to keep all your expect forms, and just wrap them in named tests 🙂

seancorfield00:06:41

I created it because “classic” Expectations needed custom tooling and did not work with CIDER or Cursive 🙂

seancorfield00:06:58

And you can (expect ::some-spec (my-fn 1 2 3)) so you get Spec support built-in, which I’m pretty sure did not exist in the “classic” version…

👍 3
Cam Saul00:06:05

Gotcha. One more question. IIRC I took a look at the 1.x version of your lib at one point but the semantics were a little different from the old Expectations lib, so it wasn't directly compatible. For example,

(expect
 (re-pattern "\\d+")
 "1000")
passes in "classic" Expectations, but in the new lib it doesn't (or at least didn't) because it's macro-based and the expected form isn't a regular expression yet at macroexpansion time. I don't know if that's been fixed or not yet, but at a glance it still looks like you'd run into the same thing https://github.com/clojure-expectations/clojure-test/blob/develop/src/expectations/clojure/test.cljc#L381

Cam Saul00:06:22

Is maintaining the same exact semantics as legacy Expectations a project goal? Or is the expectation (pun intended) that a few tests here and there will have to be rewritten?

seancorfield00:06:40

I would consider that a bug, if it worked in “classic” Expectations and not in the clojure.test-compatible version.

👍 3
seancorfield00:06:38

Although (re-find #"\\d+" "123") => nil so I don’t think that expectation would pass either?

Cam Saul00:06:59

(re-pattern "\\d+") -> #"\d+"

Cam Saul00:06:12

the escaped slash gets unescaped

Cam Saul01:06:44

I just double-checked, and

(expect
 (re-pattern "\\d+")
 "123")
definitely passes on old-school legacy classic traditional Expectations. I think there were a few other related test failures I ran in to last time I tried it. For example in Metabase we had a lot of places where we wrote tests that ran against different databases (e.g. Postgres/MySQL/H2/Oracle/SQL Server/etc.) depending on which CI node we were on e.g.
(expect
 (if (testing-some-completely-broken-database?)
   some-form
   some-other-form)
 do-something)
I think basically anywhere where the expected form has any sort of logic doesn't work with the macro-based expect approach. I ended up just writing an assert-expr method that does appropriate comparisons/assertions after the expected form is evaled

jmv16:06:58

Hi all, wanted to share https://github.com/nytimes/vase.elasticsearch This adds Elasticsearch bindings to Vase so that you can build out simple search systems in a data-driven manner. We currently use it to power the NYT cooking search as well as some internal search systems.

🎉 20
😍 7
👀 4
Oliver George21:06:45

Sounds interesting. Would you mind giving us the elevator pitch? For the initiated…

vemv10:06:19

I'm a (positively) surprised Vase is still in use, I thought it had lost traction :)

jmv17:06:56

@U055DUUFS sure! this follows on the same basic premise as https://github.com/cognitect-labs/vase/blob/master/docs/design.md: a concise way to specify simple microservices for some business need. this library extends vase to add support for elasticsearch so that you can add search to a microservice or make a full search oriented microservice. we use this internally so that small teams can spin up search for their product without having to have deep knowledge about running the entirety of a search system. so we take care of the infra and the data sources and let product teams create these concise specifications of search for their business domain

Luis Thiam-Nye17:06:26

Initial public release of snoop — use malli schemas to instrument functions and validate inputs & outputs at runtime. • Compatible with both Clojure and ClojureScript • Convenient schema notation or use m/=> • Works with multi-arity functions • Configuration options for runtime and compile-time • Uses a custom defn wrapper macro that hopes to be easier to combine with other defn wrappers • Alpha I've found instrumentation to be very helpful in tracking down errors in data-heavy situations. https://github.com/CrypticButter/snoop

💯 40
malli 12
👍 9
nice 9
2
ikitommi18:06:40

Added link to malli README. Congrats on the release!

❤️ 6
borkdude09:06:57

Just out of curiosity, is there a reason why such functionality isn't included in malli itself yet? Future plans? @U055NJ5CC

ikitommi11:06:19

there are at least 4 different flavours of schematized defn macros in the wild and Rich is doing/thinking something new for this. Don't wont to make any one standard now. All anyway share m=> machinery, all contribute to same registry, get clj-kondo for free etc. The Plumatic-style will be an optional part of malli, as I like the most 😎

Luis Thiam-Nye13:06:53

I've updated the library to allow specifying schemas next to each parameter declaration, like you can with Plumatic. Personally, I'm not terribly keen on peppering the params vector with :- and commas, so I decided on lists instead:

(>defn fun
  [(x int?) (y int?) (z melon?)]
  [=> string?]
  ...)
https://github.com/CrypticButter/snoop#inline-schema

borkdude13:06:46

@U016JRE24NL One benefit of using the Schema notation would be that the syntax is supported out of the box with clj-kondo :)

Luis Thiam-Nye13:06:08

@U04V15CAJ I provided a clj-kondo config export in the repository 👍.

borkdude13:06:19

ah that works too :)