Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update testing_boiler and unify test helpers #269

Merged
merged 33 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
991c5b2
Replace try_create with create_ok
FreezyLemon Sep 4, 2024
a587d7f
Replace bad_create_case with create_err
FreezyLemon Sep 4, 2024
7f59db6
Add docs to testing_boiler functions
FreezyLemon Sep 4, 2024
e3256c1
Use test_none for Beta
FreezyLemon Sep 4, 2024
6d5940b
Use test_none for StudentsT
FreezyLemon Sep 4, 2024
2633f74
Rename `get_value` to `create_and_get`
FreezyLemon Sep 4, 2024
cd09bf8
Rename testing functions & simplify trait bounds
FreezyLemon Sep 4, 2024
016614a
Add test_exact function
FreezyLemon Sep 4, 2024
b68410f
Use testing_boiler! for Bernoulli
FreezyLemon Sep 4, 2024
08bb56e
Use testing_boiler! for Binomial
FreezyLemon Sep 4, 2024
fca9e8a
Use testing_boiler! for Categorical
FreezyLemon Sep 4, 2024
e7fc33e
Use testing_boiler! for Cauchy
FreezyLemon Sep 4, 2024
2e7c672
Use testing_boiler! for ChiSquared
FreezyLemon Sep 4, 2024
722693b
Use testing_boiler! for Chi
FreezyLemon Sep 4, 2024
83bf7b9
Use testing_boiler! for Dirac
FreezyLemon Sep 4, 2024
7ace674
Use testing_boiler! for DiscreteUniform
FreezyLemon Sep 4, 2024
615a98a
Use testing_boiler! for Erlang
FreezyLemon Sep 4, 2024
cdfe1f0
Use testing_boiler! for Exp
FreezyLemon Sep 4, 2024
aedb3b9
Use testing_boiler! for FisherSnedecor
FreezyLemon Sep 4, 2024
3e077c6
Use testing_boiler! for Geometric
FreezyLemon Sep 4, 2024
640d2bb
Use testing_boiler! for HyperGeometric
FreezyLemon Sep 4, 2024
8c240b5
Use testing_boiler! for InverseGamma
FreezyLemon Sep 4, 2024
2e3b150
Use testing_boiler! for Laplace
FreezyLemon Sep 4, 2024
d93e75d
Use testing_boiler! for LogNormal
FreezyLemon Sep 4, 2024
6c34703
Use testing_boiler! for NegativeBinomial
FreezyLemon Sep 4, 2024
363fa4e
Use testing_boiler! for Normal
FreezyLemon Sep 4, 2024
a08d5c9
Use testing_boiler! for Pareto
FreezyLemon Sep 4, 2024
0ffc676
Use testing_boiler! for Poisson
FreezyLemon Sep 4, 2024
34bbf84
Use testing_boiler! for Triangular
FreezyLemon Sep 4, 2024
daeff3b
Use testing_boiler! for Uniform
FreezyLemon Sep 4, 2024
e335ad5
Use testing_boiler! for Weibull
FreezyLemon Sep 4, 2024
4a4adb2
Rewrite one `#[should_panic]` test for Pareto
FreezyLemon Sep 4, 2024
110fa86
Add unit tests for testing_boiler
FreezyLemon Sep 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 18 additions & 55 deletions src/distribution/bernoulli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,90 +265,53 @@ impl Discrete<u64, f64> for Bernoulli {
#[rustfmt::skip]
#[cfg(test)]
mod testing {
use std::fmt::Debug;
use crate::distribution::DiscreteCDF;
use crate::testing_boiler;
use super::Bernoulli;

fn try_create(p: f64) -> Bernoulli {
let n = Bernoulli::new(p);
assert!(n.is_ok());
n.unwrap()
}

fn create_case(p: f64) {
let dist = try_create(p);
assert_eq!(p, dist.p());
}

fn bad_create_case(p: f64) {
let n = Bernoulli::new(p);
assert!(n.is_err());
}

fn get_value<T, F>(p: f64, eval: F) -> T
where T: PartialEq + Debug,
F: Fn(Bernoulli) -> T
{
let n = try_create(p);
eval(n)
}

fn test_case<T, F>(p: f64, expected: T, eval: F)
where T: PartialEq + Debug,
F: Fn(Bernoulli) -> T
{
let x = get_value(p, eval);
assert_eq!(expected, x);
}

fn test_almost<F>(p: f64, expected: f64, acc: f64, eval: F)
where F: Fn(Bernoulli) -> f64
{
let x = get_value(p, eval);
assert_almost_eq!(expected, x, acc);
}
testing_boiler!(p: f64; Bernoulli);

#[test]
fn test_create() {
create_case(0.0);
create_case(0.3);
create_case(1.0);
create_ok(0.0);
create_ok(0.3);
create_ok(1.0);
}

#[test]
fn test_bad_create() {
bad_create_case(f64::NAN);
bad_create_case(-1.0);
bad_create_case(2.0);
create_err(f64::NAN);
create_err(-1.0);
create_err(2.0);
}

#[test]
fn test_cdf_upper_bound() {
let cdf = |arg: u64| move |x: Bernoulli| x.cdf(arg);
test_case(0.3, 1., cdf(1));
test_relative(0.3, 1., cdf(1));
}

#[test]
fn test_sf_upper_bound() {
let sf = |arg: u64| move |x: Bernoulli| x.sf(arg);
test_case(0.3, 0., sf(1));
test_relative(0.3, 0., sf(1));
}

#[test]
fn test_cdf() {
let cdf = |arg: u64| move |x: Bernoulli| x.cdf(arg);
test_case(0.0, 1.0, cdf(0));
test_case(0.0, 1.0, cdf(1));
test_almost(0.3, 0.7, 1e-15, cdf(0));
test_almost(0.7, 0.3, 1e-15, cdf(0));
test_relative(0.0, 1.0, cdf(0));
test_relative(0.0, 1.0, cdf(1));
test_absolute(0.3, 0.7, 1e-15, cdf(0));
test_absolute(0.7, 0.3, 1e-15, cdf(0));
}

#[test]
fn test_sf() {
let sf = |arg: u64| move |x: Bernoulli| x.sf(arg);
test_case(0.0, 0.0, sf(0));
test_case(0.0, 0.0, sf(1));
test_almost(0.3, 0.3, 1e-15, sf(0));
test_almost(0.7, 0.7, 1e-15, sf(0));
test_relative(0.0, 0.0, sf(0));
test_relative(0.0, 0.0, sf(1));
test_absolute(0.3, 0.3, 1e-15, sf(0));
test_absolute(0.7, 0.7, 1e-15, sf(0));
}
}
70 changes: 33 additions & 37 deletions src/distribution/beta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ mod tests {
fn test_create() {
let valid = [(1.0, 1.0), (9.0, 1.0), (5.0, 100.0), (1.0, f64::INFINITY), (f64::INFINITY, 1.0)];
for (a, b) in valid {
try_create(a, b);
create_ok(a, b);
}
}

Expand All @@ -460,7 +460,7 @@ mod tests {
(f64::INFINITY, f64::INFINITY),
];
for (a, b) in invalid {
bad_create_case(a, b);
create_err(a, b);
}
}

Expand All @@ -475,7 +475,7 @@ mod tests {
((f64::INFINITY, 1.0), 1.0),
];
for ((a, b), res) in test {
test_case(a, b, res, f);
test_relative(a, b, res, f);
}
}

Expand All @@ -490,7 +490,7 @@ mod tests {
((f64::INFINITY, 1.0), 0.0),
];
for ((a, b), res) in test {
test_case(a, b, res, f);
test_relative(a, b, res, f);
}
}

Expand All @@ -502,9 +502,9 @@ mod tests {
((5.0, 100.0), -2.52016231876027436794592),
];
for ((a, b), res) in test {
test_case(a, b, res, f);
test_relative(a, b, res, f);
}
test_case_special(1.0, 1.0, 0.0, 1e-14, f);
test_absolute(1.0, 1.0, 0.0, 1e-14, f);
let entropy = |x: Beta| x.entropy();
test_none(1.0, f64::INFINITY, entropy);
test_none(f64::INFINITY, 1.0, entropy);
Expand All @@ -513,41 +513,37 @@ mod tests {
#[test]
fn test_skewness() {
let skewness = |x: Beta| x.skewness().unwrap();
test_case(1.0, 1.0, 0.0, skewness);
test_case(9.0, 1.0, -1.4740554623801777107177478829, skewness);
test_case(5.0, 100.0, 0.817594109275534303545831591, skewness);
test_case(1.0, f64::INFINITY, 2.0, skewness);
test_case(f64::INFINITY, 1.0, -2.0, skewness);
test_relative(1.0, 1.0, 0.0, skewness);
test_relative(9.0, 1.0, -1.4740554623801777107177478829, skewness);
test_relative(5.0, 100.0, 0.817594109275534303545831591, skewness);
test_relative(1.0, f64::INFINITY, 2.0, skewness);
test_relative(f64::INFINITY, 1.0, -2.0, skewness);
}

#[test]
fn test_mode() {
let mode = |x: Beta| x.mode().unwrap();
test_case(5.0, 100.0, 0.038834951456310676243255386, mode);
test_case(92.0, f64::INFINITY, 0.0, mode);
test_case(f64::INFINITY, 2.0, 1.0, mode);
test_relative(5.0, 100.0, 0.038834951456310676243255386, mode);
test_relative(92.0, f64::INFINITY, 0.0, mode);
test_relative(f64::INFINITY, 2.0, 1.0, mode);
}

#[test]
#[should_panic]
fn test_mode_shape_a_lte_1() {
let mode = |x: Beta| x.mode().unwrap();
get_value(1.0, 5.0, mode);
test_none(1.0, 5.0, |dist| dist.mode());
}

#[test]
#[should_panic]
fn test_mode_shape_b_lte_1() {
let mode = |x: Beta| x.mode().unwrap();
get_value(5.0, 1.0, mode);
test_none(5.0, 1.0, |dist| dist.mode());
}

#[test]
fn test_min_max() {
let min = |x: Beta| x.min();
let max = |x: Beta| x.max();
test_case(1.0, 1.0, 0.0, min);
test_case(1.0, 1.0, 1.0, max);
test_relative(1.0, 1.0, 0.0, min);
test_relative(1.0, 1.0, 1.0, max);
}

#[test]
Expand All @@ -572,20 +568,20 @@ mod tests {
((f64::INFINITY, 1.0), 1.0, f64::INFINITY),
];
for ((a, b), x, expect) in test {
test_case(a, b, expect, f(x));
test_relative(a, b, expect, f(x));
}
}

#[test]
fn test_pdf_input_lt_0() {
let pdf = |arg: f64| move |x: Beta| x.pdf(arg);
test_case(1.0, 1.0, 0.0, pdf(-1.0));
test_relative(1.0, 1.0, 0.0, pdf(-1.0));
}

#[test]
fn test_pdf_input_gt_0() {
let pdf = |arg: f64| move |x: Beta| x.pdf(arg);
test_case(1.0, 1.0, 0.0, pdf(2.0));
test_relative(1.0, 1.0, 0.0, pdf(2.0));
}

#[test]
Expand All @@ -609,20 +605,20 @@ mod tests {
((f64::INFINITY, 1.0), 1.0, f64::INFINITY),
];
for ((a, b), x, expect) in test {
test_case(a, b, expect, f(x));
test_relative(a, b, expect, f(x));
}
}

#[test]
fn test_ln_pdf_input_lt_0() {
let ln_pdf = |arg: f64| move |x: Beta| x.ln_pdf(arg);
test_case(1.0, 1.0, f64::NEG_INFINITY, ln_pdf(-1.0));
test_relative(1.0, 1.0, f64::NEG_INFINITY, ln_pdf(-1.0));
}

#[test]
fn test_ln_pdf_input_gt_1() {
let ln_pdf = |arg: f64| move |x: Beta| x.ln_pdf(arg);
test_case(1.0, 1.0, f64::NEG_INFINITY, ln_pdf(2.0));
test_relative(1.0, 1.0, f64::NEG_INFINITY, ln_pdf(2.0));
}

#[test]
Expand All @@ -646,7 +642,7 @@ mod tests {
((f64::INFINITY, 1.0), 1.0, 1.0),
];
for ((a, b), x, expect) in test {
test_case(a, b, expect, cdf(x));
test_relative(a, b, expect, cdf(x));
}
}

Expand All @@ -671,7 +667,7 @@ mod tests {
((f64::INFINITY, 1.0), 1.0, 0.0),
];
for ((a, b), x, expect) in test {
test_case(a, b, expect, sf(x));
test_relative(a, b, expect, sf(x));
}
}

Expand All @@ -692,37 +688,37 @@ mod tests {
((5.0, 100.0), 1.0, 1.0),
];
for ((a, b), x, expect) in test {
test_case(a, b, expect, func(x));
test_relative(a, b, expect, func(x));
};
}

#[test]
fn test_cdf_input_lt_0() {
let cdf = |arg: f64| move |x: Beta| x.cdf(arg);
test_case(1.0, 1.0, 0.0, cdf(-1.0));
test_relative(1.0, 1.0, 0.0, cdf(-1.0));
}

#[test]
fn test_cdf_input_gt_1() {
let cdf = |arg: f64| move |x: Beta| x.cdf(arg);
test_case(1.0, 1.0, 1.0, cdf(2.0));
test_relative(1.0, 1.0, 1.0, cdf(2.0));
}

#[test]
fn test_sf_input_lt_0() {
let sf = |arg: f64| move |x: Beta| x.sf(arg);
test_case(1.0, 1.0, 1.0, sf(-1.0));
test_relative(1.0, 1.0, 1.0, sf(-1.0));
}

#[test]
fn test_sf_input_gt_1() {
let sf = |arg: f64| move |x: Beta| x.sf(arg);
test_case(1.0, 1.0, 0.0, sf(2.0));
test_relative(1.0, 1.0, 0.0, sf(2.0));
}

#[test]
fn test_continuous() {
test::check_continuous_distribution(&try_create(1.2, 3.4), 0.0, 1.0);
test::check_continuous_distribution(&try_create(4.5, 6.7), 0.0, 1.0);
test::check_continuous_distribution(&create_ok(1.2, 3.4), 0.0, 1.0);
test::check_continuous_distribution(&create_ok(4.5, 6.7), 0.0, 1.0);
}
}
Loading