derive_deftly_tests/tests.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
#![allow(clippy::style, clippy::complexity, clippy::perf)]
//! Tests for derive-deftly
//!
//! **Internal, unpublished crate.**
//!
//! Separating these tests into their own crate arranges that they
//! can go through the "front door" of `use derive_deftly::...`,
//! and in particular makes the cross-crate tests uniform with the others.
//!
//! ## Invoking the tests
//!
//! When running the full test suite,
//! you should use a particular version of Nightly Rust:
//! ```text
//! rustup toolchain add nightly-2024-06-06
//! cargo +nightly-2024-06-06 test --locked --workspace --all-features
//! ```
//! With other versions, the pretty printing of the macro expansions,
//! or the results of standard library macros, can change,
//! causing the tests to break.
//!
//! After your first run, it will probably be helpful to say
//! ```text
//! CARGO_NET_OFFLINE=true cargo +nightly-2024-06-06 test --locked --workspace --all-features
//!```
//! This is because otherwise cargo
//! will uselessly re-update the cargo index,
//! when it is reinvoked by some of the tests.
//!
//! ## Updating the expected outputs
//!
//! Many of the test cases compare an actual with expected output.
//! For example, an expected macro expansion, or error message.
//!
//! If this is expected
//! (for example, you added to the tests, or fixed a bug)
//! can update the expected output files from the actual output.
//!
//! ```text
//! TRYBUILD=overwrite MACROTEST=overwrite STDERRTEST=overwrite \
//! CARGO_NET_OFFLINE=true cargo +nightly-2024-06-06 test --locked --workspace --all-features
//! ```
//!
//! *Check that the actual output is as desired!*
//! This is easily done with `git diff` before committing.
//!
//! ### Slight discrepancies in output, due to reformatting unfaithfulness
//!
//! The outputs in `tests/expand/` come from `cargo expand`,
//! which reformats them for legibility.
//! This reformatting is not always 100% faithful.
//! For example, it can insert or remove `::` tokens.
//!
//! The output from `dbg_all_keywords` is completely faithful.
//! This appears in `tests/stderr/recent.real-stderr`, for example.
//!
//! See
//! [#13](https://gitlab.torproject.org/Diziet/rust-derive-deftly/-/issues/13)
//! for some more discussion.
//!
//! ## Classes of test in the derive-deftly workspace
//!
//! Testing proc macros is not entirely straightforward,
//! so there are multiple classes of test with different approaches.
//!
//! ### `tests/expand/*.rs`
//!
//! - Run with [`trybuild`], and expected to pass.
//! - Expanded with `macrotest`, compared with `expand/*.expanded.rs`.
//!
//! Invoked from `tests/macrotest.rs`,
//! using [`list_expand_test_paths`]
//! and [`list_expand_test_paths_for_macrotest`].
//!
//! Tests with `recent` somewhere in their name are only run
//! if the `recent` cargo feature is enabled for `derive-deftly-tests`.
//! This is enabled in CI for the newer compilers, but not for the MSRV.
//!
//! ### `tests/ui/*.rs`
//!
//! - Run with trybuild and expected to fail.
//! - Errors compared with `tests/ui/*.stderr`.
//!
//! Invoked from `tests/trybuild.rs`.
//!
//! Some of these `.rs` files are reused for `tests/stderr/`.
//!
//! #### `tests/minimal-ui/*.rs`
//!
//! As above, but used when feature `full` isn't enabled.
//! This just tests errors from features being disabled.
//! (In the tests, we include `beta` in `full`.)
//!
//! ### `tests/stderr/`
//!
//! Test cases listed in `tests/stderr/stderr-lib.rs`.
//!
//! - Compile attempted, and stderr captured
//! - Output compared with `tests/stderr/combined.real-stderr`
//!
//! Invoked from `tests/stderr.rs`,
//! which builds the crate `derive-deftly-stderr-tests`.
//! See the doc comment there for details and rationale.
//!
//! ### `tests/pub-a/`, `tests/pub-b/`
//!
//! Tests of cross-crate exports of macros and templates.
//! `pub-a` exports things, and `pub-b` imports and uses them.
//!
//! `pub-a` uses a special `bizarre` version of derive-deftly,
//! to test that the right template expander is used in each case.
//! See the [`pub-b` doc comment](../pub_b/index.html) for details.
//!
//! ### `tests/compat/`
//!
//! Tests compatibility with old, published, versions of derive-deftly.
//! See `tests/compat/README.md`.
//!
//! ### The normal-ish `#[cfg(test)]` modules listed in here `tests/tests.rs`
//!
//! Each module is compiled, and its `#[test]` functions are run.
//!
//! ### `tests/directly/`
//!
//! Tests that go through the "back door",
//! to use the innards of derive-deftly.
//!
//! Currently this is the tests in `directly::check_examples`
//! which extract examples from `doc/reference.md`
//! and check that they match real output.
// We don't want to have to cfg-mark all the imports
#![cfg_attr(
not(all(test, feature = "full", feature = "ui", feature = "recent")),
allow(unused_imports, dead_code)
)]
use std::cell::RefCell;
use std::collections::HashMap;
use std::fmt::Debug;
use std::fmt::Display;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::iter;
use std::path::PathBuf;
use std::rc::Rc;
use easy_ext::ext;
use educe::Educe;
use itertools::Itertools;
use regex::Regex;
use static_assertions::assert_not_impl_any;
pub mod tutils;
pub use tutils::*;
// These mostly serve to avoid rustdoc warnings from directly::macros,
// which is macros.rs re-built outside the proc macro system.
#[allow(unused_imports)]
use derive_deftly::{define_derive_deftly, derive_deftly_adhoc, Deftly};
//---------- modules containing straightforwrad `#[test]` tests ----------
#[cfg(test)]
mod list_names;
#[cfg(test)]
mod modules;
// This is special, and contains tests that use a clone of the d-d-m crate
#[cfg(not(doc))]
mod directly;