Skip to content

Commit e4021e1

Browse files
committed
Increased test coverage
Signed-off-by: Marvin Hansen <[email protected]>
1 parent d81c53d commit e4021e1

File tree

3 files changed

+156
-8
lines changed

3 files changed

+156
-8
lines changed

deep_causality/src/types/causal_types/causaloid/causable.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,20 +106,29 @@ where
106106
}
107107

108108
CausaloidType::Collection => {
109-
// Delegates to the `explain` method provided by the `CausableReasoning` trait.
110-
Ok(self
111-
.causal_coll
109+
// Safely unwrap the collection or return a descriptive error.
110+
self.causal_coll
112111
.as_ref()
113-
.expect("Causaloid collection should not be None")
114-
.explain()?)
112+
.ok_or_else(|| {
113+
CausalityError(format!(
114+
"Causaloid {} is type Collection but its collection is None",
115+
self.id
116+
))
117+
})?
118+
.explain() // Delegate to the collection's explain method.
115119
}
116120

117121
CausaloidType::Graph => {
118-
// Delegates to the `explain` method on the graph itself.
122+
// Safely unwrap the graph or return a descriptive error.
119123
self.causal_graph
120124
.as_ref()
121-
.expect("Causaloid graph should not be None")
122-
.explain()
125+
.ok_or_else(|| {
126+
CausalityError(format!(
127+
"Causaloid {} is type Graph but its graph is None",
128+
self.id
129+
))
130+
})?
131+
.explain() // Delegate to the graph's explain method.
123132
}
124133
}
125134
}

deep_causality/tests/types/causal_types/causaloid/causaloid_tests.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,3 +289,109 @@ fn test_debug() {
289289
let actual_active = format!("{causaloid:?}");
290290
assert_eq!(actual_active, expected_active);
291291
}
292+
293+
#[test]
294+
fn test_evaluate_collection_with_halting_effect() {
295+
// Setup: A collection where a Halting causaloid appears before a 'true' one.
296+
let halting_causaloid = test_utils::get_test_causaloid_halting();
297+
let true_causaloid = test_utils::get_test_causaloid_deterministic_true();
298+
let causal_coll = vec![halting_causaloid, true_causaloid];
299+
let collection_causaloid =
300+
Causaloid::from_causal_collection(100, Arc::new(causal_coll), "Halting Collection");
301+
302+
// Act
303+
let evidence = Evidence::Numerical(0.0);
304+
let effect = collection_causaloid.evaluate(&evidence).unwrap();
305+
306+
// Assert: The Halting effect should short-circuit the evaluation.
307+
assert_eq!(effect, PropagatingEffect::Halting);
308+
}
309+
310+
#[test]
311+
fn test_evaluate_collection_without_true_effect() {
312+
// Setup: A collection with only 'false' causaloids.
313+
let false_causaloid1 = test_utils::get_test_causaloid_deterministic_false();
314+
let false_causaloid2 = test_utils::get_test_causaloid_deterministic_false();
315+
let causal_coll = vec![false_causaloid1, false_causaloid2];
316+
let collection_causaloid =
317+
Causaloid::from_causal_collection(101, Arc::new(causal_coll), "All False Collection");
318+
319+
// Act
320+
let evidence = Evidence::Numerical(0.0);
321+
let effect = collection_causaloid.evaluate(&evidence).unwrap();
322+
323+
// Assert: Since no causaloid is true, the aggregated effect should be false.
324+
assert_eq!(effect, PropagatingEffect::Deterministic(false));
325+
}
326+
327+
#[test]
328+
fn test_evaluate_collection_with_sub_evaluation_error() {
329+
// Setup: A collection containing a causaloid that will return an error.
330+
let error_causaloid = test_utils::get_test_error_causaloid();
331+
let true_causaloid = test_utils::get_test_causaloid_deterministic_true();
332+
333+
// The error_causaloid must come first to ensure it gets evaluated.
334+
let causal_coll = vec![error_causaloid, true_causaloid]; // <-- The order is swapped here.
335+
336+
let collection_causaloid =
337+
Causaloid::from_causal_collection(102, Arc::new(causal_coll), "Error Collection");
338+
339+
// Act
340+
let evidence = Evidence::Numerical(0.0);
341+
let result = collection_causaloid.evaluate(&evidence);
342+
343+
// Assert: The error from the sub-causaloid should now be propagated up.
344+
assert!(result.is_err());
345+
let err = result.unwrap_err();
346+
assert!(err.to_string().contains("Test error"));
347+
}
348+
#[test]
349+
fn test_explain_collection_success() {
350+
// Setup: A collection causaloid that has been evaluated.
351+
let true_causaloid = test_utils::get_test_causaloid_deterministic_true();
352+
let false_causaloid = test_utils::get_test_causaloid_deterministic_false();
353+
354+
// The `false` causaloid must come first to ensure the `evaluate` loop
355+
// does not short-circuit before evaluating both.
356+
let causal_coll = vec![false_causaloid, true_causaloid]; // <-- Swapped order
357+
358+
let collection_causaloid =
359+
Causaloid::from_causal_collection(104, Arc::new(causal_coll), "Explainable Collection");
360+
361+
// Act: Evaluate the collection. Now both members will be evaluated.
362+
let evidence = Evidence::Numerical(0.0);
363+
collection_causaloid.evaluate(&evidence).unwrap();
364+
365+
// Now, call explain.
366+
let explanation = collection_causaloid.explain().unwrap();
367+
368+
// Assert: The explanation should contain the results from both sub-causaloids.
369+
assert!(explanation.contains("evaluated to: Deterministic(true)"));
370+
assert!(explanation.contains("evaluated to: Deterministic(false)"));
371+
}
372+
// This test covers an error path in explain() for a Collection Causaloid.
373+
#[test]
374+
fn test_explain_collection_with_sub_explain_error() {
375+
// Setup: A collection where one causaloid will not be evaluated due to short-circuiting.
376+
let true_causaloid = test_utils::get_test_causaloid_deterministic_true();
377+
let unevaluated_causaloid = test_utils::get_test_causaloid(); // This one will remain unevaluated.
378+
379+
let causal_coll = vec![true_causaloid, unevaluated_causaloid];
380+
let collection_causaloid = Causaloid::from_causal_collection(
381+
105,
382+
Arc::new(causal_coll),
383+
"Sub-explain Error Collection",
384+
);
385+
386+
// Act: Evaluate the collection. The evaluation will stop after the first `true` effect.
387+
let evidence = Evidence::Numerical(0.0);
388+
collection_causaloid.evaluate(&evidence).unwrap();
389+
390+
// Now, call explain. This will fail because the second causaloid was never evaluated.
391+
let result = collection_causaloid.explain();
392+
393+
// Assert: The result should be an error.
394+
assert!(result.is_err());
395+
let err_msg = result.unwrap_err().to_string();
396+
assert!(err_msg.contains("has not been evaluated"));
397+
}

deep_causality/tests/types/model_types/assumption/assumption_tests.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,39 @@ fn test_assumption_description() {
7575
assert_eq!(assumption.description(), description)
7676
}
7777

78+
#[test]
79+
fn test_assumption_debug() {
80+
let assumption = get_test_assumption();
81+
let id = 1;
82+
let description = "Test assumption that data are there";
83+
84+
// 1. Test initial state (before verification)
85+
let expected_initial = format!(
86+
"Assumption: id: {}, description: {}, assumption_fn: fn(&[NumericalValue]) -> bool;, assumption_tested: {},assumption_valid: {}",
87+
id, description, false, false
88+
);
89+
90+
// Test the Display trait implementation
91+
assert_eq!(format!("{assumption}"), expected_initial);
92+
// Test the Debug trait implementation
93+
assert_eq!(format!("{assumption:?}"), expected_initial);
94+
95+
// 2. Verify the assumption to change its internal state
96+
let data = get_test_num_array();
97+
assumption.verify_assumption(&data); // This sets tested and valid to true
98+
99+
// 3. Test final state (after verification)
100+
let expected_after_verify = format!(
101+
"Assumption: id: {}, description: {}, assumption_fn: fn(&[NumericalValue]) -> bool;, assumption_tested: {},assumption_valid: {}",
102+
id, description, true, true
103+
);
104+
105+
// Test the Display trait again
106+
assert_eq!(format!("{assumption}"), expected_after_verify);
107+
// Test the Debug trait again
108+
assert_eq!(format!("{assumption:?}"), expected_after_verify);
109+
}
110+
78111
#[test]
79112
fn test_assumption_to_string() {
80113
let id = 1;

0 commit comments

Comments
 (0)