Fix wasm-bindgen if lib is renamed via `lib.name`

This commit fixes an issue where if a library is renamed via the `name`
key in the `[lib]` section of the manifest then `wasm-pack` would try to
generate bindings for an noexistent wasm-file, generating an error.

The fix was to internally use `cargo_metadata` more aggressively and
move around where this data is generated. This ended up refactoring a
few locations, but this should also bring improved error messages for
`cargo metadata` as well as caching the resulting data more aggressively
to avoid recalculating it too much.

Closes #339
master
Alex Crichton 7 years ago
parent e8b3075dae
commit 35fe250d09
  1. 21
      src/bindgen.rs
  2. 21
      src/command/build.rs
  3. 6
      src/command/test.rs
  4. 40
      src/lockfile.rs
  5. 406
      src/manifest/mod.rs
  6. 41
      tests/all/build.rs
  7. 13
      tests/all/lockfile.rs
  8. 65
      tests/all/manifest.rs
  9. 44
      tests/all/test.rs
  10. 2
      tests/all/utils/fixture.rs

@ -1,10 +1,10 @@
//! Functionality related to installing and running `wasm-bindgen`.
use binaries::{Cache, Download};
use cargo_metadata;
use child;
use emoji;
use failure::{self, ResultExt};
use manifest::CrateData;
use progressbar::Step;
use slog::Logger;
use std::fs;
@ -140,10 +140,9 @@ pub fn cargo_install_wasm_bindgen(
/// Run the `wasm-bindgen` CLI to generate bindings for the current crate's
/// `.wasm`.
pub fn wasm_bindgen_build(
path: &Path,
data: &CrateData,
bindgen: &Download,
out_dir: &Path,
name: &str,
disable_dts: bool,
target: &str,
debug: bool,
@ -153,21 +152,16 @@ pub fn wasm_bindgen_build(
let msg = format!("{}Running WASM-bindgen...", emoji::RUNNER);
PBAR.step(step, &msg);
let binary_name = name.replace("-", "_");
let release_or_debug = if debug { "debug" } else { "release" };
let out_dir = out_dir.to_str().unwrap();
let manifest = path.join("Cargo.toml");
let target_path = cargo_metadata::metadata(Some(&manifest))
.unwrap()
.target_directory;
let mut wasm_path = PathBuf::from(&target_path)
let wasm_path = data
.target_directory()
.join("wasm32-unknown-unknown")
.join(release_or_debug)
.join(binary_name);
wasm_path.set_extension("wasm");
let wasm_path = wasm_path.display().to_string();
.join(data.crate_name())
.with_extension("wasm");
let dts_arg = if disable_dts {
"--no-typescript"
@ -181,8 +175,7 @@ pub fn wasm_bindgen_build(
};
let bindgen_path = bindgen.binary("wasm-bindgen");
let mut cmd = Command::new(bindgen_path);
cmd.current_dir(path)
.arg(&wasm_path)
cmd.arg(&wasm_path)
.arg("--out-dir")
.arg(out_dir)
.arg(dts_arg)

@ -21,14 +21,13 @@ use PBAR;
#[allow(missing_docs)]
pub struct Build {
pub crate_path: PathBuf,
pub crate_data: manifest::CargoManifest,
pub crate_data: manifest::CrateData,
pub scope: Option<String>,
pub disable_dts: bool,
pub target: String,
pub debug: bool,
pub mode: BuildMode,
// build_config: Option<BuildConfig>,
pub crate_name: String,
pub out_dir: PathBuf,
pub bindgen: Option<Download>,
pub cache: Cache,
@ -105,8 +104,7 @@ impl Build {
/// Construct a build command from the given options.
pub fn try_from_opts(build_opts: BuildOptions) -> Result<Self, failure::Error> {
let crate_path = set_crate_path(build_opts.path)?;
let crate_data = manifest::CargoManifest::read(&crate_path)?;
let crate_name = crate_data.get_crate_name().to_string();
let crate_data = manifest::CrateData::new(&crate_path)?;
let out_dir = crate_path.join(PathBuf::from(build_opts.out_dir));
// let build_config = manifest::xxx(&crate_path).xxx();
Ok(Build {
@ -118,7 +116,6 @@ impl Build {
debug: build_opts.debug,
mode: build_opts.mode,
// build_config,
crate_name,
out_dir,
bindgen: None,
cache: Cache::new()?,
@ -281,7 +278,7 @@ impl Build {
log: &Logger,
) -> Result<(), failure::Error> {
info!(&log, "Identifying wasm-bindgen dependency...");
let lockfile = Lockfile::new(&self.crate_path)?;
let lockfile = Lockfile::new(&self.crate_data)?;
let bindgen_version = lockfile.require_wasm_bindgen()?;
info!(&log, "Installing wasm-bindgen-cli...");
let install_permitted = match self.mode {
@ -298,25 +295,15 @@ impl Build {
)?;
self.bindgen = Some(bindgen);
info!(&log, "Installing wasm-bindgen-cli was successful.");
info!(&log, "Getting the crate name from the manifest...");
self.crate_name = self.crate_data.get_crate_name().to_string();
info!(
&log,
"Got crate name {:#?} from the manifest at {:#?}.",
&self.crate_name,
&self.crate_path.join("Cargo.toml")
);
Ok(())
}
fn step_run_wasm_bindgen(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> {
info!(&log, "Building the wasm bindings...");
bindgen::wasm_bindgen_build(
&self.crate_path,
&self.crate_data,
self.bindgen.as_ref().unwrap(),
&self.out_dir,
&self.crate_name,
self.disable_dts,
&self.target,
self.debug,

@ -82,7 +82,7 @@ pub struct TestOptions {
/// A configured `wasm-pack test` command.
pub struct Test {
crate_path: PathBuf,
crate_data: manifest::CargoManifest,
crate_data: manifest::CrateData,
cache: Cache,
node: bool,
mode: BuildMode,
@ -117,7 +117,7 @@ impl Test {
} = test_opts;
let crate_path = set_crate_path(path)?;
let crate_data = manifest::CargoManifest::read(&crate_path)?;
let crate_data = manifest::CrateData::new(&crate_path)?;
let any_browser = chrome || firefox || safari;
if !node && !any_browser {
@ -274,7 +274,7 @@ impl Test {
log: &Logger,
) -> Result<(), failure::Error> {
info!(&log, "Identifying wasm-bindgen dependency...");
let lockfile = Lockfile::new(&self.crate_path)?;
let lockfile = Lockfile::new(&self.crate_data)?;
let bindgen_version = lockfile.require_wasm_bindgen()?;
// Unlike `wasm-bindgen` and `wasm-bindgen-cli`, `wasm-bindgen-test`

@ -1,11 +1,11 @@
//! Reading Cargo.lock lock file.
use std::fs;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use cargo_metadata;
use console::style;
use error::Error;
use failure::{Error, ResultExt};
use manifest::CrateData;
use toml;
/// This struct represents the contents of `Cargo.lock`.
@ -23,10 +23,13 @@ struct Package {
impl Lockfile {
/// Read the `Cargo.lock` file for the crate at the given path.
pub fn new(crate_path: &Path) -> Result<Lockfile, failure::Error> {
let lock_path = get_lockfile_path(crate_path)?;
let lockfile = fs::read_to_string(lock_path)?;
toml::from_str(&lockfile).map_err(|err| Error::from(err).into())
pub fn new(crate_data: &CrateData) -> Result<Lockfile, Error> {
let lock_path = get_lockfile_path(crate_data)?;
let lockfile = fs::read_to_string(&lock_path)
.with_context(|_| format!("failed to read: {}", lock_path.display()))?;
let lockfile = toml::from_str(&lockfile)
.with_context(|_| format!("failed to parse: {}", lock_path.display()))?;
Ok(lockfile)
}
/// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.
@ -36,15 +39,14 @@ impl Lockfile {
/// Like `wasm_bindgen_version`, except it returns an error instead of
/// `None`.
pub fn require_wasm_bindgen(&self) -> Result<&str, failure::Error> {
pub fn require_wasm_bindgen(&self) -> Result<&str, Error> {
self.wasm_bindgen_version().ok_or_else(|| {
let message = format!(
format_err!(
"Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
[dependencies]\n\
wasm-bindgen = \"0.2\"",
style("wasm-bindgen").bold().dim(),
);
Error::CrateConfig { message }.into()
)
})
}
@ -63,22 +65,12 @@ impl Lockfile {
/// Given the path to the crate that we are buliding, return a `PathBuf`
/// containing the location of the lock file, by finding the workspace root.
fn get_lockfile_path(crate_path: &Path) -> Result<PathBuf, failure::Error> {
// Identify the crate's root directory, or return an error.
let manifest = crate_path.join("Cargo.toml");
let crate_root = cargo_metadata::metadata(Some(&manifest))
.map_err(|_| Error::CrateConfig {
message: String::from("Error while processing crate metadata"),
})?
.workspace_root;
fn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf, Error> {
// Check that a lock file can be found in the directory. Return an error
// if it cannot, otherwise return the path buffer.
let lockfile_path = Path::new(&crate_root).join("Cargo.lock");
let lockfile_path = crate_data.workspace_root().join("Cargo.lock");
if !lockfile_path.is_file() {
Err(Error::CrateConfig {
message: format!("Could not find lockfile at {:?}", lockfile_path),
}
.into())
bail!("Could not find lockfile at {:?}", lockfile_path)
} else {
Ok(lockfile_path)
}

@ -2,99 +2,140 @@
mod npm;
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::fs;
use std::path::Path;
use self::npm::{
repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage,
};
use cargo_metadata::Metadata;
use emoji;
use error::Error;
use failure;
use failure::{Error, ResultExt};
use progressbar::Step;
use serde_json;
use toml;
use PBAR;
/// A parsed `Cargo.toml` manifest.
#[derive(Clone, Debug, Deserialize)]
pub struct CargoManifest {
/// Store for metadata learned about a crate
pub struct CrateData {
data: Metadata,
current_idx: usize,
manifest: CargoManifest,
}
#[derive(Deserialize)]
struct CargoManifest {
package: CargoPackage,
dependencies: Option<HashMap<String, CargoDependency>>,
#[serde(rename = "dev-dependencies")]
dev_dependencies: Option<HashMap<String, CargoDependency>>,
lib: Option<CargoLib>,
}
#[derive(Clone, Debug, Deserialize)]
#[derive(Deserialize)]
struct CargoPackage {
name: String,
authors: Vec<String>,
description: Option<String>,
version: String,
license: Option<String>,
repository: Option<String>,
}
impl CargoPackage {
fn check_optional_fields(&self) {
let mut messages = vec![];
if self.description.is_none() {
messages.push("description");
}
if self.repository.is_none() {
messages.push("repository");
struct NpmData {
name: String,
files: Vec<String>,
dts_file: Option<String>,
main: String,
}
impl CrateData {
/// Reads all metadata for the crate whose manifest is inside the directory
/// specified by `path`.
pub fn new(crate_path: &Path) -> Result<CrateData, Error> {
let manifest_path = crate_path.join("Cargo.toml");
if !manifest_path.is_file() {
bail!(
"crate directory is missing a `Cargo.toml` file; is `{}` the \
wrong directory?",
crate_path.display()
)
}
if self.license.is_none() {
messages.push("license");
let manifest = fs::read_to_string(&manifest_path)
.with_context(|_| format!("failed to read: {}", manifest_path.display()))?;
let manifest: CargoManifest = toml::from_str(&manifest)
.with_context(|_| format!("failed to parse manifest: {}", manifest_path.display()))?;
let data =
cargo_metadata::metadata(Some(&manifest_path)).map_err(error_chain_to_failure)?;
let current_idx = data
.packages
.iter()
.position(|pkg| pkg.name == manifest.package.name)
.ok_or_else(|| format_err!("failed to find package in metadata"))?;
return Ok(CrateData {
data,
manifest,
current_idx,
});
fn error_chain_to_failure(err: cargo_metadata::Error) -> Error {
let errors = err.iter().collect::<Vec<_>>();
let mut err: Error = match errors.last() {
Some(e) => format_err!("{}", e),
None => return format_err!("{}", err),
};
for e in errors[..errors.len() - 1].iter().rev() {
err = err.context(e.to_string()).into();
}
return err;
}
match messages.len() {
1 => PBAR.info(&format!("Optional field missing from Cargo.toml: '{}'. This is not necessary, but recommended", messages[0])),
2 => PBAR.info(&format!("Optional fields missing from Cargo.toml: '{}', '{}'. These are not necessary, but recommended", messages[0], messages[1])),
3 => PBAR.info(&format!("Optional fields missing from Cargo.toml: '{}', '{}', and '{}'. These are not necessary, but recommended", messages[0], messages[1], messages[2])),
_ => ()
};
}
}
#[derive(Clone, Debug, Deserialize)]
#[serde(untagged)]
enum CargoDependency {
Simple(String),
Detailed(DetailedCargoDependency),
}
#[derive(Clone, Debug, Deserialize)]
struct DetailedCargoDependency {
version: Option<String>,
}
/// Check that the crate the given path is properly configured.
pub fn check_crate_config(&self, step: &Step) -> Result<(), Error> {
let msg = format!("{}Checking crate configuration...", emoji::WRENCH);
PBAR.step(&step, &msg);
self.check_crate_type()?;
Ok(())
}
#[derive(Clone, Debug, Deserialize)]
struct CargoLib {
#[serde(rename = "crate-type")]
crate_type: Option<Vec<String>>,
}
fn check_crate_type(&self) -> Result<(), Error> {
let pkg = &self.data.packages[self.current_idx];
let any_cdylib = pkg
.targets
.iter()
.filter(|target| target.kind.iter().any(|k| k == "cdylib"))
.any(|target| target.crate_types.iter().any(|s| s == "cdylib"));
if any_cdylib {
return Ok(());
}
bail!(
"crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your \
Cargo.toml file:\n\n\
[lib]\n\
crate-type = [\"cdylib\", \"rlib\"]"
)
}
impl CargoManifest {
/// Read the `Cargo.toml` inside the crate at the given `crate_path`.
pub fn read(crate_path: &Path) -> Result<CargoManifest, failure::Error> {
let manifest_path = crate_path.join("Cargo.toml");
if !manifest_path.is_file() {
return Err(Error::crate_config(&format!(
"Crate directory is missing a `Cargo.toml` file; is `{}` the wrong directory?",
crate_path.display()
))
.into());
/// Get the crate name for the crate at the given path.
pub fn crate_name(&self) -> String {
let pkg = &self.data.packages[self.current_idx];
match pkg
.targets
.iter()
.find(|t| t.kind.iter().any(|k| k == "cdylib"))
{
Some(lib) => lib.name.replace("-", "_"),
None => pkg.name.replace("-", "_"),
}
let mut cargo_file = File::open(manifest_path)?;
let mut cargo_contents = String::new();
cargo_file.read_to_string(&mut cargo_contents)?;
}
let manifest: CargoManifest = toml::from_str(&cargo_contents)?;
Ok(manifest)
/// Returns the path to this project's target directory where artifacts are
/// located after a cargo build.
pub fn target_directory(&self) -> &Path {
Path::new(&self.data.target_directory)
}
/// Returns the path to this project's root cargo workspace directory
pub fn workspace_root(&self) -> &Path {
Path::new(&self.data.workspace_root)
}
/// Generate a package.json file inside in `./pkg`.
@ -105,163 +146,162 @@ impl CargoManifest {
disable_dts: bool,
target: &str,
step: &Step,
) -> Result<(), failure::Error> {
) -> Result<(), Error> {
let msg = format!("{}Writing a package.json...", emoji::MEMO);
PBAR.step(step, &msg);
let pkg_file_path = out_dir.join("package.json");
let mut pkg_file = File::create(pkg_file_path)?;
let npm_data = if target == "nodejs" {
self.clone().into_commonjs(scope, disable_dts)
self.to_commonjs(scope, disable_dts)
} else if target == "no-modules" {
self.clone().into_nomodules(scope, disable_dts)
self.to_nomodules(scope, disable_dts)
} else {
self.clone().into_esmodules(scope, disable_dts)
self.to_esmodules(scope, disable_dts)
};
let npm_json = serde_json::to_string_pretty(&npm_data)?;
pkg_file.write_all(npm_json.as_bytes())?;
Ok(())
}
/// Get the crate name for the crate at the given path.
pub fn get_crate_name(&self) -> &str {
&self.package.name
}
/// Check that the crate the given path is properly configured.
pub fn check_crate_config(&self, step: &Step) -> Result<(), failure::Error> {
let msg = format!("{}Checking crate configuration...", emoji::WRENCH);
PBAR.step(&step, &msg);
self.check_crate_type()?;
fs::write(&pkg_file_path, npm_json)
.with_context(|_| format!("failed to write: {}", pkg_file_path.display()))?;
Ok(())
}
fn check_crate_type(&self) -> Result<(), failure::Error> {
if self.lib.as_ref().map_or(false, |lib| {
lib.crate_type
.as_ref()
.map_or(false, |types| types.iter().any(|s| s == "cdylib"))
}) {
return Ok(());
}
Err(Error::crate_config(
"crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your \
Cargo.toml file:\n\n\
[lib]\n\
crate-type = [\"cdylib\", \"rlib\"]"
).into())
}
fn into_commonjs(mut self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let filename = self.package.name.replace("-", "_");
let wasm_file = format!("{}_bg.wasm", filename);
let js_file = format!("{}.js", filename);
fn npm_data(
&self,
scope: &Option<String>,
include_commonjs_shim: bool,
disable_dts: bool,
) -> NpmData {
let crate_name = self.crate_name();
let wasm_file = format!("{}_bg.wasm", crate_name);
let js_file = format!("{}.js", crate_name);
let mut files = vec![wasm_file];
let js_bg_file = format!("{}_bg.js", filename);
files.push(js_bg_file.to_string());
if let Some(s) = scope {
self.package.name = format!("@{}/{}", s, self.package.name);
files.push(js_file.clone());
if include_commonjs_shim {
let js_bg_file = format!("{}_bg.js", crate_name);
files.push(js_bg_file.to_string());
}
let dts_file = if disable_dts == false {
let file = format!("{}.d.ts", filename);
let pkg = &self.data.packages[self.current_idx];
let npm_name = match scope {
Some(s) => format!("@{}/{}", s, pkg.name),
None => pkg.name.clone(),
};
let dts_file = if !disable_dts {
let file = format!("{}.d.ts", crate_name);
files.push(file.to_string());
Some(file)
} else {
None
};
NpmData {
name: npm_name,
dts_file,
files,
main: js_file,
}
}
fn to_commonjs(&self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let data = self.npm_data(scope, true, disable_dts);
let pkg = &self.data.packages[self.current_idx];
&self.package.check_optional_fields();
self.check_optional_fields();
NpmPackage::CommonJSPackage(CommonJSPackage {
name: self.package.name,
collaborators: self.package.authors,
description: self.package.description,
version: self.package.version,
license: self.package.license,
repository: self.package.repository.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: files,
main: js_file,
types: dts_file,
name: data.name,
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
version: pkg.version.clone(),
license: self.manifest.package.license.clone(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: data.files,
main: data.main,
types: data.dts_file,
})
}
fn into_esmodules(mut self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let filename = self.package.name.replace("-", "_");
let wasm_file = format!("{}_bg.wasm", filename);
let js_file = format!("{}.js", filename);
let mut files = vec![wasm_file, js_file.clone()];
let dts_file = if disable_dts == false {
let file = format!("{}.d.ts", filename);
files.push(file.to_string());
Some(file)
} else {
None
};
if let Some(s) = scope {
self.package.name = format!("@{}/{}", s, self.package.name);
}
fn to_esmodules(&self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let data = self.npm_data(scope, false, disable_dts);
let pkg = &self.data.packages[self.current_idx];
&self.package.check_optional_fields();
self.check_optional_fields();
NpmPackage::ESModulesPackage(ESModulesPackage {
name: self.package.name,
collaborators: self.package.authors,
description: self.package.description,
version: self.package.version,
license: self.package.license,
repository: self.package.repository.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: files,
module: js_file,
types: dts_file,
name: data.name,
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
version: pkg.version.clone(),
license: self.manifest.package.license.clone(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: data.files,
module: data.main,
types: data.dts_file,
side_effects: "false".to_string(),
})
}
fn into_nomodules(mut self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let filename = self.package.name.replace("-", "_");
let wasm_file = format!("{}_bg.wasm", filename);
let js_file = format!("{}.js", filename);
let mut files = vec![wasm_file, js_file.clone()];
let dts_file = if disable_dts == false {
let file = format!("{}.d.ts", filename);
files.push(file.to_string());
Some(file)
} else {
None
};
if let Some(s) = scope {
self.package.name = format!("@{}/{}", s, self.package.name);
}
fn to_nomodules(&self, scope: &Option<String>, disable_dts: bool) -> NpmPackage {
let data = self.npm_data(scope, false, disable_dts);
let pkg = &self.data.packages[self.current_idx];
&self.package.check_optional_fields();
self.check_optional_fields();
NpmPackage::NoModulesPackage(NoModulesPackage {
name: self.package.name,
collaborators: self.package.authors,
description: self.package.description,
version: self.package.version,
license: self.package.license,
repository: self.package.repository.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: files,
browser: js_file,
types: dts_file,
name: data.name,
collaborators: pkg.authors.clone(),
description: self.manifest.package.description.clone(),
version: pkg.version.clone(),
license: self.manifest.package.license.clone(),
repository: self
.manifest
.package
.repository
.clone()
.map(|repo_url| Repository {
ty: "git".to_string(),
url: repo_url,
}),
files: data.files,
browser: data.main,
types: data.dts_file,
})
}
fn check_optional_fields(&self) {
let mut messages = vec![];
if self.manifest.package.description.is_none() {
messages.push("description");
}
if self.manifest.package.repository.is_none() {
messages.push("repository");
}
if self.manifest.package.license.is_none() {
messages.push("license");
}
match messages.len() {
1 => PBAR.info(&format!("Optional field missing from Cargo.toml: '{}'. This is not necessary, but recommended", messages[0])),
2 => PBAR.info(&format!("Optional fields missing from Cargo.toml: '{}', '{}'. These are not necessary, but recommended", messages[0], messages[1])),
3 => PBAR.info(&format!("Optional fields missing from Cargo.toml: '{}', '{}', and '{}'. These are not necessary, but recommended", messages[0], messages[1], messages[2])),
_ => ()
};
}
}

@ -84,3 +84,44 @@ fn it_should_build_crates_in_a_workspace() {
.unwrap();
fixture.run(cli.cmd).unwrap();
}
#[test]
fn renamed_crate_name_works() {
let fixture = utils::fixture::Fixture::new();
fixture
.readme()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
authors = []
[lib]
crate-type = ["cdylib"]
name = 'bar'
[dependencies]
wasm-bindgen = "=0.2.21"
"#,
)
.file(
"src/lib.rs",
r#"
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn one() -> u32 { 1 }
"#,
);
fixture.install_local_wasm_bindgen();
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
&fixture.path.display().to_string(),
])
.unwrap();
fixture.run(cli.cmd).unwrap();
}

@ -1,11 +1,13 @@
use utils::fixture;
use wasm_pack::lockfile::Lockfile;
use wasm_pack::manifest::CrateData;
#[test]
fn it_gets_wasm_bindgen_version() {
let fixture = fixture::js_hello_world();
fixture.cargo_check();
let lock = Lockfile::new(&fixture.path).unwrap();
let data = CrateData::new(&fixture.path).unwrap();
let lock = Lockfile::new(&data).unwrap();
assert_eq!(lock.wasm_bindgen_version(), Some("0.2.21"),);
}
@ -13,7 +15,8 @@ fn it_gets_wasm_bindgen_version() {
fn it_gets_wasm_bindgen_test_version() {
let fixture = fixture::wbg_test_node();
fixture.cargo_check();
let lock = Lockfile::new(&fixture.path).unwrap();
let data = CrateData::new(&fixture.path).unwrap();
let lock = Lockfile::new(&data).unwrap();
assert_eq!(lock.wasm_bindgen_test_version(), Some("0.2.21"),);
}
@ -57,7 +60,8 @@ fn it_gets_wasm_bindgen_version_in_crate_inside_workspace() {
"#,
);
fixture.cargo_check();
let lock = Lockfile::new(&fixture.path.join("blah")).unwrap();
let data = CrateData::new(&fixture.path.join("blah")).unwrap();
let lock = Lockfile::new(&data).unwrap();
assert_eq!(lock.wasm_bindgen_version(), Some("0.2.21"),);
}
@ -124,6 +128,7 @@ fn it_gets_wasm_bindgen_version_from_dependencies() {
"#,
);
fixture.cargo_check();
let lock = Lockfile::new(&fixture.path.join("parent")).unwrap();
let data = CrateData::new(&fixture.path.join("parent")).unwrap();
let lock = Lockfile::new(&data).unwrap();
assert_eq!(lock.wasm_bindgen_version(), Some("0.2.21"),);
}

@ -8,16 +8,16 @@ use wasm_pack::{self, manifest};
#[test]
fn it_gets_the_crate_name_default_path() {
let path = &PathBuf::from(".");
let crate_data = manifest::CargoManifest::read(&path).unwrap();
let name = crate_data.get_crate_name();
assert_eq!(name, "wasm-pack");
let crate_data = manifest::CrateData::new(&path).unwrap();
let name = crate_data.crate_name();
assert_eq!(name, "wasm_pack");
}
#[test]
fn it_gets_the_crate_name_provided_path() {
let fixture = fixture::js_hello_world();
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
assert_eq!(crate_data.get_crate_name(), "js-hello-world");
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
assert_eq!(crate_data.crate_name(), "js_hello_world");
}
#[test]
@ -25,7 +25,7 @@ fn it_checks_has_cdylib_default_path() {
let fixture = fixture::no_cdylib();
// Ensure that there is a `Cargo.lock`.
fixture.cargo_check();
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(crate_data.check_crate_config(&step).is_err());
}
@ -35,15 +35,15 @@ fn it_checks_has_cdylib_provided_path() {
let fixture = fixture::js_hello_world();
// Ensure that there is a `Cargo.lock`.
fixture.cargo_check();
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(crate_data.check_crate_config(&step).is_ok());
crate_data.check_crate_config(&step).unwrap();
}
#[test]
fn it_checks_has_cdylib_wrong_crate_type() {
let fixture = fixture::bad_cargo_toml();
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(crate_data.check_crate_config(&step).is_err());
}
@ -53,24 +53,24 @@ fn it_recognizes_a_map_during_depcheck() {
let fixture = fixture::serde_feature();
// Ensure that there is a `Cargo.lock`.
fixture.cargo_check();
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(crate_data.check_crate_config(&step).is_ok());
crate_data.check_crate_config(&step).unwrap();
}
#[test]
fn it_creates_a_package_json_default_path() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(crate_data
.write_package_json(&out_dir, &None, false, "", &step)
.is_ok());
let package_json_path = &fixture.path.join("pkg").join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
assert_eq!(pkg.repository.ty, "git");
@ -98,14 +98,14 @@ fn it_creates_a_package_json_default_path() {
fn it_creates_a_package_json_provided_path() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(crate_data
.write_package_json(&out_dir, &None, false, "", &step)
.is_ok());
let package_json_path = &fixture.path.join("pkg").join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
@ -127,15 +127,15 @@ fn it_creates_a_package_json_provided_path() {
fn it_creates_a_package_json_provided_path_with_scope() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(crate_data
.write_package_json(&out_dir, &Some("test".to_string()), false, "", &step)
.is_ok());
let package_json_path = &fixture.path.join("pkg").join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "@test/js-hello-world");
assert_eq!(pkg.module, "js_hello_world.js");
@ -156,14 +156,14 @@ fn it_creates_a_package_json_provided_path_with_scope() {
fn it_creates_a_pkg_json_with_correct_files_on_node() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(crate_data
.write_package_json(&out_dir, &None, false, "nodejs", &step)
.is_ok());
let package_json_path = &out_dir.join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
@ -180,6 +180,7 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() {
"js_hello_world_bg.wasm",
"js_hello_world_bg.js",
"js_hello_world.d.ts",
"js_hello_world.js",
]
.iter()
.map(|&s| String::from(s))
@ -191,14 +192,14 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() {
fn it_creates_a_pkg_json_with_correct_files_on_nomodules() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(crate_data
.write_package_json(&out_dir, &None, false, "no-modules", &step)
.is_ok());
let package_json_path = &out_dir.join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
@ -226,7 +227,7 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() {
fn it_creates_a_pkg_json_in_out_dir() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("./custom/out");
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(crate_data
@ -234,23 +235,23 @@ fn it_creates_a_pkg_json_in_out_dir() {
.is_ok());
let package_json_path = &fixture.path.join(&out_dir).join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
}
#[test]
fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() {
let fixture = fixture::js_hello_world();
let out_dir = fixture.path.join("pkg");
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap();
assert!(crate_data
.write_package_json(&out_dir, &None, true, "", &step)
.is_ok());
let package_json_path = &out_dir.join("package.json");
assert!(fs::metadata(package_json_path).is_ok());
assert!(utils::manifest::read_package_json(&fixture.path, &out_dir).is_ok());
fs::metadata(package_json_path).unwrap();
utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();
assert_eq!(pkg.name, "js-hello-world");
assert_eq!(pkg.repository.ty, "git");
@ -271,7 +272,7 @@ fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() {
#[test]
fn it_errors_when_wasm_bindgen_is_not_declared() {
let fixture = fixture::bad_cargo_toml();
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(crate_data.check_crate_config(&step).is_err());
}
@ -281,7 +282,7 @@ fn it_does_not_error_when_wasm_bindgen_is_declared() {
let fixture = fixture::js_hello_world();
// Ensure that there is a `Cargo.lock`.
fixture.cargo_check();
let crate_data = manifest::CargoManifest::read(&fixture.path).unwrap();
let crate_data = manifest::CrateData::new(&fixture.path).unwrap();
let step = wasm_pack::progressbar::Step::new(1);
assert!(crate_data.check_crate_config(&step).is_ok());
crate_data.check_crate_config(&step).unwrap();
}

@ -242,3 +242,47 @@ fn complains_about_missing_wasm_bindgen_test_dependency() {
assert!(second.is_some());
assert_ne!(first, second, "should have found two occurrences");
}
#[test]
fn renamed_crate_name_works() {
let fixture = fixture::Fixture::new();
fixture
.readme()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
authors = []
[lib]
crate-type = ["cdylib"]
name = 'bar'
[dependencies]
wasm-bindgen = "=0.2.21"
[dev-dependencies]
wasm-bindgen-test = "=0.2.21"
"#,
)
.file(
"src/lib.rs",
r#"
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn one() -> u32 { 1 }
"#,
);
fixture.install_local_wasm_bindgen();
let cmd = Command::Test(test::TestOptions {
path: Some(fixture.path.clone()),
node: true,
mode: build::BuildMode::Noinstall,
..Default::default()
});
fixture.run(cmd).unwrap();
}

@ -277,7 +277,7 @@ pub fn no_cdylib() -> Fixture {
authors = ["The wasm-pack developers"]
description = "so awesome rust+wasm package"
license = "WTFPL"
name = "{}"
name = "foo"
repository = "https://github.com/rustwasm/wasm-pack.git"
version = "0.1.0"

Loading…
Cancel
Save