-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information
1 parent
bac1334
commit 8034368
Showing
4 changed files
with
298 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 `--no-modules`; use `--nodejs`, `--browser`, or no flag 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(); | ||
} |