diff --git a/src/cargo.rs b/src/cargo.rs index 8f9142c..9d4c1e6 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -80,7 +80,7 @@ pub(crate) fn build_dependencies(project: &mut Project) -> Result<()> { let mut command = cargo(project); command - .arg(if project.has_pass { "build" } else { "check" }) + .arg(if project.full_build { "build" } else { "check" }) .args(target()) .arg("--bin") .arg(&project.name) @@ -114,7 +114,7 @@ pub(crate) fn build_test(project: &Project, name: &Name) -> Result { .status(); cargo(project) - .arg(if project.has_pass { "build" } else { "check" }) + .arg(if project.full_build { "build" } else { "check" }) .args(target()) .arg("--bin") .arg(name) @@ -137,7 +137,7 @@ pub(crate) fn build_all_tests(project: &Project) -> Result { .status(); cargo(project) - .arg(if project.has_pass { "build" } else { "check" }) + .arg(if project.full_build { "build" } else { "check" }) .args(target()) .arg("--bins") .args(features(project)) diff --git a/src/lib.rs b/src/lib.rs index 143698f..abd1dcb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -294,6 +294,7 @@ pub struct TestCases { #[derive(Debug)] struct Runner { tests: Vec, + full_build: bool, } #[derive(Clone, Debug)] @@ -312,10 +313,18 @@ impl TestCases { #[allow(clippy::new_without_default)] pub fn new() -> Self { TestCases { - runner: RefCell::new(Runner { tests: Vec::new() }), + runner: RefCell::new(Runner { + tests: Vec::new(), + full_build: false, + }), } } + /// Add one or more source files containing pass tests. + /// + /// You can use a [`glob`][glob::glob] patterns add multiple source files at once. + /// + /// Each source file must have a `main` function, and the test is considered to suceed if the `main` function does not panic. pub fn pass>(&self, path: P) { self.runner.borrow_mut().tests.push(Test { path: path.as_ref().to_owned(), @@ -323,12 +332,25 @@ impl TestCases { }); } + /// Add one or more source files containing compile-fail tests. + /// + /// You can use a [`glob`][glob::glob] patterns add multiple source files at once. pub fn compile_fail>(&self, path: P) { self.runner.borrow_mut().tests.push(Test { path: path.as_ref().to_owned(), expected: Expected::CompileFail, }); } + + /// Enable or disable full builds of the test cases. + /// + /// To save time, `trybuild` runs `cargo check` instead of `cargo build` if there are no [`pass()`][Self::pass] tests. + /// However, some build failures (like assertions in const context) do not currently show up with `cargo check`. + /// + /// You can force `trybuild` to run a full build as a work-around. + pub fn full_build(&self, full: bool) { + self.runner.borrow_mut().full_build = full; + } } impl RefUnwindSafe for TestCases {} diff --git a/src/run.rs b/src/run.rs index ff62e2c..d1709d3 100644 --- a/src/run.rs +++ b/src/run.rs @@ -25,8 +25,9 @@ pub(crate) struct Project { pub target_dir: Directory, pub name: String, update: Update, - pub has_pass: bool, + has_pass: bool, has_compile_fail: bool, + pub full_build: bool, pub features: Option>, pub workspace: Directory, pub path_dependencies: Vec, @@ -172,6 +173,7 @@ impl Runner { update: Update::env()?, has_pass, has_compile_fail, + full_build: self.full_build || has_pass, features, workspace, path_dependencies, diff --git a/tests/test.rs b/tests/test.rs index a3bdf91..121cc05 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -20,3 +20,10 @@ fn test() { t.compile_fail("tests/ui/compile-fail-2.rs"); t.compile_fail("tests/ui/compile-fail-3.rs"); } + +#[test] +fn test_full_build() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/compile-fail-const-assert.rs"); + t.full_build(true); +} diff --git a/tests/ui/compile-fail-const-assert.rs b/tests/ui/compile-fail-const-assert.rs new file mode 100644 index 0000000..70c4a66 --- /dev/null +++ b/tests/ui/compile-fail-const-assert.rs @@ -0,0 +1,3 @@ +fn main() { + const { assert!(false) }; +} diff --git a/tests/ui/compile-fail-const-assert.stderr b/tests/ui/compile-fail-const-assert.stderr new file mode 100644 index 0000000..4214c32 --- /dev/null +++ b/tests/ui/compile-fail-const-assert.stderr @@ -0,0 +1,13 @@ +error[E0080]: evaluation of `main::{constant#0}` failed + --> tests/ui/compile-fail-const-assert.rs:2:13 + | +2 | const { assert!(false) }; + | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/tests/ui/compile-fail-const-assert.rs:2:13 + | + = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: erroneous constant encountered + --> tests/ui/compile-fail-const-assert.rs:2:5 + | +2 | const { assert!(false) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^