i develop an alternative test framework called #lazytest that supports running tests from the repl. i don't use emacs or CIDER so I'm unfamiliar with how it works, but someone has asked for help on getting the CIDER keybinds/workflow to integrate with lazytest. i use neovim and have instructions for neovim (conjure) and calva and intellij, but i'd love for some help with CIDER. can one of you help me/us?
https://github.com/NoahTheDuke/lazytest?tab=readme-ov-file#editor-integration has the existing "Editor Integration" instructions
in short, you can call (lazytest.repl/run-all-tests) to run all loaded tests, (lazytest.repl/run-tests to run the tests in a given namespace, or (lazytest.repl/run-test-var #') to run a given var's test (either a defdescribe test var or a function with :test metadata, which lazytest supports). All three functions also support an optional trailing config map, so you can say (lazytest.repl/run-test-var #'example-var {:reporter [lazytest.reporters/nested]}) and it "just works"
i know CIDER has a whole test integration toolbox for looking at stack traces and jumping to errors etc. I don't expect to copy all of that, just a way to say "add X to your emacs config and you can run tests under your cursor with a keybind" or similar
https://docs.cider.mx/cider/testing/supported_libraries.html
so basically cider testing functionality allows you to run single test, all tests inside a ns and all tests in a project. Under the hood I think it uses clojure.test which runs all vars with a :test meta
that said you can easily create some elisp function to run whatever function you want runtime side like this :
(defun run-all-lazy-tests ()
(interactive)
(let* ((current-ns (cider-current-ns)))
(cider-interactive-eval "(lazytest.repl/run-all-tests)"
nil
nil
`(("ns" ,current-ns)))))those are interactive functions, so you can run them by command name or assign a keybinding
cool, thanks
yeah, this is wholly separate from clojure.test, no overlap at all, so i can't rely on the clojure.test functionality
then maybe you can create a couple elisp functions like that for calling lazytest.repl functions
let me try to create those functions for your description
thank you, that's kind of you
these seams to work :
(defun lazy-tests-run-var ()
(interactive)
(let* ((current-ns (cider-current-ns))
(var (cider-last-sexp)))
(cider-interactive-eval (format "(lazytest.repl/run-test-var #'%s)" var)
nil
nil
`(("ns" ,current-ns)))))
(defun lazy-tests-run-ns ()
(interactive)
(let* ((current-ns (cider-current-ns)))
(cider-interactive-eval (format "(lazytest.repl/run-tests '%s)" current-ns)
nil
nil
`(("ns" ,current-ns)))))
(defun lazy-tests-run-all ()
(interactive)
(let* ((current-ns (cider-current-ns)))
(cider-interactive-eval "(lazytest.repl/run-all-tests)"
nil
nil
`(("ns" ,current-ns)))))I tried them with :
(ns lazytest.repl)
(defn run-test-var [v] (println "Running" v))
(defn run-tests [ns] (println "Running ns" ns))
(defn run-all-tests [] (println "Running all tests"))and seams to be printing the correct messages when I fire those commands
hell yeah, thank you so much
you are welcome!
if you use this instead for the var one :
(defun lazy-tests-run-var ()
(interactive)
(let* ((current-ns (cider-current-ns))
(var (cider--extract-test-var-at-point))
(var-ns (first var))
(var-name (second var)))
(cider-interactive-eval (format "(lazytest.repl/run-test-var #'%s/%s)" var-ns var-name)
nil
nil
`(("ns" ,current-ns)))))
then you don't need to run the lazy-tests-run-var command with the cursor on the var name, you can do it on the body of the form. But I'm not sure it will work with your tests forms, to find the test var name cider does some fancy lookup for "the var" by looking at its highlighting 😅, and checks it contains :test metayeah, cider--extract-test-var-at-point doesn't quite work, i looked at that earlier. if there's an extract-root-form or similar then that could be used