use maplit::btreeset;
use crate::quorum::Joint;
use crate::quorum::QuorumBridge;
use crate::quorum::QuorumIntersection;
use crate::quorum::QuorumSet;
use crate::quorum::ThresholdQuorumSet;
use crate::quorum::threshold_quorum_set_test::all_subsets;
use crate::quorum::threshold_quorum_set_test::all_thresholds;
use crate::quorum::threshold_quorum_set_test::threshold;
use crate::quorum::verify_intersection;
fn all_joints() -> Vec<Joint<ThresholdQuorumSet<u64>>> {
let thresholds = all_thresholds(&btreeset! {1, 2, 3});
let mut joints = vec![Joint::default()];
for a in &thresholds {
joints.push(Joint::new([a.clone()]));
for b in &thresholds {
joints.push(Joint::new([a.clone(), b.clone()]));
}
}
joints
}
#[test]
fn test_joint_of_thresholds() {
let old = threshold(2, btreeset! {1, 2, 3});
let new = threshold(2, btreeset! {2, 3, 4});
let joint = Joint::new([old, new]);
let mut accepted = vec![];
for ids in all_subsets(&btreeset! {1, 2, 3, 4}) {
let is_quorum = joint.is_quorum(ids.iter());
if is_quorum {
accepted.push(ids);
}
}
let want = vec![
btreeset! {2, 3},
btreeset! {1, 2, 3},
btreeset! {1, 2, 4},
btreeset! {1, 3, 4},
btreeset! {2, 3, 4},
btreeset! {1, 2, 3, 4},
];
assert_eq!(want, accepted);
let ids = joint.ids().collect::<Vec<_>>();
assert_eq!(vec![1, 2, 3, 4], ids);
}
#[test]
fn test_empty_joint_accepts_no_set() {
let empty = Joint::<ThresholdQuorumSet<u64>>::default();
let empty_input = empty.is_quorum(std::iter::empty());
assert!(!empty_input);
let some_ids = empty.is_quorum([1, 2].iter());
assert!(!some_ids);
let ids = empty.ids().collect::<Vec<_>>();
assert_eq!(Vec::<u64>::new(), ids);
}
#[test]
fn test_intersects_with() {
let r123 = || threshold(2, btreeset! {1, 2, 3});
let r345 = || threshold(2, btreeset! {3, 4, 5});
let r789 = || threshold(2, btreeset! {7, 8, 9});
let j123 = Joint::new([r123()]);
let j345 = Joint::new([r345()]);
let j123_345 = Joint::new([r123(), r345()]);
let j345_789 = Joint::new([r345(), r789()]);
let uniform = j123.intersects_with(&j345);
assert_eq!(Some(false), uniform);
let shared_rule = j123_345.intersects_with(&j345_789);
assert_eq!(Some(true), shared_rule);
let no_shared_rule = j123.intersects_with(&j345_789);
assert_eq!(None, no_shared_rule);
}
#[test]
fn test_intersects_with_agrees_with_verify_intersection() {
let joints = all_joints();
for a in &joints {
for b in &joints {
let intersects = a.intersects_with(b);
let at_most_one_rule = a.rules().len() <= 1 && b.rules().len() <= 1;
if at_most_one_rule {
let exact = verify_intersection(a, b);
assert_eq!(Some(exact), intersects, "a: {a:?}, b: {b:?}");
continue;
}
let Some(intersects) = intersects else {
continue;
};
let exact = verify_intersection(a, b);
assert_eq!(exact, intersects, "a: {a:?}, b: {b:?}");
}
}
}
#[test]
fn test_joint_with() {
let r1 = || threshold(2, btreeset! {1, 2, 3});
let r2 = || threshold(1, btreeset! {3, 4});
let r3 = || threshold(3, btreeset! {4, 5, 6});
let j12 = Joint::new([r1(), r2()]);
let j3 = Joint::new([r3()]);
let joint = j12.joint_with(j3.clone());
let want = Joint::new([r1(), r2(), r3()]);
assert_eq!(want, joint);
let empty = Joint::default();
let with_empty = j12.joint_with(empty.clone());
assert_eq!(empty, with_empty);
let from_empty = empty.joint_with(j3);
assert_eq!(empty, from_empty);
}
#[test]
fn test_joint_with_accepts_quorums_of_both_sides() {
let joints = all_joints();
let id_sets = all_subsets(&btreeset! {1, 2, 3});
for current in &joints {
for goal in &joints {
let joint = current.joint_with(goal.clone());
for ids in &id_sets {
let in_current = current.is_quorum(ids.iter());
let in_goal = goal.is_quorum(ids.iter());
let in_both = in_current && in_goal;
let in_joint = joint.is_quorum(ids.iter());
assert_eq!(
in_both, in_joint,
"{current:?} joint with {goal:?} on {ids:?}"
);
}
}
}
}