1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//! A test `#[session]` allow to use methods as tests.
//!
//! # Example
//!
//! ```rust
//! use fluid::prelude::*;
//! use std::sync::atomic::{AtomicUsize, Ordering};
//! use std::fs;
//!
//! static FILE_NBR: AtomicUsize = AtomicUsize::new(0);
//!
//! struct ReadingTest {
//! file: String,
//! }
//!
//! // Setup the test: create the file that will be read:
//! impl Default for ReadingTest {
//! fn default() -> Self {
//! let nbr = FILE_NBR.fetch_add(1, Ordering::SeqCst);
//! let file = format!("file_to_read_{}", nbr);
//!
//! // Must create a different file for each test to avoid data race:
//! fs::write(&file, "Here is a dummy content for the test: foo, bar, qux.").unwrap();
//!
//! ReadingTest { file }
//! }
//! }
//!
//! // Don't forget to clean up the mess:
//! impl Drop for ReadingTest {
//! fn drop(&mut self) {
//! // Try to comment this line: the files will not be cleaned after the tests:
//! let _ = fs::remove_file(&self.file);
//! }
//! }
//!
//! // The tests:
//! #[session]
//! impl ReadingTest {
//! fn read(&self) -> String {
//! let content = fs::read_to_string(&self.file);
//!
//! content.as_ref().should().be_ok();
//! content.unwrap()
//! }
//!
//! #[fact]
//! fn dummy(self) {
//! let content = self.read();
//!
//! (&content).should().contain("dummy");
//! }
//!
//! #[theory]
//! #[case("foo")]
//! #[case("bar")]
//! #[case("qux")]
//! fn content(self, word: &str) {
//! let content = self.read();
//!
//! (&content).should().contain(word);
//! }
//! }
//! ```
//!
//! # Notable points
//!
//! - The setup (the implementation of the `Default` trait) is mandatory.
//! - The teardown (the implementation of the `Drop` trait) is optional.
//! - The test methods must take `self` by value.
//! - The `fact` and `theory` attributes must be written exactly like that.
//! Despite appearances, they are not the proc macro attributes used in the free functions, so
//! `#[fluid::fact]` will **not** work, for example.