From 00bc8c82e320f06add1f90176d27f3c193490a61 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Wed, 17 Apr 2019 18:27:37 +0200 Subject: [PATCH 01/11] Correct Expected Test results (I am bad at quick math) --- spec/services/playoff_stage_service_spec.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/services/playoff_stage_service_spec.rb b/spec/services/playoff_stage_service_spec.rb index 1fb8eb7..be4f250 100644 --- a/spec/services/playoff_stage_service_spec.rb +++ b/spec/services/playoff_stage_service_spec.rb @@ -55,11 +55,13 @@ RSpec.describe PlayoffStageService do [ { team_size: 4, expected_amount_of_playoff_stages: 2 }, { team_size: 8, expected_amount_of_playoff_stages: 3 }, + { team_size: 9, expected_amount_of_playoff_stages: 4 }, + { team_size: 10, expected_amount_of_playoff_stages: 4 }, { team_size: 16, expected_amount_of_playoff_stages: 4 }, - { team_size: 24, expected_amount_of_playoff_stages: 4 }, + { team_size: 24, expected_amount_of_playoff_stages: 5 }, { team_size: 32, expected_amount_of_playoff_stages: 5 }, { team_size: 64, expected_amount_of_playoff_stages: 6 }, - { team_size: 111, expected_amount_of_playoff_stages: 6 } + { team_size: 111, expected_amount_of_playoff_stages: 7 } ].each do |parameters| it "generates playoff stages for #{parameters[:team_size]} teams" do amount_of_teams = parameters[:team_size] From 1c2d051364191c522aa9fdd12aaa37b3e3a287a9 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Wed, 17 Apr 2019 18:30:17 +0200 Subject: [PATCH 02/11] Subtract one off required stages if the number of teams is a power of 2 This way we now calculate the right amount of stages for every number. (I would test every number, but Jonas won't let me write tests for all of them..) --- app/services/playoff_stage_service.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index 1168ff4..fedcd07 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -65,7 +65,8 @@ class PlayoffStageService 0 else # black voodoo magic - stage_count = Math.log(Utils.previous_power_of_two(number_of_teams)) / Math.log(2) + stage_count = Math.log(Utils.next_power_of_two(number_of_teams)) / Math.log(2) + stage_count -= 1 if Utils.po2?(number_of_teams) stage_count.to_int end end From 49a6545af9f9f3e20ee390afe9cab56fc4e5ea73 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Wed, 17 Apr 2019 21:05:09 +0200 Subject: [PATCH 03/11] Fix start point for stages with matchnumbers that are not powers of 2 --- app/services/match_service.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/services/match_service.rb b/app/services/match_service.rb index 0eb9fa8..29fffdb 100644 --- a/app/services/match_service.rb +++ b/app/services/match_service.rb @@ -37,9 +37,11 @@ class MatchService matches << match end + # the start point is to compensate for all the teams that are already within a "normal" match + startpoint = matches.size until matches.size >= needed_games # while we do not have enough matches in general we need to fill the array with "single team" matches - i = matches.size + i = matches.size + startpoint match = Match.new state: :single_team, position: i, match_scores: [MatchScore.create(team: teams[i])] matches << match end From 6baaebddd932c8db0626ee82d4c338fee9c62f67 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Wed, 17 Apr 2019 21:06:20 +0200 Subject: [PATCH 04/11] Add Test for team numbers that are not powers of 2 --- spec/services/match_service_spec.rb | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/spec/services/match_service_spec.rb b/spec/services/match_service_spec.rb index 09fc450..3c46148 100644 --- a/spec/services/match_service_spec.rb +++ b/spec/services/match_service_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe MatchService do - describe '#generate_matches' do + describe 'generates' do [ { team_size: 2 }, { team_size: 4 }, @@ -11,7 +11,7 @@ RSpec.describe MatchService do { team_size: 64 } ].each do |parameters| result = parameters[:team_size] / 2 - it "generates #{result} matches from #{parameters[:team_size]} teams" do + it "#{result} matches from #{parameters[:team_size]} teams" do teams = build_list(:team, parameters[:team_size], tournament: create(:tournament)) generated_matches = MatchService.generate_matches teams expect(generated_matches.size).to eq(result) @@ -67,7 +67,29 @@ RSpec.describe MatchService do end end - # TODO: matches right teams for !powers of 2 + [ + { team_size: 3 }, + { team_size: 5 }, + { team_size: 7 }, + { team_size: 19 }, + { team_size: 41 }, + { team_size: 52 }, + { team_size: 111 } + + ].each do |parameters| + it "matches the right teams for team numbers that are not powers of 2 (#{parameters[:team_size]})" ,focus: true do + team_size = parameters[:team_size] + teams = build_list(:team, team_size, tournament: create(:tournament)) + generated_matches = MatchService.generate_matches teams + team_order = [] + generated_matches.each do |match| + match.match_scores.each do |score| + team_order << score.team + end + end + expect(team_order).to eq(teams) + end + end [ { team_size: 3, single_team_matches: 1 }, From 9918b4a71c5f478b48ed07044e30ec3bbd469c2d Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Wed, 17 Apr 2019 21:06:46 +0200 Subject: [PATCH 05/11] Improve test readability in logs --- spec/services/match_service_spec.rb | 4 ++-- spec/services/playoff_stage_service_spec.rb | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/services/match_service_spec.rb b/spec/services/match_service_spec.rb index 3c46148..e507890 100644 --- a/spec/services/match_service_spec.rb +++ b/spec/services/match_service_spec.rb @@ -54,7 +54,7 @@ RSpec.describe MatchService do { team_size: 256 } ].each do |parameters| - it "matches the right teams for powers of 2 (#{parameters[:team_size]})" do + it "the right matchups for powers of 2 (#{parameters[:team_size]})" do teams = build_list(:team, parameters[:team_size], tournament: create(:tournament)) generated_matches = MatchService.generate_matches teams generated_matches.each_index do |index| @@ -77,7 +77,7 @@ RSpec.describe MatchService do { team_size: 111 } ].each do |parameters| - it "matches the right teams for team numbers that are not powers of 2 (#{parameters[:team_size]})" ,focus: true do + it "the right matchups for team numbers that are not powers of 2 (#{parameters[:team_size]})" do team_size = parameters[:team_size] teams = build_list(:team, team_size, tournament: create(:tournament)) generated_matches = MatchService.generate_matches teams diff --git a/spec/services/playoff_stage_service_spec.rb b/spec/services/playoff_stage_service_spec.rb index be4f250..2e5270d 100644 --- a/spec/services/playoff_stage_service_spec.rb +++ b/spec/services/playoff_stage_service_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe PlayoffStageService do - describe '#generate_empty_matches' do + describe 'generates' do [ { amount: 1 }, { amount: 3 }, @@ -12,7 +12,7 @@ RSpec.describe PlayoffStageService do { amount: 82 }, { amount: 359 } ].each do |parameters| - it "generates #{parameters[:amount]} empty matches" do + it "#{parameters[:amount]} empty matches" do amount = parameters[:amount] generated_matches = PlayoffStageService.generate_empty_matches amount generated_matches.each_index do |i| @@ -24,7 +24,7 @@ RSpec.describe PlayoffStageService do end end - describe '#generate_stages_with_empty_matches' do + describe 'generates' do [ { stages: 1 }, { stages: 2 }, @@ -37,7 +37,7 @@ RSpec.describe PlayoffStageService do { stages: 9 }, { stages: 10 } ].each do |parameters| - it "generates #{parameters[:stages]} stages with matches provided by #generate_empty_matches" do + it "#{parameters[:stages]} stages with matches provided by #generate_empty_matches" do amount_of_empty_stages = parameters[:stages] empty_stages = PlayoffStageService.generate_stages_with_empty_matches(amount_of_empty_stages) expect(empty_stages.size).to eq(amount_of_empty_stages) @@ -51,7 +51,7 @@ RSpec.describe PlayoffStageService do end end - describe '#generate_playoffs' do + describe 'generates playoff stages for' do [ { team_size: 4, expected_amount_of_playoff_stages: 2 }, { team_size: 8, expected_amount_of_playoff_stages: 3 }, @@ -63,7 +63,7 @@ RSpec.describe PlayoffStageService do { team_size: 64, expected_amount_of_playoff_stages: 6 }, { team_size: 111, expected_amount_of_playoff_stages: 7 } ].each do |parameters| - it "generates playoff stages for #{parameters[:team_size]} teams" do + it "#{parameters[:team_size]} teams" do amount_of_teams = parameters[:team_size] expected_amount_of_playoff_stages = parameters[:expected_amount_of_playoff_stages] teams = build_list(:team, amount_of_teams) From 8b11f73a58afd378be7a0548b515951f153afcdf Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Thu, 18 Apr 2019 13:42:22 +0200 Subject: [PATCH 06/11] Add another Test Case --- spec/services/match_service_spec.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/spec/services/match_service_spec.rb b/spec/services/match_service_spec.rb index e507890..e1e2731 100644 --- a/spec/services/match_service_spec.rb +++ b/spec/services/match_service_spec.rb @@ -68,13 +68,14 @@ RSpec.describe MatchService do end [ - { team_size: 3 }, - { team_size: 5 }, - { team_size: 7 }, - { team_size: 19 }, - { team_size: 41 }, - { team_size: 52 }, - { team_size: 111 } + { team_size: 3 }, + { team_size: 5 }, + { team_size: 7 }, + { team_size: 9 }, + { team_size: 19 }, + { team_size: 41 }, + { team_size: 52 }, + { team_size: 111 } ].each do |parameters| it "the right matchups for team numbers that are not powers of 2 (#{parameters[:team_size]})" do From d221928a12b5cde8e12593c1e07c1f8202c34048 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Thu, 18 Apr 2019 14:18:17 +0200 Subject: [PATCH 07/11] Test generation of playoff stages for 1 2 and 3 teams --- spec/services/playoff_stage_service_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/services/playoff_stage_service_spec.rb b/spec/services/playoff_stage_service_spec.rb index 2e5270d..46dfe55 100644 --- a/spec/services/playoff_stage_service_spec.rb +++ b/spec/services/playoff_stage_service_spec.rb @@ -53,6 +53,9 @@ RSpec.describe PlayoffStageService do describe 'generates playoff stages for' do [ + { team_size: 1, expected_amount_of_playoff_stages: 1 }, + { team_size: 2, expected_amount_of_playoff_stages: 1 }, + { team_size: 3, expected_amount_of_playoff_stages: 2 }, { team_size: 4, expected_amount_of_playoff_stages: 2 }, { team_size: 8, expected_amount_of_playoff_stages: 3 }, { team_size: 9, expected_amount_of_playoff_stages: 4 }, From 38425df8237cb5e9e708327ea80af1f38fe51282 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Thu, 18 Apr 2019 14:19:19 +0200 Subject: [PATCH 08/11] Only support stage count calculation for 1+ teams --- app/services/playoff_stage_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/playoff_stage_service.rb b/app/services/playoff_stage_service.rb index fedcd07..340a9a2 100644 --- a/app/services/playoff_stage_service.rb +++ b/app/services/playoff_stage_service.rb @@ -61,8 +61,8 @@ class PlayoffStageService # @param number_of_teams [Integer] the teams number of teams to calculate amount of stages # @return [Integer] amount of required stages def self.calculate_required_stage_count(number_of_teams) - if number_of_teams.zero? || number_of_teams == 1 - 0 + if number_of_teams == 1 + 1 else # black voodoo magic stage_count = Math.log(Utils.next_power_of_two(number_of_teams)) / Math.log(2) From a30ff860e90b4fe5964f160feb0679b8f4ce344c Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Thu, 18 Apr 2019 14:19:50 +0200 Subject: [PATCH 09/11] Return a valid list of matches for 1 team --- app/services/match_service.rb | 9 ++++++++- spec/services/match_service_spec.rb | 4 ---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/services/match_service.rb b/app/services/match_service.rb index 29fffdb..90c5290 100644 --- a/app/services/match_service.rb +++ b/app/services/match_service.rb @@ -6,11 +6,18 @@ class MatchService # @param teams [Array] the teams to generate matches with # @return [Array] the generated matches def self.generate_matches(teams) - if teams.size < 2 + if teams.empty? # should be prevented by controller return end + if teams.size == 1 + matches = [] + match = Match.new state: :single_team, position: 1, match_scores: [MatchScore.create(team: teams.first)] + matches << match + return matches + end + # normal_games = number of matches with two teams attending # needed_games = number of matches to generate in total for the given number of teams if Utils.po2?(teams.size) diff --git a/spec/services/match_service_spec.rb b/spec/services/match_service_spec.rb index e1e2731..bdb844e 100644 --- a/spec/services/match_service_spec.rb +++ b/spec/services/match_service_spec.rb @@ -117,9 +117,5 @@ RSpec.describe MatchService do it 'generates no matches for 0 teams' do expect(MatchService.generate_matches([])). to eq(nil) end - - it 'generates no matches for 1 team' do - expect(MatchService.generate_matches(build_list(:team, 1))). to eq(nil) - end end end From a449e0193a47de6f44d26523dd58c0cc1d7c70e0 Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Tue, 23 Apr 2019 13:37:05 +0200 Subject: [PATCH 10/11] Use match_array instead of eq This is the proper way to compare arrays --- spec/services/match_service_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/services/match_service_spec.rb b/spec/services/match_service_spec.rb index bdb844e..c4abdb9 100644 --- a/spec/services/match_service_spec.rb +++ b/spec/services/match_service_spec.rb @@ -88,7 +88,7 @@ RSpec.describe MatchService do team_order << score.team end end - expect(team_order).to eq(teams) + expect(team_order).to match_array(teams) end end From d3d572ea1b68ab13dc6a3fa4f2784a7ddbf8f56e Mon Sep 17 00:00:00 2001 From: Malaber <32635600+Malaber@users.noreply.github.com> Date: Tue, 23 Apr 2019 14:18:34 +0200 Subject: [PATCH 11/11] Change return for 0 teams to exception --- app/services/match_service.rb | 2 +- spec/services/match_service_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/services/match_service.rb b/app/services/match_service.rb index 90c5290..adf2995 100644 --- a/app/services/match_service.rb +++ b/app/services/match_service.rb @@ -8,7 +8,7 @@ class MatchService def self.generate_matches(teams) if teams.empty? # should be prevented by controller - return + raise 'Cannot generate Matches without teams' end if teams.size == 1 diff --git a/spec/services/match_service_spec.rb b/spec/services/match_service_spec.rb index c4abdb9..21ada52 100644 --- a/spec/services/match_service_spec.rb +++ b/spec/services/match_service_spec.rb @@ -114,8 +114,8 @@ RSpec.describe MatchService do end end - it 'generates no matches for 0 teams' do - expect(MatchService.generate_matches([])). to eq(nil) + it 'raises an exception for for 0 teams' do + expect { MatchService.generate_matches([]) }. to raise_error 'Cannot generate Matches without teams' end end end