mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-13 13:01:22 +00:00
Start implementing a test suite for the CLI
We have very few tests today so this starts to add the basics of a test suite which compiles Cargo projects on-the-fly which will hopefully help us bolster the amount of assertions we can make about the output.
This commit is contained in:
@ -62,12 +62,17 @@ jobs:
|
||||
- template: ci/azure-install-sccache.yml
|
||||
- script: cargo test --target wasm32-unknown-unknown --features nightly --test wasm
|
||||
|
||||
- job: test_cli_support
|
||||
displayName: "Run wasm-bindgen-cli-support crate tests"
|
||||
- job: test_cli
|
||||
displayName: "Run wasm-bindgen-cli crate tests"
|
||||
steps:
|
||||
- template: ci/azure-install-rust.yml
|
||||
- template: ci/azure-install-sccache.yml
|
||||
- script: rustup target add wasm32-unknown-unknown
|
||||
displayName: "install wasm target"
|
||||
- script: cargo test -p wasm-bindgen-cli-support
|
||||
displayName: "wasm-bindgen-cli-support tests"
|
||||
- script: cargo test -p wasm-bindgen-cli
|
||||
displayName: "wasm-bindgen-cli tests"
|
||||
|
||||
- job: test_web_sys
|
||||
displayName: "Run web-sys crate tests"
|
||||
@ -139,16 +144,22 @@ jobs:
|
||||
steps:
|
||||
- template: ci/azure-install-rust.yml
|
||||
- template: ci/azure-install-sccache.yml
|
||||
- script: npm install
|
||||
- script: mv _package.json package.json && npm install && rm package.json
|
||||
displayName: "run npm install"
|
||||
- script: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
|
||||
- script: cargo build -p wasm-bindgen-cli
|
||||
- script: ln -snf `pwd`/target/debug/wasm-bindgen $HOME/.cargo/bin/wasm-bindgen
|
||||
displayName: "install wasm-pack"
|
||||
- script: |
|
||||
set -ex
|
||||
cargo build -p wasm-bindgen-cli
|
||||
ln -snf `pwd`/target/debug/wasm-bindgen $HOME/.cargo/bin/wasm-bindgen
|
||||
displayName: "install wasm-bindgen for `wasm-pack` to use"
|
||||
- script: |
|
||||
for dir in `ls examples | grep -v README | grep -v asm.js | grep -v raytrace | grep -v without-a-bundler`; do
|
||||
(cd examples/$dir &&
|
||||
ln -fs ../../node_modules . &&
|
||||
npm run build -- --output-path $BUILD_ARTIFACTSTAGINGDIRECTORY/exbuild/$dir) || exit 1;
|
||||
done
|
||||
displayName: "build examples"
|
||||
- task: PublishPipelineArtifact@0
|
||||
inputs:
|
||||
artifactName: examples1
|
||||
|
@ -67,6 +67,9 @@ pub struct Context<'a> {
|
||||
|
||||
/// All package.json dependencies we've learned about so far
|
||||
pub package_json_read: HashSet<&'a str>,
|
||||
|
||||
/// A map of the name of npm dependencies we've loaded so far to the path
|
||||
/// they're defined in as well as their version specification.
|
||||
pub npm_dependencies: HashMap<String, (&'a str, String)>,
|
||||
|
||||
pub anyref: wasm_bindgen_anyref_xform::Context,
|
||||
@ -2967,8 +2970,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
}
|
||||
if !self.cx.config.mode.nodejs() && !self.cx.config.mode.bundler() {
|
||||
bail!("NPM dependencies have been specified in `{}` but \
|
||||
this is only compatible with the default output of \
|
||||
`wasm-bindgen` or the `--nodejs` flag");
|
||||
this is only compatible with the `bundler` and `nodejs` targets");
|
||||
}
|
||||
let contents = fs::read_to_string(path).context(format!("failed to read `{}`", path))?;
|
||||
let json: serde_json::Value = serde_json::from_str(&contents)?;
|
||||
|
@ -716,7 +716,7 @@ impl OutputMode {
|
||||
|
||||
fn bundler(&self) -> bool {
|
||||
match self {
|
||||
OutputMode::Bundler => true,
|
||||
OutputMode::Bundler { .. } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -28,5 +28,9 @@ walrus = "0.5"
|
||||
wasm-bindgen-cli-support = { path = "../cli-support", version = "=0.2.40" }
|
||||
wasm-bindgen-shared = { path = "../shared", version = "=0.2.40" }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd = "0.11"
|
||||
predicates = "1.0.0"
|
||||
|
||||
[features]
|
||||
vendored-openssl = ['openssl/vendored']
|
||||
|
@ -79,7 +79,7 @@ fn main() {
|
||||
};
|
||||
eprintln!("error: {}", err);
|
||||
for cause in err.iter_causes() {
|
||||
eprintln!("\tcaused by: {}", cause);
|
||||
eprintln!(" caused by: {}", cause);
|
||||
}
|
||||
process::exit(1);
|
||||
}
|
||||
|
138
crates/cli/tests/wasm-bindgen/main.rs
Normal file
138
crates/cli/tests/wasm-bindgen/main.rs
Normal file
@ -0,0 +1,138 @@
|
||||
//! A small test suite for the `wasm-bindgen` CLI command itself
|
||||
//!
|
||||
//! This test suite is intended to exercise functionality of the CLI in terms of
|
||||
//! errors and such. It is not intended for comprehensive behavior testing, as
|
||||
//! that should all be placed in the top-level `tests` directory for the
|
||||
//! `wasm-bindgen` crate itself.
|
||||
//!
|
||||
//! Assertions about errors in `wasm-bindgen` or assertions about the output of
|
||||
//! `wasm-bindgen` should all be placed in this test suite, however. Currently
|
||||
//! it is largely based off actually running `cargo build` at test time which is
|
||||
//! quite expensive, so it's recommended that this test suite doesn't become too
|
||||
//! large!
|
||||
|
||||
use assert_cmd::prelude::*;
|
||||
use predicates::str;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
fn target_dir() -> PathBuf {
|
||||
let mut dir = PathBuf::from(env::current_exe().unwrap());
|
||||
dir.pop(); // current exe
|
||||
if dir.ends_with("deps") {
|
||||
dir.pop();
|
||||
}
|
||||
dir.pop(); // debug and/or release
|
||||
return dir;
|
||||
}
|
||||
|
||||
fn repo_root() -> PathBuf {
|
||||
let mut repo_root = env::current_dir().unwrap();
|
||||
repo_root.pop(); // remove 'cli'
|
||||
repo_root.pop(); // remove 'crates'
|
||||
repo_root
|
||||
}
|
||||
|
||||
struct Project {
|
||||
root: PathBuf,
|
||||
name: &'static str,
|
||||
}
|
||||
|
||||
impl Project {
|
||||
fn new(name: &'static str) -> Project {
|
||||
let root = target_dir().join("cli-tests").join(name);
|
||||
drop(fs::remove_dir_all(&root));
|
||||
fs::create_dir_all(&root).unwrap();
|
||||
Project { root, name }
|
||||
}
|
||||
|
||||
fn file(&mut self, name: &str, contents: &str) -> &mut Project {
|
||||
let dst = self.root.join(name);
|
||||
fs::create_dir_all(dst.parent().unwrap()).unwrap();
|
||||
fs::write(&dst, contents).unwrap();
|
||||
self
|
||||
}
|
||||
|
||||
fn wasm_bindgen(&mut self, args: &str) -> (Command, PathBuf) {
|
||||
let wasm = self.build();
|
||||
let output = self.root.join("pkg");
|
||||
fs::create_dir_all(&output).unwrap();
|
||||
let mut cmd = Command::cargo_bin("wasm-bindgen").unwrap();
|
||||
cmd.arg("--out-dir").arg(&output);
|
||||
cmd.arg(&wasm);
|
||||
for arg in args.split_whitespace() {
|
||||
cmd.arg(arg);
|
||||
}
|
||||
(cmd, output)
|
||||
}
|
||||
|
||||
fn build(&mut self) -> PathBuf {
|
||||
if !self.root.join("Cargo.toml").is_file() {
|
||||
self.file(
|
||||
"Cargo.toml",
|
||||
&format!(
|
||||
"
|
||||
[package]
|
||||
name = \"{}\"
|
||||
authors = []
|
||||
version = \"1.0.0\"
|
||||
edition = '2018'
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = {{ path = '{}' }}
|
||||
|
||||
[lib]
|
||||
crate-type = ['cdylib']
|
||||
|
||||
[workspace]
|
||||
",
|
||||
self.name,
|
||||
repo_root().display(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
let target_dir = target_dir();
|
||||
Command::new("cargo")
|
||||
.current_dir(&self.root)
|
||||
.arg("build")
|
||||
.arg("--target")
|
||||
.arg("wasm32-unknown-unknown")
|
||||
.env("CARGO_TARGET_DIR", &target_dir)
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
target_dir
|
||||
.join("wasm32-unknown-unknown")
|
||||
.join("debug")
|
||||
.join(self.name)
|
||||
.with_extension("wasm")
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_useful() {
|
||||
Command::cargo_bin("wasm-bindgen")
|
||||
.unwrap()
|
||||
.arg("-V")
|
||||
.assert()
|
||||
.stdout(str::ends_with("\n"))
|
||||
.stdout(str::starts_with("wasm-bindgen "))
|
||||
.success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_empty_project() {
|
||||
let (mut cmd, _out_dir) = Project::new("works_on_empty_project")
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
"#,
|
||||
)
|
||||
.wasm_bindgen("");
|
||||
cmd.assert().success();
|
||||
}
|
||||
|
||||
mod npm;
|
155
crates/cli/tests/wasm-bindgen/npm.rs
Normal file
155
crates/cli/tests/wasm-bindgen/npm.rs
Normal file
@ -0,0 +1,155 @@
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
fn no_modules_rejects_npm() {
|
||||
let (mut cmd, _out_dir) = Project::new("no_modules_rejects_npm")
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "foo")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn main() {
|
||||
foo();
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file("package.json", "")
|
||||
.wasm_bindgen("--no-modules");
|
||||
cmd.assert()
|
||||
.stderr("\
|
||||
error: failed to generate bindings for JS import `foo`
|
||||
caused by: import from `foo` module not allowed with `--target no-modules`; use `nodejs`, `web`, or `bundler` target instead
|
||||
")
|
||||
.failure();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn more_package_json_fields_rejected() {
|
||||
let (mut cmd, _out_dir) = Project::new("more_package_json_fields_rejected")
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "foo")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn main() {
|
||||
foo();
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"package.json",
|
||||
r#"
|
||||
{
|
||||
"name": "foo",
|
||||
"dependencies": {}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.wasm_bindgen("");
|
||||
cmd.assert()
|
||||
.stderr(str::is_match("\
|
||||
error: NPM manifest found at `.*` can currently only have one key, .*
|
||||
").unwrap())
|
||||
.failure();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn npm_conflict_rejected() {
|
||||
let (mut cmd, _out_dir) = Project::new("npm_conflict_rejected")
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
&format!(r#"
|
||||
[package]
|
||||
name = "npm_conflict_rejected"
|
||||
authors = []
|
||||
version = "1.0.0"
|
||||
edition = '2018'
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = {{ path = '{}' }}
|
||||
bar = {{ path = 'bar' }}
|
||||
|
||||
[lib]
|
||||
crate-type = ['cdylib']
|
||||
|
||||
[workspace]
|
||||
"#,
|
||||
repo_root().display()
|
||||
)
|
||||
)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "bar")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn main() {
|
||||
foo();
|
||||
bar::foo();
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"package.json",
|
||||
r#"
|
||||
{
|
||||
"dependencies": {"bar": "0.0.0"}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"bar/Cargo.toml",
|
||||
&format!(r#"
|
||||
[package]
|
||||
name = "bar"
|
||||
authors = []
|
||||
version = "1.0.0"
|
||||
edition = '2018'
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = {{ path = '{}' }}
|
||||
"#,
|
||||
repo_root().display()
|
||||
)
|
||||
)
|
||||
.file(
|
||||
"bar/src/lib.rs",
|
||||
r#"
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "bar")]
|
||||
extern {
|
||||
pub fn foo();
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"bar/package.json",
|
||||
r#"
|
||||
{
|
||||
"dependencies": {"bar": "1.0.0"}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.wasm_bindgen("");
|
||||
cmd.assert()
|
||||
.stderr(str::is_match("dependency on NPM package `bar` specified in two").unwrap())
|
||||
.failure();
|
||||
}
|
Reference in New Issue
Block a user