unit/
tdd.rs

1pub mod tdd {
2    pub mod unit {
3
4        pub const IS_OK: &str = "The result match true";
5        pub const IS_KO: &str = "The result match false";
6        pub const IS_EQUALS: &str = "The values are equals";
7        pub const IS_UNEQUALS: &str = "The values are unequals";
8        pub const IS_BETWEEN: &str = "The values are between the expected values";
9        pub const IS_INFERIOR: &str = "The value are inferior to the expected value";
10        pub const IS_SUPERIOR: &str = "The value are superior to the expected value";
11        pub const IS_EMPTY: &str = "The value is empty";
12        pub const IS_DIRECTORY: &str = "The directory exist";
13        pub const IS_FILE: &str = "The file exist";
14        pub const IS_FULL: &str = "The value is at this maximum value";
15        pub const IS_PRIME: &str = "The value is a prime number";
16        pub const IS_PAIR: &str = "The value is a pair number";
17        pub const IS_START_WITH: &str = "The value start with the expected value";
18        pub const IS_FINNISH_WITH: &str = "The value finnish with the expected value";
19        pub const IS_IMPAIR: &str = "The value is not a pair number";
20        pub const IS_CONTAINS: &str = "The value contains the expected value";
21        pub const IS_ABSOLUTE: &str = "The path is absolute";
22        pub const IS_EXISTS: &str = "The path exists";
23        pub const IS_RELATIVE: &str = "The path is relative";
24        pub const IS_SYMLINK: &str = "The path is a symlink";
25        pub const IS_EXECUTABLE: &str = "The file is executable";
26        pub const THEORY_IS_TRUE: &str = "The theory is true";
27        pub const THEORY_IS_FALSE: &str = "The theory is false";
28        pub const IS_NOT_EXECUTABLE: &str = "The file is not executable";
29        pub const IS_NOT_SYMLINK: &str = "The path is a symlink";
30        pub const IS_NOT_RELATIVE: &str = "The path is not relative";
31        pub const IS_NOT_EXISTS: &str = "The path not exists";
32        pub const IS_NOT_ABSOLUTE: &str = "The path is not absolute";
33        pub const IS_NOT_FINNISH_WITH: &str = "The value don't finnish with the expected value";
34        pub const IS_NOT_CONTAINS: &str = "The value not contains the expected value";
35        pub const IS_NOT_PRIME: &str = "The value is not a prime number";
36        pub const IS_NOT_FULL: &str = "The value is not at this maximum value";
37        pub const IS_NOT_FILE: &str = "The file not exist";
38        pub const IS_NOT_DIRECTORY: &str = "The directory not exist";
39        pub const IS_NOT_EMPTY: &str = "The value is not empty";
40        pub const IS_NOT_BETWEEN: &str = "The values aren't between the expected values";
41        pub const IS_NOT_START_WITH: &str = "The value no start with the expected value";
42
43        pub const PROGRESS: u64 = 500;
44        pub const NO_PROGRESS: u64 = 0;
45
46        pub enum Style {
47            POINT,
48            ASTERIX,
49            OKAY,
50        }
51        use colored_truecolor::Colorize;
52        use is_executable::IsExecutable;
53        use std::cell::Cell;
54        use std::ops::Add;
55        use std::path::Path;
56        use std::thread::sleep;
57        use std::time::{Duration, Instant};
58        extern crate reqwest;
59
60        pub struct Unit {
61            description: String,
62            assertions: Cell<usize>,
63            failures: Cell<usize>,
64            start: Instant,
65            tdd: Cell<usize>,
66            sleep_time: u64,
67            style: Style,
68        }
69
70        ///
71        /// # To run unit test
72        ///
73        impl Unit {
74            pub fn see(url: &str, expected: &str) -> bool {
75                reqwest::blocking::get(url)
76                    .expect("failed to parse url")
77                    .text()
78                    .expect("failed to get text")
79                    .contains(expected)
80            }
81            ///
82            /// Get all assertions number
83            ///
84            fn assertions(&mut self) -> usize {
85                self.assertions.get()
86            }
87
88            pub fn equals_bytes(&mut self, actual: &str, expected: &[u8]) -> &mut Unit {
89                self.assert(
90                    String::from(actual).as_bytes().eq(expected),
91                    IS_EQUALS,
92                    IS_UNEQUALS,
93                )
94            }
95
96            pub fn unequals_bytes(&mut self, actual: &str, expected: &[u8]) -> &mut Unit {
97                self.assert(
98                    String::from(actual).as_bytes().ne(expected),
99                    IS_EQUALS,
100                    IS_UNEQUALS,
101                )
102            }
103
104            pub fn begin_with(&mut self, actual: &str, expected: &str) -> &mut Unit {
105                self.assert(
106                    String::from(actual).starts_with(expected),
107                    IS_START_WITH,
108                    IS_NOT_START_WITH,
109                )
110            }
111
112            pub fn finnish_with(&mut self, actual: &str, expected: &str) -> &mut Unit {
113                self.assert(
114                    String::from(actual).ends_with(expected),
115                    IS_FINNISH_WITH,
116                    IS_NOT_FINNISH_WITH,
117                )
118            }
119
120            ///
121            /// Get all failures number
122            ///
123            fn failures(&mut self) -> usize {
124                self.failures.get()
125            }
126
127            ///
128            /// # Test if a file is an executable
129            ///
130            /// - `filename`    The filename to test
131            ///
132            pub fn exe(&mut self, filename: &str) -> &mut Unit {
133                self.assert(
134                    Path::new(filename).is_executable(),
135                    IS_EXECUTABLE,
136                    IS_NOT_EXECUTABLE,
137                )
138            }
139
140            pub fn not_exe(&mut self, filename: &str) -> &mut Unit {
141                self.assert(
142                    !Path::new(filename).is_executable(),
143                    IS_NOT_EXECUTABLE,
144                    IS_EXECUTABLE,
145                )
146            }
147
148            ///
149            /// Run a test
150            ///
151            /// - `tdd` The test to execute
152            /// - `s`   The success output
153            /// - `f`   The failure output
154            ///
155            fn assert(&mut self, tdd: bool, s: &str, f: &str) -> &mut Unit {
156                self.tdd.set(self.tdd.get() + 1);
157
158                match self.style {
159                    Style::POINT => {
160                        if tdd {
161                            self.assertions.set(self.assertions.get() + 1);
162                            print!("{}", ".".magenta().bold());
163                        } else {
164                            self.failures.set(self.failures.get() + 1);
165                            print!("{}", "F".magenta().bold());
166                        }
167                        sleep(Duration::from_millis(self.sleep_time));
168                    }
169                    Style::OKAY => {
170                        if tdd {
171                            self.assertions.set(self.assertions.get() + 1);
172                            println!(
173                                "{}  {}  {} {}\n",
174                                "[".white().bold(),
175                                "OK".green().bold(),
176                                "]".white().bold(),
177                                s.blue().bold()
178                            );
179                        } else {
180                            self.failures.set(self.failures.get() + 1);
181                            println!(
182                                "{}  {}  {} {}\n",
183                                "[".white().bold(),
184                                "KO".red().bold(),
185                                "]".white().bold(),
186                                f.yellow().bold()
187                            );
188                        }
189                        sleep(Duration::from_millis(self.sleep_time));
190                    }
191                    Style::ASTERIX => {
192                        if tdd {
193                            self.assertions.set(self.assertions.get() + 1);
194                            println!("{} {}\n", "*".green().bold(), s.blue().bold());
195                        } else {
196                            self.failures.set(self.failures.get() + 1);
197                            println!("{} {}\n", "*".red().bold(), f.yellow().bold());
198                        }
199                        sleep(Duration::from_millis(self.sleep_time));
200                    }
201                }
202                sleep(Duration::from_millis(self.sleep_time));
203                self
204            }
205
206            ///
207            ///
208            /// # Group test in a function
209            ///
210            /// - `description` The group test description
211            /// - `it`          The callback to execute
212            ///
213            pub fn describe(
214                &mut self,
215                description: &str,
216                it: fn(&mut Unit) -> &mut Unit,
217            ) -> &mut Unit {
218                self.title(description);
219                it(self)
220            }
221
222            pub fn title(&mut self, description: &str) {
223                if self.assertions() == 0 && self.failures() == 0 {
224                    println!("{}\n", description.blue().bold());
225                } else {
226                    println!("\n\n{}\n", description.blue().bold());
227                }
228            }
229            pub fn theory(&mut self, description: &str, it: fn() -> bool) -> &mut Unit {
230                self.title(description);
231                self.assert(it(), THEORY_IS_TRUE, THEORY_IS_FALSE)
232            }
233
234            ///
235            /// # Check if a theory match false
236            ///
237            /// - `description` THe theory description
238            /// - `it`          The callback to execute
239            ///
240            pub fn chaos(&mut self, description: &str, it: fn() -> bool) -> &mut Unit {
241                self.title(description);
242                self.assert(!it(), THEORY_IS_FALSE, THEORY_IS_TRUE)
243            }
244
245            ///
246            ///
247            /// # Unit constructor
248            ///
249            /// - `description`     The unit test description
250            /// - `time`            The sleep time
251            ///
252            ///
253            pub fn new(description: &str, time: u64, s: Style) -> Unit {
254                println!("\n{}\n", description.magenta().bold());
255
256                Self {
257                    description: description.to_string(),
258                    assertions: Cell::new(0),
259                    failures: Cell::new(0),
260                    start: Instant::now(),
261                    tdd: Cell::new(0),
262                    sleep_time: time,
263                    style: s,
264                }
265            }
266
267            ///
268            ///
269            /// End of the tests
270            ///
271            pub fn end(&mut self) -> Result<String, String> {
272                let asserts = self.assertions();
273                let fails = self.failures();
274
275                println!(
276                    "\n\n{} : {}  {} : {}  {} : {} {} : {}\n",
277                    "Assertions".blue().bold(),
278                    asserts.to_string().green().bold(),
279                    "Failures".blue().bold(),
280                    fails.to_string().red().bold(),
281                    "Execution time".blue().bold(),
282                    self.start
283                        .elapsed()
284                        .as_millis()
285                        .to_string()
286                        .add(" ms")
287                        .magenta()
288                        .bold(),
289                    "All tests executed".blue().bold(),
290                    self.tdd.get().to_string().white().bold()
291                );
292
293                return if self.failures() >= 1 {
294                    Err(String::from(self.description.as_str()))
295                } else {
296                    Ok(String::from(self.description.as_str()))
297                };
298            }
299
300            ///
301            ///
302            /// # Check if all values are equals to true
303            ///
304            /// - `b`   A value to check
305            ///
306            pub fn ok(&mut self, b: bool) -> &mut Unit {
307                self.assert(b, IS_OK, IS_KO)
308            }
309
310            ///
311            ///
312            /// # Check if all values are equals to false
313            ///
314            /// - `b`   The value to check
315            ///
316            pub fn ko(&mut self, b: bool) -> &mut Unit {
317                self.assert(!b, IS_KO, IS_OK)
318            }
319
320            ///
321            /// # Check if two value are equals
322            ///
323            /// - `a`       The first value
324            /// - `b`       The second value
325            ///
326            pub fn equals<T: PartialEq>(&mut self, a: T, b: T) -> &mut Unit {
327                self.assert(a == b, IS_EQUALS, IS_UNEQUALS)
328            }
329
330            ///
331            ///
332            /// # Check if actual is in min and []ax value
333            ///
334            ///
335            /// - `actual`  The actual value
336            /// - `min`     The minimun value for actual
337            /// - `max`     The maximum value for actual
338            ///
339            pub fn between<T: PartialOrd>(&mut self, actual: T, min: T, max: T) -> &mut Unit {
340                self.assert(actual > min && actual < max, IS_BETWEEN, IS_NOT_BETWEEN)
341            }
342
343            ///
344            ///
345            /// Check if values are unequals
346            ///
347            /// - `a`   The first value
348            /// - `b`   The second value
349            ///
350            pub fn unequals<T: PartialEq>(&mut self, a: T, b: T) -> &mut Unit {
351                self.assert(a != b, IS_UNEQUALS, IS_EQUALS)
352            }
353
354            ///
355            /// # Check if the value is inferior to the maximum value
356            ///
357            /// - `actual`      The actual value
358            /// - `max`         The maximum value
359            ///
360            pub fn inferior<T: PartialOrd>(&mut self, actual: T, max: T) -> &mut Unit {
361                self.assert(actual < max, IS_INFERIOR, IS_SUPERIOR)
362            }
363
364            ///
365            /// # Check if the value is superior to the minimun value
366            ///
367            /// - `actual`      The actual value
368            /// - `min`         The minimum value
369            ///
370            pub fn superior<T: PartialOrd>(&mut self, actual: T, min: T) -> &mut Unit {
371                self.assert(actual > min, IS_SUPERIOR, IS_INFERIOR)
372            }
373
374            ///
375            ///
376            /// # Check if a string is not empty
377            ///
378            /// -  `x` The string to check
379            ///
380            pub fn not_empty(&mut self, x: &str) -> &mut Unit {
381                self.assert(!x.to_string().is_empty(), IS_NOT_EMPTY, IS_EMPTY)
382            }
383
384            ///
385            ///
386            /// # Check if a string contains another string
387            ///
388            /// -  `x`          The string to check
389            /// -  `expected`   The string to verify
390            ///
391            pub fn contains(&mut self, x: &str, expected: &str) -> &mut Unit {
392                self.assert(
393                    x.to_string().contains(expected),
394                    IS_CONTAINS,
395                    IS_NOT_CONTAINS,
396                )
397            }
398
399            ///
400            ///
401            /// # Check if a string not contains another string
402            ///
403            /// -  `x`          The string to check
404            /// -  `expected`   The string to verify
405            ///
406            pub fn not_contains(&mut self, x: &str, expected: &str) -> &mut Unit {
407                self.assert(
408                    !x.to_string().contains(expected),
409                    IS_CONTAINS,
410                    IS_NOT_CONTAINS,
411                )
412            }
413
414            ///
415            ///
416            /// # Check if a string is empty
417            ///
418            /// -  `x` The string to check
419            ///
420            pub fn empty(&mut self, x: &str) -> &mut Unit {
421                self.assert(x.to_string().is_empty(), IS_EMPTY, IS_NOT_EMPTY)
422            }
423
424            ///
425            /// # Check if the given value is a directory
426            ///
427            /// - `d` The path to check
428            ///
429            pub fn is_directory(&mut self, d: &str) -> &mut Unit {
430                self.assert(Path::new(d).is_dir(), IS_DIRECTORY, IS_NOT_DIRECTORY)
431            }
432
433            ///
434            /// # Check if the given value is not a directory
435            ///
436            /// - `d` The path to check
437            ///
438            pub fn is_not_directory(&mut self, d: &str) -> &mut Unit {
439                self.assert(!Path::new(d).is_dir(), IS_NOT_DIRECTORY, IS_DIRECTORY)
440            }
441
442            ///
443            /// # Check if the given value is a file
444            ///
445            /// - `f` The path to check
446            ///
447            pub fn is_file(&mut self, f: &str) -> &mut Unit {
448                self.assert(Path::new(f).is_file(), IS_FILE, IS_NOT_FILE)
449            }
450
451            ///
452            ///
453            /// # Chek if a path start with a expected base
454            ///
455            ///
456            /// - `path`    The path to check
457            /// - `base`    The path's base
458            ///
459            ///
460            pub fn path_start_with(&mut self, path: &str, base: &str) -> &mut Unit {
461                self.assert(
462                    Path::new(path).starts_with(base),
463                    IS_START_WITH,
464                    IS_NOT_START_WITH,
465                )
466            }
467
468            ///
469            ///
470            /// # Chek if a path is absolute
471            ///
472            /// - `path`    The path to check
473            ///
474            ///
475            pub fn path_absolute(&mut self, path: &str) -> &mut Unit {
476                self.assert(Path::new(path).is_absolute(), IS_ABSOLUTE, IS_NOT_ABSOLUTE)
477            }
478
479            ///
480            ///
481            /// # Chek if a path is not absolute
482            ///
483            /// - `path`    The path to check
484            ///
485            ///
486            pub fn path_not_absolute(&mut self, path: &str) -> &mut Unit {
487                self.assert(!Path::new(path).is_absolute(), IS_NOT_ABSOLUTE, IS_ABSOLUTE)
488            }
489
490            ///
491            ///
492            /// # Chek if a path exist
493            ///
494            /// - `path`    The path to check
495            ///
496            ///
497            pub fn path_exists(&mut self, path: &str) -> &mut Unit {
498                self.assert(Path::new(path).exists(), IS_EXISTS, IS_NOT_EXISTS)
499            }
500
501            ///
502            ///
503            /// # Chek if a path is not relative
504            ///
505            /// - `path`    The path to check
506            ///
507            pub fn path_not_relative(&mut self, path: &str) -> &mut Unit {
508                self.assert(!Path::new(path).is_relative(), IS_RELATIVE, IS_NOT_RELATIVE)
509            }
510
511            ///
512            ///
513            /// # Chek if a path is not relative
514            ///
515            /// - `path`    The path to check
516            ///
517            pub fn is_executable(&mut self, path: &str) -> &mut Unit {
518                self.assert(
519                    Path::new(path).is_executable(),
520                    IS_EXECUTABLE,
521                    IS_NOT_EXECUTABLE,
522                )
523            }
524
525            ///
526            ///
527            /// # Chek if a path is relative
528            ///
529            /// - `path`    The path to check
530            ///
531            pub fn is_not_executable(&mut self, path: &str) -> &mut Unit {
532                self.assert(
533                    !Path::new(path).is_executable(),
534                    IS_NOT_EXECUTABLE,
535                    IS_EXECUTABLE,
536                )
537            }
538
539            ///
540            ///
541            /// # Chek if a path is relative
542            ///
543            /// - `path`    The path to check
544            ///
545            pub fn path_symlink(&mut self, path: &str) -> &mut Unit {
546                self.assert(!Path::new(path).is_symlink(), IS_SYMLINK, IS_NOT_SYMLINK)
547            }
548
549            ///
550            ///
551            /// # Chek if a path exist
552            ///
553            /// - `path`    The path to check
554            ///
555            ///
556            pub fn path_relative(&mut self, path: &str) -> &mut Unit {
557                self.assert(Path::new(path).is_relative(), IS_RELATIVE, IS_NOT_RELATIVE)
558            }
559            ///
560            ///
561            /// # Chek if a path is not absolute
562            ///
563            /// - `path`    The path to check
564            ///
565            ///
566            pub fn path_no_exists(&mut self, path: &str) -> &mut Unit {
567                self.assert(!Path::new(path).exists(), IS_NOT_EXISTS, IS_EXISTS)
568            }
569
570            ///
571            /// # Check if a file contains an another string
572            ///
573            /// - `file`        The path to check
574            /// - `expected`    The expected value
575            ///
576            ///
577            pub fn file_contains(&mut self, file: &str, expected: &str) -> &mut Unit {
578                let content = std::fs::read_to_string(file).expect("Failed to parse file");
579
580                self.assert(content.contains(expected), IS_CONTAINS, IS_NOT_CONTAINS)
581            }
582
583            ///
584            /// # Check if a file no contains an another string
585            ///
586            /// - `file`        The path to check
587            /// - `expected`    The unexpected value
588            ///
589            ///
590            pub fn file_no_contains(&mut self, file: &str, expected: &str) -> &mut Unit {
591                let content = std::fs::read_to_string(file).expect("Failed to parse file");
592                self.assert(content.contains(expected), IS_NOT_CONTAINS, IS_CONTAINS)
593            }
594            ///
595            /// # Check if two vec length are equals
596            ///
597            /// - `a`   The first vector
598            /// - `b`   The second vector
599            ///
600            pub fn vec_length_equals<T: PartialEq>(&mut self, a: Vec<T>, b: Vec<T>) -> &mut Unit {
601                self.assert(a.len() == b.len(), IS_EQUALS, IS_UNEQUALS)
602            }
603
604            ///
605            /// # Check if two vec length are unequals
606            ///
607            /// - `a`   The first vector
608            /// - `b`   The second vector
609            ///
610            pub fn vec_length_unequals<T: PartialEq>(&mut self, a: Vec<T>, b: Vec<T>) -> &mut Unit {
611                self.assert(a.len() != b.len(), IS_UNEQUALS, IS_EQUALS)
612            }
613
614            ///
615            /// # Check if a vec contains a value
616            ///
617            /// - `a`   The vector
618            /// - `b`   The value
619            ///
620            pub fn vec_contains<T: PartialEq>(&mut self, a: Vec<T>, b: T) -> &mut Unit {
621                self.assert(a.contains(&b), IS_CONTAINS, IS_NOT_CONTAINS)
622            }
623
624            ///
625            /// # Check if a vec not contains a value
626            ///
627            /// - `a`   The vector
628            /// - `b`   The value
629            ///
630            pub fn vec_no_contains<T: PartialEq>(&mut self, a: Vec<T>, b: T) -> &mut Unit {
631                self.assert(!a.contains(&b), IS_NOT_CONTAINS, IS_CONTAINS)
632            }
633
634            ///
635            /// # Check if a vec start with a value
636            ///
637            /// - `a`   The vector
638            /// - `b`   The value
639            ///
640            pub fn vec_start_with<T: PartialEq>(&mut self, a: Vec<T>, b: T) -> &mut Unit {
641                self.assert(a.starts_with(&[b]), IS_START_WITH, IS_NOT_START_WITH)
642            }
643
644            ///
645            /// # Check if a vec no start with a value
646            ///
647            /// - `a`   The vector
648            /// - `b`   The value
649            ///
650            pub fn vec_no_start_with<T: PartialEq>(&mut self, a: Vec<T>, b: T) -> &mut Unit {
651                self.assert(!a.starts_with(&[b]), IS_NOT_CONTAINS, IS_CONTAINS)
652            }
653
654            ///
655            /// # Check if a vec finnish with a value
656            ///
657            /// - `a`   The vector
658            /// - `b`   The value
659            ///
660            pub fn vec_end_with<T: PartialEq>(&mut self, a: Vec<T>, b: T) -> &mut Unit {
661                self.assert(a.ends_with(&[b]), IS_FINNISH_WITH, IS_NOT_FINNISH_WITH)
662            }
663
664            ///
665            /// # Check if a vec finnish with a value
666            ///
667            /// - `a`   The vector
668            /// - `b`   The value
669            ///
670            pub fn vec_no_end_with<T: PartialEq>(&mut self, a: Vec<T>, b: T) -> &mut Unit {
671                self.assert(!a.ends_with(&[b]), IS_NOT_FINNISH_WITH, IS_FINNISH_WITH)
672            }
673
674            ///
675            /// # Check if a vec is empty
676            ///
677            /// - `a`   The vector
678            ///
679            pub fn vec_empty<T: PartialEq>(&mut self, a: Vec<T>) -> &mut Unit {
680                self.assert(a.is_empty(), IS_EMPTY, IS_NOT_EMPTY)
681            }
682
683            ///
684            /// # Check if a vec is not empty
685            ///
686            /// - `a`   The vector
687            ///
688            pub fn vec_not_empty<T: PartialEq>(&mut self, a: Vec<T>) -> &mut Unit {
689                self.assert(!a.is_empty(), IS_NOT_EMPTY, IS_EMPTY)
690            }
691
692            //
693            /// # Check if the return of the callback is not at this maximum value
694            ///
695            /// - `callback`        The callback to check
696            /// - `max`             The callback maximum value
697            ///
698            pub fn full(&mut self, callback: fn() -> usize, max: usize) -> &mut Unit {
699                self.assert((callback() / max) == 1, IS_FULL, IS_NOT_FULL)
700            }
701
702            //
703            /// # Check if the return of the callback is not at this maximum value
704            ///
705            /// - `callback`        The callback to check
706            /// - `max`             The callback maximum value
707            ///
708            pub fn not_full(&mut self, callback: fn() -> usize, max: usize) -> &mut Unit {
709                self.assert((callback() / max) < 1, IS_NOT_FULL, IS_FULL)
710            }
711
712            ///
713            /// # Check if the value is a prime number
714            ///
715            /// - `x`       The value to check
716            ///
717            pub fn prime(&mut self, x: usize) -> &mut Unit {
718                self.assert(x % 2 != 0 && x % 3 != 0, IS_NOT_PRIME, IS_PRIME)
719            }
720
721            ///
722            /// # Check if the value is a pair number
723            ///
724            /// - `x`       The value to check
725            ///
726            pub fn pair(&mut self, x: usize) -> &mut Unit {
727                self.assert(x % 2 == 0, IS_PAIR, IS_IMPAIR)
728            }
729
730            ///
731            /// # Check if the value is an impair number
732            ///
733            /// - `x`       The value to check
734            ///
735            pub fn impair(&mut self, x: usize) -> &mut Unit {
736                if x % 2 == 0 {
737                    return self.assert(false, IS_PAIR, IS_PAIR);
738                }
739                if x % 3 == 0 {
740                    return self.assert(true, IS_IMPAIR, IS_PAIR);
741                }
742                return self.assert(false, IS_PRIME, IS_PRIME);
743            }
744        }
745
746        ///
747        /// # Check if all values matches true
748        ///
749        /// - `description`     The unit description
750        /// - `items`           A vector contening boolean values
751        ///
752        #[macro_export]
753        macro_rules! assert_true {
754            ($description:expr,$items:expr) => {
755                let mut u = Unit::new($description, NO_PROGRESS, POINT);
756                for &item in $items.iter() {
757                    u.ok(item);
758                }
759                u.end().expect("A result not match true");
760            };
761        }
762
763        ///
764        /// # Check if all values matches false
765        ///
766        /// - `description`     The unit description
767        /// - `items`           A vector contening boolean values
768        ///
769        #[macro_export]
770        macro_rules! assert_false {
771            ($description:expr,$items:expr) => {
772                let mut u = Unit::new($description, NO_PROGRESS, POINT);
773                for &item in $items.iter() {
774                    u.ko(item);
775                }
776                u.end().expect("A result not match false");
777            };
778        }
779
780        ///
781        /// # Check if all directories exist
782        ///
783        /// - `description`     The unit description
784        /// - `items`           A vector contening all paths
785        ///
786        #[macro_export]
787        macro_rules! assert_directory_exist {
788            ($description:expr,$items:expr) => {
789                let mut u = Unit::new($description, NO_PROGRESS, POINT);
790                for &item in $items.iter() {
791                    u.is_directory(item);
792                }
793                u.end().expect("A directory has not been founded");
794            };
795        }
796
797        ///
798        /// # Check if all files exist
799        ///
800        /// - `description`     The unit description
801        /// - `items`           A vector contening all paths
802        ///
803        #[macro_export]
804        macro_rules! assert_files_exist {
805            ($description:expr,$items:expr) => {
806                let mut u = Unit::new($description, NO_PROGRESS, POINT);
807                for &item in $items.iter() {
808                    u.is_file(item);
809                }
810                u.end().expect("A file has not been founded");
811            };
812        }
813
814        ///
815        /// # Check if a value contains an another
816        ///
817        /// - `description`     The unit description
818        /// - `items`           A vector contening all expected values
819        /// - `v`               The actual value to check if contains data
820        ///
821        #[macro_export]
822        macro_rules! assert_contains {
823            ($description:expr,$items:expr,$v:expr) => {
824                let mut u = Unit::new($description, NO_PROGRESS, POINT);
825                for &item in $items.iter() {
826                    u.contains($v, item);
827                }
828                u.end().expect("A value has not been founded");
829            };
830        }
831
832        ///
833        /// # Check if a value not contains an another
834        ///
835        /// - `description`     The unit description
836        /// - `items`           A vector contening all expected values
837        /// - `v`               The actual value to check if not contains data
838        ///
839        #[macro_export]
840        macro_rules! assert_not_contains {
841            ($description:expr,$items:expr,$v:expr) => {
842                let mut u = Unit::new($description, NO_PROGRESS, POINT);
843                for &item in $items.iter() {
844                    u.not_contains($v, item);
845                }
846                u.end().expect("A value has not been founded");
847            };
848        }
849
850        ///
851        /// # Check if a value not contains an another
852        ///
853        /// - `description`     The unit description
854        /// - `items`           A vector contening all expected values
855        ///
856        #[macro_export]
857        macro_rules! assert_not_exe {
858            ($description:expr,$items:expr) => {
859                let mut u = Unit::new($description, NO_PROGRESS, POINT);
860                for &item in $items.iter() {
861                    u.not_exe(item);
862                }
863                u.end().expect("A value is not an executable");
864            };
865        }
866
867        ///
868        /// # Check if a value equal to an another
869        ///
870        /// - `description`     The unit description
871        /// - `items`           A vector contening all values
872        /// - `v`               The actual value to check equality
873        ///
874        #[macro_export]
875        macro_rules! assert_equals {
876            ($description:expr,$items:expr,$v:expr) => {
877                let mut u = Unit::new($description, NO_PROGRESS, POINT);
878                for &item in $items.iter() {
879                    u.equals($v, item);
880                }
881                u.end().expect("A value not equal to the expected value");
882            };
883        }
884
885        ///
886        /// # Check if a value not equal to an another
887        ///
888        /// - `description`     The unit description
889        /// - `items`           A vector contening all values
890        /// - `v`               The actual value to check unequality
891        ///
892        #[macro_export]
893        macro_rules! assert_unequals {
894            ($description:expr,$items:expr,$v:expr) => {
895                let mut u = Unit::new($description, NO_PROGRESS, POINT);
896                for &item in $items.iter() {
897                    u.unequals($v, item);
898                }
899                u.end().expect("A value equal to the expected value");
900            };
901        }
902
903        ///
904        /// # Check if a value not equal to an another
905        ///
906        /// - `description`     The unit description
907        /// - `items`           A vector contening all values
908        /// - `v`               The actual value to check unequality
909        ///
910        #[macro_export]
911        macro_rules! unit {
912            ($description:expr) => {
913                Unit::new($description, NO_PROGRESS, POINT)
914            };
915        }
916
917        ///
918        /// # Check if a value not contains an another
919        ///
920        /// - `description`     The unit description
921        /// - `items`           A vector contening all expected values
922        /// - `v`               The actual value to check if not contains data
923        ///
924        #[macro_export]
925        macro_rules! assert_exe {
926            ($description:expr,$items:expr) => {
927                let mut u = Unit::new($description, NO_PROGRESS, POINT);
928                for &item in $items.iter() {
929                    u.exe(item);
930                }
931                u.end().expect("A value is not an executable");
932            };
933        }
934    }
935}
936
937#[cfg(test)]
938mod tests {
939
940    use crate::{
941        assert_contains, assert_directory_exist, assert_equals, assert_false, assert_files_exist,
942        assert_not_contains, assert_not_exe, assert_true, assert_unequals,
943        tdd::unit::{Style::POINT, Unit, NO_PROGRESS},
944        unit,
945    };
946    use std::env::consts::OS;
947    fn battery_full() -> usize {
948        100
949    }
950    fn battery_not_full() -> usize {
951        50
952    }
953
954    fn together() -> bool {
955        false
956    }
957
958    fn pythagore() -> bool {
959        4 * 4 + 3 * 3 == 5 * 5
960    }
961
962    fn admin(u: &mut Unit) -> &mut Unit {
963        u.inferior(1, 2).prime(1).superior(1, 0).between(1, 0, 2)
964    }
965
966    fn boolean(u: &mut Unit) -> &mut Unit {
967        u.ok(pythagore())
968            .ko(together())
969            .theory("Check the theorm of pythagore", pythagore)
970            .chaos("The bigbang", together)
971            .is_directory(".")
972            .is_file("README.md")
973    }
974
975    fn git_test_install(u: &mut Unit) -> &mut Unit {
976        u.exe("/usr/bin/git")
977    }
978
979    fn e(u: &mut Unit) -> &mut Unit {
980        u.empty("").not_empty(OS)
981    }
982    fn battery(u: &mut Unit) -> &mut Unit {
983        u.full(battery_full, 100).not_full(battery_not_full, 100)
984    }
985    fn equals(u: &mut Unit) -> &mut Unit {
986        u.equals(true, pythagore())
987            .unequals(false, pythagore())
988            .equals_bytes("hello", &[104, 101, 108, 108, 111])
989            .unequals_bytes("hallo", &[104, 101, 108, 108, 111])
990    }
991
992    fn numbers(u: &mut Unit) -> &mut Unit {
993        u.prime(1).prime(7).prime(11);
994        u.pair(2).pair(4).pair(6);
995        u.impair(3).impair(9)
996    }
997
998    #[test]
999    pub fn test_see() {
1000        assert!(Unit::see("https://www.google.com", "google"));
1001    }
1002
1003    #[test]
1004    pub fn unit() {
1005        unit!("Test the unit framework")
1006            .describe("Check theories", boolean)
1007            .describe("Test charge", battery)
1008            .describe("Check admin users accout number", admin)
1009            .describe("Test number", numbers)
1010            .describe("They are equals", equals)
1011            .describe("Check empty", e)
1012            .describe("Check if git is installed", git_test_install)
1013            .end()
1014            .expect("failed");
1015    }
1016
1017    #[test]
1018    pub fn test_macros() {
1019        assert_true!("All values must matches true", vec![true, true, true]);
1020        assert_false!("All values must matches false", vec![false, false, false]);
1021        assert_directory_exist!(
1022            "Check if user use linux",
1023            vec!["/", "/home", "/etc", ".", ".."]
1024        );
1025        assert_files_exist!(
1026            "Check if user use linux",
1027            vec!["/etc/hosts", "/etc/locale.conf"]
1028        );
1029
1030        assert_not_exe!(
1031            "Check if configugrations files is not an executable",
1032            vec!["/etc/hosts", "/etc/locale.gen"]
1033        );
1034
1035        assert_contains!("Check if user use linux", vec!["linux"], OS);
1036        assert_not_contains!(
1037            "Check if user use linux",
1038            vec!["windows", "ios", "freebsd", "openbsd", "android", "solaris", "netbsd", "macos"],
1039            OS
1040        );
1041
1042        assert_equals!(
1043            "All value must be equals to linux",
1044            vec!["linux", "linux", "linux"],
1045            OS
1046        );
1047
1048        assert_unequals!(
1049            "All os must be only equals to linux",
1050            vec!["windows", "ios", "freebsd", "openbsd", "android", "solaris", "netbsd", "macos"],
1051            OS
1052        );
1053    }
1054}