football-manager 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'http://rubygems.org'
2
+
3
+ group :test, :development do
4
+ gem 'cucumber', '~>1.1'
5
+ gem 'aruba', '~> 0.4'
6
+ gem 'rake'
7
+ gem 'awesome_print'
8
+ gem 'ruby-debug19', :require => 'ruby-debug'
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,57 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ archive-tar-minitar (0.5.2)
5
+ aruba (0.4.11)
6
+ childprocess (>= 0.2.3)
7
+ cucumber (>= 1.1.1)
8
+ ffi (>= 1.0.11)
9
+ rspec (>= 2.7.0)
10
+ awesome_print (1.0.2)
11
+ builder (3.0.0)
12
+ childprocess (0.3.1)
13
+ ffi (~> 1.0.6)
14
+ columnize (0.3.6)
15
+ cucumber (1.1.9)
16
+ builder (>= 2.1.2)
17
+ diff-lcs (>= 1.1.2)
18
+ gherkin (~> 2.9.0)
19
+ json (>= 1.4.6)
20
+ term-ansicolor (>= 1.0.6)
21
+ diff-lcs (1.1.3)
22
+ ffi (1.0.11)
23
+ gherkin (2.9.0)
24
+ json (>= 1.4.6)
25
+ json (1.6.5)
26
+ linecache19 (0.5.12)
27
+ ruby_core_source (>= 0.1.4)
28
+ rake (0.9.2.2)
29
+ rspec (2.8.0)
30
+ rspec-core (~> 2.8.0)
31
+ rspec-expectations (~> 2.8.0)
32
+ rspec-mocks (~> 2.8.0)
33
+ rspec-core (2.8.0)
34
+ rspec-expectations (2.8.0)
35
+ diff-lcs (~> 1.1.2)
36
+ rspec-mocks (2.8.0)
37
+ ruby-debug-base19 (0.11.25)
38
+ columnize (>= 0.3.1)
39
+ linecache19 (>= 0.5.11)
40
+ ruby_core_source (>= 0.1.4)
41
+ ruby-debug19 (0.11.6)
42
+ columnize (>= 0.3.1)
43
+ linecache19 (>= 0.5.11)
44
+ ruby-debug-base19 (>= 0.11.19)
45
+ ruby_core_source (0.1.5)
46
+ archive-tar-minitar (>= 0.5.2)
47
+ term-ansicolor (1.0.7)
48
+
49
+ PLATFORMS
50
+ ruby
51
+
52
+ DEPENDENCIES
53
+ aruba (~> 0.4)
54
+ awesome_print
55
+ cucumber (~> 1.1)
56
+ rake
57
+ ruby-debug19
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ ## WHY I EXIST
2
+
3
+ I am a tool to help you pick the fairest teams for your game
4
+
5
+ ## HOW TO INSTALL ME
6
+
7
+ gem install football-manager
8
+
9
+ ## HOW TO USE ME
10
+
11
+ 1) Create a file with all your available players, including their names and skill level
12
+
13
+ e.g. players.txt
14
+
15
+ Alan, 5
16
+ Paul, 3
17
+ Jeff, 4
18
+ Tom, 2
19
+ Steve B, 4
20
+ Steve T, 4
21
+
22
+ 2) Run me from the command line
23
+
24
+ football-manager -f players.txt
25
+
26
+ 3) Two fair team should now be output
27
+
28
+
29
+
30
+ I will randomise the teams to the best of my algorithmic ability!
data/Rakefile ADDED
@@ -0,0 +1,150 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'date'
4
+
5
+ #############################################################################
6
+ #
7
+ # Helper functions
8
+ #
9
+ #############################################################################
10
+
11
+ def name
12
+ @name ||= Dir['*.gemspec'].first.split('.').first
13
+ end
14
+
15
+ def version
16
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
17
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
+ end
19
+
20
+ def date
21
+ Date.today.to_s
22
+ end
23
+
24
+ def rubyforge_project
25
+ name
26
+ end
27
+
28
+ def gemspec_file
29
+ "#{name}.gemspec"
30
+ end
31
+
32
+ def gem_file
33
+ "#{name}-#{version}.gem"
34
+ end
35
+
36
+ def replace_header(head, header_name)
37
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
38
+ end
39
+
40
+ #############################################################################
41
+ #
42
+ # Standard tasks
43
+ #
44
+ #############################################################################
45
+
46
+ task :default => :test
47
+
48
+ require 'rake/testtask'
49
+ Rake::TestTask.new(:test) do |test|
50
+ test.libs << 'lib' << 'test'
51
+ test.pattern = 'test/**/test_*.rb'
52
+ test.verbose = true
53
+ end
54
+
55
+ desc "Generate RCov test coverage and open in your browser"
56
+ task :coverage do
57
+ require 'rcov'
58
+ sh "rm -fr coverage"
59
+ sh "rcov test/test_*.rb"
60
+ sh "open coverage/index.html"
61
+ end
62
+
63
+ require 'rake/rdoctask'
64
+ Rake::RDocTask.new do |rdoc|
65
+ rdoc.rdoc_dir = 'rdoc'
66
+ rdoc.title = "#{name} #{version}"
67
+ rdoc.rdoc_files.include('README*')
68
+ rdoc.rdoc_files.include('lib/**/*.rb')
69
+ end
70
+
71
+ desc "Open an irb session preloaded with this library"
72
+ task :console do
73
+ sh "irb -rubygems -r ./lib/#{name}.rb"
74
+ end
75
+
76
+ #############################################################################
77
+ #
78
+ # Custom tasks (add your own tasks here)
79
+ #
80
+ #############################################################################
81
+
82
+
83
+
84
+ #############################################################################
85
+ #
86
+ # Packaging tasks
87
+ #
88
+ #############################################################################
89
+
90
+ desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
91
+ task :release => :build do
92
+ unless `git branch` =~ /^\* master$/
93
+ puts "You must be on the master branch to release!"
94
+ exit!
95
+ end
96
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
97
+ sh "git tag v#{version}"
98
+ sh "git push origin master"
99
+ sh "git push origin v#{version}"
100
+ sh "gem push pkg/#{name}-#{version}.gem"
101
+ end
102
+
103
+ desc "Build #{gem_file} into the pkg directory"
104
+ task :build => :gemspec do
105
+ sh "mkdir -p pkg"
106
+ sh "gem build #{gemspec_file}"
107
+ sh "mv #{gem_file} pkg"
108
+ end
109
+
110
+ desc "Generate #{gemspec_file}"
111
+ task :gemspec => :validate do
112
+ # read spec file and split out manifest section
113
+ spec = File.read(gemspec_file)
114
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
115
+
116
+ # replace name version and date
117
+ replace_header(head, :name)
118
+ replace_header(head, :version)
119
+ replace_header(head, :date)
120
+ #comment this out if your rubyforge_project has a different name
121
+ replace_header(head, :rubyforge_project)
122
+
123
+ # determine file list from git ls-files
124
+ files = `git ls-files`.
125
+ split("\n").
126
+ sort.
127
+ reject { |file| file =~ /^\./ }.
128
+ reject { |file| file =~ /^(rdoc|pkg)/ }.
129
+ map { |file| " #{file}" }.
130
+ join("\n")
131
+
132
+ # piece file back together and write
133
+ manifest = " s.files = %w[\n#{files}\n ]\n"
134
+ spec = [head, manifest, tail].join(" # = MANIFEST =\n")
135
+ File.open(gemspec_file, 'w') { |io| io.write(spec) }
136
+ puts "Updated #{gemspec_file}"
137
+ end
138
+
139
+ desc "Validate #{gemspec_file}"
140
+ task :validate do
141
+ libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
142
+ unless libfiles.empty?
143
+ puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
144
+ exit!
145
+ end
146
+ unless Dir['VERSION*'].empty?
147
+ puts "A `VERSION` file at root level violates Gem best practices."
148
+ exit!
149
+ end
150
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ruby-debug'
4
+ require 'optparse'
5
+
6
+ require File.dirname(__FILE__) + '/../lib/football-manager'
7
+
8
+ options = {}
9
+
10
+ optparse = OptionParser.new do |opts|
11
+ options[:player_data] = nil
12
+ opts.on('-f', '--file FILE', 'Input player data') { |player_data| options[:player_data] = player_data }
13
+ end
14
+
15
+ optparse.parse!
16
+
17
+ FootballManager::Game.pick_teams(options[:player_data])
@@ -0,0 +1,25 @@
1
+ Feature: Pick balanced teams
2
+ So that we have a close game at mnf
3
+ As a team manager
4
+ I want to pick balanced teams from the list of available players
5
+
6
+ Scenario: 2 players are available
7
+ Given the following available players
8
+ | name | skill |
9
+ | player 1 | 5 |
10
+ | player 2 | 5 |
11
+ When I pick the teams
12
+ Then each team should have 1 player and 5 points
13
+
14
+ Scenario: 5 players are available
15
+ Given the following available players
16
+ | name | skill |
17
+ | player 1 | 5 |
18
+ | player 2 | 5 |
19
+ | player 3 | 1 |
20
+ | player 4 | 1 |
21
+ | player 5 | 3 |
22
+
23
+ When I pick the teams
24
+ Then one team should have 3 players and 7 points
25
+ And one team should have 2 players and 8 points
@@ -0,0 +1,18 @@
1
+ Given 'the following available players' do |players|
2
+ player_content = players.hashes.inject('') do |total_content, player|
3
+ total_content << "#{player['name']},#{player['skill']}\n"
4
+ end
5
+ @player_data = write_file('player_data.txt', player_content)
6
+ end
7
+
8
+ When /^I pick the teams$/ do
9
+ run_simple(unescape('football-manager -f player_data.txt'))
10
+ end
11
+
12
+ Then /^each team should have (\d+) players? and (\d+) points?$/ do |number_of_players, points|
13
+ check_both_teams_are_equal(number_of_players, points)
14
+ end
15
+
16
+ Then /^one team should have (\d+) players? and (\d+) points?$/ do |number_of_players, points|
17
+ check_team_has_the_following(number_of_players, points)
18
+ end
@@ -0,0 +1,3 @@
1
+ require 'aruba/cucumber'
2
+
3
+ require 'ruby-debug'
@@ -0,0 +1,11 @@
1
+ def check_both_teams_are_equal(number_of_players, points)
2
+ ['A', 'B'].each do |team|
3
+ pattern = "Team #{team} has #{number_of_players} player[s]? and #{points} points"
4
+ assert_matching_output(pattern, all_output)
5
+ end
6
+ end
7
+
8
+ def check_team_has_the_following(number_of_players, points)
9
+ pattern = "Team (A|B) has #{number_of_players} player[s]? and #{points} points"
10
+ assert_matching_output(pattern, all_output)
11
+ end
@@ -0,0 +1,98 @@
1
+ ## This is the rakegem gemspec template. Make sure you read and understand
2
+ ## all of the comments. Some sections require modification, and others can
3
+ ## be deleted if you don't need them. Once you understand the contents of
4
+ ## this file, feel free to delete any comments that begin with two hash marks.
5
+ ## You can find comprehensive Gem::Specification documentation, at
6
+ ## http://docs.rubygems.org/read/chapter/20
7
+ Gem::Specification.new do |s|
8
+ s.specification_version = 2 if s.respond_to? :specification_version=
9
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
+ s.rubygems_version = '1.3.5'
11
+
12
+ ## Leave these as is they will be modified for you by the rake gemspec task.
13
+ ## If your rubyforge_project name is different, then edit it and comment out
14
+ ## the sub! line in the Rakefile
15
+ s.name = 'football-manager'
16
+ s.version = '0.1.0'
17
+ s.date = '2012-03-13'
18
+ s.rubyforge_project = 'football-manager'
19
+
20
+ ## Make sure your summary is short. The description may be as long
21
+ ## as you like.
22
+ s.summary = "Picks two teams fair based on player skill"
23
+ s.description = "Picks two teams fair based on player skill"
24
+
25
+ ## List the primary authors. If there are a bunch of authors, it's probably
26
+ ## better to set the email to an email list or something. If you don't have
27
+ ## a custom homepage, consider using your GitHub URL or the like.
28
+ s.authors = ["James Shipton"]
29
+ s.email = 'ionysis@gmail.com'
30
+ s.homepage = 'https://github.com/jamesshipton/football-manager'
31
+
32
+ ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
33
+ ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
34
+ s.require_paths = %w[lib]
35
+
36
+ ## This sections is only necessary if you have C extensions.
37
+ # s.require_paths << 'ext'
38
+ # s.extensions = %w[ext/extconf.rb]
39
+
40
+ ## If your gem includes any executables, list them here.
41
+ s.executables = ["football-manager"]
42
+
43
+ ## Specify any RDoc options here. You'll want to add your README and
44
+ ## LICENSE files to the extra_rdoc_files list.
45
+ s.rdoc_options = ["--charset=UTF-8"]
46
+ s.extra_rdoc_files = %w[README.md]
47
+
48
+ ## List your runtime dependencies here. Runtime dependencies are those
49
+ ## that are needed for an end user to actually USE your code.
50
+ # s.add_dependency('DEPNAME', [">= 1.1.0", "< 2.0.0"])
51
+
52
+ ## List your development dependencies here. Development dependencies are
53
+ ## those that are only needed during development
54
+ s.add_development_dependency 'aruba', '~> 0.4'
55
+ s.add_development_dependency 'cucumber', '~>1.1'
56
+ s.add_development_dependency 'aruba', '~> 0.4'
57
+ s.add_development_dependency 'rake'
58
+ s.add_development_dependency 'awesome_print'
59
+ s.add_development_dependency 'ruby-debug19'
60
+
61
+ ## Leave this section as-is. It will be automatically generated from the
62
+ ## contents of your Git repository via the gemspec task. DO NOT REMOVE
63
+ ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
64
+ # = MANIFEST =
65
+ s.files = %w[
66
+ Gemfile
67
+ Gemfile.lock
68
+ README.md
69
+ Rakefile
70
+ bin/football-manager
71
+ features/choose_teams.feature
72
+ features/step-definitions/choose_teams_steps.rb
73
+ features/support/aruba.rb
74
+ features/support/choose_teams_support.rb
75
+ football-manager.gemspec
76
+ lib/football-manager.rb
77
+ lib/football-manager/custom_exceptions.rb
78
+ lib/football-manager/game.rb
79
+ lib/football-manager/i_o_helper.rb
80
+ lib/football-manager/player.rb
81
+ lib/football-manager/players_creator.rb
82
+ lib/football-manager/team.rb
83
+ lib/football-manager/team_picker.rb
84
+ lib/football-manager/team_sheet_creator.rb
85
+ spec/football-manager/game_spec.rb
86
+ spec/football-manager/player_spec.rb
87
+ spec/football-manager/players_creator_spec.rb
88
+ spec/football-manager/team_picker_spec.rb
89
+ spec/football-manager/team_sheet_creator_spec.rb
90
+ spec/football-manager/team_spec.rb
91
+ spec/spec_helper.rb
92
+ ]
93
+ # = MANIFEST =
94
+
95
+ ## Test files will be grabbed from the file list. Make sure the path glob
96
+ ## matches what you actually use.
97
+ s.test_files = s.files.select { |path| path =~ /spec_.*\.rb/ }
98
+ end
@@ -0,0 +1,5 @@
1
+ module FootballManager
2
+ class PlayerError < ::StandardError; end
3
+
4
+ class TeamError < ::StandardError; end
5
+ end
@@ -0,0 +1,10 @@
1
+ module FootballManager
2
+ module Game
3
+ def self.pick_teams(player_data_reference)
4
+ player_data = FootballManager::IOHelper.fetch_player_data(player_data_reference)
5
+ players = FootballManager::PlayersCreator.create_players(player_data)
6
+ teams = FootballManager::TeamPicker.calculate_fair_teams(players)
7
+ FootballManager::TeamSheetCreator.create_team_sheet(teams)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ module FootballManager
2
+ module IOHelper
3
+ def self.fetch_player_data(player_data_reference)
4
+ File.readlines(player_data_reference)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module FootballManager
2
+ class Player
3
+
4
+ attr_accessor :name, :skill
5
+
6
+ def initialize(name, skill)
7
+ @name = name if valid?(name, 'name')
8
+ @skill = skill.to_i if valid?(skill, 'skill')
9
+ end
10
+
11
+ def valid?(attribute, attribute_name)
12
+ attribute.nil? ? fail(FootballManager::PlayerError, "You cannot create a player with no #{attribute_name}") : true
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ module FootballManager
2
+ class PlayersCreator
3
+
4
+ class << self
5
+ attr_accessor :player_match
6
+
7
+ def create_players(player_data)
8
+ player_data.collect do |player|
9
+ player =~ player_pattern
10
+ self.player_match = Regexp.last_match
11
+ FootballManager::Player.new(player_name, player_skill)
12
+ end
13
+ end
14
+
15
+ def player_pattern
16
+ /^\s*([a-zA-Z0-9]+\s?[a-zA-Z0-9]+)\s*,\s*([1-5]{1})\s*$/
17
+ end
18
+
19
+ def player_name
20
+ player_match.captures.first
21
+ end
22
+
23
+ def player_skill
24
+ player_match.captures.last
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ module FootballManager
2
+ class Team
3
+ attr_reader :players
4
+
5
+ def initialize
6
+ @players = []
7
+ end
8
+
9
+ def <<(player)
10
+ @players << player
11
+ end
12
+
13
+ def empty?
14
+ @players.empty?
15
+ end
16
+
17
+ def size
18
+ @players.size
19
+ end
20
+
21
+ def points
22
+ @players.inject(0) { |total_skill, player| total_skill + player.skill}
23
+ end
24
+
25
+ def players_ordered_by_name
26
+ @players.sort_by { |player| player.name }
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+
33
+
34
+
@@ -0,0 +1,26 @@
1
+ module FootballManager
2
+ module TeamPicker
3
+ def self.calculate_fair_teams(players)
4
+ # players_in_descending_order = players.sort { |a,b| b.skill <=> a.skill }
5
+ players_in_descending_order = []
6
+
7
+ 5.downto(1) do |i|
8
+ players_in_descending_order <<
9
+ players.select { |player| player.skill == i }.sort_by {rand}
10
+ end
11
+
12
+ team_a, team_b = FootballManager::Team.new, FootballManager::Team.new
13
+
14
+ players_in_descending_order.flatten.partition do |player|
15
+ if team_a.empty? || team_a.points <= team_b.points
16
+ team_a << player
17
+ else
18
+ team_b << player
19
+ end
20
+ end
21
+
22
+ return [team_a, team_b]
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,12 @@
1
+ module FootballManager
2
+ module TeamSheetCreator
3
+ def self.create_team_sheet(teams)
4
+ teams.each do |team|
5
+ puts "Team #{teams.first == team ? 'A' : 'B'} has #{team.size} player and #{team.points} points"
6
+ team.players_ordered_by_name.each do |player|
7
+ puts player.name
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ module FOOTBALLMANAGER
2
+ VERSION = '0.1.0'
3
+ end
4
+
5
+ require 'ruby-debug'
6
+
7
+ require File.dirname(__FILE__) + '/football-manager/game'
8
+ require File.dirname(__FILE__) + '/football-manager/players_creator'
9
+ require File.dirname(__FILE__) + '/football-manager/team_picker'
10
+ require File.dirname(__FILE__) + '/football-manager/team_sheet_creator'
11
+ require File.dirname(__FILE__) + '/football-manager/i_o_helper'
12
+ require File.dirname(__FILE__) + '/football-manager/player'
13
+ require File.dirname(__FILE__) + '/football-manager/team'
14
+ require File.dirname(__FILE__) + '/football-manager/custom_exceptions'
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe FootballManager::Game do
4
+ subject { FootballManager::Game }
5
+
6
+ describe 'pick_teams' do
7
+ let(:player_data_reference) { double('player data reference') }
8
+ let(:player_data) { double('player data') }
9
+ let(:players) { double('players') }
10
+ let(:teams) { double('teams') }
11
+ let(:team_sheet) { double('team sheet') }
12
+
13
+ before(:each) do
14
+ FootballManager::IOHelper.stub(:fetch_player_data => player_data)
15
+ FootballManager::PlayersCreator.stub(:create_players => players)
16
+ FootballManager::TeamPicker.stub(:calculate_fair_teams => teams)
17
+ FootballManager::TeamSheetCreator.stub(:create_team_sheet => team_sheet)
18
+ end
19
+
20
+ it 'tells the IOHelper to fetch the player data' do
21
+ FootballManager::IOHelper.should_receive(:fetch_player_data).with(player_data_reference).and_return(player_data)
22
+ subject.pick_teams(player_data_reference)
23
+ end
24
+
25
+ it 'tells the PlayersCreator to create the players from the input file' do
26
+ FootballManager::PlayersCreator.should_receive(:create_players).with(player_data).and_return(players)
27
+ subject.pick_teams(player_data_reference)
28
+ end
29
+
30
+ it 'tells the TeamPicker to pick the fairest teams from the available players' do
31
+ FootballManager::TeamPicker.should_receive(:calculate_fair_teams).with(players).and_return(teams)
32
+ subject.pick_teams(player_data_reference)
33
+ end
34
+
35
+ it 'tells the TeamSheetCreator to create a teamsheet from the teams' do
36
+ FootballManager::TeamSheetCreator.should_receive(:create_team_sheet).with(teams)
37
+ subject.pick_teams(player_data_reference)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe FootballManager::Player do
4
+ subject { FootballManager::Player.new(name, skill)}
5
+
6
+ context 'valid' do
7
+ let(:name) { 'player 1' }
8
+ let(:skill) { '5' }
9
+
10
+ its(:name) { should == 'player 1' }
11
+ its(:skill) { should == 5 }
12
+ end
13
+
14
+ context 'invalid with no name' do
15
+ let(:name) { nil }
16
+ let(:skill) { '5' }
17
+
18
+ it 'raises an error' do
19
+ lambda { subject }.should raise_error(FootballManager::PlayerError, 'You cannot create a player with no name')
20
+ end
21
+ end
22
+
23
+ context 'invalid with no skill' do
24
+ let(:name) { 'player 1' }
25
+ let(:skill) { nil }
26
+
27
+ it 'raises an error' do
28
+ lambda { subject }.should raise_error(FootballManager::PlayerError, 'You cannot create a player with no skill')
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe FootballManager::PlayersCreator do
4
+ subject { FootballManager::PlayersCreator }
5
+
6
+ describe 'create_players' do
7
+ let(:player_1) { 'player 1, 5' }
8
+ let(:player_2) { 'player 2, 5' }
9
+ let(:player_1_name) { 'player 1' }
10
+ let(:player_2_name) { 'player 2' }
11
+ let(:player_1_skill) { '5' }
12
+ let(:player_2_skill) { '5' }
13
+ let(:player_data) { [player_1, player_2] }
14
+
15
+ it 'iterate through the player details, creating new players' do
16
+ FootballManager::Player.should_receive(:new).once.with(player_1_name, player_1_skill)
17
+ FootballManager::Player.should_receive(:new).once.with(player_2_name, player_2_skill)
18
+ subject.create_players(player_data)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe FootballManager::TeamPicker do
4
+ subject { FootballManager::TeamPicker.calculate_fair_teams(players) }
5
+
6
+ describe 'calculate_fair_teams' do
7
+ context 'for 2 players each team should have 1 player each' do
8
+ let(:player_1) { double('player 1', :skill => 1) }
9
+ let(:player_2) { double('player 2', :skill => 1) }
10
+ let(:players) { [player_1, player_2] }
11
+ let(:team_a) { double('team a') }
12
+ let(:team_b) { double('team b') }
13
+
14
+ before(:each) do
15
+ FootballManager::Team.should_receive(:new).twice.and_return(team_a, team_b)
16
+ team_a.should_receive(:empty?).twice.and_return(true, false)
17
+ team_a.should_receive(:points).once.and_return(1)
18
+ team_b.should_receive(:points).once.and_return(0)
19
+ team_a.should_receive(:<<).once
20
+ team_b.should_receive(:<<).once
21
+ end
22
+
23
+ it { should == [team_a, team_b] }
24
+ end
25
+
26
+ context 'for 5 players with a total of 15 points' do
27
+ let(:player_with_5_skill) { double('player 5', :skill => 5) }
28
+ let(:player_with_1_skill) { double('player 1', :skill => 1) }
29
+ let(:player_with_3_skill) { double('player 3', :skill => 3) }
30
+ let(:players) { [ player_with_5_skill,
31
+ player_with_5_skill,
32
+ player_with_1_skill,
33
+ player_with_1_skill,
34
+ player_with_3_skill] }
35
+ let(:team_a) { double('team a') }
36
+ let(:team_b) { double('team b') }
37
+
38
+ before(:each) do
39
+ FootballManager::Team.should_receive(:new).twice.and_return(team_a, team_b)
40
+ team_a.should_receive(:empty?).exactly(5).times.and_return(true, false, false, false, false)
41
+ team_a.should_receive(:points).exactly(4).times.and_return(5, 5, 8, 8)
42
+ team_b.should_receive(:points).exactly(4).times.and_return(0, 5, 6, 7)
43
+ team_a.should_receive(:<<).once.with(player_with_5_skill)
44
+ team_a.should_receive(:<<).once.with(player_with_3_skill)
45
+ team_b.should_receive(:<<).once.with(player_with_5_skill)
46
+ team_b.should_receive(:<<).once.with(player_with_1_skill)
47
+ team_b.should_receive(:<<).once.with(player_with_1_skill)
48
+ end
49
+
50
+ it { should == [team_a, team_b] }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe FootballManager::TeamSheetCreator do
4
+ subject { FootballManager::TeamSheetCreator }
5
+
6
+ describe 'create_team_sheet' do
7
+ let(:player_1) { double('player 1', :name => 'player 1', :skill => 1) }
8
+ let(:player_2) { double('player 2', :name => 'player 2', :skill => 1) }
9
+ let(:team_1) { double('team 1', :size => 1, :points => 5, :players => [player_1]) }
10
+ let(:team_2) { double('team 2', :size => 1, :points => 5, :players => [player_2]) }
11
+
12
+
13
+ it 'asks each team for their size' do
14
+ team_1.should_receive(:size).once
15
+ team_2.should_receive(:size).once
16
+ subject.create_team_sheet([team_1, team_2])
17
+ end
18
+
19
+ it 'asks each team for their points' do
20
+ team_1.should_receive(:points).once
21
+ team_2.should_receive(:points).once
22
+ subject.create_team_sheet([team_1, team_2])
23
+ end
24
+
25
+ it 'outputs the team size in the teamsheet' do
26
+ $stdout.should_receive(:puts).with("Team A has 1 player and 5 points")
27
+ $stdout.should_receive(:puts).with("player 1")
28
+ $stdout.should_receive(:puts).with("Team B has 1 player and 5 points")
29
+ $stdout.should_receive(:puts).with("player 2")
30
+ subject.create_team_sheet([team_1, team_2])
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe FootballManager::Team do
4
+ subject { FootballManager::Team.new}
5
+
6
+ context 'without any players' do
7
+ its(:size) { should == 0 }
8
+
9
+ its(:points) { should == 0 }
10
+
11
+ its(:empty?) { should be_true }
12
+
13
+ its(:players) { should == [] }
14
+ end
15
+
16
+ context 'a player is added' do
17
+ let(:player_1) { double('player 1', :skill => 5) }
18
+
19
+ before(:each) do
20
+ subject << player_1
21
+ end
22
+
23
+ its(:size) { should == 1 }
24
+
25
+ its(:points) { should == 5 }
26
+
27
+ its(:empty?) { should be_false }
28
+
29
+ its(:players) { should == [player_1] }
30
+ end
31
+
32
+ context '2 players are added' do
33
+ let(:player_A) { double('player A', :name => 'player A', :skill => 5) }
34
+ let(:player_B) { double('player B', :name => 'player B', :skill => 3) }
35
+
36
+ before(:each) do
37
+ subject << player_B
38
+ subject << player_A
39
+ end
40
+
41
+ its(:size) { should == 2 }
42
+
43
+ its(:points) { should == 8 }
44
+
45
+ its(:players) { should == [player_B, player_A] }
46
+
47
+ its(:players_ordered_by_name) { should == [player_A, player_B] }
48
+ end
49
+
50
+ end
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/../lib/football-manager'
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: football-manager
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James Shipton
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-13 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aruba
16
+ requirement: &70156026556000 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '0.4'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70156026556000
25
+ - !ruby/object:Gem::Dependency
26
+ name: cucumber
27
+ requirement: &70156026555300 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '1.1'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70156026555300
36
+ - !ruby/object:Gem::Dependency
37
+ name: aruba
38
+ requirement: &70156026554220 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '0.4'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70156026554220
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70156026553240 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70156026553240
58
+ - !ruby/object:Gem::Dependency
59
+ name: awesome_print
60
+ requirement: &70156026425360 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70156026425360
69
+ - !ruby/object:Gem::Dependency
70
+ name: ruby-debug19
71
+ requirement: &70156026424600 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70156026424600
80
+ description: Picks two teams fair based on player skill
81
+ email: ionysis@gmail.com
82
+ executables:
83
+ - football-manager
84
+ extensions: []
85
+ extra_rdoc_files:
86
+ - README.md
87
+ files:
88
+ - Gemfile
89
+ - Gemfile.lock
90
+ - README.md
91
+ - Rakefile
92
+ - bin/football-manager
93
+ - features/choose_teams.feature
94
+ - features/step-definitions/choose_teams_steps.rb
95
+ - features/support/aruba.rb
96
+ - features/support/choose_teams_support.rb
97
+ - football-manager.gemspec
98
+ - lib/football-manager.rb
99
+ - lib/football-manager/custom_exceptions.rb
100
+ - lib/football-manager/game.rb
101
+ - lib/football-manager/i_o_helper.rb
102
+ - lib/football-manager/player.rb
103
+ - lib/football-manager/players_creator.rb
104
+ - lib/football-manager/team.rb
105
+ - lib/football-manager/team_picker.rb
106
+ - lib/football-manager/team_sheet_creator.rb
107
+ - spec/football-manager/game_spec.rb
108
+ - spec/football-manager/player_spec.rb
109
+ - spec/football-manager/players_creator_spec.rb
110
+ - spec/football-manager/team_picker_spec.rb
111
+ - spec/football-manager/team_sheet_creator_spec.rb
112
+ - spec/football-manager/team_spec.rb
113
+ - spec/spec_helper.rb
114
+ homepage: https://github.com/jamesshipton/football-manager
115
+ licenses: []
116
+ post_install_message:
117
+ rdoc_options:
118
+ - --charset=UTF-8
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ segments:
128
+ - 0
129
+ hash: 1859079858319446041
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project: football-manager
138
+ rubygems_version: 1.8.15
139
+ signing_key:
140
+ specification_version: 2
141
+ summary: Picks two teams fair based on player skill
142
+ test_files:
143
+ - spec/spec_helper.rb