This commit is contained in:
Micha Reiser 2025-12-12 17:35:58 +00:00 committed by GitHub
commit cac6a2de8b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 42 additions and 104 deletions

23
Cargo.lock generated
View File

@ -1004,27 +1004,6 @@ dependencies = [
"crypto-common", "crypto-common",
] ]
[[package]]
name = "dir-test"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62c013fe825864f3e4593f36426c1fa7a74f5603f13ca8d1af7a990c1cd94a79"
dependencies = [
"dir-test-macros",
]
[[package]]
name = "dir-test-macros"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d42f54d7b4a6bc2400fe5b338e35d1a335787585375322f49c5d5fe7b243da7e"
dependencies = [
"glob",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "dirs" name = "dirs"
version = "6.0.0" version = "6.0.0"
@ -4512,7 +4491,7 @@ dependencies = [
"camino", "camino",
"colored 3.0.0", "colored 3.0.0",
"compact_str", "compact_str",
"dir-test", "datatest-stable",
"drop_bomb", "drop_bomb",
"get-size2", "get-size2",
"glob", "glob",

View File

@ -82,7 +82,6 @@ criterion = { version = "0.7.0", default-features = false }
crossbeam = { version = "0.8.4" } crossbeam = { version = "0.8.4" }
dashmap = { version = "6.0.1" } dashmap = { version = "6.0.1" }
datatest-stable = { version = "0.3.3" } datatest-stable = { version = "0.3.3" }
dir-test = { version = "0.4.0" }
dunce = { version = "1.0.5" } dunce = { version = "1.0.5" }
drop_bomb = { version = "0.1.5" } drop_bomb = { version = "0.1.5" }
etcetera = { version = "0.11.0" } etcetera = { version = "0.11.0" }

View File

@ -33,7 +33,7 @@ camino = { workspace = true }
colored = { workspace = true } colored = { workspace = true }
compact_str = { workspace = true } compact_str = { workspace = true }
drop_bomb = { workspace = true } drop_bomb = { workspace = true }
get-size2 = { workspace = true, features = ["indexmap", "ordermap"]} get-size2 = { workspace = true, features = ["indexmap", "ordermap"] }
indexmap = { workspace = true } indexmap = { workspace = true }
itertools = { workspace = true } itertools = { workspace = true }
ordermap = { workspace = true } ordermap = { workspace = true }
@ -62,7 +62,7 @@ ty_test = { workspace = true }
ty_vendored = { workspace = true } ty_vendored = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
dir-test = { workspace = true } datatest-stable = { workspace = true }
glob = { workspace = true } glob = { workspace = true }
indoc = { workspace = true } indoc = { workspace = true }
insta = { workspace = true } insta = { workspace = true }
@ -76,5 +76,9 @@ schemars = ["dep:schemars", "dep:serde_json"]
serde = ["ruff_db/serde", "dep:serde", "ruff_python_ast/serde"] serde = ["ruff_db/serde", "dep:serde", "ruff_python_ast/serde"]
testing = [] testing = []
[[test]]
name = "mdtest"
harness = false
[lints] [lints]
workspace = true workspace = true

View File

@ -1,4 +0,0 @@
/// Rebuild the crate if a test file is added or removed from
pub fn main() {
println!("cargo::rerun-if-changed=resources/mdtest");
}

View File

@ -129,17 +129,8 @@ class MDTestRunner:
check=False, check=False,
) )
def _mangle_path(self, markdown_file: Path) -> str:
return (
markdown_file.as_posix()
.replace("/", "_")
.replace("-", "_")
.removesuffix(".md")
)
def _run_mdtests_for_file(self, markdown_file: Path) -> None: def _run_mdtests_for_file(self, markdown_file: Path) -> None:
path_mangled = self._mangle_path(markdown_file) test_name = f"mdtest::{markdown_file}"
test_name = f"mdtest__{path_mangled}"
output = self._run_mdtest(["--exact", test_name], capture_output=True) output = self._run_mdtest(["--exact", test_name], capture_output=True)
@ -245,16 +236,10 @@ class MDTestRunner:
if rust_code_has_changed: if rust_code_has_changed:
if self._recompile_tests("Rust code has changed, recompiling tests..."): if self._recompile_tests("Rust code has changed, recompiling tests..."):
self._run_mdtest(self.filters) self._run_mdtest(self.filters)
elif vendored_typeshed_has_changed: elif vendored_typeshed_has_changed and self._recompile_tests(
if self._recompile_tests( "Vendored typeshed has changed, recompiling tests..."
"Vendored typeshed has changed, recompiling tests..." ):
): self._run_mdtest(self.filters)
self._run_mdtest(self.filters)
elif new_md_files:
files = " ".join(file.as_posix() for file in new_md_files)
self._recompile_tests(
f"New Markdown test [yellow]{files}[/yellow] detected, recompiling tests..."
)
for path in new_md_files | changed_md_files: for path in new_md_files | changed_md_files:
self._run_mdtests_for_file(path) self._run_mdtests_for_file(path)

View File

@ -1,24 +1,25 @@
use anyhow::anyhow;
use camino::Utf8Path; use camino::Utf8Path;
use dir_test::{Fixture, dir_test};
use ty_static::EnvVars; use ty_static::EnvVars;
use ty_test::OutputFormat; use ty_test::OutputFormat;
/// See `crates/ty_test/README.md` for documentation on these tests. /// See `crates/ty_test/README.md` for documentation on these tests.
#[dir_test(
dir: "$CARGO_MANIFEST_DIR/resources/mdtest",
glob: "**/*.md"
)]
#[expect(clippy::needless_pass_by_value)] #[expect(clippy::needless_pass_by_value)]
fn mdtest(fixture: Fixture<&str>) { fn mdtest(fixture_path: &Utf8Path, content: String) -> datatest_stable::Result<()> {
let absolute_fixture_path = Utf8Path::new(fixture.path()); let short_title = fixture_path
.file_name()
.ok_or_else(|| anyhow!("Expected fixture path to have a file name"))?;
let crate_dir = Utf8Path::new(env!("CARGO_MANIFEST_DIR")); let crate_dir = Utf8Path::new(env!("CARGO_MANIFEST_DIR"));
let snapshot_path = crate_dir.join("resources").join("mdtest").join("snapshots"); let snapshot_path = crate_dir.join("resources").join("mdtest").join("snapshots");
let workspace_root = crate_dir.ancestors().nth(2).unwrap(); let absolute_fixture_path = crate_dir.join(fixture_path);
let workspace_relative_fixture_path = Utf8Path::new("crates/ty_python_semantic")
.join(fixture_path.strip_prefix(".").unwrap_or(fixture_path));
let relative_fixture_path = absolute_fixture_path.strip_prefix(workspace_root).unwrap(); let test_name = fixture_path
let short_title = absolute_fixture_path.file_name().unwrap(); .strip_prefix("./resources/mdtest")
.unwrap_or(fixture_path)
let test_name = test_name("mdtest", absolute_fixture_path); .as_str();
let output_format = if std::env::var(EnvVars::MDTEST_GITHUB_ANNOTATIONS_FORMAT).is_ok() { let output_format = if std::env::var(EnvVars::MDTEST_GITHUB_ANNOTATIONS_FORMAT).is_ok() {
OutputFormat::GitHub OutputFormat::GitHub
@ -27,43 +28,18 @@ fn mdtest(fixture: Fixture<&str>) {
}; };
ty_test::run( ty_test::run(
absolute_fixture_path, &absolute_fixture_path,
relative_fixture_path, &workspace_relative_fixture_path,
&content,
&snapshot_path, &snapshot_path,
short_title, short_title,
&test_name, test_name,
output_format, output_format,
); )?;
Ok(())
} }
/// Constructs the test name used for individual markdown files datatest_stable::harness! {
/// { test = mdtest, root = "./resources/mdtest", pattern = r"\.md$" },
/// This code is copied from <https://github.com/fe-lang/dir-test/blob/1c0f41c480a3490bc2653a043ff6e3f8085a1f47/macros/src/lib.rs#L104-L138>
/// and should be updated if they diverge
fn test_name(test_func_name: &str, fixture_path: &Utf8Path) -> String {
assert!(fixture_path.is_file());
let dir_path = format!("{}/resources/mdtest", std::env!("CARGO_MANIFEST_DIR"));
let rel_path = fixture_path.strip_prefix(dir_path).unwrap();
assert!(rel_path.is_relative());
let mut test_name = test_func_name.to_owned();
test_name.push_str("__");
for component in rel_path.parent().unwrap().components() {
let component = component
.as_str()
.replace(|c: char| c.is_ascii_punctuation(), "_");
test_name.push_str(&component);
test_name.push('_');
}
test_name.push_str(
&rel_path
.file_stem()
.unwrap()
.replace(|c: char| c.is_ascii_punctuation(), "_"),
);
test_name
} }

View File

@ -1,6 +1,7 @@
use crate::config::Log; use crate::config::Log;
use crate::db::Db; use crate::db::Db;
use crate::parser::{BacktickOffsets, EmbeddedFileSourceMap}; use crate::parser::{BacktickOffsets, EmbeddedFileSourceMap};
use anyhow::anyhow;
use camino::Utf8Path; use camino::Utf8Path;
use colored::Colorize; use colored::Colorize;
use config::SystemKind; use config::SystemKind;
@ -41,18 +42,14 @@ use ty_static::EnvVars;
pub fn run( pub fn run(
absolute_fixture_path: &Utf8Path, absolute_fixture_path: &Utf8Path,
relative_fixture_path: &Utf8Path, relative_fixture_path: &Utf8Path,
source: &str,
snapshot_path: &Utf8Path, snapshot_path: &Utf8Path,
short_title: &str, short_title: &str,
test_name: &str, test_name: &str,
output_format: OutputFormat, output_format: OutputFormat,
) { ) -> anyhow::Result<()> {
let source = std::fs::read_to_string(absolute_fixture_path).unwrap(); let suite = test_parser::parse(short_title, source)
let suite = match test_parser::parse(short_title, &source) { .map_err(|err| anyhow!("Failed to parse fixture: {err}"))?;
Ok(suite) => suite,
Err(err) => {
panic!("Error parsing `{absolute_fixture_path}`: {err:?}")
}
};
let mut db = db::Db::setup(); let mut db = db::Db::setup();
@ -86,7 +83,7 @@ pub fn run(
} }
if let Err(failures) = result { if let Err(failures) = result {
let md_index = LineIndex::from_source_text(&source); let md_index = LineIndex::from_source_text(source);
for test_failures in failures { for test_failures in failures {
let source_map = let source_map =
@ -156,6 +153,8 @@ pub fn run(
println!("\n{}\n", "-".repeat(50)); println!("\n{}\n", "-".repeat(50));
assert!(!any_failures, "Some tests failed."); assert!(!any_failures, "Some tests failed.");
Ok(())
} }
/// Defines the format in which mdtest should print an error to the terminal /// Defines the format in which mdtest should print an error to the terminal