Add tests to poll stats
While we already had "one test to rule all stats", testing each method individually makes reading, adding and changing tests easier. Note we need to make all methods being tested public. We could also test them using methods like `stats.generate[:total_valid_votes]` instead of `stats.total_valid_votes`, but then the tests would be more difficult to read.
This commit is contained in:
@@ -12,32 +12,49 @@ module Statisticable
|
||||
self.class.stats_methods.map { |stat_name| [stat_name, send(stat_name)] }.to_h
|
||||
end
|
||||
|
||||
def total_male_participants
|
||||
participants.where(gender: "male").count
|
||||
end
|
||||
|
||||
def total_female_participants
|
||||
participants.where(gender: "female").count
|
||||
end
|
||||
|
||||
def total_unknown_gender_or_age
|
||||
participants.where("gender IS NULL OR date_of_birth is NULL").uniq.count
|
||||
end
|
||||
|
||||
def male_percentage
|
||||
calculate_percentage(total_male_participants, total_participants_with_gender)
|
||||
end
|
||||
|
||||
def female_percentage
|
||||
calculate_percentage(total_female_participants, total_participants_with_gender)
|
||||
end
|
||||
|
||||
def participants_by_age
|
||||
age_groups.map do |start, finish|
|
||||
users = participants.where("date_of_birth > ? AND date_of_birth < ?",
|
||||
finish.years.ago.beginning_of_year,
|
||||
start.years.ago.end_of_year)
|
||||
|
||||
[
|
||||
"#{start} - #{finish}",
|
||||
{
|
||||
range: range_description(start, finish),
|
||||
count: users.count,
|
||||
percentage: calculate_percentage(users.count, total_participants)
|
||||
}
|
||||
]
|
||||
end.to_h
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def total_participants_with_gender
|
||||
participants.where.not(gender: nil).distinct.count
|
||||
end
|
||||
|
||||
def total_male_participants
|
||||
participants.where(gender: "male").count
|
||||
end
|
||||
|
||||
def total_female_participants
|
||||
participants.where(gender: "female").count
|
||||
end
|
||||
|
||||
def total_unknown_gender_or_age
|
||||
participants.where("gender IS NULL OR date_of_birth is NULL").uniq.count
|
||||
end
|
||||
|
||||
def male_percentage
|
||||
calculate_percentage(total_male_participants, total_participants_with_gender)
|
||||
end
|
||||
|
||||
def female_percentage
|
||||
calculate_percentage(total_female_participants, total_participants_with_gender)
|
||||
end
|
||||
|
||||
def age_groups
|
||||
[[16, 19],
|
||||
[20, 24],
|
||||
@@ -58,23 +75,6 @@ module Statisticable
|
||||
]
|
||||
end
|
||||
|
||||
def participants_by_age
|
||||
age_groups.map do |start, finish|
|
||||
users = participants.where("date_of_birth > ? AND date_of_birth < ?",
|
||||
finish.years.ago.beginning_of_year,
|
||||
start.years.ago.end_of_year)
|
||||
|
||||
[
|
||||
"#{start} - #{finish}",
|
||||
{
|
||||
range: range_description(start, finish),
|
||||
count: users.count,
|
||||
percentage: calculate_percentage(users.count, total_participants)
|
||||
}
|
||||
]
|
||||
end.to_h
|
||||
end
|
||||
|
||||
def calculate_percentage(fraction, total)
|
||||
return 0.0 if total.zero?
|
||||
|
||||
|
||||
@@ -13,77 +13,78 @@ class Poll::Stats
|
||||
null_percentage_web null_percentage_booth total_null_percentage]
|
||||
end
|
||||
|
||||
def total_participants
|
||||
total_participants_web + total_participants_booth
|
||||
end
|
||||
|
||||
%i[web booth].each do |channel|
|
||||
define_method :"total_participants_#{channel}" do
|
||||
send(:"total_#{channel}_valid") +
|
||||
send(:"total_#{channel}_white") +
|
||||
send(:"total_#{channel}_null")
|
||||
end
|
||||
|
||||
define_method :"total_participants_#{channel}_percentage" do
|
||||
calculate_percentage(send(:"total_participants_#{channel}"), total_participants)
|
||||
end
|
||||
end
|
||||
|
||||
def total_web_valid
|
||||
voters.where(origin: "web").count - total_web_white
|
||||
end
|
||||
|
||||
def total_web_white
|
||||
0
|
||||
end
|
||||
|
||||
def total_web_null
|
||||
0
|
||||
end
|
||||
|
||||
def total_booth_valid
|
||||
recounts.sum(:total_amount)
|
||||
end
|
||||
|
||||
def total_booth_white
|
||||
recounts.sum(:white_amount)
|
||||
end
|
||||
|
||||
def total_booth_null
|
||||
recounts.sum(:null_amount)
|
||||
end
|
||||
|
||||
def valid_percentage_web
|
||||
calculate_percentage(total_web_valid, total_valid_votes)
|
||||
end
|
||||
|
||||
def white_percentage_web
|
||||
calculate_percentage(total_web_white, total_white_votes)
|
||||
end
|
||||
|
||||
def null_percentage_web
|
||||
calculate_percentage(total_web_null, total_null_votes)
|
||||
end
|
||||
|
||||
%i[valid white null].each do |type|
|
||||
define_method :"#{type}_percentage_booth" do
|
||||
calculate_percentage(send(:"total_booth_#{type}"), send(:"total_#{type}_votes"))
|
||||
end
|
||||
|
||||
define_method :"total_#{type}_votes" do
|
||||
send(:"total_web_#{type}") + send(:"total_booth_#{type}")
|
||||
end
|
||||
|
||||
define_method :"total_#{type}_percentage" do
|
||||
calculate_percentage(send(:"total_#{type}_votes"), total_participants)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def participants
|
||||
User.where(id: voters.pluck(:user_id))
|
||||
end
|
||||
|
||||
def total_participants
|
||||
total_participants_web + total_participants_booth
|
||||
end
|
||||
|
||||
%i[web booth].each do |channel|
|
||||
define_method :"total_participants_#{channel}" do
|
||||
send(:"total_#{channel}_valid") +
|
||||
send(:"total_#{channel}_white") +
|
||||
send(:"total_#{channel}_null")
|
||||
end
|
||||
|
||||
define_method :"total_participants_#{channel}_percentage" do
|
||||
calculate_percentage(send(:"total_participants_#{channel}"), total_participants)
|
||||
end
|
||||
end
|
||||
|
||||
def total_web_valid
|
||||
voters.where(origin: "web").count - total_web_white
|
||||
end
|
||||
|
||||
def total_web_white
|
||||
0
|
||||
end
|
||||
|
||||
def total_web_null
|
||||
0
|
||||
end
|
||||
|
||||
def total_booth_valid
|
||||
recounts.sum(:total_amount)
|
||||
end
|
||||
|
||||
def total_booth_white
|
||||
recounts.sum(:white_amount)
|
||||
end
|
||||
|
||||
def total_booth_null
|
||||
recounts.sum(:null_amount)
|
||||
end
|
||||
|
||||
def valid_percentage_web
|
||||
calculate_percentage(total_web_valid, total_valid_votes)
|
||||
end
|
||||
|
||||
def white_percentage_web
|
||||
calculate_percentage(total_web_white, total_white_votes)
|
||||
end
|
||||
|
||||
def null_percentage_web
|
||||
calculate_percentage(total_web_null, total_null_votes)
|
||||
end
|
||||
|
||||
%i[valid white null].each do |type|
|
||||
define_method :"#{type}_percentage_booth" do
|
||||
calculate_percentage(send(:"total_booth_#{type}"), send(:"total_#{type}_votes"))
|
||||
end
|
||||
|
||||
define_method :"total_#{type}_votes" do
|
||||
send(:"total_web_#{type}") + send(:"total_booth_#{type}")
|
||||
end
|
||||
|
||||
define_method :"total_#{type}_percentage" do
|
||||
calculate_percentage(send(:"total_#{type}_votes"), total_participants)
|
||||
end
|
||||
end
|
||||
|
||||
def voters
|
||||
poll.voters
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user