Skip to content

Commit edd897a

Browse files
authored
Migrate jest to vitest & update eslint (#12)
1 parent 9ff6463 commit edd897a

11 files changed

Lines changed: 1474 additions & 2600 deletions

File tree

.eslintignore

Lines changed: 0 additions & 4 deletions
This file was deleted.

.eslintrc.js

Lines changed: 0 additions & 19 deletions
This file was deleted.

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212

1313
strategy:
1414
matrix:
15-
node-version: [18, 20, 22, 24]
15+
node-version: [20, 22, 24]
1616

1717
steps:
1818
- uses: actions/checkout@v4

bun.lock

Lines changed: 227 additions & 450 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli.ts

Lines changed: 119 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -9,138 +9,139 @@ import { generateKcm } from "./generator/generateKcm"
99
import { generateChr_background } from "./generator/generateChr_background"
1010
import { generateChr_manifest } from "./generator/generateChr_manifest"
1111
import { fixUnicode } from "./utils"
12+
import { argv } from "yargs"
1213

13-
// eslint-disable-next-line @typescript-eslint/no-var-requires
14-
prompts.override(require("yargs").argv)
14+
prompts.override(argv)
1515

16-
const filenames = fs.readdirSync("input")
17-
.filter(name => name.endsWith(".json") && !name.endsWith(".json.bak"))
16+
const filenames = fs
17+
.readdirSync("input")
18+
.filter((name) => name.endsWith(".json") && !name.endsWith(".json.bak"))
1819
.sort((a, b) => a.localeCompare(b))
1920
const choices = filenames.map((filename) => ({
2021
title: filename,
2122
value: filename,
2223
}))
2324

24-
; (async () => {
25-
const response = await prompts({
26-
type: "select",
27-
name: "input",
28-
message: "Pick input JSON file",
29-
choices,
30-
})
31-
32-
const jsonInput = JSON.parse(
33-
fs.readFileSync(path.join(process.cwd(), "input", response.input), "utf8")
34-
)
35-
36-
let jsonName: string;
37-
let layoutName: string;
38-
let safeLayoutName: string;
39-
let dir: string;
40-
41-
try {
42-
jsonName = response.input.split(".").slice(0, -1).join(".");
43-
layoutName = jsonInput.name;
44-
// Replace spaces with underscores for safe use in IDs or filenames for some system
45-
safeLayoutName = layoutName.replace(/\s+/g, "_").replace(/\./g, "_");
46-
dir = `output/${jsonName}`;
47-
if (!fs.existsSync(dir)) {
48-
fs.mkdirSync(dir);
49-
}
50-
} catch (e) {
51-
console.error(e)
52-
process.exit(1)
25+
;(async () => {
26+
const response = await prompts({
27+
type: "select",
28+
name: "input",
29+
message: "Pick input JSON file",
30+
choices,
31+
})
32+
33+
const jsonInput = JSON.parse(
34+
fs.readFileSync(path.join(process.cwd(), "input", response.input), "utf8"),
35+
)
36+
37+
let jsonName: string
38+
let layoutName: string
39+
let safeLayoutName: string
40+
let dir: string
41+
42+
try {
43+
jsonName = response.input.split(".").slice(0, -1).join(".")
44+
layoutName = jsonInput.name
45+
// Replace spaces with underscores for safe use in IDs or filenames for some system
46+
safeLayoutName = layoutName.replace(/\s+/g, "_").replace(/\./g, "_")
47+
dir = `output/${jsonName}`
48+
if (!fs.existsSync(dir)) {
49+
fs.mkdirSync(dir)
5350
}
54-
55-
// Keylayout
56-
try {
57-
const keylayoutXml = await generateKeylayout(jsonInput)
58-
const bundleDir = `${dir}/${layoutName}.bundle`
59-
const contentsDir = `${bundleDir}/Contents`
60-
const resourceDir = `${contentsDir}/Resources`
61-
const lprojDir = `${resourceDir}/th.lproj`
62-
if (!fs.existsSync(lprojDir)) {
63-
fs.mkdirSync(lprojDir, { recursive: true })
64-
}
65-
const outputFilename = `${resourceDir}/${layoutName}.keylayout`
66-
fs.writeFileSync(outputFilename, keylayoutXml, "utf-8")
67-
fixUnicode(outputFilename)
68-
69-
console.log(`Output : ${outputFilename}`)
70-
71-
const iconName = jsonInput.icon ? `icon_${jsonInput.icon}` : 'icon';
72-
fs.copyFileSync(
73-
`src/iconMac/${iconName}.icns`,
74-
path.join(resourceDir, `${layoutName}.icns`)
75-
);
76-
77-
const files = await generateMacBundle(jsonInput)
78-
for (const [filename, content] of Object.entries(files)) {
79-
const filePath = path.join(contentsDir, filename)
80-
fs.writeFileSync(filePath, content, "utf-8")
81-
}
82-
} catch (e) {
83-
console.error(e)
84-
process.exit(1)
51+
} catch (e) {
52+
console.error(e)
53+
process.exit(1)
54+
}
55+
56+
// Keylayout
57+
try {
58+
const keylayoutXml = await generateKeylayout(jsonInput)
59+
const bundleDir = `${dir}/${layoutName}.bundle`
60+
const contentsDir = `${bundleDir}/Contents`
61+
const resourceDir = `${contentsDir}/Resources`
62+
const lprojDir = `${resourceDir}/th.lproj`
63+
if (!fs.existsSync(lprojDir)) {
64+
fs.mkdirSync(lprojDir, { recursive: true })
8565
}
66+
const outputFilename = `${resourceDir}/${layoutName}.keylayout`
67+
fs.writeFileSync(outputFilename, keylayoutXml, "utf-8")
68+
fixUnicode(outputFilename)
8669

70+
console.log(`Output : ${outputFilename}`)
8771

88-
// Klc
89-
try {
90-
if (!fs.existsSync(dir)){
91-
fs.mkdirSync(dir);
92-
}
93-
const outputFilename = `${dir}/`+jsonInput.os.windows.installerName+`.klc`
94-
await generateKlc(jsonInput, outputFilename)
72+
const iconName = jsonInput.icon ? `icon_${jsonInput.icon}` : "icon"
73+
fs.copyFileSync(
74+
`src/iconMac/${iconName}.icns`,
75+
path.join(resourceDir, `${layoutName}.icns`),
76+
)
9577

96-
console.log(`Output : ${outputFilename}`)
97-
} catch (e) {
98-
console.error(e)
99-
process.exit(1)
78+
const files = await generateMacBundle(jsonInput)
79+
for (const [filename, content] of Object.entries(files)) {
80+
const filePath = path.join(contentsDir, filename)
81+
fs.writeFileSync(filePath, content, "utf-8")
10082
}
101-
102-
// Xkb
103-
try {
104-
const outputFilename = `${dir}/${safeLayoutName}_xkb`
105-
await generateXkb(jsonInput, outputFilename)
106-
107-
console.log(`Output : ${outputFilename}`)
108-
} catch (e) {
109-
console.error(e)
110-
process.exit(1)
83+
} catch (e) {
84+
console.error(e)
85+
process.exit(1)
86+
}
87+
88+
// Klc
89+
try {
90+
if (!fs.existsSync(dir)) {
91+
fs.mkdirSync(dir)
11192
}
112-
113-
// Kmc
114-
try {
115-
if (!fs.existsSync(dir)){
116-
fs.mkdirSync(dir);
117-
}
118-
const outputFilename = `${dir}/${safeLayoutName}.kcm`
119-
await generateKcm(jsonInput, outputFilename)
120-
121-
console.log(`Output : ${outputFilename}`)
122-
} catch (e) {
123-
console.error(e)
124-
process.exit(1)
93+
const outputFilename =
94+
`${dir}/` + jsonInput.os.windows.installerName + `.klc`
95+
await generateKlc(jsonInput, outputFilename)
96+
97+
console.log(`Output : ${outputFilename}`)
98+
} catch (e) {
99+
console.error(e)
100+
process.exit(1)
101+
}
102+
103+
// Xkb
104+
try {
105+
const outputFilename = `${dir}/${safeLayoutName}_xkb`
106+
await generateXkb(jsonInput, outputFilename)
107+
108+
console.log(`Output : ${outputFilename}`)
109+
} catch (e) {
110+
console.error(e)
111+
process.exit(1)
112+
}
113+
114+
// Kmc
115+
try {
116+
if (!fs.existsSync(dir)) {
117+
fs.mkdirSync(dir)
125118
}
126-
127-
// Chr___OS
128-
try {
129-
const chrDir = `${dir}/${jsonInput.os.windows.installerName.toLowerCase()}`
130-
if (!fs.existsSync(chrDir)){
131-
fs.mkdirSync(chrDir);
132-
}
133-
const outputManifest = chrDir+`/manifest.json`
134-
await generateChr_manifest(jsonInput, outputManifest)
135-
console.log(`Output : ${outputManifest}`)
136-
const outputBackground = chrDir+`/background.js`
137-
await generateChr_background(jsonInput, outputBackground)
138-
console.log(`Output : ${outputBackground}`)
139-
fs.readdirSync('src/iconChr').forEach(f =>
140-
fs.copyFileSync(path.join('src/iconChr', f), path.join(chrDir, f))
141-
)
142-
} catch (e) {
143-
console.error(e)
144-
process.exit(1)
119+
const outputFilename = `${dir}/${safeLayoutName}.kcm`
120+
await generateKcm(jsonInput, outputFilename)
121+
122+
console.log(`Output : ${outputFilename}`)
123+
} catch (e) {
124+
console.error(e)
125+
process.exit(1)
126+
}
127+
128+
// Chr___OS
129+
try {
130+
const chrDir = `${dir}/${jsonInput.os.windows.installerName.toLowerCase()}`
131+
if (!fs.existsSync(chrDir)) {
132+
fs.mkdirSync(chrDir)
145133
}
146-
})()
134+
const outputManifest = chrDir + `/manifest.json`
135+
await generateChr_manifest(jsonInput, outputManifest)
136+
console.log(`Output : ${outputManifest}`)
137+
const outputBackground = chrDir + `/background.js`
138+
await generateChr_background(jsonInput, outputBackground)
139+
console.log(`Output : ${outputBackground}`)
140+
fs.readdirSync("src/iconChr").forEach((f) =>
141+
fs.copyFileSync(path.join("src/iconChr", f), path.join(chrDir, f)),
142+
)
143+
} catch (e) {
144+
console.error(e)
145+
process.exit(1)
146+
}
147+
})()

eslint.config.mts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import js from "@eslint/js"
2+
import globals from "globals"
3+
import tseslint from "typescript-eslint"
4+
import { defineConfig, globalIgnores } from "eslint/config"
5+
import eslintConfigPrettier from "eslint-config-prettier/flat"
6+
7+
export default defineConfig([
8+
{
9+
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
10+
plugins: { js },
11+
extends: ["js/recommended"],
12+
languageOptions: { globals: { ...globals.browser, ...globals.node } },
13+
},
14+
tseslint.configs.recommended,
15+
eslintConfigPrettier,
16+
globalIgnores(["dist", "coverage", "output"]),
17+
])

jest.config.js

Lines changed: 0 additions & 4 deletions
This file was deleted.

package.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"scripts": {
1010
"generate": "ts-node cli.ts",
1111
"start": "ts-node .",
12-
"test": "jest",
12+
"test": "vitest",
1313
"lint": "eslint .",
1414
"prepare": "husky install"
1515
},
@@ -22,20 +22,23 @@
2222
"xml-js": "^1.6.11"
2323
},
2424
"devDependencies": {
25-
"@types/jest": "^29.5.14",
25+
"@eslint/eslintrc": "^3.3.1",
26+
"@eslint/js": "^9.36.0",
2627
"@types/node": "^20.19.9",
2728
"@types/prompts": "^2.4.9",
28-
"@typescript-eslint/eslint-plugin": "^6.21.0",
29-
"@typescript-eslint/parser": "^6.21.0",
30-
"eslint": "^8.57.1",
31-
"eslint-plugin-jest": "^27.9.0",
32-
"eslint-plugin-prettier": "^5.5.3",
29+
"@types/yargs": "^17.0.33",
30+
"@vitest/coverage-v8": "3.2.4",
31+
"@vitest/ui": "^3.2.4",
32+
"eslint": "^9.36.0",
33+
"eslint-config-prettier": "^10.1.8",
34+
"globals": "^16.4.0",
3335
"husky": "^8.0.3",
34-
"jest": "^29.7.0",
36+
"jiti": "^2.6.1",
3537
"prettier": "3.0.0",
36-
"ts-jest": "^29.4.1",
3738
"ts-node": "^10.9.2",
38-
"typescript": "^5.9.2"
39+
"typescript": "^5.9.3",
40+
"typescript-eslint": "^8.45.0",
41+
"vitest": "^3.2.4"
3942
},
4043
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
4144
}

test/main.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import fs from "fs"
22
import path from "path"
33
import { js2xml, xml2js } from "xml-js"
4+
import { describe, it, expect } from 'vitest'
45
import { validateLayout } from "../main"
56
import { generateKeylayout } from "../generator/generateKeylayout"
67
import { generateKlc } from "../generator/generateKlc"

vitest.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineConfig } from 'vitest/config'
2+
3+
export default defineConfig({
4+
test: {
5+
environment: 'node',
6+
},
7+
})

0 commit comments

Comments
 (0)