aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock11
-rw-r--r--Cargo.toml1
-rw-r--r--crates/mozart-test-harness/Cargo.toml10
-rw-r--r--crates/mozart-test-harness/src/lib.rs12
-rw-r--r--crates/mozart-test-harness/src/parser.rs322
-rw-r--r--crates/mozart-test-harness/src/runner.rs62
-rw-r--r--crates/mozart/Cargo.toml1
-rw-r--r--crates/mozart/tests/installer.rs791
8 files changed, 1210 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e7778c3..d1ae1cb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1081,6 +1081,7 @@ dependencies = [
"mozart-core",
"mozart-registry",
"mozart-semver",
+ "mozart-test-harness",
"mozart-vcs",
"predicates",
"regex",
@@ -1209,6 +1210,16 @@ dependencies = [
]
[[package]]
+name = "mozart-test-harness"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "regex",
+ "serde_json",
+ "tempfile",
+]
+
+[[package]]
name = "mozart-vcs"
version = "0.1.0"
dependencies = [
diff --git a/Cargo.toml b/Cargo.toml
index ecb0c67..324c0a5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,6 +16,7 @@ mozart-registry = { path = "crates/mozart-registry" }
mozart-sat-resolver = { path = "crates/mozart-sat-resolver" }
mozart-semver = { path = "crates/mozart-semver" }
mozart-spdx-licenses = { path = "crates/mozart-spdx-licenses" }
+mozart-test-harness = { path = "crates/mozart-test-harness" }
mozart-vcs = { path = "crates/mozart-vcs" }
anyhow = "1.0.102"
assert_cmd = "2.1.2"
diff --git a/crates/mozart-test-harness/Cargo.toml b/crates/mozart-test-harness/Cargo.toml
new file mode 100644
index 0000000..61b9109
--- /dev/null
+++ b/crates/mozart-test-harness/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "mozart-test-harness"
+version.workspace = true
+edition.workspace = true
+
+[dependencies]
+anyhow.workspace = true
+regex.workspace = true
+serde_json.workspace = true
+tempfile.workspace = true
diff --git a/crates/mozart-test-harness/src/lib.rs b/crates/mozart-test-harness/src/lib.rs
new file mode 100644
index 0000000..f8fa2b3
--- /dev/null
+++ b/crates/mozart-test-harness/src/lib.rs
@@ -0,0 +1,12 @@
+//! Harness for Composer's `.test` integration fixture format.
+//!
+//! See `composer/tests/Composer/Test/Fixtures/installer/SAMPLE` and
+//! `composer/tests/Composer/Test/InstallerTest.php` for the reference
+//! implementation. This crate provides the parser and a binary-invoking
+//! runner; actual `.test` fixtures and tests live elsewhere.
+
+mod parser;
+mod runner;
+
+pub use parser::{ParsedTest, parse_test_file, parse_test_str};
+pub use runner::{RunResult, run_test};
diff --git a/crates/mozart-test-harness/src/parser.rs b/crates/mozart-test-harness/src/parser.rs
new file mode 100644
index 0000000..dbc71ae
--- /dev/null
+++ b/crates/mozart-test-harness/src/parser.rs
@@ -0,0 +1,322 @@
+use anyhow::{Context, Result, bail};
+use std::collections::HashMap;
+use std::fs;
+use std::path::Path;
+
+const VALID_SECTIONS: &[&str] = &[
+ "TEST",
+ "CONDITION",
+ "COMPOSER",
+ "LOCK",
+ "INSTALLED",
+ "RUN",
+ "EXPECT-LOCK",
+ "EXPECT-INSTALLED",
+ "EXPECT-OUTPUT",
+ "EXPECT-OUTPUT-OPTIMIZED",
+ "EXPECT-EXIT-CODE",
+ "EXPECT-EXCEPTION",
+ "EXPECT",
+];
+
+const REQUIRED_SECTIONS: &[&str] = &["TEST", "COMPOSER", "RUN", "EXPECT"];
+
+#[derive(Debug, Clone)]
+pub struct ParsedTest {
+ pub test: String,
+ pub condition: Option<String>,
+ pub composer: String,
+ pub lock: Option<String>,
+ pub installed: Option<String>,
+ pub run: String,
+ pub expect_lock: Option<String>,
+ pub expect_installed: Option<String>,
+ pub expect_output: Option<String>,
+ pub expect_output_optimized: Option<String>,
+ pub expect_exit_code: Option<i32>,
+ pub expect_exception: Option<String>,
+ pub expect: String,
+}
+
+pub fn parse_test_file(path: &Path) -> Result<ParsedTest> {
+ let content =
+ fs::read_to_string(path).with_context(|| format!("failed to read {}", path.display()))?;
+ parse_test_str(&content).with_context(|| format!("failed to parse {}", path.display()))
+}
+
+pub fn parse_test_str(content: &str) -> Result<ParsedTest> {
+ let mut sections = split_sections(content)?;
+
+ for required in REQUIRED_SECTIONS {
+ if !sections.contains_key(*required) {
+ bail!("missing required section: --{required}--");
+ }
+ }
+
+ let mut take = |key: &str| sections.remove(key);
+
+ let test = take("TEST").unwrap();
+ let composer = take("COMPOSER").unwrap();
+ let run = take("RUN").unwrap();
+ let expect = take("EXPECT").unwrap();
+
+ let expect_exit_code = match take("EXPECT-EXIT-CODE") {
+ Some(s) => Some(
+ s.trim()
+ .parse::<i32>()
+ .with_context(|| format!("invalid EXPECT-EXIT-CODE: {s:?}"))?,
+ ),
+ None => None,
+ };
+
+ Ok(ParsedTest {
+ test,
+ condition: take("CONDITION"),
+ composer,
+ lock: take("LOCK"),
+ installed: take("INSTALLED"),
+ run,
+ expect_lock: take("EXPECT-LOCK"),
+ expect_installed: take("EXPECT-INSTALLED"),
+ expect_output: take("EXPECT-OUTPUT"),
+ expect_output_optimized: take("EXPECT-OUTPUT-OPTIMIZED"),
+ expect_exit_code,
+ expect_exception: take("EXPECT-EXCEPTION"),
+ expect,
+ })
+}
+
+fn split_sections(content: &str) -> Result<HashMap<String, String>> {
+ let header_re = regex::Regex::new(r"^--([A-Z][A-Z-]*)--$").unwrap();
+
+ let mut sections: HashMap<String, String> = HashMap::new();
+ let mut current_section: Option<String> = None;
+ let mut current_body = String::new();
+
+ for line in content.split_inclusive('\n') {
+ let trimmed = line.trim_end_matches('\n').trim_end_matches('\r');
+ if let Some(caps) = header_re.captures(trimmed) {
+ let name = caps[1].to_string();
+ if !VALID_SECTIONS.contains(&name.as_str()) {
+ bail!("unknown section: --{name}--");
+ }
+ if let Some(prev) = current_section.take() {
+ let body = trim_trailing_newlines(&current_body).to_string();
+ if sections.insert(prev.clone(), body).is_some() {
+ bail!("duplicate section: --{prev}--");
+ }
+ current_body.clear();
+ }
+ current_section = Some(name);
+ } else if current_section.is_some() {
+ current_body.push_str(line);
+ }
+ }
+
+ if let Some(name) = current_section.take() {
+ let body = trim_trailing_newlines(&current_body).to_string();
+ if sections.insert(name.clone(), body).is_some() {
+ bail!("duplicate section: --{name}--");
+ }
+ }
+
+ Ok(sections)
+}
+
+fn trim_trailing_newlines(s: &str) -> &str {
+ s.trim_end_matches(['\n', '\r'])
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parses_minimal_required_sections() {
+ let input = "\
+--TEST--
+A simple test
+--COMPOSER--
+{\"require\": {\"a/a\": \"1.0.0\"}}
+--RUN--
+install
+--EXPECT--
+Installing a/a (1.0.0)
+";
+ let t = parse_test_str(input).unwrap();
+ assert_eq!(t.test, "A simple test");
+ assert_eq!(t.composer, "{\"require\": {\"a/a\": \"1.0.0\"}}");
+ assert_eq!(t.run, "install");
+ assert_eq!(t.expect, "Installing a/a (1.0.0)");
+ assert!(t.lock.is_none());
+ assert!(t.installed.is_none());
+ assert!(t.expect_output.is_none());
+ assert!(t.expect_exit_code.is_none());
+ }
+
+ #[test]
+ fn parses_all_sections() {
+ let input = "\
+--TEST--
+desc
+--CONDITION--
+true
+--COMPOSER--
+{}
+--LOCK--
+{\"packages\": []}
+--INSTALLED--
+[]
+--RUN--
+update --with-dependencies a/a
+--EXPECT-LOCK--
+{\"packages\": []}
+--EXPECT-INSTALLED--
+[]
+--EXPECT-OUTPUT--
+some output
+--EXPECT-OUTPUT-OPTIMIZED--
+optimized output
+--EXPECT-EXIT-CODE--
+2
+--EXPECT-EXCEPTION--
+SomeException
+--EXPECT--
+op log
+";
+ let t = parse_test_str(input).unwrap();
+ assert_eq!(t.test, "desc");
+ assert_eq!(t.condition.as_deref(), Some("true"));
+ assert_eq!(t.composer, "{}");
+ assert_eq!(t.lock.as_deref(), Some("{\"packages\": []}"));
+ assert_eq!(t.installed.as_deref(), Some("[]"));
+ assert_eq!(t.run, "update --with-dependencies a/a");
+ assert_eq!(t.expect_lock.as_deref(), Some("{\"packages\": []}"));
+ assert_eq!(t.expect_installed.as_deref(), Some("[]"));
+ assert_eq!(t.expect_output.as_deref(), Some("some output"));
+ assert_eq!(
+ t.expect_output_optimized.as_deref(),
+ Some("optimized output")
+ );
+ assert_eq!(t.expect_exit_code, Some(2));
+ assert_eq!(t.expect_exception.as_deref(), Some("SomeException"));
+ assert_eq!(t.expect, "op log");
+ }
+
+ #[test]
+ fn preserves_internal_newlines_in_body() {
+ let input = "\
+--TEST--
+multi
+--COMPOSER--
+{
+ \"name\": \"a/a\"
+}
+--RUN--
+install
+--EXPECT--
+line1
+line2
+line3
+";
+ let t = parse_test_str(input).unwrap();
+ assert_eq!(t.composer, "{\n \"name\": \"a/a\"\n}");
+ assert_eq!(t.expect, "line1\nline2\nline3");
+ }
+
+ #[test]
+ fn rejects_unknown_section() {
+ let input = "\
+--TEST--
+x
+--MYSTERY--
+y
+--COMPOSER--
+{}
+--RUN--
+install
+--EXPECT--
+z
+";
+ let err = parse_test_str(input).unwrap_err();
+ assert!(err.to_string().contains("unknown section"), "{err}");
+ }
+
+ #[test]
+ fn rejects_missing_required_section() {
+ let input = "\
+--TEST--
+x
+--COMPOSER--
+{}
+--EXPECT--
+z
+";
+ let err = parse_test_str(input).unwrap_err();
+ assert!(err.to_string().contains("RUN"), "{err}");
+ }
+
+ #[test]
+ fn rejects_duplicate_section() {
+ let input = "\
+--TEST--
+first
+--COMPOSER--
+{}
+--RUN--
+install
+--TEST--
+second
+--EXPECT--
+z
+";
+ let err = parse_test_str(input).unwrap_err();
+ assert!(err.to_string().contains("duplicate"), "{err}");
+ }
+
+ #[test]
+ fn rejects_invalid_exit_code() {
+ let input = "\
+--TEST--
+x
+--COMPOSER--
+{}
+--RUN--
+install
+--EXPECT-EXIT-CODE--
+not-a-number
+--EXPECT--
+z
+";
+ let err = parse_test_str(input).unwrap_err();
+ assert!(err.to_string().contains("EXPECT-EXIT-CODE"), "{err}");
+ }
+
+ #[test]
+ fn skips_text_before_first_section() {
+ let input = "\
+this is a header comment
+that should be ignored
+--TEST--
+x
+--COMPOSER--
+{}
+--RUN--
+install
+--EXPECT--
+z
+";
+ let t = parse_test_str(input).unwrap();
+ assert_eq!(t.test, "x");
+ }
+
+ #[test]
+ fn handles_crlf_line_endings() {
+ let input =
+ "--TEST--\r\nx\r\n--COMPOSER--\r\n{}\r\n--RUN--\r\ninstall\r\n--EXPECT--\r\nz\r\n";
+ let t = parse_test_str(input).unwrap();
+ assert_eq!(t.test, "x");
+ assert_eq!(t.composer, "{}");
+ assert_eq!(t.expect, "z");
+ }
+}
diff --git a/crates/mozart-test-harness/src/runner.rs b/crates/mozart-test-harness/src/runner.rs
new file mode 100644
index 0000000..e041cd7
--- /dev/null
+++ b/crates/mozart-test-harness/src/runner.rs
@@ -0,0 +1,62 @@
+use anyhow::{Context, Result};
+use std::path::Path;
+use std::process::Command;
+use tempfile::TempDir;
+
+use crate::parser::ParsedTest;
+
+/// Outcome of running a parsed `.test` against the `mozart` binary.
+///
+/// The temp directory is kept alive in this struct so callers can inspect
+/// files written by the run; it is removed when `RunResult` is dropped.
+pub struct RunResult {
+ pub working_dir: TempDir,
+ pub stdout: String,
+ pub stderr: String,
+ pub exit_code: i32,
+ pub final_lock: Option<String>,
+ pub final_installed: Option<String>,
+}
+
+/// Set up a temp project from the parsed test, invoke `mozart` with the
+/// `--RUN--` command, and capture the result.
+pub fn run_test(test: &ParsedTest, mozart_bin: &Path) -> Result<RunResult> {
+ let working_dir = TempDir::new().context("failed to create tempdir")?;
+ let root = working_dir.path();
+
+ std::fs::write(root.join("composer.json"), &test.composer)
+ .context("failed to write composer.json")?;
+
+ if let Some(lock) = &test.lock {
+ std::fs::write(root.join("composer.lock"), lock)
+ .context("failed to write composer.lock")?;
+ }
+
+ if let Some(installed) = &test.installed {
+ let vendor_composer = root.join("vendor").join("composer");
+ std::fs::create_dir_all(&vendor_composer)
+ .context("failed to create vendor/composer dir")?;
+ std::fs::write(vendor_composer.join("installed.json"), installed)
+ .context("failed to write installed.json")?;
+ }
+
+ let args: Vec<&str> = test.run.split_whitespace().collect();
+ let output = Command::new(mozart_bin)
+ .args(&args)
+ .current_dir(root)
+ .output()
+ .with_context(|| format!("failed to invoke {}", mozart_bin.display()))?;
+
+ let final_lock = std::fs::read_to_string(root.join("composer.lock")).ok();
+ let final_installed =
+ std::fs::read_to_string(root.join("vendor").join("composer").join("installed.json")).ok();
+
+ Ok(RunResult {
+ working_dir,
+ stdout: String::from_utf8_lossy(&output.stdout).into_owned(),
+ stderr: String::from_utf8_lossy(&output.stderr).into_owned(),
+ exit_code: output.status.code().unwrap_or(-1),
+ final_lock,
+ final_installed,
+ })
+}
diff --git a/crates/mozart/Cargo.toml b/crates/mozart/Cargo.toml
index 3f1cd33..fb47195 100644
--- a/crates/mozart/Cargo.toml
+++ b/crates/mozart/Cargo.toml
@@ -28,5 +28,6 @@ tracing-subscriber.workspace = true
tracing.workspace = true
[dev-dependencies]
+mozart-test-harness.workspace = true
assert_cmd.workspace = true
predicates.workspace = true
diff --git a/crates/mozart/tests/installer.rs b/crates/mozart/tests/installer.rs
new file mode 100644
index 0000000..5503476
--- /dev/null
+++ b/crates/mozart/tests/installer.rs
@@ -0,0 +1,791 @@
+use mozart_test_harness::{parse_test_file, run_test};
+use std::path::{Path, PathBuf};
+
+fn fixtures_dir() -> PathBuf {
+ Path::new(env!("CARGO_MANIFEST_DIR"))
+ .join("../../composer/tests/Composer/Test/Fixtures/installer")
+}
+
+fn run_installer_fixture(ident: &str) {
+ let filename = format!("{}.test", ident.replace('_', "-"));
+ let path = fixtures_dir().join(&filename);
+ let parsed = parse_test_file(&path)
+ .unwrap_or_else(|e| panic!("failed to parse {}: {:#}", path.display(), e));
+ let mozart_bin: &Path = assert_cmd::cargo::cargo_bin!("mozart");
+ let result = run_test(&parsed, mozart_bin)
+ .unwrap_or_else(|e| panic!("failed to run {}: {:#}", path.display(), e));
+ let expected = parsed.expect_exit_code.unwrap_or(0);
+ assert_eq!(
+ result.exit_code,
+ expected,
+ "exit code mismatch for {}\n--- stdout ---\n{}\n--- stderr ---\n{}",
+ path.display(),
+ result.stdout,
+ result.stderr,
+ );
+}
+
+macro_rules! installer_fixture {
+ ($name:ident) => {
+ #[test]
+ fn $name() {
+ run_installer_fixture(stringify!($name));
+ }
+ };
+ ($name:ident, ignore = $reason:literal) => {
+ #[test]
+ #[ignore = $reason]
+ fn $name() {
+ run_installer_fixture(stringify!($name));
+ }
+ };
+}
+
+installer_fixture!(
+ abandoned_listed,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ alias_in_complex_constraints,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ alias_in_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ alias_in_lock2,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ alias_on_unloadable_package,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ alias_solver_problems,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ alias_solver_problems2,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ alias_with_reference,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ aliased_priority,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ aliased_priority_conflicting,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ aliases_with_require_dev,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ broken_deps_do_not_replace,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ circular_dependency,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ circular_dependency2,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ circular_dependency_errors,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_against_provided_by_dep_package_works,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_against_provided_package_works,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_against_replaced_by_dep_package_problem,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_against_replaced_package_problem,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_between_dependents,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_between_root_and_dependent,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_downgrade,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_downgrade_nested,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_on_root_with_alias_prevents_update_if_not_required,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_with_alias_in_lock_does_prevents_install,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_with_alias_prevents_update,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_with_alias_prevents_update_if_not_required,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ conflict_with_all_dependencies_option_dont_recommend_to_use_it,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ deduplicate_solver_problems,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ disjunctive_multi_constraints,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ full_update_minimal_changes,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ github_issues_4319,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ github_issues_4795,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ github_issues_4795_2,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ github_issues_7051,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ github_issues_8902,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ github_issues_8903,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ github_issues_9012,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ github_issues_9290,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ hint_main_rename,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_aliased_alias,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_branch_alias_composer_repo,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_dev,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_dev_using_dist,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_forces_reinstall_if_abandon_changes,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_from_incomplete_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_from_incomplete_lock_with_ignore,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_from_lock_removes_package,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_funding_notice,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_funding_notice_env,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_funding_notice_not_displayed_env,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_ignore_platform_package_requirement_list,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_ignore_platform_package_requirement_wildcard,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_ignore_platform_package_requirements,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_missing_alias_from_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_overridden_platform_packages,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_package_and_its_provider_skips_original,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_prefers_repos_over_package_versions,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_reference,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_security_advisory_matching_dependency,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_self_from_root,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_simple,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ install_without_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ load_replaced_package_if_replacer_dropped,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ outdated_lock_file_fails_install,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ outdated_lock_file_with_new_platform_reqs_fails,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_always_updates_symlinked_path_repos,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_downgrades_non_allow_listed_unstable,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_forces_dev_reference_from_lock_for_non_updated_packages,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_from_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_from_lock_with_root_alias,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_installs_from_lock_even_missing,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_keeps_older_dep_if_still_required,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_keeps_older_dep_if_still_required_with_provide,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_loads_root_aliases_for_path_repos,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_security_advisory_matching_locked_dep,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_security_advisory_matching_locked_dep_with_dependencies,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_with_dependencies_provide,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_with_dependencies_replace,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_with_deps_warns_root,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_with_symlinked_path_repos,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ partial_update_without_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ platform_ext_solver_problems,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ plugins_are_installed_first,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ prefer_lowest_branches,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ problems_reduce_versions,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_can_coexist_with_other_version_of_provided,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_conflicts,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_conflicts2,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_conflicts3,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_dev_require_can_satisfy_require,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_gets_picked_together_with_other_version_of_provided,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_gets_picked_together_with_other_version_of_provided_conflict,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_gets_picked_together_with_other_version_of_provided_indirect,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_packages_can_be_installed_if_selected,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_packages_can_be_installed_together_with_provided_if_both_installable,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_packages_can_not_be_installed_unless_selected,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ provider_satisfies_its_own_requirement,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ remove_deletes_unused_deps,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ remove_does_nothing_if_removal_requires_update_of_dep,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ replace_alias,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ replace_priorities,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ replace_range_require_single_version,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ replace_root_require,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ replaced_packages_should_not_be_installed,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ replaced_packages_should_not_be_installed_when_installing_from_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ replacer_satisfies_its_own_requirement,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ repositories_priorities,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ repositories_priorities2,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ repositories_priorities3,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ repositories_priorities4,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ repositories_priorities5,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ root_alias_change_with_circular_dep,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ root_alias_gets_loaded_for_locked_pkgs,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ root_requirements_do_not_affect_locked_versions,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ solver_problem_with_hash_in_branch,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ solver_problems,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ solver_problems_with_disabled_platform,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ suggest_installed,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ suggest_prod,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ suggest_prod_nolock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ suggest_replaced,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ suggest_uninstalled,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ unbounded_conflict_does_not_match_default_branch_with_branch_alias,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ unbounded_conflict_does_not_match_default_branch_with_numeric_branch,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ unbounded_conflict_matches_default_branch,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_abandoned_package_required_but_blocked_via_audit_config,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_alias,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_alias_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_alias_lock2,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_all,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_all_dry_run,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_locked_require,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_minimal_changes,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_patterns,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_patterns_with_all_dependencies,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_patterns_with_dependencies,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_patterns_with_root_dependencies,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_patterns_without_dependencies,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_reads_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_removes_unused,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_require_new_replace,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_warns_non_existing_patterns,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_with_dependencies,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_with_dependencies_alias,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_with_dependencies_new_requirement,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_with_dependencies_require_new,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_with_dependencies_require_new_replace,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_with_dependencies_require_new_replace_mutual,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_allow_list_with_dependency_conflict,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_changes_url,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_dev_ignores_providers,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_dev_packages_updates_repo_url,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_dev_to_new_ref_picks_up_changes,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_downgrades_unstable_packages,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_ignore_platform_package_requirement_list,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_ignore_platform_package_requirement_list_upper_bounds,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_ignore_platform_package_requirement_wildcard,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_ignore_platform_package_requirements,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_installed_alias,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_installed_alias_dry_run,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_installed_reference,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_installed_reference_dry_run,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_mirrors_changes_url,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_mirrors_fails_with_new_req,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_no_dev_still_resolves_dev,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_no_install,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_package_present_in_lock_but_not_at_all_in_remote,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_package_present_in_lock_but_not_in_remote,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_package_present_in_lock_but_not_in_remote_due_to_min_stability,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_package_present_in_lower_repo_prio_but_not_main_due_to_min_stability,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_picks_up_change_of_vcs_type,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_prefer_lowest_stable,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_reference,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_reference_picks_latest,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_removes_unused_locked_dep,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_requiring_decision_reverts_and_learning_positive_literals,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_security_advisory_matching_direct_dependency,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_security_advisory_matching_indirect_dependency,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_syncs_outdated,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_to_empty_from_blank,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_to_empty_from_locked,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_with_all_dependencies,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ update_without_lock,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ updating_dev_from_lock_removes_old_deps,
+ ignore = "mozart binary cannot yet run this fixture"
+);
+installer_fixture!(
+ updating_dev_updates_url_and_reference,
+ ignore = "mozart binary cannot yet run this fixture"
+);