proby 0.13.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +202 -78
  2. package/lib/bin.js +7 -1
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -5,8 +5,10 @@ Test runner for JavaScript runtimes.
5
5
  ## What is proby?
6
6
 
7
7
  A cross-runtime test runner that automatically discovers and runs test files.
8
- Works with both single repositories and monorepos. Uses `@rcompat/test` for
9
- writing tests. Works consistently across Node, Deno, and Bun.
8
+ Works with both single repositories and monorepos. Supports TypeScript source
9
+ execution in monorepos without a build step when your packages expose `source`
10
+ entries in `package.json`. Uses `@rcompat/test` for writing tests. Works
11
+ consistently across Node, Deno, and Bun.
10
12
 
11
13
  ## Installation
12
14
 
@@ -43,45 +45,213 @@ npx proby
43
45
  ```
44
46
 
45
47
  Run a single file:
48
+
46
49
  ```bash
47
50
  npx proby math.spec.ts
48
51
  ```
49
52
 
50
53
  Run a single group within a file:
54
+
51
55
  ```bash
52
56
  npx proby math.spec.ts addition
53
57
  ```
54
58
 
55
- ### Grouping tests
59
+ ## How proby resolves source files
56
60
 
57
- Use `test.group` in your spec files to cluster related cases. Groups can then
58
- be targeted individually when running proby:
59
- ```js
60
- // src/math.spec.ts
61
- import test from "@rcompat/test";
61
+ Proby relaunches itself with runtime conditions before running tests. By
62
+ default it uses the `source` condition, which lets runtimes resolve package
63
+ `imports` and `exports` to your TypeScript source files instead of built
64
+ JavaScript.
62
65
 
63
- test.group("addition", () => {
64
- test.case("integers", assert => {
65
- assert(1 + 1).equals(2);
66
- });
67
- });
66
+ This is especially useful in monorepos where packages depend on each other and
67
+ you want to run tests against source directly.
68
68
 
69
- test.group("multiplication", () => {
70
- test.case("integers", assert => {
71
- assert(2 * 3).equals(6);
72
- });
69
+ To use this pattern, expose `source` entries in your packages.
70
+
71
+ Example:
72
+
73
+ ```json
74
+ {
75
+ "imports": {
76
+ "#*": {
77
+ "source": "./src/*.ts",
78
+ "default": "./lib/*.js"
79
+ }
80
+ },
81
+ "exports": {
82
+ ".": {
83
+ "source": "./src/index.ts",
84
+ "default": "./lib/index.js"
85
+ }
86
+ }
87
+ }
88
+ ```
89
+
90
+ With this setup, proby can run against your TypeScript source without requiring
91
+ an upfront build step.
92
+
93
+ ## Configuration
94
+
95
+ Create `proby.config.ts` or `proby.config.js` in your project root.
96
+
97
+ ```ts
98
+ import config from "proby/config";
99
+
100
+ export default config({
101
+ monorepo: true,
102
+ packages: "packages",
103
+ include: ["src"],
104
+ conditions: ["source"],
73
105
  });
74
106
  ```
75
- ```bash
76
- npx proby math.spec.ts addition # runs only the addition group
107
+
108
+ ### Config options
109
+
110
+ #### `monorepo`
111
+
112
+ ```ts
113
+ boolean
77
114
  ```
78
115
 
79
- ### Grouping tests
116
+ Whether proby should scan package directories inside a monorepo.
117
+
118
+ Default:
119
+
120
+ ```ts
121
+ false
122
+ ```
123
+
124
+ #### `packages`
125
+
126
+ ```ts
127
+ string
128
+ ```
129
+
130
+ Directory containing package folders when `monorepo` is enabled.
131
+
132
+ Default:
133
+
134
+ ```ts
135
+ "packages"
136
+ ```
137
+
138
+ #### `include`
139
+
140
+ ```ts
141
+ string[]
142
+ ```
143
+
144
+ Directories to scan for spec files.
145
+
146
+ Default:
147
+
148
+ ```ts
149
+ ["src"]
150
+ ```
151
+
152
+ #### `conditions`
153
+
154
+ ```ts
155
+ string[]
156
+ ```
157
+
158
+ Runtime conditions used when proby relaunches itself.
159
+
160
+ Default:
161
+
162
+ ```ts
163
+ ["source"]
164
+ ```
165
+
166
+ ## Project structure
167
+
168
+ Proby automatically detects your project structure.
169
+
170
+ ### Single repository
171
+
172
+ ```text
173
+ my-project/
174
+ ├── src/
175
+ │ ├── utils.ts
176
+ │ ├── utils.spec.ts
177
+ │ ├── math.ts
178
+ │ └── math.spec.ts
179
+ └── package.json
180
+ ```
181
+
182
+ ### Monorepo
183
+
184
+ ```text
185
+ my-monorepo/
186
+ ├── packages/
187
+ │ ├── core/
188
+ │ │ └── src/
189
+ │ │ ├── index.ts
190
+ │ │ └── index.spec.ts
191
+ │ └── utils/
192
+ │ └── src/
193
+ │ ├── helpers.ts
194
+ │ └── helpers.spec.ts
195
+ └── package.json
196
+ ```
197
+
198
+ ## Test file conventions
199
+
200
+ - Files must end with `.spec.ts` or `.spec.js`
201
+ - Files must be in one of the configured include directories
202
+ - Use `@rcompat/test` to write tests
203
+ - Use `test.group` to organize cases into named groups targetable by proby
204
+
205
+ ## Static mock files
206
+
207
+ Proby supports preloading sibling mock files before a spec file is evaluated.
208
+ This allows module mocks to be registered before the spec's static imports are
209
+ read.
210
+
211
+ Pair files by matching the spec extension exactly:
212
+
213
+ - `math.spec.ts` pairs with `math.mock.ts`
214
+ - `math.spec.js` pairs with `math.mock.js`
215
+
216
+ If a sibling mock file exists, proby loads it before the spec file.
217
+
218
+ Example:
219
+
220
+ ```ts
221
+ // math.ts
222
+ export function add(a: number, b: number) {
223
+ return a + b;
224
+ }
225
+ ```
226
+
227
+ ```ts
228
+ // math.mock.ts
229
+ import test from "@rcompat/test";
230
+
231
+ test.mock("./math.ts", () => ({
232
+ add: (a: number, b: number) => 99,
233
+ }));
234
+ ```
235
+
236
+ ```ts
237
+ // math.spec.ts
238
+ import test from "@rcompat/test";
239
+ import { add } from "./math.ts";
240
+
241
+ test.case("uses the preloaded mock", assert => {
242
+ assert(add(1, 2)).equals(99);
243
+ });
244
+ ```
245
+
246
+ Static mocks are file-scoped. A mock loaded for one spec file does not leak
247
+ into later spec files.
248
+
249
+ ## Grouping tests
80
250
 
81
251
  Use `test.group` in your spec files to cluster related cases. Groups can then
82
- be targeted individually when running proby:
252
+ be targeted individually when running proby.
253
+
83
254
  ```js
84
- // src/math.spec.ts
85
255
  import test from "@rcompat/test";
86
256
 
87
257
  test.group("addition", () => {
@@ -96,17 +266,16 @@ test.group("multiplication", () => {
96
266
  });
97
267
  });
98
268
  ```
269
+
99
270
  ```bash
100
- npx proby math.spec.ts addition # runs only the addition group
271
+ npx proby math.spec.ts addition
101
272
  ```
102
273
 
103
- ### Writing tests
274
+ ## Writing tests
104
275
 
105
- Create test files with `.spec.ts` or `.spec.js` extension in your `src`
106
- directory:
276
+ Create test files with `.spec.ts` or `.spec.js`:
107
277
 
108
278
  ```js
109
- // src/math.spec.ts
110
279
  import test from "@rcompat/test";
111
280
 
112
281
  test.case("addition", assert => {
@@ -120,50 +289,21 @@ test.case("multiplication", assert => {
120
289
  });
121
290
  ```
122
291
 
123
- ### Test output
292
+ ## Test output
124
293
 
125
294
  Proby displays colored output:
295
+
126
296
  - Green `o` for passing tests
127
297
  - Red `x` for failing tests
128
298
 
129
- ```
299
+ ```text
130
300
  oooooxoo
131
301
  src/math.spec.ts division
132
302
  expected 5
133
303
  actual 4
134
304
  ```
135
305
 
136
- ### Project structure
137
-
138
- Proby automatically detects your project structure:
139
-
140
- **Single repository:**
141
- ```
142
- my-project/
143
- ├── src/
144
- │ ├── utils.ts
145
- │ ├── utils.spec.ts # ← Test file
146
- │ ├── math.ts
147
- │ └── math.spec.ts # ← Test file
148
- └── package.json
149
- ```
150
-
151
- **Monorepo:**
152
- ```
153
- my-monorepo/
154
- ├── packages/
155
- │ ├── core/
156
- │ │ └── src/
157
- │ │ ├── index.ts
158
- │ │ └── index.spec.ts # ← Test file
159
- │ └── utils/
160
- │ └── src/
161
- │ ├── helpers.ts
162
- │ └── helpers.spec.ts # ← Test file
163
- └── package.json
164
- ```
165
-
166
- ### npm scripts
306
+ ## npm scripts
167
307
 
168
308
  Add proby to your `package.json`:
169
309
 
@@ -181,13 +321,6 @@ Then run:
181
321
  npm test
182
322
  ```
183
323
 
184
- ## Test file conventions
185
-
186
- - Files must end with `.spec.ts` or `.spec.js`
187
- - Files must be in the `src` directory (or `packages/*/src` for monorepos)
188
- - Use `@rcompat/test` to write tests
189
- - Use `test.group` to organize cases into named groups targetable by proby
190
-
191
324
  ## Examples
192
325
 
193
326
  ### Basic assertions
@@ -196,17 +329,10 @@ npm test
196
329
  import test from "@rcompat/test";
197
330
 
198
331
  test.case("basic assertions", assert => {
199
- // equality
200
332
  assert(value).equals(expected);
201
-
202
- // truthiness
203
333
  assert(condition).true();
204
334
  assert(condition).false();
205
-
206
- // type checking
207
335
  assert(value).type<string>();
208
-
209
- // throws
210
336
  assert(() => throwingFunction()).throws();
211
337
  assert(() => safeFunction()).tries();
212
338
  });
@@ -227,7 +353,7 @@ test.case("async operations", async assert => {
227
353
 
228
354
  ```js
229
355
  // src/calculator.ts
230
- export function add(a: number, b: number) {
356
+ export function add(a, b) {
231
357
  return a + b;
232
358
  }
233
359
 
@@ -245,13 +371,11 @@ test.case("add function", assert => {
245
371
  ## Cross-Runtime Compatibility
246
372
 
247
373
  | Runtime | Supported |
248
- |---------|-----------|
374
+ | ------- | --------- |
249
375
  | Node.js | ✓ |
250
376
  | Deno | ✓ |
251
377
  | Bun | ✓ |
252
378
 
253
- No configuration required — just run `npx proby`.
254
-
255
379
  ## License
256
380
 
257
381
  MIT
package/lib/bin.js CHANGED
@@ -1,10 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import Schema from "#Schema";
2
+ import p from "pema";
3
3
  import env from "@rcompat/env";
4
4
  import fs from "@rcompat/fs";
5
5
  import io from "@rcompat/io";
6
6
  import is from "@rcompat/is";
7
7
  import runtime from "@rcompat/runtime";
8
+ const Schema = p({
9
+ monorepo: p.boolean.default(false),
10
+ packages: p.string.default("packages"),
11
+ include: p.array(p.string).default(["src"]),
12
+ conditions: p.array(p.string).default(["source"]),
13
+ });
8
14
  const root = await fs.project.root();
9
15
  const ts_config_file = root.join("proby.config.ts");
10
16
  const js_config_file = root.join("proby.config.js");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "proby",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Standard library test runner",
5
5
  "bugs": "https://github.com/rcompat/rcompat/issues",
6
6
  "license": "MIT",
@@ -20,8 +20,8 @@
20
20
  "@rcompat/assert": "^0.8.0",
21
21
  "@rcompat/cli": "^0.18.0",
22
22
  "@rcompat/env": "^0.17.0",
23
- "@rcompat/io": "^0.5.0",
24
23
  "@rcompat/fs": "^0.28.0",
24
+ "@rcompat/io": "^0.5.0",
25
25
  "@rcompat/is": "^0.6.0",
26
26
  "@rcompat/runtime": "^0.11.0"
27
27
  },