@fluidframework/test-utils 2.0.0-internal.5.1.1 → 2.0.0-internal.5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/testFluidObject.d.ts +5 -0
- package/dist/testFluidObject.d.ts.map +1 -1
- package/dist/testFluidObject.js +5 -0
- package/dist/testFluidObject.js.map +1 -1
- package/dist/timeoutUtils.d.ts +20 -0
- package/dist/timeoutUtils.d.ts.map +1 -1
- package/dist/timeoutUtils.js +51 -30
- package/dist/timeoutUtils.js.map +1 -1
- package/package.json +23 -23
- package/src/packageVersion.ts +1 -1
- package/src/testFluidObject.ts +5 -0
- package/src/timeoutUtils.ts +63 -43
package/CHANGELOG.md
CHANGED
package/dist/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/test-utils";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-internal.5.
|
|
8
|
+
export declare const pkgVersion = "2.0.0-internal.5.2.0";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
package/dist/packageVersion.js
CHANGED
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.pkgVersion = exports.pkgName = void 0;
|
|
10
10
|
exports.pkgName = "@fluidframework/test-utils";
|
|
11
|
-
exports.pkgVersion = "2.0.0-internal.5.
|
|
11
|
+
exports.pkgVersion = "2.0.0-internal.5.2.0";
|
|
12
12
|
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,4BAA4B,CAAC;AACvC,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/test-utils\";\nexport const pkgVersion = \"2.0.0-internal.5.
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,4BAA4B,CAAC;AACvC,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/test-utils\";\nexport const pkgVersion = \"2.0.0-internal.5.2.0\";\n"]}
|
|
@@ -65,6 +65,11 @@ export declare type ChannelFactoryRegistry = Iterable<[string | undefined, IChan
|
|
|
65
65
|
* sharedString = testFluidObject.getSharedObject<SharedString>("sharedString");
|
|
66
66
|
* sharedDir = testFluidObject.getSharedObject<SharedDirectory>("sharedDirectory");
|
|
67
67
|
* ```
|
|
68
|
+
*
|
|
69
|
+
* @privateRemarks - Beware that using this class generally forfeits some compatibility coverage
|
|
70
|
+
* `describeCompat` aims to provide:
|
|
71
|
+
* `SharedMap`s always reference the current version of SharedMap.
|
|
72
|
+
* AB#4670 tracks improving this situation.
|
|
68
73
|
*/
|
|
69
74
|
export declare class TestFluidObjectFactory implements IFluidDataStoreFactory {
|
|
70
75
|
private readonly factoryEntries;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testFluidObject.d.ts","sourceRoot":"","sources":["../src/testFluidObject.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EAGZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEN,qBAAqB,EAErB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAa,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAEhG,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,gBAAgB,EAAE,YAAY;aAyCpD,OAAO,EAAE,sBAAsB;aAC/B,OAAO,EAAE,sBAAsB;aAC/B,OAAO,EAAE,sBAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;WA3Cf,IAAI,CACvB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAC5C,QAAQ,EAAE,OAAO;IAQlB,IAAW,gBAAgB,SAE1B;IAED,IAAW,cAAc,SAExB;IAED,IAAW,YAAY,SAEtB;IAED,IAAW,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,CAEtC;IAEM,IAAI,EAAG,UAAU,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IAEjD;;;;;;OAMG;gBAEc,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC9B,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAKjE;;;OAGG;IACU,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAehD,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;YAI7C,UAAU;CAcxB;AAED,oBAAY,sBAAsB,GAAG,QAAQ,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;AAErF
|
|
1
|
+
{"version":3,"file":"testFluidObject.d.ts","sourceRoot":"","sources":["../src/testFluidObject.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,YAAY,EAGZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEN,qBAAqB,EAErB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAa,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAEhG,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,gBAAgB,EAAE,YAAY;aAyCpD,OAAO,EAAE,sBAAsB;aAC/B,OAAO,EAAE,sBAAsB;aAC/B,OAAO,EAAE,sBAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;WA3Cf,IAAI,CACvB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAC5C,QAAQ,EAAE,OAAO;IAQlB,IAAW,gBAAgB,SAE1B;IAED,IAAW,cAAc,SAExB;IAED,IAAW,YAAY,SAEtB;IAED,IAAW,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,CAEtC;IAEM,IAAI,EAAG,UAAU,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IAEjD;;;;;;OAMG;gBAEc,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC9B,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAKjE;;;OAGG;IACU,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAehD,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;YAI7C,UAAU;CAcxB;AAED,oBAAY,sBAAsB,GAAG,QAAQ,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,sBAAuB,YAAW,sBAAsB;IAYnE,OAAO,CAAC,QAAQ,CAAC,cAAc;aACf,IAAI;IAZrB,IAAW,sBAAsB,SAEhC;IAED;;;;;OAKG;gBAEe,cAAc,EAAE,sBAAsB,EACvC,IAAI,SAA2B;IAGnC,oBAAoB,CAChC,OAAO,EAAE,sBAAsB,EAC/B,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,qBAAqB,CAAC;CAmDjC"}
|
package/dist/testFluidObject.js
CHANGED
|
@@ -101,6 +101,11 @@ exports.TestFluidObject = TestFluidObject;
|
|
|
101
101
|
* sharedString = testFluidObject.getSharedObject<SharedString>("sharedString");
|
|
102
102
|
* sharedDir = testFluidObject.getSharedObject<SharedDirectory>("sharedDirectory");
|
|
103
103
|
* ```
|
|
104
|
+
*
|
|
105
|
+
* @privateRemarks - Beware that using this class generally forfeits some compatibility coverage
|
|
106
|
+
* `describeCompat` aims to provide:
|
|
107
|
+
* `SharedMap`s always reference the current version of SharedMap.
|
|
108
|
+
* AB#4670 tracks improving this situation.
|
|
104
109
|
*/
|
|
105
110
|
class TestFluidObjectFactory {
|
|
106
111
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testFluidObject.js","sourceRoot":"","sources":["../src/testFluidObject.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { defaultFluidObjectRequestHandler } from \"@fluidframework/aqueduct\";\nimport {\n\tIRequest,\n\tIResponse,\n\tIFluidHandle,\n\tIFluidRouter,\n\tFluidObject,\n\tIProvideFluidRouter,\n} from \"@fluidframework/core-interfaces\";\nimport {\n\tFluidObjectHandle,\n\tFluidDataStoreRuntime,\n\tmixinRequestHandler,\n} from \"@fluidframework/datastore\";\nimport { SharedMap, ISharedMap } from \"@fluidframework/map\";\nimport {\n\tIFluidDataStoreContext,\n\tIFluidDataStoreFactory,\n\tIFluidDataStoreChannel,\n} from \"@fluidframework/runtime-definitions\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ITestFluidObject } from \"./interfaces\";\n\n/**\n * A test Fluid object that will create a shared object for each key-value pair in the factoryEntries passed to load.\n * The shared objects can be retrieved by passing the key of the entry to getSharedObject.\n * It exposes the IFluidDataStoreContext and IFluidDataStoreRuntime.\n */\nexport class TestFluidObject implements ITestFluidObject, IFluidRouter {\n\tpublic static async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tchannel: IFluidDataStoreChannel,\n\t\tcontext: IFluidDataStoreContext,\n\t\tfactoryEntries: Map<string, IChannelFactory>,\n\t\texisting: boolean,\n\t) {\n\t\tconst fluidObject = new TestFluidObject(runtime, channel, context, factoryEntries);\n\t\tawait fluidObject.initialize(existing);\n\n\t\treturn fluidObject;\n\t}\n\n\tpublic get ITestFluidObject() {\n\t\treturn this;\n\t}\n\n\tpublic get IFluidLoadable() {\n\t\treturn this;\n\t}\n\n\tpublic get IFluidRouter() {\n\t\treturn this;\n\t}\n\n\tpublic get handle(): IFluidHandle<this> {\n\t\treturn this.innerHandle;\n\t}\n\n\tpublic root!: ISharedMap;\n\tprivate readonly innerHandle: IFluidHandle<this>;\n\n\t/**\n\t * Creates a new TestFluidObject.\n\t * @param runtime - The data store runtime.\n\t * @param context - The data store context.\n\t * @param factoryEntries - A list of id to IChannelFactory mapping. For each item in the list,\n\t * a shared object is created which can be retrieved by calling getSharedObject() with the id;\n\t */\n\tconstructor(\n\t\tpublic readonly runtime: IFluidDataStoreRuntime,\n\t\tpublic readonly channel: IFluidDataStoreChannel,\n\t\tpublic readonly context: IFluidDataStoreContext,\n\t\tprivate readonly factoryEntriesMap: Map<string, IChannelFactory>,\n\t) {\n\t\tthis.innerHandle = new FluidObjectHandle(this, \"\", runtime.objectsRoutingContext);\n\t}\n\n\t/**\n\t * Retrieves a shared object with the given id.\n\t * @param id - The id of the shared object to retrieve.\n\t */\n\tpublic async getSharedObject<T = any>(id: string): Promise<T> {\n\t\tif (this.factoryEntriesMap === undefined) {\n\t\t\tthrow new Error(\"Shared objects were not provided during creation.\");\n\t\t}\n\n\t\tfor (const key of this.factoryEntriesMap.keys()) {\n\t\t\tif (key === id) {\n\t\t\t\tconst handle = this.root.get<IFluidHandle>(id);\n\t\t\t\treturn handle?.get() as unknown as T;\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(`Shared object with id ${id} not found.`);\n\t}\n\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\treturn defaultFluidObjectRequestHandler(this, request);\n\t}\n\n\tprivate async initialize(existing: boolean) {\n\t\tif (!existing) {\n\t\t\tthis.root = SharedMap.create(this.runtime, \"root\");\n\n\t\t\tthis.factoryEntriesMap.forEach((sharedObjectFactory: IChannelFactory, key: string) => {\n\t\t\t\tconst sharedObject = this.runtime.createChannel(key, sharedObjectFactory.type);\n\t\t\t\tthis.root.set(key, sharedObject.handle);\n\t\t\t});\n\n\t\t\tthis.root.bindToContext();\n\t\t}\n\n\t\tthis.root = (await this.runtime.getChannel(\"root\")) as ISharedMap;\n\t}\n}\n\nexport type ChannelFactoryRegistry = Iterable<[string | undefined, IChannelFactory]>;\n\n/**\n * Creates a factory for a TestFluidObject with the given object factory entries. It creates a data store runtime\n * with the object factories in the entry list. All the entries with an id other than undefined are passed to the\n * Fluid object so that it can create a shared object for each.\n *\n * @example\n * The following will create a Fluid object that creates and loads a SharedString and SharedDirectory.\n * It will add SparseMatrix to the data store's factory so that it can be created later.\n *\n * ```typescript\n * new TestFluidObjectFactory([\n * [ \"sharedString\", SharedString.getFactory() ],\n * [ \"sharedDirectory\", SharedDirectory.getFactory() ],\n * [ undefined, SparseMatrix.getFactory() ],\n * ]);\n * ```\n *\n * The SharedString and SharedDirectory can be retrieved via getSharedObject() on the TestFluidObject as follows:\n *\n * ```typescript\n * sharedString = testFluidObject.getSharedObject<SharedString>(\"sharedString\");\n * sharedDir = testFluidObject.getSharedObject<SharedDirectory>(\"sharedDirectory\");\n * ```\n */\nexport class TestFluidObjectFactory implements IFluidDataStoreFactory {\n\tpublic get IFluidDataStoreFactory() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Creates a new TestFluidObjectFactory.\n\t * @param factoryEntries - A list of id to IChannelFactory mapping. It creates a data store runtime with each\n\t * IChannelFactory. Entries with string ids are passed to the Fluid object so that it can create a shared object\n\t * for it.\n\t */\n\tconstructor(\n\t\tprivate readonly factoryEntries: ChannelFactoryRegistry,\n\t\tpublic readonly type = \"TestFluidObjectFactory\",\n\t) {}\n\n\tpublic async instantiateDataStore(\n\t\tcontext: IFluidDataStoreContext,\n\t\texisting: boolean,\n\t): Promise<FluidDataStoreRuntime> {\n\t\tconst dataTypes = new Map<string, IChannelFactory>();\n\n\t\t// Add SharedMap's factory which will be used to create the root map.\n\t\tconst sharedMapFactory = SharedMap.getFactory();\n\t\tdataTypes.set(sharedMapFactory.type, sharedMapFactory);\n\n\t\t// Add the object factories to the list to be sent to data store runtime.\n\t\tfor (const entry of this.factoryEntries) {\n\t\t\tconst factory = entry[1];\n\t\t\tdataTypes.set(factory.type, factory);\n\t\t}\n\n\t\t// Create a map from the factory entries with entries that don't have the id as undefined. This will be\n\t\t// passed to the Fluid object.\n\t\tconst factoryEntriesMapForObject = new Map<string, IChannelFactory>();\n\t\tfor (const entry of this.factoryEntries) {\n\t\t\tconst id = entry[0];\n\t\t\tif (id !== undefined) {\n\t\t\t\tfactoryEntriesMapForObject.set(id, entry[1]);\n\t\t\t}\n\t\t}\n\n\t\tconst runtimeClass = mixinRequestHandler(\n\t\t\tasync (request: IRequest, rt: FluidDataStoreRuntime) => {\n\t\t\t\tconst maybeRouter: FluidObject<IProvideFluidRouter> | undefined =\n\t\t\t\t\tawait rt.entryPoint?.get();\n\t\t\t\tassert(\n\t\t\t\t\tmaybeRouter?.IFluidRouter !== undefined,\n\t\t\t\t\t\"entryPoint should have been initialized by now\",\n\t\t\t\t);\n\t\t\t\treturn maybeRouter.IFluidRouter.request(request);\n\t\t\t},\n\t\t);\n\n\t\treturn new runtimeClass(\n\t\t\tcontext,\n\t\t\tdataTypes,\n\t\t\texisting,\n\t\t\tasync (dataStoreRuntime: IFluidDataStoreRuntime) =>\n\t\t\t\tTestFluidObject.load(\n\t\t\t\t\tdataStoreRuntime,\n\t\t\t\t\t// This works because 'runtime' is an instance of runtimeClass (which is a FluidDataStoreRuntime and\n\t\t\t\t\t// thus implements IFluidDataStoreChannel) which passes itself as the parameter to this function.\n\t\t\t\t\tdataStoreRuntime as FluidDataStoreRuntime,\n\t\t\t\t\tcontext,\n\t\t\t\t\tfactoryEntriesMapForObject,\n\t\t\t\t\texisting,\n\t\t\t\t),\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"testFluidObject.js","sourceRoot":"","sources":["../src/testFluidObject.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { defaultFluidObjectRequestHandler } from \"@fluidframework/aqueduct\";\nimport {\n\tIRequest,\n\tIResponse,\n\tIFluidHandle,\n\tIFluidRouter,\n\tFluidObject,\n\tIProvideFluidRouter,\n} from \"@fluidframework/core-interfaces\";\nimport {\n\tFluidObjectHandle,\n\tFluidDataStoreRuntime,\n\tmixinRequestHandler,\n} from \"@fluidframework/datastore\";\nimport { SharedMap, ISharedMap } from \"@fluidframework/map\";\nimport {\n\tIFluidDataStoreContext,\n\tIFluidDataStoreFactory,\n\tIFluidDataStoreChannel,\n} from \"@fluidframework/runtime-definitions\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ITestFluidObject } from \"./interfaces\";\n\n/**\n * A test Fluid object that will create a shared object for each key-value pair in the factoryEntries passed to load.\n * The shared objects can be retrieved by passing the key of the entry to getSharedObject.\n * It exposes the IFluidDataStoreContext and IFluidDataStoreRuntime.\n */\nexport class TestFluidObject implements ITestFluidObject, IFluidRouter {\n\tpublic static async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tchannel: IFluidDataStoreChannel,\n\t\tcontext: IFluidDataStoreContext,\n\t\tfactoryEntries: Map<string, IChannelFactory>,\n\t\texisting: boolean,\n\t) {\n\t\tconst fluidObject = new TestFluidObject(runtime, channel, context, factoryEntries);\n\t\tawait fluidObject.initialize(existing);\n\n\t\treturn fluidObject;\n\t}\n\n\tpublic get ITestFluidObject() {\n\t\treturn this;\n\t}\n\n\tpublic get IFluidLoadable() {\n\t\treturn this;\n\t}\n\n\tpublic get IFluidRouter() {\n\t\treturn this;\n\t}\n\n\tpublic get handle(): IFluidHandle<this> {\n\t\treturn this.innerHandle;\n\t}\n\n\tpublic root!: ISharedMap;\n\tprivate readonly innerHandle: IFluidHandle<this>;\n\n\t/**\n\t * Creates a new TestFluidObject.\n\t * @param runtime - The data store runtime.\n\t * @param context - The data store context.\n\t * @param factoryEntries - A list of id to IChannelFactory mapping. For each item in the list,\n\t * a shared object is created which can be retrieved by calling getSharedObject() with the id;\n\t */\n\tconstructor(\n\t\tpublic readonly runtime: IFluidDataStoreRuntime,\n\t\tpublic readonly channel: IFluidDataStoreChannel,\n\t\tpublic readonly context: IFluidDataStoreContext,\n\t\tprivate readonly factoryEntriesMap: Map<string, IChannelFactory>,\n\t) {\n\t\tthis.innerHandle = new FluidObjectHandle(this, \"\", runtime.objectsRoutingContext);\n\t}\n\n\t/**\n\t * Retrieves a shared object with the given id.\n\t * @param id - The id of the shared object to retrieve.\n\t */\n\tpublic async getSharedObject<T = any>(id: string): Promise<T> {\n\t\tif (this.factoryEntriesMap === undefined) {\n\t\t\tthrow new Error(\"Shared objects were not provided during creation.\");\n\t\t}\n\n\t\tfor (const key of this.factoryEntriesMap.keys()) {\n\t\t\tif (key === id) {\n\t\t\t\tconst handle = this.root.get<IFluidHandle>(id);\n\t\t\t\treturn handle?.get() as unknown as T;\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(`Shared object with id ${id} not found.`);\n\t}\n\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\treturn defaultFluidObjectRequestHandler(this, request);\n\t}\n\n\tprivate async initialize(existing: boolean) {\n\t\tif (!existing) {\n\t\t\tthis.root = SharedMap.create(this.runtime, \"root\");\n\n\t\t\tthis.factoryEntriesMap.forEach((sharedObjectFactory: IChannelFactory, key: string) => {\n\t\t\t\tconst sharedObject = this.runtime.createChannel(key, sharedObjectFactory.type);\n\t\t\t\tthis.root.set(key, sharedObject.handle);\n\t\t\t});\n\n\t\t\tthis.root.bindToContext();\n\t\t}\n\n\t\tthis.root = (await this.runtime.getChannel(\"root\")) as ISharedMap;\n\t}\n}\n\nexport type ChannelFactoryRegistry = Iterable<[string | undefined, IChannelFactory]>;\n\n/**\n * Creates a factory for a TestFluidObject with the given object factory entries. It creates a data store runtime\n * with the object factories in the entry list. All the entries with an id other than undefined are passed to the\n * Fluid object so that it can create a shared object for each.\n *\n * @example\n * The following will create a Fluid object that creates and loads a SharedString and SharedDirectory.\n * It will add SparseMatrix to the data store's factory so that it can be created later.\n *\n * ```typescript\n * new TestFluidObjectFactory([\n * [ \"sharedString\", SharedString.getFactory() ],\n * [ \"sharedDirectory\", SharedDirectory.getFactory() ],\n * [ undefined, SparseMatrix.getFactory() ],\n * ]);\n * ```\n *\n * The SharedString and SharedDirectory can be retrieved via getSharedObject() on the TestFluidObject as follows:\n *\n * ```typescript\n * sharedString = testFluidObject.getSharedObject<SharedString>(\"sharedString\");\n * sharedDir = testFluidObject.getSharedObject<SharedDirectory>(\"sharedDirectory\");\n * ```\n *\n * @privateRemarks - Beware that using this class generally forfeits some compatibility coverage\n * `describeCompat` aims to provide:\n * `SharedMap`s always reference the current version of SharedMap.\n * AB#4670 tracks improving this situation.\n */\nexport class TestFluidObjectFactory implements IFluidDataStoreFactory {\n\tpublic get IFluidDataStoreFactory() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Creates a new TestFluidObjectFactory.\n\t * @param factoryEntries - A list of id to IChannelFactory mapping. It creates a data store runtime with each\n\t * IChannelFactory. Entries with string ids are passed to the Fluid object so that it can create a shared object\n\t * for it.\n\t */\n\tconstructor(\n\t\tprivate readonly factoryEntries: ChannelFactoryRegistry,\n\t\tpublic readonly type = \"TestFluidObjectFactory\",\n\t) {}\n\n\tpublic async instantiateDataStore(\n\t\tcontext: IFluidDataStoreContext,\n\t\texisting: boolean,\n\t): Promise<FluidDataStoreRuntime> {\n\t\tconst dataTypes = new Map<string, IChannelFactory>();\n\n\t\t// Add SharedMap's factory which will be used to create the root map.\n\t\tconst sharedMapFactory = SharedMap.getFactory();\n\t\tdataTypes.set(sharedMapFactory.type, sharedMapFactory);\n\n\t\t// Add the object factories to the list to be sent to data store runtime.\n\t\tfor (const entry of this.factoryEntries) {\n\t\t\tconst factory = entry[1];\n\t\t\tdataTypes.set(factory.type, factory);\n\t\t}\n\n\t\t// Create a map from the factory entries with entries that don't have the id as undefined. This will be\n\t\t// passed to the Fluid object.\n\t\tconst factoryEntriesMapForObject = new Map<string, IChannelFactory>();\n\t\tfor (const entry of this.factoryEntries) {\n\t\t\tconst id = entry[0];\n\t\t\tif (id !== undefined) {\n\t\t\t\tfactoryEntriesMapForObject.set(id, entry[1]);\n\t\t\t}\n\t\t}\n\n\t\tconst runtimeClass = mixinRequestHandler(\n\t\t\tasync (request: IRequest, rt: FluidDataStoreRuntime) => {\n\t\t\t\tconst maybeRouter: FluidObject<IProvideFluidRouter> | undefined =\n\t\t\t\t\tawait rt.entryPoint?.get();\n\t\t\t\tassert(\n\t\t\t\t\tmaybeRouter?.IFluidRouter !== undefined,\n\t\t\t\t\t\"entryPoint should have been initialized by now\",\n\t\t\t\t);\n\t\t\t\treturn maybeRouter.IFluidRouter.request(request);\n\t\t\t},\n\t\t);\n\n\t\treturn new runtimeClass(\n\t\t\tcontext,\n\t\t\tdataTypes,\n\t\t\texisting,\n\t\t\tasync (dataStoreRuntime: IFluidDataStoreRuntime) =>\n\t\t\t\tTestFluidObject.load(\n\t\t\t\t\tdataStoreRuntime,\n\t\t\t\t\t// This works because 'runtime' is an instance of runtimeClass (which is a FluidDataStoreRuntime and\n\t\t\t\t\t// thus implements IFluidDataStoreChannel) which passes itself as the parameter to this function.\n\t\t\t\t\tdataStoreRuntime as FluidDataStoreRuntime,\n\t\t\t\t\tcontext,\n\t\t\t\t\tfactoryEntriesMapForObject,\n\t\t\t\t\texisting,\n\t\t\t\t),\n\t\t);\n\t}\n}\n"]}
|
package/dist/timeoutUtils.d.ts
CHANGED
|
@@ -24,6 +24,26 @@ export interface TimeoutWithValue<T = void> {
|
|
|
24
24
|
value: T;
|
|
25
25
|
}
|
|
26
26
|
export declare type PromiseExecutor<T = void> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Wraps the given promise around with promise that will complete after a specific timeout if the original promise does
|
|
29
|
+
* not resolve by then. By default, it uses the mocha test timeout and complete the promise just before that so that
|
|
30
|
+
* tests don't time out because of unpredictable awaits.
|
|
31
|
+
* The timeout can be overridden via timeoutOptions but it's recommended to use the default value.
|
|
32
|
+
* @param promise - The promise to be awaited.
|
|
33
|
+
* @param timeoutOptions - Options that can be used to override the timeout and / or define the behavior
|
|
34
|
+
* when the promise is not fulfilled. For example, instead of rejecting the promise, resolve with a
|
|
35
|
+
* specific value.
|
|
36
|
+
* @returns A new promise that will complete when the given promise resolves or the timeout expires.
|
|
37
|
+
*/
|
|
27
38
|
export declare function timeoutAwait<T = void>(promise: PromiseLike<T>, timeoutOptions?: TimeoutWithError | TimeoutWithValue<T>): Promise<T>;
|
|
39
|
+
/**
|
|
40
|
+
* Creates a promise from the given executor that will complete after a specific timeout. By default, it uses the mocha
|
|
41
|
+
* test timeout and complete the promise just before that so that tests don't time out because of unpredictable awaits.
|
|
42
|
+
* The timeout can be overridden via timeoutOptions but it's recommended to use the default value.
|
|
43
|
+
* @param executor - The executor for the promise.
|
|
44
|
+
* @param timeoutOptions - Options that can be used to override the timeout and / or define the behavior when
|
|
45
|
+
* the promise is not fulfilled. For example, instead of rejecting the promise, resolve with a specific value.
|
|
46
|
+
* @returns A new promise that will complete when the given executor resolves or the timeout expires.
|
|
47
|
+
*/
|
|
28
48
|
export declare function timeoutPromise<T = void>(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void, timeoutOptions?: TimeoutWithError | TimeoutWithValue<T>): Promise<T>;
|
|
29
49
|
//# sourceMappingURL=timeoutUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeoutUtils.d.ts","sourceRoot":"","sources":["../src/timeoutUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,eAAO,MAAM,wBAAwB,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"timeoutUtils.d.ts","sourceRoot":"","sources":["../src/timeoutUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,eAAO,MAAM,wBAAwB,MAAM,CAAC;AA8F5C,MAAM,WAAW,gBAAgB;IAChC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,IAAI;IACzC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,CAAC,CAAC;CACT;AAED,oBAAY,eAAe,CAAC,CAAC,GAAG,IAAI,IAAI,CACvC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,EAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,KAC1B,IAAI,CAAC;AAEV;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,CAAC,GAAG,IAAI,EAC1C,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,EACvB,cAAc,GAAE,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAM,GACzD,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,CAAC,GAAG,IAAI,EAC5C,QAAQ,EAAE,CACT,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,EAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,KAC1B,IAAI,EACT,cAAc,GAAE,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAM,GACzD,OAAO,CAAC,CAAC,CAAC,CA6BZ"}
|
package/dist/timeoutUtils.js
CHANGED
|
@@ -8,10 +8,12 @@ exports.timeoutPromise = exports.timeoutAwait = exports.defaultTimeoutDurationMs
|
|
|
8
8
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
9
9
|
// @deprecated this value is no longer used
|
|
10
10
|
exports.defaultTimeoutDurationMs = 250;
|
|
11
|
-
// TestTimeout class manage tracking of test timeout. It create a timer when timeout is in effect,
|
|
12
|
-
// and provide a promise that will be reject before the test timeout happen with a `timeBuffer` of 15 ms.
|
|
13
|
-
// Once rejected, a new TestTimeout object will be create for the timeout.
|
|
14
11
|
const timeBuffer = 15; // leave 15 ms leeway for finish processing
|
|
12
|
+
// TestTimeout class that manages tracking of test timeout. It creates a timer when timeout is in effect,
|
|
13
|
+
// and provides a promise that will be rejected some time (as defined by `timeBuffer`) before the test timeout happens.
|
|
14
|
+
// This will ensure that async awaits in tests do not end up timing out the tests but resolve / reject
|
|
15
|
+
// before that happens.
|
|
16
|
+
// Once rejected, a new TestTimeout object will be create for the timeout.
|
|
15
17
|
class TestTimeout {
|
|
16
18
|
constructor() {
|
|
17
19
|
this.timeout = 0;
|
|
@@ -84,37 +86,30 @@ if (globalThis.getMochaModule !== undefined) {
|
|
|
84
86
|
oldClearTimeoutFunc.call(this);
|
|
85
87
|
};
|
|
86
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Wraps the given promise around with promise that will complete after a specific timeout if the original promise does
|
|
91
|
+
* not resolve by then. By default, it uses the mocha test timeout and complete the promise just before that so that
|
|
92
|
+
* tests don't time out because of unpredictable awaits.
|
|
93
|
+
* The timeout can be overridden via timeoutOptions but it's recommended to use the default value.
|
|
94
|
+
* @param promise - The promise to be awaited.
|
|
95
|
+
* @param timeoutOptions - Options that can be used to override the timeout and / or define the behavior
|
|
96
|
+
* when the promise is not fulfilled. For example, instead of rejecting the promise, resolve with a
|
|
97
|
+
* specific value.
|
|
98
|
+
* @returns A new promise that will complete when the given promise resolves or the timeout expires.
|
|
99
|
+
*/
|
|
87
100
|
async function timeoutAwait(promise, timeoutOptions = {}) {
|
|
88
101
|
return Promise.race([promise, timeoutPromise(() => { }, timeoutOptions)]);
|
|
89
102
|
}
|
|
90
103
|
exports.timeoutAwait = timeoutAwait;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
101
|
-
const errorObject = err;
|
|
102
|
-
errorObject.message = `${errorObject.message} (${timeout}ms)`;
|
|
103
|
-
reject(err);
|
|
104
|
-
};
|
|
105
|
-
const timer = setTimeout(() => timeoutOptions.reject === false
|
|
106
|
-
? resolve(timeoutOptions.value)
|
|
107
|
-
: timeoutRejections(), timeout);
|
|
108
|
-
executor((value) => {
|
|
109
|
-
clearTimeout(timer);
|
|
110
|
-
resolve(value);
|
|
111
|
-
}, (reason) => {
|
|
112
|
-
clearTimeout(timer);
|
|
113
|
-
reject(reason);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
// Create a promise based on test timeout and the timeout options
|
|
104
|
+
/**
|
|
105
|
+
* Creates a promise from the given executor that will complete after a specific timeout. By default, it uses the mocha
|
|
106
|
+
* test timeout and complete the promise just before that so that tests don't time out because of unpredictable awaits.
|
|
107
|
+
* The timeout can be overridden via timeoutOptions but it's recommended to use the default value.
|
|
108
|
+
* @param executor - The executor for the promise.
|
|
109
|
+
* @param timeoutOptions - Options that can be used to override the timeout and / or define the behavior when
|
|
110
|
+
* the promise is not fulfilled. For example, instead of rejecting the promise, resolve with a specific value.
|
|
111
|
+
* @returns A new promise that will complete when the given executor resolves or the timeout expires.
|
|
112
|
+
*/
|
|
118
113
|
async function timeoutPromise(executor, timeoutOptions = {}) {
|
|
119
114
|
var _a;
|
|
120
115
|
// create the timeout error outside the async task, so its callstack includes
|
|
@@ -143,4 +138,30 @@ async function timeoutPromise(executor, timeoutOptions = {}) {
|
|
|
143
138
|
});
|
|
144
139
|
}
|
|
145
140
|
exports.timeoutPromise = timeoutPromise;
|
|
141
|
+
// Create a promise based on the timeout options
|
|
142
|
+
async function getTimeoutPromise(executor, timeoutOptions, err) {
|
|
143
|
+
var _a;
|
|
144
|
+
const timeout = (_a = timeoutOptions.durationMs) !== null && _a !== void 0 ? _a : 0;
|
|
145
|
+
if (timeout <= 0 || !Number.isFinite(timeout)) {
|
|
146
|
+
return new Promise(executor);
|
|
147
|
+
}
|
|
148
|
+
return new Promise((resolve, reject) => {
|
|
149
|
+
const timeoutRejections = () => {
|
|
150
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
151
|
+
const errorObject = err;
|
|
152
|
+
errorObject.message = `${errorObject.message} (${timeout}ms)`;
|
|
153
|
+
reject(err);
|
|
154
|
+
};
|
|
155
|
+
const timer = setTimeout(() => timeoutOptions.reject === false
|
|
156
|
+
? resolve(timeoutOptions.value)
|
|
157
|
+
: timeoutRejections(), timeout);
|
|
158
|
+
executor((value) => {
|
|
159
|
+
clearTimeout(timer);
|
|
160
|
+
resolve(value);
|
|
161
|
+
}, (reason) => {
|
|
162
|
+
clearTimeout(timer);
|
|
163
|
+
reject(reason);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
146
167
|
//# sourceMappingURL=timeoutUtils.js.map
|
package/dist/timeoutUtils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeoutUtils.js","sourceRoot":"","sources":["../src/timeoutUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\n\n// @deprecated this value is no longer used\nexport const defaultTimeoutDurationMs = 250;\n\n// TestTimeout class manage tracking of test timeout. It create a timer when timeout is in effect,\n// and provide a promise that will be reject before the test timeout happen with a `timeBuffer` of 15 ms.\n// Once rejected, a new TestTimeout object will be create for the timeout.\n\nconst timeBuffer = 15; // leave 15 ms leeway for finish processing\n\nclass TestTimeout {\n\tprivate timeout: number = 0;\n\tprivate timer: NodeJS.Timeout | undefined;\n\tprivate readonly deferred: Deferred<void>;\n\tprivate rejected = false;\n\n\tprivate static instance: TestTimeout = new TestTimeout();\n\tpublic static reset(runnable: Mocha.Runnable) {\n\t\tTestTimeout.clear();\n\t\tTestTimeout.instance.resetTimer(runnable);\n\t}\n\n\tpublic static clear() {\n\t\tif (TestTimeout.instance.rejected) {\n\t\t\tTestTimeout.instance = new TestTimeout();\n\t\t} else {\n\t\t\tTestTimeout.instance.clearTimer();\n\t\t}\n\t}\n\n\tpublic static getInstance() {\n\t\treturn TestTimeout.instance;\n\t}\n\n\tpublic async getPromise() {\n\t\treturn this.deferred.promise;\n\t}\n\n\tpublic getTimeout() {\n\t\treturn this.timeout;\n\t}\n\n\tprivate constructor() {\n\t\tthis.deferred = new Deferred();\n\t\t// Ignore rejection for timeout promise if no one is waiting for it.\n\t\tthis.deferred.promise.catch(() => {});\n\t}\n\n\tprivate resetTimer(runnable: Mocha.Runnable) {\n\t\tassert(!this.timer, \"clearTimer should have been called before reset\");\n\t\tassert(!this.deferred.isCompleted, \"can't reset a completed TestTimeout\");\n\n\t\t// Check the test timeout setting\n\t\tconst timeout = runnable.timeout();\n\t\tif (!(Number.isFinite(timeout) && timeout > 0)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// subtract a buffer\n\t\tthis.timeout = Math.max(timeout - timeBuffer, 1);\n\n\t\t// Set up timer to reject near the test timeout.\n\t\tthis.timer = setTimeout(() => {\n\t\t\tthis.deferred.reject(this);\n\t\t\tthis.rejected = true;\n\t\t}, this.timeout);\n\t}\n\tprivate clearTimer() {\n\t\tif (this.timer) {\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.timer = undefined;\n\t\t}\n\t}\n}\n\n// only register if we are running with mocha-test-setup loaded\nif (globalThis.getMochaModule !== undefined) {\n\t// patching resetTimeout and clearTimeout on the runnable object\n\t// so we can track when test timeout are enforced\n\tconst mochaModule = globalThis.getMochaModule() as typeof Mocha;\n\tconst runnablePrototype = mochaModule.Runnable.prototype;\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tconst oldResetTimeoutFunc = runnablePrototype.resetTimeout;\n\trunnablePrototype.resetTimeout = function (this: Mocha.Runnable) {\n\t\toldResetTimeoutFunc.call(this);\n\t\tTestTimeout.reset(this);\n\t};\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tconst oldClearTimeoutFunc = runnablePrototype.clearTimeout;\n\trunnablePrototype.clearTimeout = function (this: Mocha.Runnable) {\n\t\tTestTimeout.clear();\n\t\toldClearTimeoutFunc.call(this);\n\t};\n}\n\nexport interface TimeoutWithError {\n\t/**\n\t * Timeout duration in milliseconds, if it is great than 0 and not Infinity\n\t * If it is undefined, then it will use test timeout if we are in side the test function\n\t * Otherwise, there is no timeout\n\t */\n\tdurationMs?: number;\n\treject?: true;\n\terrorMsg?: string;\n}\nexport interface TimeoutWithValue<T = void> {\n\t/**\n\t * Timeout duration in milliseconds, if it is great than 0 and not Infinity\n\t * If it is undefined, then it will use test timeout if we are in side the test function\n\t * Otherwise, there is no timeout\n\t */\n\tdurationMs?: number;\n\treject: false;\n\tvalue: T;\n}\n\nexport type PromiseExecutor<T = void> = (\n\tresolve: (value: T | PromiseLike<T>) => void,\n\treject: (reason?: any) => void,\n) => void;\n\nexport async function timeoutAwait<T = void>(\n\tpromise: PromiseLike<T>,\n\ttimeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},\n) {\n\treturn Promise.race([promise, timeoutPromise<T>(() => {}, timeoutOptions)]);\n}\n\n// Create a promise based on the timeout options\nasync function getTimeoutPromise<T = void>(\n\texecutor: (\n\t\tresolve: (value: T | PromiseLike<T>) => void,\n\t\treject: (reason?: any) => void,\n\t) => void,\n\ttimeoutOptions: TimeoutWithError | TimeoutWithValue<T>,\n\terr: Error | undefined,\n) {\n\tconst timeout = timeoutOptions.durationMs ?? 0;\n\tif (timeout <= 0 || !Number.isFinite(timeout)) {\n\t\treturn new Promise(executor);\n\t}\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\tconst timeoutRejections = () => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst errorObject = err!;\n\t\t\terrorObject.message = `${errorObject.message} (${timeout}ms)`;\n\t\t\treject(err);\n\t\t};\n\t\tconst timer = setTimeout(\n\t\t\t() =>\n\t\t\t\ttimeoutOptions.reject === false\n\t\t\t\t\t? resolve(timeoutOptions.value)\n\t\t\t\t\t: timeoutRejections(),\n\t\t\ttimeout,\n\t\t);\n\n\t\texecutor(\n\t\t\t(value) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(reason) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\treject(reason);\n\t\t\t},\n\t\t);\n\t});\n}\n\n// Create a promise based on test timeout and the timeout options\nexport async function timeoutPromise<T = void>(\n\texecutor: (\n\t\tresolve: (value: T | PromiseLike<T>) => void,\n\t\treject: (reason?: any) => void,\n\t) => void,\n\ttimeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},\n): Promise<T> {\n\t// create the timeout error outside the async task, so its callstack includes\n\t// the original call site, this makes it easier to debug\n\tconst err =\n\t\ttimeoutOptions.reject === false\n\t\t\t? undefined\n\t\t\t: new Error(timeoutOptions.errorMsg ?? \"Timed out\");\n\tconst executorPromise = getTimeoutPromise(executor, timeoutOptions, err);\n\n\tconst currentTestTimeout = TestTimeout.getInstance();\n\tif (currentTestTimeout === undefined) {\n\t\treturn executorPromise;\n\t}\n\n\treturn Promise.race([executorPromise, currentTestTimeout.getPromise()]).catch((e) => {\n\t\tif (e === currentTestTimeout) {\n\t\t\tif (timeoutOptions.reject !== false) {\n\t\t\t\t// If the rejection is because of the timeout then\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst errorObject = err!;\n\t\t\t\terrorObject.message = `${\n\t\t\t\t\ttimeoutOptions.errorMsg ?? \"Test timed out\"\n\t\t\t\t} (${currentTestTimeout.getTimeout()}ms)`;\n\t\t\t\tthrow errorObject;\n\t\t\t}\n\t\t\treturn timeoutOptions.value;\n\t\t}\n\t\tthrow e;\n\t}) as Promise<T>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"timeoutUtils.js","sourceRoot":"","sources":["../src/timeoutUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\n\n// @deprecated this value is no longer used\nexport const defaultTimeoutDurationMs = 250;\n\nconst timeBuffer = 15; // leave 15 ms leeway for finish processing\n\n// TestTimeout class that manages tracking of test timeout. It creates a timer when timeout is in effect,\n// and provides a promise that will be rejected some time (as defined by `timeBuffer`) before the test timeout happens.\n// This will ensure that async awaits in tests do not end up timing out the tests but resolve / reject\n// before that happens.\n// Once rejected, a new TestTimeout object will be create for the timeout.\nclass TestTimeout {\n\tprivate timeout: number = 0;\n\tprivate timer: NodeJS.Timeout | undefined;\n\tprivate readonly deferred: Deferred<void>;\n\tprivate rejected = false;\n\n\tprivate static instance: TestTimeout = new TestTimeout();\n\tpublic static reset(runnable: Mocha.Runnable) {\n\t\tTestTimeout.clear();\n\t\tTestTimeout.instance.resetTimer(runnable);\n\t}\n\n\tpublic static clear() {\n\t\tif (TestTimeout.instance.rejected) {\n\t\t\tTestTimeout.instance = new TestTimeout();\n\t\t} else {\n\t\t\tTestTimeout.instance.clearTimer();\n\t\t}\n\t}\n\n\tpublic static getInstance() {\n\t\treturn TestTimeout.instance;\n\t}\n\n\tpublic async getPromise() {\n\t\treturn this.deferred.promise;\n\t}\n\n\tpublic getTimeout() {\n\t\treturn this.timeout;\n\t}\n\n\tprivate constructor() {\n\t\tthis.deferred = new Deferred();\n\t\t// Ignore rejection for timeout promise if no one is waiting for it.\n\t\tthis.deferred.promise.catch(() => {});\n\t}\n\n\tprivate resetTimer(runnable: Mocha.Runnable) {\n\t\tassert(!this.timer, \"clearTimer should have been called before reset\");\n\t\tassert(!this.deferred.isCompleted, \"can't reset a completed TestTimeout\");\n\n\t\t// Check the test timeout setting\n\t\tconst timeout = runnable.timeout();\n\t\tif (!(Number.isFinite(timeout) && timeout > 0)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// subtract a buffer\n\t\tthis.timeout = Math.max(timeout - timeBuffer, 1);\n\n\t\t// Set up timer to reject near the test timeout.\n\t\tthis.timer = setTimeout(() => {\n\t\t\tthis.deferred.reject(this);\n\t\t\tthis.rejected = true;\n\t\t}, this.timeout);\n\t}\n\tprivate clearTimer() {\n\t\tif (this.timer) {\n\t\t\tclearTimeout(this.timer);\n\t\t\tthis.timer = undefined;\n\t\t}\n\t}\n}\n\n// only register if we are running with mocha-test-setup loaded\nif (globalThis.getMochaModule !== undefined) {\n\t// patching resetTimeout and clearTimeout on the runnable object\n\t// so we can track when test timeout are enforced\n\tconst mochaModule = globalThis.getMochaModule() as typeof Mocha;\n\tconst runnablePrototype = mochaModule.Runnable.prototype;\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tconst oldResetTimeoutFunc = runnablePrototype.resetTimeout;\n\trunnablePrototype.resetTimeout = function (this: Mocha.Runnable) {\n\t\toldResetTimeoutFunc.call(this);\n\t\tTestTimeout.reset(this);\n\t};\n\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\tconst oldClearTimeoutFunc = runnablePrototype.clearTimeout;\n\trunnablePrototype.clearTimeout = function (this: Mocha.Runnable) {\n\t\tTestTimeout.clear();\n\t\toldClearTimeoutFunc.call(this);\n\t};\n}\n\nexport interface TimeoutWithError {\n\t/**\n\t * Timeout duration in milliseconds, if it is great than 0 and not Infinity\n\t * If it is undefined, then it will use test timeout if we are in side the test function\n\t * Otherwise, there is no timeout\n\t */\n\tdurationMs?: number;\n\treject?: true;\n\terrorMsg?: string;\n}\nexport interface TimeoutWithValue<T = void> {\n\t/**\n\t * Timeout duration in milliseconds, if it is great than 0 and not Infinity\n\t * If it is undefined, then it will use test timeout if we are in side the test function\n\t * Otherwise, there is no timeout\n\t */\n\tdurationMs?: number;\n\treject: false;\n\tvalue: T;\n}\n\nexport type PromiseExecutor<T = void> = (\n\tresolve: (value: T | PromiseLike<T>) => void,\n\treject: (reason?: any) => void,\n) => void;\n\n/**\n * Wraps the given promise around with promise that will complete after a specific timeout if the original promise does\n * not resolve by then. By default, it uses the mocha test timeout and complete the promise just before that so that\n * tests don't time out because of unpredictable awaits.\n * The timeout can be overridden via timeoutOptions but it's recommended to use the default value.\n * @param promise - The promise to be awaited.\n * @param timeoutOptions - Options that can be used to override the timeout and / or define the behavior\n * when the promise is not fulfilled. For example, instead of rejecting the promise, resolve with a\n * specific value.\n * @returns A new promise that will complete when the given promise resolves or the timeout expires.\n */\nexport async function timeoutAwait<T = void>(\n\tpromise: PromiseLike<T>,\n\ttimeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},\n): Promise<T> {\n\treturn Promise.race([promise, timeoutPromise<T>(() => {}, timeoutOptions)]);\n}\n\n/**\n * Creates a promise from the given executor that will complete after a specific timeout. By default, it uses the mocha\n * test timeout and complete the promise just before that so that tests don't time out because of unpredictable awaits.\n * The timeout can be overridden via timeoutOptions but it's recommended to use the default value.\n * @param executor - The executor for the promise.\n * @param timeoutOptions - Options that can be used to override the timeout and / or define the behavior when\n * the promise is not fulfilled. For example, instead of rejecting the promise, resolve with a specific value.\n * @returns A new promise that will complete when the given executor resolves or the timeout expires.\n */\nexport async function timeoutPromise<T = void>(\n\texecutor: (\n\t\tresolve: (value: T | PromiseLike<T>) => void,\n\t\treject: (reason?: any) => void,\n\t) => void,\n\ttimeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},\n): Promise<T> {\n\t// create the timeout error outside the async task, so its callstack includes\n\t// the original call site, this makes it easier to debug\n\tconst err =\n\t\ttimeoutOptions.reject === false\n\t\t\t? undefined\n\t\t\t: new Error(timeoutOptions.errorMsg ?? \"Timed out\");\n\tconst executorPromise = getTimeoutPromise(executor, timeoutOptions, err);\n\n\tconst currentTestTimeout = TestTimeout.getInstance();\n\tif (currentTestTimeout === undefined) {\n\t\treturn executorPromise;\n\t}\n\n\treturn Promise.race([executorPromise, currentTestTimeout.getPromise()]).catch((e) => {\n\t\tif (e === currentTestTimeout) {\n\t\t\tif (timeoutOptions.reject !== false) {\n\t\t\t\t// If the rejection is because of the timeout then\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst errorObject = err!;\n\t\t\t\terrorObject.message = `${\n\t\t\t\t\ttimeoutOptions.errorMsg ?? \"Test timed out\"\n\t\t\t\t} (${currentTestTimeout.getTimeout()}ms)`;\n\t\t\t\tthrow errorObject;\n\t\t\t}\n\t\t\treturn timeoutOptions.value;\n\t\t}\n\t\tthrow e;\n\t}) as Promise<T>;\n}\n\n// Create a promise based on the timeout options\nasync function getTimeoutPromise<T = void>(\n\texecutor: (\n\t\tresolve: (value: T | PromiseLike<T>) => void,\n\t\treject: (reason?: any) => void,\n\t) => void,\n\ttimeoutOptions: TimeoutWithError | TimeoutWithValue<T>,\n\terr: Error | undefined,\n) {\n\tconst timeout = timeoutOptions.durationMs ?? 0;\n\tif (timeout <= 0 || !Number.isFinite(timeout)) {\n\t\treturn new Promise(executor);\n\t}\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\tconst timeoutRejections = () => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst errorObject = err!;\n\t\t\terrorObject.message = `${errorObject.message} (${timeout}ms)`;\n\t\t\treject(err);\n\t\t};\n\t\tconst timer = setTimeout(\n\t\t\t() =>\n\t\t\t\ttimeoutOptions.reject === false\n\t\t\t\t\t? resolve(timeoutOptions.value)\n\t\t\t\t\t: timeoutRejections(),\n\t\t\ttimeout,\n\t\t);\n\n\t\texecutor(\n\t\t\t(value) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(reason) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\treject(reason);\n\t\t\t},\n\t\t);\n\t});\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/test-utils",
|
|
3
|
-
"version": "2.0.0-internal.5.
|
|
3
|
+
"version": "2.0.0-internal.5.2.0",
|
|
4
4
|
"description": "Utilities for Fluid tests",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -35,38 +35,38 @@
|
|
|
35
35
|
"temp-directory": "nyc/.nyc_output"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@fluidframework/aqueduct": ">=2.0.0-internal.5.
|
|
38
|
+
"@fluidframework/aqueduct": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
39
39
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
40
40
|
"@fluidframework/common-utils": "^1.1.1",
|
|
41
|
-
"@fluidframework/container-definitions": ">=2.0.0-internal.5.
|
|
42
|
-
"@fluidframework/container-loader": ">=2.0.0-internal.5.
|
|
43
|
-
"@fluidframework/container-runtime": ">=2.0.0-internal.5.
|
|
44
|
-
"@fluidframework/container-runtime-definitions": ">=2.0.0-internal.5.
|
|
45
|
-
"@fluidframework/core-interfaces": ">=2.0.0-internal.5.
|
|
46
|
-
"@fluidframework/datastore": ">=2.0.0-internal.5.
|
|
47
|
-
"@fluidframework/datastore-definitions": ">=2.0.0-internal.5.
|
|
48
|
-
"@fluidframework/driver-definitions": ">=2.0.0-internal.5.
|
|
49
|
-
"@fluidframework/driver-utils": ">=2.0.0-internal.5.
|
|
50
|
-
"@fluidframework/local-driver": ">=2.0.0-internal.5.
|
|
51
|
-
"@fluidframework/map": ">=2.0.0-internal.5.
|
|
41
|
+
"@fluidframework/container-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
42
|
+
"@fluidframework/container-loader": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
43
|
+
"@fluidframework/container-runtime": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
44
|
+
"@fluidframework/container-runtime-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
45
|
+
"@fluidframework/core-interfaces": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
46
|
+
"@fluidframework/datastore": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
47
|
+
"@fluidframework/datastore-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
48
|
+
"@fluidframework/driver-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
49
|
+
"@fluidframework/driver-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
50
|
+
"@fluidframework/local-driver": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
51
|
+
"@fluidframework/map": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
52
52
|
"@fluidframework/protocol-definitions": "^1.1.0",
|
|
53
|
-
"@fluidframework/request-handler": ">=2.0.0-internal.5.
|
|
54
|
-
"@fluidframework/routerlicious-driver": ">=2.0.0-internal.5.
|
|
55
|
-
"@fluidframework/runtime-definitions": ">=2.0.0-internal.5.
|
|
56
|
-
"@fluidframework/runtime-utils": ">=2.0.0-internal.5.
|
|
57
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-internal.5.
|
|
58
|
-
"@fluidframework/test-driver-definitions": ">=2.0.0-internal.5.
|
|
59
|
-
"@fluidframework/test-runtime-utils": ">=2.0.0-internal.5.
|
|
53
|
+
"@fluidframework/request-handler": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
54
|
+
"@fluidframework/routerlicious-driver": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
55
|
+
"@fluidframework/runtime-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
56
|
+
"@fluidframework/runtime-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
57
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
58
|
+
"@fluidframework/test-driver-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
59
|
+
"@fluidframework/test-runtime-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
60
60
|
"best-random": "^1.0.0",
|
|
61
61
|
"debug": "^4.1.1",
|
|
62
62
|
"uuid": "^8.3.1"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@fluid-tools/build-cli": "^0.
|
|
65
|
+
"@fluid-tools/build-cli": "^0.20.0",
|
|
66
66
|
"@fluidframework/build-common": "^1.2.0",
|
|
67
|
-
"@fluidframework/build-tools": "^0.
|
|
67
|
+
"@fluidframework/build-tools": "^0.20.0",
|
|
68
68
|
"@fluidframework/eslint-config-fluid": "^2.0.0",
|
|
69
|
-
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.5.
|
|
69
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
|
|
70
70
|
"@fluidframework/test-utils-previous": "npm:@fluidframework/test-utils@2.0.0-internal.5.0.0",
|
|
71
71
|
"@microsoft/api-extractor": "^7.34.4",
|
|
72
72
|
"@types/debug": "^4.1.5",
|
package/src/packageVersion.ts
CHANGED
package/src/testFluidObject.ts
CHANGED
|
@@ -145,6 +145,11 @@ export type ChannelFactoryRegistry = Iterable<[string | undefined, IChannelFacto
|
|
|
145
145
|
* sharedString = testFluidObject.getSharedObject<SharedString>("sharedString");
|
|
146
146
|
* sharedDir = testFluidObject.getSharedObject<SharedDirectory>("sharedDirectory");
|
|
147
147
|
* ```
|
|
148
|
+
*
|
|
149
|
+
* @privateRemarks - Beware that using this class generally forfeits some compatibility coverage
|
|
150
|
+
* `describeCompat` aims to provide:
|
|
151
|
+
* `SharedMap`s always reference the current version of SharedMap.
|
|
152
|
+
* AB#4670 tracks improving this situation.
|
|
148
153
|
*/
|
|
149
154
|
export class TestFluidObjectFactory implements IFluidDataStoreFactory {
|
|
150
155
|
public get IFluidDataStoreFactory() {
|
package/src/timeoutUtils.ts
CHANGED
|
@@ -8,12 +8,13 @@ import { assert, Deferred } from "@fluidframework/common-utils";
|
|
|
8
8
|
// @deprecated this value is no longer used
|
|
9
9
|
export const defaultTimeoutDurationMs = 250;
|
|
10
10
|
|
|
11
|
-
// TestTimeout class manage tracking of test timeout. It create a timer when timeout is in effect,
|
|
12
|
-
// and provide a promise that will be reject before the test timeout happen with a `timeBuffer` of 15 ms.
|
|
13
|
-
// Once rejected, a new TestTimeout object will be create for the timeout.
|
|
14
|
-
|
|
15
11
|
const timeBuffer = 15; // leave 15 ms leeway for finish processing
|
|
16
12
|
|
|
13
|
+
// TestTimeout class that manages tracking of test timeout. It creates a timer when timeout is in effect,
|
|
14
|
+
// and provides a promise that will be rejected some time (as defined by `timeBuffer`) before the test timeout happens.
|
|
15
|
+
// This will ensure that async awaits in tests do not end up timing out the tests but resolve / reject
|
|
16
|
+
// before that happens.
|
|
17
|
+
// Once rejected, a new TestTimeout object will be create for the timeout.
|
|
17
18
|
class TestTimeout {
|
|
18
19
|
private timeout: number = 0;
|
|
19
20
|
private timer: NodeJS.Timeout | undefined;
|
|
@@ -125,13 +126,70 @@ export type PromiseExecutor<T = void> = (
|
|
|
125
126
|
reject: (reason?: any) => void,
|
|
126
127
|
) => void;
|
|
127
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Wraps the given promise around with promise that will complete after a specific timeout if the original promise does
|
|
131
|
+
* not resolve by then. By default, it uses the mocha test timeout and complete the promise just before that so that
|
|
132
|
+
* tests don't time out because of unpredictable awaits.
|
|
133
|
+
* The timeout can be overridden via timeoutOptions but it's recommended to use the default value.
|
|
134
|
+
* @param promise - The promise to be awaited.
|
|
135
|
+
* @param timeoutOptions - Options that can be used to override the timeout and / or define the behavior
|
|
136
|
+
* when the promise is not fulfilled. For example, instead of rejecting the promise, resolve with a
|
|
137
|
+
* specific value.
|
|
138
|
+
* @returns A new promise that will complete when the given promise resolves or the timeout expires.
|
|
139
|
+
*/
|
|
128
140
|
export async function timeoutAwait<T = void>(
|
|
129
141
|
promise: PromiseLike<T>,
|
|
130
142
|
timeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},
|
|
131
|
-
) {
|
|
143
|
+
): Promise<T> {
|
|
132
144
|
return Promise.race([promise, timeoutPromise<T>(() => {}, timeoutOptions)]);
|
|
133
145
|
}
|
|
134
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Creates a promise from the given executor that will complete after a specific timeout. By default, it uses the mocha
|
|
149
|
+
* test timeout and complete the promise just before that so that tests don't time out because of unpredictable awaits.
|
|
150
|
+
* The timeout can be overridden via timeoutOptions but it's recommended to use the default value.
|
|
151
|
+
* @param executor - The executor for the promise.
|
|
152
|
+
* @param timeoutOptions - Options that can be used to override the timeout and / or define the behavior when
|
|
153
|
+
* the promise is not fulfilled. For example, instead of rejecting the promise, resolve with a specific value.
|
|
154
|
+
* @returns A new promise that will complete when the given executor resolves or the timeout expires.
|
|
155
|
+
*/
|
|
156
|
+
export async function timeoutPromise<T = void>(
|
|
157
|
+
executor: (
|
|
158
|
+
resolve: (value: T | PromiseLike<T>) => void,
|
|
159
|
+
reject: (reason?: any) => void,
|
|
160
|
+
) => void,
|
|
161
|
+
timeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},
|
|
162
|
+
): Promise<T> {
|
|
163
|
+
// create the timeout error outside the async task, so its callstack includes
|
|
164
|
+
// the original call site, this makes it easier to debug
|
|
165
|
+
const err =
|
|
166
|
+
timeoutOptions.reject === false
|
|
167
|
+
? undefined
|
|
168
|
+
: new Error(timeoutOptions.errorMsg ?? "Timed out");
|
|
169
|
+
const executorPromise = getTimeoutPromise(executor, timeoutOptions, err);
|
|
170
|
+
|
|
171
|
+
const currentTestTimeout = TestTimeout.getInstance();
|
|
172
|
+
if (currentTestTimeout === undefined) {
|
|
173
|
+
return executorPromise;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return Promise.race([executorPromise, currentTestTimeout.getPromise()]).catch((e) => {
|
|
177
|
+
if (e === currentTestTimeout) {
|
|
178
|
+
if (timeoutOptions.reject !== false) {
|
|
179
|
+
// If the rejection is because of the timeout then
|
|
180
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
181
|
+
const errorObject = err!;
|
|
182
|
+
errorObject.message = `${
|
|
183
|
+
timeoutOptions.errorMsg ?? "Test timed out"
|
|
184
|
+
} (${currentTestTimeout.getTimeout()}ms)`;
|
|
185
|
+
throw errorObject;
|
|
186
|
+
}
|
|
187
|
+
return timeoutOptions.value;
|
|
188
|
+
}
|
|
189
|
+
throw e;
|
|
190
|
+
}) as Promise<T>;
|
|
191
|
+
}
|
|
192
|
+
|
|
135
193
|
// Create a promise based on the timeout options
|
|
136
194
|
async function getTimeoutPromise<T = void>(
|
|
137
195
|
executor: (
|
|
@@ -173,41 +231,3 @@ async function getTimeoutPromise<T = void>(
|
|
|
173
231
|
);
|
|
174
232
|
});
|
|
175
233
|
}
|
|
176
|
-
|
|
177
|
-
// Create a promise based on test timeout and the timeout options
|
|
178
|
-
export async function timeoutPromise<T = void>(
|
|
179
|
-
executor: (
|
|
180
|
-
resolve: (value: T | PromiseLike<T>) => void,
|
|
181
|
-
reject: (reason?: any) => void,
|
|
182
|
-
) => void,
|
|
183
|
-
timeoutOptions: TimeoutWithError | TimeoutWithValue<T> = {},
|
|
184
|
-
): Promise<T> {
|
|
185
|
-
// create the timeout error outside the async task, so its callstack includes
|
|
186
|
-
// the original call site, this makes it easier to debug
|
|
187
|
-
const err =
|
|
188
|
-
timeoutOptions.reject === false
|
|
189
|
-
? undefined
|
|
190
|
-
: new Error(timeoutOptions.errorMsg ?? "Timed out");
|
|
191
|
-
const executorPromise = getTimeoutPromise(executor, timeoutOptions, err);
|
|
192
|
-
|
|
193
|
-
const currentTestTimeout = TestTimeout.getInstance();
|
|
194
|
-
if (currentTestTimeout === undefined) {
|
|
195
|
-
return executorPromise;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return Promise.race([executorPromise, currentTestTimeout.getPromise()]).catch((e) => {
|
|
199
|
-
if (e === currentTestTimeout) {
|
|
200
|
-
if (timeoutOptions.reject !== false) {
|
|
201
|
-
// If the rejection is because of the timeout then
|
|
202
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
203
|
-
const errorObject = err!;
|
|
204
|
-
errorObject.message = `${
|
|
205
|
-
timeoutOptions.errorMsg ?? "Test timed out"
|
|
206
|
-
} (${currentTestTimeout.getTimeout()}ms)`;
|
|
207
|
-
throw errorObject;
|
|
208
|
-
}
|
|
209
|
-
return timeoutOptions.value;
|
|
210
|
-
}
|
|
211
|
-
throw e;
|
|
212
|
-
}) as Promise<T>;
|
|
213
|
-
}
|