From a6402fb51e7df7f2df6e34438c04f797462e004c Mon Sep 17 00:00:00 2001 From: Connor Skees <39542938+connorskees@users.noreply.github.com> Date: Fri, 29 Nov 2024 06:59:07 -0500 Subject: [PATCH] mdtest: allow specifying a specific test inside a file (#14670) --- crates/red_knot_test/README.md | 7 +++++-- crates/red_knot_test/src/lib.rs | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/crates/red_knot_test/README.md b/crates/red_knot_test/README.md index e53b9ca4ac..e5df6eb6ff 100644 --- a/crates/red_knot_test/README.md +++ b/crates/red_knot_test/README.md @@ -184,8 +184,11 @@ The tests are run independently, in independent in-memory file systems and with [Salsa](https://github.com/salsa-rs/salsa) databases. This means that each is a from-scratch run of the type checker, with no data persisting from any previous test. -Due to `cargo test` limitations, an entire test suite (Markdown file) is run as a single Rust test, -so it's not possible to select individual tests within it to run. +It is possible to filter to individual tests within a single markdown file using the +`MDTEST_TEST_FILTER` environment variable. This variable will match any tests which contain the +value as a case-sensitive substring in its name. An example test name is +`unpacking.md - Unpacking - Tuple - Multiple assignment`, which contains the name of the markdown +file and its parent headers joined together with hyphens. ## Structured test suites diff --git a/crates/red_knot_test/src/lib.rs b/crates/red_knot_test/src/lib.rs index 83247e1e51..62c3c50a76 100644 --- a/crates/red_knot_test/src/lib.rs +++ b/crates/red_knot_test/src/lib.rs @@ -15,6 +15,8 @@ mod diagnostic; mod matcher; mod parser; +const MDTEST_TEST_FILTER: &str = "MDTEST_TEST_FILTER"; + /// Run `path` as a markdown test suite with given `title`. /// /// Panic on test failure, and print failure details. @@ -30,8 +32,13 @@ pub fn run(path: &Path, long_title: &str, short_title: &str) { let mut db = db::Db::setup(SystemPathBuf::from("/src")); + let filter = std::env::var(MDTEST_TEST_FILTER).ok(); let mut any_failures = false; for test in suite.tests() { + if filter.as_ref().is_some_and(|f| !test.name().contains(f)) { + continue; + } + // Remove all files so that the db is in a "fresh" state. db.memory_file_system().remove_all(); Files::sync_all(&mut db); @@ -54,6 +61,15 @@ pub fn run(path: &Path, long_title: &str, short_title: &str) { } } } + + println!( + "\nTo rerun this specific test, set the environment variable: {MDTEST_TEST_FILTER}=\"{}\"", + test.name() + ); + println!( + "{MDTEST_TEST_FILTER}=\"{}\" cargo test -p red_knot_python_semantic --test mdtest", + test.name() + ); } }