Fork me on GitHub
#docs
<
2018-01-04
>
pithyless13:01:07

I’ve previously written some code to play with the idea of executing tests via the docstring, similar to python’s doctest. I wonder if this is maybe something that would be good idea to try to integrate into @arrdem stacks structure or something. https://gist.github.com/pithyless/c7d6954c055ad45b6dfd2fca6ddfcce9

arrdem16:01:33

Interesting idea! You could definitely relax the language lines constraint. What has your experience been using this / transcriptor @pithyless?

noisesmith17:01:43

@pithyless there's probably a few ways to simplify that. clojure.test checks every var in every ns for a :test key on its metadata, then runs the fn mapped to by that metadata using fixtures defined in the same ns (if any)

noisesmith17:01:26

so eg. you don't need a macro that calls deftest, it suffices to create a var with ^{:test (fn [] ....)} metadata on it

noisesmith17:01:42

and that var could be the same function you are testing

arrdem19:01:50

@noisesmith I thought ^:test was a boolean flag that the tagged var was a test fn, what are you doing there?

noisesmith19:01:56

double checking...

arrdem19:01:49

I mean I can check as well as you can

arrdem19:01:54

no need if it was offhand

noisesmith19:01:09

right, but if I misremembered it's helpful for me to see what the actual situation is

arrdem19:01:44

(defmacro deftest
  "Defines a test function with no arguments.  Test functions may call
  other tests, so tests may be composed.  If you compose tests, you
  should also define a function named test-ns-hook; run-tests will
  call test-ns-hook instead of testing all vars.

  Note: Actually, the test body goes in the :test metadata on the var,
  and the real function (the value of the var) calls test-var on
  itself.

  When *load-tests* is false, deftest is ignored."
  {:added "1.1"}
  [name & body]
  (when *load-tests*
    `(def ~(vary-meta name assoc :test `(fn [] ~@body))
          (fn [] (test-var (var ~name))))))

noisesmith19:01:02

+user=> (clojure.test/deftest foo-test (clojure.test/is true))
#'user/foo-test
+user=> (meta #'foo-test)
{:test #object[user$fn__147 0x2e61d218 "user$fn__147@2e61d218"], :line 2, :column 1, :file "NO_SOURCE_PATH", :name foo-test, :ns #object[clojure.lang.Namespace 0x20b12f8a "user"]}

noisesmith19:01:15

so the value under the :test metadata contains the actual function to run

arrdem19:01:35

Yeah okay interesting.

noisesmith19:01:52

that means you can easily add an inline test to any function you like, if that suits your fancy

arrdem19:01:17

well… if you have a thing that either annotates vars after the fact or hacks defn

arrdem19:01:33

but maybe that’s worth building

noisesmith19:01:45

I mean - you can put ^{:test (fn ...)} in your function definition, as I was suggesting

noisesmith19:01:58

or a macro that makes a nicer syntax for that of course

noisesmith19:01:32

just saying there's a more direct route than using deftest is all, especially if part of the root desire here is to define the test in the same code that defines the function