Skip to content

Commit ac85b87

Browse files
committed
feat: added option to skip a single unit test in code
1 parent 286286e commit ac85b87

File tree

3 files changed

+97
-68
lines changed

3 files changed

+97
-68
lines changed

src/base/test-runner.ts

Lines changed: 86 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -49,43 +49,35 @@ const currentMicrosecond = () => {
4949
return now.to_unix() * 1000000 + now.get_microsecond();
5050
};
5151

52-
class SuiteRunner {
53-
constructor(
54-
private readonly options: SuiteRunnerOptions,
55-
private readonly tracker: ProgressTracker,
56-
private readonly suiteID: symbol
57-
) {}
52+
class UnitRunner {
53+
readonly unitName: string[];
54+
readonly isSkipped: boolean = false;
5855

59-
private async measureRun(
60-
action: () => void | Promise<void>
61-
): Promise<number> {
62-
const start = currentMicrosecond();
63-
await action();
64-
const end = currentMicrosecond();
56+
constructor(
57+
public readonly unit: It,
58+
parentName: string[],
59+
public readonly suite: SuiteRunner
60+
) {
61+
this.unitName = [...parentName, unit.name];
6562

66-
const duration = end - start;
67-
return duration;
63+
if (!this.testNameMatches(this.unitName) || unit.skip) {
64+
this.isSkipped = true;
65+
this.suite.tracker.unitProgress({
66+
suite: this.suite.suiteID,
67+
skipped: true,
68+
unitName: this.unitName,
69+
unit,
70+
});
71+
}
6872
}
6973

7074
private testNameMatches(unitName: string[]) {
71-
const testableName = unitName.join(" > ");
72-
const { testNamePattern } = this.options;
75+
const { testNamePattern } = this.suite.options;
7376
if (!testNamePattern) return true;
77+
const testableName = unitName.join(" > ");
7478
return testableName.match(testNamePattern) !== null;
7579
}
7680

77-
private markAsSkipped(units: It[], parentName: string[]) {
78-
for (const unit of units) {
79-
const unitName = [...parentName, unit.name];
80-
this.tracker.unitProgress({
81-
suite: this.suiteID,
82-
unitName,
83-
skipped: true,
84-
unit,
85-
});
86-
}
87-
}
88-
8981
private async runWithTimeout(
9082
action: () => void | Promise<void>,
9183
time: number
@@ -112,60 +104,42 @@ class SuiteRunner {
112104
return r;
113105
}
114106

115-
private async runHook(hook: TestHook, unitName: string[]) {
116-
try {
117-
await hook.callback();
118-
} catch (e) {
119-
this.tracker.suiteProgress({
120-
suite: this.suiteID,
121-
parentUnitName: unitName,
122-
error: {
123-
origin: "lifecycleHook",
124-
thrown: e,
125-
hook,
126-
},
127-
});
107+
private async measureRun(
108+
action: () => void | Promise<void>
109+
): Promise<number> {
110+
const start = currentMicrosecond();
111+
await action();
112+
const end = currentMicrosecond();
128113

129-
throw new NoLogError(e, "Hook error");
130-
}
114+
const duration = end - start;
115+
return duration;
131116
}
132117

133-
private async runUnit(unit: It, parentName: string[]) {
134-
const unitName = [...parentName, unit.name];
118+
async run() {
119+
if (this.isSkipped) return false;
135120

136121
try {
137-
if (!this.testNameMatches(unitName)) {
138-
this.tracker.unitProgress({
139-
suite: this.suiteID,
140-
skipped: true,
141-
unitName,
142-
unit,
143-
});
144-
145-
return true;
146-
}
147-
148122
const duration = await this.measureRun(() =>
149-
this.runWithTimeout(unit.callback, this.options.timeout)
123+
this.runWithTimeout(this.unit.callback, this.suite.options.timeout)
150124
);
151125

152-
this.tracker.unitProgress({
153-
suite: this.suiteID,
154-
unitName,
126+
this.suite.tracker.unitProgress({
127+
suite: this.suite.suiteID,
128+
unitName: this.unitName,
155129
duration,
156-
unit,
130+
unit: this.unit,
157131
});
158132

159133
return true;
160134
} catch (e) {
161-
this.tracker.unitProgress({
162-
suite: this.suiteID,
163-
unitName,
135+
this.suite.tracker.unitProgress({
136+
suite: this.suite.suiteID,
137+
unitName: this.unitName,
164138
error: {
165139
origin: "test",
166140
thrown: e,
167141
},
168-
unit,
142+
unit: this.unit,
169143
});
170144

171145
if (_isExpectError(e)) {
@@ -175,6 +149,44 @@ class SuiteRunner {
175149
return false;
176150
}
177151
}
152+
}
153+
154+
class SuiteRunner {
155+
constructor(
156+
public readonly options: SuiteRunnerOptions,
157+
public readonly tracker: ProgressTracker,
158+
public readonly suiteID: symbol
159+
) {}
160+
161+
private markAsSkipped(units: It[], parentName: string[]) {
162+
for (const unit of units) {
163+
const unitName = [...parentName, unit.name];
164+
this.tracker.unitProgress({
165+
suite: this.suiteID,
166+
unitName,
167+
skipped: true,
168+
unit,
169+
});
170+
}
171+
}
172+
173+
private async runHook(hook: TestHook, unitName: string[]) {
174+
try {
175+
await hook.callback();
176+
} catch (e) {
177+
this.tracker.suiteProgress({
178+
suite: this.suiteID,
179+
parentUnitName: unitName,
180+
error: {
181+
origin: "lifecycleHook",
182+
thrown: e,
183+
hook,
184+
},
185+
});
186+
187+
throw new NoLogError(e, "Hook error");
188+
}
189+
}
178190

179191
async runSuite(test: Test, parentName: string[] = []): Promise<boolean> {
180192
let passed = true;
@@ -192,19 +204,25 @@ class SuiteRunner {
192204
}
193205
}
194206

195-
$: for (const [index, unitTest] of test.its.entries()) {
207+
$: for (const unitTest of test.its) {
208+
const unitRunner = new UnitRunner(unitTest, unitName, this);
209+
210+
if (unitRunner.isSkipped) {
211+
continue;
212+
}
213+
196214
for (const hook of test.beforeEach) {
197215
try {
198216
await this.runHook(hook, unitName);
199217
} catch (e) {
200218
// All tests that cannot be ran because of a beforeAll hook
201219
// error should be marked as skipped
202-
this.markAsSkipped(test.its.slice(index, index + 1), unitName);
220+
this.markAsSkipped([unitTest], unitName);
203221
continue $;
204222
}
205223
}
206224

207-
const result = await this.runUnit(unitTest, unitName);
225+
const result = await unitRunner.run();
208226

209227
passed &&= result;
210228

src/user-land/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ export const it = (name: string, fn: () => any) => {
2323
});
2424
};
2525

26+
export const skip = (name: string, fn: () => any) => {
27+
TestCollector.addIt({
28+
name,
29+
line: 0,
30+
column: 0,
31+
skip: true,
32+
callback: () => {},
33+
});
34+
};
35+
2636
export const beforeAll = (fn: () => void) => {
2737
// Get line where this function was called
2838
const [line, column] = _getLineFromError(new Error());

src/user-land/test-collector.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export type It = {
22
name: string;
33
line: number;
44
column: number;
5+
skip?: boolean;
56
callback: () => any;
67
};
78

0 commit comments

Comments
 (0)