diff --git a/Cargo.lock b/Cargo.lock index 4709fb5b4..5c148c117 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3018,6 +3018,7 @@ dependencies = [ "typst-pdf", "typst-render", "typst-svg", + "typst-syntax", "unscanny", "walkdir", ] diff --git a/tests/Cargo.toml b/tests/Cargo.toml index b1855b496..eed093eb6 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -11,14 +11,32 @@ name = "tests" path = "src/tests.rs" harness = false +[features] +# Allow just compiling the parser when only testing typst-syntax. To do so, +# pass '--no-default-features' to 'cargo test'. +default = [ + # "typst-syntax" intentionally not present + "typst", + "typst-assets", + "typst-dev-assets", + "typst-library", + "typst-pdf", + "typst-render", + "typst-svg", + "typst-svg", +] + [dependencies] -typst = { workspace = true } -typst-assets = { workspace = true, features = ["fonts"] } -typst-dev-assets = { workspace = true } -typst-library = { workspace = true } -typst-pdf = { workspace = true } -typst-render = { workspace = true } -typst-svg = { workspace = true } +typst-syntax = { workspace = true } +# Mark other Typst crates as optional so we can use '--no-default-features' +# to decrease compile times for parser testing. +typst = { workspace = true, optional = true } +typst-assets = { workspace = true, features = ["fonts"], optional = true } +typst-dev-assets = { workspace = true, optional = true } +typst-library = { workspace = true, optional = true } +typst-pdf = { workspace = true, optional = true } +typst-render = { workspace = true, optional = true } +typst-svg = { workspace = true, optional = true } clap = { workspace = true } comemo = { workspace = true } ecow = { workspace = true } diff --git a/tests/src/args.rs b/tests/src/args.rs index e94986ced..db5d1a9ba 100644 --- a/tests/src/args.rs +++ b/tests/src/args.rs @@ -66,6 +66,10 @@ pub struct CliArguments { /// This overrides the normal testing system. It parses, but does not run /// the test suite. /// + /// If `cargo test` is run with `--no-default-features`, then compiling will + /// not include Typst's core crates, only typst-syntax, greatly speeding up + /// debugging when changing the parser. + /// /// You can generate a correct reference directory by running on a known /// good commit and copying the generated outputs to a new directory. /// `_things` may be a good location as it is in the top-level gitignore. diff --git a/tests/src/collect.rs b/tests/src/collect.rs index 80e5e5a8b..5c7327f13 100644 --- a/tests/src/collect.rs +++ b/tests/src/collect.rs @@ -6,8 +6,8 @@ use std::str::FromStr; use std::sync::LazyLock; use ecow::{eco_format, EcoString}; -use typst::syntax::package::PackageVersion; -use typst::syntax::{is_id_continue, is_ident, is_newline, FileId, Source, VirtualPath}; +use typst_syntax::package::PackageVersion; +use typst_syntax::{is_id_continue, is_ident, is_newline, FileId, Source, VirtualPath}; use unscanny::Scanner; /// Collects all tests from all files. diff --git a/tests/src/logger.rs b/tests/src/logger.rs index 45c9f0981..48bad451b 100644 --- a/tests/src/logger.rs +++ b/tests/src/logger.rs @@ -2,7 +2,16 @@ use std::io::{self, IsTerminal, StderrLock, Write}; use std::time::{Duration, Instant}; use crate::collect::Test; -use crate::run::TestResult; + +/// The result of running a single test. +pub struct TestResult { + /// The error log for this test. If empty, the test passed. + pub errors: String, + /// The info log for this test. + pub infos: String, + /// Whether the image was mismatched. + pub mismatched_image: bool, +} /// Receives status updates by individual test runs. pub struct Logger<'a> { @@ -58,7 +67,7 @@ impl<'a> Logger<'a> { } }; - if result.is_ok() { + if result.errors.is_empty() { self.passed += 1; } else { self.failed += 1; diff --git a/tests/src/run.rs b/tests/src/run.rs index caa078c4b..1ea19a16a 100644 --- a/tests/src/run.rs +++ b/tests/src/run.rs @@ -12,6 +12,7 @@ use typst::WorldExt; use typst_pdf::PdfOptions; use crate::collect::{FileSize, NoteKind, Test}; +use crate::logger::TestResult; use crate::world::TestWorld; /// Runs a single test. @@ -21,23 +22,6 @@ pub fn run(test: &Test) -> TestResult { Runner::new(test).run() } -/// The result of running a single test. -pub struct TestResult { - /// The error log for this test. If empty, the test passed. - pub errors: String, - /// The info log for this test. - pub infos: String, - /// Whether the image was mismatched. - pub mismatched_image: bool, -} - -impl TestResult { - /// Whether the test passed. - pub fn is_ok(&self) -> bool { - self.errors.is_empty() - } -} - /// Write a line to a log sink, defaulting to the test's error log. macro_rules! log { (into: $sink:expr, $($tts:tt)*) => { diff --git a/tests/src/tests.rs b/tests/src/tests.rs index eb2cfd796..2b09b29c0 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -1,10 +1,16 @@ //! Typst's test runner. +#![cfg_attr(not(feature = "default"), allow(dead_code, unused_imports))] + mod args; mod collect; -mod custom; mod logger; + +#[cfg(feature = "default")] +mod custom; +#[cfg(feature = "default")] mod run; +#[cfg(feature = "default")] mod world; use std::path::{Path, PathBuf}; @@ -17,8 +23,7 @@ use rayon::iter::{ParallelBridge, ParallelIterator}; use crate::args::{CliArguments, Command}; use crate::collect::Test; -use crate::logger::Logger; -use crate::run::TestResult; +use crate::logger::{Logger, TestResult}; /// The parsed command line arguments. static ARGS: LazyLock = LazyLock::new(CliArguments::parse); @@ -95,12 +100,17 @@ fn test() { } let parser_dirs = ARGS.parser_compare.clone().map(create_syntax_store); + #[cfg(not(feature = "default"))] + let parser_dirs = parser_dirs.or_else(|| Some(create_syntax_store(None))); let runner = |test: &Test| { if let Some((live_path, ref_path)) = &parser_dirs { run_parser_test(test, live_path, ref_path) } else { - run::run(test) + #[cfg(feature = "default")] + return run::run(test); + #[cfg(not(feature = "default"))] + unreachable!(); } };