uv/scripts/scenarios/generate.py
Zanie Blue c9f43e915c
Add packse scenario tests (#746)
Adds tests using packse test scenarios! Uses `test.pypi.org` as a
backing index.

Tests are generated by a simple Python script. Requires
https://github.com/zanieb/packse/pull/49.

This opens us to a slight attack surface, as we cannot force use of
`test.pypi.org` only and someone could register these package names on
the real `pypi.org` index with malicious content. I could publish these
packages there too.
2024-01-03 15:50:06 -06:00

86 lines
2 KiB
Python

"""
Generates snapshot test cases from packse scenarios.
Usage:
$ python scripts/scenarios/generate.py > crates/puffin-cli/tests/pip_install_scenarios.rs
"""
try:
import packse
except ImportError:
print("packse must be installed")
exit(1)
import sys
import subprocess
import json
TEMPLATE = """
/// {{ name }}
///
/// {{ description }}
#[test]
fn {{ test_name }}() -> Result<()> {
let temp_dir = assert_fs::TempDir::new()?;
let cache_dir = assert_fs::TempDir::new()?;
let venv = create_venv_py312(&temp_dir, &cache_dir);
insta::with_settings!({
filters => INSTA_FILTERS.to_vec()
}, {
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
.arg("pip-install")
.arg("{{ prefix }}")
.arg("--extra-index-url")
.arg("https://test.pypi.org/simple")
.arg("--cache-dir")
.arg(cache_dir.path())
.env("VIRTUAL_ENV", venv.as_os_str())
.current_dir(&temp_dir), @r###"<snapshot>
"###);
});
Ok(())
}
"""
PRELUDE = """
#![cfg(all(feature = "python", feature = "pypi"))]
/// Generated by `{{ generated_by }}`
use std::process::Command;
use anyhow::Result;
use insta_cmd::_macro_support::insta;
use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
use common::{create_venv_py312, BIN_NAME, INSTA_FILTERS};
mod common;
"""
scenarios = json.loads(
subprocess.check_output(
[
"packse",
"inspect",
str(packse.__development_base_path__ / "scenarios"),
],
)
)["scenarios"]
output = PRELUDE.lstrip().replace("{{ generated_by }}", " ".join(sys.argv))
for scenario in scenarios:
# Skip the example scenario file
if scenario["name"] == "example":
continue
output += (
TEMPLATE.replace("{{ name }}", scenario["name"])
.replace("{{ test_name }}", scenario["name"].replace("-", "_"))
.replace("{{ description }}", scenario["description"])
.replace("{{ prefix }}", scenario["prefix"])
)
print(output)