@digitaldefiance/express-suite-test-utils 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -70,6 +70,14 @@ MIT
70
70
 
71
71
  ## ChangeLog
72
72
 
73
+ ### v1.0.2
74
+
75
+ - Add LocalStorageMock
76
+
77
+ ### v1.0.1
78
+
79
+ - Bugfix release, fixing lack of js files in tarball
80
+
73
81
  ### v1.0.0
74
82
 
75
83
  - Initial Release
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@digitaldefiance/express-suite-test-utils",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Test utilities for Digital Defiance Express Suite",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
7
7
  "scripts": {
8
- "build": "npx nx build digitaldefiance-express-suite-test-utils",
8
+ "build": "npx nx build digitaldefiance-express-suite-test-utils && npx nx run digitaldefiance-express-suite-test-utils:postbuild",
9
9
  "build:stream": "npx nx build --outputStyle=stream digitaldefiance-express-suite-test-utils",
10
10
  "build:logged": "npx nx build --outputStyle=stream digitaldefiance-express-suite-test-utils 2>&1 | ansifilter -o build.log",
11
11
  "test": "npx nx test digitaldefiance-express-suite-test-utils",
package/src/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from './lib/to-throw-type';
2
2
  export * from './lib/console';
3
+ export * from './lib/localStorage-mock';
4
+ export * from './lib/localStorage-mock';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-express-suite-test-utils/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-express-suite-test-utils/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAA"}
package/src/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./lib/to-throw-type"), exports);
5
+ tslib_1.__exportStar(require("./lib/console"), exports);
6
+ tslib_1.__exportStar(require("./lib/localStorage-mock"), exports);
7
+ tslib_1.__exportStar(require("./lib/localStorage-mock"), exports);
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /* Reusable console mock helpers for e2e tests */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.withConsoleMocks = withConsoleMocks;
5
+ exports.spyContains = spyContains;
6
+ /**
7
+ * Wrap a test body with console spies that are always restored.
8
+ * By default mutes console output to keep test logs clean.
9
+ */
10
+ async function withConsoleMocks(options, fn) {
11
+ const mute = options?.mute !== false; // default true
12
+ const noop = () => undefined;
13
+ const spies = {
14
+ log: jest
15
+ .spyOn(console, 'log')
16
+ .mockImplementation(mute ? noop : console.log),
17
+ info: jest
18
+ .spyOn(console, 'info')
19
+ .mockImplementation(mute ? noop : console.info),
20
+ warn: jest
21
+ .spyOn(console, 'warn')
22
+ .mockImplementation(mute ? noop : console.warn),
23
+ error: jest
24
+ .spyOn(console, 'error')
25
+ .mockImplementation(mute ? noop : console.error),
26
+ debug: jest
27
+ .spyOn(console, 'debug')
28
+ .mockImplementation(mute
29
+ ? noop
30
+ : console.debug ??
31
+ noop),
32
+ };
33
+ try {
34
+ return await fn(spies);
35
+ }
36
+ finally {
37
+ spies.log.mockRestore();
38
+ spies.info.mockRestore();
39
+ spies.warn.mockRestore();
40
+ spies.error.mockRestore();
41
+ spies.debug.mockRestore();
42
+ }
43
+ }
44
+ /**
45
+ * True if any call to the spy contains all provided substrings, in order-agnostic check.
46
+ */
47
+ function spyContains(spy, ...needles) {
48
+ return spy.mock.calls.some((args) => {
49
+ const text = args.map((a) => (typeof a === 'string' ? a : '')).join(' ');
50
+ return needles.every((n) => text.includes(n));
51
+ });
52
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Simple localStorage mock for Node.js test environment
3
+ */
4
+ export declare class LocalStorageMock implements Storage {
5
+ private store;
6
+ get length(): number;
7
+ clear(): void;
8
+ getItem(key: string): string | null;
9
+ key(index: number): string | null;
10
+ removeItem(key: string): void;
11
+ setItem(key: string, value: string): void;
12
+ }
13
+ //# sourceMappingURL=localStorage-mock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localStorage-mock.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-test-utils/src/lib/localStorage-mock.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,gBAAiB,YAAW,OAAO;IAC9C,OAAO,CAAC,KAAK,CAAkC;IAE/C,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CAG1C"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalStorageMock = void 0;
4
+ /**
5
+ * Simple localStorage mock for Node.js test environment
6
+ */
7
+ class LocalStorageMock {
8
+ store = new Map();
9
+ get length() {
10
+ return this.store.size;
11
+ }
12
+ clear() {
13
+ this.store.clear();
14
+ }
15
+ getItem(key) {
16
+ return this.store.get(key) ?? null;
17
+ }
18
+ key(index) {
19
+ const keys = Array.from(this.store.keys());
20
+ return keys[index] ?? null;
21
+ }
22
+ removeItem(key) {
23
+ this.store.delete(key);
24
+ }
25
+ setItem(key, value) {
26
+ this.store.set(key, value);
27
+ }
28
+ }
29
+ exports.LocalStorageMock = LocalStorageMock;
30
+ // Set up global localStorage mock
31
+ if (typeof globalThis.localStorage === 'undefined') {
32
+ Object.defineProperty(globalThis, 'localStorage', {
33
+ value: new LocalStorageMock(),
34
+ writable: true,
35
+ configurable: true,
36
+ });
37
+ }
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toThrowType = void 0;
4
+ const globals_1 = require("@jest/globals");
5
+ const fs_1 = require("fs");
6
+ function isMatcherError(error) {
7
+ return error instanceof Error && 'matcherResult' in error;
8
+ }
9
+ function extractTestInfo(stackTrace) {
10
+ const stackLines = stackTrace.split('\n');
11
+ const anonymousLine = stackLines.find((line) => line.includes('Object.<anonymous>'));
12
+ const match = anonymousLine?.match(/\((.+?\.spec\.ts):(\d+):(\d+)\)/);
13
+ if (!match) {
14
+ return { testHierarchy: ['Unknown Test'], location: '' };
15
+ }
16
+ const fullTestPath = match[1];
17
+ const lineNumber = parseInt(match[2]);
18
+ const testFile = fullTestPath.split('/').pop() || '';
19
+ try {
20
+ const fileContent = (0, fs_1.readFileSync)(fullTestPath, 'utf8');
21
+ const lines = fileContent.split('\n');
22
+ const testLineContent = lines[lineNumber - 1];
23
+ const testNameMatch = testLineContent.match(/it\(['"](.+?)['"]/);
24
+ const testName = testNameMatch?.[1];
25
+ const testHierarchy = ['Test'];
26
+ if (testName) {
27
+ testHierarchy.push(testName);
28
+ }
29
+ return {
30
+ testHierarchy,
31
+ location: ` (${testFile}:${lineNumber})`,
32
+ };
33
+ }
34
+ catch {
35
+ return {
36
+ testHierarchy: ['Test'],
37
+ location: ` (${testFile}:${lineNumber})`,
38
+ };
39
+ }
40
+ }
41
+ const toThrowType = async function (received, errorType, validator) {
42
+ const matcherName = 'toThrowType';
43
+ const options = {
44
+ isNot: this.isNot,
45
+ promise: this.promise,
46
+ };
47
+ let error;
48
+ let pass = false;
49
+ try {
50
+ if (this.promise) {
51
+ try {
52
+ await received;
53
+ pass = false;
54
+ }
55
+ catch (e) {
56
+ error = e;
57
+ if (error instanceof Error &&
58
+ (error instanceof errorType || error.constructor === errorType)) {
59
+ pass = true;
60
+ if (validator) {
61
+ await validator(error);
62
+ }
63
+ }
64
+ }
65
+ }
66
+ else {
67
+ if (typeof received !== 'function') {
68
+ throw new Error(this.utils.matcherHint(matcherName, undefined, undefined, options) +
69
+ '\n\n' +
70
+ 'Received value must be a function');
71
+ }
72
+ try {
73
+ await received();
74
+ pass = false;
75
+ }
76
+ catch (e) {
77
+ error = e;
78
+ if (error instanceof Error &&
79
+ (error instanceof errorType || error.constructor === errorType)) {
80
+ pass = true;
81
+ if (validator) {
82
+ await validator(error);
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+ catch (validatorError) {
89
+ const error = validatorError instanceof Error
90
+ ? validatorError
91
+ : new Error(String(validatorError));
92
+ const message = error.message;
93
+ const stack = error.stack || '';
94
+ let diffString;
95
+ if (isMatcherError(error) && error.matcherResult) {
96
+ diffString =
97
+ this.utils.diff(error.matcherResult.expected, error.matcherResult.received) || '';
98
+ }
99
+ else {
100
+ diffString = this.utils.diff('Error to match assertions', message) || '';
101
+ }
102
+ const { testHierarchy, location } = extractTestInfo(stack);
103
+ return {
104
+ pass: false,
105
+ message: () => `\n\n${this.utils.RECEIVED_COLOR(`● ${testHierarchy.join(' › ')}${location ? ` ${location}` : ''}`)}\n\n` +
106
+ this.utils.matcherHint(matcherName, undefined, undefined, options) +
107
+ '\n\n' +
108
+ diffString +
109
+ '\n\n' +
110
+ (stack
111
+ ? this.utils.RECEIVED_COLOR(stack.split('\n').slice(1).join('\n'))
112
+ : ''),
113
+ };
114
+ }
115
+ const testHeader = error instanceof Error && error.stack
116
+ ? (() => {
117
+ const { testHierarchy, location } = extractTestInfo(error.stack);
118
+ return `\n\n${this.utils.RECEIVED_COLOR(`● ${testHierarchy.join(' › ')}${location}`)}\n\n`;
119
+ })()
120
+ : '\n';
121
+ return {
122
+ pass,
123
+ message: () => testHeader +
124
+ this.utils.matcherHint(matcherName, undefined, undefined, options) +
125
+ '\n\n' +
126
+ (pass
127
+ ? `Expected function not to throw ${this.utils.printExpected(errorType.name)}`
128
+ : this.promise
129
+ ? this.utils.matcherErrorMessage(this.utils.matcherHint(matcherName, undefined, undefined, options), 'Expected promise to reject', 'Promise resolved successfully')
130
+ : this.utils.matcherErrorMessage(this.utils.matcherHint(matcherName, undefined, undefined, options), `Expected function to throw ${this.utils.printExpected(errorType.name)}`, `Received: ${this.utils.printReceived(error instanceof Error ? error.constructor.name : typeof error)}`)),
131
+ };
132
+ };
133
+ exports.toThrowType = toThrowType;
134
+ globals_1.expect.extend({ toThrowType: exports.toThrowType });
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ /// <reference types="jest" />
3
+ Object.defineProperty(exports, "__esModule", { value: true });