diff --git a/app/services/statistics_service.rb b/app/services/statistics_service.rb new file mode 100644 index 0000000..72c2b09 --- /dev/null +++ b/app/services/statistics_service.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class StatisticsService + def initialize(stage) + raise 'Unsupported stage type' if stage.nil? || stage.groups.empty? + + @stage = stage + @group_scores = sort_group_scores(@stage.groups, :group_points) + + @most_dominant_score = sort_group_scores(@stage.groups, :scored_points).first + @least_dominant_score = sort_group_scores(@stage.groups, :received_points).first + end + + attr_reader :group_scores + attr_reader :most_dominant_score + attr_reader :least_dominant_score + + private + + def sort_group_scores(groups, by) + groups + .map(&:group_scores).flatten # collect all group scores + .sort_by(&by).reverse + end +end diff --git a/spec/services/statistics_service_spec.rb b/spec/services/statistics_service_spec.rb new file mode 100644 index 0000000..6e53708 --- /dev/null +++ b/spec/services/statistics_service_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +RSpec.describe StatisticsService do + before do + # build tournament with predictable test data + tournament = create(:tournament) + group_stage = create(:group_stage) + group = group_stage.groups.first + @most_dominant_score = GroupScore.new team: create(:team), + group_points: 100, + scored_points: 100, received_points: 0 + @least_dominant_score = GroupScore.new team: create(:team), + group_points: 0, + scored_points: 0, received_points: 100 + group.group_scores << @most_dominant_score + group.group_scores << @least_dominant_score + tournament.stages << group_stage + @service = StatisticsService.new group_stage + end + + describe '#new' do + context 'with a playoff stage' do + it 'throws an exception' do + expect do + StatisticsService.new create(:playoff_stage) + end.to raise_error(RuntimeError) + end + end + + context 'with a group stage' do + it 'succeeds' do + StatisticsService.new create(:group_stage) + end + end + end + + describe '#most_dominant_score' do + it 'returns the most dominant group score' do + expect(@service.most_dominant_score.id).to eq(@most_dominant_score.id) + end + end + + describe '#least_dominant_score' do + it 'returns the least dominant group score' do + expect(@service.least_dominant_score.id).to eq(@least_dominant_score.id) + end + end + + describe '#group_scores' do + it 'returns an array containing all group scores' do + expect(@service.group_scores.length).to eq(GroupScore.count) + end + end +end