dmntk_model_evaluator/
lib.rs

1#[macro_use]
2extern crate dmntk_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 dmntk_common::{color_red, color_reset, ColorMode};
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  #[ignore]
39  fn compare_the_number_of_tests_and_benchmarks() {
40    let (tests, test_count) = count_number_of_artefacts("src/tests/compatibility", "#[test]");
41    let (benches, bench_count) = count_number_of_artefacts("benches/compatibility", "#[bench]");
42    println!("---------------------------------------------------------------");
43    println!("      tests: {}", test_count);
44    println!(" benchmarks: {}", bench_count);
45    println!("---------------------------------------------------------------");
46    println!(" {:29} {:^9} {:^6} {:^6}", "File name", "Tests", "Benchmarks", "Difference");
47    println!("---------------------------------------------------------------");
48    let mut file_names = BTreeSet::new();
49    file_names.append(&mut tests.keys().map(|key| key.to_string()).collect::<BTreeSet<String>>());
50    file_names.append(&mut benches.keys().map(|key| key.to_string()).collect::<BTreeSet<String>>());
51    for file_name in &file_names {
52      let t_count = tests.get(file_name).unwrap_or(&0_usize).to_owned();
53      let b_count = benches.get(file_name).unwrap_or(&0_usize).to_owned();
54      println!("{:30} {:>6} {:>12} {}", file_name, t_count, b_count, diff(t_count, b_count));
55    }
56    println!("---------------------------------------------------------------");
57    println!("{:30} {:>6} {:>12} {}", "Total", test_count, bench_count, diff(test_count, bench_count));
58  }
59
60  /// Counts the number of specific words in a file.
61  fn count_number_of_artefacts(root_dir: &str, artefact: &str) -> (BTreeMap<String, usize>, usize) {
62    let mut results = BTreeMap::new();
63    let mut total = 0_usize;
64    for entry_result in WalkDir::new(root_dir).into_iter() {
65      match entry_result {
66        Ok(entry) => {
67          let path = entry.path();
68          if path.is_file() && path.extension().is_some_and(|ext| ext == "rs") {
69            let content = fs::read_to_string(path).unwrap_or_else(|e| panic!("failed to load file: {} with reason: {}", path.display(), e));
70            let mut count = 0_usize;
71            for line in content.lines() {
72              if line.trim() == artefact {
73                count += 1;
74              }
75            }
76            if count > 1 {
77              results.insert(path.strip_prefix(root_dir).unwrap().display().to_string(), count);
78              total += count;
79            }
80          }
81        }
82        Err(reason) => eprintln!("{}", reason),
83      }
84    }
85    (results, total)
86  }
87
88  /// Prepares the difference in text format.
89  fn diff(a: usize, b: usize) -> String {
90    let color_red = color_red!(ColorMode::On);
91    let color_reset = color_reset!(ColorMode::On);
92    let diff = if a > b { a - b } else { b - a };
93    if diff > 0 {
94      format!("{1}{2:>9}{0}", color_reset, color_red, diff)
95    } else {
96      "".to_string()
97    }
98  }
99}