pax_global_header00006660000000000000000000000064145257444550014531gustar00rootroot0000000000000052 comment=1ea705cf59109b2b895c5716d90572a28e5919f8 test-case-3.3.1/000077500000000000000000000000001452574445500134255ustar00rootroot00000000000000test-case-3.3.1/.github/000077500000000000000000000000001452574445500147655ustar00rootroot00000000000000test-case-3.3.1/.github/workflows/000077500000000000000000000000001452574445500170225ustar00rootroot00000000000000test-case-3.3.1/.github/workflows/test.yml000066400000000000000000000036341452574445500205320ustar00rootroot00000000000000name: Test on: pull_request: push: branches: - master - develop schedule: - cron: "0 0 * * *" jobs: validate: name: Validate clippy and rustfmt runs-on: ubuntu-latest steps: - name: Checkout source code uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy - name: Cache uses: Swatinem/rust-cache@v2 - name: Check run: cargo check --all-features --all-targets - name: Clippy run: cargo clippy --all-features --all-targets -- -D warnings - name: Fmt run: cargo fmt -- --check test: name: Test crate runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: - ubuntu-latest - windows-latest - macOS-latest toolchain: - nightly - stable steps: - name: Checkout source code uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} - name: Cache uses: Swatinem/rust-cache@v2 - name: Test env: CARGO_TERM_COLOR: never SNAPSHOT_DIR: rust-${{ matrix.toolchain }} run: cargo test msrv-build: name: Build crate with documented MSRV runs-on: ubuntu-latest steps: - name: Checkout source code uses: actions/checkout@v4 - name: Read crate metadata id: metadata run: echo "rust-version=$(sed -ne 's/rust-version *= *\"\(.*\)\"/\1/p' Cargo.toml)" >> $GITHUB_OUTPUT - name: Install Rust uses: dtolnay/rust-toolchain@master with: toolchain: ${{ steps.metadata.outputs.rust-version }} - name: Cache uses: Swatinem/rust-cache@v2 - name: Build run: cargo build test-case-3.3.1/.gitignore000066400000000000000000000005671452574445500154250ustar00rootroot00000000000000# Generated by Cargo # will have compiled files and executables target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk .idea *.new # Ignore toolchain installed by script rust-toolchain test-case-3.3.1/CHANGELOG.md000066400000000000000000000142551452574445500152450ustar00rootroot00000000000000# Changelog ## 3.3.1 ### Fixes * Avoid emitting additional misleading error messages by proc-macro2-diagnostics (#138) ## 3.3.0 ### Features * Allow comments in `test-matrix` macro (#132) ### Improvements * Drop `proc-macro-error` dependency & improve error messages (#136) ## 3.2.1 ### Improvements * Update `syn` dependency to 2.0 * Ensure that `test-case` selects correct version of it's `core` and `macros` subcrates ## 3.2.0 ### Features * Add `test_matrix` macro: generates test cases from Cartesian product of possible test function argument values (#128) ### Improvements * Retain `allow` attributes on test functions (#127) ## 3.1.0 ### Features * Copy attribute span to generated test functions so that IDEs recognize them properly as individual tests ### Improvements * Added LICENSE file to child crates ## 3.0.0 [IMPORTANT] Starting with 3.0 release we are changing `test-case` MSRV policy to support only 3 latest stable releases. ### Improvements * Split out functional parts of `test-case-macros` crate into `test-case-core` for easy reuse by external libraries ## 2.2.2 ### Fixes * Use fully qualified `test` macro path to avoid conflicts in workspace (#105) ## 2.2.1 ### Fixes * Ensure `test-case` depends on correct version of `test-case-macros` ## 2.2.0 ### Features * Support `ignore["reason"]` syntax (#102) ## 2.1.0 ### Features * Support `matches_regex` complex test-case (requires `with-regex` feature) (#98) * Support `len`, `count` and `empty` complex test-cases (#97) ### Fixes * Support keyword `ignore` on void fn (#100) ### Improvements * Move macros to separate subcrate so that test-case can export other things (#96) ## 2.0.2 ### Fixes * Covered missing cases in `matches X if Y` *test_case* variant (fixes the fact that previous bug fix didn't produce guard code) ## 2.0.1 ### Fixes * `matches Pattern if condition` parses correctly (`if condition` part wasn't allowed) ## 2.0.0 ### Features * `=> with |x: T| assert!(x)` custom inline test assertions * `=> using path::to::fn` custom fn test assertions * `ignore|inconclusive` can be combined with other keywords (eg.: `=> ignore matches Ok(_)`) * `=> it|is ...` syntax is a built-in (_previously required `hamcrest2` crate integration_) * Tested items are left in place where they were defined #77 * Simple test cases allow `Result<(), _>` return types similar to native `#[test]` macro ### Improvements * Significant code refactoring * Improved test case name selection ### Breaking changes * Deprecation of `inconclusive` within test description string - it will no longer act like modifier keyword * Deprecation of `hamcrest2` integration * Deprecation of `allow_result` feature ## V1.2.3 ### Fixes * Fix regression where `panics` and `inconclusive` were not allowed on `test_cases` returning a value * Fix case where `test_case` would allow to return a type when only single attribute was used ## V1.2.2 ### Fixes * `test-case` no longer allows returning values from tested function without `=>` pattern (thanks to @tarka) * Behaviour can be reenabled via `allow_result` feature ## V1.2.1 ### Fixes * Disabled clippy warning when test-case was generating `assert_eq(bool, bool)` expression. ## V1.2.0 ### Features * Allow usage of fully qualified attribute `#[test_case::test_case]` (thanks to @tomprince) ### Improvements * Stopped code from emmiting unneded `()` expression in test cases with `expected` fragment (thanks to @martinvonz) ## V1.1.0 ### Features * Added support for using `hamcrest2` assertions with test case * Enabled support of `async` via tokio or similar * Enabled attribute passthrough for test cases - it means that you can combine `test-case` with other testing frameworks, given at least one `#[test_case]` attribute appears before mentioned framework in testing function ### Deprecation * `inconclusive` inside test case name will not be supported starting `2.0.0` ## V1.0.0 ### Features * Added support for three new keywords: `panics`, `matches` and `inconclusive` which can be applied after `=>` token. `matches` gives possibility to test patterns, like: ```rust #[test_case("foo" => matches Some(("foo", _)))] ``` `panics` gives `should_panic(expected="...")` for one `test_case`: ```rust #[test_case(true => panics "Panic error message" ; "This should panic")] #[test_case(false => None ; "But this should return None")] ``` `inconclusive` ignores one specific test case.- thanks to @luke_biel ```rust #[test_case("42")] #[test_case("XX" ; "inconclusive - parsing letters temporarily doesn't work, but it's ok")] #[test_case("na" => inconclusive ())] ``` ### Major improvements * Added extra unit tests - thanks to @luke-biel * Replace `parented_test_case` with parsing `test_case` directly from args - thanks to @luke-biel * Added keeping trailing underscores in names - thanks to @rzumer ### Minor improvements * Moved `lazy-static` dependency to `dev-dependencies` * Fixed README - thanks to @luke-biel and @drwilco ### Upgraded dependencies * Upgraded `insta` to `0.12.0` ## v0.3.3 ### Fixes * Fixed "inconclusive" feature with different cases. ## v0.3.2 ### Fixes * Added support for `impl Trait` - it worked in v2.x crate. ### Minor improvements * Added extra test cases ### Upgraded dependencies * Upgraded `version_check` to `v0.9.1` ## v0.3.1 ### Minor improvements: * Refreshed readme * Added CI for stable version of Rust. - thanks to @macisamuele * Limited crate to Rust 1.29+ - thanks to @macisamuele ### Upgraded dependencies: * Upgraded `syn`, `quote` and `proc-macro-2` to `v1` * Upgraded `lazy-static` to `1.4.0` * Upgraded `insta` to `0.11.0` ## v0.3.0 ### Breaking changes * Crate has new maintainer: Wojciech Polak :hand: :tada: * Crate has new name, as `test-case-derive` had no meaning for `derive` part. * Delimiter for test case description is `;` instead of `::`. Reason: `::` is valid part of expression and rustc treats const variable as path ### New features * Proper error propagation :tada: When there is for example a typo in function body, rustc can now show location of it instead of `test_case` location. * Internally for tests crate uses `cargo insta` for snapshot testing * Attribute is now compatible all other attributes like `#[should_panic]` test-case-3.3.1/Cargo.toml000066400000000000000000000023211452574445500153530ustar00rootroot00000000000000[package] name = "test-case" version = "3.3.1" edition = "2021" authors = ["Marcin Sas-Szymanski ", "Wojciech Polak ", "Łukasz Biel "] description = "Provides #[test_case(...)] procedural macro attribute for generating parametrized test cases easily" keywords = ["test", "case", "tests", "unit", "testing"] categories = ["development-tools", "development-tools::testing"] readme = "README.md" license = "MIT" repository = "https://github.com/frondeus/test-case" documentation = "https://docs.rs/test-case" exclude = ["tests/snapshots/**/*"] rust-version = "1.63" [features] with-regex = ["regex", "test-case-macros/with-regex"] [badges] maintenance = { status = "actively-developed" } [lib] doctest = false path = "src/lib.rs" [dependencies] test-case-macros = { version = "3.2.1", path = "crates/test-case-macros", default-features = false } regex = { version = "1.5", optional = true } [dev-dependencies] insta = "1.12" itertools = "0.11" regex = "1.5" [workspace] members = ["crates/*"] [[test]] name = "acceptance" path = "tests/acceptance_tests.rs" test-case-3.3.1/LICENSE000066400000000000000000000020661452574445500144360ustar00rootroot00000000000000MIT License Copyright (c) 2017 Marcin Sas-Szymański Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. test-case-3.3.1/README.md000066400000000000000000000074311452574445500147110ustar00rootroot00000000000000[![Crates.io](https://img.shields.io/crates/v/test-case.svg)](https://crates.io/crates/test-case) [![Crates.io](https://img.shields.io/crates/d/test-case.svg)](https://crates.io/crates/test-case) [![Docs.rs](https://docs.rs/test-case/badge.svg)](https://docs.rs/test-case) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/rust-lang/docs.rs/master/LICENSE) [![Build Status](https://github.com/frondeus/test-case/workflows/Test/badge.svg)](https://github.com/frondeus/test-case/actions) ![Maintenance](https://img.shields.io/badge/maintenance-activly--developed-brightgreen.svg) # Test Case ## Overview `test_case` crate provides procedural macro attribute that generates parametrized test instances. ## Getting Started Crate has to be added as a dependency to `Cargo.toml`: ```toml [dev-dependencies] test-case = "*" ``` and imported to the scope of a block where it's being called (since attribute name collides with rust's built-in `custom_test_frameworks`) via: ```rust use test_case::test_case; ``` ## Example usage: ```rust #[cfg(test)] mod tests { use test_case::test_case; #[test_case(-2, -4 ; "when both operands are negative")] #[test_case(2, 4 ; "when both operands are positive")] #[test_case(4, 2 ; "when operands are swapped")] fn multiplication_tests(x: i8, y: i8) { let actual = (x * y).abs(); assert_eq!(8, actual) } } ``` Output from `cargo test` for this example: ```sh $ cargo test running 4 tests test tests::multiplication_tests::when_both_operands_are_negative ... ok test tests::multiplication_tests::when_both_operands_are_positive ... ok test tests::multiplication_tests::when_operands_are_swapped ... ok test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ``` ### Test Matrix The `#[test_matrix(...)]` macro allows generating multiple test cases from the Cartesian product of one or more possible values for each test function argument. The number of arguments to the `test_matrix` macro must be the same as the number of arguments to the test function. Each macro argument can be: 1. A list in array (`[x, y, ...]`) or tuple (`(x, y, ...)`) syntax. The values can be any valid [expression](https://doc.rust-lang.org/reference/expressions.html). 2. A closed numeric range expression (e.g. `0..100` or `1..=99`), which will generate argument values for all integers in the range. 3. A single expression, which can be used to keep one argument constant while varying the other test function arguments using a list or range. #### Example usage: ```rust #[cfg(test)] mod tests { use test_case::test_matrix; #[test_matrix( [-2, 2], [-4, 4] )] fn multiplication_tests(x: i8, y: i8) { let actual = (x * y).abs(); assert_eq!(8, actual) } } ``` ## MSRV Policy Starting with version 3.0 and up `test-case` introduces policy of only supporting latest stable Rust. These changes may happen overnight, so if your stack is lagging behind current stable release, it may be best to consider locking `test-case` version with `=` in your `Cargo.toml`. ## Documentation Most up to date documentation is available in our [wiki](https://github.com/frondeus/test-case/wiki). # License Licensed under of MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT) # Contributing Project roadmap is available at [link](https://github.com/frondeus/test-case/issues/74). All contributions are welcome. Recommended tools: * `cargo readme` - to regenerate README.md based on template and lib.rs comments * `cargo insta` - to review test snapshots * `cargo edit` - to add/remove dependencies * `cargo fmt` - to format code * `cargo clippy` - for all insights and tips * `cargo fix` - for fixing warnings test-case-3.3.1/README.tpl000066400000000000000000000021531452574445500151040ustar00rootroot00000000000000[![Crates.io](https://img.shields.io/crates/v/test-case.svg)](https://crates.io/crates/test-case) [![Crates.io](https://img.shields.io/crates/d/test-case.svg)](https://crates.io/crates/test-case) [![Docs.rs](https://docs.rs/test-case/badge.svg)](https://docs.rs/test-case) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/rust-lang/docs.rs/master/LICENSE) [![Build Status](https://github.com/frondeus/test-case/workflows/Test/badge.svg)](https://github.com/frondeus/test-case/actions) {{badges}} # Test Case {{readme}} # License Licensed under of MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT) # Contributing Project roadmap is available at [link](https://github.com/frondeus/test-case/issues/74). All contributions are welcome. Recommended tools: * `cargo readme` - to regenerate README.md based on template and lib.rs comments * `cargo insta` - to review test snapshots * `cargo edit` - to add/remove dependencies * `cargo fmt` - to format code * `cargo clippy` - for all insights and tips * `cargo fix` - for fixing warnings test-case-3.3.1/crates/000077500000000000000000000000001452574445500147065ustar00rootroot00000000000000test-case-3.3.1/crates/test-case-core/000077500000000000000000000000001452574445500175245ustar00rootroot00000000000000test-case-3.3.1/crates/test-case-core/Cargo.toml000066400000000000000000000017401452574445500214560ustar00rootroot00000000000000[package] name = "test-case-core" version = "3.3.1" edition = "2021" authors = ["Marcin Sas-Szymanski ", "Wojciech Polak ", "Łukasz Biel "] description = "Provides core functionality for parsing #[test_case(...)] procedural macro attribute for generating parametrized test cases easily" keywords = ["test", "case", "tests", "unit", "testing"] categories = ["development-tools", "development-tools::testing"] readme = "../../README.md" license = "MIT" repository = "https://github.com/frondeus/test-case" documentation = "https://docs.rs/test-case" [features] with-regex = [] [badges] maintenance = { status = "actively-developed" } [lib] doctest = false path = "src/lib.rs" [dependencies] cfg-if = "1.0" proc-macro2 = { version = "1.0", features = [] } quote = "1.0" syn = { version = "2.0", features = ["full", "extra-traits"] } test-case-3.3.1/crates/test-case-core/LICENSE000077700000000000000000000000001452574445500221572../../LICENSEustar00rootroot00000000000000test-case-3.3.1/crates/test-case-core/src/000077500000000000000000000000001452574445500203135ustar00rootroot00000000000000test-case-3.3.1/crates/test-case-core/src/comment.rs000066400000000000000000000017041452574445500223250ustar00rootroot00000000000000use crate::TokenStream2; use quote::ToTokens; use syn::parse::{Parse, ParseStream}; use syn::{LitStr, Token}; #[derive(Clone, Debug)] pub struct TestCaseComment { _semicolon: Token![;], pub comment: LitStr, } impl Parse for TestCaseComment { fn parse(input: ParseStream) -> syn::Result { Ok(Self { _semicolon: input.parse()?, comment: input.parse()?, }) } } impl ToTokens for TestCaseComment { fn to_tokens(&self, tokens: &mut TokenStream2) { self._semicolon.to_tokens(tokens); self.comment.to_tokens(tokens); } } #[cfg(test)] mod tests { use crate::comment::TestCaseComment; use proc_macro2::TokenStream; use syn::parse_quote; #[test] fn parses_token_stream() { let input: TokenStream = parse_quote! { ; "abcdef" }; let actual: TestCaseComment = syn::parse2(input).unwrap(); assert_eq!(actual.comment.value(), "abcdef") } } test-case-3.3.1/crates/test-case-core/src/complex_expr.rs000066400000000000000000000611001452574445500233640ustar00rootroot00000000000000use crate::utils::fmt_syn; use proc_macro2::Group; use proc_macro2::Span; use proc_macro2::TokenStream; use quote::{quote, TokenStreamExt}; use std::fmt::{Display, Formatter}; use syn::parse::{Parse, ParseStream}; use syn::{parse_quote, Expr}; mod kw { syn::custom_keyword!(eq); syn::custom_keyword!(equal_to); syn::custom_keyword!(lt); syn::custom_keyword!(less_than); syn::custom_keyword!(gt); syn::custom_keyword!(greater_than); syn::custom_keyword!(leq); syn::custom_keyword!(less_or_equal_than); syn::custom_keyword!(geq); syn::custom_keyword!(greater_or_equal_than); syn::custom_keyword!(almost); syn::custom_keyword!(almost_equal_to); syn::custom_keyword!(precision); syn::custom_keyword!(existing_path); syn::custom_keyword!(directory); syn::custom_keyword!(dir); syn::custom_keyword!(file); syn::custom_keyword!(contains); syn::custom_keyword!(contains_in_order); syn::custom_keyword!(not); syn::custom_keyword!(and); syn::custom_keyword!(or); syn::custom_keyword!(len); syn::custom_keyword!(has_length); syn::custom_keyword!(count); syn::custom_keyword!(has_count); syn::custom_keyword!(empty); syn::custom_keyword!(matching_regex); syn::custom_keyword!(matches_regex); } #[derive(Clone, Debug, PartialEq, Eq)] pub enum OrderingToken { Eq, Lt, Gt, Leq, Geq, } #[derive(Clone, Debug, PartialEq, Eq)] pub enum PathToken { Any, Dir, File, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct Ord { pub token: OrderingToken, pub expected_value: Box, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct AlmostEqual { pub expected_value: Box, pub precision: Box, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct Path { pub token: PathToken, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct Contains { pub expected_element: Box, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct ContainsInOrder { pub expected_slice: Box, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct Len { pub expected_len: Box, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct Count { pub expected_len: Box, } #[cfg(feature = "with-regex")] #[derive(Clone, Debug, PartialEq, Eq)] pub struct Regex { pub expected_regex: Box, } #[derive(Clone, Debug, PartialEq)] pub enum ComplexTestCase { Not(Box), And(Vec), Or(Vec), Ord(Ord), AlmostEqual(AlmostEqual), Path(Path), Contains(Contains), ContainsInOrder(ContainsInOrder), Len(Len), Count(Count), Empty, #[cfg(feature = "with-regex")] Regex(Regex), } impl Parse for ComplexTestCase { fn parse(input: ParseStream) -> syn::Result { let item = Self::parse_single_item(input)?; Ok(if input.peek(kw::and) { ComplexTestCase::And(parse_kw_repeat::(item, input)?) } else if input.peek(kw::or) { ComplexTestCase::Or(parse_kw_repeat::(item, input)?) } else { item }) } } impl Display for OrderingToken { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { OrderingToken::Eq => f.write_str("eq"), OrderingToken::Lt => f.write_str("lt"), OrderingToken::Gt => f.write_str("gt"), OrderingToken::Leq => f.write_str("leq"), OrderingToken::Geq => f.write_str("geq"), } } } impl Display for PathToken { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { PathToken::Any => f.write_str("path"), PathToken::Dir => f.write_str("dir"), PathToken::File => f.write_str("file"), } } } impl Display for ComplexTestCase { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { ComplexTestCase::Not(not) => write!(f, "not {not}"), ComplexTestCase::And(cases) => { write!(f, "{}", cases[0])?; for case in cases[1..].iter() { write!(f, " and {case}")?; } Ok(()) } ComplexTestCase::Or(cases) => { write!(f, "{}", cases[0])?; for case in cases[1..].iter() { write!(f, " or {case}")?; } Ok(()) } ComplexTestCase::Ord(Ord { token, expected_value, }) => write!(f, "{} {}", token, fmt_syn(expected_value)), ComplexTestCase::AlmostEqual(AlmostEqual { expected_value, precision, }) => write!( f, "almost {} p {}", fmt_syn(expected_value), fmt_syn(precision) ), ComplexTestCase::Path(Path { token }) => write!(f, "path {token}"), ComplexTestCase::Contains(Contains { expected_element }) => { write!(f, "contains {}", fmt_syn(expected_element)) } ComplexTestCase::ContainsInOrder(ContainsInOrder { expected_slice }) => { write!(f, "contains in order {}", fmt_syn(expected_slice)) } ComplexTestCase::Len(Len { expected_len }) => { write!(f, "len {}", fmt_syn(expected_len)) } ComplexTestCase::Count(Count { expected_len }) => { write!(f, "count {}", fmt_syn(expected_len)) } ComplexTestCase::Empty => { write!(f, "empty") } #[cfg(feature = "with-regex")] ComplexTestCase::Regex(Regex { expected_regex }) => { write!(f, "regex {}", fmt_syn(expected_regex)) } } } } impl ComplexTestCase { pub fn assertion(&self) -> TokenStream { let tokens = self.boolean_check(); quote! { assert!(#tokens) } } fn boolean_check(&self) -> TokenStream { match self { ComplexTestCase::Not(not) => not_assertion(not), ComplexTestCase::And(cases) => and_assertion(cases), ComplexTestCase::Or(cases) => or_assertion(cases), ComplexTestCase::Ord(Ord { token, expected_value, }) => ord_assertion(token, expected_value), ComplexTestCase::AlmostEqual(AlmostEqual { expected_value, precision, }) => almost_equal_assertion(expected_value, precision), ComplexTestCase::Path(Path { token }) => path_assertion(token), ComplexTestCase::Contains(Contains { expected_element }) => { contains_assertion(expected_element) } ComplexTestCase::ContainsInOrder(ContainsInOrder { expected_slice }) => { contains_in_order_assertion(expected_slice) } ComplexTestCase::Len(Len { expected_len }) => len_assertion(expected_len), ComplexTestCase::Count(Count { expected_len }) => count_assertion(expected_len), ComplexTestCase::Empty => empty_assertion(), #[cfg(feature = "with-regex")] ComplexTestCase::Regex(Regex { expected_regex }) => regex_assertion(expected_regex), } } fn parse_single_item(input: ParseStream) -> syn::Result { Ok(if let Ok(group) = Group::parse(input) { syn::parse2(group.stream())? } else if input.parse::().is_ok() || input.parse::().is_ok() { ComplexTestCase::Ord(Ord { token: OrderingToken::Eq, expected_value: input.parse()?, }) } else if input.parse::().is_ok() || input.parse::().is_ok() { ComplexTestCase::Ord(Ord { token: OrderingToken::Lt, expected_value: input.parse()?, }) } else if input.parse::().is_ok() || input.parse::().is_ok() { ComplexTestCase::Ord(Ord { token: OrderingToken::Gt, expected_value: input.parse()?, }) } else if input.parse::().is_ok() || input.parse::().is_ok() { ComplexTestCase::Ord(Ord { token: OrderingToken::Leq, expected_value: input.parse()?, }) } else if input.parse::().is_ok() || input.parse::().is_ok() { ComplexTestCase::Ord(Ord { token: OrderingToken::Geq, expected_value: input.parse()?, }) } else if input.parse::().is_ok() || input.parse::().is_ok() { let target = input.parse()?; let _ = input.parse::()?; let precision = input.parse()?; ComplexTestCase::AlmostEqual(AlmostEqual { expected_value: target, precision, }) } else if input.parse::().is_ok() { ComplexTestCase::Path(Path { token: PathToken::Any, }) } else if input.parse::().is_ok() || input.parse::().is_ok() { ComplexTestCase::Path(Path { token: PathToken::Dir, }) } else if input.parse::().is_ok() { ComplexTestCase::Path(Path { token: PathToken::File, }) } else if input.parse::().is_ok() { ComplexTestCase::Contains(Contains { expected_element: input.parse()?, }) } else if input.parse::().is_ok() { ComplexTestCase::ContainsInOrder(ContainsInOrder { expected_slice: input.parse()?, }) } else if input.parse::().is_ok() { ComplexTestCase::Not(Box::new(input.parse()?)) } else if input.parse::().is_ok() || input.parse::().is_ok() { ComplexTestCase::Len(Len { expected_len: input.parse()?, }) } else if input.parse::().is_ok() || input.parse::().is_ok() { ComplexTestCase::Count(Count { expected_len: input.parse()?, }) } else if input.parse::().is_ok() { ComplexTestCase::Empty } else if input.parse::().is_ok() || input.parse::().is_ok() { cfg_if::cfg_if! { if #[cfg(feature = "with-regex")] { ComplexTestCase::Regex(Regex { expected_regex: input.parse()?, }) } else { return Err(input.error("'with-regex' feature is required to use 'matches-regex' keyword")); } } } else { return Err(input.error("cannot parse complex expression")); }) } } fn and_assertion(cases: &[ComplexTestCase]) -> TokenStream { let ts = cases[0].boolean_check(); let mut ts: TokenStream = parse_quote! { #ts }; for case in cases.iter().skip(1) { let case = case.boolean_check(); let case: TokenStream = parse_quote! { && #case }; ts.append_all(case); } ts } fn or_assertion(cases: &[ComplexTestCase]) -> TokenStream { let ts = cases[0].boolean_check(); let mut ts: TokenStream = parse_quote! { #ts }; for case in cases.iter().skip(1) { let case = case.boolean_check(); let case: TokenStream = parse_quote! { || #case }; ts.append_all(case); } ts } fn parse_kw_repeat( first: ComplexTestCase, input: ParseStream, ) -> syn::Result> { let mut acc = vec![first]; while input.parse::().is_ok() { acc.push(ComplexTestCase::parse_single_item(input)?); } Ok(acc) } fn negate(tokens: TokenStream) -> TokenStream { quote! { !{#tokens} } } fn contains_in_order_assertion(expected_slice: &Expr) -> TokenStream { parse_quote! { { let mut _tc_outcome = false; for i in 0..=_result.len() - #expected_slice.len() { if #expected_slice == _result[i..i+#expected_slice.len()] { _tc_outcome = true; } } _tc_outcome } } } fn contains_assertion(expected_element: &Expr) -> TokenStream { parse_quote! { _result.iter().find(|i| i.eq(&&#expected_element)).is_some() } } fn path_assertion(token: &PathToken) -> TokenStream { match token { PathToken::Any => parse_quote! { std::path::Path::new(&_result).exists() }, PathToken::Dir => parse_quote! { std::path::Path::new(&_result).is_dir() }, PathToken::File => parse_quote! { std::path::Path::new(&_result).is_file() }, } } fn almost_equal_assertion(expected_value: &Expr, precision: &Expr) -> TokenStream { quote! { (_result - #expected_value).abs() < #precision } } fn ord_assertion(token: &OrderingToken, expected_value: &Expr) -> TokenStream { let ts: TokenStream = match token { OrderingToken::Eq => parse_quote! { == }, OrderingToken::Lt => parse_quote! { < }, OrderingToken::Gt => parse_quote! { > }, OrderingToken::Leq => parse_quote! { <= }, OrderingToken::Geq => parse_quote! { >= }, }; quote! { _result #ts #expected_value } } fn len_assertion(expected_len: &Expr) -> TokenStream { quote! { _result.len() == #expected_len } } fn count_assertion(expected_len: &Expr) -> TokenStream { quote! { std::iter::IntoIterator::into_iter(_result).count() == #expected_len } } fn empty_assertion() -> TokenStream { quote! { _result.is_empty() } } #[cfg(feature = "with-regex")] fn regex_assertion(expected_regex: &Expr) -> TokenStream { quote! { { let re = ::test_case::Regex::new(#expected_regex).expect("Regex::new"); re.is_match(_result) } } } fn not_assertion(not: &ComplexTestCase) -> TokenStream { match not { ComplexTestCase::Not(_) => { let msg = "multiple negations on single item are forbidden"; syn::Error::new(Span::call_site(), msg).into_compile_error() } ComplexTestCase::And(cases) => negate(and_assertion(cases)), ComplexTestCase::Or(cases) => negate(or_assertion(cases)), ComplexTestCase::Ord(Ord { token, expected_value, }) => negate(ord_assertion(token, expected_value)), ComplexTestCase::AlmostEqual(AlmostEqual { expected_value, precision, }) => negate(almost_equal_assertion(expected_value, precision)), ComplexTestCase::Path(Path { token }) => negate(path_assertion(token)), ComplexTestCase::Contains(Contains { expected_element }) => { negate(contains_assertion(expected_element)) } ComplexTestCase::ContainsInOrder(ContainsInOrder { expected_slice }) => { negate(contains_in_order_assertion(expected_slice)) } ComplexTestCase::Len(Len { expected_len }) => negate(len_assertion(expected_len)), ComplexTestCase::Count(Count { expected_len }) => negate(count_assertion(expected_len)), ComplexTestCase::Empty => negate(empty_assertion()), #[cfg(feature = "with-regex")] ComplexTestCase::Regex(Regex { expected_regex }) => negate(regex_assertion(expected_regex)), } } #[cfg(test)] mod tests { use crate::complex_expr::{ AlmostEqual, ComplexTestCase, Contains, ContainsInOrder, Count, Len, OrderingToken, Path, PathToken, }; use syn::{parse_quote, LitFloat, LitInt, LitStr}; macro_rules! assert_ord { ($actual:tt, $token:path, $value:tt) => { if let ComplexTestCase::Ord(ord) = $actual { assert_eq!(ord.token, $token); let lit = ord.expected_value; let actual_expr: LitFloat = parse_quote! { #lit }; assert_eq!(actual_expr.base10_parse::().unwrap(), $value) } else { panic!("invalid enum variant") } }; } macro_rules! assert_almost_eq { ($actual:tt, $value:tt, $precision:tt) => { if let ComplexTestCase::AlmostEqual(AlmostEqual { expected_value, precision, }) = $actual { let expected_value: LitFloat = parse_quote! { #expected_value }; assert_eq!(expected_value.base10_parse::().unwrap(), $value); let precision: LitFloat = parse_quote! { #precision }; assert_eq!(precision.base10_parse::().unwrap(), $precision); } else { panic!("invalid enum variant") } }; } #[test] #[allow(clippy::float_cmp)] fn parses_ord_token_stream() { let actual: ComplexTestCase = parse_quote! { equal_to 1.0 }; assert_ord!(actual, OrderingToken::Eq, 1.0); let actual: ComplexTestCase = parse_quote! { eq 0.0 }; assert_ord!(actual, OrderingToken::Eq, 0.0); let actual: ComplexTestCase = parse_quote! { less_than 2.0 }; assert_ord!(actual, OrderingToken::Lt, 2.0); let actual: ComplexTestCase = parse_quote! { lt 2.0 }; assert_ord!(actual, OrderingToken::Lt, 2.0); let actual: ComplexTestCase = parse_quote! { greater_than 2.0 }; assert_ord!(actual, OrderingToken::Gt, 2.0); let actual: ComplexTestCase = parse_quote! { gt 2.0 }; assert_ord!(actual, OrderingToken::Gt, 2.0); let actual: ComplexTestCase = parse_quote! { less_or_equal_than 2.0 }; assert_ord!(actual, OrderingToken::Leq, 2.0); let actual: ComplexTestCase = parse_quote! { leq 2.0 }; assert_ord!(actual, OrderingToken::Leq, 2.0); let actual: ComplexTestCase = parse_quote! { greater_or_equal_than 2.0 }; assert_ord!(actual, OrderingToken::Geq, 2.0); let actual: ComplexTestCase = parse_quote! { geq 2.0 }; assert_ord!(actual, OrderingToken::Geq, 2.0); } #[test] fn can_parse_eq_other_types() { let actual: ComplexTestCase = parse_quote! { equal_to "abcde" }; if let ComplexTestCase::Ord(ord) = actual { assert_eq!(ord.token, OrderingToken::Eq); let lit = ord.expected_value; let actual_expr: LitStr = parse_quote! { #lit }; assert_eq!(actual_expr.value(), "abcde") } else { panic!("invalid enum variant") } let actual: ComplexTestCase = parse_quote! { equal_to 1 }; if let ComplexTestCase::Ord(ord) = actual { assert_eq!(ord.token, OrderingToken::Eq); let lit = ord.expected_value; let actual_expr: LitInt = parse_quote! { #lit }; assert_eq!(actual_expr.base10_parse::().unwrap(), 1) } else { panic!("invalid enum variant") } } #[test] #[allow(clippy::float_cmp)] fn parses_almost_equal_token_stream() { let actual: ComplexTestCase = parse_quote! { almost_equal_to 1.0 precision 0.1 }; assert_almost_eq!(actual, 1.0, 0.1); let actual: ComplexTestCase = parse_quote! { almost_equal_to 1.0 precision 0.0f32 }; assert_almost_eq!(actual, 1.0, 0.0); } #[test] fn parses_path_token_stream() { let actual: ComplexTestCase = parse_quote! { existing_path }; assert_eq!( actual, ComplexTestCase::Path(Path { token: PathToken::Any }) ); let actual: ComplexTestCase = parse_quote! { file }; assert_eq!( actual, ComplexTestCase::Path(Path { token: PathToken::File }) ); let actual: ComplexTestCase = parse_quote! { dir }; assert_eq!( actual, ComplexTestCase::Path(Path { token: PathToken::Dir }) ); let actual: ComplexTestCase = parse_quote! { directory }; assert_eq!( actual, ComplexTestCase::Path(Path { token: PathToken::Dir }) ); } #[test] fn parses_contains_token_stream() { let actual: ComplexTestCase = parse_quote! { contains 1.0 }; assert_eq!( actual, ComplexTestCase::Contains(Contains { expected_element: Box::new(parse_quote! { 1.0 }) }) ); let actual: ComplexTestCase = parse_quote! { contains "abcde" }; assert_eq!( actual, ComplexTestCase::Contains(Contains { expected_element: Box::new(parse_quote! { "abcde" }) }) ); let actual: ComplexTestCase = parse_quote! { contains true }; assert_eq!( actual, ComplexTestCase::Contains(Contains { expected_element: Box::new(parse_quote! { true }) }) ); } #[test] fn parses_contains_in_order_token_stream() { let actual: ComplexTestCase = parse_quote! { contains_in_order [1, 2, 3] }; assert_eq!( actual, ComplexTestCase::ContainsInOrder(ContainsInOrder { expected_slice: Box::new(parse_quote! { [1, 2, 3] }) }) ) } #[test] fn parses_len_token_stream() { let actual1: ComplexTestCase = parse_quote! { len 10 }; let actual2: ComplexTestCase = parse_quote! { has_length 11 }; assert_eq!( actual1, ComplexTestCase::Len(Len { expected_len: Box::new(parse_quote! { 10 }) }) ); assert_eq!( actual2, ComplexTestCase::Len(Len { expected_len: Box::new(parse_quote! { 11 }) }) ) } #[test] fn parses_count_token_stream() { let actual1: ComplexTestCase = parse_quote! { count 10 }; let actual2: ComplexTestCase = parse_quote! { has_count 11 }; assert_eq!( actual1, ComplexTestCase::Count(Count { expected_len: Box::new(parse_quote! { 10 }) }) ); assert_eq!( actual2, ComplexTestCase::Count(Count { expected_len: Box::new(parse_quote! { 11 }) }) ) } #[test] fn parses_empty() { let actual: ComplexTestCase = parse_quote! { empty }; assert_eq!(actual, ComplexTestCase::Empty,) } #[test] fn parses_negation() { let actual: ComplexTestCase = parse_quote! { not eq 1.0 }; match actual { ComplexTestCase::Not(_) => {} _ => panic!("test failed"), }; } #[test] #[allow(clippy::float_cmp)] fn parses_grouping() { let actual: ComplexTestCase = parse_quote! { (lt 1.0) }; assert_ord!(actual, OrderingToken::Lt, 1.0); let actual: ComplexTestCase = parse_quote! { (((lt 1.0))) }; assert_ord!(actual, OrderingToken::Lt, 1.0); let actual: ComplexTestCase = parse_quote! { ({[(lt 1.0)]}) }; assert_ord!(actual, OrderingToken::Lt, 1.0) } #[test] fn parses_logic() { let actual: ComplexTestCase = parse_quote! { lt 1.0 and gt 0.0 }; match actual { ComplexTestCase::And(v) if v.len() == 2 => {} _ => panic!("test failed"), } let actual: ComplexTestCase = parse_quote! { lt 0.0 or gt 1.0 }; match actual { ComplexTestCase::Or(v) if v.len() == 2 => {} _ => panic!("test failed"), } let actual: ComplexTestCase = parse_quote! { lt 1.0 and gt 0.0 and eq 0.5 }; match actual { ComplexTestCase::And(v) if v.len() == 3 => {} _ => panic!("test failed"), } let actual: ComplexTestCase = parse_quote! { lt 0.0 or gt 1.0 or eq 2.0 }; match actual { ComplexTestCase::Or(v) if v.len() == 3 => {} _ => panic!("test failed"), } let actual: ComplexTestCase = parse_quote! { (lt 0.0 or gt 1.0) and eq 2.0 }; match actual { ComplexTestCase::And(v) if v.len() == 2 => {} _ => panic!("test failed"), } let actual: ComplexTestCase = parse_quote! { (lt 1.0 and gt 0.0) or eq 2.0 }; match actual { ComplexTestCase::Or(v) if v.len() == 2 => {} _ => panic!("test failed"), } } } test-case-3.3.1/crates/test-case-core/src/expr.rs000066400000000000000000000152141452574445500216420ustar00rootroot00000000000000use crate::complex_expr::ComplexTestCase; use crate::modifier::{parse_kws, Modifier}; use crate::utils::fmt_syn; use crate::TokenStream2; use quote::ToTokens; use std::collections::HashSet; use std::fmt::{Display, Formatter}; use syn::parse::{Parse, ParseStream}; use syn::token::If; use syn::{parse_quote, Attribute, Expr, Pat, Token}; pub mod kw { syn::custom_keyword!(matches); syn::custom_keyword!(using); syn::custom_keyword!(with); syn::custom_keyword!(it); syn::custom_keyword!(is); syn::custom_keyword!(panics); } #[derive(Clone, Debug)] pub struct TestCaseExpression { _token: Token![=>], pub extra_keywords: HashSet, pub result: TestCaseResult, } #[derive(Clone, Debug)] pub enum TestCaseResult { // test_case(a, b, c => keywords) Empty, // test_case(a, b, c => result) Simple(Expr), // test_case(a, b, c => matches Ok(_) if true) Matching(Pat, Option>), // test_case(a, b, c => panics "abcd") Panicking(Option), // test_case(a, b, c => with |v: T| assert!(v.is_nan())) With(Expr), // test_case(a, b, c => using assert_nan) UseFn(Expr), // test_case(a, b, c => is close to 4 precision 0.1) Complex(ComplexTestCase), } impl Parse for TestCaseExpression { fn parse(input: ParseStream) -> syn::Result { let token: Token![=>] = input.parse()?; let extra_keywords = parse_kws(input); if input.parse::().is_ok() { let pattern = Pat::parse_single(input)?; let guard = if input.peek(If) { let _if_kw: If = input.parse()?; let guard: Box = input.parse()?; Some(guard) } else { None }; Ok(TestCaseExpression { _token: token, extra_keywords, result: TestCaseResult::Matching(pattern, guard), }) } else if input.parse::().is_ok() || input.parse::().is_ok() { parse_with_keyword::<_, _>(input, token, extra_keywords, TestCaseResult::Complex) } else if input.parse::().is_ok() { parse_with_keyword::<_, _>(input, token, extra_keywords, TestCaseResult::UseFn) } else if input.parse::().is_ok() { parse_with_keyword::<_, _>(input, token, extra_keywords, TestCaseResult::With) } else if input.parse::().is_ok() { parse_with_keyword_ok::<_, _>(input, token, extra_keywords, TestCaseResult::Panicking) } else { let result = match input.parse::() { Ok(expr) => TestCaseResult::Simple(expr), Err(_) if !extra_keywords.is_empty() => TestCaseResult::Empty, Err(e) => return Err(e), }; Ok(Self { _token: token, extra_keywords, result, }) } } } impl Display for TestCaseExpression { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { for kw in &self.extra_keywords { write!(f, "{kw:?}")?; } write!(f, "{}", self.result) } } impl Display for TestCaseResult { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { TestCaseResult::Simple(expr) => write!(f, "{}", fmt_syn(expr)), TestCaseResult::Matching(pat, expr) => { write!(f, "matching {} {}", fmt_syn(pat), fmt_syn(expr)) } TestCaseResult::Panicking(expr) => write!( f, "panicking {:?}", expr.as_ref().map(|inner| fmt_syn(&inner)) ), TestCaseResult::With(expr) => write!(f, "with {}", fmt_syn(expr)), TestCaseResult::UseFn(expr) => write!(f, "use {}", fmt_syn(expr)), TestCaseResult::Complex(complex) => write!(f, "complex {complex}"), TestCaseResult::Empty => write!(f, "empty"), } } } impl TestCaseExpression { pub fn assertion(&self) -> TokenStream2 { match &self.result { TestCaseResult::Simple(expr) => parse_quote! { assert_eq!(#expr, _result) }, TestCaseResult::Matching(pat, guard) => { let pat_str = pat.to_token_stream().to_string(); if let Some(guard) = guard { let guard_str = guard.to_token_stream().to_string(); parse_quote! { match _result { #pat if #guard => (), e => panic!("Expected `{} if {}` found {:?}", #pat_str, #guard_str, e) } } } else { parse_quote! { match _result { #pat => (), e => panic!("Expected `{}` found {:?}", #pat_str, e) } } } } TestCaseResult::Panicking(_) => TokenStream2::new(), TestCaseResult::With(expr) => parse_quote! { let fun = #expr; fun(_result) }, TestCaseResult::UseFn(path) => parse_quote! { #path(_result) }, TestCaseResult::Complex(complex) => complex.assertion(), TestCaseResult::Empty => TokenStream2::new(), } } pub fn attributes(&self) -> Vec { let mut attrs: Vec = self .extra_keywords .iter() .map(|modifier| modifier.attribute()) .collect(); if let TestCaseResult::Panicking(opt) = &self.result { if let Some(expr) = opt { attrs.push(parse_quote! { #[should_panic(expected = #expr)] }) } else { attrs.push(parse_quote! { #[should_panic] }) } } attrs } } fn parse_with_keyword( input: ParseStream, token: Token![=>], extra_keywords: HashSet, mapping: Mapping, ) -> syn::Result where Mapping: FnOnce(Inner) -> TestCaseResult, Inner: Parse, { Ok(TestCaseExpression { _token: token, extra_keywords, result: mapping(input.parse()?), }) } fn parse_with_keyword_ok( input: ParseStream, token: Token![=>], extra_keywords: HashSet, mapping: Mapping, ) -> syn::Result where Mapping: FnOnce(Option) -> TestCaseResult, Inner: Parse, { let result = (!input.is_empty()).then(|| input.parse()).transpose()?; Ok(TestCaseExpression { _token: token, extra_keywords, result: mapping(result), }) } test-case-3.3.1/crates/test-case-core/src/lib.rs000066400000000000000000000003201452574445500214220ustar00rootroot00000000000000use proc_macro2::TokenStream as TokenStream2; mod comment; mod complex_expr; mod expr; mod modifier; mod test_case; mod test_matrix; mod utils; pub use test_case::TestCase; pub use test_matrix::TestMatrix; test-case-3.3.1/crates/test-case-core/src/modifier.rs000066400000000000000000000035651452574445500224700ustar00rootroot00000000000000use std::collections::HashSet; use std::fmt::{Debug, Formatter}; use syn::parse::{Parse, ParseStream}; use syn::token::Bracket; use syn::{bracketed, parse_quote, Attribute, LitStr}; mod kw { syn::custom_keyword!(inconclusive); syn::custom_keyword!(ignore); } #[derive(Clone, PartialEq, Eq, Hash)] pub enum Modifier { Inconclusive, InconclusiveWithReason(LitStr), } impl Debug for Modifier { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Modifier::Inconclusive | Modifier::InconclusiveWithReason(_) => { write!(f, "inconclusive") } } } } impl Parse for Modifier { fn parse(input: ParseStream) -> syn::Result { if input.peek(kw::inconclusive) { let _: kw::inconclusive = input.parse()?; Self::parse_inconclusive(input) } else if input.peek(kw::ignore) { let _: kw::ignore = input.parse()?; Self::parse_inconclusive(input) } else { Err(syn::Error::new(input.span(), "unknown modifier keyword")) } } } impl Modifier { pub fn parse_inconclusive(input: ParseStream) -> syn::Result { if input.peek(Bracket) { let content; let _: Bracket = bracketed!(content in input); let reason: LitStr = content.parse()?; Ok(Self::InconclusiveWithReason(reason)) } else { Ok(Self::Inconclusive) } } pub fn attribute(&self) -> Attribute { match self { Modifier::Inconclusive => parse_quote! { #[ignore] }, Modifier::InconclusiveWithReason(r) => parse_quote! { #[ignore = #r] }, } } } pub fn parse_kws(input: ParseStream) -> HashSet { let mut kws = HashSet::new(); while let Ok(kw) = Modifier::parse(input) { kws.insert(kw); } kws } test-case-3.3.1/crates/test-case-core/src/test_case.rs000066400000000000000000000136011452574445500226340ustar00rootroot00000000000000use crate::comment::TestCaseComment; use crate::expr::{TestCaseExpression, TestCaseResult}; use crate::utils::fmt_syn; use proc_macro2::{Span as Span2, TokenStream as TokenStream2}; use quote::quote; use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; use syn::{parse_quote, Error, Expr, Ident, ItemFn, ReturnType, Token}; #[derive(Debug)] pub struct TestCase { args: Punctuated, expression: Option, name: Ident, } impl Parse for TestCase { fn parse(input: ParseStream) -> Result { let args = Punctuated::parse_separated_nonempty_with(input, Expr::parse)?; let expression = (!input.is_empty()).then(|| input.parse()).transpose(); let comment = (!input.is_empty()).then(|| input.parse()).transpose(); // if both are errors, pick the expression error since it is more likely to be informative. // // TODO(https://github.com/frondeus/test-case/issues/135): avoid Result::ok entirely. let (expression, comment) = match (expression, comment) { (Err(expression), Err(_comment)) => return Err(expression), (expression, comment) => (expression.ok().flatten(), comment.ok().flatten()), }; Ok(Self::new_from_parsed(args, expression, comment)) } } impl TestCase { pub(crate) fn new>( args: I, expression: Option, comment: Option, ) -> Self { Self::new_from_parsed(args.into_iter().collect(), expression, comment) } pub(crate) fn new_from_parsed( args: Punctuated, expression: Option, comment: Option, ) -> Self { let name = Self::test_case_name_ident(args.iter(), expression.as_ref(), comment.as_ref()); Self { args, expression, name, } } pub(crate) fn new_with_prefixed_name>( args: I, expression: Option, prefix: &str, ) -> Self { let parsed_args = args.into_iter().collect::>(); let name = Self::prefixed_test_case_name(parsed_args.iter(), expression.as_ref(), prefix); Self { args: parsed_args, expression, name, } } pub fn test_case_name(&self) -> Ident { // The clone is kind of annoying here, but because this is behind a reference, we must clone // to preserve the signature without a breaking change // TODO: return a reference? self.name.clone() } pub fn render(&self, mut item: ItemFn, origin_span: Span2) -> TokenStream2 { let item_name = item.sig.ident.clone(); let arg_values = self.args.iter(); let test_case_name = { let mut test_case_name = self.test_case_name(); test_case_name.set_span(origin_span); test_case_name }; let mut attrs = self .expression .as_ref() .map(|expr| expr.attributes()) .unwrap_or_default(); attrs.push(parse_quote! { #[allow(clippy::bool_assert_comparison)] }); attrs.append(&mut item.attrs); let (mut signature, body) = if item.sig.asyncness.is_some() { ( quote! { async }, quote! { let _result = super::#item_name(#(#arg_values),*).await; }, ) } else { attrs.insert(0, parse_quote! { #[::core::prelude::v1::test] }); ( TokenStream2::new(), quote! { let _result = super::#item_name(#(#arg_values),*); }, ) }; let expected = if let Some(expr) = self.expression.as_ref() { attrs.extend(expr.attributes()); signature.extend(quote! { fn #test_case_name() }); if let TestCaseResult::Panicking(_) = expr.result { TokenStream2::new() } else { expr.assertion() } } else { signature.extend(if let ReturnType::Type(_, typ) = item.sig.output { quote! { fn #test_case_name() -> #typ } } else { quote! { fn #test_case_name() } }); quote! { _result } }; quote! { #(#attrs)* #signature { #body #expected } } } fn test_case_name_ident<'a, I: Iterator>( args: I, expression: Option<&TestCaseExpression>, comment: Option<&TestCaseComment>, ) -> Ident { let desc = Self::test_case_name_string(args, expression, comment); crate::utils::escape_test_name(desc) } fn prefixed_test_case_name<'a, I: Iterator>( args: I, expression: Option<&TestCaseExpression>, prefix: &str, ) -> Ident { let generated_name = Self::test_case_name_string(args, expression, None); let full_desc = format!("{prefix}_{generated_name}"); crate::utils::escape_test_name(full_desc) } fn test_case_name_string<'a, I: Iterator>( args: I, expression: Option<&TestCaseExpression>, comment: Option<&TestCaseComment>, ) -> String { comment .as_ref() .map(|item| item.comment.value()) .unwrap_or_else(|| { let mut acc = String::new(); for arg in args { acc.push_str(&fmt_syn(&arg)); acc.push('_'); } acc.push_str("expects"); if let Some(expression) = expression { acc.push(' '); acc.push_str(&expression.to_string()) } acc }) } } test-case-3.3.1/crates/test-case-core/src/test_matrix/000077500000000000000000000000001452574445500226565ustar00rootroot00000000000000test-case-3.3.1/crates/test-case-core/src/test_matrix/matrix_product.rs000066400000000000000000000174361452574445500263030ustar00rootroot00000000000000//! Copied with minor modifications from itertools v0.11.0 //! under MIT License //! //! Modifications called out in "(MOD)" comments, below //! //! Source file and commit hash: //! https://github.com/rust-itertools/itertools/blob/v0.11.0/src/adaptors/multi_product.rs //! ed6fbda086a913a787450a642acfd4d36dc07c3b #[derive(Clone)] /// An iterator adaptor that iterates over the cartesian product of /// multiple iterators of type `I`. /// /// An iterator element type is `Vec`. /// /// See [`.multi_cartesian_product()`](crate::Itertools::multi_cartesian_product) /// for more information. #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub struct MultiProduct(Vec>) where I: Iterator + Clone, I::Item: Clone; // (MOD) Omit `impl Debug for MultiProduct` // Not needed here and relies on a macro from itertools /// Create a new cartesian product iterator over an arbitrary number /// of iterators of the same type. /// /// Iterator element is of type `Vec`. pub fn multi_cartesian_product(iters: H) -> MultiProduct<::IntoIter> where H: Iterator, H::Item: IntoIterator, ::IntoIter: Clone, ::Item: Clone, { MultiProduct( iters .map(|i| MultiProductIter::new(i.into_iter())) .collect(), ) } #[derive(Clone, Debug)] /// Holds the state of a single iterator within a `MultiProduct`. struct MultiProductIter where I: Iterator + Clone, I::Item: Clone, { cur: Option, iter: I, iter_orig: I, } /// Holds the current state during an iteration of a `MultiProduct`. #[derive(Debug)] enum MultiProductIterState { StartOfIter, MidIter { on_first_iter: bool }, } impl MultiProduct where I: Iterator + Clone, I::Item: Clone, { /// Iterates the rightmost iterator, then recursively iterates iterators /// to the left if necessary. /// /// Returns true if the iteration succeeded, else false. fn iterate_last( multi_iters: &mut [MultiProductIter], mut state: MultiProductIterState, ) -> bool { use self::MultiProductIterState::*; if let Some((last, rest)) = multi_iters.split_last_mut() { let on_first_iter = match state { StartOfIter => { let on_first_iter = !last.in_progress(); state = MidIter { on_first_iter }; on_first_iter } MidIter { on_first_iter } => on_first_iter, }; if !on_first_iter { last.iterate(); } if last.in_progress() { true } else if MultiProduct::iterate_last(rest, state) { last.reset(); last.iterate(); // If iterator is None twice consecutively, then iterator is // empty; whole product is empty. last.in_progress() } else { false } } else { // Reached end of iterator list. On initialisation, return true. // At end of iteration (final iterator finishes), finish. match state { StartOfIter => false, MidIter { on_first_iter } => on_first_iter, } } } /// Returns the unwrapped value of the next iteration. fn curr_iterator(&self) -> Vec { self.0 .iter() .map(|multi_iter| multi_iter.cur.clone().unwrap()) .collect() } /// Returns true if iteration has started and has not yet finished; false /// otherwise. fn in_progress(&self) -> bool { if let Some(last) = self.0.last() { last.in_progress() } else { false } } } impl MultiProductIter where I: Iterator + Clone, I::Item: Clone, { fn new(iter: I) -> Self { MultiProductIter { cur: None, iter: iter.clone(), iter_orig: iter, } } /// Iterate the managed iterator. fn iterate(&mut self) { self.cur = self.iter.next(); } /// Reset the managed iterator. fn reset(&mut self) { self.iter = self.iter_orig.clone(); } /// Returns true if the current iterator has been started and has not yet /// finished; false otherwise. fn in_progress(&self) -> bool { self.cur.is_some() } } impl Iterator for MultiProduct where I: Iterator + Clone, I::Item: Clone, { type Item = Vec; fn next(&mut self) -> Option { if MultiProduct::iterate_last(&mut self.0, MultiProductIterState::StartOfIter) { Some(self.curr_iterator()) } else { None } } fn count(self) -> usize { if self.0.is_empty() { return 0; } if !self.in_progress() { return self .0 .into_iter() .fold(1, |acc, multi_iter| acc * multi_iter.iter.count()); } self.0.into_iter().fold( 0, |acc, MultiProductIter { iter, iter_orig, cur: _, }| { let total_count = iter_orig.count(); let cur_count = iter.count(); acc * total_count + cur_count }, ) } fn size_hint(&self) -> (usize, Option) { // Not ExactSizeIterator because size may be larger than usize if self.0.is_empty() { return (0, Some(0)); } if !self.in_progress() { return self.0.iter().fold((1, Some(1)), |acc, multi_iter| { size_hint::mul(acc, multi_iter.iter.size_hint()) }); } // (MOD) Clippy warning about unnecessary `ref` destructuring of `MultiProductIter` // Removed redundant `&` and `ref` self.0.iter().fold( (0, Some(0)), |acc, MultiProductIter { iter, iter_orig, cur: _, }| { let cur_size = iter.size_hint(); let total_size = iter_orig.size_hint(); size_hint::add(size_hint::mul(acc, total_size), cur_size) }, ) } fn last(self) -> Option { let iter_count = self.0.len(); // (MOD) Replaced `itertools::Itertools::while_some()` // `std::iter::Iterator::filter_map()` does the same // thing in this case, and doesn't require the `Itertools` trait let lasts: Self::Item = self .0 .into_iter() .filter_map(|multi_iter| multi_iter.iter.last()) .collect(); if lasts.len() == iter_count { Some(lasts) } else { None } } } // (MOD) Copied two required functions and type alias // From itertools::size_hint module mod size_hint { /// `SizeHint` is the return type of `Iterator::size_hint()`. pub type SizeHint = (usize, Option); /// Add `SizeHint` correctly. #[inline] pub fn add(a: SizeHint, b: SizeHint) -> SizeHint { let min = a.0.saturating_add(b.0); let max = match (a.1, b.1) { (Some(x), Some(y)) => x.checked_add(y), _ => None, }; (min, max) } /// Multiply `SizeHint` correctly #[inline] pub fn mul(a: SizeHint, b: SizeHint) -> SizeHint { let low = a.0.saturating_mul(b.0); let hi = match (a.1, b.1) { (Some(x), Some(y)) => x.checked_mul(y), (Some(0), None) | (None, Some(0)) => Some(0), _ => None, }; (low, hi) } } test-case-3.3.1/crates/test-case-core/src/test_matrix/mod.rs000066400000000000000000000105031452574445500240020ustar00rootroot00000000000000use std::{iter, mem}; use proc_macro2::{Literal, Span}; use syn::{ parse::{Parse, ParseStream}, punctuated::Punctuated, spanned::Spanned, Expr, ExprLit, ExprRange, Lit, RangeLimits, Token, }; use crate::{comment::TestCaseComment, expr::TestCaseExpression, TestCase}; mod matrix_product; #[derive(Debug, Default)] pub struct TestMatrix { variables: Vec>, expression: Option, comment: Option, } impl TestMatrix { pub fn push_argument(&mut self, values: Vec) { self.variables.push(values); } pub fn cases(&self) -> impl Iterator { let expression = self.expression.clone(); let comment = self.comment.clone(); matrix_product::multi_cartesian_product(self.variables.iter().cloned()).map(move |v| { if let Some(comment) = comment.clone() { TestCase::new_with_prefixed_name( v, expression.clone(), comment.comment.value().as_ref(), ) } else { TestCase::new(v, expression.clone(), None) } }) } } impl Parse for TestMatrix { fn parse(input: ParseStream) -> syn::Result { let args: Punctuated = Punctuated::parse_separated_nonempty(input)?; let expression = (!input.is_empty()).then(|| input.parse()).transpose(); let comment = (!input.is_empty()).then(|| input.parse()).transpose(); // if both are errors, pick the expression error since it is more likely to be informative. // // TODO(https://github.com/frondeus/test-case/issues/135): avoid Result::ok entirely. let (expression, comment) = match (expression, comment) { (Err(expression), Err(_comment)) => return Err(expression), (expression, comment) => (expression.ok().flatten(), comment.ok().flatten()), }; let mut matrix = TestMatrix { expression, comment, ..Default::default() }; for arg in args { let values: Vec = match &arg { Expr::Array(v) => v.elems.iter().cloned().collect(), Expr::Tuple(v) => v.elems.iter().cloned().collect(), Expr::Range(ExprRange { start, limits, end, .. }) => { let start = isize_from_range_expr(limits.span(), start.as_deref())?; let end = isize_from_range_expr(limits.span(), end.as_deref())?; let range: Box> = match limits { RangeLimits::HalfOpen(_) => Box::from(start..end), RangeLimits::Closed(_) => Box::from(start..=end), }; range .map(|n| { let mut lit = Lit::new(Literal::isize_unsuffixed(n)); lit.set_span(arg.span()); Expr::from(ExprLit { lit, attrs: vec![] }) }) .collect() } v => iter::once(v.clone()).collect(), }; let mut value_literal_type = None; for expr in &values { if let Expr::Lit(ExprLit { lit, .. }) = expr { let first_literal_type = *value_literal_type.get_or_insert_with(|| mem::discriminant(lit)); if first_literal_type != mem::discriminant(lit) { return Err(syn::Error::new( lit.span(), "All literal values must be of the same type", )); } } } matrix.push_argument(values); } Ok(matrix) } } fn isize_from_range_expr(limits_span: Span, expr: Option<&Expr>) -> syn::Result { match expr { Some(Expr::Lit(ExprLit { lit: Lit::Int(n), .. })) => n.base10_parse(), Some(e) => Err(syn::Error::new( e.span(), "Range bounds can only be an integer literal", )), None => Err(syn::Error::new( limits_span, "Unbounded ranges are not supported", )), } } test-case-3.3.1/crates/test-case-core/src/utils.rs000066400000000000000000000055631452574445500220320ustar00rootroot00000000000000use proc_macro2::{Ident, Span}; use quote::ToTokens; pub fn escape_test_name(input: impl AsRef) -> Ident { if input.as_ref().is_empty() { return Ident::new("_empty", Span::call_site()); } let mut last_under = false; let mut ident: String = input .as_ref() .to_ascii_lowercase() .chars() .filter_map(|c| match c { c if c.is_alphanumeric() => { last_under = false; Some(c.to_ascii_lowercase()) } _ if !last_under => { last_under = true; Some('_') } _ => None, }) .collect(); if !ident.starts_with(|c: char| c == '_' || c.is_ascii_alphabetic()) { ident = format!("_{ident}"); } Ident::new(&ident, Span::call_site()) } pub fn fmt_syn(syn: &(impl ToTokens + Clone)) -> String { syn.clone().into_token_stream().to_string() } #[cfg(test)] mod tests { use super::*; mod escape_test_name { use super::*; #[test] fn converts_arbitrary_test_names() { assert_eq!( escape_test_name("word"), Ident::new("word", Span::call_site()) ); assert_eq!( escape_test_name("a simple sentence"), Ident::new("a_simple_sentence", Span::call_site()) ); assert_eq!( escape_test_name("extra spaces inbetween"), Ident::new("extra_spaces_inbetween", Span::call_site()) ); assert_eq!( escape_test_name(" extra end and start spaces "), Ident::new("_extra_end_and_start_spaces_", Span::call_site()) ); assert_eq!( escape_test_name("abcdefghijklmnoqprstuwvxyz1234567890"), Ident::new("abcdefghijklmnoqprstuwvxyz1234567890", Span::call_site()) ); } #[test] fn converts_to_lowercase() { assert_eq!( escape_test_name("ALL UPPER"), Ident::new("all_upper", Span::call_site()) ); assert_eq!( escape_test_name("MiXeD CaSe"), Ident::new("mixed_case", Span::call_site()) ); } #[test] fn handles_numeric_first_char() { assert_eq!( escape_test_name("1test"), Ident::new("_1test", Span::call_site()) ); } #[test] fn omits_unicode() { assert_eq!( escape_test_name("from⟶to"), Ident::new("from_to", Span::call_site()) ); } #[test] fn handles_empty_input() { assert_eq!( escape_test_name(""), Ident::new("_empty", Span::call_site()) ); } } } test-case-3.3.1/crates/test-case-macros/000077500000000000000000000000001452574445500200605ustar00rootroot00000000000000test-case-3.3.1/crates/test-case-macros/Cargo.toml000066400000000000000000000021211452574445500220040ustar00rootroot00000000000000[package] name = "test-case-macros" version = "3.3.1" edition = "2021" authors = ["Marcin Sas-Szymanski ", "Wojciech Polak ", "Łukasz Biel "] description = "Provides #[test_case(...)] procedural macro attribute for generating parametrized test cases easily" keywords = ["test", "case", "tests", "unit", "testing"] categories = ["development-tools", "development-tools::testing"] readme = "../../README.md" license = "MIT" repository = "https://github.com/frondeus/test-case" documentation = "https://docs.rs/test-case" [features] with-regex = ["test-case-core/with-regex"] [badges] maintenance = { status = "actively-developed" } [lib] doctest = false proc-macro = true path = "src/lib.rs" [dependencies] proc-macro2 = { version = "1.0", features = [] } quote = "1.0" syn = { version = "2.0", features = ["full", "extra-traits", "parsing"] } test-case-core = { version = "3.2.1", path = "../test-case-core", default-features = false } test-case-3.3.1/crates/test-case-macros/LICENSE000077700000000000000000000000001452574445500225132../../LICENSEustar00rootroot00000000000000test-case-3.3.1/crates/test-case-macros/src/000077500000000000000000000000001452574445500206475ustar00rootroot00000000000000test-case-3.3.1/crates/test-case-macros/src/lib.rs000066400000000000000000000121021452574445500217570ustar00rootroot00000000000000extern crate proc_macro; use proc_macro::TokenStream; use proc_macro2::Span as Span2; use syn::{parse_macro_input, ItemFn, Path}; use quote::quote; use syn::parse_quote; use syn::spanned::Spanned; use test_case_core::{TestCase, TestMatrix}; /// Generates tests for given set of data /// /// In general, test case consists of four elements: /// /// 1. _(Required)_ Arguments passed to test body /// 2. _(Optional)_ Expected result /// 3. _(Optional)_ Test case description /// 4. _(Required)_ Test body /// /// When _expected result_ is provided, it is compared against the actual value generated with _test body_ using `assert_eq!`. /// _Test cases_ that don't provide _expected result_ should contain custom assertions within _test body_ or return `Result` similar to `#[test]` macro. #[proc_macro_attribute] pub fn test_case(args: TokenStream, input: TokenStream) -> TokenStream { let test_case = parse_macro_input!(args as TestCase); let mut item = parse_macro_input!(input as ItemFn); let mut test_cases = vec![(test_case, Span2::call_site())]; match expand_additional_test_case_macros(&mut item) { Ok(cases) => test_cases.extend(cases), Err(err) => return err.into_compile_error().into(), } render_test_cases(&test_cases, item) } /// Generates tests for the cartesian product of a given set of data /// /// A test matrix consists of four elements: /// /// 1. _(Required)_ Sets of values to combine; the number of sets must be the same as the number of /// arguments to the test body function /// 2. _(Optional)_ Expected result (for all combinations of values) /// 3. _(Optional)_ Test case description (applied as a prefix the generated name of the test) /// 4. _(Required)_ Test body /// /// _Expected result_ and _Test body_ are the same as they are for the singular `#[test_case(...)]` /// macro but are applied to every case generated by `#[test_matrix(...)]`. #[proc_macro_attribute] pub fn test_matrix(args: TokenStream, input: TokenStream) -> TokenStream { let matrix = parse_macro_input!(args as TestMatrix); let mut item = parse_macro_input!(input as ItemFn); let mut test_cases = expand_test_matrix(&matrix, Span2::call_site()); match expand_additional_test_case_macros(&mut item) { Ok(cases) => test_cases.extend(cases), Err(err) => return err.into_compile_error().into(), } render_test_cases(&test_cases, item) } fn expand_test_matrix(matrix: &TestMatrix, span: Span2) -> Vec<(TestCase, Span2)> { matrix.cases().map(|c| (c, span)).collect() } fn expand_additional_test_case_macros(item: &mut ItemFn) -> syn::Result> { let mut additional_cases = vec![]; let mut attrs_to_remove = vec![]; let legal_test_case_names: [Path; 4] = [ parse_quote!(test_case), parse_quote!(test_case::test_case), parse_quote!(test_case::case), parse_quote!(case), ]; let legal_test_matrix_names: [Path; 2] = [ parse_quote!(test_matrix), parse_quote!(test_case::test_matrix), ]; for (idx, attr) in item.attrs.iter().enumerate() { if legal_test_case_names.contains(attr.path()) { let test_case = match attr.parse_args::() { Ok(test_case) => test_case, Err(err) => { return Err(syn::Error::new( attr.span(), format!("cannot parse test_case arguments: {err}"), )) } }; additional_cases.push((test_case, attr.span())); attrs_to_remove.push(idx); } else if legal_test_matrix_names.contains(attr.path()) { let test_matrix = match attr.parse_args::() { Ok(test_matrix) => test_matrix, Err(err) => { return Err(syn::Error::new( attr.span(), format!("cannot parse test_matrix arguments: {err}"), )) } }; additional_cases.extend(expand_test_matrix(&test_matrix, attr.span())); attrs_to_remove.push(idx); } } for i in attrs_to_remove.into_iter().rev() { item.attrs.swap_remove(i); } Ok(additional_cases) } #[allow(unused_mut)] fn render_test_cases(test_cases: &[(TestCase, Span2)], mut item: ItemFn) -> TokenStream { let mut rendered_test_cases = vec![]; for (test_case, span) in test_cases { rendered_test_cases.push(test_case.render(item.clone(), *span)); } let mod_name = item.sig.ident.clone(); // We don't want any external crate to alter main fn code, we are passing attributes to each sub-function anyway item.attrs.retain(|attr| { attr.path() .get_ident() .map(|ident| ident == "allow") .unwrap_or(false) }); let output = quote! { #[allow(unused_attributes)] #item #[cfg(test)] mod #mod_name { #[allow(unused_imports)] use super::*; #(#rendered_test_cases)* } }; output.into() } test-case-3.3.1/scripts/000077500000000000000000000000001452574445500151145ustar00rootroot00000000000000test-case-3.3.1/scripts/publish.sh000077500000000000000000000023161452574445500171230ustar00rootroot00000000000000#!/usr/bin/env bash # Publish a new version of the crate. # # Dependencies: # - cargo-get # - nvim SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) REPO_DIR="${SCRIPT_DIR}/.." CURRENT_DIR=$(pwd) cd "${REPO_DIR}" set -eo xtrace # Read current version from the Cargo.toml file CURRENT_VERSION=$(cargo get package.version) echo "Current version: ${CURRENT_VERSION}" read -p 'New version: ' NEW_VERSION # Update version in Cargo.toml files sed -i '' "s/version = \"${CURRENT_VERSION}\"/version = \"${NEW_VERSION}\"/g" Cargo.toml sed -i '' "s/version = \"${CURRENT_VERSION}\"/version = \"${NEW_VERSION}\"/g" crates/test-case-macros/Cargo.toml sed -i '' "s/version = \"${CURRENT_VERSION}\"/version = \"${NEW_VERSION}\"/g" crates/test-case-core/Cargo.toml # Validate the release rustup update ./scripts/test_all.sh # Update README if needed cargo readme > README.md # Add changelog entry nvim CHANGELOG.md # Push to github git add . git commit git push origin set +o xtrace echo "Next step: Wait for CI" echo "Next step: \`git tag vX.Y.Z; git push --tags\`" echo "Next step: Create release in Github" echo "Next step: \`cargo publish\`" cd "${CURRENT_DIR}" test-case-3.3.1/scripts/test_all.sh000077500000000000000000000005371452574445500172670ustar00rootroot00000000000000#!/usr/bin/env bash set -e cargo clean cargo +nightly clippy --all-targets --all-features -- -D warnings cargo +nightly fmt --all find . -name 'target' | xargs rm -rf SNAPSHOT_DIR=rust-stable cargo +stable test --workspace --all-features find . -name 'target' | xargs rm -rf SNAPSHOT_DIR=rust-nightly cargo +nightly test --workspace --all-features test-case-3.3.1/src/000077500000000000000000000000001452574445500142145ustar00rootroot00000000000000test-case-3.3.1/src/lib.rs000066400000000000000000000061451452574445500153360ustar00rootroot00000000000000//! # Overview //! `test_case` crate provides procedural macro attribute that generates parametrized test instances. //! //! # Getting Started //! //! Crate has to be added as a dependency to `Cargo.toml`: //! //! ```toml //! [dev-dependencies] //! test-case = "*" //! ``` //! //! and imported to the scope of a block where it's being called //! (since attribute name collides with rust's built-in `custom_test_frameworks`) via: //! //! ```rust //! use test_case::test_case; //! ``` //! //! # Example usage: //! //! ```rust //! #[cfg(test)] //! mod tests { //! use test_case::test_case; //! //! #[test_case(-2, -4 ; "when both operands are negative")] //! #[test_case(2, 4 ; "when both operands are positive")] //! #[test_case(4, 2 ; "when operands are swapped")] //! fn multiplication_tests(x: i8, y: i8) { //! let actual = (x * y).abs(); //! //! assert_eq!(8, actual) //! } //! } //! ``` //! //! Output from `cargo test` for this example: //! //! ```sh //! $ cargo test //! //! running 4 tests //! test tests::multiplication_tests::when_both_operands_are_negative ... ok //! test tests::multiplication_tests::when_both_operands_are_positive ... ok //! test tests::multiplication_tests::when_operands_are_swapped ... ok //! //! test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out //! ``` //! //! ## Test Matrix //! //! The `#[test_matrix(...)]` macro allows generating multiple test cases from the //! Cartesian product of one or more possible values for each test function argument. The //! number of arguments to the `test_matrix` macro must be the same as the number of arguments to //! the test function. Each macro argument can be: //! //! 1. A list in array (`[x, y, ...]`) or tuple (`(x, y, ...)`) syntax. The values can be any //! valid [expression](https://doc.rust-lang.org/reference/expressions.html). //! 2. A closed numeric range expression (e.g. `0..100` or `1..=99`), which will generate //! argument values for all integers in the range. //! 3. A single expression, which can be used to keep one argument constant while varying the //! other test function arguments using a list or range. //! //! ### Example usage: //! //! ```rust //! #[cfg(test)] //! mod tests { //! use test_case::test_matrix; //! //! #[test_matrix( //! [-2, 2], //! [-4, 4] //! )] //! fn multiplication_tests(x: i8, y: i8) { //! let actual = (x * y).abs(); //! //! assert_eq!(8, actual) //! } //! } //! ``` //! //! # MSRV Policy //! //! Starting with version 3.0 and up `test-case` introduces policy of only supporting latest stable Rust. //! These changes may happen overnight, so if your stack is lagging behind current stable release, //! it may be best to consider locking `test-case` version with `=` in your `Cargo.toml`. //! //! # Documentation //! //! Most up to date documentation is available in our [wiki](https://github.com/frondeus/test-case/wiki). pub use test_case_macros::test_case; pub use test_case_macros::test_case as case; pub use test_case_macros::test_matrix; #[cfg(feature = "with-regex")] pub use regex::*; test-case-3.3.1/tests/000077500000000000000000000000001452574445500145675ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/000077500000000000000000000000001452574445500200335ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/allow_stays_on_fn/000077500000000000000000000000001452574445500235535ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/allow_stays_on_fn/Cargo.toml000066400000000000000000000004311452574445500255010ustar00rootroot00000000000000### # Ensure that `#[allow(...)]` is propagated to the test function. ### [package] name = "allow_stays_on_fn" version = "0.1.0" edition = "2021" [lib] name = "allow_stays_on_fn" path = "src/lib.rs" doctest = false [dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/allow_stays_on_fn/src/000077500000000000000000000000001452574445500243425ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/allow_stays_on_fn/src/lib.rs000066400000000000000000000002061452574445500254540ustar00rootroot00000000000000#![deny(unused_variables)] use test_case::test_case; #[test_case(42)] #[allow(unused_variables)] fn allow_stays_on_fn(value: u32) {}test-case-3.3.1/tests/acceptance_cases/cases_can_be_declared_on_async_methods/000077500000000000000000000000001452574445500276575ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_be_declared_on_async_methods/Cargo.toml000066400000000000000000000010071452574445500316050ustar00rootroot00000000000000### # Ensure that tests can be ran in tandem with `#[tokio::test]` and `#[async_std::test]`. ### [package] name = "async_tests" version = "0.1.0" authors = ["Łukasz Biel "] edition = "2021" [lib] name = "async" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } tokio = { version = "=1.32.0", features = [ "macros", "rt" ] } async-std = { version = "=1.12.0", features = ["attributes"] } async-attributes = "=1.1.2" once_cell = "=1.18.0" [workspace] test-case-3.3.1/tests/acceptance_cases/cases_can_be_declared_on_async_methods/src/000077500000000000000000000000001452574445500304465ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_be_declared_on_async_methods/src/lib.rs000066400000000000000000000004641452574445500315660ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; #[test_case(100i32 => 100usize)] #[tokio::test] async fn works_seamlessly_with_tokio(arg: i32) -> usize { arg as usize } #[test_case(100i32 => 100usize)] #[async_std::test] async fn works_seamlessly_with_async_std(arg: i32) -> usize { arg as usize } test-case-3.3.1/tests/acceptance_cases/cases_can_be_declared_on_non_test_items/000077500000000000000000000000001452574445500300515ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_be_declared_on_non_test_items/Cargo.toml000066400000000000000000000005141452574445500320010ustar00rootroot00000000000000### # Ensure that test cases can be declared outsie of #[cfg(test)] modules. ### [package] name = "cases_can_be_declared_on_non_test_items" version = "0.1.0" edition = "2021" [lib] name = "cases_can_be_declared_on_non_test_items" path = "src/lib.rs" doctest = false [dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_can_be_declared_on_non_test_items/src/000077500000000000000000000000001452574445500306405ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_be_declared_on_non_test_items/src/lib.rs000066400000000000000000000013641452574445500317600ustar00rootroot00000000000000pub fn normal_public_function(value: i32) -> i32 { internal_tested_function1(value) * internal_tested_function2(value) * internal_tested_function3(value) * internal_tested_function4(value) } #[test_case::test_case(2 => 4)] #[test_case::test_case(3 => 6)] fn internal_tested_function1(value: i32) -> i32 { if value == 3 { 0 } else { value * 2 } } use test_case::test_case; #[test_case(1 => 0)] fn internal_tested_function2(value: i32) -> i32 { value / 2 } #[test_case(1 => matches 3)] #[test_case(2 => inconclusive 6)] fn internal_tested_function3(value: i32) -> i32 { value + 2 } #[test_case(2 => panics "Can't")] fn internal_tested_function4(_value: i32) -> i32 { panic!("Can't") } test-case-3.3.1/tests/acceptance_cases/cases_can_be_declared_on_non_test_items/src/main.rs000066400000000000000000000002041452574445500321260ustar00rootroot00000000000000use cases_can_be_declared_on_non_test_items::normal_public_function; fn main() { println!("{}", normal_public_function(12)); } test-case-3.3.1/tests/acceptance_cases/cases_can_be_ignored/000077500000000000000000000000001452574445500241275ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_be_ignored/Cargo.toml000066400000000000000000000004111452574445500260530ustar00rootroot00000000000000### # Ensure that `=> ignore` syntax works. ### [package] name = "cases_can_be_ignored" version = "0.1.0" edition = "2021" [lib] name = "cases_can_be_ignored" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_can_be_ignored/src/000077500000000000000000000000001452574445500247165ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_be_ignored/src/lib.rs000066400000000000000000000012071452574445500260320ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; #[test_case(() => inconclusive ())] #[test_case(() => inconclusive (); "test is not ran")] #[test_case(() => inconclusive (); "inconclusive test")] #[test_case(() => ignore (); "ignore keyword")] fn inconclusives(_: ()) { unreachable!() } #[test_case(1 => ignore)] #[test_case(2 => ignore)] fn ignore_void(input: u8) { assert_eq!(input, 1) } #[test_case(() => inconclusive["reason but no comment"] ())] #[test_case(() => inconclusive["reason and comment"] (); "test is not run")] #[test_case(() => ignore["reason and comment"] (); "ignore keyword")] fn descriptions(_: ()) { unreachable!() } test-case-3.3.1/tests/acceptance_cases/cases_can_panic/000077500000000000000000000000001452574445500231245ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_panic/Cargo.toml000066400000000000000000000004471452574445500250610ustar00rootroot00000000000000### # Ensure that `panics` syntax anh `#[should_panic]` macro works. ### [package] name = "cases_can_panic" version = "0.1.0" edition = "2021" [dependencies] [lib] name = "cases_can_panic" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_can_panic/src/000077500000000000000000000000001452574445500237135ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_panic/src/lib.rs000066400000000000000000000013351452574445500250310ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; #[derive(Debug, PartialEq)] #[allow(dead_code)] enum SimpleEnum { Var1, Var2, } #[should_panic(expected = "Expected `SimpleEnum :: Var2` found Var1")] #[test_case(SimpleEnum::Var1 => matches SimpleEnum::Var2)] fn pattern_matching_result_fails(e: SimpleEnum) -> SimpleEnum { e } #[test_case(() => panics "It has to panic")] #[test_case(() => panics "This should fail")] fn panicking(_: ()) { panic!("It has to panic") } #[test_case(() => panics)] fn panics_without_value(_: ()) { panic!("Message doesn't matter") } #[test_case(2, 2 => 2 + 3)] #[should_panic(expected = "assertion failed: `(left == right)`")] fn result_which_panics(x: u32, y: u32) -> u32 { x + y } test-case-3.3.1/tests/acceptance_cases/cases_can_return_result/000077500000000000000000000000001452574445500247475ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_return_result/Cargo.toml000066400000000000000000000004401452574445500266750ustar00rootroot00000000000000### # Ensure that test cases automatically assert return values. ### [package] name = "cases_can_return_result" version = "0.1.0" edition = "2021" [lib] name = "cases_can_return_result" path = "src/lib.rs" doctest = false [dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_can_return_result/src/000077500000000000000000000000001452574445500255365ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_return_result/src/lib.rs000066400000000000000000000013601452574445500266520ustar00rootroot00000000000000#![cfg(test)] use std::error::Error; use test_case::test_case; #[test_case(12)] #[test_case(13)] fn is_even(value: u64) -> Result<(), String> { if value % 2 == 0 { Ok(()) } else { Err("is odd".to_string()) } } #[test_case(12)] #[test_case(13)] fn is_odd_boxed(value: u64) -> Result<(), Box> { if value % 2 == 1 { Ok(()) } else { Err("is even".to_string().into()) } } #[test_case(12 => panics)] #[test_case(13 => panics "with text")] fn panics_supported(_value: u64) -> Result<(), Box> { panic!("with text") } #[test_case(12 => ignore matches Ok(_))] // `(12 => ignore)` is not supported fn ignore_supported(_value: u64) -> Result<(), Box> { todo!() } test-case-3.3.1/tests/acceptance_cases/cases_can_use_regex/000077500000000000000000000000001452574445500240205ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_use_regex/Cargo.toml000066400000000000000000000003721452574445500257520ustar00rootroot00000000000000### # Ensure that `with-regex` feature allows to use `is matching_regex` syntax. ### [package] name = "cases_can_use_regex" version = "0.1.0" edition = "2021" [dependencies] test-case = { path = "../../../", features = ["with-regex"]} [workspace] test-case-3.3.1/tests/acceptance_cases/cases_can_use_regex/src/000077500000000000000000000000001452574445500246075ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_can_use_regex/src/lib.rs000066400000000000000000000006441452574445500257270ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; #[test_case("abcabc" => is matching_regex r#"abc"#)] #[test_case("abcabc201" => is matching_regex r#"\d"#)] #[test_case("abcabc201" => is matching_regex r#"\d{4}"#)] #[test_case("kumkwat" => is matching_regex r#"abc"#)] #[test_case("kumkwat" => is matching_regex r#"\"#)] #[test_case("kumkwat" => it matches_regex r#"^kumkwat$"#)] fn regex_test(text: &str) -> &str { text } test-case-3.3.1/tests/acceptance_cases/cases_support_basic_features/000077500000000000000000000000001452574445500257645ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_basic_features/Cargo.toml000066400000000000000000000005161452574445500277160ustar00rootroot00000000000000### # Ensure basic test case functionality. ### [package] name = "cases_support_basic_features" version = "0.1.0" authors = ["Łukasz Biel "] edition = "2021" [lib] name = "cases_support_basic_features" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_support_basic_features/src/000077500000000000000000000000001452574445500265535ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_basic_features/src/lib.rs000066400000000000000000000061031452574445500276670ustar00rootroot00000000000000#[cfg(test)] mod test_cases { use test_case::test_case; #[test_case(2)] #[test_case(4)] fn multiple_test_cases(x: u32) { assert!(x < 10) } #[test_case(1)] fn basic_test(x: u32) { assert_eq!(x, 1) } #[test_case("foo")] fn impl_trait(x: impl AsRef) { assert_eq!("foo", x.as_ref()); } #[test_case(2 => 4)] #[test_case(4 => 8)] fn result(x: u32) -> u32 { x * 2 } #[test_case(1, 8 ; "test 1 + 8 = 9")] #[test_case(2, 7 ; "2nd test")] #[test_case(3, 6 ; "test_3_+6_=_9")] #[test_case(4, 5)] fn name(x: u32, y: u32) { assert_eq!(9, x + y) } #[test_case(1, 2 => 3 ; "test no. 1")] #[test_case(4, 5 => 9)] fn result_and_name(x: u32, y: u32) -> u32 { x + y } #[test_case(true)] fn keyword_test(x: bool) { assert!(x) } #[test_case(2 + 4, "6".to_string())] fn arg_expressions(x: u32, expected: String) { assert_eq!(expected, x.to_string()) } #[test_case(2, 2 => 2 + 2)] fn result_expression(x: u32, y: u32) -> u32 { x + y } #[test_case(2, 2 => 2 + 2 ; "test result expression")] fn result_expresion_with_name(x: u32, y: u32) -> u32 { x + y } fn foo() -> u32 { 42 } #[test_case("dummy")] fn leading_underscore_in_test_name(x: &str) { assert_eq!("dummy", x) } #[test_case("DUMMY_CODE")] fn lowercase_test_name(x: &str) { assert_eq!("DUMMY_CODE", x) } mod nested { use super::*; use test_case::test_case; #[test_case(1, 1)] fn nested_test_case(x: u32, y: u32) { assert_eq!(x, y) } #[test_case(20 + 22)] #[test_case(42)] fn using_fn_from_super(x: u32) { assert_eq!(foo(), x) } } #[test_case(42 => std::string::String::new())] fn result_with_mod_sep(_: i8) -> String { "".to_string() } // tests from documentation #[test_case( 2 => 2 ; "returns given number for positive input")] #[test_case(-2 => 2 ; "returns opposite number for non-positive input")] #[test_case( 0 => 0 ; "returns 0 for 0")] fn abs_tests(x: i8) -> i8 { if x > 0 { x } else { -x } } #[test_case(None, None => 0 ; "treats none as 0")] #[test_case(Some(2), Some(3) => 5)] #[test_case(Some(2 + 3), Some(4) => 2 + 3 + 4)] fn fancy_addition(x: Option, y: Option) -> i8 { x.unwrap_or(0) + y.unwrap_or(0) } #[test_case( 2, 4 ; "when both operands are possitive")] #[test_case( 4, 2 ; "when operands are swapped")] #[test_case(-2, -4 ; "when both operands are negative")] fn multiplication_tests(x: i8, y: i8) { let actual = x * y; assert_eq!(8, actual); } const MY_CONST: &str = "my const"; #[test_case(MY_CONST ; "this is desc, not an argument")] fn const_in_arg(_s: &str) {} #[test_case("" => String::default())] fn bar(_: &str) -> String { String::default() } } test-case-3.3.1/tests/acceptance_cases/cases_support_complex_assertions/000077500000000000000000000000001452574445500267265ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_complex_assertions/Cargo.toml000066400000000000000000000004251452574445500306570ustar00rootroot00000000000000### # Ensure `it` syntax works. ### [package] name = "cases_support_complex_assertions" version = "0.1.0" edition = "2021" [lib] name = "cases_support_complex_assertions" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_support_complex_assertions/src/000077500000000000000000000000001452574445500275155ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_complex_assertions/src/lib.rs000066400000000000000000000071471452574445500306420ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; #[test_case(1.0 => is equal_to 2.0 ; "eq1")] #[test_case(1.0 => is eq 2.0 ; "eq2")] #[test_case(1.0 => is less_than 3.0 ; "lt1")] #[test_case(1.0 => is lt 3.0 ; "lt2")] #[test_case(1.0 => is greater_than 0.0 ; "gt1")] #[test_case(1.0 => is gt 0.0 ; "gt2")] #[test_case(1.0 => is less_or_equal_than 2.0 ; "leq1")] #[test_case(1.0 => is leq 2.0 ; "leq2")] #[test_case(1.0 => is greater_or_equal_than 1.0 ; "geq1")] #[test_case(1.0 => is geq 1.0 ; "geq2")] #[test_case(1.0 => is almost_equal_to 2.1 precision 0.15 ; "almost_eq1")] #[test_case(1.0 => is almost 2.0 precision 0.01 ; "almost_eq2")] fn complex_tests(input: f64) -> f64 { input * 2.0 } #[test_case("Cargo.toml" => is existing_path)] #[test_case("src/lib.rs" => is file)] #[test_case("src/" => is dir ; "short_dir")] #[test_case("src/" => is directory ; "long_dir")] fn create_path(val: &str) -> std::path::PathBuf { std::path::PathBuf::from(val) } #[test_case(vec![1, 2, 3, 4] => it contains 1)] #[test_case(vec![1, 2, 3, 4] => it contains_in_order [3, 4])] fn contains_tests(items: Vec) -> Vec { items } #[test_case(1.0 => is not eq 2.5)] #[test_case(1.0 => is not almost 2.1 precision 0.01)] fn not_complex(input: f32) -> f32 { input * 1.0 } #[test_case("Cargo.yaml".parse().unwrap() => is not existing_path)] #[test_case("Cargo.toml".parse().unwrap() => is not dir)] #[test_case("src/".parse().unwrap() => is not file)] fn not_path(path: std::path::PathBuf) -> String { path.to_string_lossy().to_string() } #[test_case(vec![1, 2, 3, 4] => it not contains 5)] #[test_case(vec![1, 2, 3, 4] => it not contains_in_order [3, 2])] fn not_contains_tests(items: Vec) -> Vec { items } #[test_case(2.0 => it (eq 2.0))] fn in_parens(_: f32) -> f32 { 2.0 } #[test_case(1.0 => is gt 0.0 and lt 5.0)] #[test_case(1.0 => is gt 0.0 or lt 0.0)] #[test_case(-2.0 => is gt 0.0 or lt 0.0)] #[test_case(-2.0 => is (gt 0.0 or lt 0.0) and lt -1.0)] #[test_case(1.0 => is (gt 0.0 or lt -1.5) and lt 2.0)] #[test_case(0.3 => is (gt 0.0 and lt 1.0) or gt 1.2)] #[test_case(0.7 => is (gt 0.0 and lt 1.0) or gt 1.2)] fn combinators(v: f32) -> f32 { v * 2.0 } #[test_case(vec![1, 2, 3] => it contains 1 and contains 2 and contains_in_order [2, 3])] #[test_case(vec![1, 2, 3] => it contains 1 or contains 4)] #[test_case(vec![1, 2, 3] => it (contains 1 or contains 4) and contains 2)] #[test_case(vec![1, 2, 3] => it (contains 1 and contains 3) or contains 5)] #[test_case(vec![1, 2, 3] => it (contains 6 and contains 7) or contains 1)] #[test_case(vec![1, 2, 3] => it (contains 6 and contains 7) or (contains 1 and contains_in_order [1, 2, 3]))] fn combinators_with_arrays(a: Vec) -> Vec { a } #[test_case(vec![0, 1, 3] => is len 3)] #[test_case(vec![0, 1] => it has_length 2)] fn len_vec(v: Vec) -> Vec { v } #[test_case("abc" => is len 3)] #[test_case("ab" => it has_length 2)] fn len_str(v: &str) -> &str { v } #[test_case("abc" => is len 3)] #[test_case("ab" => it has_length 2)] fn len_string(v: &str) -> String { v.to_string() } #[test_case(b"abc" => is len 3)] #[test_case(b"ab" => it has_length 2)] fn len_byte_str(v: &[u8]) -> &[u8] { v } #[test_case(vec![0, 1, 3] => is count 3)] #[test_case(vec![0, 1] => it has_count 2)] fn count_vec(v: Vec) -> Vec { v } #[test_case(vec![0, 1, 3] => is count 3)] #[test_case("abcd".chars() => is count 4)] #[test_case(std::iter::once(2) => is count 1)] fn count_general(v: impl IntoIterator) -> impl IntoIterator { v } #[test_case(vec![0] => is empty)] #[test_case(vec![] => is empty)] fn empty(v: Vec) -> Vec { v } test-case-3.3.1/tests/acceptance_cases/cases_support_generics/000077500000000000000000000000001452574445500246045ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_generics/Cargo.toml000066400000000000000000000004641452574445500265400ustar00rootroot00000000000000### # Ensure that cases can be ran against test functions with generic parameters. ### [package] name = "cases_support_generics" version = "0.1.0" edition = "2021" [lib] name = "cases_support_generics" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_support_generics/src/000077500000000000000000000000001452574445500253735ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_generics/src/lib.rs000066400000000000000000000011201452574445500265010ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; struct Target { i: i64 } struct Source1; struct Source2; impl From for Target { fn from(_: Source1) -> Self { Self { i: 1 } } } impl From for Target { fn from(_: Source2) -> Self { Self { i: 2 } } } #[test_case(Source1 => 1)] #[test_case(Source2 => 2)] fn test_generics>(input: T) -> i64 { let t: Target = input.into(); t.i } #[test_case(Source1 => 1)] #[test_case(Source2 => 2)] fn test_impl(input: impl Into) -> i64 { let t: Target = input.into(); t.i } test-case-3.3.1/tests/acceptance_cases/cases_support_keyword_using/000077500000000000000000000000001452574445500256765ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_keyword_using/Cargo.toml000066400000000000000000000004601452574445500276260ustar00rootroot00000000000000### # Ensure that `using` syntax works. ### [package] name = "cases_support_keyword_using" version = "0.1.0" edition = "2021" [lib] name = "cases_support_keyword_using" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } pretty_assertions = "=1.2.1" [workspace] test-case-3.3.1/tests/acceptance_cases/cases_support_keyword_using/src/000077500000000000000000000000001452574445500264655ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_keyword_using/src/lib.rs000066400000000000000000000012161452574445500276010ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; pub fn assert_is_power_of_two(input: u64) { assert!(input.is_power_of_two()) } mod some_mod { pub use super::assert_is_power_of_two; } #[test_case(1 => using assert_is_power_of_two)] #[test_case(2 => using crate::assert_is_power_of_two)] #[test_case(4 => using some_mod::assert_is_power_of_two)] fn power_of_two_with_using(input: u64) -> u64 { input } fn wrapped_pretty_assert(expected: u64) -> impl Fn(u64) { move |actual: u64| { pretty_assertions::assert_eq!(actual, expected) } } #[test_case(1 => using wrapped_pretty_assert(1))] fn pretty_assertions_usage(input: u64) -> u64 { input } test-case-3.3.1/tests/acceptance_cases/cases_support_keyword_with/000077500000000000000000000000001452574445500255245ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_keyword_with/Cargo.toml000066400000000000000000000004201452574445500274500ustar00rootroot00000000000000### # Ensure that `with` syntax works. ### [package] name = "cases_support_keyword_with" version = "0.1.0" edition = "2021" [lib] name = "cases_support_keyword_with" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_support_keyword_with/src/000077500000000000000000000000001452574445500263135ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_keyword_with/src/lib.rs000066400000000000000000000003501452574445500274250ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; #[test_case(1.0 => with |v: f64| assert!(v.is_infinite()))] #[test_case(0.0 => with |v: f64| assert!(v.is_nan()))] fn divide_by_zero_f64_with_lambda(input: f64) -> f64 { input / 0.0f64 } test-case-3.3.1/tests/acceptance_cases/cases_support_multiple_calling_methods/000077500000000000000000000000001452574445500300545ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_multiple_calling_methods/Cargo.toml000066400000000000000000000004761452574445500320130ustar00rootroot00000000000000### # Ensure that all aliases of test case macro are usable. ### [package] name = "cases_support_multiple_calling_methods" version = "0.1.0" edition = "2021" [lib] name = "cases_support_multiple_calling_methods" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_support_multiple_calling_methods/src/000077500000000000000000000000001452574445500306435ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_multiple_calling_methods/src/lib.rs000066400000000000000000000010411452574445500317530ustar00rootroot00000000000000#![cfg(test)] mod import { use test_case::test_case; #[test_case(2)] fn can_import_test_case_attribute(_: u8) {} } mod short_version { use test_case::case; #[case(12u8 => 12u16)] #[case(8u8 => 8u16)] fn can_use_case_attribute_same_as_test_case(i: u8) -> u16 { i as u16 } } #[test_case::test_case(1; "first test")] #[test_case::test_case(1; "second test")] fn can_use_fully_qualified_test_case_path(_: u8) {} #[test_case::case(2)] #[test_case::case(3)] fn can_use_fully_qualified_case_path(_: u8) {} test-case-3.3.1/tests/acceptance_cases/cases_support_pattern_matching/000077500000000000000000000000001452574445500263345ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_pattern_matching/Cargo.toml000066400000000000000000000004331452574445500302640ustar00rootroot00000000000000### # Ensure that `matches` syntax works. ### [package] name = "cases_support_pattern_matching" version = "0.1.0" edition = "2021" [lib] name = "cases_support_pattern_matching" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/cases_support_pattern_matching/src/000077500000000000000000000000001452574445500271235ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/cases_support_pattern_matching/src/lib.rs000066400000000000000000000013461452574445500302430ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; #[derive(Debug, PartialEq)] #[allow(dead_code)] enum SimpleEnum { Var1, Var2, } #[test_case(SimpleEnum::Var2 => matches SimpleEnum::Var2)] fn pattern_matching_result(e: SimpleEnum) -> SimpleEnum { e } #[test_case(SimpleEnum::Var1 => matches Ok(e) if e == SimpleEnum::Var1)] #[test_case(SimpleEnum::Var1 => matches Ok(e) if e == SimpleEnum::Var2; "ok should fail")] #[test_case(SimpleEnum::Var2 => matches Err(e) if e == "var2")] #[test_case(SimpleEnum::Var2 => matches Err(e) if e == "var1"; "err should fail")] fn extended_pattern_matching_result(e: SimpleEnum) -> Result { if e == SimpleEnum::Var1 { Ok(e) } else { Err("var2") } } test-case-3.3.1/tests/acceptance_cases/features_produce_human_readable_errors/000077500000000000000000000000001452574445500277755ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/features_produce_human_readable_errors/Cargo.toml000066400000000000000000000004451452574445500317300ustar00rootroot00000000000000### # Ensure that when missing a `feature` flag in Cargo.toml file, the error message is human readable. ### [package] name = "features_produce_human_readable_errors" version = "0.1.0" edition = "2021" [dependencies] test-case = { path = "../../../", default-features = false } [workspace] test-case-3.3.1/tests/acceptance_cases/features_produce_human_readable_errors/src/000077500000000000000000000000001452574445500305645ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/features_produce_human_readable_errors/src/lib.rs000066400000000000000000000002341452574445500316770ustar00rootroot00000000000000#![cfg(test)] use test_case::test_case; #[test_case(2 => is matching_regex "abc")] fn fail_on_missing_with_regex_feature(_: u8) -> String { todo!() } test-case-3.3.1/tests/acceptance_cases/matrices_compilation_errors/000077500000000000000000000000001452574445500256345ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/matrices_compilation_errors/Cargo.toml000066400000000000000000000004731452574445500275700ustar00rootroot00000000000000### # Ensure that matrix syntax produces human readable errors. ### [package] name = "matrices_compilation_errors" version = "0.1.0" edition = "2021" [dependencies] [lib] name = "matrices_compilation_errors" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/matrices_compilation_errors/src/000077500000000000000000000000001452574445500264235ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/matrices_compilation_errors/src/lib.rs000066400000000000000000000011661452574445500275430ustar00rootroot00000000000000#![cfg(test)] use test_case::test_matrix; #[test_matrix( ["one", 1, true,] )] fn mixed_literals(x: u32) { unreachable!("Should never compile") } const END: u32 = 1; #[test_matrix(1..END)] fn non_literal_range(x: u32) { unreachable!("Should never compile") } #[test_matrix(0..9_223_372_036_854_775_808)] fn range_outside_isize_bounds(x: u32) { unreachable!("Should never compile") } #[test_matrix(1..)] fn unbounded_range(x: u32) { unreachable!("Should never compile") } const USIZE_CONST: usize = 0; #[test_matrix(USIZE_CONST)] fn wrong_argument_type(x: i8) { unreachable!("Should never compile") } test-case-3.3.1/tests/acceptance_cases/matrices_support_basic_features/000077500000000000000000000000001452574445500264755ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/matrices_support_basic_features/Cargo.toml000066400000000000000000000005731452574445500304320ustar00rootroot00000000000000### # Ensure that `matrix` syntax works. ### [package] name = "matrices_support_basic_features" version = "0.1.0" authors = ["Łukasz Biel ", "Ross Williams "] edition = "2021" [lib] name = "matrices_support_basic_features" path = "src/lib.rs" doctest = false [dev-dependencies] test-case = { path = "../../../" } [workspace] test-case-3.3.1/tests/acceptance_cases/matrices_support_basic_features/src/000077500000000000000000000000001452574445500272645ustar00rootroot00000000000000test-case-3.3.1/tests/acceptance_cases/matrices_support_basic_features/src/lib.rs000066400000000000000000000047601452574445500304070ustar00rootroot00000000000000#[cfg(test)] mod test_cases { use test_case::{test_case, test_matrix}; #[test_matrix( [1, 2], [11, 12] )] fn numeric_values_array(x: u32, y: u32) { assert!(x < 10); assert!(y > 10); } #[test_matrix( 1..10, [11, 12] )] fn matrix_with_range(x: u32, y: u32) { assert!(x < 10); assert!(y > 10); } #[test_matrix( ("one", "two"), ("yellow", "blue") )] fn str_values_tuple(a: &str, b: &str) { assert!(a.len() == 3); assert!(b.len() > 3); } #[test_matrix( "just", (1, 2, 3) )] fn matrix_with_singleton(a: &str, b: u32) { assert_eq!(a, "just"); assert!(b < 10); } #[test_matrix("alone")] fn only_singleton(a: &str) { assert_eq!(a, "alone"); } const TWO: u32 = 2; fn double(x: u32) -> u32 { x * TWO } #[test_matrix( 2, [double(2), 2 * TWO, 4] )] fn matrix_with_expressions(x: u32, two_x: u32) { assert_eq!(2 * x, two_x); } #[test_matrix(["foo", "bar", "baz"])] fn impl_trait(x: impl AsRef) { assert_eq!(3, x.as_ref().len()); } #[test_matrix( true, [true, false] )] fn matrix_with_keywords(x: bool, y: bool) { assert!(x || y) } #[test_matrix( [1, 2, 3] )] #[test_case(4)] fn case_after_matrix(x: u32) { assert!(x < 10); } #[test_matrix( [1, 2], [11, 12] )] #[test_matrix( [3, 4], [13, 14] )] fn two_matrices(x: u32, y: u32) { assert!(x < 10); assert!(y > 10); } #[test_matrix( [1, 2], [11, 12] ; "one, two" )] #[test_matrix( [3, 4], [13, 14] ; "three, four" )] fn two_matrices_with_comments(x: u32, y: u32) { assert!(x < 10); assert!(y > 10); } #[test_case(5)] #[test_matrix( [6, 7, 8] )] fn case_before_matrix(x: u32) { assert!(x < 10); } #[test_matrix( [1, 2,], [11, 12,] )] #[should_panic(expected = "Always panics")] fn matrix_with_should_panic(_x: u32, _y: u32) { panic!("Always panics") } #[test_matrix( [1, 2,], [11, 12,] => panics "Always panics" )] fn matrix_with_panics(_x: u32, _y: u32) { panic!("Always panics") } // tests from documentation // TODO } test-case-3.3.1/tests/acceptance_tests.rs000066400000000000000000000074561452574445500204610ustar00rootroot00000000000000#![cfg(test)] use insta::with_settings; use itertools::Itertools; use regex::Regex; use std::env; use std::path::PathBuf; use std::process::Command; macro_rules! run_acceptance_test { ($cmd:expr, $case_name:expr) => { with_settings!({snapshot_path => get_snapshot_directory()}, { let subcommand = Command::new("cargo") .current_dir(PathBuf::from("tests").join("acceptance_cases").join($case_name)) .args(&[$cmd]) .output() .expect("Failed to spawn cargo subcommand"); let mut output = String::new(); output.push_str(String::from_utf8_lossy(&subcommand.stdout).as_ref()); output.push_str(String::from_utf8_lossy(&subcommand.stderr).as_ref()); let output = sanitize_lines(output); insta::assert_display_snapshot!(output); }) }; ($case_name:expr) => { run_acceptance_test!("test", $case_name) } } fn get_snapshot_directory() -> String { PathBuf::from("snapshots") .join(env::var("SNAPSHOT_DIR").unwrap_or_else(|_| "rust-stable".to_string())) .to_str() .unwrap() .to_string() } fn sanitize_lines(s: String) -> String { let re_time = Regex::new(r"\d+\.\d{2}s").expect("Building regex"); let mut s = s .lines() .filter(|line| { (line.starts_with("test") // For general test output || line.contains("panicked at") // For panic messages || line.starts_with("error:") // For validating red paths || line.starts_with("error[")) // For validating red paths && !line.contains("process didn't exit successfully") // for Windows }) .map(|line| line.replace('\\', "/")) .map(|line| line.replace(".exe", "")) .map(|line| re_time.replace_all(&line, "0.00s").to_string()) .collect::>(); s.sort_unstable(); s.into_iter().join("\n") } #[test] fn cases_can_be_declared_on_async_methods() { run_acceptance_test!("cases_can_be_declared_on_async_methods") } #[test] fn cases_can_be_declared_on_non_test_items() { run_acceptance_test!("cases_can_be_declared_on_non_test_items") } #[test] fn cases_declared_on_non_test_items_can_be_used() { run_acceptance_test!("run", "cases_can_be_declared_on_non_test_items") } #[test] fn cases_can_be_ignored() { run_acceptance_test!("cases_can_be_ignored") } #[test] fn cases_can_panic() { run_acceptance_test!("cases_can_panic") } #[test] fn cases_can_return_result() { run_acceptance_test!("cases_can_return_result") } #[test] fn cases_support_basic_features() { run_acceptance_test!("cases_support_basic_features") } #[test] fn matrices_support_basic_features() { run_acceptance_test!("matrices_support_basic_features") } #[test] fn cases_support_complex_assertions() { run_acceptance_test!("cases_support_complex_assertions") } #[test] fn cases_support_generics() { run_acceptance_test!("cases_support_generics") } #[test] fn cases_support_keyword_using() { run_acceptance_test!("cases_support_keyword_using") } #[test] fn cases_support_keyword_with() { run_acceptance_test!("cases_support_keyword_with") } #[test] fn cases_support_multiple_calling_methods() { run_acceptance_test!("cases_support_multiple_calling_methods") } #[test] fn cases_support_pattern_matching() { run_acceptance_test!("cases_support_pattern_matching") } #[test] fn cases_can_use_regex() { run_acceptance_test!("cases_can_use_regex") } #[test] fn features_produce_human_readable_errors() { run_acceptance_test!("features_produce_human_readable_errors") } #[test] fn allow_stays_on_fn() { run_acceptance_test!("allow_stays_on_fn") } #[test] fn matrices_compilation_errors() { run_acceptance_test!("matrices_compilation_errors") } test-case-3.3.1/tests/snapshots/000077500000000000000000000000001452574445500166115ustar00rootroot00000000000000test-case-3.3.1/tests/snapshots/rust-nightly/000077500000000000000000000000001452574445500212625ustar00rootroot00000000000000test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__allow_stays_on_fn.snap000066400000000000000000000003061452574445500301710ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test allow_stays_on_fn::_42_expects ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_can_be_declared_on_async_methods.snap000066400000000000000000000004431452574445500342770ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test works_seamlessly_with_async_std::_100i32_expects_100usize ... ok test works_seamlessly_with_tokio::_100i32_expects_100usize ... ok acceptance__cases_can_be_declared_on_non_test_items.snap000066400000000000000000000012201452574445500344040ustar00rootroot00000000000000test-case-3.3.1/tests/snapshots/rust-nightly--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test internal_tested_function1::_2_expects_4 ... ok test internal_tested_function1::_3_expects_6 ... FAILED test internal_tested_function2::_1_expects_0 ... ok test internal_tested_function3::_1_expects_matching_3_ ... ok test internal_tested_function3::_2_expects_inconclusive6 ... ignored test internal_tested_function4::_2_expects_panicking_some_can_t_ - should panic ... ok test result: FAILED. 4 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s thread 'internal_tested_function1::_3_expects_6' panicked at src/lib.rs:8:1: test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_can_be_ignored.snap000066400000000000000000000012531452574445500305470ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test descriptions::_expects_inconclusive_ ... ignored, reason but no comment test descriptions::ignore_keyword ... ignored, reason and comment test descriptions::test_is_not_run ... ignored, reason and comment test ignore_void::_1_expects_inconclusiveempty ... ignored test ignore_void::_2_expects_inconclusiveempty ... ignored test inconclusives::_expects_inconclusive_ ... ignored test inconclusives::ignore_keyword ... ignored test inconclusives::inconclusive_test ... ignored test inconclusives::test_is_not_ran ... ignored test result: ok. 0 passed; 0 failed; 9 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_can_panic.snap000066400000000000000000000014151452574445500275440ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test panicking::_expects_panicking_some_it_has_to_panic_ - should panic ... ok test panicking::_expects_panicking_some_this_should_fail_ - should panic ... FAILED test panics_without_value::_expects_panicking_none - should panic ... ok test pattern_matching_result_fails::simpleenum_var1_expects_matching_simpleenum_var2_ - should panic ... ok test result: FAILED. 3 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result_which_panics::_2_2_expects_2_3 - should panic ... FAILED thread 'panicking::_expects_panicking_some_this_should_fail_' panicked at src/lib.rs:20:5: thread 'result_which_panics::_2_2_expects_2_3' panicked at src/lib.rs:28:1: test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_can_return_result.snap000066400000000000000000000011021452574445500313600ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test ignore_supported::_12_expects_inconclusivematching_ok_ ... ignored test is_even::_12_expects ... ok test is_even::_13_expects ... FAILED test is_odd_boxed::_12_expects ... FAILED test is_odd_boxed::_13_expects ... ok test panics_supported::_12_expects_panicking_none - should panic ... ok test panics_supported::_13_expects_panicking_some_with_text_ - should panic ... ok test result: FAILED. 4 passed; 2 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_can_use_regex.snap000066400000000000000000000016231452574445500304410ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: incomplete escape sequence, reached end of pattern prematurely error: test failed, to rerun pass `--lib` test regex_test::_abcabc201_expects_complex_regex_r_d_ ... ok test regex_test::_abcabc201_expects_complex_regex_r_d_4_ ... FAILED test regex_test::_abcabc_expects_complex_regex_r_abc_ ... ok test regex_test::_kumkwat_expects_complex_regex_r_ ... FAILED test regex_test::_kumkwat_expects_complex_regex_r_abc_ ... FAILED test regex_test::_kumkwat_expects_complex_regex_r_kumkwat_ ... ok test result: FAILED. 3 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s thread 'regex_test::_abcabc201_expects_complex_regex_r_d_4_' panicked at src/lib.rs:5:1: thread 'regex_test::_kumkwat_expects_complex_regex_r_' panicked at src/lib.rs:5:1: thread 'regex_test::_kumkwat_expects_complex_regex_r_abc_' panicked at src/lib.rs:5:1: acceptance__cases_declared_on_non_test_items_can_be_used.snap000066400000000000000000000001501452574445500354250ustar00rootroot00000000000000test-case-3.3.1/tests/snapshots/rust-nightly--- source: tests/acceptance_tests.rs expression: output --- thread 'main' panicked at src/lib.rs:33:5: test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_support_basic_features.snap000066400000000000000000000041341452574445500324050ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test result: ok. 33 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test test_cases::abs_tests::returns_0_for_0 ... ok test test_cases::abs_tests::returns_given_number_for_positive_input ... ok test test_cases::abs_tests::returns_opposite_number_for_non_positive_input ... ok test test_cases::arg_expressions::_2_4_6_to_string_expects ... ok test test_cases::bar::_expects_string_default_ ... ok test test_cases::basic_test::_1_expects ... ok test test_cases::const_in_arg::this_is_desc_not_an_argument ... ok test test_cases::fancy_addition::some_2_3_some_4_expects_2_3_4 ... ok test test_cases::fancy_addition::some_2_some_3_expects_5 ... ok test test_cases::fancy_addition::treats_none_as_0 ... ok test test_cases::impl_trait::_foo_expects ... ok test test_cases::keyword_test::true_expects ... ok test test_cases::leading_underscore_in_test_name::_dummy_expects ... ok test test_cases::lowercase_test_name::_dummy_code_expects ... ok test test_cases::multiple_test_cases::_2_expects ... ok test test_cases::multiple_test_cases::_4_expects ... ok test test_cases::multiplication_tests::when_both_operands_are_negative ... ok test test_cases::multiplication_tests::when_both_operands_are_possitive ... ok test test_cases::multiplication_tests::when_operands_are_swapped ... ok test test_cases::name::_2nd_test ... ok test test_cases::name::_4_5_expects ... ok test test_cases::name::test_1_8_9 ... ok test test_cases::name::test_3_6_9 ... ok test test_cases::nested::nested_test_case::_1_1_expects ... ok test test_cases::nested::using_fn_from_super::_20_22_expects ... ok test test_cases::nested::using_fn_from_super::_42_expects ... ok test test_cases::result::_2_expects_4 ... ok test test_cases::result::_4_expects_8 ... ok test test_cases::result_and_name::_4_5_expects_9 ... ok test test_cases::result_and_name::test_no_1 ... ok test test_cases::result_expresion_with_name::test_result_expression ... ok test test_cases::result_expression::_2_2_expects_2_2 ... ok test test_cases::result_with_mod_sep::_42_expects_std_string_string_new_ ... ok test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_support_complex_assertions.snap000066400000000000000000000066611452574445500333560ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test combinators::_0_3_expects_complex_gt_0_0_and_lt_1_0_or_gt_1_2 ... ok test combinators::_0_7_expects_complex_gt_0_0_and_lt_1_0_or_gt_1_2 ... ok test combinators::_1_0_expects_complex_gt_0_0_and_lt_5_0 ... ok test combinators::_1_0_expects_complex_gt_0_0_or_lt_0_0 ... ok test combinators::_1_0_expects_complex_gt_0_0_or_lt_1_5_and_lt_2_0 ... ok test combinators::_2_0_expects_complex_gt_0_0_or_lt_0_0 ... ok test combinators::_2_0_expects_complex_gt_0_0_or_lt_0_0_and_lt_1_0 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_1_and_contains_2_and_contains_in_order_2_3_ ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_1_and_contains_3_or_contains_5 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_1_or_contains_4 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_1_or_contains_4_and_contains_2 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_6_and_contains_7_or_contains_1 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_6_and_contains_7_or_contains_1_and_contains_in_order_1_2_3_ ... ok test complex_tests::almost_eq1 ... ok test complex_tests::almost_eq2 ... ok test complex_tests::eq1 ... ok test complex_tests::eq2 ... ok test complex_tests::geq1 ... ok test complex_tests::geq2 ... ok test complex_tests::gt1 ... ok test complex_tests::gt2 ... ok test complex_tests::leq1 ... ok test complex_tests::leq2 ... ok test complex_tests::lt1 ... ok test complex_tests::lt2 ... ok test contains_tests::vec_1_2_3_4_expects_complex_contains_1 ... ok test contains_tests::vec_1_2_3_4_expects_complex_contains_in_order_3_4_ ... ok test count_general::_abcd_chars_expects_complex_count_4 ... ok test count_general::std_iter_once_2_expects_complex_count_1 ... ok test count_general::vec_0_1_3_expects_complex_count_3 ... ok test count_vec::vec_0_1_3_expects_complex_count_3 ... ok test count_vec::vec_0_1_expects_complex_count_2 ... ok test create_path::_cargo_toml_expects_complex_path_path ... ok test create_path::_src_lib_rs_expects_complex_path_file ... ok test create_path::long_dir ... ok test create_path::short_dir ... ok test empty::vec_0_expects_complex_empty ... FAILED test empty::vec_expects_complex_empty ... ok test in_parens::_2_0_expects_complex_eq_2_0 ... ok test len_byte_str::b_ab_expects_complex_len_2 ... ok test len_byte_str::b_abc_expects_complex_len_3 ... ok test len_str::_ab_expects_complex_len_2 ... ok test len_str::_abc_expects_complex_len_3 ... ok test len_string::_ab_expects_complex_len_2 ... ok test len_string::_abc_expects_complex_len_3 ... ok test len_vec::vec_0_1_3_expects_complex_len_3 ... ok test len_vec::vec_0_1_expects_complex_len_2 ... ok test not_complex::_1_0_expects_complex_not_almost_2_1_p_0_01 ... ok test not_complex::_1_0_expects_complex_not_eq_2_5 ... ok test not_contains_tests::vec_1_2_3_4_expects_complex_not_contains_5 ... ok test not_contains_tests::vec_1_2_3_4_expects_complex_not_contains_in_order_3_2_ ... ok test not_path::_cargo_toml_parse_unwrap_expects_complex_not_path_dir ... ok test not_path::_cargo_yaml_parse_unwrap_expects_complex_not_path_path ... ok test not_path::_src_parse_unwrap_expects_complex_not_path_file ... ok test result: FAILED. 53 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s thread 'empty::vec_0_expects_complex_empty' panicked at src/lib.rs:115:1: test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_support_generics.snap000066400000000000000000000005071452574445500312250ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test test_generics::source1_expects_1 ... ok test test_generics::source2_expects_2 ... ok test test_impl::source1_expects_1 ... ok test test_impl::source2_expects_2 ... ok test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_support_keyword_using.snap000066400000000000000000000007301452574445500323150ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test power_of_two_with_using::_1_expects_use_assert_is_power_of_two ... ok test power_of_two_with_using::_2_expects_use_crate_assert_is_power_of_two ... ok test power_of_two_with_using::_4_expects_use_some_mod_assert_is_power_of_two ... ok test pretty_assertions_usage::_1_expects_use_wrapped_pretty_assert_1_ ... ok test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_support_keyword_with.snap000066400000000000000000000005121452574445500321410ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test divide_by_zero_f64_with_lambda::_0_0_expects_with_v_f64_assert_v_is_nan_ ... ok test divide_by_zero_f64_with_lambda::_1_0_expects_with_v_f64_assert_v_is_infinite_ ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_support_multiple_calling_methods.snap000066400000000000000000000011751452574445500344770ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test can_use_fully_qualified_case_path::_2_expects ... ok test can_use_fully_qualified_case_path::_3_expects ... ok test can_use_fully_qualified_test_case_path::first_test ... ok test can_use_fully_qualified_test_case_path::second_test ... ok test import::can_import_test_case_attribute::_2_expects ... ok test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test short_version::can_use_case_attribute_same_as_test_case::_12u8_expects_12u16 ... ok test short_version::can_use_case_attribute_same_as_test_case::_8u8_expects_8u16 ... ok test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__cases_support_pattern_matching.snap000066400000000000000000000014251452574445500327550ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test extended_pattern_matching_result::err_should_fail ... FAILED test extended_pattern_matching_result::ok_should_fail ... FAILED test extended_pattern_matching_result::simpleenum_var1_expects_matching_ok_e_e_simpleenum_var1 ... ok test extended_pattern_matching_result::simpleenum_var2_expects_matching_err_e_e_var2_ ... ok test pattern_matching_result::simpleenum_var2_expects_matching_simpleenum_var2_ ... ok test result: FAILED. 3 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s thread 'extended_pattern_matching_result::err_should_fail' panicked at src/lib.rs:16:1: thread 'extended_pattern_matching_result::ok_should_fail' panicked at src/lib.rs:16:1: test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__features_produce_human_readable_errors.snap000066400000000000000000000003471452574445500344200ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: 'with-regex' feature is required to use 'matches-regex' keyword error: could not compile `features_produce_human_readable_errors` (lib test) due to previous error test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__matrices_compilation_errors.snap000066400000000000000000000005651452574445500322610ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: All literal values must be of the same type error: Range bounds can only be an integer literal error: Unbounded ranges are not supported error: could not compile `matrices_compilation_errors` (lib test) due to 5 previous errors error: number too large to fit in target type error[E0308]: mismatched types test-case-3.3.1/tests/snapshots/rust-nightly/acceptance__matrices_support_basic_features.snap000066400000000000000000000107171452574445500331220ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test result: ok. 70 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test test_cases::case_after_matrix::_1_expects ... ok test test_cases::case_after_matrix::_2_expects ... ok test test_cases::case_after_matrix::_3_expects ... ok test test_cases::case_after_matrix::_4_expects ... ok test test_cases::case_before_matrix::_5_expects ... ok test test_cases::case_before_matrix::_6_expects ... ok test test_cases::case_before_matrix::_7_expects ... ok test test_cases::case_before_matrix::_8_expects ... ok test test_cases::impl_trait::_bar_expects ... ok test test_cases::impl_trait::_baz_expects ... ok test test_cases::impl_trait::_foo_expects ... ok test test_cases::matrix_with_expressions::_2_2_two_expects ... ok test test_cases::matrix_with_expressions::_2_4_expects ... ok test test_cases::matrix_with_expressions::_2_double_2_expects ... ok test test_cases::matrix_with_keywords::true_false_expects ... ok test test_cases::matrix_with_keywords::true_true_expects ... ok test test_cases::matrix_with_panics::_1_11_expects_panicking_some_always_panics_ - should panic ... ok test test_cases::matrix_with_panics::_1_12_expects_panicking_some_always_panics_ - should panic ... ok test test_cases::matrix_with_panics::_2_11_expects_panicking_some_always_panics_ - should panic ... ok test test_cases::matrix_with_panics::_2_12_expects_panicking_some_always_panics_ - should panic ... ok test test_cases::matrix_with_range::_1_11_expects ... ok test test_cases::matrix_with_range::_1_12_expects ... ok test test_cases::matrix_with_range::_2_11_expects ... ok test test_cases::matrix_with_range::_2_12_expects ... ok test test_cases::matrix_with_range::_3_11_expects ... ok test test_cases::matrix_with_range::_3_12_expects ... ok test test_cases::matrix_with_range::_4_11_expects ... ok test test_cases::matrix_with_range::_4_12_expects ... ok test test_cases::matrix_with_range::_5_11_expects ... ok test test_cases::matrix_with_range::_5_12_expects ... ok test test_cases::matrix_with_range::_6_11_expects ... ok test test_cases::matrix_with_range::_6_12_expects ... ok test test_cases::matrix_with_range::_7_11_expects ... ok test test_cases::matrix_with_range::_7_12_expects ... ok test test_cases::matrix_with_range::_8_11_expects ... ok test test_cases::matrix_with_range::_8_12_expects ... ok test test_cases::matrix_with_range::_9_11_expects ... ok test test_cases::matrix_with_range::_9_12_expects ... ok test test_cases::matrix_with_should_panic::_1_11_expects - should panic ... ok test test_cases::matrix_with_should_panic::_1_12_expects - should panic ... ok test test_cases::matrix_with_should_panic::_2_11_expects - should panic ... ok test test_cases::matrix_with_should_panic::_2_12_expects - should panic ... ok test test_cases::matrix_with_singleton::_just_1_expects ... ok test test_cases::matrix_with_singleton::_just_2_expects ... ok test test_cases::matrix_with_singleton::_just_3_expects ... ok test test_cases::numeric_values_array::_1_11_expects ... ok test test_cases::numeric_values_array::_1_12_expects ... ok test test_cases::numeric_values_array::_2_11_expects ... ok test test_cases::numeric_values_array::_2_12_expects ... ok test test_cases::only_singleton::_alone_expects ... ok test test_cases::str_values_tuple::_one_blue_expects ... ok test test_cases::str_values_tuple::_one_yellow_expects ... ok test test_cases::str_values_tuple::_two_blue_expects ... ok test test_cases::str_values_tuple::_two_yellow_expects ... ok test test_cases::two_matrices::_1_11_expects ... ok test test_cases::two_matrices::_1_12_expects ... ok test test_cases::two_matrices::_2_11_expects ... ok test test_cases::two_matrices::_2_12_expects ... ok test test_cases::two_matrices::_3_13_expects ... ok test test_cases::two_matrices::_3_14_expects ... ok test test_cases::two_matrices::_4_13_expects ... ok test test_cases::two_matrices::_4_14_expects ... ok test test_cases::two_matrices_with_comments::one_two_1_11_expects ... ok test test_cases::two_matrices_with_comments::one_two_1_12_expects ... ok test test_cases::two_matrices_with_comments::one_two_2_11_expects ... ok test test_cases::two_matrices_with_comments::one_two_2_12_expects ... ok test test_cases::two_matrices_with_comments::three_four_3_13_expects ... ok test test_cases::two_matrices_with_comments::three_four_3_14_expects ... ok test test_cases::two_matrices_with_comments::three_four_4_13_expects ... ok test test_cases::two_matrices_with_comments::three_four_4_14_expects ... ok test-case-3.3.1/tests/snapshots/rust-stable/000077500000000000000000000000001452574445500210565ustar00rootroot00000000000000test-case-3.3.1/tests/snapshots/rust-stable/acceptance__allow_stays_on_fn.snap000066400000000000000000000003061452574445500277650ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test allow_stays_on_fn::_42_expects ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_can_be_declared_on_async_methods.snap000066400000000000000000000004431452574445500340730ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test works_seamlessly_with_async_std::_100i32_expects_100usize ... ok test works_seamlessly_with_tokio::_100i32_expects_100usize ... ok test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_can_be_declared_on_non_test_items.snap000066400000000000000000000012201452574445500342570ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test internal_tested_function1::_2_expects_4 ... ok test internal_tested_function1::_3_expects_6 ... FAILED test internal_tested_function2::_1_expects_0 ... ok test internal_tested_function3::_1_expects_matching_3_ ... ok test internal_tested_function3::_2_expects_inconclusive6 ... ignored test internal_tested_function4::_2_expects_panicking_some_can_t_ - should panic ... ok test result: FAILED. 4 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s thread 'internal_tested_function1::_3_expects_6' panicked at src/lib.rs:8:1: test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_can_be_ignored.snap000066400000000000000000000012531452574445500303430ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test descriptions::_expects_inconclusive_ ... ignored, reason but no comment test descriptions::ignore_keyword ... ignored, reason and comment test descriptions::test_is_not_run ... ignored, reason and comment test ignore_void::_1_expects_inconclusiveempty ... ignored test ignore_void::_2_expects_inconclusiveempty ... ignored test inconclusives::_expects_inconclusive_ ... ignored test inconclusives::ignore_keyword ... ignored test inconclusives::inconclusive_test ... ignored test inconclusives::test_is_not_ran ... ignored test result: ok. 0 passed; 0 failed; 9 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_can_panic.snap000066400000000000000000000014151452574445500273400ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test panicking::_expects_panicking_some_it_has_to_panic_ - should panic ... ok test panicking::_expects_panicking_some_this_should_fail_ - should panic ... FAILED test panics_without_value::_expects_panicking_none - should panic ... ok test pattern_matching_result_fails::simpleenum_var1_expects_matching_simpleenum_var2_ - should panic ... ok test result: FAILED. 3 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result_which_panics::_2_2_expects_2_3 - should panic ... FAILED thread 'panicking::_expects_panicking_some_this_should_fail_' panicked at src/lib.rs:20:5: thread 'result_which_panics::_2_2_expects_2_3' panicked at src/lib.rs:28:1: test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_can_return_result.snap000066400000000000000000000011021452574445500311540ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test ignore_supported::_12_expects_inconclusivematching_ok_ ... ignored test is_even::_12_expects ... ok test is_even::_13_expects ... FAILED test is_odd_boxed::_12_expects ... FAILED test is_odd_boxed::_13_expects ... ok test panics_supported::_12_expects_panicking_none - should panic ... ok test panics_supported::_13_expects_panicking_some_with_text_ - should panic ... ok test result: FAILED. 4 passed; 2 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_can_use_regex.snap000066400000000000000000000016231452574445500302350ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: incomplete escape sequence, reached end of pattern prematurely error: test failed, to rerun pass `--lib` test regex_test::_abcabc201_expects_complex_regex_r_d_ ... ok test regex_test::_abcabc201_expects_complex_regex_r_d_4_ ... FAILED test regex_test::_abcabc_expects_complex_regex_r_abc_ ... ok test regex_test::_kumkwat_expects_complex_regex_r_ ... FAILED test regex_test::_kumkwat_expects_complex_regex_r_abc_ ... FAILED test regex_test::_kumkwat_expects_complex_regex_r_kumkwat_ ... ok test result: FAILED. 3 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s thread 'regex_test::_abcabc201_expects_complex_regex_r_d_4_' panicked at src/lib.rs:5:1: thread 'regex_test::_kumkwat_expects_complex_regex_r_' panicked at src/lib.rs:5:1: thread 'regex_test::_kumkwat_expects_complex_regex_r_abc_' panicked at src/lib.rs:5:1: acceptance__cases_declared_on_non_test_items_can_be_used.snap000066400000000000000000000001501452574445500352210ustar00rootroot00000000000000test-case-3.3.1/tests/snapshots/rust-stable--- source: tests/acceptance_tests.rs expression: output --- thread 'main' panicked at src/lib.rs:33:5: test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_support_basic_features.snap000066400000000000000000000041341452574445500322010ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test result: ok. 33 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test test_cases::abs_tests::returns_0_for_0 ... ok test test_cases::abs_tests::returns_given_number_for_positive_input ... ok test test_cases::abs_tests::returns_opposite_number_for_non_positive_input ... ok test test_cases::arg_expressions::_2_4_6_to_string_expects ... ok test test_cases::bar::_expects_string_default_ ... ok test test_cases::basic_test::_1_expects ... ok test test_cases::const_in_arg::this_is_desc_not_an_argument ... ok test test_cases::fancy_addition::some_2_3_some_4_expects_2_3_4 ... ok test test_cases::fancy_addition::some_2_some_3_expects_5 ... ok test test_cases::fancy_addition::treats_none_as_0 ... ok test test_cases::impl_trait::_foo_expects ... ok test test_cases::keyword_test::true_expects ... ok test test_cases::leading_underscore_in_test_name::_dummy_expects ... ok test test_cases::lowercase_test_name::_dummy_code_expects ... ok test test_cases::multiple_test_cases::_2_expects ... ok test test_cases::multiple_test_cases::_4_expects ... ok test test_cases::multiplication_tests::when_both_operands_are_negative ... ok test test_cases::multiplication_tests::when_both_operands_are_possitive ... ok test test_cases::multiplication_tests::when_operands_are_swapped ... ok test test_cases::name::_2nd_test ... ok test test_cases::name::_4_5_expects ... ok test test_cases::name::test_1_8_9 ... ok test test_cases::name::test_3_6_9 ... ok test test_cases::nested::nested_test_case::_1_1_expects ... ok test test_cases::nested::using_fn_from_super::_20_22_expects ... ok test test_cases::nested::using_fn_from_super::_42_expects ... ok test test_cases::result::_2_expects_4 ... ok test test_cases::result::_4_expects_8 ... ok test test_cases::result_and_name::_4_5_expects_9 ... ok test test_cases::result_and_name::test_no_1 ... ok test test_cases::result_expresion_with_name::test_result_expression ... ok test test_cases::result_expression::_2_2_expects_2_2 ... ok test test_cases::result_with_mod_sep::_42_expects_std_string_string_new_ ... ok test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_support_complex_assertions.snap000066400000000000000000000066611452574445500331520ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test combinators::_0_3_expects_complex_gt_0_0_and_lt_1_0_or_gt_1_2 ... ok test combinators::_0_7_expects_complex_gt_0_0_and_lt_1_0_or_gt_1_2 ... ok test combinators::_1_0_expects_complex_gt_0_0_and_lt_5_0 ... ok test combinators::_1_0_expects_complex_gt_0_0_or_lt_0_0 ... ok test combinators::_1_0_expects_complex_gt_0_0_or_lt_1_5_and_lt_2_0 ... ok test combinators::_2_0_expects_complex_gt_0_0_or_lt_0_0 ... ok test combinators::_2_0_expects_complex_gt_0_0_or_lt_0_0_and_lt_1_0 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_1_and_contains_2_and_contains_in_order_2_3_ ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_1_and_contains_3_or_contains_5 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_1_or_contains_4 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_1_or_contains_4_and_contains_2 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_6_and_contains_7_or_contains_1 ... ok test combinators_with_arrays::vec_1_2_3_expects_complex_contains_6_and_contains_7_or_contains_1_and_contains_in_order_1_2_3_ ... ok test complex_tests::almost_eq1 ... ok test complex_tests::almost_eq2 ... ok test complex_tests::eq1 ... ok test complex_tests::eq2 ... ok test complex_tests::geq1 ... ok test complex_tests::geq2 ... ok test complex_tests::gt1 ... ok test complex_tests::gt2 ... ok test complex_tests::leq1 ... ok test complex_tests::leq2 ... ok test complex_tests::lt1 ... ok test complex_tests::lt2 ... ok test contains_tests::vec_1_2_3_4_expects_complex_contains_1 ... ok test contains_tests::vec_1_2_3_4_expects_complex_contains_in_order_3_4_ ... ok test count_general::_abcd_chars_expects_complex_count_4 ... ok test count_general::std_iter_once_2_expects_complex_count_1 ... ok test count_general::vec_0_1_3_expects_complex_count_3 ... ok test count_vec::vec_0_1_3_expects_complex_count_3 ... ok test count_vec::vec_0_1_expects_complex_count_2 ... ok test create_path::_cargo_toml_expects_complex_path_path ... ok test create_path::_src_lib_rs_expects_complex_path_file ... ok test create_path::long_dir ... ok test create_path::short_dir ... ok test empty::vec_0_expects_complex_empty ... FAILED test empty::vec_expects_complex_empty ... ok test in_parens::_2_0_expects_complex_eq_2_0 ... ok test len_byte_str::b_ab_expects_complex_len_2 ... ok test len_byte_str::b_abc_expects_complex_len_3 ... ok test len_str::_ab_expects_complex_len_2 ... ok test len_str::_abc_expects_complex_len_3 ... ok test len_string::_ab_expects_complex_len_2 ... ok test len_string::_abc_expects_complex_len_3 ... ok test len_vec::vec_0_1_3_expects_complex_len_3 ... ok test len_vec::vec_0_1_expects_complex_len_2 ... ok test not_complex::_1_0_expects_complex_not_almost_2_1_p_0_01 ... ok test not_complex::_1_0_expects_complex_not_eq_2_5 ... ok test not_contains_tests::vec_1_2_3_4_expects_complex_not_contains_5 ... ok test not_contains_tests::vec_1_2_3_4_expects_complex_not_contains_in_order_3_2_ ... ok test not_path::_cargo_toml_parse_unwrap_expects_complex_not_path_dir ... ok test not_path::_cargo_yaml_parse_unwrap_expects_complex_not_path_path ... ok test not_path::_src_parse_unwrap_expects_complex_not_path_file ... ok test result: FAILED. 53 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s thread 'empty::vec_0_expects_complex_empty' panicked at src/lib.rs:115:1: test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_support_generics.snap000066400000000000000000000005071452574445500310210ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test test_generics::source1_expects_1 ... ok test test_generics::source2_expects_2 ... ok test test_impl::source1_expects_1 ... ok test test_impl::source2_expects_2 ... ok test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_support_keyword_using.snap000066400000000000000000000007301452574445500321110ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test power_of_two_with_using::_1_expects_use_assert_is_power_of_two ... ok test power_of_two_with_using::_2_expects_use_crate_assert_is_power_of_two ... ok test power_of_two_with_using::_4_expects_use_some_mod_assert_is_power_of_two ... ok test pretty_assertions_usage::_1_expects_use_wrapped_pretty_assert_1_ ... ok test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_support_keyword_with.snap000066400000000000000000000005121452574445500317350ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test divide_by_zero_f64_with_lambda::_0_0_expects_with_v_f64_assert_v_is_nan_ ... ok test divide_by_zero_f64_with_lambda::_1_0_expects_with_v_f64_assert_v_is_infinite_ ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_support_multiple_calling_methods.snap000066400000000000000000000011751452574445500342730ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test can_use_fully_qualified_case_path::_2_expects ... ok test can_use_fully_qualified_case_path::_3_expects ... ok test can_use_fully_qualified_test_case_path::first_test ... ok test can_use_fully_qualified_test_case_path::second_test ... ok test import::can_import_test_case_attribute::_2_expects ... ok test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test short_version::can_use_case_attribute_same_as_test_case::_12u8_expects_12u16 ... ok test short_version::can_use_case_attribute_same_as_test_case::_8u8_expects_8u16 ... ok test-case-3.3.1/tests/snapshots/rust-stable/acceptance__cases_support_pattern_matching.snap000066400000000000000000000014251452574445500325510ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: test failed, to rerun pass `--lib` test extended_pattern_matching_result::err_should_fail ... FAILED test extended_pattern_matching_result::ok_should_fail ... FAILED test extended_pattern_matching_result::simpleenum_var1_expects_matching_ok_e_e_simpleenum_var1 ... ok test extended_pattern_matching_result::simpleenum_var2_expects_matching_err_e_e_var2_ ... ok test pattern_matching_result::simpleenum_var2_expects_matching_simpleenum_var2_ ... ok test result: FAILED. 3 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s thread 'extended_pattern_matching_result::err_should_fail' panicked at src/lib.rs:16:1: thread 'extended_pattern_matching_result::ok_should_fail' panicked at src/lib.rs:16:1: test-case-3.3.1/tests/snapshots/rust-stable/acceptance__features_produce_human_readable_errors.snap000066400000000000000000000003471452574445500342140ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: 'with-regex' feature is required to use 'matches-regex' keyword error: could not compile `features_produce_human_readable_errors` (lib test) due to previous error test-case-3.3.1/tests/snapshots/rust-stable/acceptance__matrices_compilation_errors.snap000066400000000000000000000005651452574445500320550ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- error: All literal values must be of the same type error: Range bounds can only be an integer literal error: Unbounded ranges are not supported error: could not compile `matrices_compilation_errors` (lib test) due to 5 previous errors error: number too large to fit in target type error[E0308]: mismatched types test-case-3.3.1/tests/snapshots/rust-stable/acceptance__matrices_support_basic_features.snap000066400000000000000000000107171452574445500327160ustar00rootroot00000000000000--- source: tests/acceptance_tests.rs expression: output --- test result: ok. 70 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test test_cases::case_after_matrix::_1_expects ... ok test test_cases::case_after_matrix::_2_expects ... ok test test_cases::case_after_matrix::_3_expects ... ok test test_cases::case_after_matrix::_4_expects ... ok test test_cases::case_before_matrix::_5_expects ... ok test test_cases::case_before_matrix::_6_expects ... ok test test_cases::case_before_matrix::_7_expects ... ok test test_cases::case_before_matrix::_8_expects ... ok test test_cases::impl_trait::_bar_expects ... ok test test_cases::impl_trait::_baz_expects ... ok test test_cases::impl_trait::_foo_expects ... ok test test_cases::matrix_with_expressions::_2_2_two_expects ... ok test test_cases::matrix_with_expressions::_2_4_expects ... ok test test_cases::matrix_with_expressions::_2_double_2_expects ... ok test test_cases::matrix_with_keywords::true_false_expects ... ok test test_cases::matrix_with_keywords::true_true_expects ... ok test test_cases::matrix_with_panics::_1_11_expects_panicking_some_always_panics_ - should panic ... ok test test_cases::matrix_with_panics::_1_12_expects_panicking_some_always_panics_ - should panic ... ok test test_cases::matrix_with_panics::_2_11_expects_panicking_some_always_panics_ - should panic ... ok test test_cases::matrix_with_panics::_2_12_expects_panicking_some_always_panics_ - should panic ... ok test test_cases::matrix_with_range::_1_11_expects ... ok test test_cases::matrix_with_range::_1_12_expects ... ok test test_cases::matrix_with_range::_2_11_expects ... ok test test_cases::matrix_with_range::_2_12_expects ... ok test test_cases::matrix_with_range::_3_11_expects ... ok test test_cases::matrix_with_range::_3_12_expects ... ok test test_cases::matrix_with_range::_4_11_expects ... ok test test_cases::matrix_with_range::_4_12_expects ... ok test test_cases::matrix_with_range::_5_11_expects ... ok test test_cases::matrix_with_range::_5_12_expects ... ok test test_cases::matrix_with_range::_6_11_expects ... ok test test_cases::matrix_with_range::_6_12_expects ... ok test test_cases::matrix_with_range::_7_11_expects ... ok test test_cases::matrix_with_range::_7_12_expects ... ok test test_cases::matrix_with_range::_8_11_expects ... ok test test_cases::matrix_with_range::_8_12_expects ... ok test test_cases::matrix_with_range::_9_11_expects ... ok test test_cases::matrix_with_range::_9_12_expects ... ok test test_cases::matrix_with_should_panic::_1_11_expects - should panic ... ok test test_cases::matrix_with_should_panic::_1_12_expects - should panic ... ok test test_cases::matrix_with_should_panic::_2_11_expects - should panic ... ok test test_cases::matrix_with_should_panic::_2_12_expects - should panic ... ok test test_cases::matrix_with_singleton::_just_1_expects ... ok test test_cases::matrix_with_singleton::_just_2_expects ... ok test test_cases::matrix_with_singleton::_just_3_expects ... ok test test_cases::numeric_values_array::_1_11_expects ... ok test test_cases::numeric_values_array::_1_12_expects ... ok test test_cases::numeric_values_array::_2_11_expects ... ok test test_cases::numeric_values_array::_2_12_expects ... ok test test_cases::only_singleton::_alone_expects ... ok test test_cases::str_values_tuple::_one_blue_expects ... ok test test_cases::str_values_tuple::_one_yellow_expects ... ok test test_cases::str_values_tuple::_two_blue_expects ... ok test test_cases::str_values_tuple::_two_yellow_expects ... ok test test_cases::two_matrices::_1_11_expects ... ok test test_cases::two_matrices::_1_12_expects ... ok test test_cases::two_matrices::_2_11_expects ... ok test test_cases::two_matrices::_2_12_expects ... ok test test_cases::two_matrices::_3_13_expects ... ok test test_cases::two_matrices::_3_14_expects ... ok test test_cases::two_matrices::_4_13_expects ... ok test test_cases::two_matrices::_4_14_expects ... ok test test_cases::two_matrices_with_comments::one_two_1_11_expects ... ok test test_cases::two_matrices_with_comments::one_two_1_12_expects ... ok test test_cases::two_matrices_with_comments::one_two_2_11_expects ... ok test test_cases::two_matrices_with_comments::one_two_2_12_expects ... ok test test_cases::two_matrices_with_comments::three_four_3_13_expects ... ok test test_cases::two_matrices_with_comments::three_four_3_14_expects ... ok test test_cases::two_matrices_with_comments::three_four_4_13_expects ... ok test test_cases::two_matrices_with_comments::three_four_4_14_expects ... ok