football-manager 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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