@fougere/testing 0.9.2-alpha.0 → 0.10.0-alpha.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 +1 -1
- package/dist/{comparison.d.ts → DoorContractCase.d.ts} +5 -13
- package/dist/DoorContractCase.d.ts.map +1 -0
- package/dist/{comparison.js → DoorContractCase.js} +31 -31
- package/dist/DoorContractCase.js.map +1 -0
- package/dist/DoorInput.d.ts +5 -0
- package/dist/DoorInput.d.ts.map +1 -0
- package/dist/DoorInput.js +2 -0
- package/dist/DoorInput.js.map +1 -0
- package/dist/DoorOptions.d.ts +7 -0
- package/dist/DoorOptions.d.ts.map +1 -0
- package/dist/DoorOptions.js +2 -0
- package/dist/DoorOptions.js.map +1 -0
- package/dist/all.d.ts +4 -4
- package/dist/all.d.ts.map +1 -1
- package/dist/all.js +3 -3
- package/dist/all.js.map +1 -1
- package/dist/app/TestApp.d.ts +15 -0
- package/dist/app/TestApp.d.ts.map +1 -0
- package/dist/{app.js → app/TestApp.js} +3 -3
- package/dist/app/TestApp.js.map +1 -0
- package/dist/{app.d.ts → app/TestAppOptions.d.ts} +2 -14
- package/dist/app/TestAppOptions.d.ts.map +1 -0
- package/dist/app/TestAppOptions.js +2 -0
- package/dist/app/TestAppOptions.js.map +1 -0
- package/dist/facades/CheckOptions.d.ts +6 -0
- package/dist/facades/CheckOptions.d.ts.map +1 -0
- package/dist/facades/CheckOptions.js +2 -0
- package/dist/facades/CheckOptions.js.map +1 -0
- package/dist/{doors.d.ts → facades/Verdict.d.ts} +4 -8
- package/dist/facades/Verdict.d.ts.map +1 -0
- package/dist/{doors.js → facades/Verdict.js} +4 -4
- package/dist/facades/Verdict.js.map +1 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/load.d.ts +19 -5
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js +29 -9
- package/dist/load.js.map +1 -1
- package/dist/spans.d.ts +18 -0
- package/dist/spans.d.ts.map +1 -0
- package/dist/spans.js +56 -0
- package/dist/spans.js.map +1 -0
- package/dist/statements.d.ts +17 -0
- package/dist/statements.d.ts.map +1 -0
- package/dist/statements.js +37 -0
- package/dist/statements.js.map +1 -0
- package/dist/stub/Port.d.ts +3 -0
- package/dist/stub/Port.d.ts.map +1 -0
- package/dist/stub/Port.js +2 -0
- package/dist/stub/Port.js.map +1 -0
- package/dist/{stub.d.ts → stub/Stub.d.ts} +2 -3
- package/dist/stub/Stub.d.ts.map +1 -0
- package/dist/{stub.js → stub/Stub.js} +1 -1
- package/dist/stub/Stub.js.map +1 -0
- package/dist/{sync.d.ts → sync/SyncDrift.d.ts} +2 -10
- package/dist/sync/SyncDrift.d.ts.map +1 -0
- package/dist/{sync.js → sync/SyncDrift.js} +5 -18
- package/dist/sync/SyncDrift.js.map +1 -0
- package/dist/sync/SyncedRemote.d.ts +10 -0
- package/dist/sync/SyncedRemote.d.ts.map +1 -0
- package/dist/sync/SyncedRemote.js +15 -0
- package/dist/sync/SyncedRemote.js.map +1 -0
- package/dist/vitest.d.ts.map +1 -1
- package/dist/vitest.js +4 -0
- package/dist/vitest.js.map +1 -1
- package/package.json +20 -10
- package/src/{comparison.ts → DoorContractCase.ts} +34 -40
- package/src/DoorInput.ts +1 -0
- package/src/DoorOptions.ts +7 -0
- package/src/all.ts +7 -5
- package/src/{app.ts → app/TestApp.ts} +4 -26
- package/src/app/TestAppOptions.ts +25 -0
- package/src/facades/CheckOptions.ts +6 -0
- package/src/{doors.ts → facades/Verdict.ts} +5 -9
- package/src/index.ts +8 -8
- package/src/load.ts +52 -13
- package/src/spans.ts +66 -0
- package/src/statements.ts +41 -0
- package/src/stub/Port.ts +2 -0
- package/src/{stub.ts → stub/Stub.ts} +1 -3
- package/src/{sync.ts → sync/SyncDrift.ts} +3 -23
- package/src/sync/SyncedRemote.ts +22 -0
- package/src/vitest.ts +4 -0
- package/dist/app.d.ts.map +0 -1
- package/dist/app.js.map +0 -1
- package/dist/comparison.d.ts.map +0 -1
- package/dist/comparison.js.map +0 -1
- package/dist/doors.d.ts.map +0 -1
- package/dist/doors.js.map +0 -1
- package/dist/stub.d.ts.map +0 -1
- package/dist/stub.js.map +0 -1
- package/dist/sync.d.ts.map +0 -1
- package/dist/sync.js.map +0 -1
package/dist/load.js
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import { frameCall } from '@fougere/transport-http';
|
|
2
|
+
import { resolveEffectiveOperations } from '@fougere/core';
|
|
2
3
|
import { sampleInput } from './sample.js';
|
|
3
4
|
/** Every operation the app answers, with a body for those that take one. */
|
|
4
|
-
export function reachableOps(app, given = {}) {
|
|
5
|
+
export function reachableOps(app, given = {}, remotes = {}) {
|
|
6
|
+
const { operations } = resolveEffectiveOperations(app.fronds, { remotes });
|
|
7
|
+
const hops = new Map(operations.map((op) => [`${op.handler.address}.${op.name}`, op.reach.hops]));
|
|
5
8
|
const found = [];
|
|
6
9
|
for (const frond of app.fronds) {
|
|
7
10
|
for (const handler of frond.handlers) {
|
|
8
|
-
// A named surface is a restricted
|
|
9
|
-
//
|
|
11
|
+
// A named surface is a restricted facade; the load of an app is what its default
|
|
12
|
+
// facade answers, so a surface would count the same operation twice.
|
|
10
13
|
if (handler.surface)
|
|
11
14
|
continue;
|
|
12
15
|
for (const [op, contract] of handler.operations ?? []) {
|
|
13
16
|
const schema = contract.input;
|
|
17
|
+
const method = `${handler.address}.${op}`;
|
|
14
18
|
found.push({
|
|
15
|
-
method
|
|
19
|
+
method,
|
|
16
20
|
input: schema ? sampleInput(schema, given[handler.address] ?? {}) : undefined,
|
|
21
|
+
hops: hops.get(method) ?? 0,
|
|
17
22
|
});
|
|
18
23
|
}
|
|
19
24
|
}
|
|
@@ -22,8 +27,8 @@ export function reachableOps(app, given = {}) {
|
|
|
22
27
|
}
|
|
23
28
|
/** A k6 scenario, written from what the app answers. */
|
|
24
29
|
export function loadScript(app, options = {}) {
|
|
25
|
-
const
|
|
26
|
-
const ops = reachableOps(app, options.given);
|
|
30
|
+
const facade = options.facade ?? 'http://127.0.0.1:3000/_fougere/call';
|
|
31
|
+
const ops = reachableOps(app, options.given, options.remotes ?? {});
|
|
27
32
|
// The shape, from the one function that states it. `body` is replaced per iteration.
|
|
28
33
|
const envelope = frameCall({ entity: 'ENTITY', op: 'OP' }, { params: {}, query: {}, input: undefined, state: {} }, 0);
|
|
29
34
|
// What the envelope carries that an iteration does not fill in itself. Keeping
|
|
@@ -35,11 +40,17 @@ export function loadScript(app, options = {}) {
|
|
|
35
40
|
import http from 'k6/http';
|
|
36
41
|
import { check } from 'k6';
|
|
37
42
|
|
|
38
|
-
const DOOR = ${JSON.stringify(
|
|
43
|
+
const DOOR = ${JSON.stringify(facade)};
|
|
39
44
|
|
|
40
45
|
// Every operation the app serves. A weight of 0 takes one out, visibly.
|
|
41
46
|
const OPS = ${JSON.stringify(ops.map((op) => ({ ...op, weight: 1 })), null, 2)};
|
|
42
47
|
|
|
48
|
+
// Yours: how long an op may take here, and what one process boundary is allowed to add. Two
|
|
49
|
+
// numbers instead of one, because an op that crosses nothing and an op that crosses twice were
|
|
50
|
+
// never the same subject — hops above is read from the code, these two are facts about your
|
|
51
|
+
// network.
|
|
52
|
+
const BUDGET = { base: 300, perHop: 200 };
|
|
53
|
+
|
|
43
54
|
export const options = {
|
|
44
55
|
// Yours: a flat rate draws flat lines and there is nothing to read in them.
|
|
45
56
|
stages: [
|
|
@@ -47,8 +58,17 @@ export const options = {
|
|
|
47
58
|
{ duration: '45s', target: 5 },
|
|
48
59
|
{ duration: '30s', target: 0 },
|
|
49
60
|
],
|
|
50
|
-
// Yours:
|
|
51
|
-
|
|
61
|
+
// Yours: the shape of the run.
|
|
62
|
+
// Derived from BUDGET and each op's hops — an op that crosses two processes is not held to
|
|
63
|
+
// the same figure as one that never leaves. k6 reads a threshold per tag, and every call
|
|
64
|
+
// below is tagged with the op it made.
|
|
65
|
+
thresholds: {
|
|
66
|
+
http_req_failed: ['rate<0.01'],
|
|
67
|
+
...Object.fromEntries(OPS.map((op) => [
|
|
68
|
+
\`http_req_duration{op:\${op.method}}\`,
|
|
69
|
+
[\`p(95)<\${BUDGET.base + op.hops * BUDGET.perHop}\`],
|
|
70
|
+
])),
|
|
71
|
+
},
|
|
52
72
|
};
|
|
53
73
|
|
|
54
74
|
const TOTAL = OPS.reduce((sum, op) => sum + op.weight, 0);
|
package/dist/load.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"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"}
|
package/dist/spans.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { App } from '@fougere/core';
|
|
2
|
+
import type { FinishedSpan } from '@fougere/observability';
|
|
3
|
+
/**
|
|
4
|
+
* The steps one call opened — the operation, then whatever ran under it.
|
|
5
|
+
*
|
|
6
|
+
* The dual of [statementsOf]: that one counts what a call asked the database, this one holds
|
|
7
|
+
* the shape of the call itself. What it is FOR is a test about structure rather than speed —
|
|
8
|
+
* an op that delegates reports almost no self time, whatever the machine it runs on:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* const [op] = await spansOf(app, () => facade.list());
|
|
12
|
+
* expect(op.selfMs).toBeLessThan(0.1 * op.ms); // it delegates, it does not work
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* A threshold in milliseconds tests the machine. A ratio tests the code.
|
|
16
|
+
*/
|
|
17
|
+
export declare function spansOf(app: App, run: () => Promise<unknown>): Promise<FinishedSpan[]>;
|
|
18
|
+
//# sourceMappingURL=spans.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spans.d.ts","sourceRoot":"","sources":["../src/spans.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAK3D;;;;;;;;;;;;;GAaG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAY5F"}
|
package/dist/spans.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** One tracer per app: `app.use` has no undo, so a second call would stack a middleware. */
|
|
2
|
+
const installed = new WeakMap();
|
|
3
|
+
/**
|
|
4
|
+
* The steps one call opened — the operation, then whatever ran under it.
|
|
5
|
+
*
|
|
6
|
+
* The dual of [statementsOf]: that one counts what a call asked the database, this one holds
|
|
7
|
+
* the shape of the call itself. What it is FOR is a test about structure rather than speed —
|
|
8
|
+
* an op that delegates reports almost no self time, whatever the machine it runs on:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* const [op] = await spansOf(app, () => facade.list());
|
|
12
|
+
* expect(op.selfMs).toBeLessThan(0.1 * op.ms); // it delegates, it does not work
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* A threshold in milliseconds tests the machine. A ratio tests the code.
|
|
16
|
+
*/
|
|
17
|
+
export async function spansOf(app, run) {
|
|
18
|
+
const collecting = await tracerOf(app);
|
|
19
|
+
const spans = [];
|
|
20
|
+
collecting.push(spans);
|
|
21
|
+
try {
|
|
22
|
+
await run();
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
collecting.splice(collecting.indexOf(spans), 1);
|
|
26
|
+
}
|
|
27
|
+
return spans;
|
|
28
|
+
}
|
|
29
|
+
async function tracerOf(app) {
|
|
30
|
+
const held = installed.get(app);
|
|
31
|
+
if (held)
|
|
32
|
+
return held;
|
|
33
|
+
const { statementsUnder, tracing } = await observability();
|
|
34
|
+
const collecting = [];
|
|
35
|
+
installed.set(app, collecting);
|
|
36
|
+
// A test IS the diagnosis, so it asks for the detail a process running continuously does not.
|
|
37
|
+
const tracer = tracing([(span) => { for (const into of collecting)
|
|
38
|
+
into.push(span); }], { spanPerStatement: true });
|
|
39
|
+
app.use(tracer.middleware);
|
|
40
|
+
// Both halves, or `selfMs` would read as if the handler did the waiting itself. The
|
|
41
|
+
// subscription lives as long as the test process: `app.use` has no undo either, and one
|
|
42
|
+
// app per file is what a test file has.
|
|
43
|
+
await statementsUnder(tracer);
|
|
44
|
+
return collecting;
|
|
45
|
+
}
|
|
46
|
+
/** Optional, and dynamic for the reason `@fougere/calls` states: this package depends on none. */
|
|
47
|
+
async function observability() {
|
|
48
|
+
try {
|
|
49
|
+
return await import('@fougere/observability');
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
throw new Error('[spansOf] reading what a call cost needs @fougere/observability — install it, '
|
|
53
|
+
+ 'or there is no span to read.');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=spans.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spans.js","sourceRoot":"","sources":["../src/spans.ts"],"names":[],"mappings":"AAGA,4FAA4F;AAC5F,MAAM,SAAS,GAAG,IAAI,OAAO,EAAyB,CAAC;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAQ,EAAE,GAA2B;IACjE,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEvB,IAAI,CAAC;QACH,MAAM,GAAG,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,GAAQ;IAC9B,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,GAAG,MAAM,aAAa,EAAE,CAAC;IAC3D,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC/B,8FAA8F;IAC9F,MAAM,MAAM,GAAG,OAAO,CACpB,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,MAAM,IAAI,IAAI,UAAU;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAC/D,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAC3B,CAAC;IACF,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3B,oFAAoF;IACpF,wFAAwF;IACxF,wCAAwC;IACxC,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAE9B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,kGAAkG;AAClG,KAAK,UAAU,aAAa;IAC1B,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,gFAAgF;cAC9E,8BAA8B,CACjC,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { QueryEvent } from '@fougere/adapter-sql';
|
|
2
|
+
/**
|
|
3
|
+
* Every statement a call ran, in order.
|
|
4
|
+
*
|
|
5
|
+
* `testApp` boots on real SQLite, so this is what the handler actually asked the database —
|
|
6
|
+
* one per row is the shape of an N+1, and it is a number a test can refuse. A computed field
|
|
7
|
+
* that reads is the case: the façade hands the presenter the whole PAGE, so one query is
|
|
8
|
+
* possible, and nothing refuses `Promise.all(rows.map(…))` inside the field body.
|
|
9
|
+
*
|
|
10
|
+
* It REFUSES when `@fougere/adapter-sql` is absent, where the tracer degrades quietly: zero
|
|
11
|
+
* is what a passing assertion looks like, so an app observing nothing would turn this into a
|
|
12
|
+
* test that cannot fail.
|
|
13
|
+
*
|
|
14
|
+
* What it counts is the PROCESS, not the call — everything running while the block runs.
|
|
15
|
+
*/
|
|
16
|
+
export declare function statementsOf(run: () => Promise<unknown>): Promise<QueryEvent[]>;
|
|
17
|
+
//# sourceMappingURL=statements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../src/statements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAYrF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every statement a call ran, in order.
|
|
3
|
+
*
|
|
4
|
+
* `testApp` boots on real SQLite, so this is what the handler actually asked the database —
|
|
5
|
+
* one per row is the shape of an N+1, and it is a number a test can refuse. A computed field
|
|
6
|
+
* that reads is the case: the façade hands the presenter the whole PAGE, so one query is
|
|
7
|
+
* possible, and nothing refuses `Promise.all(rows.map(…))` inside the field body.
|
|
8
|
+
*
|
|
9
|
+
* It REFUSES when `@fougere/adapter-sql` is absent, where the tracer degrades quietly: zero
|
|
10
|
+
* is what a passing assertion looks like, so an app observing nothing would turn this into a
|
|
11
|
+
* test that cannot fail.
|
|
12
|
+
*
|
|
13
|
+
* What it counts is the PROCESS, not the call — everything running while the block runs.
|
|
14
|
+
*/
|
|
15
|
+
export async function statementsOf(run) {
|
|
16
|
+
const { onQuery } = await sql();
|
|
17
|
+
const ran = [];
|
|
18
|
+
const stop = onQuery((event) => ran.push(event));
|
|
19
|
+
try {
|
|
20
|
+
await run();
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
stop();
|
|
24
|
+
}
|
|
25
|
+
return ran;
|
|
26
|
+
}
|
|
27
|
+
/** Optional, and dynamic for the reason `@fougere/calls` states: this package depends on none. */
|
|
28
|
+
async function sql() {
|
|
29
|
+
try {
|
|
30
|
+
return await import('@fougere/adapter-sql');
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new Error('[statementsOf] counting statements needs @fougere/adapter-sql — install it, '
|
|
34
|
+
+ 'or the count is zero whatever the handler ran.');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=statements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statements.js","sourceRoot":"","sources":["../src/statements.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAA2B;IAC5D,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,GAAG,EAAE,CAAC;IAChC,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,GAAG,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,IAAI,EAAE,CAAC;IACT,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,kGAAkG;AAClG,KAAK,UAAU,GAAG;IAChB,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,8EAA8E;cAC5E,gDAAgD,CACnD,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Port.d.ts","sourceRoot":"","sources":["../../src/stub/Port.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,MAAM,IAAI,GAAG,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Port.js","sourceRoot":"","sources":["../../src/stub/Port.ts"],"names":[],"mappings":""}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type Mock } from 'vitest';
|
|
2
2
|
import type { App } from '@fougere/core';
|
|
3
|
-
|
|
4
|
-
export type Port = abstract new (...args: never[]) => unknown;
|
|
3
|
+
import type { Port } from './Port.js';
|
|
5
4
|
/** The double handed in place of a port — one spy per method the port declares. */
|
|
6
5
|
export type Stub<T> = {
|
|
7
6
|
[K in keyof T]: T[K] extends (...args: never[]) => unknown ? Mock : T[K];
|
|
@@ -12,4 +11,4 @@ export declare function methodsOf(port: Port): string[];
|
|
|
12
11
|
export declare function stubOf<T>(port: Port): Stub<T>;
|
|
13
12
|
/** Put doubles in front of ports, in every frond scope that answers under their name. */
|
|
14
13
|
export declare function installStubs(app: App, ports: Port[]): Map<Port, Stub<unknown>>;
|
|
15
|
-
//# sourceMappingURL=
|
|
14
|
+
//# sourceMappingURL=Stub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Stub.d.ts","sourceRoot":"","sources":["../../src/stub/Stub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAM,KAAK,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,mFAAmF;AACnF,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAEnG,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAY9C;AAED,2BAA2B;AAC3B,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAI7C;AAED,yFAAyF;AACzF,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAiB9E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Stub.js","sourceRoot":"","sources":["../../src/stub/Stub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAa,MAAM,QAAQ,CAAC;AAQvC,6EAA6E;AAC7E,MAAM,UAAU,SAAS,CAAC,IAAU;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,IAAI,KAAK,GAAkB,IAAI,CAAC,SAAmB,CAAC;IACpD,OAAO,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,IAAI,IAAI,KAAK,aAAa;gBAAE,SAAS;YACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC9D,IAAI,OAAO,QAAQ,EAAE,KAAK,KAAK,UAAU;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC;QACD,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAkB,CAAC;IACxD,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,MAAM,CAAI,IAAU;IAClC,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC;QAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;IAC/D,OAAO,MAAiB,CAAC;AAC3B,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,YAAY,CAAC,GAAQ,EAAE,KAAa;IAClD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC/C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAY,SAAS,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAExF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,CAAC,IAAI,mDAAmD;kBACpE,sFAAsF,CACzF,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,SAAS;YAAE,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { type Change, type SchemaDescriptor } from '@fougere/schema';
|
|
2
2
|
import type { IdentityCard } from '@fougere/core';
|
|
3
|
-
|
|
4
|
-
export interface SyncedRemote {
|
|
5
|
-
name: string;
|
|
6
|
-
url: string;
|
|
7
|
-
/** Where the synced classes were written. */
|
|
8
|
-
path: string;
|
|
9
|
-
}
|
|
3
|
+
import type { SyncedRemote } from './SyncedRemote.js';
|
|
10
4
|
/** What separates a consumer's synced copy from what the producer serves today. */
|
|
11
5
|
export interface SyncDrift {
|
|
12
6
|
frond: string;
|
|
@@ -18,12 +12,10 @@ export interface SyncDrift {
|
|
|
18
12
|
changes: Change[];
|
|
19
13
|
}[];
|
|
20
14
|
}
|
|
21
|
-
/** The remotes a project synced, read from the file `fougere sync` writes. */
|
|
22
|
-
export declare function syncedRemotes(root: string): Promise<SyncedRemote[]>;
|
|
23
15
|
/** The shapes a consumer holds for one remote frond. */
|
|
24
16
|
export declare function heldShapes(remote: SyncedRemote): Promise<Map<string, SchemaDescriptor>>;
|
|
25
17
|
/** What the consumer's copy no longer matches. */
|
|
26
18
|
export declare function syncDriftOf(held: Map<string, SchemaDescriptor>, card: IdentityCard, frond: string): SyncDrift;
|
|
27
19
|
/** Whether the copy still matches. */
|
|
28
20
|
export declare function inSync(drift: SyncDrift): boolean;
|
|
29
|
-
//# sourceMappingURL=
|
|
21
|
+
//# sourceMappingURL=SyncDrift.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyncDrift.d.ts","sourceRoot":"","sources":["../../src/sync/SyncDrift.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,KAAK,MAAM,EAAE,KAAK,gBAAgB,EAAmB,MAAM,iBAAiB,CAAC;AAC5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gEAAgE;IAChE,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;CAChD;AAED,wDAAwD;AACxD,wBAAsB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAW7F;AAYD,kDAAkD;AAClD,wBAAgB,WAAW,CACzB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACnC,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,GACZ,SAAS,CAWX;AAED,sCAAsC;AACtC,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAEhD"}
|
|
@@ -1,19 +1,6 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
2
1
|
import { join } from 'node:path';
|
|
3
2
|
import { pathToFileURL } from 'node:url';
|
|
4
3
|
import { Card } from '@fougere/schema';
|
|
5
|
-
/** The remotes a project synced, read from the file `fougere sync` writes. */
|
|
6
|
-
export async function syncedRemotes(root) {
|
|
7
|
-
try {
|
|
8
|
-
const raw = await readFile(join(root, '.fougere', 'remotes.json'), 'utf8');
|
|
9
|
-
const parsed = JSON.parse(raw);
|
|
10
|
-
return Object.entries(parsed).map(([name, one]) => ({ name, ...one }));
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
// No file is the ordinary case: an app with no remote synced nothing.
|
|
14
|
-
return [];
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
4
|
/** The shapes a consumer holds for one remote frond. */
|
|
18
5
|
export async function heldShapes(remote) {
|
|
19
6
|
const cards = new Map();
|
|
@@ -27,15 +14,15 @@ export async function heldShapes(remote) {
|
|
|
27
14
|
}
|
|
28
15
|
return cards;
|
|
29
16
|
}
|
|
30
|
-
/** The shapes a card announces, by the name a
|
|
17
|
+
/** The shapes a card announces, by the name a facade carries. */
|
|
31
18
|
function servedShapes(card, frond) {
|
|
32
19
|
const served = new Map();
|
|
33
20
|
for (const one of card.fronds) {
|
|
34
21
|
if (one.name !== frond)
|
|
35
22
|
continue;
|
|
36
|
-
for (const
|
|
37
|
-
if (
|
|
38
|
-
served.set(
|
|
23
|
+
for (const facade of one.facades)
|
|
24
|
+
if (facade.schema)
|
|
25
|
+
served.set(facade.schema.title ?? facade.name, facade.schema);
|
|
39
26
|
}
|
|
40
27
|
return served;
|
|
41
28
|
}
|
|
@@ -59,4 +46,4 @@ export function syncDriftOf(held, card, frond) {
|
|
|
59
46
|
export function inSync(drift) {
|
|
60
47
|
return drift.gone.length === 0 && drift.moved.length === 0;
|
|
61
48
|
}
|
|
62
|
-
//# sourceMappingURL=
|
|
49
|
+
//# sourceMappingURL=SyncDrift.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyncDrift.js","sourceRoot":"","sources":["../../src/sync/SyncDrift.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAuD,MAAM,iBAAiB,CAAC;AAa5F,wDAAwD;AACxD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAoB;IACnD,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAC;IAClD,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAA4B,CAAC;IAE9D,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,MAAM,MAAM,GAAG,QAAkC,CAAC;QAClD,IAAI,OAAO,MAAM,KAAK,UAAU,IAAI,OAAQ,MAAqB,CAAC,SAAS,KAAK,UAAU;YAAE,SAAS;QACrG,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iEAAiE;AACjE,SAAS,YAAY,CAAC,IAAkB,EAAE,KAAa;IACrD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;YAAE,SAAS;QACjC,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO;YAAE,IAAI,MAAM,CAAC,MAAM;gBAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACrH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,WAAW,CACzB,IAAmC,EACnC,IAAkB,EAClB,KAAa;IAEb,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,KAAK,GAAc,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAExD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,EAAE,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAA0B,CAAC,CAAC,CAAC;QAC9F,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,MAAM,CAAC,KAAgB;IACrC,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** One entry of `.fougere/remotes.json`, written by `fougere sync`. */
|
|
2
|
+
export interface SyncedRemote {
|
|
3
|
+
name: string;
|
|
4
|
+
url: string;
|
|
5
|
+
/** Where the synced classes were written. */
|
|
6
|
+
path: string;
|
|
7
|
+
}
|
|
8
|
+
/** The remotes a project synced, read from the file `fougere sync` writes. */
|
|
9
|
+
export declare function syncedRemotes(root: string): Promise<SyncedRemote[]>;
|
|
10
|
+
//# sourceMappingURL=SyncedRemote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyncedRemote.d.ts","sourceRoot":"","sources":["../../src/sync/SyncedRemote.ts"],"names":[],"mappings":"AAGA,uEAAuE;AACvE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,8EAA8E;AAC9E,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CASzE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/** The remotes a project synced, read from the file `fougere sync` writes. */
|
|
4
|
+
export async function syncedRemotes(root) {
|
|
5
|
+
try {
|
|
6
|
+
const raw = await readFile(join(root, '.fougere', 'remotes.json'), 'utf8');
|
|
7
|
+
const parsed = JSON.parse(raw);
|
|
8
|
+
return Object.entries(parsed).map(([name, one]) => ({ name, ...one }));
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
// No file is the ordinary case: an app with no remote synced nothing.
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=SyncedRemote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyncedRemote.js","sourceRoot":"","sources":["../../src/sync/SyncedRemote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAUjC,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkD,CAAC;QAChF,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;QACtE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
package/dist/vitest.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../src/vitest.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../src/vitest.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6B5F"}
|
package/dist/vitest.js
CHANGED
|
@@ -16,6 +16,10 @@ export function fougereTest(overrides = {}) {
|
|
|
16
16
|
// the fronds when it is about several of them.
|
|
17
17
|
include: ['tests/**/*.test.ts', 'fronds/*/tests/**/*.test.ts'],
|
|
18
18
|
server: { deps: { inline: [/@fougere\//, '@pothos/core'] } },
|
|
19
|
+
// A Fougere test boots an app, and a boot runs the scan — a tsc program over the
|
|
20
|
+
// project. Vitest's 5s default times that out on a cold machine, which three
|
|
21
|
+
// packages had each discovered and patched on their own.
|
|
22
|
+
testTimeout: 20_000,
|
|
19
23
|
},
|
|
20
24
|
};
|
|
21
25
|
return {
|
package/dist/vitest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vitest.js","sourceRoot":"","sources":["../src/vitest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,sFAAsF;AACtF,MAAM,UAAU,WAAW,CAAC,SAAS,GAA4B,EAAE;IACjE,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,UAA8B,CAAC;IACnC,IAAI,CAAC;QACH,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;IAED,MAAM,IAAI,GAAG;QACX,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,IAAI,EAAE;YACJ,gFAAgF;YAChF,+CAA+C;YAC/C,OAAO,EAAE,CAAC,oBAAoB,EAAE,6BAA6B,CAAC;YAC9D,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,YAAY,EAAE,cAAc,CAAC,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"vitest.js","sourceRoot":"","sources":["../src/vitest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,sFAAsF;AACtF,MAAM,UAAU,WAAW,CAAC,SAAS,GAA4B,EAAE;IACjE,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,UAA8B,CAAC;IACnC,IAAI,CAAC;QACH,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;IAED,MAAM,IAAI,GAAG;QACX,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,IAAI,EAAE;YACJ,gFAAgF;YAChF,+CAA+C;YAC/C,OAAO,EAAE,CAAC,oBAAoB,EAAE,6BAA6B,CAAC;YAC9D,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,YAAY,EAAE,cAAc,CAAC,EAAE,EAAE;YAC5D,iFAAiF;YACjF,6EAA6E;YAC7E,yDAAyD;YACzD,WAAW,EAAE,MAAM;SACpB;KACF,CAAC;IAEF,OAAO;QACL,GAAG,IAAI;QACP,GAAG,SAAS;QACZ,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,OAAiB,IAAI,EAAE,CAAC,EAAE;QACpE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,CAAC,IAAc,IAAI,EAAE,CAAC,EAAE;KAC5D,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fougere/testing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0-alpha.0",
|
|
4
4
|
"description": "Tests derived from the declaration — cases, stubs and a gradient of realities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fougere",
|
|
@@ -34,20 +34,22 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"json-schema-faker": "^0.6.3",
|
|
37
|
-
"@fougere/core": "0.
|
|
38
|
-
"@fougere/
|
|
39
|
-
"@fougere/schema": "0.
|
|
40
|
-
"@fougere/app": "0.
|
|
41
|
-
"@fougere/
|
|
42
|
-
"@fougere/
|
|
43
|
-
"@fougere/
|
|
37
|
+
"@fougere/core": "0.10.0-alpha.0",
|
|
38
|
+
"@fougere/transport-http": "0.10.0-alpha.0",
|
|
39
|
+
"@fougere/schema": "0.10.0-alpha.0",
|
|
40
|
+
"@fougere/app": "0.10.0-alpha.0",
|
|
41
|
+
"@fougere/container": "0.10.0-alpha.0",
|
|
42
|
+
"@fougere/defaults": "0.10.0-alpha.0",
|
|
43
|
+
"@fougere/compiler": "0.10.0-alpha.0"
|
|
44
44
|
},
|
|
45
45
|
"publishConfig": {
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"vitest": ">=2",
|
|
50
|
-
"@fougere/adapter-graphql": "0.
|
|
50
|
+
"@fougere/adapter-graphql": "0.10.0-alpha.0",
|
|
51
|
+
"@fougere/observability": "0.10.0-alpha.0",
|
|
52
|
+
"@fougere/adapter-sql": "0.10.0-alpha.0"
|
|
51
53
|
},
|
|
52
54
|
"peerDependenciesMeta": {
|
|
53
55
|
"vitest": {
|
|
@@ -55,11 +57,19 @@
|
|
|
55
57
|
},
|
|
56
58
|
"@fougere/adapter-graphql": {
|
|
57
59
|
"optional": true
|
|
60
|
+
},
|
|
61
|
+
"@fougere/adapter-sql": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"@fougere/observability": {
|
|
65
|
+
"optional": true
|
|
58
66
|
}
|
|
59
67
|
},
|
|
60
68
|
"devDependencies": {
|
|
61
69
|
"vitest": "^4.1.0",
|
|
62
|
-
"@fougere/adapter-
|
|
70
|
+
"@fougere/adapter-sql": "0.10.0-alpha.0",
|
|
71
|
+
"@fougere/adapter-graphql": "0.10.0-alpha.0",
|
|
72
|
+
"@fougere/observability": "0.10.0-alpha.0"
|
|
63
73
|
},
|
|
64
74
|
"scripts": {
|
|
65
75
|
"build": "rm -rf dist && tsc",
|