lazytest

2026-03-19T11:23:27.384829Z

hey @karol.wojcik i saw that you wrote a custom reporter for lazytest. you're the first one from what i can tell, and i'm interested in hearing your experience working with lazytest.

2026-03-19T11:24:38.511639Z

you had to do some naughtiness to make it work (redef'ing try-test-case to capture output), which is an area we could clean up

Karol Wójcik 2026-03-19T11:48:26.274859Z

Craftsmanship is dead. It was not even me who did this part. It was mix of Claude/GPT/GLM and friends.

👀 1
Karol Wójcik 2026-03-19T11:48:35.149859Z

😅

Karol Wójcik 2026-03-19T11:49:51.643099Z

Btw, lazytest is awesome. Boost of productivity is enormous compared to Clojure.test

❤️ 1
2026-03-19T11:54:55.170559Z

i'm so glad you think so!

2026-03-19T13:04:12.841499Z

final question for y'all before i merge this thing: as i have it written, hooks are expected to be functions that take the config object and a map of some kind (a suite or a test-case or the config itself). i'm assoc'ing the ::hook-type onto the target map, and my built-in dispatch function expects that. however, this means that the :cli-opts method (which collects custom entries for tools.cli) needs to pass in a map, not a vector, and the output is expected to be a map as well, which leads to messiness of (cli-opts [config opts] (update opts :new conj [...] [...])). that's ugly, and if i can think of the write way to go about this, can be avoided entirely

2026-03-19T13:07:58.666499Z

ideas: 1. move the dispatch keyword onto config, which will always be a map. this "hides" the dispatch value from the target object and allows for passing in non-map objects (such as a vector of cli options). 2. have a third arg, the dispatch value. the arg-list becomes [dispatch-kw config target] , and users would be expected to write (cli-opts [_ config opts] (conj opts [...] [...])) 3. don't include the config at all. then it's [dispatch-kw target]. 4. have the defhook macro modify the arg list to include the the dispatch-kw itself. then writing a function/mm directly requires writing (defn some-hook [dispatch-kw config target] (case dispatch-kw :cli-opts (...))) while writing a hook is only (defhook some-hook (cli-opts [config target] ...))

2026-03-19T13:11:50.296959Z

i think the second way is the best way, but it feels bad to not "hide" the dispatch value in some way. i hate exposing it like that, it's a useless arg

seancorfield 2026-03-19T13:16:27.767949Z

This is because the hook is essentially a generic thing and the dispatch keyword is one of a fixed set of "lifecycle" points in LazyTest itself?

seancorfield 2026-03-19T13:17:46.593709Z

If that is the case, 4. seems like the "best" option, insofar as it matching the semantics of the domain (lifecycle hook, identified via symbol name that is implemented via a mapping to a keyword under the hood)?

👀 1
2026-03-19T13:18:17.165049Z

yes. the hook is merely a function (can be a multimethod but doesn't have to be) that's held in a vector, and at every run-hook call, it executes all of the loaded hooks with the config and target object

seancorfield 2026-03-19T13:19:30.842649Z

And it's up to the hook's implementation to only fire for the lifecycle event(s) it cares about? So it's inherently a case under the hood, with one (or more) dispatch keyword clauses?

2026-03-19T13:19:44.688209Z

yes

seancorfield 2026-03-19T13:19:59.916159Z

(because the lifecycle is a fixed set of keywords identifying the hookable points)

2026-03-19T13:20:09.645509Z

yes

seancorfield 2026-03-19T13:20:26.066789Z

Okay, then I'm more convinced 4. is the better option.

2026-03-19T13:20:36.686969Z

Allowed hook methods:
  * cli-opts
  * config
  * pre-test-run
  * post-test-run
  * pre-test-suite
  * post-test-suite
  * pre-test-case
  * post-test-case

2026-03-19T13:23:40.443179Z

for prior art, kaocha handles this by not using multimethods lol. it creates standalone functions, a var map of {hook-kw func}, and then calls (defmethod -register plugin-id [plugins (conj plugins var-sym)) (in a macro)

2026-03-19T13:24:21.267029Z

that means each function can have a custom argument list

2026-03-19T13:26:17.887109Z

that's not a bad way to do it, but i don't mind requiring some regularity (and would include the config in all calls anyway)

2026-03-19T13:26:51.176519Z

i think you're right that 4 is the best option. folks writing the functions/mm manually can just include the dispatch-kw arg, and folks using defhook won't notice

👍🏻 1
2026-03-19T13:04:34.433839Z

(instead of filling the whole channel as i did yesterday, i'll try to keep this discussion in the thread above)

2026-03-19T02:04:54.698079Z

shout out to the kaocha docs authors, this is way better than the stuff i'm writing