mirror of
https://github.com/discourse/discourse.git
synced 2025-03-23 06:35:45 +08:00
FIX: poll ranked choice result algo majority check (#28191)
This commit is contained in:
parent
26c4d1398a
commit
183ef2024c
@ -44,7 +44,7 @@ class DiscoursePoll::RankedChoice
|
||||
potential_winners = find_potential_winners(tally, max_votes)
|
||||
|
||||
# Check for a majority and return if found
|
||||
if majority_check(tally, potential_winners, max_votes)
|
||||
if majority_check(tally, max_votes)
|
||||
majority_candidate = enrich(potential_winners.keys.first, options)
|
||||
|
||||
round_activity << { round: round, majority: majority_candidate, eliminated: nil }
|
||||
@ -112,10 +112,10 @@ class DiscoursePoll::RankedChoice
|
||||
tally.select { |k, v| v == max_votes }
|
||||
end
|
||||
|
||||
def self.majority_check(tally, potential_winners, max_votes)
|
||||
def self.majority_check(tally, max_votes)
|
||||
total_votes = tally.values.sum
|
||||
|
||||
max_votes > total_votes / 2 || potential_winners.count == 1
|
||||
max_votes && max_votes > total_votes / 2
|
||||
end
|
||||
|
||||
def self.identify_losers(tally)
|
||||
|
@ -14,6 +14,19 @@ RSpec.describe DiscoursePoll::RankedChoice do
|
||||
]
|
||||
end
|
||||
|
||||
let(:options_4) do
|
||||
[
|
||||
{ id: "Belle-lettres", html: "Belle-lettres" },
|
||||
{ id: "Comedy", html: "Comedy" },
|
||||
{ id: "Fantasy", html: "Fantasy" },
|
||||
{ id: "Historical", html: "Historical" },
|
||||
{ id: "Mystery", html: "Mystery" },
|
||||
{ id: "Non-fiction", html: "Non-fiction" },
|
||||
{ id: "Sci-fi", html: "Sci-fi" },
|
||||
{ id: "Thriller", html: "Thriller" },
|
||||
]
|
||||
end
|
||||
|
||||
it "correctly finds the winner with a simple majority" do
|
||||
votes = [%w[Alice Bob], %w[Bob Alice], %w[Alice Bob], %w[Bob Alice], %w[Alice Bob]]
|
||||
expect(described_class.run(votes, options_1)[:winning_candidate]).to eq(
|
||||
@ -60,10 +73,38 @@ RSpec.describe DiscoursePoll::RankedChoice do
|
||||
expect(described_class.run(votes, options_3)[:round_activity].length).to eq(2)
|
||||
end
|
||||
|
||||
it "handles the winner with a simple majority" do
|
||||
it "handles a tie after an elimination" do
|
||||
votes = [%w[Dave Alice], %w[Bob Dave]]
|
||||
expect(described_class.run(votes, options_3)[:tied_candidates]).to eq(
|
||||
[{ digest: "Dave", html: "Dave" }, { digest: "Bob", html: "Bob" }],
|
||||
)
|
||||
end
|
||||
|
||||
it "handles a complex multi-round tie" do
|
||||
votes = [
|
||||
%w[Belle-lettres Thriller Non-fiction Sci-fi Mystery Comedy Historical Fantasy],
|
||||
%w[Mystery Fantasy Belle-lettres Sci-fi Non-fiction Historical Thriller Comedy],
|
||||
%w[Mystery Thriller Belle-lettres Sci-fi Comedy Non-fiction Fantasy Historical],
|
||||
%w[Mystery Sci-fi Fantasy Thriller Non-fiction Belle-lettres Historical Comedy],
|
||||
%w[Mystery Thriller Non-fiction Sci-fi Comedy Historical Belle-lettres Fantasy],
|
||||
%w[Fantasy Non-fiction Mystery Sci-fi Thriller Historical Belle-lettres Comedy],
|
||||
%w[Fantasy Mystery Historical Thriller Sci-fi Non-fiction Comedy Belle-lettres],
|
||||
%w[Thriller Mystery Fantasy Non-fiction Sci-fi Historical Comedy Belle-lettres],
|
||||
%w[Mystery Fantasy Historical Thriller Non-fiction Comedy Sci-fi Belle-lettres],
|
||||
%w[Fantasy Sci-fi Thriller Mystery Non-fiction Comedy Historical Belle-lettres],
|
||||
%w[Fantasy Sci-fi Historical Non-fiction Comedy],
|
||||
%w[Fantasy Sci-fi Mystery Comedy Thriller Non-fiction Historical],
|
||||
%w[Fantasy Mystery Historical Non-fiction Sci-fi Comedy],
|
||||
%w[Fantasy Sci-fi Mystery Comedy Thriller Historical Non-fiction],
|
||||
%w[Comedy Historical Fantasy Sci-fi Mystery],
|
||||
%w[Sci-fi Thriller Mystery Non-fiction Comedy Fantasy],
|
||||
]
|
||||
|
||||
outcome = described_class.run(votes, options_4)
|
||||
|
||||
expect(outcome[:tied_candidates]).to eq(
|
||||
[{ digest: "Mystery", html: "Mystery" }, { digest: "Fantasy", html: "Fantasy" }],
|
||||
)
|
||||
expect(outcome[:round_activity].length).to eq(3)
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user