use trie_rcv; use trie_rcv::{EliminationStrategies, RankedChoiceVoteTrie}; use trie_rcv::vote::{SpecialVotes, RankedVote}; const WITHOLD_VOTE_VAL: i32 = SpecialVotes::WITHHOLD.to_int(); const ABSTAIN_VOTE_VAL: i32 = SpecialVotes::ABSTAIN.to_int(); #[test] fn test_basic_scenario() { let votes = RankedVote::from_vectors(&vec![ vec![1, 2, 3, 4], vec![1, 2, 3], vec![3], vec![3, 2, 4], vec![4, 1] ]).unwrap(); let rcv = RankedChoiceVoteTrie::new(); assert_eq!(rcv.get_num_votes(), 0); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!( winner, Some(1), "Vote 4 > 1 should go to 1, leading to Candidate 1 winning" ); } #[test] fn test_vote_insert() { let mut rcv = RankedChoiceVoteTrie::new(); rcv.set_elimination_strategy(EliminationStrategies::EliminateAll); rcv.insert_vote(RankedVote::from_vector(&vec![1, 2, 3, 4]).unwrap()); rcv.insert_vote(RankedVote::from_vector(&vec![1, 2, 3]).unwrap()); rcv.insert_vote(RankedVote::from_vector(&vec![3]).unwrap()); rcv.insert_vote(RankedVote::from_vector(&vec![3, 2, 4]).unwrap()); rcv.insert_vote(RankedVote::from_vector(&vec![4, 1]).unwrap()); assert_eq!(rcv.get_num_votes(), 5); let winner = rcv.determine_winner(); println!("WINNER = {:?}", winner); assert_eq!( winner, Some(1), "Vote 4 > 1 should go to 1, leading to Candidate 1 winning" ); } #[test] fn test_simple_majority() { let votes = RankedVote::from_vectors(&vec![ vec![1, 2, 3, 4], vec![1, 2, 3], vec![3], vec![3, 2, 4], vec![1, 2] ]).unwrap(); let rcv = RankedChoiceVoteTrie::new(); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!(winner, Some(1), "Candidate 1 has majority"); } #[test] fn test_tie_scenario() { let votes = RankedVote::from_vectors(&vec![ vec![1, 2], vec![2, 1] ]).unwrap(); let rcv = RankedChoiceVoteTrie::new(); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!(winner, None, "There should be a tie"); } #[test] fn test_withold_vote_end() { let votes = RankedVote::from_vectors(&vec![ vec![1, WITHOLD_VOTE_VAL], vec![2, 1], vec![3, 2], vec![3] ]).unwrap(); let rcv = RankedChoiceVoteTrie::new(); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!( winner, None, concat![ "Candidate 1's vote should not count after round 1, ", "no one should have majority" ]); } #[test] fn test_abstain_vote_end() { let votes = RankedVote::from_vectors(&vec![ vec![1, ABSTAIN_VOTE_VAL], vec![2, 1], vec![3, 2], vec![3] ]).unwrap(); let rcv = RankedChoiceVoteTrie::new(); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!( winner, Some(3), concat![ "First vote is ignored in round 2, candidate 3 wins" ]); } #[test] fn test_withhold_votes_only() { let votes = RankedVote::from_vectors(&vec![ vec![WITHOLD_VOTE_VAL], vec![WITHOLD_VOTE_VAL], vec![WITHOLD_VOTE_VAL], vec![ABSTAIN_VOTE_VAL] ]).unwrap(); let rcv = RankedChoiceVoteTrie::new(); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!(winner, None); } #[test] fn test_dowdall_elimination() { let votes = RankedVote::from_vectors(&vec![ vec![1, 6, 15], vec![1, 2, 6, 15, 5, 4, 7, 3, 11], vec![6, 15, 1, 11, 10, 16, 17, 8, 2, 3, 5, 7], vec![9, 8, 6, 11, 13, 3, 1], vec![13, 14, 16, 6, 3, 4, 5, 2, 1, 8, 9] ]).unwrap(); let rcv = RankedChoiceVoteTrie::new(); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!(winner, Some(6)); } #[test] fn test_all_elimination() { let votes = RankedVote::from_vectors(&vec![ vec![1, 6, 15], vec![1, 2, 6, 15, 5, 4, 7, 3, 11], vec![6, 15, 1, 11, 10, 16, 17, 8, 2, 3, 5, 7], vec![9, 8, 6, 11, 13, 3, 1], vec![13, 14, 16, 6, 3, 4, 5, 2, 1, 8, 9] ]).unwrap(); let mut rcv = RankedChoiceVoteTrie::new(); rcv.set_elimination_strategy(EliminationStrategies::EliminateAll); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!(winner, Some(1)); } #[test] fn test_spoiler_vote() { const T: i32 = 3; const S: i32 = 2; const B: i32 = 1; let rcv_vote_type1 = vec![vec![S, B, T]]; let rcv_vote_type2 = vec![vec![B, S, T]]; let rcv_vote_type3 = vec![vec![B, T, S]]; let rcv_vote_type4 = vec![vec![T, B, S]]; fn repeat(num_votes: u64, vote_type: Vec>) -> Vec> { return (0..num_votes) .flat_map(|_| vote_type.clone()) .collect::>(); } let mut raw_votes: Vec> = vec![]; raw_votes.extend(repeat(35, rcv_vote_type1)); raw_votes.extend(repeat(10, rcv_vote_type2)); raw_votes.extend(repeat(10, rcv_vote_type3)); raw_votes.extend(repeat(45, rcv_vote_type4)); let votes = RankedVote::from_vectors(&raw_votes).unwrap(); let mut rcv = RankedChoiceVoteTrie::new(); rcv.set_elimination_strategy(EliminationStrategies::RankedPairs); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!(winner, Some(T as u32)); } #[test] fn test_condorcet_vote() { const T: i32 = 3; const S: i32 = 2; const B: i32 = 1; let rcv_vote_type1 = vec![vec![S, B, T]]; let rcv_vote_type2 = vec![vec![B, S, T]]; let rcv_vote_type3 = vec![vec![B, T, S]]; let rcv_vote_type4 = vec![vec![T, B, S]]; fn repeat(num_votes: u64, vote_type: Vec>) -> Vec> { (0..num_votes) .flat_map(|_| vote_type.clone()) .collect::>() } let mut raw_votes: Vec> = vec![]; raw_votes.extend(repeat(35, rcv_vote_type1)); raw_votes.extend(repeat(10, rcv_vote_type2)); raw_votes.extend(repeat(10, rcv_vote_type3)); raw_votes.extend(repeat(45, rcv_vote_type4)); let votes = RankedVote::from_vectors(&raw_votes).unwrap(); let mut rcv = RankedChoiceVoteTrie::new(); rcv.set_elimination_strategy(EliminationStrategies::CondorcetRankedPairs); let winner = rcv.run_election(votes); println!("WINNER = {:?}", winner); assert_eq!(winner, Some(B as u32)); }