@zohodesk/unit-testing-framework 0.0.30-experimental → 0.0.32-experimental
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 +2 -0
- package/build/src/runner/__tests__/jest-runner.test.js +115 -0
- package/build/src/runner/jest-runner.js +135 -15
- package/build/src/runner/runner-base.js +3 -3
- package/build/src/utils/__tests__/pipeline-summary-directory.test.js +248 -0
- package/build/src/utils/__tests__/pipeline-summary.test.js +473 -0
- package/build/src/utils/pipeline-summary.js +359 -0
- package/package.json +1 -1
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
4
|
+
var _path = _interopRequireDefault(require("path"));
|
|
5
|
+
var _url = require("url");
|
|
6
|
+
var _pipelineSummary = require("../pipeline-summary.js");
|
|
7
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
const _dirname = _path.default.dirname((0, _url.fileURLToPath)(import.meta.url));
|
|
9
|
+
const TEST_OUTPUT_DIR = _path.default.join(_dirname, '../../__temp__');
|
|
10
|
+
describe('PipelineSummaryGenerator', () => {
|
|
11
|
+
let summary;
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
summary = (0, _pipelineSummary.createPipelineSummary)('TestStage', {
|
|
14
|
+
outputPath: _path.default.join(TEST_OUTPUT_DIR, 'test-summary.json'),
|
|
15
|
+
webUrl: 'https://example.com/report'
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Create temp directory
|
|
19
|
+
if (!_fs.default.existsSync(TEST_OUTPUT_DIR)) {
|
|
20
|
+
_fs.default.mkdirSync(TEST_OUTPUT_DIR, {
|
|
21
|
+
recursive: true
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
// Clean up
|
|
27
|
+
if (_fs.default.existsSync(TEST_OUTPUT_DIR)) {
|
|
28
|
+
_fs.default.rmSync(TEST_OUTPUT_DIR, {
|
|
29
|
+
recursive: true,
|
|
30
|
+
force: true
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
36
|
+
// SUCCESS RESPONSE TESTS
|
|
37
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
describe('success()', () => {
|
|
40
|
+
test('should create success response with defaults', () => {
|
|
41
|
+
const response = summary.success();
|
|
42
|
+
expect(response.status).toBe('SUCCESS');
|
|
43
|
+
expect(response.message).toBe('TestStage completed successfully');
|
|
44
|
+
expect(response.web_url).toBe('https://example.com/report');
|
|
45
|
+
});
|
|
46
|
+
test('should create success response with custom message', () => {
|
|
47
|
+
const response = summary.success({
|
|
48
|
+
message: 'All tests passed'
|
|
49
|
+
});
|
|
50
|
+
expect(response.status).toBe('SUCCESS');
|
|
51
|
+
expect(response.message).toBe('All tests passed');
|
|
52
|
+
});
|
|
53
|
+
test('should create success response with custom web_url', () => {
|
|
54
|
+
const response = summary.success({
|
|
55
|
+
webUrl: 'https://example.com/custom-report'
|
|
56
|
+
});
|
|
57
|
+
expect(response.web_url).toBe('https://example.com/custom-report');
|
|
58
|
+
});
|
|
59
|
+
test('should not contain error field in success response', () => {
|
|
60
|
+
const response = summary.success();
|
|
61
|
+
expect(response).not.toHaveProperty('error');
|
|
62
|
+
expect(response).not.toHaveProperty('result');
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
67
|
+
// FAILURE RESPONSE TESTS
|
|
68
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
69
|
+
|
|
70
|
+
describe('failure()', () => {
|
|
71
|
+
test('should create failure response with defaults', () => {
|
|
72
|
+
const response = summary.failure();
|
|
73
|
+
expect(response.status).toBe('FAILURE');
|
|
74
|
+
expect(response.message).toBe('TestStage failed');
|
|
75
|
+
expect(response.error.code).toBe('UNKNOWN_ERROR');
|
|
76
|
+
expect(response.error.category).toBe(_pipelineSummary.ERROR_CATEGORIES.TOOL);
|
|
77
|
+
expect(Array.isArray(response.error.errors)).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
test('should create failure response with custom error details', () => {
|
|
80
|
+
const response = summary.failure({
|
|
81
|
+
message: 'Database connection failed',
|
|
82
|
+
errorCode: 'DB_CONN_ERROR',
|
|
83
|
+
errorCategory: _pipelineSummary.ERROR_CATEGORIES.ENVIRONMENT,
|
|
84
|
+
errorMessage: 'Cannot connect to database',
|
|
85
|
+
errors: ['Connection timeout', 'Host unreachable']
|
|
86
|
+
});
|
|
87
|
+
expect(response.status).toBe('FAILURE');
|
|
88
|
+
expect(response.message).toBe('Database connection failed');
|
|
89
|
+
expect(response.error.code).toBe('DB_CONN_ERROR');
|
|
90
|
+
expect(response.error.category).toBe(_pipelineSummary.ERROR_CATEGORIES.ENVIRONMENT);
|
|
91
|
+
expect(response.error.message).toBe('Cannot connect to database');
|
|
92
|
+
expect(response.error.errors).toHaveLength(2);
|
|
93
|
+
});
|
|
94
|
+
test('should accept single error and convert to array', () => {
|
|
95
|
+
const response = summary.failure({
|
|
96
|
+
errors: 'Single error message'
|
|
97
|
+
});
|
|
98
|
+
expect(Array.isArray(response.error.errors)).toBe(true);
|
|
99
|
+
expect(response.error.errors[0]).toBe('Single error message');
|
|
100
|
+
});
|
|
101
|
+
test('should include result field if provided', () => {
|
|
102
|
+
const response = summary.failure({
|
|
103
|
+
result: [{
|
|
104
|
+
key: 'value'
|
|
105
|
+
}]
|
|
106
|
+
});
|
|
107
|
+
expect(response.result).toEqual([{
|
|
108
|
+
key: 'value'
|
|
109
|
+
}]);
|
|
110
|
+
});
|
|
111
|
+
test('should not include empty result field', () => {
|
|
112
|
+
const response = summary.failure({
|
|
113
|
+
result: []
|
|
114
|
+
});
|
|
115
|
+
expect(response).not.toHaveProperty('result');
|
|
116
|
+
});
|
|
117
|
+
test('should validate and warn for invalid error category', () => {
|
|
118
|
+
const response = summary.failure({
|
|
119
|
+
errorCategory: 'invalid_category'
|
|
120
|
+
});
|
|
121
|
+
expect(response.error.category).toBe(_pipelineSummary.ERROR_CATEGORIES.TOOL);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
126
|
+
// TEST FAILURE TESTS
|
|
127
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
128
|
+
|
|
129
|
+
describe('testFailure()', () => {
|
|
130
|
+
test('should handle test failure without results object', () => {
|
|
131
|
+
const response = summary.testFailure({
|
|
132
|
+
message: 'Tests failed'
|
|
133
|
+
});
|
|
134
|
+
expect(response.status).toBe('FAILURE');
|
|
135
|
+
expect(response.error.code).toBe('TEST_FAILURE');
|
|
136
|
+
expect(response.error.category).toBe(_pipelineSummary.ERROR_CATEGORIES.CODE);
|
|
137
|
+
});
|
|
138
|
+
test('should extract failed test information from jest results', () => {
|
|
139
|
+
const testResults = {
|
|
140
|
+
numTotalTests: 10,
|
|
141
|
+
numFailedTests: 2,
|
|
142
|
+
numPassedTests: 8,
|
|
143
|
+
numSkippedTests: 0,
|
|
144
|
+
testResults: [{
|
|
145
|
+
name: 'test-file-1.js',
|
|
146
|
+
numFailingTests: 1,
|
|
147
|
+
assertionResults: [{
|
|
148
|
+
title: 'Test 1',
|
|
149
|
+
fullName: 'Suite › Test 1',
|
|
150
|
+
status: 'failed',
|
|
151
|
+
failureMessages: ['Expected true to be false']
|
|
152
|
+
}]
|
|
153
|
+
}, {
|
|
154
|
+
name: 'test-file-2.js',
|
|
155
|
+
numFailingTests: 1,
|
|
156
|
+
assertionResults: [{
|
|
157
|
+
title: 'Test 2',
|
|
158
|
+
fullName: 'Suite › Test 2',
|
|
159
|
+
status: 'failed',
|
|
160
|
+
failureMessages: ['Timeout after 5000ms']
|
|
161
|
+
}]
|
|
162
|
+
}]
|
|
163
|
+
};
|
|
164
|
+
const response = summary.testFailure({
|
|
165
|
+
testResults
|
|
166
|
+
});
|
|
167
|
+
expect(response.error.errors).toHaveLength(2);
|
|
168
|
+
expect(response.error.errors[0].test).toBe('Suite › Test 1');
|
|
169
|
+
expect(response.error.errors[0].file).toBe('test-file-1.js');
|
|
170
|
+
expect(response.result[0].failedTests).toBe(2);
|
|
171
|
+
});
|
|
172
|
+
test('should include test statistics in result', () => {
|
|
173
|
+
const testResults = {
|
|
174
|
+
numTotalTests: 50,
|
|
175
|
+
numFailedTests: 5,
|
|
176
|
+
numPassedTests: 45,
|
|
177
|
+
numSkippedTests: 0,
|
|
178
|
+
testResults: []
|
|
179
|
+
};
|
|
180
|
+
const response = summary.testFailure({
|
|
181
|
+
testResults
|
|
182
|
+
});
|
|
183
|
+
expect(response.result[0]).toEqual({
|
|
184
|
+
totalTests: 50,
|
|
185
|
+
failedTests: 5,
|
|
186
|
+
passedTests: 45,
|
|
187
|
+
skippedTests: 0
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
193
|
+
// TOOL ERROR TESTS
|
|
194
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
195
|
+
|
|
196
|
+
describe('toolError()', () => {
|
|
197
|
+
test('should handle error object', () => {
|
|
198
|
+
const error = new Error('Module not found');
|
|
199
|
+
error.stack = 'Error: Module not found\n at line 10';
|
|
200
|
+
const response = summary.toolError({
|
|
201
|
+
toolName: 'jest',
|
|
202
|
+
error,
|
|
203
|
+
exitCode: 1
|
|
204
|
+
});
|
|
205
|
+
expect(response.status).toBe('FAILURE');
|
|
206
|
+
expect(response.error.code).toBe('JEST_EXECUTION_ERROR');
|
|
207
|
+
expect(response.error.category).toBe(_pipelineSummary.ERROR_CATEGORIES.TOOL);
|
|
208
|
+
expect(response.error.errors[0].tool).toBe('jest');
|
|
209
|
+
expect(response.error.errors[0].stack).toBeDefined();
|
|
210
|
+
});
|
|
211
|
+
test('should handle string error message', () => {
|
|
212
|
+
const response = summary.toolError({
|
|
213
|
+
toolName: 'npm',
|
|
214
|
+
error: 'npm ERR! code ERESOLVE',
|
|
215
|
+
exitCode: 1
|
|
216
|
+
});
|
|
217
|
+
expect(response.error.errors[0].message).toBe('npm ERR! code ERESOLVE');
|
|
218
|
+
});
|
|
219
|
+
test('should handle missing error', () => {
|
|
220
|
+
const response = summary.toolError({
|
|
221
|
+
toolName: 'webpack',
|
|
222
|
+
exitCode: 127
|
|
223
|
+
});
|
|
224
|
+
expect(response.error.errors[0].message).toBeFalsy();
|
|
225
|
+
expect(response.error.errors[0].tool).toBe('webpack');
|
|
226
|
+
});
|
|
227
|
+
test('should format tool name in error code', () => {
|
|
228
|
+
const response = summary.toolError({
|
|
229
|
+
toolName: 'eslint',
|
|
230
|
+
error: 'Linting failed'
|
|
231
|
+
});
|
|
232
|
+
expect(response.error.code).toBe('ESLINT_EXECUTION_ERROR');
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
237
|
+
// ENVIRONMENT ERROR TESTS
|
|
238
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
239
|
+
|
|
240
|
+
describe('environmentError()', () => {
|
|
241
|
+
test('should create environment error response', () => {
|
|
242
|
+
const response = summary.environmentError({
|
|
243
|
+
issue: 'Node.js version too old',
|
|
244
|
+
requirement: 'Node.js >= 16',
|
|
245
|
+
suggestion: 'Update Node.js'
|
|
246
|
+
});
|
|
247
|
+
expect(response.status).toBe('FAILURE');
|
|
248
|
+
expect(response.error.code).toBe('ENV_SETUP_ERROR');
|
|
249
|
+
expect(response.error.category).toBe(_pipelineSummary.ERROR_CATEGORIES.ENVIRONMENT);
|
|
250
|
+
expect(response.error.errors[0].issue).toBe('Node.js version too old');
|
|
251
|
+
expect(response.error.errors[0].requirement).toBe('Node.js >= 16');
|
|
252
|
+
expect(response.error.errors[0].suggestion).toBe('Update Node.js');
|
|
253
|
+
});
|
|
254
|
+
test('should handle partial environment error details', () => {
|
|
255
|
+
const response = summary.environmentError({
|
|
256
|
+
issue: 'Missing DATABASE_URL'
|
|
257
|
+
});
|
|
258
|
+
expect(response.error.errors[0]).toEqual({
|
|
259
|
+
issue: 'Missing DATABASE_URL'
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
test('should use default issue message', () => {
|
|
263
|
+
const response = summary.environmentError();
|
|
264
|
+
expect(response.error.errors[0].issue).toBe('Environment configuration issue');
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
269
|
+
// FLAKY TEST TESTS
|
|
270
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
271
|
+
|
|
272
|
+
describe('flakyTestFailure()', () => {
|
|
273
|
+
test('should create flaky test failure response', () => {
|
|
274
|
+
const response = summary.flakyTestFailure({
|
|
275
|
+
testNames: ['Test A', 'Test B'],
|
|
276
|
+
attemptNumber: 1,
|
|
277
|
+
maxAttempts: 3
|
|
278
|
+
});
|
|
279
|
+
expect(response.status).toBe('FAILURE');
|
|
280
|
+
expect(response.error.code).toBe('FLAKY_TEST_FAILURE');
|
|
281
|
+
expect(response.error.category).toBe(_pipelineSummary.ERROR_CATEGORIES.FLAKY);
|
|
282
|
+
expect(response.error.errors).toHaveLength(2);
|
|
283
|
+
expect(response.result[0].attemptNumber).toBe(1);
|
|
284
|
+
expect(response.result[0].maxAttempts).toBe(3);
|
|
285
|
+
});
|
|
286
|
+
test('should include attempt information in message', () => {
|
|
287
|
+
const response = summary.flakyTestFailure({
|
|
288
|
+
testNames: ['Flaky Test'],
|
|
289
|
+
attemptNumber: 2,
|
|
290
|
+
maxAttempts: 3
|
|
291
|
+
});
|
|
292
|
+
expect(response.message).toContain('attempt 2/3');
|
|
293
|
+
});
|
|
294
|
+
test('should handle custom message override', () => {
|
|
295
|
+
const response = summary.flakyTestFailure({
|
|
296
|
+
testNames: ['Test'],
|
|
297
|
+
message: 'Custom flaky message'
|
|
298
|
+
});
|
|
299
|
+
expect(response.message).toBe('Custom flaky message');
|
|
300
|
+
});
|
|
301
|
+
test('should use default attempt values', () => {
|
|
302
|
+
const response = summary.flakyTestFailure({
|
|
303
|
+
testNames: ['Test']
|
|
304
|
+
});
|
|
305
|
+
expect(response.result[0].attemptNumber).toBe(1);
|
|
306
|
+
expect(response.result[0].maxAttempts).toBe(3);
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
311
|
+
// FILE SAVE TESTS
|
|
312
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
313
|
+
|
|
314
|
+
describe('saveToFile()', () => {
|
|
315
|
+
test('should save response to file', () => {
|
|
316
|
+
const response = summary.success();
|
|
317
|
+
const saved = summary.saveToFile(response);
|
|
318
|
+
expect(saved).toBe(true);
|
|
319
|
+
expect(_fs.default.existsSync(summary.outputPath)).toBe(true);
|
|
320
|
+
const content = _fs.default.readFileSync(summary.outputPath, 'utf-8');
|
|
321
|
+
const parsed = JSON.parse(content);
|
|
322
|
+
expect(parsed.status).toBe('SUCCESS');
|
|
323
|
+
});
|
|
324
|
+
test('should create parent directories if not exist', () => {
|
|
325
|
+
const customPath = _path.default.join(TEST_OUTPUT_DIR, 'nested/deep/summary.json');
|
|
326
|
+
const customSummary = (0, _pipelineSummary.createPipelineSummary)('Test', {
|
|
327
|
+
outputPath: customPath
|
|
328
|
+
});
|
|
329
|
+
const response = customSummary.success();
|
|
330
|
+
const saved = customSummary.saveToFile(response);
|
|
331
|
+
expect(saved).toBe(true);
|
|
332
|
+
expect(_fs.default.existsSync(customPath)).toBe(true);
|
|
333
|
+
});
|
|
334
|
+
test('should handle missing output path', () => {
|
|
335
|
+
const noPathSummary = (0, _pipelineSummary.createPipelineSummary)('Test');
|
|
336
|
+
const response = noPathSummary.success();
|
|
337
|
+
const saved = noPathSummary.saveToFile(response);
|
|
338
|
+
expect(saved).toBe(false);
|
|
339
|
+
});
|
|
340
|
+
test('should format JSON with indentation', () => {
|
|
341
|
+
const response = summary.success();
|
|
342
|
+
summary.saveToFile(response);
|
|
343
|
+
const content = _fs.default.readFileSync(summary.outputPath, 'utf-8');
|
|
344
|
+
expect(content).toContain('\n');
|
|
345
|
+
expect(content).toContain(' ');
|
|
346
|
+
});
|
|
347
|
+
test('should override output path', () => {
|
|
348
|
+
const customPath = _path.default.join(TEST_OUTPUT_DIR, 'custom.json');
|
|
349
|
+
const response = summary.success();
|
|
350
|
+
summary.saveToFile(response, customPath);
|
|
351
|
+
expect(_fs.default.existsSync(customPath)).toBe(true);
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
356
|
+
// SAVE AND RETURN TESTS
|
|
357
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
358
|
+
|
|
359
|
+
describe('saveAndReturn()', () => {
|
|
360
|
+
test('should return response and save status', () => {
|
|
361
|
+
const response = summary.success();
|
|
362
|
+
const {
|
|
363
|
+
response: retResponse,
|
|
364
|
+
saved
|
|
365
|
+
} = summary.saveAndReturn(response);
|
|
366
|
+
expect(retResponse).toEqual(response);
|
|
367
|
+
expect(saved).toBe(true);
|
|
368
|
+
expect(_fs.default.existsSync(summary.outputPath)).toBe(true);
|
|
369
|
+
});
|
|
370
|
+
test('should indicate save failure', () => {
|
|
371
|
+
const noPathSummary = (0, _pipelineSummary.createPipelineSummary)('Test');
|
|
372
|
+
const response = noPathSummary.success();
|
|
373
|
+
const {
|
|
374
|
+
saved
|
|
375
|
+
} = noPathSummary.saveAndReturn(response);
|
|
376
|
+
expect(saved).toBe(false);
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
381
|
+
// EDGE CASES
|
|
382
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
383
|
+
|
|
384
|
+
describe('edge cases', () => {
|
|
385
|
+
test('should handle very long error messages', () => {
|
|
386
|
+
const longMessage = 'x'.repeat(10000);
|
|
387
|
+
const response = summary.failure({
|
|
388
|
+
errorMessage: longMessage
|
|
389
|
+
});
|
|
390
|
+
expect(response.error.message).toBe(longMessage);
|
|
391
|
+
});
|
|
392
|
+
test('should handle special characters in messages', () => {
|
|
393
|
+
const response = summary.failure({
|
|
394
|
+
message: 'Failed: "test" & <script>alert(1)</script>'
|
|
395
|
+
});
|
|
396
|
+
expect(response.message).toContain('<script>');
|
|
397
|
+
});
|
|
398
|
+
test('should handle null/undefined in optional fields', () => {
|
|
399
|
+
const response = summary.failure({
|
|
400
|
+
errorMessage: null,
|
|
401
|
+
errors: null
|
|
402
|
+
});
|
|
403
|
+
expect(response.error.message).toBeNull();
|
|
404
|
+
expect(Array.isArray(response.error.errors)).toBe(true);
|
|
405
|
+
});
|
|
406
|
+
test('should handle errors with circular references', () => {
|
|
407
|
+
const circularObj = {
|
|
408
|
+
name: 'test'
|
|
409
|
+
};
|
|
410
|
+
circularObj.self = circularObj;
|
|
411
|
+
|
|
412
|
+
// Should not throw
|
|
413
|
+
const response = summary.failure({
|
|
414
|
+
errors: [circularObj]
|
|
415
|
+
});
|
|
416
|
+
expect(response.error.errors).toBeDefined();
|
|
417
|
+
});
|
|
418
|
+
test('should handle unicode characters', () => {
|
|
419
|
+
const response = summary.failure({
|
|
420
|
+
errorMessage: '测试失败 🔥 エラーが発生しました'
|
|
421
|
+
});
|
|
422
|
+
expect(response.error.message).toContain('测试失败');
|
|
423
|
+
expect(response.error.message).toContain('🔥');
|
|
424
|
+
});
|
|
425
|
+
test('should handle multiple consecutive saves', () => {
|
|
426
|
+
const response1 = summary.success({
|
|
427
|
+
message: 'First'
|
|
428
|
+
});
|
|
429
|
+
const response2 = summary.failure({
|
|
430
|
+
message: 'Second'
|
|
431
|
+
});
|
|
432
|
+
summary.saveToFile(response1);
|
|
433
|
+
summary.saveToFile(response2);
|
|
434
|
+
const content = _fs.default.readFileSync(summary.outputPath, 'utf-8');
|
|
435
|
+
const parsed = JSON.parse(content);
|
|
436
|
+
expect(parsed.message).toBe('Second');
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
441
|
+
// ERROR CATEGORIES EXPORT
|
|
442
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
443
|
+
|
|
444
|
+
describe('ERROR_CATEGORIES', () => {
|
|
445
|
+
test('should export valid error categories', () => {
|
|
446
|
+
expect(_pipelineSummary.ERROR_CATEGORIES.CODE).toBe('code');
|
|
447
|
+
expect(_pipelineSummary.ERROR_CATEGORIES.ENVIRONMENT).toBe('environment');
|
|
448
|
+
expect(_pipelineSummary.ERROR_CATEGORIES.FLAKY).toBe('flaky');
|
|
449
|
+
expect(_pipelineSummary.ERROR_CATEGORIES.TOOL).toBe('tool');
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
454
|
+
// FACTORY FUNCTION TESTS
|
|
455
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
456
|
+
|
|
457
|
+
describe('createPipelineSummary()', () => {
|
|
458
|
+
test('should create instance with stage name', () => {
|
|
459
|
+
const instance = (0, _pipelineSummary.createPipelineSummary)('MyStage');
|
|
460
|
+
expect(instance).toBeInstanceOf(_pipelineSummary.PipelineSummaryGenerator);
|
|
461
|
+
const response = instance.success();
|
|
462
|
+
expect(response.message).toContain('MyStage');
|
|
463
|
+
});
|
|
464
|
+
test('should merge options correctly', () => {
|
|
465
|
+
const instance = (0, _pipelineSummary.createPipelineSummary)('Build', {
|
|
466
|
+
outputPath: '/path/to/file.json',
|
|
467
|
+
webUrl: 'https://example.com'
|
|
468
|
+
});
|
|
469
|
+
const response = instance.success();
|
|
470
|
+
expect(response.web_url).toBe('https://example.com');
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
});
|