Skip to content

Commit

Permalink
testing(bisect): extract symbols into testing module
Browse files Browse the repository at this point in the history
  • Loading branch information
arxanas committed Feb 12, 2024
1 parent aff490b commit c9dcc00
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 106 deletions.
115 changes: 9 additions & 106 deletions scm-bisect/src/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,41 +239,20 @@ impl<G: BasicSourceControlGraph> search::Strategy<G> for BasicStrategy {

#[cfg(test)]
mod tests {
use std::convert::Infallible;

use itertools::Itertools;
use maplit::{hashmap, hashset};
use proptest::prelude::Strategy as ProptestStrategy;
use proptest::prelude::*;
use proptest::proptest;
use super::*;

use crate::search::Bounds;
use crate::search::EagerSolution;
use crate::search::Search;
use crate::search::Status;
use crate::testing::arb_strategy;
use crate::testing::arb_test_graph_and_nodes;
use crate::testing::TestGraph;
use crate::testing::UsizeGraph;

use super::BasicStrategyKind;
use super::*;

#[derive(Clone, Debug)]
struct UsizeGraph {
max: usize,
}

impl BasicSourceControlGraph for UsizeGraph {
type Node = usize;
type Error = Infallible;

fn ancestors(&self, node: Self::Node) -> Result<HashSet<Self::Node>, Infallible> {
assert!(node < self.max);
Ok((0..=node).collect())
}

fn descendants(&self, node: Self::Node) -> Result<HashSet<Self::Node>, Infallible> {
assert!(node < self.max);
Ok((node..self.max).collect())
}
}
use itertools::Itertools;
use maplit::hashmap;
use maplit::hashset;

#[test]
fn test_search_stick() {
Expand All @@ -289,10 +268,6 @@ mod tests {
strategy: BasicStrategyKind::Binary,
};
let mut search = Search::new(graph.clone(), nodes.clone());
// let mut linear_search = Search::new(graph.clone(), linear_strategy, nodes.clone());
// let mut linear_reverse_search =
// Search::new(graph.clone(), linear_reverse_strategy, nodes.clone());
// let mut binary_search = Search::new(graph.clone(), binary_strategy, nodes.clone());

assert_eq!(
search
Expand Down Expand Up @@ -455,34 +430,6 @@ mod tests {
"###);
}

#[derive(Clone, Debug)]
struct TestGraph {
nodes: HashMap<char, HashSet<char>>,
}

impl BasicSourceControlGraph for TestGraph {
type Node = char;
type Error = Infallible;

fn ancestors(&self, node: Self::Node) -> Result<HashSet<Self::Node>, Infallible> {
let mut result = hashset! {node};
let parents: HashSet<char> = self
.nodes
.iter()
.filter_map(|(k, v)| if v.contains(&node) { Some(*k) } else { None })
.collect();
result.extend(self.ancestors_all(parents)?);
Ok(result)
}

fn descendants(&self, node: Self::Node) -> Result<HashSet<Self::Node>, Infallible> {
let mut result = hashset! {node};
let children: HashSet<char> = self.nodes[&node].clone();
result.extend(self.descendants_all(children)?);
Ok(result)
}
}

#[test]
fn test_search_dag() {
let graph = TestGraph {
Expand Down Expand Up @@ -586,51 +533,7 @@ mod tests {
);
}

fn arb_strategy() -> impl ProptestStrategy<Value = BasicStrategyKind> {
prop_oneof![
Just(BasicStrategyKind::Linear),
Just(BasicStrategyKind::LinearReverse),
Just(BasicStrategyKind::Binary),
]
}

fn arb_test_graph_and_nodes() -> impl ProptestStrategy<Value = (TestGraph, Vec<char>)> {
let nodes = prop::collection::hash_set(
prop::sample::select(vec!['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']),
1..=8,
);
nodes
.prop_flat_map(|nodes| {
let num_nodes = nodes.len();
let nodes_kv = nodes
.iter()
.copied()
.map(|node| (node, HashSet::new()))
.collect();
let graph = TestGraph { nodes: nodes_kv };
let lineages = prop::collection::vec(
prop::sample::subsequence(nodes.into_iter().collect_vec(), 0..num_nodes),
0..num_nodes,
);
(Just(graph), lineages)
})
.prop_map(|(mut graph, lineages)| {
for lineage in lineages {
for (parent, child) in lineage.into_iter().tuple_windows() {
graph.nodes.get_mut(&parent).unwrap().insert(child);
}
}
graph
})
.prop_flat_map(|graph| {
let nodes = graph.nodes.keys().copied().collect::<Vec<_>>();
let num_nodes = nodes.len();
let failure_nodes = prop::sample::subsequence(nodes, 0..num_nodes);
(Just(graph), failure_nodes)
})
}

proptest! {
proptest::proptest! {
#[test]
fn test_search_dag_proptest(strategy in arb_strategy(), (graph, failure_nodes) in arb_test_graph_and_nodes()) {
let nodes = graph.nodes.keys().sorted().copied().collect::<Vec<_>>();
Expand Down
3 changes: 3 additions & 0 deletions scm-bisect/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@

pub mod basic;
pub mod search;

#[cfg(test)]
pub mod testing;
102 changes: 102 additions & 0 deletions scm-bisect/src/testing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use std::collections::{HashMap, HashSet};
use std::convert::Infallible;

use itertools::Itertools;
use proptest::prelude::Strategy as ProptestStrategy;
use proptest::prelude::*;

use crate::basic::{BasicSourceControlGraph, BasicStrategyKind};

#[derive(Clone, Debug)]
pub struct UsizeGraph {
pub max: usize,
}

impl BasicSourceControlGraph for UsizeGraph {
type Node = usize;
type Error = Infallible;

fn ancestors(&self, node: Self::Node) -> Result<HashSet<Self::Node>, Infallible> {
assert!(node < self.max);
Ok((0..=node).collect())
}

fn descendants(&self, node: Self::Node) -> Result<HashSet<Self::Node>, Infallible> {
assert!(node < self.max);
Ok((node..self.max).collect())
}
}

#[derive(Clone, Debug)]
pub struct TestGraph {
pub nodes: HashMap<char, HashSet<char>>,
}

impl BasicSourceControlGraph for TestGraph {
type Node = char;
type Error = Infallible;

fn ancestors(&self, node: Self::Node) -> Result<HashSet<Self::Node>, Infallible> {
let mut result = HashSet::new();
result.insert(node);
let parents: HashSet<char> = self
.nodes
.iter()
.filter_map(|(k, v)| if v.contains(&node) { Some(*k) } else { None })
.collect();
result.extend(self.ancestors_all(parents)?);
Ok(result)
}

fn descendants(&self, node: Self::Node) -> Result<HashSet<Self::Node>, Infallible> {
let mut result = HashSet::new();
result.insert(node);
let children: HashSet<char> = self.nodes[&node].clone();
result.extend(self.descendants_all(children)?);
Ok(result)
}
}

pub fn arb_strategy() -> impl ProptestStrategy<Value = BasicStrategyKind> {
prop_oneof![
Just(BasicStrategyKind::Linear),
Just(BasicStrategyKind::LinearReverse),
Just(BasicStrategyKind::Binary),
]
}

pub fn arb_test_graph_and_nodes() -> impl ProptestStrategy<Value = (TestGraph, Vec<char>)> {
let nodes = prop::collection::hash_set(
prop::sample::select(vec!['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']),
1..=8,
);
nodes
.prop_flat_map(|nodes| {
let num_nodes = nodes.len();
let nodes_kv = nodes
.iter()
.copied()
.map(|node| (node, HashSet::new()))
.collect();
let graph = TestGraph { nodes: nodes_kv };
let lineages = prop::collection::vec(
prop::sample::subsequence(nodes.into_iter().collect_vec(), 0..num_nodes),
0..num_nodes,
);
(Just(graph), lineages)
})
.prop_map(|(mut graph, lineages)| {
for lineage in lineages {
for (parent, child) in lineage.into_iter().tuple_windows() {
graph.nodes.get_mut(&parent).unwrap().insert(child);
}
}
graph
})
.prop_flat_map(|graph| {
let nodes = graph.nodes.keys().copied().collect::<Vec<_>>();
let num_nodes = nodes.len();
let failure_nodes = prop::sample::subsequence(nodes, 0..num_nodes);
(Just(graph), failure_nodes)
})
}

0 comments on commit c9dcc00

Please sign in to comment.