babashka/test-resources/lib_tests/doric/test/doctest.clj
Gabriel Horner 665ae4dd97
Finish up library tests (#1120)
* Add tests for markdown-clj and tools.namespace

See comment for why only one markdown test could be run.
Closes #1069 and #1064

* Convert 10 test libs using add-libtest

Also improved add-libtest to only require maven artifact
and rely on clojars for getting git-url most of the time

* Convert 8 more test libs using add-libtest

Also updated table and added comment for newline test

* Fix doric test

* Disable tools.namespace test that fails on windows

* Added dozen manual test libs and converted 2 test libs

add-libtest.clj supports manually-added and test-directories options

* Converts last tests to test namespaces and write libraries.csv

* Add a number of library tests from projects.md

Also add more docs around adding test libs and tweak add script

* Use :sha for gitlib and older clojure cli

* Revert "Use :sha for gitlib and older clojure cli"

This reverts commit c663ab8368.

* Fix and disable failing tests

Disabled tests that fail consistently and fixed windows one
2021-12-29 16:35:14 +01:00

93 lines
2.3 KiB
Clojure

(ns doric.test.doctest
(:use [clojure.java.io :only [file]]
[clojure.test])
(:import (java.io PushbackReader StringReader)))
(defn fenced-blocks
"detect and extract github-style fenced blocks in a file"
[s]
(map second
(re-seq #"(?m)(?s)^```clojure\n(.*?)\n^```" s)))
(def prompt
;; regex for finding 'foo.bar>' repl prompts
"(?m)\n*^\\S*>\\s*")
(defn skip?
"is a result skippable?"
;; if it's a comment, the answer is yes
[s]
(.startsWith s ";"))
(defn reps
"given a string of read-eval-print sequences, separate the different
'r-e-p's from each other"
[prompt s]
(rest (.split s prompt)))
(defn markdown-tests
"extract all the tests from a markdown file"
[f]
(->> f
slurp
fenced-blocks
(mapcat (partial reps prompt))))
(defn repl-tests
"extract all the tests from a repl-session-like file"
[f]
(->> f
slurp
(reps prompt)))
(defn temp-ns
"create a temporary ns, and return its name"
[]
(binding [*ns* *ns*]
(in-ns (gensym))
(use 'clojure.core)
;; BB-TEST-PATCH: bb can't .getName on ns
(str *ns*)))
(defn eval-in-ns
"evaluate a form inside the given ns-name"
[ns form]
(binding [*ns* *ns*]
(in-ns ns)
(eval form)))
(defn run-doctest
"run a single doctest, reporting success or failure"
[file idx ns test]
(let [r (PushbackReader. (StringReader. test))
form (read r)
expected (.trim (slurp r))
actual (when-not (skip? expected)
(.trim (try
(with-out-str
(pr (eval-in-ns ns form))
(flush))
(catch Exception _
(println _)
(.toString (gensym))))))]
(if (or (skip? expected)
(= actual expected))
(report {:type :pass})
(report {:type :fail
:file file :line idx
:expected expected :actual actual}))))
(defn run-doctests
"use text-extract-fn to get all the tests out of file, and run them
all, reporting success or failure"
[test-extract-fn file]
(let [ns (temp-ns)]
(doseq [[idx t] (map-indexed vector (test-extract-fn file))]
(run-doctest file idx ns t))
(remove-ns ns)))
(comment
;; example usage
(deftest bar-repl
(run-doctests repl-tests "test/bar.repl")))