@fluid-internal/mocha-test-setup 2.0.0-dev-rc.3.0.0.250606

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.eslintrc.cjs +8 -0
  2. package/CHANGELOG.md +132 -0
  3. package/LICENSE +21 -0
  4. package/README.md +151 -0
  5. package/api-extractor-lint.json +4 -0
  6. package/api-extractor.json +8 -0
  7. package/api-report/mocha-test-setup.api.md +18 -0
  8. package/dist/index.d.ts +6 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +10 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/mochaHooks.d.ts +14 -0
  13. package/dist/mochaHooks.d.ts.map +1 -0
  14. package/dist/mochaHooks.js +138 -0
  15. package/dist/mochaHooks.js.map +1 -0
  16. package/dist/package.json +3 -0
  17. package/dist/packageVersion.d.ts +9 -0
  18. package/dist/packageVersion.d.ts.map +1 -0
  19. package/dist/packageVersion.js +12 -0
  20. package/dist/packageVersion.js.map +1 -0
  21. package/dist/tsdoc-metadata.json +11 -0
  22. package/lib/index.d.ts +6 -0
  23. package/lib/index.d.ts.map +1 -0
  24. package/lib/index.js +6 -0
  25. package/lib/index.js.map +1 -0
  26. package/lib/mochaHooks.d.ts +14 -0
  27. package/lib/mochaHooks.d.ts.map +1 -0
  28. package/lib/mochaHooks.js +112 -0
  29. package/lib/mochaHooks.js.map +1 -0
  30. package/lib/packageVersion.d.ts +9 -0
  31. package/lib/packageVersion.d.ts.map +1 -0
  32. package/lib/packageVersion.js +9 -0
  33. package/lib/packageVersion.js.map +1 -0
  34. package/mocharc-common.cjs +88 -0
  35. package/package.json +81 -0
  36. package/prettier.config.cjs +8 -0
  37. package/src/index.ts +6 -0
  38. package/src/mochaHooks.ts +127 -0
  39. package/src/packageVersion.ts +9 -0
  40. package/test-config.json +10 -0
  41. package/tsconfig.cjs.json +7 -0
  42. package/tsconfig.esnext.json +7 -0
  43. package/tsconfig.json +10 -0
package/.eslintrc.cjs ADDED
@@ -0,0 +1,8 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ module.exports = {
7
+ extends: ["@fluidframework/eslint-config-fluid/minimal-deprecated", "prettier"],
8
+ };
package/CHANGELOG.md ADDED
@@ -0,0 +1,132 @@
1
+ # @fluid-internal/mocha-test-setup
2
+
3
+ ## 2.0.0-rc.2.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - @fluidframework/mocha-test-setup moved to @fluid-internal/mocha-test-setup ([#19759](https://github.com/microsoft/FluidFramework/issues/19759)) [d530594684](https://github.com/microsoft/FluidFramework/commits/d530594684e074caa3c1899fdf332d3a3208969f)
8
+
9
+ The mocha-test-setup package is intended to aid in testing internal to the FluidFramework repo, and should not be used outside of the repo.
10
+
11
+ ## 2.0.0-rc.1.0.0
12
+
13
+ Dependency updates only.
14
+
15
+ ## 2.0.0-internal.8.0.0
16
+
17
+ Dependency updates only.
18
+
19
+ ## 2.0.0-internal.7.4.0
20
+
21
+ ### Minor Changes
22
+
23
+ - azure-client: Deprecated FluidStatic Classes ([#18402](https://github.com/microsoft/FluidFramework/issues/18402)) [589ec39de5](https://github.com/microsoft/FluidFramework/commits/589ec39de52116c7f782319e6f6aa61bc5aa9964)
24
+
25
+ Several FluidStatic classes were unnecessarily exposed. They have been replaced with creation functions. This helps us
26
+ keep implementations decoupled from usage which is easier to maintain and extend. It has very minimal impact on the
27
+ public surface area of downstream packages. The deprecated classes are as follows:
28
+
29
+ - `AzureAudience` (use `IAzureAudience` instead)
30
+ - `TinyliciousAudience` (use `ITinyliciousAudience` instead)
31
+ - `DOProviderContainerRuntimeFactory`
32
+ - `FluidContainer`
33
+ - `ServiceAudience`
34
+
35
+ ## 2.0.0-internal.7.3.0
36
+
37
+ Dependency updates only.
38
+
39
+ ## 2.0.0-internal.7.2.0
40
+
41
+ Dependency updates only.
42
+
43
+ ## 2.0.0-internal.7.1.0
44
+
45
+ Dependency updates only.
46
+
47
+ ## 2.0.0-internal.7.0.0
48
+
49
+ ### Major Changes
50
+
51
+ - Minimum TypeScript version now 5.1.6 [871b3493dd](https://github.com/microsoft/FluidFramework/commits/871b3493dd0d7ea3a89be64998ceb6cb9021a04e)
52
+
53
+ The minimum supported TypeScript version for Fluid 2.0 clients is now 5.1.6.
54
+
55
+ ## 2.0.0-internal.6.4.0
56
+
57
+ Dependency updates only.
58
+
59
+ ## 2.0.0-internal.6.3.0
60
+
61
+ Dependency updates only.
62
+
63
+ ## 2.0.0-internal.6.2.0
64
+
65
+ ### Minor Changes
66
+
67
+ - Remove use of @fluidframework/common-definitions ([#16638](https://github.com/microsoft/FluidFramework/issues/16638)) [a8c81509c9](https://github.com/microsoft/FluidFramework/commits/a8c81509c9bf09cfb2092ebcf7265205f9eb6dbf)
68
+
69
+ The **@fluidframework/common-definitions** package is being deprecated, so the following interfaces and types are now
70
+ imported from the **@fluidframework/core-interfaces** package:
71
+
72
+ - interface IDisposable
73
+ - interface IErrorEvent
74
+ - interface IErrorEvent
75
+ - interface IEvent
76
+ - interface IEventProvider
77
+ - interface ILoggingError
78
+ - interface ITaggedTelemetryPropertyType
79
+ - interface ITelemetryBaseEvent
80
+ - interface ITelemetryBaseLogger
81
+ - interface ITelemetryErrorEvent
82
+ - interface ITelemetryGenericEvent
83
+ - interface ITelemetryLogger
84
+ - interface ITelemetryPerformanceEvent
85
+ - interface ITelemetryProperties
86
+ - type ExtendEventProvider
87
+ - type IEventThisPlaceHolder
88
+ - type IEventTransformer
89
+ - type ReplaceIEventThisPlaceHolder
90
+ - type ReplaceIEventThisPlaceHolder
91
+ - type TelemetryEventCategory
92
+ - type TelemetryEventPropertyType
93
+
94
+ ## 2.0.0-internal.6.1.0
95
+
96
+ Dependency updates only.
97
+
98
+ ## 2.0.0-internal.6.0.0
99
+
100
+ ### Major Changes
101
+
102
+ - Upgraded typescript transpilation target to ES2020 [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
103
+
104
+ Upgraded typescript transpilation target to ES2020. This is done in order to decrease the bundle sizes of Fluid Framework packages. This has provided size improvements across the board for ex. Loader, Driver, Runtime etc. Reduced bundle sizes helps to load lesser code in apps and hence also helps to improve the perf.If any app wants to target any older versions of browsers with which this target version is not compatible, then they can use packages like babel to transpile to a older target.
105
+
106
+ ## 2.0.0-internal.5.4.0
107
+
108
+ Dependency updates only.
109
+
110
+ ## 2.0.0-internal.5.3.0
111
+
112
+ Dependency updates only.
113
+
114
+ ## 2.0.0-internal.5.2.0
115
+
116
+ Dependency updates only.
117
+
118
+ ## 2.0.0-internal.5.1.0
119
+
120
+ Dependency updates only.
121
+
122
+ ## 2.0.0-internal.5.0.0
123
+
124
+ Dependency updates only.
125
+
126
+ ## 2.0.0-internal.4.4.0
127
+
128
+ Dependency updates only.
129
+
130
+ ## 2.0.0-internal.4.1.0
131
+
132
+ Dependency updates only.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) Microsoft Corporation and contributors. All rights reserved.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # @fluid-internal/mocha-test-setup
2
+
3
+ <!-- AUTO-GENERATED-CONTENT:START (README_PACKAGE_SCOPE_NOTICE:packageJsonPath=./package.json) -->
4
+
5
+ **IMPORTANT: This package is intended strictly as an implementation detail of the Fluid Framework and is not intended for public consumption.**
6
+ **We make no stability guarantees regarding its APIs.**
7
+
8
+ <!-- AUTO-GENERATED-CONTENT:END -->
9
+
10
+ This package has a few main purposes:
11
+
12
+ - Expose/generate a default `.mocharc.cjs` configuration for running [mocha](https://mochajs.org) tests, which other
13
+ packages can extend.
14
+ - Map paths for required packages/modules to account for [Lerna](https://lerna.js.org/)'s dependency hoisting.
15
+ - Add mocha `beforeAll`, `beforeEach` and `afterEach` [root hook plugins](https://mochajs.org/#root-hook-plugins) to add
16
+ some special behavior when we run tests.
17
+
18
+ ## Base `mocharc.cjs` configuration
19
+
20
+ To leverage the base mocha configuration exposed by this package, first add it as a `devDependency` to your `package.json`
21
+ (the rest of the file has been omitted):
22
+
23
+ ```json
24
+ {
25
+ "devDependencies": {
26
+ "@fluid-internal/mocha-test-setup": "version-that-matches-the-rest-of-the-release-group"
27
+ }
28
+ }
29
+ ```
30
+
31
+ Then put this in a `.mocharc.cjs` file at the root of your package:
32
+
33
+ ```javascript
34
+ "use strict";
35
+
36
+ const getFluidTestMochaConfig = require("@fluid-internal/mocha-test-setup/mocharc-common");
37
+
38
+ const packageDir = __dirname;
39
+ const config = getFluidTestMochaConfig(packageDir);
40
+ module.exports = config;
41
+ ```
42
+
43
+ If you need extra configuration, make changes to the `config` object before assigning it to `module.exports`.
44
+
45
+ Mocha will use this file by default if no path to a configuration file is provided explicitly.
46
+
47
+ The default configuration generated by `getFluidTestMochaConfig()` looks like this:
48
+
49
+ ```jsonc
50
+ {
51
+ "exit": true,
52
+ "recursive": true,
53
+ "require": ["path1", "path2"], // Mapped paths for packages/modules indicated as required when calling getFluidTestMochaConfig()
54
+ "unhandled-rejections": "strict",
55
+ };
56
+ ```
57
+
58
+ The configuration will have additional settings if the following environment variables are present:
59
+
60
+ ### FLUID_TEST_TIMEOUT
61
+
62
+ If it exists, the default configuration will also include this:
63
+
64
+ ```json
65
+ {
66
+ "timeout": "<value-of-FLUID_TEST_TIMEOUT>"
67
+ }
68
+ ```
69
+
70
+ ### FLUID_TEST_FORBID_ONLY
71
+
72
+ If it exists, the default configuration will also include this:
73
+
74
+ ```json
75
+ {
76
+ "forbid-only": "true"
77
+ }
78
+ ```
79
+
80
+ ### FLUID_LOGGER_PROPS
81
+
82
+ In case there is a need to override telemetry metrics, one can make use of an environment variable `FLUID_LOGGER_PROPS`,
83
+ that to override them during execution time:
84
+
85
+ ```
86
+ FLUID_LOGGER_PROPS='{ "hostName": "Benchmark" }'
87
+ ```
88
+
89
+ ## Mapping of package paths to account for Lerna hoisting
90
+
91
+ The way we use Lerna to manage our monorepo, package dependencies are sometimes moved out of the `node_modules` folder
92
+ of the package that declares them, and into a `node_modules` folder at the root of the release group.
93
+ This applies to external dependencies (i.e. not between packages in our repo) that are present in more than one of our
94
+ packages, including `mocha` itself as well as other test runners, which means that their path when they execute
95
+ might not be the one you'd normally expect.
96
+ This can cause issues when test scripts point to other dependencies of the package being tested (e.g. with the `-r/--require`
97
+ flag) when running tests.
98
+ This utility maps the paths of packages/modules passed to the `getFluidTestMochaConfig()` function, to ensure they are
99
+ imported from whichever location they end up at.
100
+
101
+ **NOTE**: once we move to `pnpm` this functionality might become irrelevant because `pnpm` keeps all dependencies in the
102
+ expected paths and creates the necessary symlinks, instead of changing where dependency folders are located.
103
+
104
+ ### Considerations for non-package/module arguments
105
+
106
+ Sometimes you'll want to provide a package/module/path as an argument when executing your tests but outside of the
107
+ required packages that you can pass to `getFluidTestMochaConfig()`.
108
+ For example, the path to a reporter file:
109
+
110
+ ```console
111
+ mocha --require @fluid-internal/mocha-test-setup --reporter @fluid-tools/benchmark/dist/MochaMemoryTestReporter.js
112
+ ```
113
+
114
+ Depending on where that file is coming from, you'll need to be careful with how that path is specified.
115
+ E.g. `@fluid-tools/benchmark`, while being part of the repository, is not part of any release group, so it will always
116
+ be downloaded from the public npm feed and treated as an external dependency.
117
+ Since several packages declare it as a dependency, Lerna will hoist it to `node_modules` at the root of the release group.
118
+ In general, the safest solution is to specify it starting with the package name (including scope if applicable).
119
+ This might break in a few edge cases as long as we use Lerna with hoisting, so we'll have to deal with them individually.
120
+
121
+ A particular way of specifying a package/module/path (e.g. starting with the package name vs starting with `node_modules/`)
122
+ might behave differently locally and in CI builds, so that's another factor to keep in mind.
123
+
124
+ ## Special behavior
125
+
126
+ ### Supress console output by default
127
+
128
+ `console.log()`, `console.warn()` and `console.error()` are disabled by default when using this package.
129
+ They can be re-enabled by setting the `FLUID_TEST_VERBOSE` environment variable to any non-empty value, e.g.
130
+ `FLUID_TEST_VERBOSE=1`.
131
+
132
+ ### Telemetry events
133
+
134
+ A couple of telemetry events `fluid:telemetry:Test_start` and `fluid:telemetry:Test_end` will be generated for each test.
135
+ The `Test_end` event includes fields with the test's state (passing/failed), its duration, if it timed out.
136
+ If a `FLUID_TEST_VARIANT` environment variable exists, the `testVariant` field in the events will have its value.
137
+
138
+ ### Support for a custom logger
139
+
140
+ This utility supports using a custom logger implementation.
141
+ This can be useful to send the operational telemetry generated by the FluidFramework while the tests are running, to a
142
+ particular log sink.
143
+
144
+ It is expected that the package with the custom logger implementation adds a `getTestLogger() => ITelemetryBufferedLogger`
145
+ function to the `global` object, which this package will call in order to obtain an instance of the custom logger.
146
+
147
+ If a custom logger implementation will be used when executing tests in a package that leverages this utility, the path
148
+ to the module with that implementation should **not** be specified with the `--require/-r` flag, but through the
149
+ `FLUID_TEST_LOGGER_PKG_PATH` environment variable.
150
+ This package has logic that needs the custom logger to be imported/executed at a particular time, and we ensure that
151
+ by requiring that the path be provided through that environment variable.
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
3
+ "extends": "../../../common/build/build-common/api-extractor-lint.esm.primary.json"
4
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
3
+ "extends": "../../../common/build/build-common/api-extractor-base.esm.primary.json",
4
+ "dtsRollup": {
5
+ // all APIs are internal - no rollup needed/used
6
+ "enabled": false
7
+ }
8
+ }
@@ -0,0 +1,18 @@
1
+ ## API Report File for "@fluid-internal/mocha-test-setup"
2
+
3
+ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4
+
5
+ ```ts
6
+
7
+ /// <reference types="mocha" />
8
+
9
+ // @internal (undocumented)
10
+ export const mochaHooks: {
11
+ beforeAll(): void;
12
+ beforeEach(this: Mocha.Context): void;
13
+ afterEach(this: Mocha.Context): void;
14
+ };
15
+
16
+ // (No @packageDocumentation comment for this package)
17
+
18
+ ```
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export { mochaHooks } from "./mochaHooks.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.mochaHooks = void 0;
8
+ var mochaHooks_js_1 = require("./mochaHooks.js");
9
+ Object.defineProperty(exports, "mochaHooks", { enumerable: true, get: function () { return mochaHooks_js_1.mochaHooks; } });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,iDAA6C;AAApC,2GAAA,UAAU,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { mochaHooks } from \"./mochaHooks.js\";\n"]}
@@ -0,0 +1,14 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /// <reference types="mocha" />
6
+ /**
7
+ * @internal
8
+ */
9
+ export declare const mochaHooks: {
10
+ beforeAll(): void;
11
+ beforeEach(this: Mocha.Context): void;
12
+ afterEach(this: Mocha.Context): void;
13
+ };
14
+ //# sourceMappingURL=mochaHooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mochaHooks.d.ts","sourceRoot":"","sources":["../src/mochaHooks.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAuDH;;GAEG;AACH,eAAO,MAAM,UAAU;;qBAoBL,MAAM,OAAO;oBAoBd,MAAM,OAAO;CAqB7B,CAAC"}
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || function (mod) {
23
+ if (mod && mod.__esModule) return mod;
24
+ var result = {};
25
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
26
+ __setModuleDefault(result, mod);
27
+ return result;
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.mochaHooks = void 0;
31
+ const mochaModule = __importStar(require("mocha"));
32
+ const packageVersion_js_1 = require("./packageVersion.js");
33
+ // this will enabling capturing the full stack for errors
34
+ // since this is test capturing the full stack is worth it
35
+ // in non-test environment we need to be more cautious
36
+ // as this will incur a perf impact when errors are
37
+ // thrown and will take more storage in any logging sink
38
+ // https://v8.dev/docs/stack-trace-api
39
+ Error.stackTraceLimit = Infinity;
40
+ const testVariant = process.env.FLUID_TEST_VARIANT;
41
+ const propsDict = process.env.FLUID_LOGGER_PROPS != null ? JSON.parse(process.env.FLUID_LOGGER_PROPS) : undefined;
42
+ const _global = global;
43
+ class TestLogger {
44
+ send(event) {
45
+ // TODO: Remove when issue #7061 is resolved.
46
+ // Don't log this event as we generate too much.
47
+ if (event.eventName === "fluid:telemetry:RouterliciousDriver:readBlob_end") {
48
+ return;
49
+ }
50
+ // The test logger is currently instantiated once and for each event triggered between begin and
51
+ // end of a test, in case the testName is undefined, we will use the currentTestName.
52
+ event.testName = this.testName ?? currentTestName;
53
+ event.testVariant = testVariant;
54
+ event.hostName = packageVersion_js_1.pkgName;
55
+ this.parentLogger.send({ ...event, ...propsDict });
56
+ }
57
+ async flush() {
58
+ return this.parentLogger.flush();
59
+ }
60
+ constructor(parentLogger, testName) {
61
+ this.parentLogger = parentLogger;
62
+ this.testName = testName;
63
+ }
64
+ }
65
+ const nullLogger = {
66
+ send: () => { },
67
+ flush: async () => { },
68
+ };
69
+ const log = console.log;
70
+ const error = console.log;
71
+ const warn = console.warn;
72
+ let currentTestLogger;
73
+ let currentTestName;
74
+ let originalLogger;
75
+ /**
76
+ * @internal
77
+ */
78
+ exports.mochaHooks = {
79
+ beforeAll() {
80
+ originalLogger = _global.getTestLogger?.() ?? nullLogger;
81
+ _global.getTestLogger = () => {
82
+ // If a current test logger exists, use that. Otherwise, create a new one. This should become the
83
+ // current test logger if this function is running in a context which understands the current test.
84
+ // Otherwise, just return the created TestLogger. (This happens e.g. if someone calls `getTestLogger`
85
+ // in a `before` or `after` hook, due to the order in which mocha hooks run)
86
+ if (currentTestLogger !== undefined) {
87
+ return currentTestLogger;
88
+ }
89
+ const testLogger = new TestLogger(originalLogger, currentTestName);
90
+ if (currentTestName !== undefined) {
91
+ currentTestLogger = testLogger;
92
+ }
93
+ return testLogger;
94
+ };
95
+ },
96
+ beforeEach() {
97
+ // Suppress console.log if not verbose mode
98
+ if (process.env.FLUID_TEST_VERBOSE === undefined) {
99
+ console.log = () => { };
100
+ console.error = () => { };
101
+ console.warn = () => { };
102
+ }
103
+ // save the test name can and clear the previous logger (if afterEach didn't get ran and it got left behind)
104
+ currentTestName = this.currentTest?.fullTitle();
105
+ currentTestLogger = undefined;
106
+ // send event on test start
107
+ originalLogger.send({
108
+ category: "generic",
109
+ eventName: "fluid:telemetry:Test_start",
110
+ testName: currentTestName,
111
+ testVariant,
112
+ hostName: packageVersion_js_1.pkgName,
113
+ });
114
+ },
115
+ afterEach() {
116
+ // send event on test end
117
+ originalLogger.send({
118
+ category: "generic",
119
+ eventName: "fluid:telemetry:Test_end",
120
+ testName: currentTestName,
121
+ state: this.currentTest?.state,
122
+ duration: this.currentTest?.duration,
123
+ timedOut: this.currentTest?.timedOut,
124
+ testVariant,
125
+ hostName: packageVersion_js_1.pkgName,
126
+ });
127
+ console.log = log;
128
+ console.error = error;
129
+ console.warn = warn;
130
+ // clear the test logger and test name after each test
131
+ currentTestLogger = undefined;
132
+ currentTestName = undefined;
133
+ },
134
+ };
135
+ globalThis.getMochaModule = () => {
136
+ return mochaModule;
137
+ };
138
+ //# sourceMappingURL=mochaHooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mochaHooks.js","sourceRoot":"","sources":["../src/mochaHooks.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 { ITelemetryBaseEvent } from \"@fluidframework/core-interfaces\";\nimport { ITelemetryBufferedLogger } from \"@fluidframework/test-driver-definitions\";\nimport * as mochaModule from \"mocha\";\nimport { pkgName } from \"./packageVersion.js\";\n\n// this will enabling capturing the full stack for errors\n// since this is test capturing the full stack is worth it\n// in non-test environment we need to be more cautious\n// as this will incur a perf impact when errors are\n// thrown and will take more storage in any logging sink\n// https://v8.dev/docs/stack-trace-api\nError.stackTraceLimit = Infinity;\n\nconst testVariant = process.env.FLUID_TEST_VARIANT;\nconst propsDict =\n\tprocess.env.FLUID_LOGGER_PROPS != null ? JSON.parse(process.env.FLUID_LOGGER_PROPS) : undefined;\n\nconst _global: any = global;\nclass TestLogger implements ITelemetryBufferedLogger {\n\tsend(event: ITelemetryBaseEvent) {\n\t\t// TODO: Remove when issue #7061 is resolved.\n\t\t// Don't log this event as we generate too much.\n\t\tif (event.eventName === \"fluid:telemetry:RouterliciousDriver:readBlob_end\") {\n\t\t\treturn;\n\t\t}\n\n\t\t// The test logger is currently instantiated once and for each event triggered between begin and\n\t\t// end of a test, in case the testName is undefined, we will use the currentTestName.\n\t\tevent.testName = this.testName ?? currentTestName;\n\t\tevent.testVariant = testVariant;\n\t\tevent.hostName = pkgName;\n\t\tthis.parentLogger.send({ ...event, ...propsDict });\n\t}\n\tasync flush() {\n\t\treturn this.parentLogger.flush();\n\t}\n\tconstructor(\n\t\tprivate readonly parentLogger: ITelemetryBufferedLogger,\n\t\tprivate readonly testName: string | undefined,\n\t) {}\n}\nconst nullLogger: ITelemetryBufferedLogger = {\n\tsend: () => {},\n\tflush: async () => {},\n};\n\nconst log = console.log;\nconst error = console.log;\nconst warn = console.warn;\nlet currentTestLogger: ITelemetryBufferedLogger | undefined;\nlet currentTestName: string | undefined;\nlet originalLogger: ITelemetryBufferedLogger;\n\n/**\n * @internal\n */\nexport const mochaHooks = {\n\tbeforeAll() {\n\t\toriginalLogger = _global.getTestLogger?.() ?? nullLogger;\n\t\t_global.getTestLogger = () => {\n\t\t\t// If a current test logger exists, use that. Otherwise, create a new one. This should become the\n\t\t\t// current test logger if this function is running in a context which understands the current test.\n\t\t\t// Otherwise, just return the created TestLogger. (This happens e.g. if someone calls `getTestLogger`\n\t\t\t// in a `before` or `after` hook, due to the order in which mocha hooks run)\n\t\t\tif (currentTestLogger !== undefined) {\n\t\t\t\treturn currentTestLogger;\n\t\t\t}\n\n\t\t\tconst testLogger = new TestLogger(originalLogger, currentTestName);\n\t\t\tif (currentTestName !== undefined) {\n\t\t\t\tcurrentTestLogger = testLogger;\n\t\t\t}\n\n\t\t\treturn testLogger;\n\t\t};\n\t},\n\tbeforeEach(this: Mocha.Context) {\n\t\t// Suppress console.log if not verbose mode\n\t\tif (process.env.FLUID_TEST_VERBOSE === undefined) {\n\t\t\tconsole.log = () => {};\n\t\t\tconsole.error = () => {};\n\t\t\tconsole.warn = () => {};\n\t\t}\n\t\t// save the test name can and clear the previous logger (if afterEach didn't get ran and it got left behind)\n\t\tcurrentTestName = this.currentTest?.fullTitle();\n\t\tcurrentTestLogger = undefined;\n\n\t\t// send event on test start\n\t\toriginalLogger.send({\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"fluid:telemetry:Test_start\",\n\t\t\ttestName: currentTestName,\n\t\t\ttestVariant,\n\t\t\thostName: pkgName,\n\t\t});\n\t},\n\tafterEach(this: Mocha.Context) {\n\t\t// send event on test end\n\t\toriginalLogger.send({\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"fluid:telemetry:Test_end\",\n\t\t\ttestName: currentTestName,\n\t\t\tstate: this.currentTest?.state,\n\t\t\tduration: this.currentTest?.duration,\n\t\t\ttimedOut: this.currentTest?.timedOut,\n\t\t\ttestVariant,\n\t\t\thostName: pkgName,\n\t\t});\n\n\t\tconsole.log = log;\n\t\tconsole.error = error;\n\t\tconsole.warn = warn;\n\n\t\t// clear the test logger and test name after each test\n\t\tcurrentTestLogger = undefined;\n\t\tcurrentTestName = undefined;\n\t},\n};\n\nglobalThis.getMochaModule = () => {\n\treturn mochaModule;\n};\n"]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ *
5
+ * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
+ */
7
+ export declare const pkgName = "@fluid-internal/mocha-test-setup";
8
+ export declare const pkgVersion = "2.0.0-dev-rc.3.0.0.250606";
9
+ //# sourceMappingURL=packageVersion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,qCAAqC,CAAC;AAC1D,eAAO,MAAM,UAAU,8BAA8B,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ *
6
+ * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.pkgVersion = exports.pkgName = void 0;
10
+ exports.pkgName = "@fluid-internal/mocha-test-setup";
11
+ exports.pkgVersion = "2.0.0-dev-rc.3.0.0.250606";
12
+ //# sourceMappingURL=packageVersion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,kCAAkC,CAAC;AAC7C,QAAA,UAAU,GAAG,2BAA2B,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 = \"@fluid-internal/mocha-test-setup\";\nexport const pkgVersion = \"2.0.0-dev-rc.3.0.0.250606\";\n"]}
@@ -0,0 +1,11 @@
1
+ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
+ // It should be published with your NPM package. It should not be tracked by Git.
3
+ {
4
+ "tsdocVersion": "0.12",
5
+ "toolPackages": [
6
+ {
7
+ "packageName": "@microsoft/api-extractor",
8
+ "packageVersion": "7.42.3"
9
+ }
10
+ ]
11
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export { mochaHooks } from "./mochaHooks.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export { mochaHooks } from "./mochaHooks.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { mochaHooks } from \"./mochaHooks.js\";\n"]}
@@ -0,0 +1,14 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /// <reference types="mocha" />
6
+ /**
7
+ * @internal
8
+ */
9
+ export declare const mochaHooks: {
10
+ beforeAll(): void;
11
+ beforeEach(this: Mocha.Context): void;
12
+ afterEach(this: Mocha.Context): void;
13
+ };
14
+ //# sourceMappingURL=mochaHooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mochaHooks.d.ts","sourceRoot":"","sources":["../src/mochaHooks.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAuDH;;GAEG;AACH,eAAO,MAAM,UAAU;;qBAoBL,MAAM,OAAO;oBAoBd,MAAM,OAAO;CAqB7B,CAAC"}
@@ -0,0 +1,112 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import * as mochaModule from "mocha";
6
+ import { pkgName } from "./packageVersion.js";
7
+ // this will enabling capturing the full stack for errors
8
+ // since this is test capturing the full stack is worth it
9
+ // in non-test environment we need to be more cautious
10
+ // as this will incur a perf impact when errors are
11
+ // thrown and will take more storage in any logging sink
12
+ // https://v8.dev/docs/stack-trace-api
13
+ Error.stackTraceLimit = Infinity;
14
+ const testVariant = process.env.FLUID_TEST_VARIANT;
15
+ const propsDict = process.env.FLUID_LOGGER_PROPS != null ? JSON.parse(process.env.FLUID_LOGGER_PROPS) : undefined;
16
+ const _global = global;
17
+ class TestLogger {
18
+ send(event) {
19
+ // TODO: Remove when issue #7061 is resolved.
20
+ // Don't log this event as we generate too much.
21
+ if (event.eventName === "fluid:telemetry:RouterliciousDriver:readBlob_end") {
22
+ return;
23
+ }
24
+ // The test logger is currently instantiated once and for each event triggered between begin and
25
+ // end of a test, in case the testName is undefined, we will use the currentTestName.
26
+ event.testName = this.testName ?? currentTestName;
27
+ event.testVariant = testVariant;
28
+ event.hostName = pkgName;
29
+ this.parentLogger.send({ ...event, ...propsDict });
30
+ }
31
+ async flush() {
32
+ return this.parentLogger.flush();
33
+ }
34
+ constructor(parentLogger, testName) {
35
+ this.parentLogger = parentLogger;
36
+ this.testName = testName;
37
+ }
38
+ }
39
+ const nullLogger = {
40
+ send: () => { },
41
+ flush: async () => { },
42
+ };
43
+ const log = console.log;
44
+ const error = console.log;
45
+ const warn = console.warn;
46
+ let currentTestLogger;
47
+ let currentTestName;
48
+ let originalLogger;
49
+ /**
50
+ * @internal
51
+ */
52
+ export const mochaHooks = {
53
+ beforeAll() {
54
+ originalLogger = _global.getTestLogger?.() ?? nullLogger;
55
+ _global.getTestLogger = () => {
56
+ // If a current test logger exists, use that. Otherwise, create a new one. This should become the
57
+ // current test logger if this function is running in a context which understands the current test.
58
+ // Otherwise, just return the created TestLogger. (This happens e.g. if someone calls `getTestLogger`
59
+ // in a `before` or `after` hook, due to the order in which mocha hooks run)
60
+ if (currentTestLogger !== undefined) {
61
+ return currentTestLogger;
62
+ }
63
+ const testLogger = new TestLogger(originalLogger, currentTestName);
64
+ if (currentTestName !== undefined) {
65
+ currentTestLogger = testLogger;
66
+ }
67
+ return testLogger;
68
+ };
69
+ },
70
+ beforeEach() {
71
+ // Suppress console.log if not verbose mode
72
+ if (process.env.FLUID_TEST_VERBOSE === undefined) {
73
+ console.log = () => { };
74
+ console.error = () => { };
75
+ console.warn = () => { };
76
+ }
77
+ // save the test name can and clear the previous logger (if afterEach didn't get ran and it got left behind)
78
+ currentTestName = this.currentTest?.fullTitle();
79
+ currentTestLogger = undefined;
80
+ // send event on test start
81
+ originalLogger.send({
82
+ category: "generic",
83
+ eventName: "fluid:telemetry:Test_start",
84
+ testName: currentTestName,
85
+ testVariant,
86
+ hostName: pkgName,
87
+ });
88
+ },
89
+ afterEach() {
90
+ // send event on test end
91
+ originalLogger.send({
92
+ category: "generic",
93
+ eventName: "fluid:telemetry:Test_end",
94
+ testName: currentTestName,
95
+ state: this.currentTest?.state,
96
+ duration: this.currentTest?.duration,
97
+ timedOut: this.currentTest?.timedOut,
98
+ testVariant,
99
+ hostName: pkgName,
100
+ });
101
+ console.log = log;
102
+ console.error = error;
103
+ console.warn = warn;
104
+ // clear the test logger and test name after each test
105
+ currentTestLogger = undefined;
106
+ currentTestName = undefined;
107
+ },
108
+ };
109
+ globalThis.getMochaModule = () => {
110
+ return mochaModule;
111
+ };
112
+ //# sourceMappingURL=mochaHooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mochaHooks.js","sourceRoot":"","sources":["../src/mochaHooks.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 { ITelemetryBaseEvent } from \"@fluidframework/core-interfaces\";\nimport { ITelemetryBufferedLogger } from \"@fluidframework/test-driver-definitions\";\nimport * as mochaModule from \"mocha\";\nimport { pkgName } from \"./packageVersion.js\";\n\n// this will enabling capturing the full stack for errors\n// since this is test capturing the full stack is worth it\n// in non-test environment we need to be more cautious\n// as this will incur a perf impact when errors are\n// thrown and will take more storage in any logging sink\n// https://v8.dev/docs/stack-trace-api\nError.stackTraceLimit = Infinity;\n\nconst testVariant = process.env.FLUID_TEST_VARIANT;\nconst propsDict =\n\tprocess.env.FLUID_LOGGER_PROPS != null ? JSON.parse(process.env.FLUID_LOGGER_PROPS) : undefined;\n\nconst _global: any = global;\nclass TestLogger implements ITelemetryBufferedLogger {\n\tsend(event: ITelemetryBaseEvent) {\n\t\t// TODO: Remove when issue #7061 is resolved.\n\t\t// Don't log this event as we generate too much.\n\t\tif (event.eventName === \"fluid:telemetry:RouterliciousDriver:readBlob_end\") {\n\t\t\treturn;\n\t\t}\n\n\t\t// The test logger is currently instantiated once and for each event triggered between begin and\n\t\t// end of a test, in case the testName is undefined, we will use the currentTestName.\n\t\tevent.testName = this.testName ?? currentTestName;\n\t\tevent.testVariant = testVariant;\n\t\tevent.hostName = pkgName;\n\t\tthis.parentLogger.send({ ...event, ...propsDict });\n\t}\n\tasync flush() {\n\t\treturn this.parentLogger.flush();\n\t}\n\tconstructor(\n\t\tprivate readonly parentLogger: ITelemetryBufferedLogger,\n\t\tprivate readonly testName: string | undefined,\n\t) {}\n}\nconst nullLogger: ITelemetryBufferedLogger = {\n\tsend: () => {},\n\tflush: async () => {},\n};\n\nconst log = console.log;\nconst error = console.log;\nconst warn = console.warn;\nlet currentTestLogger: ITelemetryBufferedLogger | undefined;\nlet currentTestName: string | undefined;\nlet originalLogger: ITelemetryBufferedLogger;\n\n/**\n * @internal\n */\nexport const mochaHooks = {\n\tbeforeAll() {\n\t\toriginalLogger = _global.getTestLogger?.() ?? nullLogger;\n\t\t_global.getTestLogger = () => {\n\t\t\t// If a current test logger exists, use that. Otherwise, create a new one. This should become the\n\t\t\t// current test logger if this function is running in a context which understands the current test.\n\t\t\t// Otherwise, just return the created TestLogger. (This happens e.g. if someone calls `getTestLogger`\n\t\t\t// in a `before` or `after` hook, due to the order in which mocha hooks run)\n\t\t\tif (currentTestLogger !== undefined) {\n\t\t\t\treturn currentTestLogger;\n\t\t\t}\n\n\t\t\tconst testLogger = new TestLogger(originalLogger, currentTestName);\n\t\t\tif (currentTestName !== undefined) {\n\t\t\t\tcurrentTestLogger = testLogger;\n\t\t\t}\n\n\t\t\treturn testLogger;\n\t\t};\n\t},\n\tbeforeEach(this: Mocha.Context) {\n\t\t// Suppress console.log if not verbose mode\n\t\tif (process.env.FLUID_TEST_VERBOSE === undefined) {\n\t\t\tconsole.log = () => {};\n\t\t\tconsole.error = () => {};\n\t\t\tconsole.warn = () => {};\n\t\t}\n\t\t// save the test name can and clear the previous logger (if afterEach didn't get ran and it got left behind)\n\t\tcurrentTestName = this.currentTest?.fullTitle();\n\t\tcurrentTestLogger = undefined;\n\n\t\t// send event on test start\n\t\toriginalLogger.send({\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"fluid:telemetry:Test_start\",\n\t\t\ttestName: currentTestName,\n\t\t\ttestVariant,\n\t\t\thostName: pkgName,\n\t\t});\n\t},\n\tafterEach(this: Mocha.Context) {\n\t\t// send event on test end\n\t\toriginalLogger.send({\n\t\t\tcategory: \"generic\",\n\t\t\teventName: \"fluid:telemetry:Test_end\",\n\t\t\ttestName: currentTestName,\n\t\t\tstate: this.currentTest?.state,\n\t\t\tduration: this.currentTest?.duration,\n\t\t\ttimedOut: this.currentTest?.timedOut,\n\t\t\ttestVariant,\n\t\t\thostName: pkgName,\n\t\t});\n\n\t\tconsole.log = log;\n\t\tconsole.error = error;\n\t\tconsole.warn = warn;\n\n\t\t// clear the test logger and test name after each test\n\t\tcurrentTestLogger = undefined;\n\t\tcurrentTestName = undefined;\n\t},\n};\n\nglobalThis.getMochaModule = () => {\n\treturn mochaModule;\n};\n"]}
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ *
5
+ * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
+ */
7
+ export declare const pkgName = "@fluid-internal/mocha-test-setup";
8
+ export declare const pkgVersion = "2.0.0-dev-rc.3.0.0.250606";
9
+ //# sourceMappingURL=packageVersion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,qCAAqC,CAAC;AAC1D,eAAO,MAAM,UAAU,8BAA8B,CAAC"}
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ *
5
+ * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
+ */
7
+ export const pkgName = "@fluid-internal/mocha-test-setup";
8
+ export const pkgVersion = "2.0.0-dev-rc.3.0.0.250606";
9
+ //# sourceMappingURL=packageVersion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,kCAAkC,CAAC;AAC1D,MAAM,CAAC,MAAM,UAAU,GAAG,2BAA2B,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 = \"@fluid-internal/mocha-test-setup\";\nexport const pkgVersion = \"2.0.0-dev-rc.3.0.0.250606\";\n"]}
@@ -0,0 +1,88 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { existsSync } = require("fs");
9
+ const path = require("path");
10
+
11
+ function getFluidTestMochaConfig(packageDir, additionalRequiredModules, testReportPrefix) {
12
+ const moduleDir = `${packageDir}/node_modules`;
13
+
14
+ const requiredModules = [
15
+ // General mocha setup e.g. suppresses console.log,
16
+ // This has to be before others (except logger) so that registerMochaTestWrapperFuncs is available
17
+ "@fluid-internal/mocha-test-setup",
18
+ "source-map-support/register",
19
+ ...(additionalRequiredModules ? additionalRequiredModules : []),
20
+ ];
21
+
22
+ // mocha install node_modules directory might not be the same as the module required because of hoisting
23
+ // We need to give the full path in that case.
24
+ // TODO: this path mapping might not be necessary once we move to pnpm, since it sets up node_modules differently
25
+ // from what Lerna does (all dependencies of a given package show up in its own node_modules folder and just symlink
26
+ // to the actual location of the installed package, instead of common dependencies being hoisted to a parent
27
+ // node_modules folder and not being present at all in the package's own node_modules).
28
+ const requiredModulePaths = requiredModules.map((mod) => {
29
+ // Just return if it is path already
30
+ if (existsSync(mod) || existsSync(`${mod}.js`)) {
31
+ return mod;
32
+ }
33
+
34
+ // Try to find it in the test package's directory
35
+ const modulePath = path.join(moduleDir, mod);
36
+ if (existsSync(modulePath)) {
37
+ return modulePath;
38
+ }
39
+
40
+ // Otherwise keep it as is
41
+ return mod;
42
+ });
43
+
44
+ if (process.env.FLUID_TEST_LOGGER_PKG_PATH) {
45
+ // Inject implementation of getTestLogger, put it first before mocha-test-setup
46
+ requiredModulePaths.unshift(process.env.FLUID_TEST_LOGGER_PKG_PATH);
47
+ }
48
+
49
+ const config = {
50
+ "exit": true,
51
+ "recursive": true,
52
+ "require": requiredModulePaths,
53
+ "unhandled-rejections": "strict",
54
+ // Performance tests benefit from having access to GC, and memory tests require it.
55
+ // Exposing it here avoids all packages which do perf testing from having to expose it.
56
+ "v8-expose-gc": true,
57
+ };
58
+
59
+ if (process.env.FLUID_TEST_TIMEOUT !== undefined) {
60
+ config["timeout"] = process.env.FLUID_TEST_TIMEOUT;
61
+ }
62
+
63
+ const packageJson = require(`${packageDir}/package.json`);
64
+ config["reporter"] = `mocha-multi-reporters`;
65
+ // See https://www.npmjs.com/package/mocha-multi-reporters#cmroutput-option
66
+ const outputFilePrefix = testReportPrefix !== undefined ? `${testReportPrefix}-` : "";
67
+ console.log(
68
+ `Writing test results relative to package to nyc/${outputFilePrefix}junit-report.xml and nyc/${outputFilePrefix}junit-report.json`,
69
+ );
70
+ const suiteName =
71
+ testReportPrefix !== undefined
72
+ ? `${packageJson.name} - ${testReportPrefix}`
73
+ : packageJson.name;
74
+ config["reporter-options"] = [
75
+ `configFile=${path.join(
76
+ __dirname,
77
+ "test-config.json",
78
+ )},cmrOutput=xunit+output+${outputFilePrefix}:mocha-json-output-reporter+output+${outputFilePrefix}:xunit+suiteName+${suiteName}`,
79
+ ];
80
+
81
+ if (process.env.FLUID_TEST_FORBID_ONLY !== undefined) {
82
+ config["forbid-only"] = true;
83
+ }
84
+
85
+ return config;
86
+ }
87
+
88
+ module.exports = getFluidTestMochaConfig;
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "@fluid-internal/mocha-test-setup",
3
+ "version": "2.0.0-dev-rc.3.0.0.250606",
4
+ "description": "Utilities for Fluid tests",
5
+ "homepage": "https://fluidframework.com",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/microsoft/FluidFramework.git",
9
+ "directory": "packages/test/mocha-test-setup"
10
+ },
11
+ "license": "MIT",
12
+ "author": "Microsoft and contributors",
13
+ "sideEffects": false,
14
+ "type": "module",
15
+ "exports": {
16
+ ".": {
17
+ "import": {
18
+ "types": "./lib/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "require": {
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.js"
24
+ }
25
+ },
26
+ "./mocharc-common": {
27
+ "require": "./mocharc-common.cjs"
28
+ }
29
+ },
30
+ "main": "dist/index.js",
31
+ "types": "dist/index.d.ts",
32
+ "dependencies": {
33
+ "@fluidframework/core-interfaces": "2.0.0-dev-rc.3.0.0.250606",
34
+ "@fluidframework/test-driver-definitions": "2.0.0-dev-rc.3.0.0.250606",
35
+ "mocha": "^10.2.0",
36
+ "source-map-support": "^0.5.21"
37
+ },
38
+ "devDependencies": {
39
+ "@arethetypeswrong/cli": "^0.13.3",
40
+ "@biomejs/biome": "^1.6.2",
41
+ "@fluid-tools/build-cli": "^0.34.0",
42
+ "@fluidframework/build-common": "^2.0.3",
43
+ "@fluidframework/build-tools": "^0.34.0",
44
+ "@fluidframework/eslint-config-fluid": "^5.1.0",
45
+ "@microsoft/api-extractor": "^7.42.3",
46
+ "@types/mocha": "^9.1.1",
47
+ "@types/node": "^18.19.0",
48
+ "copyfiles": "^2.4.1",
49
+ "eslint": "~8.55.0",
50
+ "prettier": "~3.0.3",
51
+ "rimraf": "^4.4.0",
52
+ "typescript": "~5.1.6"
53
+ },
54
+ "typeValidation": {
55
+ "disabled": true,
56
+ "broken": {}
57
+ },
58
+ "scripts": {
59
+ "build": "fluid-build . --task build",
60
+ "build:commonjs": "fluid-build . --task commonjs",
61
+ "build:compile": "fluid-build . --task compile",
62
+ "build:compile:min": "npm run build:compile",
63
+ "build:docs": "api-extractor run --local",
64
+ "build:esnext": "tsc --project ./tsconfig.json",
65
+ "build:genver": "gen-version",
66
+ "check:are-the-types-wrong": "attw --pack . --entrypoints .",
67
+ "check:biome": "biome check .",
68
+ "check:prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
69
+ "check:release-tags": "api-extractor run --local --config ./api-extractor-lint.json",
70
+ "ci:build:docs": "api-extractor run",
71
+ "clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp",
72
+ "eslint": "eslint --format stylish src",
73
+ "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
74
+ "format": "fluid-build --task format .",
75
+ "format:biome": "biome check --apply .",
76
+ "format:prettier": "prettier --write . --cache --ignore-path ../../../.prettierignore",
77
+ "lint": "fluid-build . --task lint",
78
+ "lint:fix": "fluid-build . --task eslint:fix --task format",
79
+ "tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist"
80
+ }
81
+ }
@@ -0,0 +1,8 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ module.exports = {
7
+ ...require("@fluidframework/build-common/prettier.config.cjs"),
8
+ };
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export { mochaHooks } from "./mochaHooks.js";
@@ -0,0 +1,127 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { ITelemetryBaseEvent } from "@fluidframework/core-interfaces";
7
+ import { ITelemetryBufferedLogger } from "@fluidframework/test-driver-definitions";
8
+ import * as mochaModule from "mocha";
9
+ import { pkgName } from "./packageVersion.js";
10
+
11
+ // this will enabling capturing the full stack for errors
12
+ // since this is test capturing the full stack is worth it
13
+ // in non-test environment we need to be more cautious
14
+ // as this will incur a perf impact when errors are
15
+ // thrown and will take more storage in any logging sink
16
+ // https://v8.dev/docs/stack-trace-api
17
+ Error.stackTraceLimit = Infinity;
18
+
19
+ const testVariant = process.env.FLUID_TEST_VARIANT;
20
+ const propsDict =
21
+ process.env.FLUID_LOGGER_PROPS != null ? JSON.parse(process.env.FLUID_LOGGER_PROPS) : undefined;
22
+
23
+ const _global: any = global;
24
+ class TestLogger implements ITelemetryBufferedLogger {
25
+ send(event: ITelemetryBaseEvent) {
26
+ // TODO: Remove when issue #7061 is resolved.
27
+ // Don't log this event as we generate too much.
28
+ if (event.eventName === "fluid:telemetry:RouterliciousDriver:readBlob_end") {
29
+ return;
30
+ }
31
+
32
+ // The test logger is currently instantiated once and for each event triggered between begin and
33
+ // end of a test, in case the testName is undefined, we will use the currentTestName.
34
+ event.testName = this.testName ?? currentTestName;
35
+ event.testVariant = testVariant;
36
+ event.hostName = pkgName;
37
+ this.parentLogger.send({ ...event, ...propsDict });
38
+ }
39
+ async flush() {
40
+ return this.parentLogger.flush();
41
+ }
42
+ constructor(
43
+ private readonly parentLogger: ITelemetryBufferedLogger,
44
+ private readonly testName: string | undefined,
45
+ ) {}
46
+ }
47
+ const nullLogger: ITelemetryBufferedLogger = {
48
+ send: () => {},
49
+ flush: async () => {},
50
+ };
51
+
52
+ const log = console.log;
53
+ const error = console.log;
54
+ const warn = console.warn;
55
+ let currentTestLogger: ITelemetryBufferedLogger | undefined;
56
+ let currentTestName: string | undefined;
57
+ let originalLogger: ITelemetryBufferedLogger;
58
+
59
+ /**
60
+ * @internal
61
+ */
62
+ export const mochaHooks = {
63
+ beforeAll() {
64
+ originalLogger = _global.getTestLogger?.() ?? nullLogger;
65
+ _global.getTestLogger = () => {
66
+ // If a current test logger exists, use that. Otherwise, create a new one. This should become the
67
+ // current test logger if this function is running in a context which understands the current test.
68
+ // Otherwise, just return the created TestLogger. (This happens e.g. if someone calls `getTestLogger`
69
+ // in a `before` or `after` hook, due to the order in which mocha hooks run)
70
+ if (currentTestLogger !== undefined) {
71
+ return currentTestLogger;
72
+ }
73
+
74
+ const testLogger = new TestLogger(originalLogger, currentTestName);
75
+ if (currentTestName !== undefined) {
76
+ currentTestLogger = testLogger;
77
+ }
78
+
79
+ return testLogger;
80
+ };
81
+ },
82
+ beforeEach(this: Mocha.Context) {
83
+ // Suppress console.log if not verbose mode
84
+ if (process.env.FLUID_TEST_VERBOSE === undefined) {
85
+ console.log = () => {};
86
+ console.error = () => {};
87
+ console.warn = () => {};
88
+ }
89
+ // save the test name can and clear the previous logger (if afterEach didn't get ran and it got left behind)
90
+ currentTestName = this.currentTest?.fullTitle();
91
+ currentTestLogger = undefined;
92
+
93
+ // send event on test start
94
+ originalLogger.send({
95
+ category: "generic",
96
+ eventName: "fluid:telemetry:Test_start",
97
+ testName: currentTestName,
98
+ testVariant,
99
+ hostName: pkgName,
100
+ });
101
+ },
102
+ afterEach(this: Mocha.Context) {
103
+ // send event on test end
104
+ originalLogger.send({
105
+ category: "generic",
106
+ eventName: "fluid:telemetry:Test_end",
107
+ testName: currentTestName,
108
+ state: this.currentTest?.state,
109
+ duration: this.currentTest?.duration,
110
+ timedOut: this.currentTest?.timedOut,
111
+ testVariant,
112
+ hostName: pkgName,
113
+ });
114
+
115
+ console.log = log;
116
+ console.error = error;
117
+ console.warn = warn;
118
+
119
+ // clear the test logger and test name after each test
120
+ currentTestLogger = undefined;
121
+ currentTestName = undefined;
122
+ },
123
+ };
124
+
125
+ globalThis.getMochaModule = () => {
126
+ return mochaModule;
127
+ };
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ *
5
+ * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
+ */
7
+
8
+ export const pkgName = "@fluid-internal/mocha-test-setup";
9
+ export const pkgVersion = "2.0.0-dev-rc.3.0.0.250606";
@@ -0,0 +1,10 @@
1
+ {
2
+ "reporterEnabled": "xunit,mocha-json-output-reporter,spec",
3
+ "xunitReporterOptions": {
4
+ "output": "nyc/{id}junit-report.xml",
5
+ "suiteName": "{id}"
6
+ },
7
+ "mochaJsonOutputReporterReporterOptions": {
8
+ "output": "nyc/{id}junit-report.json"
9
+ }
10
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ // This config must be used in a "type": "commonjs" environment. (Use `fluid-tsc commonjs`.)
3
+ "extends": "./tsconfig.json",
4
+ "compilerOptions": {
5
+ "outDir": "./dist",
6
+ },
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./lib",
5
+ "module": "esnext",
6
+ },
7
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../../common/build/build-common/tsconfig.node16.json",
3
+ "include": ["src/**/*"],
4
+ "exclude": ["dist", "node_modules"],
5
+ "compilerOptions": {
6
+ "rootDir": "./src",
7
+ "outDir": "./lib",
8
+ "types": ["node", "mocha"],
9
+ },
10
+ }