@sprucelabs/test-utils 5.4.2 → 5.5.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
@@ -17,4 +17,4 @@ Spruce XP Documentation
17
17
  <br />
18
18
  <p align="center">
19
19
  <a href="https://developer.spruce.ai/#/"><img width="250" src="https://raw.githubusercontent.com/sprucelabsai/spruce-test-utils/master/docs/images/read-full-docs.png" /></a>
20
- </p>
20
+ </p>
@@ -1,8 +1,17 @@
1
+ type TestLifecycleListener = () => any | Promise<any>;
1
2
  export declare class SpruceTestResolver {
2
3
  static ActiveTestClass?: any;
3
4
  private static __activeTest;
4
5
  static resolveTestClass(target: any): any;
5
6
  static getActiveTest(): any;
7
+ static onWillBeforeAll(cb: TestLifecycleListener): void;
8
+ static onAfterBeforeAll(cb: TestLifecycleListener): void;
9
+ static onBeforeBeforeEach(cb: TestLifecycleListener): void;
10
+ static onAfterBeforeEach(cb: TestLifecycleListener): void;
11
+ static onBeforeAfterEach(cb: TestLifecycleListener): void;
12
+ static onAfterAfterEach(cb: TestLifecycleListener): void;
13
+ static onBeforeAfterAll(cb: TestLifecycleListener): void;
14
+ static onAfterAfterAll(cb: TestLifecycleListener): void;
6
15
  }
7
16
  /** Test decorator */
8
17
  declare function test(description?: string, ...args: any[]): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
@@ -7,6 +7,56 @@ if (typeof it === 'undefined') {
7
7
  //@ts-ignore
8
8
  global.it = () => { };
9
9
  }
10
+ class TestLifecycleListeners {
11
+ static async runWillBeforeAll() {
12
+ for (const cb of this.beforeBeforeAll) {
13
+ await cb();
14
+ }
15
+ }
16
+ static async runAfterBeforeAll() {
17
+ for (const cb of this.afterBeforeAll) {
18
+ await cb();
19
+ }
20
+ }
21
+ static async runBeforeEach() {
22
+ for (const cb of this.beforeBeforeEach) {
23
+ await cb();
24
+ }
25
+ }
26
+ static async runAfterBeforeEach() {
27
+ for (const cb of this.afterBeforeEach) {
28
+ await cb();
29
+ }
30
+ }
31
+ static async runBeforeAfterEach() {
32
+ for (const cb of this.beforeAfterEach) {
33
+ await cb();
34
+ }
35
+ }
36
+ static async runAfterAfterEach() {
37
+ for (const cb of this.afterAfterEach) {
38
+ await cb();
39
+ }
40
+ }
41
+ static async runBeforeAfterAll() {
42
+ for (const cb of this.beforeAfterAll) {
43
+ await cb();
44
+ }
45
+ }
46
+ static async runAfterAfterAll() {
47
+ for (const cb of this.afterAfterAll) {
48
+ await cb();
49
+ }
50
+ }
51
+ }
52
+ TestLifecycleListeners.beforeBeforeAll = [];
53
+ TestLifecycleListeners.afterBeforeAll = [];
54
+ TestLifecycleListeners.beforeBeforeEach = [];
55
+ TestLifecycleListeners.afterBeforeEach = [];
56
+ TestLifecycleListeners.beforeAfterEach = [];
57
+ TestLifecycleListeners.afterAfterEach = [];
58
+ TestLifecycleListeners.beforeAfterAll = [];
59
+ TestLifecycleListeners.afterAfterAll = [];
10
60
  class SpruceTestResolver {
11
61
  static resolveTestClass(target) {
12
62
  if (!this.__activeTest) {
@@ -19,8 +69,42 @@ class SpruceTestResolver {
19
69
  static getActiveTest() {
20
70
  return this.__activeTest;
21
71
  }
72
+ static onWillBeforeAll(cb) {
73
+ TestLifecycleListeners.beforeBeforeAll.push(cb);
74
+ }
75
+ static onAfterBeforeAll(cb) {
76
+ TestLifecycleListeners.afterBeforeAll.push(cb);
77
+ }
78
+ static onBeforeBeforeEach(cb) {
79
+ TestLifecycleListeners.beforeBeforeEach.push(cb);
80
+ }
81
+ static onAfterBeforeEach(cb) {
82
+ TestLifecycleListeners.afterBeforeEach.push(cb);
83
+ }
84
+ static onBeforeAfterEach(cb) {
85
+ TestLifecycleListeners.beforeAfterEach.push(cb);
86
+ }
87
+ static onAfterAfterEach(cb) {
88
+ TestLifecycleListeners.afterAfterEach.push(cb);
89
+ }
90
+ static onBeforeAfterAll(cb) {
91
+ TestLifecycleListeners.beforeAfterAll.push(cb);
92
+ }
93
+ static onAfterAfterAll(cb) {
94
+ TestLifecycleListeners.afterAfterAll.push(cb);
95
+ }
22
96
  }
23
97
  exports.SpruceTestResolver = SpruceTestResolver;
98
+ //recursive function to get static method by name looping up through constructor chain
99
+ function resolveMethod(Target, name) {
100
+ if (Target[name]) {
101
+ return Target[name];
102
+ }
103
+ if (Target.constructor && Target.constructor !== Target) {
104
+ return resolveMethod(Target.constructor, name);
105
+ }
106
+ return null;
107
+ }
24
108
  /** Hooks up before, after, etc. */
25
109
  function hookupTestClassToJestLifecycle(Target, h) {
26
110
  if (Target.__isTestingHookedUp) {
@@ -29,10 +113,9 @@ function hookupTestClassToJestLifecycle(Target, h) {
29
113
  Target.__isTestingHookedUp = !h;
30
114
  const hooks = h ?? ['beforeAll', 'beforeEach', 'afterAll', 'afterEach'];
31
115
  hooks.forEach((hook) => {
32
- const cb = Target[hook] ?? Target?.constructor?.[hook];
116
+ const cb = resolveMethod(Target, hook);
33
117
  // Have they defined a hook
34
118
  if (!cb) {
35
- debugger;
36
119
  return;
37
120
  }
38
121
  // @ts-ignore
@@ -40,20 +123,48 @@ function hookupTestClassToJestLifecycle(Target, h) {
40
123
  // @ts-ignore
41
124
  global[hook](async () => {
42
125
  if (hook === 'beforeEach') {
43
- await SpruceTestResolver.resolveTestClass(Target).beforeEach();
126
+ SpruceTestResolver.resolveTestClass(Target);
127
+ await TestLifecycleListeners.runBeforeEach();
128
+ await runBeforeEach(Target);
129
+ await TestLifecycleListeners.runAfterBeforeEach();
44
130
  }
45
131
  else if (hook === 'afterEach') {
46
- await SpruceTestResolver.resolveTestClass(Target).afterEach();
132
+ await TestLifecycleListeners.runBeforeAfterEach();
133
+ await runAfterEach(Target);
134
+ await TestLifecycleListeners.runAfterAfterEach();
47
135
  // @ts-ignore
48
136
  delete SpruceTestResolver.__activeTest;
49
137
  }
50
138
  else {
51
- await cb.apply(Target);
139
+ if (hook === 'beforeAll') {
140
+ await TestLifecycleListeners.runWillBeforeAll();
141
+ }
142
+ else if (hook === 'afterAll') {
143
+ await TestLifecycleListeners.runBeforeAfterAll();
144
+ }
145
+ if (SpruceTestResolver.ActiveTestClass) {
146
+ await cb.apply(Target.constructor);
147
+ }
148
+ else {
149
+ await cb.apply(Target);
150
+ }
151
+ if (hook === 'beforeAll') {
152
+ await TestLifecycleListeners.runAfterBeforeAll();
153
+ }
154
+ else if (hook === 'afterAll') {
155
+ await TestLifecycleListeners.runAfterAfterAll();
156
+ }
52
157
  }
53
158
  });
54
159
  }
55
160
  });
56
161
  }
162
+ async function runAfterEach(Target) {
163
+ await SpruceTestResolver.resolveTestClass(Target).afterEach();
164
+ }
165
+ async function runBeforeEach(Target) {
166
+ await SpruceTestResolver.resolveTestClass(Target).beforeEach();
167
+ }
57
168
  /** Test decorator */
58
169
  function test(description, ...args) {
59
170
  return function (target, propertyKey, descriptor) {
@@ -1,8 +1,17 @@
1
+ type TestLifecycleListener = () => any | Promise<any>;
1
2
  export declare class SpruceTestResolver {
2
3
  static ActiveTestClass?: any;
3
4
  private static __activeTest;
4
5
  static resolveTestClass(target: any): any;
5
6
  static getActiveTest(): any;
7
+ static onWillBeforeAll(cb: TestLifecycleListener): void;
8
+ static onAfterBeforeAll(cb: TestLifecycleListener): void;
9
+ static onBeforeBeforeEach(cb: TestLifecycleListener): void;
10
+ static onAfterBeforeEach(cb: TestLifecycleListener): void;
11
+ static onBeforeAfterEach(cb: TestLifecycleListener): void;
12
+ static onAfterAfterEach(cb: TestLifecycleListener): void;
13
+ static onBeforeAfterAll(cb: TestLifecycleListener): void;
14
+ static onAfterAfterAll(cb: TestLifecycleListener): void;
6
15
  }
7
16
  /** Test decorator */
8
17
  declare function test(description?: string, ...args: any[]): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
@@ -2,6 +2,56 @@ if (typeof it === 'undefined') {
2
2
  //@ts-ignore
3
3
  global.it = () => { };
4
4
  }
5
+ class TestLifecycleListeners {
6
+ static async runWillBeforeAll() {
7
+ for (const cb of this.beforeBeforeAll) {
8
+ await cb();
9
+ }
10
+ }
11
+ static async runAfterBeforeAll() {
12
+ for (const cb of this.afterBeforeAll) {
13
+ await cb();
14
+ }
15
+ }
16
+ static async runBeforeEach() {
17
+ for (const cb of this.beforeBeforeEach) {
18
+ await cb();
19
+ }
20
+ }
21
+ static async runAfterBeforeEach() {
22
+ for (const cb of this.afterBeforeEach) {
23
+ await cb();
24
+ }
25
+ }
26
+ static async runBeforeAfterEach() {
27
+ for (const cb of this.beforeAfterEach) {
28
+ await cb();
29
+ }
30
+ }
31
+ static async runAfterAfterEach() {
32
+ for (const cb of this.afterAfterEach) {
33
+ await cb();
34
+ }
35
+ }
36
+ static async runBeforeAfterAll() {
37
+ for (const cb of this.beforeAfterAll) {
38
+ await cb();
39
+ }
40
+ }
41
+ static async runAfterAfterAll() {
42
+ for (const cb of this.afterAfterAll) {
43
+ await cb();
44
+ }
45
+ }
46
+ }
47
+ TestLifecycleListeners.beforeBeforeAll = [];
48
+ TestLifecycleListeners.afterBeforeAll = [];
49
+ TestLifecycleListeners.beforeBeforeEach = [];
50
+ TestLifecycleListeners.afterBeforeEach = [];
51
+ TestLifecycleListeners.beforeAfterEach = [];
52
+ TestLifecycleListeners.afterAfterEach = [];
53
+ TestLifecycleListeners.beforeAfterAll = [];
54
+ TestLifecycleListeners.afterAfterAll = [];
5
55
  export class SpruceTestResolver {
6
56
  static resolveTestClass(target) {
7
57
  if (!this.__activeTest) {
@@ -14,6 +64,40 @@ export class SpruceTestResolver {
14
64
  static getActiveTest() {
15
65
  return this.__activeTest;
16
66
  }
67
+ static onWillBeforeAll(cb) {
68
+ TestLifecycleListeners.beforeBeforeAll.push(cb);
69
+ }
70
+ static onAfterBeforeAll(cb) {
71
+ TestLifecycleListeners.afterBeforeAll.push(cb);
72
+ }
73
+ static onBeforeBeforeEach(cb) {
74
+ TestLifecycleListeners.beforeBeforeEach.push(cb);
75
+ }
76
+ static onAfterBeforeEach(cb) {
77
+ TestLifecycleListeners.afterBeforeEach.push(cb);
78
+ }
79
+ static onBeforeAfterEach(cb) {
80
+ TestLifecycleListeners.beforeAfterEach.push(cb);
81
+ }
82
+ static onAfterAfterEach(cb) {
83
+ TestLifecycleListeners.afterAfterEach.push(cb);
84
+ }
85
+ static onBeforeAfterAll(cb) {
86
+ TestLifecycleListeners.beforeAfterAll.push(cb);
87
+ }
88
+ static onAfterAfterAll(cb) {
89
+ TestLifecycleListeners.afterAfterAll.push(cb);
90
+ }
91
+ }
92
+ //recursive function to get static method by name looping up through constructor chain
93
+ function resolveMethod(Target, name) {
94
+ if (Target[name]) {
95
+ return Target[name];
96
+ }
97
+ if (Target.constructor && Target.constructor !== Target) {
98
+ return resolveMethod(Target.constructor, name);
99
+ }
100
+ return null;
17
101
  }
18
102
  /** Hooks up before, after, etc. */
19
103
  function hookupTestClassToJestLifecycle(Target, h) {
@@ -23,11 +107,9 @@ function hookupTestClassToJestLifecycle(Target, h) {
23
107
  Target.__isTestingHookedUp = !h;
24
108
  const hooks = h !== null && h !== void 0 ? h : ['beforeAll', 'beforeEach', 'afterAll', 'afterEach'];
25
109
  hooks.forEach((hook) => {
26
- var _a, _b;
27
- const cb = (_a = Target[hook]) !== null && _a !== void 0 ? _a : (_b = Target === null || Target === void 0 ? void 0 : Target.constructor) === null || _b === void 0 ? void 0 : _b[hook];
110
+ const cb = resolveMethod(Target, hook);
28
111
  // Have they defined a hook
29
112
  if (!cb) {
30
- debugger;
31
113
  return;
32
114
  }
33
115
  // @ts-ignore
@@ -35,20 +117,48 @@ function hookupTestClassToJestLifecycle(Target, h) {
35
117
  // @ts-ignore
36
118
  global[hook](async () => {
37
119
  if (hook === 'beforeEach') {
38
- await SpruceTestResolver.resolveTestClass(Target).beforeEach();
120
+ SpruceTestResolver.resolveTestClass(Target);
121
+ await TestLifecycleListeners.runBeforeEach();
122
+ await runBeforeEach(Target);
123
+ await TestLifecycleListeners.runAfterBeforeEach();
39
124
  }
40
125
  else if (hook === 'afterEach') {
41
- await SpruceTestResolver.resolveTestClass(Target).afterEach();
126
+ await TestLifecycleListeners.runBeforeAfterEach();
127
+ await runAfterEach(Target);
128
+ await TestLifecycleListeners.runAfterAfterEach();
42
129
  // @ts-ignore
43
130
  delete SpruceTestResolver.__activeTest;
44
131
  }
45
132
  else {
46
- await cb.apply(Target);
133
+ if (hook === 'beforeAll') {
134
+ await TestLifecycleListeners.runWillBeforeAll();
135
+ }
136
+ else if (hook === 'afterAll') {
137
+ await TestLifecycleListeners.runBeforeAfterAll();
138
+ }
139
+ if (SpruceTestResolver.ActiveTestClass) {
140
+ await cb.apply(Target.constructor);
141
+ }
142
+ else {
143
+ await cb.apply(Target);
144
+ }
145
+ if (hook === 'beforeAll') {
146
+ await TestLifecycleListeners.runAfterBeforeAll();
147
+ }
148
+ else if (hook === 'afterAll') {
149
+ await TestLifecycleListeners.runAfterAfterAll();
150
+ }
47
151
  }
48
152
  });
49
153
  }
50
154
  });
51
155
  }
156
+ async function runAfterEach(Target) {
157
+ await SpruceTestResolver.resolveTestClass(Target).afterEach();
158
+ }
159
+ async function runBeforeEach(Target) {
160
+ await SpruceTestResolver.resolveTestClass(Target).beforeEach();
161
+ }
52
162
  /** Test decorator */
53
163
  export default function test(description, ...args) {
54
164
  return function (target, propertyKey, descriptor) {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "5.4.2",
6
+ "version": "5.5.0",
7
7
  "files": [
8
8
  "build"
9
9
  ],