-
Notifications
You must be signed in to change notification settings - Fork 96
/
Copy pathbun2jest.ts
143 lines (117 loc) · 4.41 KB
/
bun2jest.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import * as grit from '@getgrit/api';
import * as sdk from '@getgrit/workflows-sdk';
import { QueryBuilder } from '@getgrit/bridge';
/**
* Rewrite a Jest setup file to be usable as a --preload file
*/
async function transformTests(targetPath: string) {
grit.logging.debug(`Transforming Jest test files at ${targetPath}`);
const pattern = `or {
js"describe" where { add_import(js"describe", js"'bun:test'")},
js"it" where { add_import(js"it", js"'bun:test'")},
js"test($_)" where { add_import(js"test", js"'bun:test'")},
js"expect($_)" where { add_import(js"expect", js"'bun:test'")},
}`;
const query = new QueryBuilder(pattern);
const instanceCount = await query.run([targetPath]);
grit.logging.info(`Transformed Jest setup file at ${targetPath}, with ${instanceCount} changes`);
return targetPath;
}
/**
* Rewrite a Jest setup file to be usable as a --preload file
*/
async function transformSetupFile(targetPath: string) {
grit.logging.debug(`Transforming Jest setup file at ${targetPath}`);
const pattern = `js"$func($contents)" where {
$func <: or {
js"beforeAll" => js"beforeEachFile" where { add_import(js"beforeEachFile", js"'bun:test'")},
js"afterAll" => js"afterEachFile" where { add_import(js"afterEachFile", js"'bun:test'")},
}
}`;
const query = new QueryBuilder(pattern);
const instanceCount = await query.run([targetPath]);
grit.logging.info(`Transformed Jest setup file at ${targetPath}, with ${instanceCount} changes`);
return targetPath;
}
/**
* Fix the provided bun config
*/
async function fixBunConfig(targetPath: string, props: { [key: string]: any } = {}) {
grit.logging.debug(`Fixing Bun config at ${targetPath}`);
const pattern = `
language toml
file($body) where {
// $props = {preload: \`"foo.ts"\`},
$props = {${Object.entries(props).map(([key, value]) => `${key}: \`${value}\``).join(', ')}},
if ($body <: contains \`[test]
$existing\`) {
$props <: some bubble($existing) [$key, $value] where {
or {
$existing <: contains \`$key = $_\` => \`$key: $value\`,
$existing += \`\n$key = $value\`
}
}
} else {
$body += \`\n[test]\n\`,
$props <: some bubble($body) [$key, $value] where {
$body += \`$key = $value\n\`
}
}
}`;
grit.logging.debug(`Pattern: ${pattern}`);
const query = new QueryBuilder(pattern);
const instanceCount = await query.run([targetPath]);
grit.logging.info(`Fixed Bun config at ${targetPath}, with ${instanceCount} changes`);
return targetPath;
}
export default await sdk.defineWorkflow({
name: 'jest_to_bun',
run: async (options) => {
const targetDir = process.cwd();
const configRoot = targetDir;
// Look for a jest.config.json file
const targetFile = 'jest.config.js';
const config = await import(`${targetDir}/${targetFile}`);
grit.logging.debug(`Successfully loaded config`, config);
// Props we want to set up
const props: { [key: string]: string } = {};
await transformTests(`${configRoot}/src`);
// Convert from setupFilesAfterEnv -> preload with beforeEachFile
if (config.setupFilesAfterEnv) {
const preloads = [];
for (const setupFile of config.setupFilesAfterEnv) {
const actualFile = `${configRoot}/${setupFile}`;
const fixed = await transformSetupFile(actualFile);
grit.logging.debug(`Adding ${fixed} to preload`);
preloads.push(setupFile);
}
props.preload = JSON.stringify(preloads);
}
if (config.bail) {
props.bail = config.bail;
}
if (config.collectCoverage) {
props.coverage = config.collectCoverage;
}
if (config.coverageThreshold?.global) {
let parts = [];
if (config.coverageThreshold.global.lines) {
parts.push(`line = ${config.coverageThreshold.global.lines / 100}`);
}
if (config.coverageThreshold.global.functions) {
parts.push(`function = ${config.coverageThreshold.global.functions / 100}`);
}
if (config.coverageThreshold.global.statements) {
parts.push(`statement = ${config.coverageThreshold.global.statements / 100}`);
}
props.coverageThreshold = `{${parts.join(', ')}}`;
}
// Apply the bunfig
const bunConfig = `${configRoot}/Bunfig.toml`;
await fixBunConfig(bunConfig, props);
return {
success: true,
message: 'Jest to Bun',
}
},
});