| Crates.io | srctrait-common-testing |
| lib.rs | srctrait-common-testing |
| version | 4.1.0 |
| created_at | 2025-05-14 16:38:14.036669+00 |
| updated_at | 2025-05-28 22:11:53.396722+00 |
| description | Structured testing with setup, teardown, and standardized fixture and temp directories |
| homepage | https://sourcetrait.com |
| repository | https://github.com/sourcetrait/srctrait-common |
| max_upload_size | |
| id | 1673671 |
| size | 146,598 |
Structured testing with setup, teardown, and standardized fixture and temp directories
srctests or exampletestinguse-case / module_path / function_name
// Just something to test against
pub fn fibonacci(n: u8) -> Option<u128> {
if n == 0 {
return Some(0);
} else if n == 1 {
return Some(1);
} else if n > FIBONACCI_MAX_N_U128 { // overflow u128
return None;
}
let mut sum: u128 = 0;
let mut last: u128 = 0;
let mut curr: u128 = 1;
for _i in 1..n {
if let Some(r) = last.checked_add(curr) {
sum = r;
} else {
return None;
}
last = curr;
curr = sum;
}
Some(sum)
}
const FIBONACCI_MAX_N_U128: u8 = 185;
// Testing namepaths will strip '::tests' out.
#[cfg(test)]
mod tests {
use std::{fs, sync::LazyLock};
use super::*;
use srctrait_common_testing::prelude::*;
// Module setup runs before any tests that use the module.
// Teardown runs on process exit.
//
// Fixture dirs are enforced at runtime and panic if they don't exist.
//
// This module's namepath().full_path() will be:
// srctrait-common-testing/integration/example-fibonacci
//
// This module's namepath().path() will be:
// integration/example-fibonacci
//
// fixture dir: $CRATE/testing/fixtures/integration/example-fibonacci
// temp dir: $TMP/srctrait-common-testing-example-fibonacci.XXXXXXXX
static TESTING: testing::Module = testing::module!(Integration, {
.using_fixture_dir()
.using_temp_dir()
.teardown_static(teardown)
.setup(|module| {
let fibonacci_u128_csv = (0..FIBONACCI_MAX_N_U128)
.map(|n| fibonacci(n).unwrap().to_string())
.collect::<Vec<_>>()
.join(",");
let fibonacci_csv_tmp_file = module.temp_dir()
.join(&*FIBONACCI_U128_CSV_FILENAME);
fs::write(&fibonacci_csv_tmp_file, fibonacci_u128_csv).unwrap();
})
});
static FIBONACCI_U128_CSV_FILENAME: LazyLock<String> = LazyLock::new(||
"fibonacci-u128.csv".to_string());
// Anything const or static can be used with static teardown functions,
// including things like LazyLock.
//
// Module's internal teardown will delete its temp directory before
// running its custom teardown.
extern "C" fn teardown() {
println!("Farewell, Fibonacci. Don't worry, {} has already been deleted.",
*FIBONACCI_U128_CSV_FILENAME);
}
// Groups are standalone and work similar to Modules, but without children.
// They have their own tmp and fixture directories, setup, and teardown.
//
// This group's namepath().full_path() will be:
// srctrait-common-testing/integration/example-fibonacci/100
// This group's namepath().path() will be:
// integration/example-fibonacci/100
static GROUP_100: testing::Group = testing::group!("example-fibonacci/100", Integration, {
.using_fixture_dir()
});
// The #[tested] helper is merely the equivalent of #[test] and #[named]
#[tested]
fn test_u128() {
// test!() assumes a module named `TESTING` is in scope and links to it.
//
// The "inherit_" methods use the same dir as their parent module.
// The "using_" methods will append a subdir named for the test function.
//
// Tests block on their module's setup. The tmp file needed here will exist.
//
// fixture dir: $CRATE/testing/fixtures/integration/example-fibonacci/test-u128
// tmp dir: $TMP/srctrait-common-testing-example-fibonacci.XXXXXXXX
let test = testing::test!({
.using_fixture_dir()
.inherit_temp_dir()
});
let fibonacci_fixture_csv_file = test.fixture_dir().join(&*FIBONACCI_U128_CSV_FILENAME);
let expected_fibonacci_u128 = fs::read_to_string(fibonacci_fixture_csv_file).unwrap()
.split(",")
.map(|d| d.trim().parse().unwrap())
.collect::<Vec<u128>>();
let fibonacci_tmp_csv_file = test.temp_dir().join(&*FIBONACCI_U128_CSV_FILENAME);
let actual_fibonacci_u128 = fs::read_to_string(fibonacci_tmp_csv_file).unwrap()
.split(",")
.map(|i| i.parse().unwrap())
.collect::<Vec<u128>>();
assert_eq!(expected_fibonacci_u128, actual_fibonacci_u128);
}
// Demonstration using a Group
#[tested]
fn test_100() {
// This empty Test will block on its Module's setup.
let _test = testing::test!();
// Groups will block on their setup.
let fib100_file = GROUP_100.fixture_dir().join("fib-100.txt");
let fib100: u128 = fs::read_to_string(fib100_file)
.map(|d| d.trim().parse().unwrap())
.unwrap();
assert_eq!(fib100, fibonacci(100).unwrap());
}
}
Refer to docs.rs/srctrait-common-testing
Contributors, please review SRCTRAIT.md.
Found a bug? Search for an existing issue on GitHub.
If an issue exists, chime in to add weight to it.
If not, create one and let us know.
SrcTrait Common Testing: Structured testing in sequence with fixture and temp directories
Developed by SourceTrait
Copyright (C) 2025 Asmov LLC
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.
An additional linking permission is granted under GNU Affero GPL version 3, section 7.
If you modify this Program, or any covered work, by linking or combining it with this Library (or a modified version of that library), containing parts covered by the terms of the AGPL3 license, the licensors of this Library grant you additional permission to convey the resulting work.
Corresponding Source for a non-source form of such a combination shall include the source code for the parts of this Program used as well as that of the covered work.
Our library publically exports the named macro from Daniel Henry-Mantilla's crate: function_name. It is available for use from our crate as
srctrait_common_testing::named.
License (MIT):
Copyright (c) 2019 Daniel Henry-Mantilla