dsntk_model_evaluator/
lib.rs

1#[macro_use]
2extern crate dsntk_macros;
3
4mod boxed_expressions;
5mod business_knowledge_model;
6mod decision;
7mod decision_service;
8mod decision_table;
9mod errors;
10mod input_data;
11mod input_data_context;
12mod item_definition;
13mod item_definition_context;
14mod item_definition_type;
15mod model_builder;
16mod model_definitions;
17mod model_evaluator;
18mod type_ref;
19mod variable;
20
21#[cfg(test)]
22mod tests;
23
24pub use decision_table::build_decision_table_evaluator;
25pub use model_evaluator::ModelEvaluator;
26
27#[cfg(test)]
28mod utilities {
29  use antex::{ColorMode, StyledText, Text};
30  use std::collections::{BTreeMap, BTreeSet};
31  use std::fs;
32  use walkdir::WalkDir;
33
34  /// This is a utility function for comparing the number of compatibility tests
35  /// with the number of compatibility benchmarks, used to verify if all tests
36  /// are also benchmarked.
37  #[test]
38  fn compare_the_number_of_tests_and_benchmarks() {
39    let (tests, test_count) = count_number_of_artefacts("src/tests/compatibility", "#[test]");
40    let (benches, bench_count) = count_number_of_artefacts("benches/compatibility", "#[bench]");
41    println!("---------------------------------------------------------------");
42    println!("      tests: {}", test_count);
43    println!(" benchmarks: {}", bench_count);
44    println!("---------------------------------------------------------------");
45    println!(" {:29} {:^9} {:^6} {:^6}", "File name", "Tests", "Benchmarks", "Difference");
46    println!("---------------------------------------------------------------");
47    let mut file_names = BTreeSet::new();
48    file_names.append(&mut tests.keys().map(|key| key.to_string()).collect::<BTreeSet<String>>());
49    file_names.append(&mut benches.keys().map(|key| key.to_string()).collect::<BTreeSet<String>>());
50    for file_name in &file_names {
51      let t_count = tests.get(file_name).unwrap_or(&0_usize).to_owned();
52      let b_count = benches.get(file_name).unwrap_or(&0_usize).to_owned();
53      println!("{:30} {:>6} {:>12} {}", file_name, t_count, b_count, diff(t_count, b_count));
54    }
55    println!("---------------------------------------------------------------");
56    println!("{:30} {:>6} {:>12} {}", "Total", test_count, bench_count, diff(test_count, bench_count));
57  }
58
59  /// Counts the number of specific words in a file.
60  fn count_number_of_artefacts(root_dir: &str, artefact: &str) -> (BTreeMap<String, usize>, usize) {
61    let mut results = BTreeMap::new();
62    let mut total = 0_usize;
63    for entry_result in WalkDir::new(root_dir).into_iter() {
64      match entry_result {
65        Ok(entry) => {
66          let path = entry.path();
67          if path.is_file() && path.extension().map_or(false, |ext| ext == "rs") {
68            let content = fs::read_to_string(path).unwrap_or_else(|e| panic!("failed to load file: {} with reason: {}", path.display(), e));
69            let mut count = 0_usize;
70            for line in content.lines() {
71              if line.trim() == artefact {
72                count += 1;
73              }
74            }
75            if count > 1 {
76              results.insert(path.strip_prefix(root_dir).unwrap().display().to_string(), count);
77              total += count;
78            }
79          }
80        }
81        Err(reason) => eprintln!("{}", reason),
82      }
83    }
84    (results, total)
85  }
86
87  /// Prepares the difference in text format.
88  fn diff(a: usize, b: usize) -> String {
89    let diff = if a > b { a - b } else { b - a };
90    if diff > 0 {
91      Text::new(ColorMode::On).red().s(format!("{:>9}", diff)).clear().to_string()
92    } else {
93      "".to_string()
94    }
95  }
96}