Skip to content

Commit a4ca539

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

File tree

4 files changed

+164
-13
lines changed

4 files changed

+164
-13
lines changed

deep_causality/src/traits/causable/causable_reasoning.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ where
6666
_ => {
6767
// Any other effect type is a contract violation for this function.
6868
return Err(CausalityError(format!(
69-
"evaluate_deterministic_chain encountered a non-deterministic effect: {effect:?}. Only Deterministic effects are allowed."
69+
"evaluate_deterministic_propagation encountered a non-deterministic effect: {effect:?}. Only Deterministic effects are allowed."
7070
)));
7171
}
7272
}

deep_causality/src/utils_test/test_utils.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@ pub fn get_test_inf_vec() -> Vec<Inference> {
2727
Vec::from_iter([i1, i2])
2828
}
2929

30-
pub fn get_test_causality_false_vec() -> BaseCausaloidVec {
31-
let q1 = get_test_causaloid_deterministic_false();
32-
let q2 = get_test_causaloid_deterministic_false();
33-
let q3 = get_test_causaloid_deterministic_false();
34-
Vec::from_iter([q1, q2, q3])
35-
}
36-
3730
pub fn get_test_causality_vec() -> BaseCausaloidVec {
3831
let q1 = get_test_causaloid();
3932
let q2 = get_test_causaloid();

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ fn unpack_evidence(evidence: &Evidence) -> Result<NumericalValue, CausalityError
1414
if let Evidence::Numerical(val) = evidence {
1515
Ok(*val)
1616
} else {
17-
Err(CausalityError("Expected Numerical evidence.".into()))
17+
Err(CausalityError(format!(
18+
"Expected Numerical evidence, got: {evidence:?}"
19+
)))
1820
}
1921
}
2022

deep_causality/tests/types/csm_types/csm_tests.rs

Lines changed: 160 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,9 @@ fn eval_single_state_success_fires_action() {
331331
fn eval_single_state_success_inactive_no_action() {
332332
let id = 42;
333333
let version = 1;
334-
let data = Evidence::Numerical(0.88f64);
335-
let causaloid = test_utils::get_test_causaloid(); // Returns Deterministic(false) for data > 0.5
334+
// Use data that makes the state inactive (0.23 < 0.55 threshold)
335+
let data = Evidence::Numerical(0.23f64);
336+
let causaloid = test_utils::get_test_causaloid(); // Returns Deterministic(false)
336337

337338
let cs = CausalState::new(id, version, data, causaloid);
338339
// Use an action that would fail to prove it's not being called.
@@ -341,10 +342,11 @@ fn eval_single_state_success_inactive_no_action() {
341342
let csm = CSM::new(state_action);
342343

343344
// Data that makes the state inactive
344-
let eval_data = test_utils::get_test_single_data(0.88f64);
345+
let eval_data = test_utils::get_test_single_data(0.23f64);
345346
// Use the correct ID
346347
let res = csm.eval_single_state(id, eval_data);
347-
assert!(res.is_err());
348+
// Should be Ok because the state is inactive, so the failing action is never fired.
349+
assert!(res.is_ok());
348350
}
349351

350352
// Test for the case where the state does not exist.
@@ -366,3 +368,157 @@ fn eval_single_state_error_not_found() {
366368
assert!(res.is_err());
367369
assert!(res.unwrap_err().0.contains("State 99 does not exist"));
368370
}
371+
372+
// This test covers the case where the state evaluation itself fails.
373+
// It adds coverage for the branch you identified.
374+
#[test]
375+
fn eval_single_state_error_eval_fails() {
376+
let id = 42;
377+
let version = 1;
378+
let data = Evidence::Numerical(0.23f64);
379+
// This causaloid's causal_fn always returns an error.
380+
let causaloid = get_test_error_causaloid();
381+
382+
let cs = CausalState::new(id, version, data, causaloid);
383+
let ca = get_test_action(); // Action won't be reached
384+
let state_action = &[(&cs, &ca)];
385+
let csm = CSM::new(state_action);
386+
387+
let eval_data = test_utils::get_test_single_data(0.23f64);
388+
// Use the correct ID to ensure we get past the 'not found' check.
389+
let res = csm.eval_single_state(id, eval_data);
390+
391+
// The result should be an error because state.eval_with_data failed.
392+
assert!(res.is_err());
393+
let err_msg = res.unwrap_err().0;
394+
assert!(err_msg.contains(&format!("CSM[eval]: Error evaluating state {id}")));
395+
}
396+
397+
// This test covers the case where the action fails to fire.
398+
#[test]
399+
fn eval_single_state_error_action_fails() {
400+
let id = 42;
401+
let version = 1;
402+
// Use data that makes the state active (0.60 > 0.55 threshold in test_causaloid)
403+
let data = Evidence::Numerical(0.60f64);
404+
let causaloid = test_utils::get_test_causaloid(); // Returns Deterministic(true)
405+
406+
let cs = CausalState::new(id, version, data, causaloid);
407+
// Use an action that is designed to fail.
408+
let ca = get_test_error_action();
409+
let state_action = &[(&cs, &ca)];
410+
let csm = CSM::new(state_action);
411+
412+
// Data that will make the state active
413+
let eval_data = test_utils::get_test_single_data(0.60f64);
414+
// Use the correct ID
415+
let res = csm.eval_single_state(id, eval_data);
416+
417+
assert!(res.is_err());
418+
let err_msg = res.unwrap_err().0;
419+
assert!(err_msg.contains(&format!(
420+
"CSM[eval]: Failed to fire action for state {id}"
421+
)));
422+
}
423+
424+
// I've renamed the original test to be more descriptive.
425+
// It correctly tests the success path where a state is inactive.
426+
#[test]
427+
fn eval_all_states_success_inactive_state() {
428+
let id = 42;
429+
let version = 1;
430+
// Data that makes the state inactive (0.23 < 0.55 threshold)
431+
let data = test_utils::get_test_single_data(0.23f64);
432+
let causaloid = test_utils::get_test_causaloid();
433+
434+
let cs = CausalState::new(id, version, data, causaloid);
435+
let ca = get_test_action();
436+
let state_action = &[(&cs, &ca)];
437+
let csm = CSM::new(state_action);
438+
439+
let res = csm.eval_all_states();
440+
assert!(res.is_ok())
441+
}
442+
443+
// New test for the success path where a state is active and the action fires.
444+
#[test]
445+
fn eval_all_states_success_active_state_fires_action() {
446+
let id = 42;
447+
let version = 1;
448+
// Data that makes the state active (0.6 > 0.55 threshold)
449+
let data = Evidence::Numerical(0.60f64);
450+
let causaloid = test_utils::get_test_causaloid(); // Returns Deterministic(true)
451+
452+
let cs = CausalState::new(id, version, data, causaloid);
453+
let ca = get_test_action(); // Succeeds
454+
let state_action = &[(&cs, &ca)];
455+
let csm = CSM::new(state_action);
456+
457+
let res = csm.eval_all_states();
458+
assert!(res.is_ok());
459+
}
460+
461+
// New test for the first error branch: state evaluation fails.
462+
#[test]
463+
fn eval_all_states_error_eval_fails() {
464+
let id = 42;
465+
let version = 1;
466+
let data = Evidence::Numerical(0.23f64);
467+
// This causaloid's causal_fn always returns an error.
468+
let causaloid = get_test_error_causaloid();
469+
470+
let cs = CausalState::new(id, version, data, causaloid);
471+
let ca = get_test_action(); // Action won't be reached
472+
let state_action = &[(&cs, &ca)];
473+
let csm = CSM::new(state_action);
474+
475+
let res = csm.eval_all_states();
476+
477+
assert!(res.is_err());
478+
let err_msg = res.unwrap_err().0;
479+
assert!(err_msg.contains(&format!("CSM[eval]: Error evaluating state {id}")));
480+
}
481+
482+
// New test for the second error branch: action firing fails.
483+
#[test]
484+
fn eval_all_states_error_action_fails() {
485+
let id = 42;
486+
let version = 1;
487+
// Use data that makes the state active (0.60 > 0.55 threshold)
488+
let data = Evidence::Numerical(0.60f64);
489+
let causaloid = test_utils::get_test_causaloid(); // Returns Deterministic(true)
490+
491+
let cs = CausalState::new(id, version, data, causaloid);
492+
// Use an action that is designed to fail.
493+
let ca = get_test_error_action();
494+
let state_action = &[(&cs, &ca)];
495+
let csm = CSM::new(state_action);
496+
497+
let res = csm.eval_all_states();
498+
499+
assert!(res.is_err());
500+
let err_msg = res.unwrap_err().0;
501+
assert!(err_msg.contains(&format!(
502+
"CSM[eval]: Failed to fire action for state {id}"
503+
)));
504+
}
505+
506+
// New test for the third error branch: non-deterministic effect.
507+
#[test]
508+
fn eval_all_states_error_non_deterministic() {
509+
let id = 42;
510+
let version = 1;
511+
let data = Evidence::Numerical(0.23f64);
512+
let causaloid = get_test_probabilistic_causaloid();
513+
514+
let cs = CausalState::new(id, version, data, causaloid);
515+
let ca = get_test_action();
516+
let state_action = &[(&cs, &ca)];
517+
let csm = CSM::new(state_action);
518+
519+
let res = csm.eval_all_states();
520+
assert!(res.is_err());
521+
let err_msg = res.unwrap_err().0;
522+
assert!(err_msg.contains("Invalid non-deterministic effect"));
523+
assert!(err_msg.contains(&format!("for state {id}")));
524+
}

0 commit comments

Comments
 (0)