-
-
Notifications
You must be signed in to change notification settings - Fork 46
/
interface.clj
147 lines (120 loc) · 6.44 KB
/
interface.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
(ns polylith.clj.core.test-runner-contract.interface)
(defprotocol TestRunner
"Implement this protocol to supply a custom test runner.
Runner options:
- `is-verbose` A boolean indicating if we are running in verbose mode
or not. `TestRunner` can use this to print additional
information about the test run.
- `color-mode` The color-mode that the poly tool is currently running with.
`TestRunner` is expected to respect the color mode.
- `project` A map containing the project information.
- `all-paths` A vector of all paths necessary to create a classpath for
running the tests in isolation within the context of the
current project.
- `setup-fn` An optional setup function for tests defined in the
workspace config. The poly tool will run this function
before calling run-tests only if this is an in-process
`TestRunner`. If this is an `ExternalTestRunner`, the external
test runner should run the `setup-fn`.
- `teardown-fn` An optional teardown function for tests defined in the
workspace config. The poly tool will run this function
after the run-tests function completes (exception or not),
only if this is an in-process `TestRunner`. If this is an
`ExternalTestRunner`, the external test runner should run
the `teardown-fn`.
Additional options for in-process `TestRunner`:
- `class-loader` The isolated classloader created from the `all-paths`.
This classloader will be used to evaluate statements within
the project's context. Use this if you need more granular
access. `eval-in-project` should be sufficient for most
cases.
- `eval-in-project` A function that takes a single form as its argument and
evaluates it within the project's classloader. It returns
the result of the evaluation. This is the primary interface
for running tests in the project's isolated context.
Additional options for `ExternalTestRunner`:
- `process-ns` The main namespace of the external test runner. This
namespace will be invoked as a Java subprocess.
Usage:
Create a constructor function that returns an instance of `TestRunner` or
`ExternalTestRunner`:
```Clojure
(defn create [{:keys [workspace project test-settings is-verbose color-mode changes]}]
...
(reify
test-runner-contract/TestRunner
(test-runner-name [this] ...)
(test-sources-present? [this] ...)
(tests-present? [this runner-opts] ...)
(run-tests [this runner-opts] ...)
; Optional, only if you want an external test runner
test-runner-contract/ExternalTestRunner
(external-process-namespace [this] ...)))
```
`workspace` passed to the constructor will contain `:user-input`, which
can be used to receive additional arguments for runtime configuration.
Add your constructor function in the `workspace.edn`. To add a single global
test runner, use the `:test` key:
```Clojure
{:test {:create-test-runner my.namespace/create}
:projects {\"project-a\" {:alias \"a\"}
\"project-b\" {:alias \"b\"}}}
```
To add a multiple global test runners, use the vector variant inside the
`:test` key. The following example will add three test runners globally
where the last one is the default test runner.
```Clojure
{:test {:create-test-runner [my.namespace/create se.example/create :default]}
:projects {\"project-a\" {:alias \"a\"}
\"project-b\" {:alias \"b\"}}}
```
To add a custom test runner for a specific project, use the `:test` key
in the project configuration. You can also add multiple test runners with
using the vector variant.
```Clojure
{:projects {\"project-a\" {:alias \"a\"
:test {:create-test-runner my.namespace/create}}
\"project-b\" {:alias \"b\"
:test {:create-test-runner [my.namespace/create
:default]}}}}
```
Adding a test runner definition to a project will override the global test
runner. The `project-a` will use the global test runner, `my.namespace/create`
whereas `project-b` will use the default test runner.
```Clojure
{:test {:create-test-runner my.namespace/create}
:projects {\"project-a\" {:alias \"a\"}
\"project-b\" {:alias \"b\"
:test {:create-test-runner :default}}}}
```"
(test-runner-name [this]
"Returns a printable name that the poly tool can print out for
information purposes")
(test-sources-present? [this]
"The poly tool calls this first before attempting to run any tests. If
it returns a falsy value, we short-circuit. Not even the project
classloader will be created")
(tests-present? [this runner-opts]
"The poly tool calls this before calling the run-tests. If it returns a
falsy value, run-tests won't be called. The runner-opts passed to this
function is identical to the one passed to the run-tests. It can evaluate
forms in the project's context.")
(run-tests [this runner-opts]
"It should run the tests and throw an exception if the test run is considered
failed."))
(defprotocol ExternalTestRunner
"Extends the `TestRunner` protocol to provide an external process namespace
for a test runner. Polylith uses a classloader approach to run tests in
isolation by default. `ExternalTestRunner` skips the classloaders and uses
Java subprocesses."
(external-process-namespace [this]
"Returns a symbol or string identifying the main namespace of an external
test runner. If it returns `nil` (default), the test runner will be an
in-process test runner and the tests will run in an isolated classloader
within the same process.
When an external test runner is used, the poly tool will not create a
classloader. The external test runner implementation should use the
`all-paths` argument passed to the run-tests function to create a classpath
for the Java subprocesses.
The setup-fn and teardown-fn must be run by the external test runner
instead of the poly tool."))