mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 02:06:08 +03:00
test(es): Make execution tests faster (#4789)
This commit is contained in:
parent
f2d79b8495
commit
38a866a900
23
.github/workflows/cargo.yml
vendored
23
.github/workflows/cargo.yml
vendored
@ -377,21 +377,30 @@ jobs:
|
||||
run: |
|
||||
jest -v && mocha --version
|
||||
|
||||
- name: Configure execution cache
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p .swc-exec-cache
|
||||
echo "SWC_ECMA_TESTING_CACHE_DIR=$(pwd)/.swc-exec-cache" >> $GITHUB_ENV
|
||||
|
||||
- name: Cache execution results
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
.swc-exec-cache
|
||||
key: swc-exec-cache-${{ runner.os }}-${{ matrix.settings.crate }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
swc-exec-cache-${{ runner.os }}-${{ matrix.settings.crate }}
|
||||
|
||||
- name: Run cargo test
|
||||
run: |
|
||||
jest -v && mocha --version
|
||||
cargo test --color always -p ${{ matrix.settings.crate }}
|
||||
|
||||
- name: Run cargo test (all features)
|
||||
if: matrix.settings.crate == 'swc_ecma_parser' || matrix.settings.crate == 'swc_ecma_loader'
|
||||
if: matrix.settings.crate == 'swc_ecma_parser' || matrix.settings.crate == 'swc_ecma_loader' || matrix.settings.crate == 'swc_ecma_transforms'
|
||||
run: |
|
||||
cargo test --color always -p ${{ matrix.settings.crate }} --all-features
|
||||
|
||||
- name: Run cargo test (swc_ecma_transforms)
|
||||
if: matrix.settings.crate == 'swc_ecma_transforms'
|
||||
run: |
|
||||
cargo test --color always -p swc_ecma_transforms --all-features
|
||||
|
||||
- name: Install cargo-hack
|
||||
uses: baptiste0928/cargo-install@v1.1.0
|
||||
if: matrix.settings.os == 'ubuntu-latest' && matrix.settings.check
|
||||
|
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -2991,6 +2991,7 @@ dependencies = [
|
||||
"swc_ecma_minifier",
|
||||
"swc_ecma_parser",
|
||||
"swc_ecma_preset_env",
|
||||
"swc_ecma_testing",
|
||||
"swc_ecma_transforms",
|
||||
"swc_ecma_transforms_base",
|
||||
"swc_ecma_transforms_compat",
|
||||
@ -3437,6 +3438,7 @@ dependencies = [
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_codegen",
|
||||
"swc_ecma_parser",
|
||||
"swc_ecma_testing",
|
||||
"swc_ecma_transforms_base",
|
||||
"swc_ecma_transforms_optimization",
|
||||
"swc_ecma_utils",
|
||||
@ -3529,6 +3531,20 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_testing"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"hex",
|
||||
"sha-1",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_codegen",
|
||||
"testing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms"
|
||||
version = "0.154.0"
|
||||
@ -3753,6 +3769,7 @@ dependencies = [
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_codegen",
|
||||
"swc_ecma_parser",
|
||||
"swc_ecma_testing",
|
||||
"swc_ecma_transforms_base",
|
||||
"swc_ecma_utils",
|
||||
"swc_ecma_visit",
|
||||
|
@ -37,6 +37,7 @@ once_cell = "1.10.0"
|
||||
parking_lot = "0.12.0"
|
||||
pathdiff = "0.2.0"
|
||||
regex = "1"
|
||||
rustc-hash = "1.1.0"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
sourcemap = "6"
|
||||
@ -81,7 +82,6 @@ swc_plugin_runner = { version = "0.55.0", path = "../swc_plugin_runner", optiona
|
||||
swc_timer = { version = "0.6.0", path = "../swc_timer" }
|
||||
swc_visit = { version = "0.3.0", path = "../swc_visit" }
|
||||
tracing = "0.1.32"
|
||||
rustc-hash = "1.1.0"
|
||||
|
||||
[dependencies.napi-derive]
|
||||
default-features = false
|
||||
@ -102,6 +102,7 @@ rayon = "1.5.1"
|
||||
swc_ecma_lints = { version = "0.41.0", path = "../swc_ecma_lints", features = [
|
||||
"non_critical_lints",
|
||||
] }
|
||||
swc_ecma_testing = { version = "0.1.0", path = "../swc_ecma_testing" }
|
||||
swc_node_base = { version = "0.5.0", path = "../swc_node_base" }
|
||||
testing = { version = "0.20.0", path = "../testing" }
|
||||
walkdir = "2"
|
||||
|
@ -1,7 +1,6 @@
|
||||
use std::{
|
||||
fs::{create_dir_all, rename},
|
||||
path::{Component, Path, PathBuf},
|
||||
process::Command,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
@ -13,6 +12,7 @@ use swc::{
|
||||
use swc_common::{errors::ColorConfig, SourceMap};
|
||||
use swc_ecma_ast::EsVersion;
|
||||
use swc_ecma_parser::{EsConfig, Syntax, TsConfig};
|
||||
use swc_ecma_testing::{exec_node_js, JsExecOptions};
|
||||
use testing::assert_eq;
|
||||
use tracing::{span, Level};
|
||||
|
||||
@ -294,27 +294,14 @@ enum NodeModuleType {
|
||||
}
|
||||
|
||||
fn stdout_of(code: &str, module_type: NodeModuleType) -> Result<String, Error> {
|
||||
let module_type = match module_type {
|
||||
NodeModuleType::CommonJs => "--input-type=commonjs",
|
||||
NodeModuleType::Module => "--input-type=module",
|
||||
};
|
||||
let actual_output = Command::new("node")
|
||||
.arg(module_type)
|
||||
.arg("-e")
|
||||
.arg(&code)
|
||||
.output()
|
||||
.context("failed to execute output of minifier")?;
|
||||
let s = exec_node_js(
|
||||
code,
|
||||
JsExecOptions {
|
||||
cache: true,
|
||||
module: matches!(module_type, NodeModuleType::Module),
|
||||
},
|
||||
)?;
|
||||
|
||||
if !actual_output.status.success() {
|
||||
bail!(
|
||||
"failed to execute:\n{}\n{}\n{}",
|
||||
code,
|
||||
String::from_utf8_lossy(&actual_output.stdout),
|
||||
String::from_utf8_lossy(&actual_output.stderr)
|
||||
)
|
||||
}
|
||||
|
||||
let s = String::from_utf8_lossy(&actual_output.stdout).to_string();
|
||||
if s.trim().is_empty() {
|
||||
bail!("empty stdout");
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ ansi_term = "0.12.1"
|
||||
anyhow = "1"
|
||||
criterion = "0.3.5"
|
||||
pretty_assertions = "1.1"
|
||||
swc_ecma_testing = { version = "0.1.0", path = "../swc_ecma_testing" }
|
||||
swc_node_base = { version = "0.5.0", path = "../swc_node_base" }
|
||||
testing = { version = "0.20.0", path = "../testing" }
|
||||
walkdir = "2"
|
||||
|
@ -8,12 +8,11 @@ use std::{
|
||||
fs::read_to_string,
|
||||
panic::catch_unwind,
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use ansi_term::Color;
|
||||
use anyhow::{bail, Context, Error};
|
||||
use anyhow::Error;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Deserialize;
|
||||
use swc_common::{
|
||||
@ -36,6 +35,7 @@ use swc_ecma_parser::{
|
||||
lexer::{input::SourceFileInput, Lexer},
|
||||
EsConfig, Parser, Syntax,
|
||||
};
|
||||
use swc_ecma_testing::{exec_node_js, JsExecOptions};
|
||||
use swc_ecma_transforms_base::{fixer::fixer, hygiene::hygiene, resolver};
|
||||
use swc_ecma_utils::drop_span;
|
||||
use swc_ecma_visit::{FoldWith, Visit, VisitMut, VisitMutWith, VisitWith};
|
||||
@ -256,27 +256,19 @@ fn run(
|
||||
}
|
||||
|
||||
fn stdout_of(code: &str) -> Result<String, Error> {
|
||||
let actual_output = Command::new("node")
|
||||
.arg("-e")
|
||||
.arg(&format!(
|
||||
exec_node_js(
|
||||
&format!(
|
||||
"
|
||||
{}
|
||||
{}",
|
||||
{}
|
||||
{}",
|
||||
include_str!("./terser_exec_base.js"),
|
||||
code
|
||||
))
|
||||
.output()
|
||||
.context("failed to execute output of minifier")?;
|
||||
|
||||
if !actual_output.status.success() {
|
||||
bail!(
|
||||
"failed to execute:\n{}\n{}",
|
||||
String::from_utf8_lossy(&actual_output.stdout),
|
||||
String::from_utf8_lossy(&actual_output.stderr)
|
||||
)
|
||||
}
|
||||
|
||||
Ok(String::from_utf8_lossy(&actual_output.stdout).to_string())
|
||||
),
|
||||
JsExecOptions {
|
||||
cache: true,
|
||||
module: false,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn find_config(dir: &Path) -> String {
|
||||
|
@ -2,10 +2,8 @@
|
||||
|
||||
extern crate swc_node_base;
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
use ansi_term::Color;
|
||||
use anyhow::{bail, Context, Error};
|
||||
use anyhow::Error;
|
||||
use serde::Deserialize;
|
||||
use swc_common::{
|
||||
comments::SingleThreadedComments, errors::Handler, sync::Lrc, FileName, Mark, SourceMap,
|
||||
@ -23,6 +21,7 @@ use swc_ecma_minifier::{
|
||||
},
|
||||
};
|
||||
use swc_ecma_parser::{parse_file_as_module, EsConfig, Syntax};
|
||||
use swc_ecma_testing::{exec_node_js, JsExecOptions};
|
||||
use swc_ecma_transforms_base::{fixer::fixer, hygiene::hygiene, resolver};
|
||||
use swc_ecma_visit::{FoldWith, VisitMutWith};
|
||||
use testing::DebugUsingDisplay;
|
||||
@ -46,21 +45,13 @@ fn parse_compressor_config(cm: Lrc<SourceMap>, s: &str) -> (bool, CompressOption
|
||||
}
|
||||
|
||||
fn stdout_of(code: &str) -> Result<String, Error> {
|
||||
let actual_output = Command::new("node")
|
||||
.arg("-e")
|
||||
.arg(&code)
|
||||
.output()
|
||||
.context("failed to execute output of minifier")?;
|
||||
|
||||
if !actual_output.status.success() {
|
||||
bail!(
|
||||
"failed to execute:\n{}\n{}",
|
||||
String::from_utf8_lossy(&actual_output.stdout),
|
||||
String::from_utf8_lossy(&actual_output.stderr)
|
||||
)
|
||||
}
|
||||
|
||||
let stdout = String::from_utf8_lossy(&actual_output.stdout).to_string();
|
||||
let stdout = exec_node_js(
|
||||
code,
|
||||
JsExecOptions {
|
||||
cache: true,
|
||||
module: false,
|
||||
},
|
||||
)?;
|
||||
|
||||
info!("Stdout: {}", stdout);
|
||||
|
||||
|
22
crates/swc_ecma_testing/Cargo.toml
Normal file
22
crates/swc_ecma_testing/Cargo.toml
Normal file
@ -0,0 +1,22 @@
|
||||
[package]
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
description = "Testing utilities for ecmascript"
|
||||
documentation = "https://rustdoc.swc.rs/swc_ecma_testing/"
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
name = "swc_ecma_testing"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.1.0"
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
hex = "0.4"
|
||||
sha-1 = "0.10"
|
||||
swc_atoms = { version = "0.2.11", path = "../swc_atoms" }
|
||||
swc_common = { version = "0.18.7", path = "../swc_common" }
|
||||
swc_ecma_ast = { version = "0.78.1", path = "../swc_ecma_ast" }
|
||||
swc_ecma_codegen = { version = "0.108.5", path = "../swc_ecma_codegen" }
|
||||
testing = { version = "0.20.0", path = "../testing" }
|
98
crates/swc_ecma_testing/src/lib.rs
Normal file
98
crates/swc_ecma_testing/src/lib.rs
Normal file
@ -0,0 +1,98 @@
|
||||
use std::{env, fs, path::PathBuf, process::Command};
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use sha1::{Digest, Sha1};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct JsExecOptions {
|
||||
/// Cache the result of the execution.
|
||||
///
|
||||
/// If `true`, the result of the execution will be cached.
|
||||
/// Cache is not removed and it will be reused if the source code is
|
||||
/// identical.
|
||||
///
|
||||
/// Note that this cache is stored in cargo target directory and will be
|
||||
/// removed by `cargo clean`.
|
||||
///
|
||||
/// You can change the cache directory name by setting the
|
||||
/// `SWC_ECMA_TESTING_CACHE_DIR`
|
||||
pub cache: bool,
|
||||
|
||||
/// If true, `--input-type=module` will be added.
|
||||
pub module: bool,
|
||||
}
|
||||
|
||||
fn cargo_manifest_dir() -> PathBuf {
|
||||
env::var("CARGO_MANIFEST_DIR").unwrap().into()
|
||||
}
|
||||
|
||||
fn cargo_cache_root() -> PathBuf {
|
||||
env::var("SWC_ECMA_TESTING_CACHE_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|_| {
|
||||
env::var("TARGET").map(PathBuf::from).unwrap_or_else(|_| {
|
||||
let mut target_dir = cargo_manifest_dir();
|
||||
target_dir.push("target");
|
||||
target_dir
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Executes `js_code` and capture thw output.
|
||||
pub fn exec_node_js(js_code: &str, opts: JsExecOptions) -> Result<String> {
|
||||
if opts.cache {
|
||||
let hash = calc_hash(js_code);
|
||||
let cache_dir = cargo_cache_root().join(".swc-node-exec-cache");
|
||||
let cache_path = cache_dir.join(format!("{}.stdout", hash));
|
||||
|
||||
if let Ok(s) = fs::read_to_string(&cache_path) {
|
||||
return Ok(s);
|
||||
}
|
||||
|
||||
let output = exec_node_js(
|
||||
js_code,
|
||||
JsExecOptions {
|
||||
cache: false,
|
||||
..opts
|
||||
},
|
||||
)?;
|
||||
|
||||
fs::create_dir_all(&cache_dir).context("failed to create cache directory")?;
|
||||
|
||||
fs::write(&cache_path, output.as_bytes()).context("failed to write cache")?;
|
||||
|
||||
return Ok(output);
|
||||
}
|
||||
|
||||
let mut c = Command::new("node");
|
||||
|
||||
if opts.module {
|
||||
c.arg("--input-type=module");
|
||||
} else {
|
||||
c.arg("--input-type=commonjs");
|
||||
}
|
||||
|
||||
let output = c
|
||||
.arg("-e")
|
||||
.arg(js_code)
|
||||
.output()
|
||||
.context("failed to execute output of minifier")?;
|
||||
|
||||
if !output.status.success() {
|
||||
bail!(
|
||||
"failed to execute:\n{}\n{}",
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
)
|
||||
}
|
||||
|
||||
String::from_utf8(output.stdout).context("output is not utf8")
|
||||
}
|
||||
|
||||
fn calc_hash(s: &str) -> String {
|
||||
let mut hasher = Sha1::default();
|
||||
hasher.update(s.as_bytes());
|
||||
let sum = hasher.finalize();
|
||||
|
||||
hex::encode(sum)
|
||||
}
|
@ -18,12 +18,13 @@ hex = "0.4.3"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
sha-1 = "0.10"
|
||||
swc_common = { version = "0.18.0", path = "../swc_common"}
|
||||
swc_ecma_ast = {version = "0.78.0", path = "../swc_ecma_ast"}
|
||||
swc_ecma_codegen = {version = "0.108.0", path = "../swc_ecma_codegen"}
|
||||
swc_ecma_parser = {version = "0.104.0", path = "../swc_ecma_parser"}
|
||||
swc_ecma_transforms_base = {version = "0.85.0", path = "../swc_ecma_transforms_base"}
|
||||
swc_ecma_utils = {version = "0.85.0", path = "../swc_ecma_utils"}
|
||||
swc_ecma_visit = {version = "0.64.0", path = "../swc_ecma_visit"}
|
||||
swc_common = { version = "0.18.0", path = "../swc_common" }
|
||||
swc_ecma_ast = { version = "0.78.0", path = "../swc_ecma_ast" }
|
||||
swc_ecma_codegen = { version = "0.108.0", path = "../swc_ecma_codegen" }
|
||||
swc_ecma_parser = { version = "0.104.0", path = "../swc_ecma_parser" }
|
||||
swc_ecma_testing = { version = "0.1.0", path = "../swc_ecma_testing" }
|
||||
swc_ecma_transforms_base = { version = "0.85.0", path = "../swc_ecma_transforms_base" }
|
||||
swc_ecma_utils = { version = "0.85.0", path = "../swc_ecma_utils" }
|
||||
swc_ecma_visit = { version = "0.64.0", path = "../swc_ecma_visit" }
|
||||
tempfile = "3.1.0"
|
||||
testing = {version = "0.20.0", path = "../testing"}
|
||||
testing = { version = "0.20.0", path = "../testing" }
|
||||
|
@ -15,7 +15,7 @@ use std::{
|
||||
};
|
||||
|
||||
use ansi_term::Color;
|
||||
use anyhow::{bail, Context, Error};
|
||||
use anyhow::Error;
|
||||
use serde::de::DeserializeOwned;
|
||||
use sha1::{Digest, Sha1};
|
||||
use swc_common::{
|
||||
@ -29,6 +29,7 @@ use swc_common::{
|
||||
use swc_ecma_ast::{Pat, *};
|
||||
use swc_ecma_codegen::Emitter;
|
||||
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax};
|
||||
use swc_ecma_testing::{exec_node_js, JsExecOptions};
|
||||
use swc_ecma_transforms_base::{
|
||||
fixer,
|
||||
helpers::{inject_helpers, HELPERS},
|
||||
@ -539,21 +540,13 @@ fn exec_with_node_test_runner(test_name: &str, src: &str) -> Result<(), ()> {
|
||||
}
|
||||
|
||||
fn stdout_of(code: &str) -> Result<String, Error> {
|
||||
let actual_output = Command::new("node")
|
||||
.arg("-e")
|
||||
.arg(&code)
|
||||
.output()
|
||||
.context("failed to execute output of minifier")?;
|
||||
|
||||
if !actual_output.status.success() {
|
||||
bail!(
|
||||
"failed to execute:\n{}\n{}",
|
||||
String::from_utf8_lossy(&actual_output.stdout),
|
||||
String::from_utf8_lossy(&actual_output.stderr)
|
||||
)
|
||||
}
|
||||
|
||||
Ok(String::from_utf8_lossy(&actual_output.stdout).to_string())
|
||||
exec_node_js(
|
||||
code,
|
||||
JsExecOptions {
|
||||
cache: true,
|
||||
module: false,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Test transformation.
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![deny(warnings)]
|
||||
#![allow(clippy::if_same_then_else)]
|
||||
#![allow(clippy::needless_update)]
|
||||
#![allow(clippy::redundant_clone)]
|
||||
#![allow(clippy::while_let_on_iterator)]
|
||||
|
Loading…
Reference in New Issue
Block a user