@tutao/tutanota-test-utils 3.89.24 → 3.91.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,9 +3,4 @@
3
3
  This is a collection of common test utils we use across multiple projects/modules internally. As creating this module
4
4
  really is just an intermediate step towards re-organising some of the dependency structure of our software, it is most
5
5
  likely going to change a lot in the future and might even disappear altogether. For these reasons **we strongly
6
- discourage anyone outside of our organisation to directly depend on this module**.
7
-
8
- For now we only provide this as a flow-typed source module and not compiled for ES6 or CJS. The reason is that our
9
- current tooling (flow, rollup, webstorm) will not allow us to use the compiled version directly without putting a lot of
10
- effort into restructuring the way we build tutanota and/or changing some of our tools or losing some convenient IDE
11
- features such as usage search.
6
+ discourage anyone outside of our organisation to directly depend on this module**.
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Mocks an attribute (function or object) on an object and makes sure that it can be restored to the original attribute by calling unmockAttribute() later.
3
+ * Additionally creates a spy for the attribute if the attribute is a function.
4
+ * @param object The object on which the attribute exists.
5
+ * @param attributeOnObject The attribute to mock.
6
+ * @param attributeMock The attribute mock.
7
+ * @returns An object to be passed to unmockAttribute() in order to restore the original attribute.
8
+ */
9
+ export declare function mockAttribute(object: Record<string, any>, attributeOnObject: ((...args: Array<any>) => any) | Record<string, any>, attributeMock: ((...args: Array<any>) => any) | Record<string, any>): Record<string, any>;
10
+ export declare function unmockAttribute(mock: Record<string, any>): void;
11
+ export declare type Spy = ((...args: any) => any) & {
12
+ invocations: any[];
13
+ };
14
+ export declare function spy(producer?: (...args: any) => any): Spy;
15
+ /**
16
+ * Create partial mock, i.e. allows mocking attributes or functions on actual instances
17
+ * @param obj The base mock object on which mocker may overwrite attributes or functions
18
+ * @param mocker This function receives obj and can overwrite attributes or functions.
19
+ * @returns {T}
20
+ */
21
+ export declare const mock: <T>(obj: T, mocker: (arg0: any) => any) => T;
22
+ export declare function mapToObject<K extends string | number | symbol, V>(map: Map<K, V>): Record<K, V>;
23
+ export declare function mapObject<K extends string | number | symbol, V, R>(mapper: (arg0: V) => R, obj: Record<K, V>): Record<K, R>;
24
+ export declare function replaceAllMaps(toReplace: any): any;
25
+ /** Catch error and return either value or error */
26
+ export declare function asResult<T>(p: Promise<T>): Promise<T | Error>;
27
+ export declare function assertThrows<T extends Error>(expected: Class<T>, fn: () => Promise<unknown>): Promise<T>;
28
+ export declare function assertResolvedIn(ms: number, ...promises: ReadonlyArray<Promise<any>>): Promise<any>;
29
+ export declare function assertNotResolvedIn(ms: number, ...promises: ReadonlyArray<Promise<any>>): Promise<any>;
30
+ export interface TimeoutMock {
31
+ (fn: () => unknown, time: number): ReturnType<typeof setTimeout>;
32
+ next(): void;
33
+ }
34
+ export declare function makeTimeoutMock(): TimeoutMock;
@@ -0,0 +1,114 @@
1
+ import o from "ospec";
2
+ /**
3
+ * Mocks an attribute (function or object) on an object and makes sure that it can be restored to the original attribute by calling unmockAttribute() later.
4
+ * Additionally creates a spy for the attribute if the attribute is a function.
5
+ * @param object The object on which the attribute exists.
6
+ * @param attributeOnObject The attribute to mock.
7
+ * @param attributeMock The attribute mock.
8
+ * @returns An object to be passed to unmockAttribute() in order to restore the original attribute.
9
+ */
10
+ export function mockAttribute(object, attributeOnObject, attributeMock) {
11
+ if (attributeOnObject == null)
12
+ throw new Error("attributeOnObject is undefined");
13
+ let attributeName = Object.getOwnPropertyNames(object).find(key => object[key] === attributeOnObject);
14
+ if (!attributeName) {
15
+ attributeName = Object.getOwnPropertyNames(Object.getPrototypeOf(object)).find(key => object[key] === attributeOnObject);
16
+ }
17
+ if (!attributeName) {
18
+ throw new Error("attribute not found on object");
19
+ }
20
+ object[attributeName] = typeof attributeOnObject == "function" ? o.spy(attributeMock) : attributeMock;
21
+ return {
22
+ _originalObject: object,
23
+ _originalAttribute: attributeOnObject,
24
+ _attributeName: attributeName,
25
+ };
26
+ }
27
+ export function unmockAttribute(mock) {
28
+ mock._originalObject[mock._attributeName] = mock._originalAttribute;
29
+ }
30
+ export function spy(producer) {
31
+ const invocations = [];
32
+ const s = (...args) => {
33
+ invocations.push(args);
34
+ return producer && producer(...args);
35
+ };
36
+ s.invocations = invocations;
37
+ return s;
38
+ }
39
+ /**
40
+ * Create partial mock, i.e. allows mocking attributes or functions on actual instances
41
+ * @param obj The base mock object on which mocker may overwrite attributes or functions
42
+ * @param mocker This function receives obj and can overwrite attributes or functions.
43
+ * @returns {T}
44
+ */
45
+ export const mock = (obj, mocker) => {
46
+ mocker(obj);
47
+ return obj;
48
+ };
49
+ export function mapToObject(map) {
50
+ const obj = {};
51
+ map.forEach((value, key) => {
52
+ obj[key] = value;
53
+ });
54
+ return obj;
55
+ }
56
+ export function mapObject(mapper, obj) {
57
+ const newObj = {};
58
+ for (let key of Object.keys(obj)) {
59
+ newObj[key] = mapper(obj[key]);
60
+ }
61
+ return newObj;
62
+ }
63
+ export function replaceAllMaps(toReplace) {
64
+ return toReplace instanceof Map
65
+ ? replaceAllMaps(mapToObject(toReplace))
66
+ : toReplace instanceof Array
67
+ ? toReplace.map(replaceAllMaps)
68
+ : toReplace != null && Object.getPrototypeOf(toReplace) === Object.prototype // plain object
69
+ ? mapObject(replaceAllMaps, toReplace)
70
+ : toReplace;
71
+ }
72
+ /** Catch error and return either value or error */
73
+ export async function asResult(p) {
74
+ return p.catch(e => e);
75
+ }
76
+ export async function assertThrows(expected, fn) {
77
+ try {
78
+ await fn();
79
+ }
80
+ catch (e) {
81
+ o(e instanceof expected).equals(true)("AssertThrows failed: Expected a " + expected + " to be thrown, but got a " + e.constructor);
82
+ return e;
83
+ }
84
+ throw new Error("AssertThrows failed: Expected a " + expected + " to be thrown, but nothing was");
85
+ }
86
+ export async function assertResolvedIn(ms, ...promises) {
87
+ const allP = [delay(ms).then(() => "timeout")].concat(promises.map((p, i) => p.then(() => `promise ${i} is resolved`)));
88
+ const result = await Promise.race(allP);
89
+ o(result).notEquals("timeout");
90
+ }
91
+ export async function assertNotResolvedIn(ms, ...promises) {
92
+ const allP = [delay(ms).then(() => "timeout")].concat(promises.map((p, i) => p.then(() => `promise ${i} is resolved`)));
93
+ const result = await Promise.race(allP);
94
+ o(result).equals("timeout");
95
+ }
96
+ export function makeTimeoutMock() {
97
+ let timeoutId = 1;
98
+ let scheduledFn;
99
+ const timeoutMock = function (fn) {
100
+ scheduledFn = fn;
101
+ timeoutId++;
102
+ return timeoutId;
103
+ };
104
+ const spiedMock = o.spy(timeoutMock);
105
+ spiedMock.next = function () {
106
+ scheduledFn && scheduledFn();
107
+ };
108
+ return spiedMock;
109
+ }
110
+ function delay(ms) {
111
+ return new Promise(resolve => {
112
+ setTimeout(resolve, ms);
113
+ });
114
+ }
@@ -0,0 +1,2 @@
1
+ export { mockAttribute, unmockAttribute, spy, mock, mapToObject, mapObject, replaceAllMaps, asResult, assertThrows, assertResolvedIn, assertNotResolvedIn, makeTimeoutMock, } from "./TestUtils.js";
2
+ export type { Spy, TimeoutMock } from "./TestUtils.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { mockAttribute, unmockAttribute, spy, mock, mapToObject, mapObject, replaceAllMaps, asResult, assertThrows, assertResolvedIn, assertNotResolvedIn, makeTimeoutMock, } from "./TestUtils.js";
package/package.json CHANGED
@@ -1,20 +1,19 @@
1
1
  {
2
2
  "name": "@tutao/tutanota-test-utils",
3
- "version": "3.89.24",
3
+ "version": "3.91.2-beta.0",
4
4
  "license": "GPL-3.0",
5
- "main": "./lib/index.js",
5
+ "main": "./dist/index.js",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/tutao/tutanota.git",
9
9
  "directory": "packages/tutanota-test-utils"
10
10
  },
11
11
  "scripts": {
12
- "flow": "flow; test $? -eq 0 -o $? -eq 2",
13
- "test": "echo \"No tests defined for module\""
12
+ "build": "rm -r dist; tsc"
14
13
  },
15
14
  "type": "module",
16
15
  "files": [
17
- "lib/*",
16
+ "dist/*",
18
17
  "README.md",
19
18
  "LICENSE.txt"
20
19
  ],
@@ -22,6 +21,6 @@
22
21
  "ospec": "https://github.com/tutao/ospec.git#0472107629ede33be4c4d19e89f237a6d7b0cb11"
23
22
  },
24
23
  "devDependencies": {
25
- "flow-bin": "0.152.0"
24
+ "typescript": "4.5.4"
26
25
  }
27
- }
26
+ }
package/lib/TestUtils.js DELETED
@@ -1,141 +0,0 @@
1
- // @flow
2
- import o from "ospec"
3
-
4
- /**
5
- * Mocks an attribute (function or object) on an object and makes sure that it can be restored to the original attribute by calling unmockAttribute() later.
6
- * Additionally creates a spy for the attribute if the attribute is a function.
7
- * @param object The object on which the attribute exists.
8
- * @param attributeOnObject The attribute to mock.
9
- * @param attributeMock The attribute mock.
10
- * @returns An object to be passed to unmockAttribute() in order to restore the original attribute.
11
- */
12
- export function mockAttribute(object: Object, attributeOnObject: Function | Object, attributeMock: Function | Object): Object {
13
- if (attributeOnObject == null) throw new Error("attributeOnObject is undefined")
14
- let attributeName = Object.getOwnPropertyNames(object).find(key => object[key] === attributeOnObject)
15
- if (!attributeName) {
16
- attributeName = Object.getOwnPropertyNames(Object.getPrototypeOf(object))
17
- .find(key => object[key] === attributeOnObject)
18
- }
19
- if (!attributeName) {
20
- throw new Error("attribute not found on object")
21
- }
22
- object[attributeName] = (typeof attributeOnObject == "function") ? o.spy(attributeMock) : attributeMock
23
- return {
24
- _originalObject: object,
25
- _originalAttribute: attributeOnObject,
26
- _attributeName: attributeName
27
- }
28
- }
29
-
30
- export function unmockAttribute(mock: Object) {
31
- mock._originalObject[mock._attributeName] = mock._originalAttribute
32
- }
33
-
34
- export type Spy = ((...any) => any) & {invocations: any[]}
35
-
36
- export function spy(producer?: (...any) => any): Spy {
37
- const invocations = []
38
- const s = (...args: any[]) => {
39
- invocations.push(args)
40
- return producer && producer(...args)
41
- }
42
- s.invocations = invocations
43
- return s
44
- }
45
-
46
- /**
47
- * Create partial mock, i.e. allows mocking attributes or functions on actual instances
48
- * @param obj The base mock object on which mocker may overwrite attributes or functions
49
- * @param mocker This function receives obj and can overwrite attributes or functions.
50
- * @returns {T}
51
- */
52
- export const mock = <T>(obj: T, mocker: any => any): T => {
53
- mocker(obj)
54
- return obj
55
- }
56
-
57
- export function mapToObject<K, V>(map: Map<K, V>): {[K]: V} {
58
- const obj: {[K]: V} = {}
59
- map.forEach((value, key) => {
60
- obj[key] = value
61
- })
62
- return obj
63
- }
64
-
65
- export function mapObject<K, V, R>(mapper: (V) => R, obj: {[K]: V}): {[K]: R} {
66
- const newObj = {}
67
- for (let key of Object.keys(obj)) {
68
- newObj[key] = mapper(obj[key])
69
- }
70
- return newObj
71
- }
72
-
73
- export function replaceAllMaps(toReplace: any): any {
74
- return toReplace instanceof Map
75
- ? replaceAllMaps(mapToObject(toReplace))
76
- : toReplace instanceof Array
77
- ? toReplace.map(replaceAllMaps)
78
- : toReplace != null && Object.getPrototypeOf(toReplace) === (Object: any).prototype // plain object
79
- ? mapObject(replaceAllMaps, toReplace)
80
- : toReplace
81
- }
82
-
83
- /** Catch error and return either value or error */
84
- export async function asResult<T>(p: Promise<T>): Promise<T | Error> {
85
- return p.catch((e) => e)
86
- }
87
-
88
- export async function assertThrows<T: Error>(expected: Class<T>, fn: () => Promise<mixed>): Promise<T> {
89
- try {
90
- await fn()
91
- } catch (e) {
92
- o(e instanceof expected).equals(true)("AssertThrows failed: Expected a " + (expected: any) + " to be thrown, but got a "
93
- + e.constructor)
94
- return e
95
- }
96
- throw new Error("AssertThrows failed: Expected a " + (expected: any) + " to be thrown, but nothing was")
97
- }
98
-
99
-
100
- export async function assertResolvedIn(ms: number, ...promises: $ReadOnlyArray<Promise<*>>): Promise<*> {
101
- const allP = [delay(ms).then(() => "timeout")]
102
- .concat(promises.map((p, i) => p.then(() => `promise ${i} is resolved`)))
103
- const result = await Promise.race(allP)
104
- o(result).notEquals("timeout")
105
- }
106
-
107
- export async function assertNotResolvedIn(ms: number, ...promises: $ReadOnlyArray<Promise<*>>): Promise<*> {
108
- const allP = [delay(ms).then(() => "timeout")]
109
- .concat(promises.map((p, i) => p.then(() => `promise ${i} is resolved`)))
110
- const result = await Promise.race(allP)
111
- o(result).equals("timeout")
112
- }
113
-
114
- export interface TimeoutMock {
115
- (fn: () => mixed, time: number): TimeoutID,
116
-
117
- next(): void
118
-
119
- }
120
-
121
- export function makeTimeoutMock(): TimeoutMock {
122
- let timeoutId = 1
123
- let scheduledFn
124
- const timeoutMock = function (fn: () => mixed) {
125
- scheduledFn = fn
126
- timeoutId++
127
- return timeoutId
128
- }
129
- const spiedMock = o.spy(timeoutMock)
130
-
131
- spiedMock.next = function () {
132
- scheduledFn && scheduledFn()
133
- }
134
- return (spiedMock: any)
135
- }
136
-
137
- function delay(ms: number): Promise<void> {
138
- return new Promise((resolve) => {
139
- setTimeout(resolve, ms)
140
- })
141
- }
package/lib/index.js DELETED
@@ -1,20 +0,0 @@
1
- // @flow
2
- export {
3
- mockAttribute,
4
- unmockAttribute,
5
- spy,
6
- mock,
7
- mapToObject,
8
- mapObject,
9
- replaceAllMaps,
10
- asResult,
11
- assertThrows,
12
- assertResolvedIn,
13
- assertNotResolvedIn,
14
- makeTimeoutMock,
15
- } from "./TestUtils"
16
-
17
- export type {
18
- Spy,
19
- TimeoutMock,
20
- } from "./TestUtils"