Skip to content

Commit

Permalink
Tests (#8)
Browse files Browse the repository at this point in the history
add unity tests
  • Loading branch information
jirigav authored Jul 3, 2024
1 parent 998fd31 commit 763bfe9
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 7 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
workflow_dispatch:

env:
CARGO_TERM_COLOR: always
Expand All @@ -22,6 +23,14 @@ jobs:
toolchain: stable
components: rustfmt, clippy

- name: Set up Python
uses: actions/setup-python@v5
with:
python-varsion: '3.x'

- name: Install SciPy
run: python -m pip install scipy

- name: Build
run: cargo build --verbose
- name: Run tests
Expand Down
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ itertools="0.11"
pyo3={ version = "0.19", features = ["auto-initialize"] }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }

[dev-dependencies]
float-cmp = "0.9.0"
32 changes: 32 additions & 0 deletions src/bottomup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,3 +378,35 @@ fn brute_force_threads(

hists
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_choose() {
assert_eq!(choose(0, 0), 1);
assert_eq!(choose(5, 6), 0);
assert_eq!(choose(8, 6), 28);
assert_eq!(choose(1, 1), 1);
assert_eq!(choose(50, 33), 9847379391150);
assert_eq!(choose(14, 9), 2002);
}

#[test]
fn test_first_zero_bit() {
assert_eq!(first_zero_bit(0b0), 0);
assert_eq!(first_zero_bit(0b000010), 0);
assert_eq!(first_zero_bit(0b1010101010), 0);
assert_eq!(first_zero_bit(0b101), 1);
assert_eq!(first_zero_bit(0b1011), 2);
assert_eq!(first_zero_bit(0b10111), 3);
assert_eq!(first_zero_bit(0b101111), 4);
assert_eq!(first_zero_bit(0b1011111), 5);
assert_eq!(first_zero_bit(0b10111111), 6);
assert_eq!(first_zero_bit(0b101111111), 7);
assert_eq!(first_zero_bit(0b1011111111), 8);
assert_eq!(first_zero_bit(0b10111111111), 9);
assert_eq!(first_zero_bit(0b101111111111), 10);
}
}
122 changes: 116 additions & 6 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ use pyo3::prelude::*;
use serde::{Deserialize, Serialize};
use std::fs;

pub(crate) fn z_score(sample_size: usize, positive: usize, p: f64) -> f64 {
((positive as f64) - p * (sample_size as f64)) / f64::sqrt(p * (1.0 - p) * (sample_size as f64))
}

#[derive(Parser, Debug, Serialize, Deserialize, Clone)]
#[command(version)]
pub(crate) struct Args {
Expand Down Expand Up @@ -71,7 +67,7 @@ pub(crate) fn bit_value_in_block(bit: usize, block: &[u8]) -> bool {
((block[byte_index] >> offset) & 1) == 1
}

#[derive(Clone)]
#[derive(Clone, PartialEq, Debug)]
pub(crate) struct Data {
pub(crate) data: Vec<Vec<u128>>,
pub(crate) _mask: u128,
Expand Down Expand Up @@ -162,7 +158,11 @@ pub(crate) fn transform_data(data: &[Vec<u8>]) -> Data {
}
}

pub(crate) fn p_value(positive: usize, sample_size: usize, probability: f64) -> f64 {
pub(crate) fn z_score(sample_size: usize, positive: usize, p: f64) -> f64 {
((positive as f64) - p * (sample_size as f64)) / f64::sqrt(p * (1.0 - p) * (sample_size as f64))
}

pub(crate) fn p_value(sample_size: usize, positive: usize, probability: f64) -> f64 {
Python::with_gil(|py| {
let scipy_stats = PyModule::import(py, "scipy.stats")
.expect("SciPy not installed! Use `pip install scipy` to install the library.");
Expand All @@ -178,3 +178,113 @@ pub(crate) fn p_value(positive: usize, sample_size: usize, probability: f64) ->
result
})
}

#[cfg(test)]
mod tests {
use super::*;
use float_cmp::approx_eq;

#[test]
fn test_p_value() {
assert!(approx_eq!(f64, p_value(1, 1, 0.0), 0.0));
assert!(approx_eq!(f64, p_value(1, 1, 1.0), 1.0));
assert!(approx_eq!(f64, p_value(1, 1, 0.5), 1.0));
assert!(approx_eq!(f64, p_value(1, 1, 0.25), 0.25));
assert!(approx_eq!(f64, p_value(8064, 675, 0.85), 0.0));
assert!(approx_eq!(
f64,
p_value(1245, 872, 0.51),
2.519147904123094e-42
));
assert!(approx_eq!(
f64,
p_value(3952, 3009, 0.87),
1.6048354143177452e-76
));
assert!(approx_eq!(
f64,
p_value(6395, 1774, 0.32),
1.4633129278540793e-13
));
assert!(approx_eq!(f64, p_value(7716, 969, 0.76), 0.0));
assert!(approx_eq!(f64, p_value(4231, 1225, 0.75), 0.0));
assert!(approx_eq!(f64, p_value(2295, 1187, 0.02), 0.0));
assert!(approx_eq!(
f64,
p_value(2228, 1993, 0.61),
8.219896711580438e-200
));
assert!(approx_eq!(f64, p_value(5936, 4649, 0.97), 0.0));
assert!(approx_eq!(
f64,
p_value(711, 342, 0.2),
5.29655579272766e-63
));
}

#[test]
fn test_z_score() {
assert!(z_score(1, 1, 1.0).is_nan());
assert_eq!(z_score(8852, 7609, 0.74), 25.649318571444642);
assert_eq!(z_score(8838, 7708, 0.99), -111.35627996866052);
assert_eq!(z_score(1040, 1037, 0.34), 44.73494199130066);
assert_eq!(z_score(5204, 1855, 0.85), -99.71004790616179);
assert_eq!(z_score(8878, 386, 0.19), -35.1917063646087);
assert_eq!(z_score(8377, 1181, 0.49), -63.9013271819615);
assert_eq!(z_score(9682, 2871, 0.11), 58.65959381857785);
assert_eq!(z_score(6615, 343, 0.21), -31.579543090478786);
assert_eq!(z_score(4997, 4918, 0.41), 82.52637218309836);
assert_eq!(z_score(9609, 1609, 0.28), -24.57254813392147);
}

#[test]
fn test_bit_value_in_block() {
assert_eq!(bit_value_in_block(0, &[2_u8.pow(7)]), true);
assert_eq!(bit_value_in_block(0, &[2_u8.pow(6)]), false);
assert_eq!(bit_value_in_block(1, &[2_u8.pow(6)]), true);
assert_eq!(bit_value_in_block(2, &[2_u8.pow(5)]), true);
assert_eq!(bit_value_in_block(3, &[2_u8.pow(4)]), true);
assert_eq!(bit_value_in_block(4, &[2_u8.pow(3)]), true);
assert_eq!(bit_value_in_block(5, &[2_u8.pow(2)]), true);
assert_eq!(bit_value_in_block(6, &[2_u8.pow(1)]), true);
assert_eq!(bit_value_in_block(7, &[2_u8.pow(0)]), true);

assert_eq!(bit_value_in_block(8, &[0, 2_u8.pow(7)]), true);
assert_eq!(bit_value_in_block(0, &[0, 2_u8.pow(7)]), false);
assert_eq!(bit_value_in_block(8, &[0, 0]), false);

assert_eq!(
bit_value_in_block(103, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]),
true
);
}

#[test]
fn test_transform_data() {
assert_eq!(
transform_data(&[vec![0, 0], vec![0, 1], vec![1, 0]]),
Data {
data: vec![
vec![0],
vec![0],
vec![0],
vec![0],
vec![0],
vec![0],
vec![0],
vec![4],
vec![0],
vec![0],
vec![0],
vec![0],
vec![0],
vec![0],
vec![0],
vec![2]
],
_mask: 7,
_num_of_blocks: 3
}
)
}
}
2 changes: 1 addition & 1 deletion src/results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ pub(crate) fn results(hist: Histogram, testing_data: &[Vec<u8>], args: Args) {
prob * (hist.best_division as f64),
);
let p_val = p_value(
count,
testing_data.len(),
count,
prob * (hist.best_division as f64),
);
print_results(p_val, z, args.alpha, &hist, bins);
Expand Down

0 comments on commit 763bfe9

Please sign in to comment.