@noego/testing 0.1.0 → 0.2.0
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.
- package/README.md +94 -0
- package/dist/index.cjs +610 -641
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +237 -227
- package/dist/index.d.ts +237 -227
- package/dist/index.js +601 -622
- package/dist/index.js.map +1 -1
- package/package.json +9 -6
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# @noego/testing
|
|
2
|
+
|
|
3
|
+
The canonical shared owner of NoEgo test composition and method control:
|
|
4
|
+
`testIoc` real-IoC environments plus the lowercase `test.*` behavior, watch,
|
|
5
|
+
inspection, and expectation language. Built on `@noego/ioc`'s production seams
|
|
6
|
+
— real containers, real lifetimes, real scopes. A fake container is never the
|
|
7
|
+
production-equivalent testing foundation.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { testIoc, test } from '@noego/testing';
|
|
11
|
+
|
|
12
|
+
const env = await testIoc()
|
|
13
|
+
.methods({
|
|
14
|
+
ProjectRepository: {
|
|
15
|
+
save: test.once(test.returns(project)),
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
.build();
|
|
19
|
+
|
|
20
|
+
const service = await env.get(ProjectService);
|
|
21
|
+
service.create('demo');
|
|
22
|
+
|
|
23
|
+
await env.verify();
|
|
24
|
+
await env.dispose();
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## The builder is a persistent immutable value
|
|
28
|
+
|
|
29
|
+
Every fluent call returns a new derived builder; the parent stays reusable.
|
|
30
|
+
Non-conflicting writes are order-insensitive; the last write to the same
|
|
31
|
+
effective identity wins on that derived branch. `.build()` is non-consuming
|
|
32
|
+
and every build creates fresh runtime, watch, and expectation state — parallel
|
|
33
|
+
environments never share state.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
const base = testIoc()
|
|
37
|
+
.classes(new Map([[ProjectRepository, MemoryProjectRepository]]))
|
|
38
|
+
.values({ FeatureFlags: testFlags });
|
|
39
|
+
|
|
40
|
+
const admin = base.values({ CurrentUser: adminUser });
|
|
41
|
+
const guest = base.values({ CurrentUser: guestUser });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Configuration surfaces:
|
|
45
|
+
|
|
46
|
+
| Call | Identity space | Meaning |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `.use(preset)` | ordered overlay | apply an `ApplicationModule` or another builder as reusable composition |
|
|
49
|
+
| `.classes({...})` | IoC class token | replace the implementation behind a class token (lifetime validation stays real) |
|
|
50
|
+
| `.functions({...})` | IoC provider key | replace a factory/provider registration (configured lifetime preserved) |
|
|
51
|
+
| `.values({...})` | IoC value token | provide/replace value registrations |
|
|
52
|
+
| `.methods({...})` | token + method | install `test.*` behavior/observation descriptors |
|
|
53
|
+
|
|
54
|
+
Plain-object keys are matched by token name; pass a `Map` to key by the
|
|
55
|
+
class/token itself. Unknown string keys fail with the known tokens listed.
|
|
56
|
+
|
|
57
|
+
## `test.*`
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
test.returns(value) // replace the result (auto-watches)
|
|
61
|
+
test.throws(error) // throw/reject (auto-watches)
|
|
62
|
+
test.original() // call the real implementation (auto-watches)
|
|
63
|
+
test.calls([...]) // one behavior per invocation; overflow fails immediately
|
|
64
|
+
|
|
65
|
+
test.watch() // keep original behavior, record calls
|
|
66
|
+
test.inspect(env, Token, 'method') // read the recorded history
|
|
67
|
+
|
|
68
|
+
test.once() // exactly one call (original behavior)
|
|
69
|
+
test.once(behavior) // exactly one call with the supplied behavior
|
|
70
|
+
test.times(n, b?) // exactly n calls
|
|
71
|
+
test.never() // zero calls; first invocation fails, original skipped
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Every installed descriptor automatically watches its method; only watched
|
|
75
|
+
methods are inspectable. Over-calls fail at invocation time; under-calls are
|
|
76
|
+
finalized by `await env.verify()` (a repeatable snapshot that aggregates every
|
|
77
|
+
unsatisfied expectation). A raw wrapper function
|
|
78
|
+
(`(original) => (...args) => ...`) is installed as-is and is **not** watched.
|
|
79
|
+
|
|
80
|
+
## Environment
|
|
81
|
+
|
|
82
|
+
`build()` returns `{ root, get, instance, extend, verify, dispose }`. `extend()`
|
|
83
|
+
creates a real child scope (method configuration and watches apply there too);
|
|
84
|
+
`dispose()` disposes the whole environment through `@noego/ioc`'s scope
|
|
85
|
+
disposal — including disposable objects registered via `.values()`.
|
|
86
|
+
|
|
87
|
+
## 0.1.x → 0.2.0
|
|
88
|
+
|
|
89
|
+
The old generic runtime-mirror doubles (ManualClock, ManualScheduler,
|
|
90
|
+
ScriptedFetchClient, ScriptedProcessRunner, memory stores, RecordingEventBus,
|
|
91
|
+
recording sinks, contract suites, LeakDetector) are retired along with the
|
|
92
|
+
`@noego/runtime` dependency, per the NoEgo runtime/testing deprecation plan.
|
|
93
|
+
Pin `0.1.x` if you still need them; boundary-specific helpers move to their
|
|
94
|
+
natural production owners.
|