use std::fs; use anyhow::Result; use assert_cmd::prelude::*; use predicates::{prelude::*, str::contains}; use crate::support::*; mod support; #[test] fn help() { for arg in ["help add", "add -h", "add --help"] { wit(arg.split_whitespace()) .assert() .stdout(contains( "Adds a reference to a WIT package from a registry", )) .success(); } } #[test] fn it_fails_with_missing_toml_file() -> Result<()> { wit(["add", "foo:bar"]) .assert() .stderr(contains( "error: failed to find configuration file `wit.toml`", )) .failure(); Ok(()) } #[test] fn requires_package() { wit(["add"]) .assert() .stderr(contains("wit add ")) .failure(); } #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn validate_the_package_exists() -> Result<()> { let (server, _, _) = spawn_server(["foo"]).await?; let project = server.project("foo", Vec::::new())?; project .wit(["add", "foo:bar"]) .assert() .stderr(contains("package `foo:bar` was not found")) .failure(); Ok(()) } #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn validate_the_version_exists() -> Result<()> { let (server, _, _) = spawn_server(Vec::::new()).await?; let project = server.project("foo", Vec::::new())?; project.file("foo.wit", "package test:bar;\n")?; project .wit(["publish"]) .env("WIT_PUBLISH_KEY", test_signing_key()) .assert() .stderr(contains("Published package `test:bar` v0.1.0")) .success(); let project = server.project("bar", Vec::::new())?; project .wit(["add", "test:bar"]) .assert() .stderr(contains("Added dependency `test:bar` with version `0.1.0`")) .success(); let manifest = fs::read_to_string(project.root().join("wit.toml"))?; assert!(contains(r#""test:bar" = "0.1.0""#).eval(&manifest)); project .wit(["add", "--name", "test:bar2", "test:bar@2.0.0"]) .assert() .stderr(contains( "component registry package `test:bar` has no release matching version requirement `^2.0.0`", )) .failure(); Ok(()) } #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn checks_for_duplicate_dependencies() -> Result<()> { let (server, _, _) = spawn_server(Vec::::new()).await?; let project = server.project("foo", Vec::::new())?; project.file("foo.wit", "package test:bar;\n")?; project .wit(["publish"]) .env("WIT_PUBLISH_KEY", test_signing_key()) .assert() .stderr(contains("Published package `test:bar` v0.1.0")) .success(); let project = server.project("bar", Vec::::new())?; project .wit(["add", "test:bar"]) .assert() .stderr(contains("Added dependency `test:bar` with version `0.1.0`")) .success(); let manifest = fs::read_to_string(project.root().join("wit.toml"))?; assert!(contains(r#""test:bar" = "0.1.0""#).eval(&manifest)); project .wit(["add", "test:bar"]) .assert() .stderr(contains( "cannot add dependency `test:bar` as it conflicts with an existing dependency", )) .failure(); Ok(()) } #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn does_not_modify_manifest_for_dry_run() -> Result<()> { let (server, _, _) = spawn_server(Vec::::new()).await?; let project = server.project("foo", Vec::::new())?; project.file("foo.wit", "package test:bar;\n")?; project .wit(["publish"]) .env("WIT_PUBLISH_KEY", test_signing_key()) .assert() .stderr(contains("Published package `test:bar` v0.1.0")) .success(); let project = server.project("bar", Vec::::new())?; project .wit(["add", "test:bar", "--dry-run"]) .assert() .stderr(contains( "Would add dependency `test:bar` with version `0.1.0` (dry run)", )) .success(); let manifest = fs::read_to_string(project.root().join("wit.toml"))?; assert!(!contains("test:bar").eval(&manifest)); Ok(()) } #[test] fn validate_add_from_path() -> Result<()> { let project = Project::new("foo")?; project .wit(["add", "--path", "foo/baz", "foo:baz"]) .assert() .stderr(contains("Added dependency `foo:baz` from path `foo/baz`")); let manifest = fs::read_to_string(project.root().join("wit.toml"))?; assert!(contains(r#""foo:baz" = { path = "foo/baz" }"#).eval(&manifest)); Ok(()) }