Skip to content

Commit 4e5b4a4

Browse files
committed
test(deep_causality_uncertain): Increased test coverage.
Signed-off-by: Marvin Hansen <[email protected]>
1 parent fb140d9 commit 4e5b4a4

File tree

8 files changed

+310
-8
lines changed

8 files changed

+310
-8
lines changed

deep_causality_uncertain/src/types/cache/global_cache.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,7 @@ where
119119
}
120120
#[cfg(test)]
121121
{
122-
GLOBAL_SAMPLE_CACHE.with(|cache_once_lock| {
123-
let cache = cache_once_lock.get_or_init(GlobalSampleCache::new);
124-
closure(cache)
125-
})
122+
GLOBAL_SAMPLE_CACHE
123+
.with(|cache_once_lock| closure(cache_once_lock.get_or_init(GlobalSampleCache::new)))
126124
}
127125
}

deep_causality_uncertain/src/types/computation/node/node_id.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
use crate::types::computation::node::computation_node::NEXT_NODE_ID;
7+
use std::fmt;
78
use std::sync::atomic::Ordering;
89

910
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -20,3 +21,15 @@ impl Default for NodeId {
2021
Self::new()
2122
}
2223
}
24+
25+
impl From<usize> for NodeId {
26+
fn from(item: usize) -> Self {
27+
NodeId(item)
28+
}
29+
}
30+
31+
impl fmt::Display for NodeId {
32+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33+
write!(f, "NodeId({})", self.0)
34+
}
35+
}

deep_causality_uncertain/tests/errors/uncertain_error_tests.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
*/
55

66
use deep_causality_uncertain::UncertainError;
7+
// For testing From methods
8+
use rand_distr::uniform::Error as UniformError;
9+
use rand_distr::{BernoulliError, NormalError};
10+
// For testing From impl
11+
use rusty_fork::rusty_fork_test;
712
use std::error::Error;
813
// For the Error trait methods
914
use ultragraph::GraphError;
10-
// For testing From impl
11-
use rusty_fork::rusty_fork_test;
1215

1316
rusty_fork_test! {
1417
#[test]
@@ -82,4 +85,41 @@ rusty_fork_test! {
8285
);
8386
assert!(err.source().is_none());
8487
}
88+
89+
#[test]
90+
fn test_from_uniform_error() {
91+
let err = UniformError::EmptyRange;
92+
let uncertain_error: UncertainError = err.into();
93+
match uncertain_error {
94+
UncertainError::UniformDistributionError(msg) => {
95+
assert!(msg.contains("low > high (or equal if exclusive)"));
96+
}
97+
_ => panic!("Expected UniformDistributionError"),
98+
}
99+
}
100+
101+
#[test]
102+
fn test_from_bernoulli_error() {
103+
let err = BernoulliError::InvalidProbability;
104+
let uncertain_error: UncertainError = err.into();
105+
match uncertain_error {
106+
UncertainError::BernoulliDistributionError(msg) => {
107+
assert!(msg.contains("p is outside [0, 1] in Bernoulli distribution"));
108+
}
109+
_ => panic!("Expected BernoulliDistributionError"),
110+
}
111+
}
112+
113+
#[test]
114+
fn test_from_normal_error() {
115+
let err = NormalError::MeanTooSmall;
116+
let uncertain_error: UncertainError = err.into();
117+
match uncertain_error {
118+
UncertainError::NormalDistributionError(msg) => {
119+
assert!(msg.contains("mean < 0 or NaN in log-normal"));
120+
}
121+
_ => panic!("Expected NormalDistributionError"),
122+
}
123+
}
124+
85125
}

deep_causality_uncertain/tests/types/cache/cache_tests.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Copyright (c) "2025" . The DeepCausality Authors and Contributors. All Rights Reserved.
44
*/
55

6-
use deep_causality_uncertain::{SampledValue, Uncertain, with_global_cache};
6+
use deep_causality_uncertain::{GlobalSampleCache, SampledValue, Uncertain, with_global_cache};
77
use rusty_fork::rusty_fork_test;
88

99
rusty_fork_test! {
@@ -55,6 +55,21 @@ rusty_fork_test! {
5555
});
5656
}
5757

58+
#[test]
59+
fn test_cache_default() {
60+
let uncertain_obj = Uncertain::<f64>::point(1.0);
61+
let key = (uncertain_obj.id(), 200);
62+
let value = SampledValue::Float(123.45);
63+
64+
let cache = GlobalSampleCache::default();
65+
66+
cache.insert(key, value);
67+
let v = cache.get(&key);
68+
assert!(v.is_some());
69+
let result = v.unwrap();
70+
assert_eq!(result, value);
71+
}
72+
5873
#[test]
5974
fn test_cache_get_and_insert() {
6075

deep_causality_uncertain/tests/types/computation/node/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
* SPDX-License-Identifier: MIT
33
* Copyright (c) "2025" . The DeepCausality Authors and Contributors. All Rights Reserved.
44
*/
5+
mod node_id_tests;
56
mod node_tests;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* SPDX-License-Identifier: MIT
3+
* Copyright (c) "2025" . The DeepCausality Authors and Contributors. All Rights Reserved.
4+
*/
5+
use deep_causality_uncertain::NodeId;
6+
7+
use rusty_fork::rusty_fork_test;
8+
9+
rusty_fork_test! {
10+
11+
#[test]
12+
fn test_new_node_id() {
13+
let initial_id = NodeId::new();
14+
let node_id1 = NodeId::from(0);
15+
16+
assert_eq!(initial_id, node_id1);
17+
}
18+
19+
#[test]
20+
fn test_default_node_id() {
21+
let initial_id = NodeId::default();
22+
let node_id = NodeId::from(0);
23+
assert_eq!(initial_id, node_id);
24+
}
25+
26+
#[test]
27+
fn test_node_id_debug_trait() {
28+
let node_id = NodeId::new();
29+
let debug_string = format!("{:?}", node_id);
30+
assert!(debug_string.contains(&node_id.to_string()));
31+
assert!(debug_string.starts_with("NodeId("));
32+
assert!(debug_string.ends_with(")"));
33+
}
34+
35+
#[test]
36+
fn test_node_id_clone_trait() {
37+
let node_id1 = NodeId::new();
38+
let node_id2 = node_id1;
39+
assert_eq!(node_id1, node_id2);
40+
}
41+
42+
#[test]
43+
fn test_node_id_copy_trait() {
44+
let node_id1 = NodeId::new();
45+
let node_id2 = node_id1; // This is a copy, not a move
46+
assert_eq!(node_id1, node_id2);
47+
}
48+
49+
}

deep_causality_uncertain/tests/types/distribution/distribution_tests.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* Copyright (c) "2025" . The DeepCausality Authors and Contributors. All Rights Reserved.
44
*/
55
use deep_causality_uncertain::{
6-
BernoulliParams, DistributionEnum, NormalDistributionParams, UniformDistributionParams,
6+
BernoulliParams, DistributionEnum, NormalDistributionParams, UncertainError,
7+
UniformDistributionParams,
78
};
89
use rand::rng;
910

@@ -130,3 +131,48 @@ fn test_distribution_enum_display() {
130131
"Distribution: Bernoulli { D: BernoulliParams { p: 0.70 } }"
131132
);
132133
}
134+
135+
#[test]
136+
fn test_sample_f64_unsupported_type_error() {
137+
let mut rng = rng();
138+
let bernoulli_dist: DistributionEnum<f64> =
139+
DistributionEnum::Bernoulli(BernoulliParams { p: 0.5 });
140+
let result = bernoulli_dist.sample(&mut rng);
141+
142+
dbg!(&result);
143+
144+
assert!(matches!(
145+
result,
146+
Err(UncertainError::UnsupportedTypeError(_))
147+
));
148+
}
149+
150+
#[test]
151+
fn test_sample_bool_unsupported_type_error() {
152+
let mut rng = rng();
153+
let normal_dist: DistributionEnum<bool> = DistributionEnum::Normal(NormalDistributionParams {
154+
mean: 0.0,
155+
std_dev: 1.0,
156+
});
157+
let result = normal_dist.sample(&mut rng);
158+
159+
dbg!(&result);
160+
161+
assert!(matches!(
162+
result,
163+
Err(UncertainError::UnsupportedTypeError(_))
164+
));
165+
166+
let uniform_dist: DistributionEnum<bool> =
167+
DistributionEnum::Uniform(UniformDistributionParams {
168+
low: 0.0,
169+
high: 1.0,
170+
});
171+
let result = uniform_dist.sample(&mut rng);
172+
dbg!(&result);
173+
174+
assert!(matches!(
175+
result,
176+
Err(UncertainError::UnsupportedTypeError(_))
177+
));
178+
}

deep_causality_uncertain/tests/types/sampler/sequential_sampler_tests.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,3 +426,143 @@ fn test_sequential_sampler_error_propagation_from_distribution() {
426426
e => panic!("Expected BernoulliDistributionError, got {:?}", e),
427427
}
428428
}
429+
430+
#[test]
431+
fn test_sequential_sampler_logical_op_not_wrong_number_of_operands() {
432+
let sampler = SequentialSampler;
433+
let op1 = Arc::new(ComputationNode::LeafBool {
434+
node_id: NodeId::new(),
435+
dist: DistributionEnum::Point(true),
436+
});
437+
let op2 = Arc::new(ComputationNode::LeafBool {
438+
node_id: NodeId::new(),
439+
dist: DistributionEnum::Point(false),
440+
});
441+
let root_node = Arc::new(ComputationNode::LogicalOp {
442+
node_id: NodeId::new(),
443+
op: LogicalOperator::Not,
444+
operands: vec![Box::new((*op1).clone()), Box::new((*op2).clone())], // Should be 1
445+
});
446+
let res = sampler.sample(&root_node);
447+
assert!(res.is_err());
448+
match res.err().unwrap() {
449+
UncertainError::UnsupportedTypeError(msg) => {
450+
assert_eq!(msg, "NOT expects exactly 1 operand");
451+
}
452+
e => panic!("Expected UnsupportedTypeError, got {:?}", e),
453+
}
454+
}
455+
456+
#[test]
457+
fn test_sequential_sampler_logical_op_not_with_zero_operands() {
458+
let sampler = SequentialSampler;
459+
let root_node = Arc::new(ComputationNode::LogicalOp {
460+
node_id: NodeId::new(),
461+
op: LogicalOperator::Not,
462+
operands: vec![], // Zero operands
463+
});
464+
let res = sampler.sample(&root_node);
465+
assert!(res.is_err());
466+
match res.err().unwrap() {
467+
UncertainError::UnsupportedTypeError(msg) => {
468+
assert_eq!(msg, "NOT expects exactly 1 operand");
469+
}
470+
e => panic!("Expected UnsupportedTypeError, got {:?}", e),
471+
}
472+
}
473+
474+
#[test]
475+
fn test_sequential_sampler_logical_op_and_wrong_number_of_operands() {
476+
let sampler = SequentialSampler;
477+
let op1 = Arc::new(ComputationNode::LeafBool {
478+
node_id: NodeId::new(),
479+
dist: DistributionEnum::Point(true),
480+
});
481+
let root_node = Arc::new(ComputationNode::LogicalOp {
482+
node_id: NodeId::new(),
483+
op: LogicalOperator::And,
484+
operands: vec![Box::new((*op1).clone())], // Should be 2
485+
});
486+
let res = sampler.sample(&root_node);
487+
assert!(res.is_err());
488+
match res.err().unwrap() {
489+
UncertainError::UnsupportedTypeError(msg) => {
490+
assert_eq!(msg, "Binary logical op expects exactly 2 operands");
491+
}
492+
e => panic!("Expected UnsupportedTypeError, got {:?}", e),
493+
}
494+
}
495+
496+
#[test]
497+
fn test_sequential_sampler_logical_op_or_with_three_operands() {
498+
let sampler = SequentialSampler;
499+
let op1 = Arc::new(ComputationNode::LeafBool {
500+
node_id: NodeId::new(),
501+
dist: DistributionEnum::Point(true),
502+
});
503+
let op2 = Arc::new(ComputationNode::LeafBool {
504+
node_id: NodeId::new(),
505+
dist: DistributionEnum::Point(false),
506+
});
507+
let op3 = Arc::new(ComputationNode::LeafBool {
508+
node_id: NodeId::new(),
509+
dist: DistributionEnum::Point(true),
510+
});
511+
let root_node = Arc::new(ComputationNode::LogicalOp {
512+
node_id: NodeId::new(),
513+
op: LogicalOperator::Or,
514+
operands: vec![
515+
Box::new((*op1).clone()),
516+
Box::new((*op2).clone()),
517+
Box::new((*op3).clone()),
518+
], // Three operands
519+
});
520+
let res = sampler.sample(&root_node);
521+
assert!(res.is_err());
522+
match res.err().unwrap() {
523+
UncertainError::UnsupportedTypeError(msg) => {
524+
assert_eq!(msg, "Binary logical op expects exactly 2 operands");
525+
}
526+
e => panic!("Expected UnsupportedTypeError, got {:?}", e),
527+
}
528+
}
529+
530+
#[test]
531+
fn test_sequential_sampler_logical_op_nor_true() {
532+
let sampler = SequentialSampler;
533+
let op1 = Arc::new(ComputationNode::LeafBool {
534+
node_id: NodeId::new(),
535+
dist: DistributionEnum::Point(false),
536+
});
537+
let op2 = Arc::new(ComputationNode::LeafBool {
538+
node_id: NodeId::new(),
539+
dist: DistributionEnum::Point(false),
540+
});
541+
let root_node = Arc::new(ComputationNode::LogicalOp {
542+
node_id: NodeId::new(),
543+
op: LogicalOperator::NOR,
544+
operands: vec![Box::new((*op1).clone()), Box::new((*op2).clone())],
545+
});
546+
let result = sampler.sample(&root_node).unwrap();
547+
assert_eq!(result, SampledValue::Bool(true));
548+
}
549+
550+
#[test]
551+
fn test_sequential_sampler_logical_op_nor_false() {
552+
let sampler = SequentialSampler;
553+
let op1 = Arc::new(ComputationNode::LeafBool {
554+
node_id: NodeId::new(),
555+
dist: DistributionEnum::Point(true),
556+
});
557+
let op2 = Arc::new(ComputationNode::LeafBool {
558+
node_id: NodeId::new(),
559+
dist: DistributionEnum::Point(false),
560+
});
561+
let root_node = Arc::new(ComputationNode::LogicalOp {
562+
node_id: NodeId::new(),
563+
op: LogicalOperator::NOR,
564+
operands: vec![Box::new((*op1).clone()), Box::new((*op2).clone())],
565+
});
566+
let result = sampler.sample(&root_node).unwrap();
567+
assert_eq!(result, SampledValue::Bool(false));
568+
}

0 commit comments

Comments
 (0)