Initial Sample.

This commit is contained in:
2024-06-03 20:23:50 +05:30
parent ef2b65f673
commit 5269ec3c66
2575 changed files with 282312 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
import type { Observable } from "../../utilities/index.js";
interface TakeOptions {
timeout?: number;
}
type ObservableEvent<T> = {
type: "next";
value: T;
} | {
type: "error";
error: any;
} | {
type: "complete";
};
declare class IteratorStream<T> {
private iterator;
constructor(iterator: AsyncGenerator<T, void, unknown>);
take({ timeout }?: TakeOptions): Promise<T>;
}
export declare class ObservableStream<T> extends IteratorStream<ObservableEvent<T>> {
constructor(observable: Observable<T>);
takeNext(options?: TakeOptions): Promise<T>;
takeError(options?: TakeOptions): Promise<any>;
takeComplete(options?: TakeOptions): Promise<void>;
}
export {};
//# sourceMappingURL=ObservableStream.d.ts.map

View File

@@ -0,0 +1,109 @@
import { __asyncGenerator, __await, __awaiter, __extends, __generator } from "tslib";
function observableToAsyncEventIterator(observable) {
return __asyncGenerator(this, arguments, function observableToAsyncEventIterator_1() {
function queuePromise() {
promises.push(new Promise(function (resolve) {
resolveNext = function (event) {
resolve(event);
queuePromise();
};
}));
}
var resolveNext, promises;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
promises = [];
queuePromise();
observable.subscribe(function (value) { return resolveNext({ type: "next", value: value }); }, function (error) { return resolveNext({ type: "error", error: error }); }, function () { return resolveNext({ type: "complete" }); });
return [4 /*yield*/, __await("initialization value")];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
_a.sent();
_a.label = 3;
case 3:
if (!true) return [3 /*break*/, 6];
return [4 /*yield*/, __await(promises.shift())];
case 4: return [4 /*yield*/, _a.sent()];
case 5:
_a.sent();
return [3 /*break*/, 3];
case 6: return [2 /*return*/];
}
});
});
}
var IteratorStream = /** @class */ (function () {
function IteratorStream(iterator) {
this.iterator = iterator;
}
IteratorStream.prototype.take = function (_a) {
var _b = _a === void 0 ? {} : _a, _c = _b.timeout, timeout = _c === void 0 ? 100 : _c;
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_d) {
return [2 /*return*/, Promise.race([
this.iterator.next().then(function (result) { return result.value; }),
new Promise(function (_, reject) {
setTimeout(reject, timeout, new Error("Timeout waiting for next event"));
}),
])];
});
});
};
return IteratorStream;
}());
var ObservableStream = /** @class */ (function (_super) {
__extends(ObservableStream, _super);
function ObservableStream(observable) {
var iterator = observableToAsyncEventIterator(observable);
// we need to call next() once to start the generator so we immediately subscribe.
// the first value is always "initialization value" which we don't care about
iterator.next();
return _super.call(this, iterator) || this;
}
ObservableStream.prototype.takeNext = function (options) {
return __awaiter(this, void 0, void 0, function () {
var event;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.take(options)];
case 1:
event = _a.sent();
expect(event).toEqual({ type: "next", value: expect.anything() });
return [2 /*return*/, event.value];
}
});
});
};
ObservableStream.prototype.takeError = function (options) {
return __awaiter(this, void 0, void 0, function () {
var event;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.take(options)];
case 1:
event = _a.sent();
expect(event).toEqual({ type: "error", error: expect.anything() });
return [2 /*return*/, event.error];
}
});
});
};
ObservableStream.prototype.takeComplete = function (options) {
return __awaiter(this, void 0, void 0, function () {
var event;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.take(options)];
case 1:
event = _a.sent();
expect(event).toEqual({ type: "complete" });
return [2 /*return*/];
}
});
});
};
return ObservableStream;
}(IteratorStream));
export { ObservableStream };
//# sourceMappingURL=ObservableStream.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ObservableStream.js","sourceRoot":"","sources":["../../../src/testing/internal/ObservableStream.ts"],"names":[],"mappings":";AAUA,SAAgB,8BAA8B,CAAI,UAAyB;;QAKzE,SAAS,YAAY;YACnB,QAAQ,CAAC,IAAI,CACX,IAAI,OAAO,CAAqB,UAAC,OAAO;gBACtC,WAAW,GAAG,UAAC,KAAyB;oBACtC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACf,YAAY,EAAE,CAAC;gBACjB,CAAC,CAAC;YACJ,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;;;;;oBAZK,QAAQ,GAAkC,EAAE,CAAC;oBACnD,YAAY,EAAE,CAAC;oBAaf,UAAU,CAAC,SAAS,CAClB,UAAC,KAAK,IAAK,OAAA,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAA,EAAE,CAAC,EAApC,CAAoC,EAC/C,UAAC,KAAK,IAAK,OAAA,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,OAAA,EAAE,CAAC,EAArC,CAAqC,EAChD,cAAM,OAAA,WAAW,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAjC,CAAiC,CACxC,CAAC;iDACI,sBAAgE;wBAAtE,gCAAsE;;oBAAtE,SAAsE,CAAC;;;yBAEhE,IAAI;iDACH,QAAQ,CAAC,KAAK,EAAG;wBAAvB,gCAAuB;;oBAAvB,SAAuB,CAAC;;;;;;CAE3B;AAED;IACE,wBAAoB,QAA0C;QAA1C,aAAQ,GAAR,QAAQ,CAAkC;IAAG,CAAC;IAE5D,6BAAI,GAAV,UAAW,EAAmC;YAAnC,qBAAiC,EAAE,KAAA,EAAjC,eAAa,EAAb,OAAO,mBAAG,GAAG,KAAA;;;gBACxB,sBAAO,OAAO,CAAC,IAAI,CAAC;wBAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,CAAC,KAAM,EAAb,CAAa,CAAC;wBACpD,IAAI,OAAO,CAAI,UAAC,CAAC,EAAE,MAAM;4BACvB,UAAU,CACR,MAAM,EACN,OAAO,EACP,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAC5C,CAAC;wBACJ,CAAC,CAAC;qBACH,CAAC,EAAC;;;KACJ;IACH,qBAAC;AAAD,CAAC,AAfD,IAeC;AAED;IAAyC,oCAAkC;IACzE,0BAAY,UAAyB;QACnC,IAAM,QAAQ,GAAG,8BAA8B,CAAC,UAAU,CAAC,CAAC;QAC5D,kFAAkF;QAClF,6EAA6E;QAC7E,QAAQ,CAAC,IAAI,EAAE,CAAC;QAChB,OAAA,MAAK,YAAC,QAAQ,CAAC,SAAC;IAClB,CAAC;IAEK,mCAAQ,GAAd,UAAe,OAAqB;;;;;4BACpB,qBAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAA;;wBAAhC,KAAK,GAAG,SAAwB;wBACtC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;wBAClE,sBAAQ,KAA+C,CAAC,KAAK,EAAC;;;;KAC/D;IAEK,oCAAS,GAAf,UAAgB,OAAqB;;;;;4BACrB,qBAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAA;;wBAAhC,KAAK,GAAG,SAAwB;wBACtC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;wBACnE,sBAAQ,KAAgD,CAAC,KAAK,EAAC;;;;KAChE;IAEK,uCAAY,GAAlB,UAAmB,OAAqB;;;;;4BACxB,qBAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAA;;wBAAhC,KAAK,GAAG,SAAwB;wBACtC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;;;;;KAC7C;IACH,uBAAC;AAAD,CAAC,AAzBD,CAAyC,cAAc,GAyBtD","sourcesContent":["import type { Observable } from \"../../utilities/index.js\";\n\ninterface TakeOptions {\n timeout?: number;\n}\ntype ObservableEvent<T> =\n | { type: \"next\"; value: T }\n | { type: \"error\"; error: any }\n | { type: \"complete\" };\n\nasync function* observableToAsyncEventIterator<T>(observable: Observable<T>) {\n let resolveNext: (value: ObservableEvent<T>) => void;\n const promises: Promise<ObservableEvent<T>>[] = [];\n queuePromise();\n\n function queuePromise() {\n promises.push(\n new Promise<ObservableEvent<T>>((resolve) => {\n resolveNext = (event: ObservableEvent<T>) => {\n resolve(event);\n queuePromise();\n };\n })\n );\n }\n\n observable.subscribe(\n (value) => resolveNext({ type: \"next\", value }),\n (error) => resolveNext({ type: \"error\", error }),\n () => resolveNext({ type: \"complete\" })\n );\n yield \"initialization value\" as unknown as Promise<ObservableEvent<T>>;\n\n while (true) {\n yield promises.shift()!;\n }\n}\n\nclass IteratorStream<T> {\n constructor(private iterator: AsyncGenerator<T, void, unknown>) {}\n\n async take({ timeout = 100 }: TakeOptions = {}): Promise<T> {\n return Promise.race([\n this.iterator.next().then((result) => result.value!),\n new Promise<T>((_, reject) => {\n setTimeout(\n reject,\n timeout,\n new Error(\"Timeout waiting for next event\")\n );\n }),\n ]);\n }\n}\n\nexport class ObservableStream<T> extends IteratorStream<ObservableEvent<T>> {\n constructor(observable: Observable<T>) {\n const iterator = observableToAsyncEventIterator(observable);\n // we need to call next() once to start the generator so we immediately subscribe.\n // the first value is always \"initialization value\" which we don't care about\n iterator.next();\n super(iterator);\n }\n\n async takeNext(options?: TakeOptions): Promise<T> {\n const event = await this.take(options);\n expect(event).toEqual({ type: \"next\", value: expect.anything() });\n return (event as ObservableEvent<T> & { type: \"next\" }).value;\n }\n\n async takeError(options?: TakeOptions): Promise<any> {\n const event = await this.take(options);\n expect(event).toEqual({ type: \"error\", error: expect.anything() });\n return (event as ObservableEvent<T> & { type: \"error\" }).error;\n }\n\n async takeComplete(options?: TakeOptions): Promise<void> {\n const event = await this.take(options);\n expect(event).toEqual({ type: \"complete\" });\n }\n}\n"]}

View File

@@ -0,0 +1,10 @@
/// <reference types="node" />
/**
* Temporarily disable act warnings.
*
* https://github.com/reactwg/react-18/discussions/102
*/
export declare function disableActWarnings(): {
prevActEnv: any;
} & Disposable;
//# sourceMappingURL=disableActWarnings.d.ts.map

View File

@@ -0,0 +1,15 @@
import { withCleanup } from "./withCleanup.js";
/**
* Temporarily disable act warnings.
*
* https://github.com/reactwg/react-18/discussions/102
*/
export function disableActWarnings() {
var prev = { prevActEnv: globalThis.IS_REACT_ACT_ENVIRONMENT };
globalThis.IS_REACT_ACT_ENVIRONMENT = false;
return withCleanup(prev, function (_a) {
var prevActEnv = _a.prevActEnv;
globalThis.IS_REACT_ACT_ENVIRONMENT = prevActEnv;
});
}
//# sourceMappingURL=disableActWarnings.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"disableActWarnings.js","sourceRoot":"","sources":["../../../../src/testing/internal/disposables/disableActWarnings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAM,IAAI,GAAG,EAAE,UAAU,EAAG,UAAkB,CAAC,wBAAwB,EAAE,CAAC;IACzE,UAAkB,CAAC,wBAAwB,GAAG,KAAK,CAAC;IAErD,OAAO,WAAW,CAAC,IAAI,EAAE,UAAC,EAAc;YAAZ,UAAU,gBAAA;QACnC,UAAkB,CAAC,wBAAwB,GAAG,UAAU,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { withCleanup } from \"./withCleanup.js\";\n\n/**\n * Temporarily disable act warnings.\n *\n * https://github.com/reactwg/react-18/discussions/102\n */\nexport function disableActWarnings() {\n const prev = { prevActEnv: (globalThis as any).IS_REACT_ACT_ENVIRONMENT };\n (globalThis as any).IS_REACT_ACT_ENVIRONMENT = false;\n\n return withCleanup(prev, ({ prevActEnv }) => {\n (globalThis as any).IS_REACT_ACT_ENVIRONMENT = prevActEnv;\n });\n}\n"]}

View File

@@ -0,0 +1,4 @@
export { disableActWarnings } from "./disableActWarnings.js";
export { spyOnConsole } from "./spyOnConsole.js";
export { withCleanup } from "./withCleanup.js";
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,4 @@
export { disableActWarnings } from "./disableActWarnings.js";
export { spyOnConsole } from "./spyOnConsole.js";
export { withCleanup } from "./withCleanup.js";
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/testing/internal/disposables/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["export { disableActWarnings } from \"./disableActWarnings.js\";\nexport { spyOnConsole } from \"./spyOnConsole.js\";\nexport { withCleanup } from \"./withCleanup.js\";\n"]}

View File

@@ -0,0 +1,11 @@
/// <reference types="node" />
/// <reference types="jest" />
type ConsoleMethod = "log" | "info" | "warn" | "error" | "debug";
type Spies<Keys extends ConsoleMethod[]> = Record<Keys[number], jest.SpyInstance<void, any[], any>>;
/** @internal */
export declare function spyOnConsole<Keys extends ConsoleMethod[]>(...spyOn: Keys): Spies<Keys> & Disposable;
export declare namespace spyOnConsole {
var takeSnapshots: <Keys extends ConsoleMethod[]>(...spyOn: Keys) => Spies<Keys> & Disposable;
}
export {};
//# sourceMappingURL=spyOnConsole.d.ts.map

View File

@@ -0,0 +1,35 @@
import { withCleanup } from "./withCleanup.js";
var noOp = function () { };
var restore = function (spy) { return spy.mockRestore(); };
/** @internal */
export function spyOnConsole() {
var spyOn = [];
for (var _i = 0; _i < arguments.length; _i++) {
spyOn[_i] = arguments[_i];
}
var spies = {};
for (var _a = 0, spyOn_1 = spyOn; _a < spyOn_1.length; _a++) {
var key = spyOn_1[_a];
// @ts-ignore
spies[key] = jest.spyOn(console, key).mockImplementation(noOp);
}
return withCleanup(spies, function (spies) {
for (var _i = 0, _a = Object.values(spies); _i < _a.length; _i++) {
var spy = _a[_i];
restore(spy);
}
});
}
spyOnConsole.takeSnapshots = function () {
var spyOn = [];
for (var _i = 0; _i < arguments.length; _i++) {
spyOn[_i] = arguments[_i];
}
return withCleanup(spyOnConsole.apply(void 0, spyOn), function (spies) {
for (var _i = 0, _a = Object.values(spies); _i < _a.length; _i++) {
var spy = _a[_i];
expect(spy).toMatchSnapshot();
}
});
};
//# sourceMappingURL=spyOnConsole.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"spyOnConsole.js","sourceRoot":"","sources":["../../../../src/testing/internal/disposables/spyOnConsole.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,IAAM,IAAI,GAAG,cAAO,CAAC,CAAC;AACtB,IAAM,OAAO,GAAG,UAAC,GAAqB,IAAK,OAAA,GAAG,CAAC,WAAW,EAAE,EAAjB,CAAiB,CAAC;AAS7D,gBAAgB;AAChB,MAAM,UAAU,YAAY;IAC1B,eAAc;SAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;QAAd,0BAAc;;IAEd,IAAM,KAAK,GAAG,EAAiB,CAAC;IAChC,KAAkB,UAAK,EAAL,eAAK,EAAL,mBAAK,EAAL,IAAK,EAAE,CAAC;QAArB,IAAM,GAAG,cAAA;QACZ,aAAa;QACb,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,WAAW,CAAC,KAAK,EAAE,UAAC,KAAK;QAC9B,KAAkB,UAA0C,EAA1C,KAAA,MAAM,CAAC,MAAM,CAAC,KAAK,CAAuB,EAA1C,cAA0C,EAA1C,IAA0C,EAAE,CAAC;YAA1D,IAAM,GAAG,SAAA;YACZ,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,YAAY,CAAC,aAAa,GAAG;IAC3B,eAAc;SAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;QAAd,0BAAc;;IAEd,OAAA,WAAW,CAAC,YAAY,eAAI,KAAK,GAAG,UAAC,KAAK;QACxC,KAAkB,UAA0C,EAA1C,KAAA,MAAM,CAAC,MAAM,CAAC,KAAK,CAAuB,EAA1C,cAA0C,EAA1C,IAA0C,EAAE,CAAC;YAA1D,IAAM,GAAG,SAAA;YACZ,MAAM,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC;QAChC,CAAC;IACH,CAAC,CAAC;AAJF,CAIE,CAAC","sourcesContent":["import { withCleanup } from \"./withCleanup.js\";\n\nconst noOp = () => {};\nconst restore = (spy: jest.SpyInstance) => spy.mockRestore();\n\ntype ConsoleMethod = \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\";\n\ntype Spies<Keys extends ConsoleMethod[]> = Record<\n Keys[number],\n jest.SpyInstance<void, any[], any>\n>;\n\n/** @internal */\nexport function spyOnConsole<Keys extends ConsoleMethod[]>(\n ...spyOn: Keys\n): Spies<Keys> & Disposable {\n const spies = {} as Spies<Keys>;\n for (const key of spyOn) {\n // @ts-ignore\n spies[key] = jest.spyOn(console, key).mockImplementation(noOp);\n }\n return withCleanup(spies, (spies) => {\n for (const spy of Object.values(spies) as jest.SpyInstance[]) {\n restore(spy);\n }\n });\n}\n\nspyOnConsole.takeSnapshots = <Keys extends ConsoleMethod[]>(\n ...spyOn: Keys\n): Spies<Keys> & Disposable =>\n withCleanup(spyOnConsole(...spyOn), (spies) => {\n for (const spy of Object.values(spies) as jest.SpyInstance[]) {\n expect(spy).toMatchSnapshot();\n }\n });\n"]}

View File

@@ -0,0 +1,4 @@
/// <reference types="node" />
/** @internal */
export declare function withCleanup<T extends object>(item: T, cleanup: (item: T) => void): T & Disposable;
//# sourceMappingURL=withCleanup.d.ts.map

View File

@@ -0,0 +1,14 @@
import { __assign } from "tslib";
/** @internal */
export function withCleanup(item, cleanup) {
var _a;
return __assign(__assign({}, item), (_a = {}, _a[Symbol.dispose] = function () {
cleanup(item);
// if `item` already has a cleanup function, we also need to call the original cleanup function
// (e.g. if something is wrapped in `withCleanup` twice)
if (Symbol.dispose in item) {
item[Symbol.dispose]();
}
}, _a));
}
//# sourceMappingURL=withCleanup.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"withCleanup.js","sourceRoot":"","sources":["../../../../src/testing/internal/disposables/withCleanup.ts"],"names":[],"mappings":";AAAA,gBAAgB;AAChB,MAAM,UAAU,WAAW,CACzB,IAAO,EACP,OAA0B;;IAE1B,6BACK,IAAI,aACP,GAAC,MAAM,CAAC,OAAO,IAAf;QACE,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,+FAA+F;QAC/F,wDAAwD;QACxD,IAAI,MAAM,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;YAC1B,IAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,CAAC;IACH,CAAC,OACD;AACJ,CAAC","sourcesContent":["/** @internal */\nexport function withCleanup<T extends object>(\n item: T,\n cleanup: (item: T) => void\n): T & Disposable {\n return {\n ...item,\n [Symbol.dispose]() {\n cleanup(item);\n // if `item` already has a cleanup function, we also need to call the original cleanup function\n // (e.g. if something is wrapped in `withCleanup` twice)\n if (Symbol.dispose in item) {\n (item as Disposable)[Symbol.dispose]();\n }\n },\n };\n}\n"]}

View File

@@ -0,0 +1,8 @@
export * from "./profile/index.js";
export * from "./disposables/index.js";
export { ObservableStream } from "./ObservableStream.js";
export type { SimpleCaseData, PaginatedCaseData, PaginatedCaseVariables, VariablesCaseData, VariablesCaseVariables, } from "./scenarios/index.js";
export { setupSimpleCase, setupVariablesCase, setupPaginatedCase, } from "./scenarios/index.js";
export type { RenderWithClientOptions, RenderWithMocksOptions, } from "./renderHelpers.js";
export { renderWithClient, renderWithMocks } from "./renderHelpers.js";
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,6 @@
export * from "./profile/index.js";
export * from "./disposables/index.js";
export { ObservableStream } from "./ObservableStream.js";
export { setupSimpleCase, setupVariablesCase, setupPaginatedCase, } from "./scenarios/index.js";
export { renderWithClient, renderWithMocks } from "./renderHelpers.js";
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AASzD,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export * from \"./profile/index.js\";\nexport * from \"./disposables/index.js\";\nexport { ObservableStream } from \"./ObservableStream.js\";\n\nexport type {\n SimpleCaseData,\n PaginatedCaseData,\n PaginatedCaseVariables,\n VariablesCaseData,\n VariablesCaseVariables,\n} from \"./scenarios/index.js\";\nexport {\n setupSimpleCase,\n setupVariablesCase,\n setupPaginatedCase,\n} from \"./scenarios/index.js\";\n\nexport type {\n RenderWithClientOptions,\n RenderWithMocksOptions,\n} from \"./renderHelpers.js\";\nexport { renderWithClient, renderWithMocks } from \"./renderHelpers.js\";\n"]}

View File

@@ -0,0 +1,171 @@
/// <reference types="react" />
import { screen } from "@testing-library/dom";
/** @internal */
export interface BaseRender {
id: string;
phase: "mount" | "update" | "nested-update";
actualDuration: number;
baseDuration: number;
startTime: number;
commitTime: number;
/**
* The number of renders that have happened so far (including this render).
*/
count: number;
}
type Screen = typeof screen;
/** @internal */
export type SyncScreen = {
[K in keyof Screen]: K extends `find${string}` ? {
/** @deprecated A snapshot is static, so avoid async queries! */
(...args: Parameters<Screen[K]>): ReturnType<Screen[K]>;
} : Screen[K];
};
/** @internal */
export interface Render<Snapshot> extends BaseRender {
/**
* The snapshot, as returned by the `takeSnapshot` option of `profile`.
* (If using `profileHook`, this is the return value of the hook.)
*/
snapshot: Snapshot;
/**
* A DOM snapshot of the rendered component, if the `snapshotDOM`
* option of `profile` was enabled.
*/
readonly domSnapshot: HTMLElement;
/**
* Returns a callback to receive a `screen` instance that is scoped to the
* DOM snapshot of this `Render` instance.
* Note: this is used as a callback to prevent linter errors.
* @example
* ```diff
* const { withinDOM } = RenderedComponent.takeRender();
* -expect(screen.getByText("foo")).toBeInTheDocument();
* +expect(withinDOM().getByText("foo")).toBeInTheDocument();
* ```
*/
withinDOM: () => SyncScreen;
renderedComponents: Array<string | React.ComponentType>;
}
/** @internal */
export declare class RenderInstance<Snapshot> implements Render<Snapshot> {
snapshot: Snapshot;
private stringifiedDOM;
renderedComponents: Array<string | React.ComponentType>;
id: string;
phase: "mount" | "update" | "nested-update";
actualDuration: number;
baseDuration: number;
startTime: number;
commitTime: number;
count: number;
constructor(baseRender: BaseRender, snapshot: Snapshot, stringifiedDOM: string | undefined, renderedComponents: Array<string | React.ComponentType>);
private _domSnapshot;
get domSnapshot(): HTMLElement;
get withinDOM(): () => {
getByLabelText<T extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined): T;
getAllByLabelText<T_1 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined): T_1[];
queryByLabelText<T_2 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined): T_2 | null;
queryAllByLabelText<T_3 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined): T_3[];
findByLabelText<T_4 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_4>;
findAllByLabelText<T_5 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_5[]>;
getByPlaceholderText<T_6 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_6;
getAllByPlaceholderText<T_7 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_7[];
queryByPlaceholderText<T_8 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_8 | null;
queryAllByPlaceholderText<T_9 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_9[];
findByPlaceholderText<T_10 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_10>;
findAllByPlaceholderText<T_11 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_11[]>;
getByText<T_12 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined): T_12;
getAllByText<T_13 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined): T_13[];
queryByText<T_14 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined): T_14 | null;
queryAllByText<T_15 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined): T_15[];
findByText<T_16 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_16>;
findAllByText<T_17 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_17[]>;
getByAltText<T_18 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_18;
getAllByAltText<T_19 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_19[];
queryByAltText<T_20 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_20 | null;
queryAllByAltText<T_21 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_21[];
findByAltText<T_22 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_22>;
findAllByAltText<T_23 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_23[]>;
getByTitle<T_24 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_24;
getAllByTitle<T_25 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_25[];
queryByTitle<T_26 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_26 | null;
queryAllByTitle<T_27 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_27[];
findByTitle<T_28 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_28>;
findAllByTitle<T_29 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_29[]>;
getByDisplayValue<T_30 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_30;
getAllByDisplayValue<T_31 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_31[];
queryByDisplayValue<T_32 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_32 | null;
queryAllByDisplayValue<T_33 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_33[];
findByDisplayValue<T_34 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_34>;
findAllByDisplayValue<T_35 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_35[]>;
getByRole<T_36 extends HTMLElement = HTMLElement>(role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined): T_36;
getAllByRole<T_37 extends HTMLElement = HTMLElement>(role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined): T_37[];
queryByRole<T_38 extends HTMLElement = HTMLElement>(role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined): T_38 | null;
queryAllByRole<T_39 extends HTMLElement = HTMLElement>(role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined): T_39[];
findByRole<T_40 extends HTMLElement = HTMLElement>(role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_40>;
findAllByRole<T_41 extends HTMLElement = HTMLElement>(role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_41[]>;
getByTestId<T_42 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_42;
getAllByTestId<T_43 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_43[];
queryByTestId<T_44 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_44 | null;
queryAllByTestId<T_45 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined): T_45[];
findByTestId<T_46 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_46>;
findAllByTestId<T_47 extends HTMLElement = HTMLElement>(id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined): Promise<T_47[]>;
} & {
getByLabelText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined) => HTMLElement;
getAllByLabelText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined) => HTMLElement[];
queryByLabelText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined) => HTMLElement | null;
queryAllByLabelText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined) => HTMLElement[];
findByLabelText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement>;
findAllByLabelText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement[]>;
getByPlaceholderText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement;
getAllByPlaceholderText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
queryByPlaceholderText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement | null;
queryAllByPlaceholderText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
findByPlaceholderText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement>;
findAllByPlaceholderText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement[]>;
getByText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined) => HTMLElement;
getAllByText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined) => HTMLElement[];
queryByText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined) => HTMLElement | null;
queryAllByText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined) => HTMLElement[];
findByText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement>;
findAllByText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").SelectorMatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement[]>;
getByAltText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement;
getAllByAltText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
queryByAltText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement | null;
queryAllByAltText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
findByAltText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement>;
findAllByAltText: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement[]>;
getByTitle: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement;
getAllByTitle: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
queryByTitle: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement | null;
queryAllByTitle: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
findByTitle: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement>;
findAllByTitle: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement[]>;
getByDisplayValue: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement;
getAllByDisplayValue: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
queryByDisplayValue: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement | null;
queryAllByDisplayValue: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
findByDisplayValue: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement>;
findAllByDisplayValue: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement[]>;
getByRole: (role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined) => HTMLElement;
getAllByRole: (role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined) => HTMLElement[];
queryByRole: (role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined) => HTMLElement | null;
queryAllByRole: (role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined) => HTMLElement[];
findByRole: (role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement>;
findAllByRole: (role: import("@testing-library/dom").ByRoleMatcher, options?: import("@testing-library/dom").ByRoleOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement[]>;
getByTestId: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement;
getAllByTestId: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
queryByTestId: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement | null;
queryAllByTestId: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined) => HTMLElement[];
findByTestId: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement>;
findAllByTestId: (id: import("@testing-library/dom").Matcher, options?: import("@testing-library/dom").MatcherOptions | undefined, waitForElementOptions?: import("@testing-library/dom").waitForOptions | undefined) => Promise<HTMLElement[]>;
} & {
debug: (element?: Element | HTMLDocument | (Element | HTMLDocument)[] | undefined, maxLength?: number | undefined, options?: import("pretty-format").PrettyFormatOptions | undefined) => void;
logTestingPlaygroundURL: (element?: Element | HTMLDocument | undefined) => void;
};
}
/** @internal */
export declare function errorOnDomInteraction(): void;
export {};
//# sourceMappingURL=Render.d.ts.map

View File

@@ -0,0 +1,144 @@
/* istanbul ignore file */
import { __spreadArray } from "tslib";
/*
Something in this file does not compile correctly while measuring code coverage
and will lead to a
Uncaught [ReferenceError: cov_1zb8w312au is not defined]
if we do not ignore this file in code coverage.
As we only use this file in our internal tests, we can safely ignore it.
*/
import { within, screen } from "@testing-library/dom";
import { JSDOM, VirtualConsole } from "jsdom";
import { applyStackTrace, captureStackTrace } from "./traces.js";
/** @internal */
var RenderInstance = /** @class */ (function () {
function RenderInstance(baseRender, snapshot, stringifiedDOM, renderedComponents) {
this.snapshot = snapshot;
this.stringifiedDOM = stringifiedDOM;
this.renderedComponents = renderedComponents;
this.id = baseRender.id;
this.phase = baseRender.phase;
this.actualDuration = baseRender.actualDuration;
this.baseDuration = baseRender.baseDuration;
this.startTime = baseRender.startTime;
this.commitTime = baseRender.commitTime;
this.count = baseRender.count;
}
Object.defineProperty(RenderInstance.prototype, "domSnapshot", {
get: function () {
if (this._domSnapshot)
return this._domSnapshot;
if (!this.stringifiedDOM) {
throw new Error("DOM snapshot is not available - please set the `snapshotDOM` option");
}
var virtualConsole = new VirtualConsole();
var stackTrace = captureStackTrace("RenderInstance.get");
virtualConsole.on("jsdomError", function (error) {
throw applyStackTrace(error, stackTrace);
});
var snapDOM = new JSDOM(this.stringifiedDOM, {
runScripts: "dangerously",
virtualConsole: virtualConsole,
});
var document = snapDOM.window.document;
var body = document.body;
var script = document.createElement("script");
script.type = "text/javascript";
script.text = "\n ".concat(errorOnDomInteraction.toString(), ";\n ").concat(errorOnDomInteraction.name, "();\n ");
body.appendChild(script);
body.removeChild(script);
return (this._domSnapshot = body);
},
enumerable: false,
configurable: true
});
Object.defineProperty(RenderInstance.prototype, "withinDOM", {
get: function () {
var _this = this;
var snapScreen = Object.assign(within(this.domSnapshot), {
debug: function () {
var _a = [];
for (var _i = 0; _i < arguments.length; _i++) {
_a[_i] = arguments[_i];
}
var _b = _a[0], dom = _b === void 0 ? _this.domSnapshot : _b, rest = _a.slice(1);
screen.debug.apply(screen, __spreadArray([dom], rest, false));
},
logTestingPlaygroundURL: function () {
var _a = [];
for (var _i = 0; _i < arguments.length; _i++) {
_a[_i] = arguments[_i];
}
var _b = _a[0], dom = _b === void 0 ? _this.domSnapshot : _b, rest = _a.slice(1);
screen.logTestingPlaygroundURL.apply(screen, __spreadArray([dom], rest, false));
},
});
return function () { return snapScreen; };
},
enumerable: false,
configurable: true
});
return RenderInstance;
}());
export { RenderInstance };
/** @internal */
export function errorOnDomInteraction() {
var events = [
"auxclick",
"blur",
"change",
"click",
"copy",
"cut",
"dblclick",
"drag",
"dragend",
"dragenter",
"dragleave",
"dragover",
"dragstart",
"drop",
"focus",
"focusin",
"focusout",
"input",
"keydown",
"keypress",
"keyup",
"mousedown",
"mouseenter",
"mouseleave",
"mousemove",
"mouseout",
"mouseover",
"mouseup",
"paste",
"pointercancel",
"pointerdown",
"pointerenter",
"pointerleave",
"pointermove",
"pointerout",
"pointerover",
"pointerup",
"scroll",
"select",
"selectionchange",
"selectstart",
"submit",
"toggle",
"touchcancel",
"touchend",
"touchmove",
"touchstart",
"wheel",
];
function warnOnDomInteraction() {
throw new Error("\n DOM interaction with a snapshot detected in test.\n Please don't interact with the DOM you get from `withinDOM`,\n but still use `screen' to get elements for simulating user interaction.\n ");
}
events.forEach(function (event) {
document.addEventListener(event, warnOnDomInteraction);
});
}
//# sourceMappingURL=Render.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
import * as React from "react";
export interface ProfilerContextValue {
renderedComponents: Array<React.ComponentType | string>;
}
export declare function ProfilerContextProvider({ children, value, }: {
children: React.ReactNode;
value: ProfilerContextValue;
}): React.JSX.Element;
export declare function useProfilerContext(): ProfilerContextValue | undefined;
//# sourceMappingURL=context.d.ts.map

View File

@@ -0,0 +1,14 @@
import * as React from "react";
var ProfilerContext = React.createContext(undefined);
export function ProfilerContextProvider(_a) {
var children = _a.children, value = _a.value;
var parentContext = useProfilerContext();
if (parentContext) {
throw new Error("Profilers should not be nested in the same tree");
}
return (React.createElement(ProfilerContext.Provider, { value: value }, children));
}
export function useProfilerContext() {
return React.useContext(ProfilerContext);
}
//# sourceMappingURL=context.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/testing/internal/profile/context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,IAAM,eAAe,GAAG,KAAK,CAAC,aAAa,CACzC,SAAS,CACV,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,EAMvC;QALC,QAAQ,cAAA,EACR,KAAK,WAAA;IAKL,IAAM,aAAa,GAAG,kBAAkB,EAAE,CAAC;IAE3C,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,CACL,oBAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,IACnC,QAAQ,CACgB,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["import * as React from \"react\";\n\nexport interface ProfilerContextValue {\n renderedComponents: Array<React.ComponentType | string>;\n}\n\nconst ProfilerContext = React.createContext<ProfilerContextValue | undefined>(\n undefined\n);\n\nexport function ProfilerContextProvider({\n children,\n value,\n}: {\n children: React.ReactNode;\n value: ProfilerContextValue;\n}) {\n const parentContext = useProfilerContext();\n\n if (parentContext) {\n throw new Error(\"Profilers should not be nested in the same tree\");\n }\n\n return (\n <ProfilerContext.Provider value={value}>\n {children}\n </ProfilerContext.Provider>\n );\n}\n\nexport function useProfilerContext() {\n return React.useContext(ProfilerContext);\n}\n"]}

View File

@@ -0,0 +1,4 @@
export type { NextRenderOptions, Profiler, ProfiledComponent, ProfiledHook, } from "./profile.js";
export { createProfiler, profile, profileHook, useTrackRenders, WaitForRenderTimeoutError, } from "./profile.js";
export type { SyncScreen } from "./Render.js";
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,2 @@
export { createProfiler, profile, profileHook, useTrackRenders, WaitForRenderTimeoutError, } from "./profile.js";
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/testing/internal/profile/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,cAAc,EACd,OAAO,EACP,WAAW,EACX,eAAe,EACf,yBAAyB,GAC1B,MAAM,cAAc,CAAC","sourcesContent":["export type {\n NextRenderOptions,\n Profiler,\n ProfiledComponent,\n ProfiledHook,\n} from \"./profile.js\";\nexport {\n createProfiler,\n profile,\n profileHook,\n useTrackRenders,\n WaitForRenderTimeoutError,\n} from \"./profile.js\";\n\nexport type { SyncScreen } from \"./Render.js\";\n"]}

View File

@@ -0,0 +1,109 @@
import * as React from "react";
import type { Render, BaseRender } from "./Render.js";
type ValidSnapshot = void | (object & {
call?: never;
});
/** only used for passing around data internally */
declare const _stackTrace: unique symbol;
/** @internal */
export interface NextRenderOptions {
timeout?: number;
[_stackTrace]?: string;
}
/** @internal */
interface ProfilerProps {
children: React.ReactNode;
}
/** @internal */
export interface Profiler<Snapshot> extends React.FC<ProfilerProps>, ProfiledComponentFields<Snapshot>, ProfiledComponentOnlyFields<Snapshot> {
}
interface ReplaceSnapshot<Snapshot> {
(newSnapshot: Snapshot): void;
(updateSnapshot: (lastSnapshot: Readonly<Snapshot>) => Snapshot): void;
}
interface MergeSnapshot<Snapshot> {
(partialSnapshot: Partial<Snapshot>): void;
(updatePartialSnapshot: (lastSnapshot: Readonly<Snapshot>) => Partial<Snapshot>): void;
}
interface ProfiledComponentOnlyFields<Snapshot> {
mergeSnapshot: MergeSnapshot<Snapshot>;
replaceSnapshot: ReplaceSnapshot<Snapshot>;
}
interface ProfiledComponentFields<Snapshot> {
/**
* An array of all renders that have happened so far.
* Errors thrown during component render will be captured here, too.
*/
renders: Array<Render<Snapshot> | {
phase: "snapshotError";
count: number;
error: unknown;
}>;
/**
* Peeks the next render from the current iterator position, without advancing the iterator.
* If no render has happened yet, it will wait for the next render to happen.
* @throws {WaitForRenderTimeoutError} if no render happens within the timeout
*/
peekRender(options?: NextRenderOptions): Promise<Render<Snapshot>>;
/**
* Iterates to the next render and returns it.
* If no render has happened yet, it will wait for the next render to happen.
* @throws {WaitForRenderTimeoutError} if no render happens within the timeout
*/
takeRender(options?: NextRenderOptions): Promise<Render<Snapshot>>;
/**
* Returns the total number of renders.
*/
totalRenderCount(): number;
/**
* Returns the current render.
* @throws {Error} if no render has happened yet
*/
getCurrentRender(): Render<Snapshot>;
/**
* Waits for the next render to happen.
* Does not advance the render iterator.
*/
waitForNextRender(options?: NextRenderOptions): Promise<Render<Snapshot>>;
}
export interface ProfiledComponent<Snapshot extends ValidSnapshot, Props = {}> extends React.FC<Props>, ProfiledComponentFields<Snapshot>, ProfiledComponentOnlyFields<Snapshot> {
}
/** @internal */
export declare function profile<Snapshot extends ValidSnapshot = void, Props = {}>({ Component, ...options }: Parameters<typeof createProfiler<Snapshot>>[0] & {
Component: React.ComponentType<Props>;
}): ProfiledComponent<Snapshot, Props>;
/** @internal */
export declare function createProfiler<Snapshot extends ValidSnapshot = void>({ onRender, snapshotDOM, initialSnapshot, skipNonTrackingRenders, }?: {
onRender?: (info: BaseRender & {
snapshot: Snapshot;
replaceSnapshot: ReplaceSnapshot<Snapshot>;
mergeSnapshot: MergeSnapshot<Snapshot>;
}) => void;
snapshotDOM?: boolean;
initialSnapshot?: Snapshot;
/**
* This will skip renders during which no renders tracked by
* `useTrackRenders` occured.
*/
skipNonTrackingRenders?: boolean;
}): Profiler<Snapshot>;
/** @internal */
export declare class WaitForRenderTimeoutError extends Error {
constructor();
}
type StringReplaceRenderWithSnapshot<T extends string> = T extends `${infer Pre}Render${infer Post}` ? `${Pre}Snapshot${Post}` : T;
type ResultReplaceRenderWithSnapshot<T> = T extends (...args: infer Args) => Render<infer Snapshot> ? (...args: Args) => Snapshot : T extends (...args: infer Args) => Promise<Render<infer Snapshot>> ? (...args: Args) => Promise<Snapshot> : T;
type ProfiledHookFields<ReturnValue> = ProfiledComponentFields<ReturnValue> extends infer PC ? {
[K in keyof PC as StringReplaceRenderWithSnapshot<K & string>]: ResultReplaceRenderWithSnapshot<PC[K]>;
} : never;
/** @internal */
export interface ProfiledHook<Props, ReturnValue> extends React.FC<Props>, ProfiledHookFields<ReturnValue> {
Profiler: Profiler<ReturnValue>;
}
/** @internal */
export declare function profileHook<ReturnValue extends ValidSnapshot, Props>(renderCallback: (props: Props) => ReturnValue): ProfiledHook<Props, ReturnValue>;
export declare function useTrackRenders({ name }?: {
name?: string;
}): void;
export {};
//# sourceMappingURL=profile.d.ts.map

View File

@@ -0,0 +1,296 @@
var _a, _b;
import { __addDisposableResource, __assign, __awaiter, __disposeResources, __extends, __generator, __rest } from "tslib";
import * as React from "react";
import { TextEncoder, TextDecoder } from "util";
(_a = global.TextEncoder) !== null && _a !== void 0 ? _a : (global.TextEncoder = TextEncoder);
// @ts-ignore
(_b = global.TextDecoder) !== null && _b !== void 0 ? _b : (global.TextDecoder = TextDecoder);
import { RenderInstance } from "./Render.js";
import { applyStackTrace, captureStackTrace } from "./traces.js";
import { ProfilerContextProvider, useProfilerContext } from "./context.js";
import { disableActWarnings } from "../disposables/index.js";
/** only used for passing around data internally */
var _stackTrace = Symbol();
/** @internal */
export function profile(_a) {
var Component = _a.Component, options = __rest(_a, ["Component"]);
var Profiler = createProfiler(options);
return Object.assign(function ProfiledComponent(props) {
return (React.createElement(Profiler, null,
React.createElement(Component, __assign({}, props))));
}, {
mergeSnapshot: Profiler.mergeSnapshot,
replaceSnapshot: Profiler.replaceSnapshot,
getCurrentRender: Profiler.getCurrentRender,
peekRender: Profiler.peekRender,
takeRender: Profiler.takeRender,
totalRenderCount: Profiler.totalRenderCount,
waitForNextRender: Profiler.waitForNextRender,
get renders() {
return Profiler.renders;
},
});
}
/** @internal */
export function createProfiler(_a) {
var _b = _a === void 0 ? {} : _a, onRender = _b.onRender, _c = _b.snapshotDOM, snapshotDOM = _c === void 0 ? false : _c, initialSnapshot = _b.initialSnapshot, skipNonTrackingRenders = _b.skipNonTrackingRenders;
var nextRender;
var resolveNextRender;
var rejectNextRender;
var snapshotRef = { current: initialSnapshot };
var replaceSnapshot = function (snap) {
if (typeof snap === "function") {
if (!initialSnapshot) {
throw new Error("Cannot use a function to update the snapshot if no initial snapshot was provided.");
}
snapshotRef.current = snap(typeof snapshotRef.current === "object" ? __assign({}, snapshotRef.current) : snapshotRef.current);
}
else {
snapshotRef.current = snap;
}
};
var mergeSnapshot = function (partialSnapshot) {
replaceSnapshot(function (snapshot) { return (__assign(__assign({}, snapshot), (typeof partialSnapshot === "function" ?
partialSnapshot(snapshot)
: partialSnapshot))); });
};
var profilerContext = {
renderedComponents: [],
};
var profilerOnRender = function (id, phase, actualDuration, baseDuration, startTime, commitTime) {
if (skipNonTrackingRenders &&
profilerContext.renderedComponents.length === 0) {
return;
}
var baseRender = {
id: id,
phase: phase,
actualDuration: actualDuration,
baseDuration: baseDuration,
startTime: startTime,
commitTime: commitTime,
count: Profiler.renders.length + 1,
};
try {
/*
* The `onRender` function could contain `expect` calls that throw
* `JestAssertionError`s - but we are still inside of React, where errors
* might be swallowed.
* So we record them and re-throw them in `takeRender`
* Additionally, we reject the `waitForNextRender` promise.
*/
onRender === null || onRender === void 0 ? void 0 : onRender(__assign(__assign({}, baseRender), { replaceSnapshot: replaceSnapshot, mergeSnapshot: mergeSnapshot, snapshot: snapshotRef.current }));
var snapshot = snapshotRef.current;
var domSnapshot = snapshotDOM ? window.document.body.innerHTML : undefined;
var render = new RenderInstance(baseRender, snapshot, domSnapshot, profilerContext.renderedComponents);
profilerContext.renderedComponents = [];
Profiler.renders.push(render);
resolveNextRender === null || resolveNextRender === void 0 ? void 0 : resolveNextRender(render);
}
catch (error) {
Profiler.renders.push({
phase: "snapshotError",
count: Profiler.renders.length,
error: error,
});
rejectNextRender === null || rejectNextRender === void 0 ? void 0 : rejectNextRender(error);
}
finally {
nextRender = resolveNextRender = rejectNextRender = undefined;
}
};
var iteratorPosition = 0;
var Profiler = Object.assign(function (_a) {
var children = _a.children;
return (React.createElement(ProfilerContextProvider, { value: profilerContext },
React.createElement(React.Profiler, { id: "test", onRender: profilerOnRender }, children)));
}, {
replaceSnapshot: replaceSnapshot,
mergeSnapshot: mergeSnapshot,
}, {
renders: new Array(),
totalRenderCount: function () {
return Profiler.renders.length;
},
peekRender: function (options) {
if (options === void 0) { options = {}; }
return __awaiter(this, void 0, void 0, function () {
var render;
var _a;
return __generator(this, function (_b) {
if (iteratorPosition < Profiler.renders.length) {
render = Profiler.renders[iteratorPosition];
if (render.phase === "snapshotError") {
throw render.error;
}
return [2 /*return*/, render];
}
return [2 /*return*/, Profiler.waitForNextRender(__assign((_a = {}, _a[_stackTrace] = captureStackTrace(Profiler.peekRender), _a), options))];
});
});
},
takeRender: function (options) {
if (options === void 0) { options = {}; }
return __awaiter(this, void 0, void 0, function () {
var env_1, _disabledActWarnings, error, e_1, e_2;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
env_1 = { stack: [], error: void 0, hasError: false };
_b.label = 1;
case 1:
_b.trys.push([1, 7, 8, 9]);
_disabledActWarnings = __addDisposableResource(env_1, disableActWarnings(), false);
error = undefined;
_b.label = 2;
case 2:
_b.trys.push([2, 4, 5, 6]);
return [4 /*yield*/, Profiler.peekRender(__assign((_a = {}, _a[_stackTrace] = captureStackTrace(Profiler.takeRender), _a), options))];
case 3: return [2 /*return*/, _b.sent()];
case 4:
e_1 = _b.sent();
error = e_1;
throw e_1;
case 5:
if (!(error && error instanceof WaitForRenderTimeoutError)) {
iteratorPosition++;
}
return [7 /*endfinally*/];
case 6: return [3 /*break*/, 9];
case 7:
e_2 = _b.sent();
env_1.error = e_2;
env_1.hasError = true;
return [3 /*break*/, 9];
case 8:
__disposeResources(env_1);
return [7 /*endfinally*/];
case 9: return [2 /*return*/];
}
});
});
},
getCurrentRender: function () {
// The "current" render should point at the same render that the most
// recent `takeRender` call returned, so we need to get the "previous"
// iterator position, otherwise `takeRender` advances the iterator
// to the next render. This means we need to call `takeRender` at least
// once before we can get a current render.
var currentPosition = iteratorPosition - 1;
if (currentPosition < 0) {
throw new Error("No current render available. You need to call `takeRender` before you can get the current render.");
}
var render = Profiler.renders[currentPosition];
if (render.phase === "snapshotError") {
throw render.error;
}
return render;
},
waitForNextRender: function (_a) {
var _b = _a === void 0 ? {} : _a, _c = _b.timeout, timeout = _c === void 0 ? 1000 : _c,
// capture the stack trace here so its stack trace is as close to the calling code as possible
_d = _stackTrace,
// capture the stack trace here so its stack trace is as close to the calling code as possible
_e = _b[_d],
// capture the stack trace here so its stack trace is as close to the calling code as possible
stackTrace = _e === void 0 ? captureStackTrace(Profiler.waitForNextRender) : _e;
if (!nextRender) {
nextRender = Promise.race([
new Promise(function (resolve, reject) {
resolveNextRender = resolve;
rejectNextRender = reject;
}),
new Promise(function (_, reject) {
return setTimeout(function () {
return reject(applyStackTrace(new WaitForRenderTimeoutError(), stackTrace));
}, timeout);
}),
]);
}
return nextRender;
},
});
return Profiler;
}
/** @internal */
var WaitForRenderTimeoutError = /** @class */ (function (_super) {
__extends(WaitForRenderTimeoutError, _super);
function WaitForRenderTimeoutError() {
var _newTarget = this.constructor;
var _this = _super.call(this, "Exceeded timeout waiting for next render.") || this;
Object.setPrototypeOf(_this, _newTarget.prototype);
return _this;
}
return WaitForRenderTimeoutError;
}(Error));
export { WaitForRenderTimeoutError };
/** @internal */
export function profileHook(renderCallback) {
var Profiler = createProfiler();
var ProfiledHook = function (props) {
Profiler.replaceSnapshot(renderCallback(props));
return null;
};
return Object.assign(function App(props) {
return (React.createElement(Profiler, null,
React.createElement(ProfiledHook, __assign({}, props))));
}, {
Profiler: Profiler,
}, {
renders: Profiler.renders,
totalSnapshotCount: Profiler.totalRenderCount,
peekSnapshot: function (options) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, Profiler.peekRender(options)];
case 1: return [2 /*return*/, (_a.sent()).snapshot];
}
});
});
},
takeSnapshot: function (options) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, Profiler.takeRender(options)];
case 1: return [2 /*return*/, (_a.sent()).snapshot];
}
});
});
},
getCurrentSnapshot: function () {
return Profiler.getCurrentRender().snapshot;
},
waitForNextSnapshot: function (options) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, Profiler.waitForNextRender(options)];
case 1: return [2 /*return*/, (_a.sent()).snapshot];
}
});
});
},
});
}
function resolveHookOwner() {
var _a, _b, _c;
return (_c = (_b = (_a = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED) === null || _a === void 0 ? void 0 : _a.ReactCurrentOwner) === null || _b === void 0 ? void 0 : _b.current) === null || _c === void 0 ? void 0 : _c.elementType;
}
export function useTrackRenders(_a) {
var _b = _a === void 0 ? {} : _a, name = _b.name;
var component = name || resolveHookOwner();
if (!component) {
throw new Error("useTrackRender: Unable to determine component. Please ensure the hook is called inside a rendered component or provide a `name` option.");
}
var ctx = useProfilerContext();
if (!ctx) {
throw new Error("useTrackComponentRender: A Profiler must be created and rendered to track component renders");
}
React.useLayoutEffect(function () {
ctx.renderedComponents.unshift(component);
});
}
//# sourceMappingURL=profile.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
/**
* Captures a StackTrace and (if passed) cuts off
* the first lines including the calling function.
*/
export declare function captureStackTrace(callingFunction?: string | (() => {})): string;
export declare function applyStackTrace(error: Error, stackTrace: string): Error;
//# sourceMappingURL=traces.d.ts.map

View File

@@ -0,0 +1,30 @@
/**
* Captures a StackTrace and (if passed) cuts off
* the first lines including the calling function.
*/
export function captureStackTrace(callingFunction) {
var stack = "";
try {
throw new Error("");
}
catch (e) {
(stack = e.stack);
}
var callerName = typeof callingFunction === "string" ? callingFunction
: callingFunction ? callingFunction.name
: undefined;
if (callerName && stack.includes(callerName)) {
var lines = stack.split("\n");
stack = lines
.slice(
// @ts-expect-error this is too old of a TS target, but node has it
lines.findLastIndex(function (line) { return line.includes(callerName); }) + 1)
.join("\n");
}
return stack;
}
export function applyStackTrace(error, stackTrace) {
error.stack = error.message + "\n" + stackTrace;
return error;
}
//# sourceMappingURL=traces.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"traces.js","sourceRoot":"","sources":["../../../../src/testing/internal/profile/traces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,eAAqC;IACrE,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,CAAC;QACH,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,CAAG,KAAK,GAAK,CAAC,MAAN,CAAO,CAAC;IAClB,CAAC;IAED,IAAM,UAAU,GACd,OAAO,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe;QACrD,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI;YACxC,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,UAAU,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7C,IAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEhC,KAAK,GAAG,KAAK;aACV,KAAK;QACJ,mEAAmE;QACnE,KAAK,CAAC,aAAa,CAAC,UAAC,IAAY,IAAK,OAAA,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAzB,CAAyB,CAAC,GAAG,CAAC,CACrE;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAY,EAAE,UAAkB;IAC9D,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,GAAG,UAAU,CAAC;IAChD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["/**\n * Captures a StackTrace and (if passed) cuts off\n * the first lines including the calling function.\n */\nexport function captureStackTrace(callingFunction?: string | (() => {})) {\n let stack = \"\";\n try {\n throw new Error(\"\");\n } catch (e: any) {\n ({ stack } = e);\n }\n\n const callerName =\n typeof callingFunction === \"string\" ? callingFunction\n : callingFunction ? callingFunction.name\n : undefined;\n\n if (callerName && stack.includes(callerName)) {\n const lines = stack.split(\"\\n\");\n\n stack = lines\n .slice(\n // @ts-expect-error this is too old of a TS target, but node has it\n lines.findLastIndex((line: string) => line.includes(callerName)) + 1\n )\n .join(\"\\n\");\n }\n\n return stack;\n}\n\nexport function applyStackTrace(error: Error, stackTrace: string) {\n error.stack = error.message + \"\\n\" + stackTrace;\n return error;\n}\n"]}

View File

@@ -0,0 +1,12 @@
import type { ReactElement } from "react";
import type { Queries, RenderOptions, queries } from "@testing-library/react";
import type { ApolloClient } from "../../core/index.js";
import type { MockedProviderProps } from "../react/MockedProvider.js";
export interface RenderWithClientOptions<Q extends Queries = typeof queries, Container extends Element | DocumentFragment = HTMLElement, BaseElement extends Element | DocumentFragment = Container> extends RenderOptions<Q, Container, BaseElement> {
client: ApolloClient<any>;
}
export declare function renderWithClient<Q extends Queries = typeof queries, Container extends Element | DocumentFragment = HTMLElement, BaseElement extends Element | DocumentFragment = Container>(ui: ReactElement, { client, wrapper: Wrapper, ...renderOptions }: RenderWithClientOptions<Q, Container, BaseElement>): import("@testing-library/react").RenderResult<Q, Container, BaseElement>;
export interface RenderWithMocksOptions<Q extends Queries = typeof queries, Container extends Element | DocumentFragment = HTMLElement, BaseElement extends Element | DocumentFragment = Container> extends RenderOptions<Q, Container, BaseElement>, MockedProviderProps<any> {
}
export declare function renderWithMocks<Q extends Queries = typeof queries, Container extends Element | DocumentFragment = HTMLElement, BaseElement extends Element | DocumentFragment = Container>(ui: ReactElement, { wrapper: Wrapper, ...renderOptions }: RenderWithMocksOptions<Q, Container, BaseElement>): import("@testing-library/react").RenderResult<Q, Container, BaseElement>;
//# sourceMappingURL=renderHelpers.d.ts.map

View File

@@ -0,0 +1,22 @@
import { __assign, __rest } from "tslib";
import * as React from "react";
import { render } from "@testing-library/react";
import { ApolloProvider } from "../../react/index.js";
import { MockedProvider } from "../react/MockedProvider.js";
export function renderWithClient(ui, _a) {
var client = _a.client, _b = _a.wrapper, Wrapper = _b === void 0 ? React.Fragment : _b, renderOptions = __rest(_a, ["client", "wrapper"]);
return render(ui, __assign(__assign({}, renderOptions), { wrapper: function (_a) {
var children = _a.children;
return (React.createElement(ApolloProvider, { client: client },
React.createElement(Wrapper, null, children)));
} }));
}
export function renderWithMocks(ui, _a) {
var _b = _a.wrapper, Wrapper = _b === void 0 ? React.Fragment : _b, renderOptions = __rest(_a, ["wrapper"]);
return render(ui, __assign(__assign({}, renderOptions), { wrapper: function (_a) {
var children = _a.children;
return (React.createElement(MockedProvider, __assign({}, renderOptions),
React.createElement(Wrapper, null, children)));
} }));
}
//# sourceMappingURL=renderHelpers.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"renderHelpers.js","sourceRoot":"","sources":["../../../src/testing/internal/renderHelpers.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGhD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAU5D,MAAM,UAAU,gBAAgB,CAK9B,EAAgB,EAChB,EAIqD;IAHnD,IAAA,MAAM,YAAA,EACN,eAAiC,EAAxB,OAAO,mBAAG,KAAK,CAAC,QAAQ,KAAA,EAC9B,aAAa,cAHlB,qBAIC,CADiB;IAGlB,OAAO,MAAM,CAAC,EAAE,wBACX,aAAa,KAChB,OAAO,EAAE,UAAC,EAAY;gBAAV,QAAQ,cAAA;YAClB,OAAO,CACL,oBAAC,cAAc,IAAC,MAAM,EAAE,MAAM;gBAC5B,oBAAC,OAAO,QAAE,QAAQ,CAAW,CACd,CAClB,CAAC;QACJ,CAAC,IACD,CAAC;AACL,CAAC;AASD,MAAM,UAAU,eAAe,CAK7B,EAAgB,EAChB,EAGoD;IAFlD,IAAA,eAAiC,EAAxB,OAAO,mBAAG,KAAK,CAAC,QAAQ,KAAA,EAC9B,aAAa,cAFlB,WAGC,CADiB;IAGlB,OAAO,MAAM,CAAC,EAAE,wBACX,aAAa,KAChB,OAAO,EAAE,UAAC,EAAY;gBAAV,QAAQ,cAAA;YAClB,OAAO,CACL,oBAAC,cAAc,eAAK,aAAa;gBAC/B,oBAAC,OAAO,QAAE,QAAQ,CAAW,CACd,CAClB,CAAC;QACJ,CAAC,IACD,CAAC;AACL,CAAC","sourcesContent":["import * as React from \"react\";\nimport type { ReactElement } from \"react\";\nimport { render } from \"@testing-library/react\";\nimport type { Queries, RenderOptions, queries } from \"@testing-library/react\";\nimport type { ApolloClient } from \"../../core/index.js\";\nimport { ApolloProvider } from \"../../react/index.js\";\nimport type { MockedProviderProps } from \"../react/MockedProvider.js\";\nimport { MockedProvider } from \"../react/MockedProvider.js\";\n\nexport interface RenderWithClientOptions<\n Q extends Queries = typeof queries,\n Container extends Element | DocumentFragment = HTMLElement,\n BaseElement extends Element | DocumentFragment = Container,\n> extends RenderOptions<Q, Container, BaseElement> {\n client: ApolloClient<any>;\n}\n\nexport function renderWithClient<\n Q extends Queries = typeof queries,\n Container extends Element | DocumentFragment = HTMLElement,\n BaseElement extends Element | DocumentFragment = Container,\n>(\n ui: ReactElement,\n {\n client,\n wrapper: Wrapper = React.Fragment,\n ...renderOptions\n }: RenderWithClientOptions<Q, Container, BaseElement>\n) {\n return render(ui, {\n ...renderOptions,\n wrapper: ({ children }) => {\n return (\n <ApolloProvider client={client}>\n <Wrapper>{children}</Wrapper>\n </ApolloProvider>\n );\n },\n });\n}\n\nexport interface RenderWithMocksOptions<\n Q extends Queries = typeof queries,\n Container extends Element | DocumentFragment = HTMLElement,\n BaseElement extends Element | DocumentFragment = Container,\n> extends RenderOptions<Q, Container, BaseElement>,\n MockedProviderProps<any> {}\n\nexport function renderWithMocks<\n Q extends Queries = typeof queries,\n Container extends Element | DocumentFragment = HTMLElement,\n BaseElement extends Element | DocumentFragment = Container,\n>(\n ui: ReactElement,\n {\n wrapper: Wrapper = React.Fragment,\n ...renderOptions\n }: RenderWithMocksOptions<Q, Container, BaseElement>\n) {\n return render(ui, {\n ...renderOptions,\n wrapper: ({ children }) => {\n return (\n <MockedProvider {...renderOptions}>\n <Wrapper>{children}</Wrapper>\n </MockedProvider>\n );\n },\n });\n}\n"]}

View File

@@ -0,0 +1,41 @@
import { ApolloLink } from "../../../core/index.js";
import type { TypedDocumentNode } from "../../../core/index.js";
import type { MockedResponse } from "../../core/index.js";
export interface SimpleCaseData {
greeting: string;
}
export declare function setupSimpleCase(): {
query: TypedDocumentNode<SimpleCaseData, Record<string, never>>;
mocks: MockedResponse<SimpleCaseData, Record<string, any>>[];
};
export interface VariablesCaseData {
character: {
__typename: "Character";
id: string;
name: string;
};
}
export interface VariablesCaseVariables {
id: string;
}
export declare function setupVariablesCase(): {
mocks: MockedResponse<VariablesCaseData, Record<string, any>>[];
query: TypedDocumentNode<VariablesCaseData, VariablesCaseVariables>;
};
interface Letter {
letter: string;
position: number;
}
export interface PaginatedCaseData {
letters: Letter[];
}
export interface PaginatedCaseVariables {
limit?: number;
offset?: number;
}
export declare function setupPaginatedCase(): {
query: TypedDocumentNode<PaginatedCaseData, PaginatedCaseVariables>;
link: ApolloLink;
};
export {};
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,48 @@
import { __makeTemplateObject, __spreadArray } from "tslib";
import { ApolloLink, Observable, gql } from "../../../core/index.js";
export function setupSimpleCase() {
var query = gql(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n query GreetingQuery {\n greeting\n }\n "], ["\n query GreetingQuery {\n greeting\n }\n "])));
var mocks = [
{
request: { query: query },
result: { data: { greeting: "Hello" } },
delay: 10,
},
];
return { query: query, mocks: mocks };
}
export function setupVariablesCase() {
var query = gql(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n query CharacterQuery($id: ID!) {\n character(id: $id) {\n id\n name\n }\n }\n "], ["\n query CharacterQuery($id: ID!) {\n character(id: $id) {\n id\n name\n }\n }\n "])));
var CHARACTERS = ["Spider-Man", "Black Widow", "Iron Man", "Hulk"];
var mocks = __spreadArray([], CHARACTERS, true).map(function (name, index) { return ({
request: { query: query, variables: { id: String(index + 1) } },
result: {
data: {
character: { __typename: "Character", id: String(index + 1), name: name },
},
},
delay: 20,
}); });
return { mocks: mocks, query: query };
}
export function setupPaginatedCase() {
var query = gql(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n query letters($limit: Int, $offset: Int) {\n letters(limit: $limit) {\n letter\n position\n }\n }\n "], ["\n query letters($limit: Int, $offset: Int) {\n letters(limit: $limit) {\n letter\n position\n }\n }\n "])));
var data = "ABCDEFGHIJKLMNOPQRSTUV".split("").map(function (letter, index) { return ({
__typename: "Letter",
letter: letter,
position: index + 1,
}); });
var link = new ApolloLink(function (operation) {
var _a = operation.variables, _b = _a.offset, offset = _b === void 0 ? 0 : _b, _c = _a.limit, limit = _c === void 0 ? 2 : _c;
var letters = data.slice(offset, offset + limit);
return new Observable(function (observer) {
setTimeout(function () {
observer.next({ data: { letters: letters } });
observer.complete();
}, 10);
});
});
return { query: query, link: link };
}
var templateObject_1, templateObject_2, templateObject_3;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/testing/internal/scenarios/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAQrE,MAAM,UAAU,eAAe;IAC7B,IAAM,KAAK,GAA6D,GAAG,2HAAA,wDAI1E,IAAA,CAAC;IAEF,IAAM,KAAK,GAAqC;QAC9C;YACE,OAAO,EAAE,EAAE,KAAK,OAAA,EAAE;YAClB,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;YACvC,KAAK,EAAE,EAAE;SACV;KACF,CAAC;IAEF,OAAO,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,CAAC;AAC1B,CAAC;AAcD,MAAM,UAAU,kBAAkB;IAChC,IAAM,KAAK,GACT,GAAG,mMAAA,gIAOF,IAAA,CAAC;IACJ,IAAM,UAAU,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAErE,IAAM,KAAK,GAAwC,kBAAI,UAAU,QAAE,GAAG,CACpE,UAAC,IAAI,EAAE,KAAK,IAAK,OAAA,CAAC;QAChB,OAAO,EAAE,EAAE,KAAK,OAAA,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,EAAE;QACxD,MAAM,EAAE;YACN,IAAI,EAAE;gBACJ,SAAS,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,IAAI,MAAA,EAAE;aACpE;SACF;QACD,KAAK,EAAE,EAAE;KACV,CAAC,EARe,CAQf,CACH,CAAC;IAEF,OAAO,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,CAAC;AAC1B,CAAC;AAgBD,MAAM,UAAU,kBAAkB;IAChC,IAAM,KAAK,GACT,GAAG,yNAAA,sJAOF,IAAA,CAAC;IAEJ,IAAM,IAAI,GAAG,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,UAAC,MAAM,EAAE,KAAK,IAAK,OAAA,CAAC;QACtE,UAAU,EAAE,QAAQ;QACpB,MAAM,QAAA;QACN,QAAQ,EAAE,KAAK,GAAG,CAAC;KACpB,CAAC,EAJqE,CAIrE,CAAC,CAAC;IAEJ,IAAM,IAAI,GAAG,IAAI,UAAU,CAAC,UAAC,SAAS;QAC9B,IAAA,KAA4B,SAAS,CAAC,SAAS,EAA7C,cAAU,EAAV,MAAM,mBAAG,CAAC,KAAA,EAAE,aAAS,EAAT,KAAK,mBAAG,CAAC,KAAwB,CAAC;QACtD,IAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;QAEnD,OAAO,IAAI,UAAU,CAAC,UAAC,QAAQ;YAC7B,UAAU,CAAC;gBACT,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,SAAA,EAAE,EAAE,CAAC,CAAC;gBACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACtB,CAAC,EAAE,EAAE,CAAC,CAAC;QACT,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,OAAA,EAAE,IAAI,MAAA,EAAE,CAAC;AACzB,CAAC","sourcesContent":["import { ApolloLink, Observable, gql } from \"../../../core/index.js\";\nimport type { TypedDocumentNode } from \"../../../core/index.js\";\nimport type { MockedResponse } from \"../../core/index.js\";\n\nexport interface SimpleCaseData {\n greeting: string;\n}\n\nexport function setupSimpleCase() {\n const query: TypedDocumentNode<SimpleCaseData, Record<string, never>> = gql`\n query GreetingQuery {\n greeting\n }\n `;\n\n const mocks: MockedResponse<SimpleCaseData>[] = [\n {\n request: { query },\n result: { data: { greeting: \"Hello\" } },\n delay: 10,\n },\n ];\n\n return { query, mocks };\n}\n\nexport interface VariablesCaseData {\n character: {\n __typename: \"Character\";\n id: string;\n name: string;\n };\n}\n\nexport interface VariablesCaseVariables {\n id: string;\n}\n\nexport function setupVariablesCase() {\n const query: TypedDocumentNode<VariablesCaseData, VariablesCaseVariables> =\n gql`\n query CharacterQuery($id: ID!) {\n character(id: $id) {\n id\n name\n }\n }\n `;\n const CHARACTERS = [\"Spider-Man\", \"Black Widow\", \"Iron Man\", \"Hulk\"];\n\n const mocks: MockedResponse<VariablesCaseData>[] = [...CHARACTERS].map(\n (name, index) => ({\n request: { query, variables: { id: String(index + 1) } },\n result: {\n data: {\n character: { __typename: \"Character\", id: String(index + 1), name },\n },\n },\n delay: 20,\n })\n );\n\n return { mocks, query };\n}\n\ninterface Letter {\n letter: string;\n position: number;\n}\n\nexport interface PaginatedCaseData {\n letters: Letter[];\n}\n\nexport interface PaginatedCaseVariables {\n limit?: number;\n offset?: number;\n}\n\nexport function setupPaginatedCase() {\n const query: TypedDocumentNode<PaginatedCaseData, PaginatedCaseVariables> =\n gql`\n query letters($limit: Int, $offset: Int) {\n letters(limit: $limit) {\n letter\n position\n }\n }\n `;\n\n const data = \"ABCDEFGHIJKLMNOPQRSTUV\".split(\"\").map((letter, index) => ({\n __typename: \"Letter\",\n letter,\n position: index + 1,\n }));\n\n const link = new ApolloLink((operation) => {\n const { offset = 0, limit = 2 } = operation.variables;\n const letters = data.slice(offset, offset + limit);\n\n return new Observable((observer) => {\n setTimeout(() => {\n observer.next({ data: { letters } });\n observer.complete();\n }, 10);\n });\n });\n\n return { query, link };\n}\n"]}