refactor(cli/node): migrate jest to vitest for tests (#11034)

* refactor(cli/node): migrate `jest` to `vitest` for tests

* fix js audit
This commit is contained in:
Amr Bashir
2024-09-17 13:36:03 +03:00
committed by GitHub
parent 5f694c3d4c
commit 09de8c6593
17 changed files with 316 additions and 2005 deletions

View File

@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "tauri-config-2.0.0-rc.14",
"$id": "https://schema.tauri.app/config/2.0.0-rc.14",
"title": "Config",
"description": "The Tauri configuration object.\n It is read from a file where you can define your frontend assets,\n configure the bundler and define a tray icon.\n\n The configuration file is generated by the\n [`tauri init`](https://tauri.app/v1/api/cli#init) command that lives in\n your Tauri application source directory (src-tauri).\n\n Once generated, you may modify it at will to customize your Tauri application.\n\n ## File Formats\n\n By default, the configuration is defined as a JSON file named `tauri.conf.json`.\n\n Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.\n The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.\n The TOML file name is `Tauri.toml`.\n\n ## Platform-Specific Configuration\n\n In addition to the default configuration file, Tauri can\n read a platform-specific configuration from `tauri.linux.conf.json`,\n `tauri.windows.conf.json`, `tauri.macos.conf.json`, `tauri.android.conf.json` and `tauri.ios.conf.json`\n (or `Tauri.linux.toml`, `Tauri.windows.toml`, `Tauri.macos.toml`, `Tauri.android.toml` and `Tauri.ios.toml` if the `Tauri.toml` format is used),\n which gets merged with the main configuration object.\n\n ## Configuration Structure\n\n The configuration is composed of the following objects:\n\n - [`app`](#appconfig): The Tauri configuration\n - [`build`](#buildconfig): The build configuration\n - [`bundle`](#bundleconfig): The bundle configurations\n - [`plugins`](#pluginconfig): The plugins configuration\n\n Example tauri.config.json file:\n\n ```json\n {\n \"productName\": \"tauri-app\",\n \"version\": \"0.1.0\",\n \"build\": {\n \"beforeBuildCommand\": \"\",\n \"beforeDevCommand\": \"\",\n \"devUrl\": \"../dist\",\n \"frontendDist\": \"../dist\"\n },\n \"app\": {\n \"security\": {\n \"csp\": null\n },\n \"windows\": [\n {\n \"fullscreen\": false,\n \"height\": 600,\n \"resizable\": true,\n \"title\": \"Tauri App\",\n \"width\": 800\n }\n ]\n },\n \"bundle\": {},\n \"plugins\": {}\n }\n ```",
"type": "object",

View File

@@ -47,7 +47,7 @@ pub fn main() -> Result<(), Box<dyn Error>> {
// set id for generated schema
let (filename, mut config_schema) = schema!("config", Config);
let schema_metadata = config_schema.schema.metadata.as_mut().unwrap();
schema_metadata.id = Some(format!("tauri-config-{}", tauri_ver));
schema_metadata.id = Some(format!("https://schema.tauri.app/config/{tauri_ver}"));
let config_schema = serde_json::to_string_pretty(&config_schema)?;
write_if_changed(schemas_dir.join(filename), &config_schema)?;

View File

@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "tauri-config-2.0.0-rc.14",
"$id": "https://schema.tauri.app/config/2.0.0-rc.14",
"title": "Config",
"description": "The Tauri configuration object.\n It is read from a file where you can define your frontend assets,\n configure the bundler and define a tray icon.\n\n The configuration file is generated by the\n [`tauri init`](https://tauri.app/v1/api/cli#init) command that lives in\n your Tauri application source directory (src-tauri).\n\n Once generated, you may modify it at will to customize your Tauri application.\n\n ## File Formats\n\n By default, the configuration is defined as a JSON file named `tauri.conf.json`.\n\n Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.\n The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.\n The TOML file name is `Tauri.toml`.\n\n ## Platform-Specific Configuration\n\n In addition to the default configuration file, Tauri can\n read a platform-specific configuration from `tauri.linux.conf.json`,\n `tauri.windows.conf.json`, `tauri.macos.conf.json`, `tauri.android.conf.json` and `tauri.ios.conf.json`\n (or `Tauri.linux.toml`, `Tauri.windows.toml`, `Tauri.macos.toml`, `Tauri.android.toml` and `Tauri.ios.toml` if the `Tauri.toml` format is used),\n which gets merged with the main configuration object.\n\n ## Configuration Structure\n\n The configuration is composed of the following objects:\n\n - [`app`](#appconfig): The Tauri configuration\n - [`build`](#buildconfig): The build configuration\n - [`bundle`](#bundleconfig): The bundle configurations\n - [`plugins`](#pluginconfig): The plugins configuration\n\n Example tauri.config.json file:\n\n ```json\n {\n \"productName\": \"tauri-app\",\n \"version\": \"0.1.0\",\n \"build\": {\n \"beforeBuildCommand\": \"\",\n \"beforeDevCommand\": \"\",\n \"devUrl\": \"../dist\",\n \"frontendDist\": \"../dist\"\n },\n \"app\": {\n \"security\": {\n \"csp\": null\n },\n \"windows\": [\n {\n \"fullscreen\": false,\n \"height\": 600,\n \"resizable\": true,\n \"title\": \"Tauri App\",\n \"width\": 800\n }\n ]\n },\n \"bundle\": {},\n \"plugins\": {}\n }\n ```",
"type": "object",

View File

@@ -8,6 +8,6 @@
"dev": "wrangler dev"
},
"devDependencies": {
"wrangler": "^3.73"
"wrangler": "^3.75"
}
}

View File

@@ -2,24 +2,25 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
const fixtureSetup = require('../fixtures/app-test-setup.js')
const { resolve } = require('path')
const { existsSync, readFileSync, writeFileSync, rmSync } = require('fs')
const { move } = require('fs-extra')
const cli = require('~/main.js')
const currentDirName = __dirname
import { resolve } from 'node:path'
import {
existsSync,
readFileSync,
writeFileSync,
rmSync,
renameSync
} from 'node:fs'
import cli from '../main.js'
import { describe, it } from 'vitest'
describe('[CLI] @tauri-apps/cli template', () => {
it('init a project and builds it', async () => {
it('init a project and builds it', { timeout: 200000 }, async () => {
const cwd = process.cwd()
const fixturePath = resolve(currentDirName, '../fixtures/empty')
const fixturePath = resolve(__dirname, './fixtures/empty')
const tauriFixturePath = resolve(fixturePath, 'src-tauri')
const outPath = resolve(tauriFixturePath, 'target')
const cacheOutPath = resolve(fixturePath, 'target')
fixtureSetup.initJest('empty')
process.chdir(fixturePath)
const outExists = existsSync(outPath)
@@ -27,7 +28,7 @@ describe('[CLI] @tauri-apps/cli template', () => {
if (existsSync(cacheOutPath)) {
rmSync(cacheOutPath, { recursive: true, force: true })
}
await move(outPath, cacheOutPath)
renameSync(outPath, cacheOutPath)
}
await cli.run([
@@ -36,7 +37,7 @@ describe('[CLI] @tauri-apps/cli template', () => {
process.cwd(),
'--force',
'--tauri-path',
resolve(currentDirName, '../../../../..'),
resolve(__dirname, '../../..'),
'--before-build-command',
'',
'--before-dev-command',
@@ -45,7 +46,7 @@ describe('[CLI] @tauri-apps/cli template', () => {
])
if (outExists) {
await move(cacheOutPath, outPath)
renameSync(cacheOutPath, outPath)
}
process.chdir(tauriFixturePath)

View File

@@ -1,18 +0,0 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
module.exports = {
setupFilesAfterEnv: ['<rootDir>/test/jest/jest.setup.js'],
testMatch: [
'<rootDir>/test/jest/__tests__/**/*.spec.js',
'<rootDir>/test/jest/__tests__/**/*.test.js'
],
moduleFileExtensions: ['ts', 'js', 'json'],
moduleNameMapper: {
'^~/(.*)$': '<rootDir>/$1'
},
transform: {
'\\.toml$': 'jest-transform-toml'
}
}

View File

@@ -7,5 +7,5 @@
export function run(
args: Array<string>,
binName: string | undefined | null
binName?: string | undefined | null
): Promise<void>

View File

@@ -39,12 +39,9 @@
},
"devDependencies": {
"@napi-rs/cli": "2.18.3",
"@types/node": "20.16.1",
"cross-env": "7.0.3",
"cross-spawn": "7.0.3",
"fs-extra": "11.2.0",
"jest": "29.7.0",
"jest-transform-toml": "1.0.0",
"prettier": "3.3.2"
"vitest": "^2.1.1"
},
"engines": {
"node": ">= 10"
@@ -58,8 +55,8 @@
"build": "cross-env TARGET=node napi build --platform",
"prepublishOnly": "napi prepublish -t npm --gh-release-id $RELEASE_ID",
"prepack": "cp ../../crates/tauri-schema-generator/schemas/config.schema.json .",
"test": "jest --runInBand --forceExit --no-cache",
"version": "napi version",
"test": "vitest run",
"tauri": "node ./tauri.js"
}
}

View File

@@ -18,7 +18,7 @@ pub fn run(args: Vec<String>, bin_name: Option<String>, callback: JsFunction) ->
// can do work while `tauri dev` is running.
std::thread::spawn(move || {
let res = match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
tauri_cli::try_run(args, bin_name)
tauri_cli::try_run(args, bin_name).inspect_err(|e| eprintln!("{e:#}"))
})) {
Ok(t) => t,
Err(_) => {

View File

@@ -1,90 +0,0 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
const path = require('path')
const http = require('http')
const currentDirName = __dirname
const mockFixtureDir = path.resolve(currentDirName, '../fixtures')
module.exports.fixtureDir = mockFixtureDir
module.exports.initJest = (mockFixture) => {
jest.setTimeout(1200000)
const mockAppDir = path.join(mockFixtureDir, mockFixture)
process.env.__TAURI_TEST_APP_DIR = mockAppDir
}
module.exports.startServer = (onSuccess) => {
const responses = {
writeFile: null,
readFile: null,
writeFileWithDir: null,
readFileWithDir: null,
readDir: null,
readDirWithDir: null,
copyFile: null,
copyFileWithDir: null,
createDir: null,
createDirWithDir: null,
removeDir: null,
removeDirWithDir: null,
renameFile: null,
renameFileWithDir: null,
removeFile: null,
renameFileWithDir: null,
listen: null
}
function addResponse(response) {
responses[response.cmd] = true
if (!Object.values(responses).some((c) => c === null)) {
server.close(onSuccess)
}
}
const app = http.createServer((req, res) => {
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*')
res.setHeader('Access-Control-Request-Method', '*')
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET')
res.setHeader('Access-Control-Allow-Headers', '*')
if (req.method === 'OPTIONS') {
res.writeHead(200)
res.end()
return
}
if (req.method === 'POST') {
let body = ''
req.on('data', (chunk) => {
body += chunk.toString()
})
if (req.url === '/reply') {
req.on('end', () => {
const json = JSON.parse(body)
addResponse(json)
res.writeHead(200)
res.end()
})
}
if (req.url === '/error') {
req.on('end', () => {
res.writeHead(200)
res.end()
throw new Error(body)
})
}
}
})
const port = 7000
const server = app.listen(port)
return {
server,
responses
}
}

View File

@@ -1,25 +0,0 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
const ms = require('ms')
let prevTime
module.exports = (banner) => {
return (msg) => {
const curr = +new Date()
const diff = curr - (prevTime || curr)
prevTime = curr
if (msg) {
console.log(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-call
` ${String(banner)} ${msg} ${`+${ms(diff)}`}`
)
} else {
console.log()
}
}
}

View File

@@ -1,63 +0,0 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
const crossSpawn = require('cross-spawn')
const logger = require('./logger')
const log = logger('app:spawn')
const warn = logger('app:spawn')
/*
Returns pid, takes onClose
*/
module.exports.spawn = (cmd, params, cwd, onClose) => {
log(`Running "${cmd} ${params.join(' ')}"`)
log()
// TODO: move to execa?
const runner = crossSpawn(cmd, params, {
stdio: 'inherit',
cwd,
env: process.env
})
runner.on('close', (code) => {
log()
if (code) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
log(`Command "${cmd}" failed with exit code: ${code}`)
}
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
onClose && onClose(code || 0, runner.pid || 0)
})
return runner.pid || 0
}
/*
Returns nothing, takes onFail
*/
module.exports.spawnSync = (cmd, params, cwd, onFail) => {
log(`[sync] Running "${cmd} ${params.join(' ')}"`)
log()
const runner = crossSpawn.sync(cmd, params, {
stdio: 'inherit',
cwd
})
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
if (runner.status || runner.error) {
warn()
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
warn(`⚠️ Command "${cmd}" failed with exit code: ${runner.status}`)
if (runner.status === null) {
warn(`⚠️ Please globally install "${cmd}"`)
}
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
onFail && onFail()
process.exit(1)
}
}

View File

@@ -1,10 +0,0 @@
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
// 30 minute timeout: 20 minutes wasn't always enough for compilation in GitHub Actions.
jest.setTimeout(1800000)
setTimeout(() => {
// do nothing
}, 1)

2065
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff