Skip to content

Commit e21efa2

Browse files
committed
test: add test for prerelease workflow
1 parent d5325a7 commit e21efa2

File tree

2 files changed

+272
-0
lines changed

2 files changed

+272
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Tests for the E2E matrix generation script
5+
* Usage: node generate-e2e-matrix.test.js
6+
*/
7+
8+
const { test } = require('node:test');
9+
const assert = require('node:assert');
10+
const { generateE2EMatrix } = require('./generate-e2e-matrix.js');
11+
12+
test('generateE2EMatrix should create cross-product of locales and shards', () => {
13+
const localesJson =
14+
'[{"locale":"zh-hans","secret_project_id":"VERCEL_PROJECT_ID_ZH_HANS"},{"locale":"zh-hant","secret_project_id":"VERCEL_PROJECT_ID_ZH_HANT"}]';
15+
const shardTotal = 3;
16+
17+
const result = generateE2EMatrix(localesJson, shardTotal);
18+
19+
// Should have 6 jobs total (2 locales × 3 shards)
20+
assert.strictEqual(result.include.length, 6);
21+
22+
// Check structure
23+
assert.ok(
24+
result.include.every(
25+
(job) =>
26+
Object.prototype.hasOwnProperty.call(job, 'locale') &&
27+
Object.prototype.hasOwnProperty.call(job, 'shard') &&
28+
Object.prototype.hasOwnProperty.call(job, 'secret_project_id'),
29+
),
30+
);
31+
32+
// Check shards are 1-indexed
33+
const shards = result.include.map((job) => job.shard).sort();
34+
assert.deepStrictEqual(shards, [1, 1, 2, 2, 3, 3]);
35+
36+
// Check both locales are present
37+
const locales = [...new Set(result.include.map((job) => job.locale))];
38+
assert.deepStrictEqual(locales.sort(), ['zh-hans', 'zh-hant']);
39+
});
40+
41+
test('generateE2EMatrix should handle single locale', () => {
42+
const localesJson =
43+
'[{"locale":"zh-hans","secret_project_id":"VERCEL_PROJECT_ID_ZH_HANS"}]';
44+
const shardTotal = 2;
45+
46+
const result = generateE2EMatrix(localesJson, shardTotal);
47+
48+
// Should have 2 jobs (1 locale × 2 shards)
49+
assert.strictEqual(result.include.length, 2);
50+
51+
// All jobs should be for zh-hans
52+
assert.ok(result.include.every((job) => job.locale === 'zh-hans'));
53+
54+
// Should have shards 1 and 2
55+
const shards = result.include.map((job) => job.shard).sort();
56+
assert.deepStrictEqual(shards, [1, 2]);
57+
});
58+
59+
test('generateE2EMatrix should handle single shard', () => {
60+
const localesJson =
61+
'[{"locale":"zh-hans","secret_project_id":"VERCEL_PROJECT_ID_ZH_HANS"},{"locale":"zh-hant","secret_project_id":"VERCEL_PROJECT_ID_ZH_HANT"}]';
62+
const shardTotal = 1;
63+
64+
const result = generateE2EMatrix(localesJson, shardTotal);
65+
66+
// Should have 2 jobs (2 locales × 1 shard)
67+
assert.strictEqual(result.include.length, 2);
68+
69+
// All jobs should have shard 1
70+
assert.ok(result.include.every((job) => job.shard === 1));
71+
72+
// Should have both locales
73+
const locales = result.include.map((job) => job.locale).sort();
74+
assert.deepStrictEqual(locales, ['zh-hans', 'zh-hant']);
75+
});
76+
77+
test('generateE2EMatrix should preserve additional properties', () => {
78+
const localesJson =
79+
'[{"locale":"zh-hans","secret_project_id":"VERCEL_PROJECT_ID_ZH_HANS","extra":"value"}]';
80+
const shardTotal = 2;
81+
82+
const result = generateE2EMatrix(localesJson, shardTotal);
83+
84+
// Should preserve the extra property
85+
assert.ok(result.include.every((job) => job.extra === 'value'));
86+
assert.ok(
87+
result.include.every(
88+
(job) => job.secret_project_id === 'VERCEL_PROJECT_ID_ZH_HANS',
89+
),
90+
);
91+
});
92+
93+
test('generateE2EMatrix should handle large shard counts', () => {
94+
const localesJson =
95+
'[{"locale":"zh-hans","secret_project_id":"VERCEL_PROJECT_ID_ZH_HANS"}]';
96+
const shardTotal = 10;
97+
98+
const result = generateE2EMatrix(localesJson, shardTotal);
99+
100+
// Should have 10 jobs
101+
assert.strictEqual(result.include.length, 10);
102+
103+
// Should have shards 1 through 10
104+
const shards = result.include.map((job) => job.shard).sort((a, b) => a - b);
105+
assert.deepStrictEqual(shards, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
106+
});
107+
108+
test('generateE2EMatrix should handle empty locales array', () => {
109+
const localesJson = '[]';
110+
const shardTotal = 3;
111+
112+
const result = generateE2EMatrix(localesJson, shardTotal);
113+
114+
// Should have no jobs
115+
assert.strictEqual(result.include.length, 0);
116+
});
117+
118+
test('generateE2EMatrix should throw on invalid JSON', () => {
119+
try {
120+
generateE2EMatrix('invalid json', 3);
121+
assert.fail('Expected function to throw');
122+
} catch (error) {
123+
assert.ok(error.message.includes('Unexpected token'));
124+
}
125+
});
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Simple tests for the prerelease matrix generation script
5+
* Usage: node test-prerelease-matrix.js
6+
*/
7+
8+
const { test } = require('node:test');
9+
const assert = require('node:assert');
10+
const {
11+
processPrerelease,
12+
isLocaleEnabled,
13+
getLocaleConfig,
14+
} = require('./generate-prerelease-matrix.js');
15+
16+
// Mock locale config for testing
17+
const mockLocaleConfig = {
18+
en: {
19+
secret_project_id: 'VERCEL_PROJECT_EN_ID',
20+
enabled: true,
21+
},
22+
'zh-hans': {
23+
secret_project_id: 'VERCEL_PROJECT_ZH_HANS_ID',
24+
enabled: true,
25+
},
26+
'zh-hant': {
27+
secret_project_id: 'VERCEL_PROJECT_ZH_HANT_ID',
28+
enabled: true,
29+
},
30+
ja: {
31+
secret_project_id: 'VERCEL_PROJECT_JA_ID',
32+
enabled: false,
33+
},
34+
es: {
35+
secret_project_id: 'VERCEL_PROJECT_ES_ID',
36+
enabled: false,
37+
},
38+
};
39+
40+
test('isLocaleEnabled should return correct boolean values', () => {
41+
assert.strictEqual(isLocaleEnabled(mockLocaleConfig, 'en'), true);
42+
assert.strictEqual(isLocaleEnabled(mockLocaleConfig, 'zh-hans'), true);
43+
assert.strictEqual(isLocaleEnabled(mockLocaleConfig, 'zh-hant'), true);
44+
assert.strictEqual(isLocaleEnabled(mockLocaleConfig, 'ja'), false);
45+
assert.strictEqual(isLocaleEnabled(mockLocaleConfig, 'es'), false);
46+
assert.strictEqual(isLocaleEnabled(mockLocaleConfig, 'nonexistent'), false);
47+
});
48+
49+
test('getLocaleConfig should return correct configuration values', () => {
50+
assert.strictEqual(
51+
getLocaleConfig(mockLocaleConfig, 'en', 'secret_project_id'),
52+
'VERCEL_PROJECT_EN_ID',
53+
);
54+
assert.strictEqual(
55+
getLocaleConfig(mockLocaleConfig, 'zh-hans', 'secret_project_id'),
56+
'VERCEL_PROJECT_ZH_HANS_ID',
57+
);
58+
assert.strictEqual(
59+
getLocaleConfig(mockLocaleConfig, 'nonexistent', 'secret_project_id'),
60+
'',
61+
);
62+
assert.strictEqual(
63+
getLocaleConfig(mockLocaleConfig, 'en', 'nonexistent_field'),
64+
'',
65+
);
66+
});
67+
68+
test('processPrerelease should handle general prerelease label (deploy all enabled locales)', () => {
69+
const result = processPrerelease(mockLocaleConfig, ['prerelease']);
70+
71+
// Should include all enabled locales
72+
assert.strictEqual(result.matrixInclude.length, 3);
73+
assert.strictEqual(result.hasChanges, true);
74+
75+
const locales = result.matrixInclude.map((item) => item.locale);
76+
assert.ok(locales.includes('en'));
77+
assert.ok(locales.includes('zh-hans'));
78+
assert.ok(locales.includes('zh-hant'));
79+
assert.ok(!locales.includes('ja')); // ja is disabled
80+
assert.ok(!locales.includes('es')); // es is disabled
81+
});
82+
83+
test('processPrerelease should handle specific locale prerelease', () => {
84+
const result = processPrerelease(mockLocaleConfig, [
85+
'prerelease:en',
86+
'prerelease:zh-hans',
87+
]);
88+
89+
// Should include only the specified locales
90+
assert.strictEqual(result.matrixInclude.length, 2);
91+
assert.strictEqual(result.hasChanges, true);
92+
93+
const locales = result.matrixInclude.map((item) => item.locale);
94+
assert.ok(locales.includes('en'));
95+
assert.ok(locales.includes('zh-hans'));
96+
assert.ok(!locales.includes('zh-hant'));
97+
});
98+
99+
test('processPrerelease should skip disabled locales', () => {
100+
const result = processPrerelease(mockLocaleConfig, ['prerelease:ja']);
101+
102+
// Should not include disabled locale
103+
assert.strictEqual(result.matrixInclude.length, 0);
104+
assert.strictEqual(result.hasChanges, false);
105+
});
106+
107+
test('processPrerelease should handle mixed labels (general + specific)', () => {
108+
const result = processPrerelease(mockLocaleConfig, [
109+
'prerelease',
110+
'prerelease:ja',
111+
]);
112+
113+
// General prerelease should take precedence - deploy all enabled locales
114+
assert.strictEqual(result.matrixInclude.length, 3);
115+
assert.strictEqual(result.hasChanges, true);
116+
117+
const locales = result.matrixInclude.map((item) => item.locale);
118+
assert.ok(locales.includes('en'));
119+
assert.ok(locales.includes('zh-hans'));
120+
assert.ok(locales.includes('zh-hant'));
121+
});
122+
123+
test('processPrerelease should handle no prerelease labels', () => {
124+
const result = processPrerelease(mockLocaleConfig, ['bug', 'feature']);
125+
126+
// Should include no locales when no prerelease labels
127+
assert.strictEqual(result.matrixInclude.length, 0);
128+
assert.strictEqual(result.hasChanges, false);
129+
});
130+
131+
test('processPrerelease should handle empty labels array', () => {
132+
const result = processPrerelease(mockLocaleConfig, []);
133+
134+
// Should include no locales when no labels
135+
assert.strictEqual(result.matrixInclude.length, 0);
136+
assert.strictEqual(result.hasChanges, false);
137+
});
138+
139+
test('processPrerelease should handle non-existent locale', () => {
140+
const result = processPrerelease(mockLocaleConfig, ['prerelease:invalid']);
141+
142+
// Should not include non-existent locale
143+
assert.strictEqual(result.matrixInclude.length, 0);
144+
assert.strictEqual(result.hasChanges, false);
145+
});
146+
147+
console.log('All tests passed! ✅');

0 commit comments

Comments
 (0)