From 830362416d7edf157086c8af9aa5232f51251be9 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Fri, 4 Jun 2021 22:54:26 +1000 Subject: [PATCH] Fix logic error where loss by fraction not updated in multi-stage exclusions --- src/stv/mod.rs | 8 +++----- tests/utils/mod.rs | 11 +++++++++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/stv/mod.rs b/src/stv/mod.rs index c41ba46..91f4da0 100644 --- a/src/stv/mod.rs +++ b/src/stv/mod.rs @@ -825,8 +825,6 @@ where let count_card = state.candidates.get_mut(excluded_candidate).unwrap(); checksum -= &result.total_votes; count_card.transfer(&-result.total_votes); - - // By definition, there is no loss by fraction } } @@ -837,14 +835,14 @@ where count_card.transfers = -count_card.votes.clone(); count_card.votes = N::new(); - // Update loss by fraction - state.loss_fraction.transfer(&-checksum); - if let ExclusionMethod::SingleStage = opts.exclusion { } else { state.logger.log_literal("Exclusion complete.".to_string()); } } + + // Update loss by fraction + state.loss_fraction.transfer(&-checksum); } fn finished_before_stage(state: &CountState) -> bool { diff --git a/tests/utils/mod.rs b/tests/utils/mod.rs index bd0325b..9953ba2 100644 --- a/tests/utils/mod.rs +++ b/tests/utils/mod.rs @@ -80,12 +80,19 @@ where fn validate_stage(idx: usize, state: &CountState, records: &Vec) { println!("Col at idx {}", idx); - // Validate candidate votes - //let mut candidate_votes: Vec = records.iter().skip(2).map(|r| N::parse(&r[idx*2 + 1])).collect(); let mut candidate_votes: Vec = records.iter().skip(2).map(|r| N::from(r[idx*2 + 1].parse::().expect("Syntax Error"))).collect(); + + // Validate exhausted/LBF + let lbf_votes = candidate_votes.pop().unwrap(); + let exhausted_votes = candidate_votes.pop().unwrap(); + + assert!(state.exhausted.votes == exhausted_votes); + assert!(state.loss_fraction.votes == lbf_votes); + // Remove exhausted/LBF rows candidate_votes.truncate(candidate_votes.len() - 2); + // Validate candidate votes for (candidate, votes) in state.election.candidates.iter().zip(candidate_votes) { let count_card = state.candidates.get(candidate).unwrap(); assert!(count_card.votes == votes, "Failed to validate votes for candidate {}. Expected {:}, got {:}", candidate.name, votes, count_card.votes);