icu_tournament 0.8.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/LICENCE +22 -0
- data/README.rdoc +75 -0
- data/Rakefile +57 -0
- data/VERSION.yml +5 -0
- data/lib/icu_tournament.rb +8 -0
- data/lib/icu_tournament/federation.rb +303 -0
- data/lib/icu_tournament/name.rb +274 -0
- data/lib/icu_tournament/player.rb +204 -0
- data/lib/icu_tournament/result.rb +191 -0
- data/lib/icu_tournament/team.rb +90 -0
- data/lib/icu_tournament/tournament.rb +508 -0
- data/lib/icu_tournament/tournament_fcsv.rb +310 -0
- data/lib/icu_tournament/tournament_krause.rb +329 -0
- data/lib/icu_tournament/util.rb +156 -0
- data/spec/federation_spec.rb +176 -0
- data/spec/name_spec.rb +208 -0
- data/spec/player_spec.rb +313 -0
- data/spec/result_spec.rb +203 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/team_spec.rb +60 -0
- data/spec/tournament_fcsv_spec.rb +548 -0
- data/spec/tournament_krause_spec.rb +379 -0
- data/spec/tournament_spec.rb +733 -0
- data/spec/util_spec.rb +357 -0
- metadata +97 -0
data/spec/player_spec.rb
ADDED
@@ -0,0 +1,313 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
module ICU
|
4
|
+
describe Player do
|
5
|
+
context "a typical player" do
|
6
|
+
it "should have a name, number and some results" do
|
7
|
+
lambda do
|
8
|
+
player = Player.new('Mark', 'Orr', 1)
|
9
|
+
player.add_result(Result.new(1, 1, 'W', :opponent => 37, :score => 'W', :colour => 'W'))
|
10
|
+
player.add_result(Result.new(2, 1, 'W', :opponent => 13, :score => 'W', :colour => 'B'))
|
11
|
+
player.add_result(Result.new(3, 1, 'W', :opponent => 7, :score => 'D', :colour => 'W'))
|
12
|
+
end.should_not raise_error
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "names" do
|
17
|
+
it "should be specified in constructor" do
|
18
|
+
p = Player.new('Mark', 'Orr', 1)
|
19
|
+
p.first_name.should == 'Mark'
|
20
|
+
p.last_name.should == 'Orr'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be resettable via accessors" do
|
24
|
+
p = Player.new('Mark', 'Orr', 1)
|
25
|
+
p.first_name= 'Gary'
|
26
|
+
p.last_name= 'Kasparov'
|
27
|
+
p.first_name.should == 'Gary'
|
28
|
+
p.last_name.should == 'Kasparov'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not contain invalid characters" do
|
32
|
+
lambda { Player.new('12', 'Orr', 1) }.should raise_error(/invalid first name/)
|
33
|
+
lambda { Player.new('Mark', '*!', 1) }.should raise_error(/invalid last name/)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not have empty last name" do
|
37
|
+
lambda { Player.new('Mark', '', 1) }.should raise_error(/invalid last name/)
|
38
|
+
lambda { Player.new('', 'Orr', 1) }.should raise_error(/invalid first name/)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "both names can be returned together" do
|
42
|
+
p = Player.new('Mark', 'Orr', 1)
|
43
|
+
p.name.should == 'Orr, Mark'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "names should be automatically canonicalised" do
|
47
|
+
p = Player.new(' maRk J l ', ' ORR', 1)
|
48
|
+
p.name.should == 'Orr, Mark J. L.'
|
49
|
+
p.first_name = 'z'
|
50
|
+
p.name.should == 'Orr, Z.'
|
51
|
+
p.last_name = " o meFiSto "
|
52
|
+
p.name.should == "O'Mefisto, Z."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "number" do
|
57
|
+
it "should just be an integer" do
|
58
|
+
Player.new('Mark', 'Orr', 3).num.should == 3
|
59
|
+
Player.new('Mark', 'Orr', -7).num.should == -7
|
60
|
+
Player.new('Mark', 'Orr', ' -4 ').num.should == -4
|
61
|
+
Player.new('Mark', 'Orr', '0').num.should == 0
|
62
|
+
lambda { Player.new('Mark', 'Orr', ' ') }.should raise_error(/invalid integer/)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "ID" do
|
67
|
+
it "defaults to nil" do
|
68
|
+
Player.new('Mark', 'Orr', 3).id.should be_nil
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should be a positive integer" do
|
72
|
+
Player.new('Mark', 'Orr', 3, :id => 1350).id.should == 1350
|
73
|
+
Player.new('Gary', 'Kasparov', 4, :id => '4100018').id.should == 4100018
|
74
|
+
lambda { Player.new('Mark', 'Orr', 3, :id => ' 0 ') }.should raise_error(/invalid positive integer/)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "federation" do
|
79
|
+
it "defaults to nil" do
|
80
|
+
Player.new('Mark', 'Orr', 3).fed.should be_nil
|
81
|
+
Player.new('Mark', 'Orr', 3, :fed => ' ').fed.should be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should consist of at least three letters" do
|
85
|
+
Player.new('Gary', 'Kasparov', 1, :fed => 'RUS').fed.should == 'RUS'
|
86
|
+
Player.new('Mark', 'Orr', 3, :fed => ' Ireland ').fed.should == 'IRL'
|
87
|
+
lambda { Player.new('Danny', 'Kopec', 3, :fed => 'US') }.should raise_error(/invalid federation/)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "title" do
|
92
|
+
it "defaults to nil" do
|
93
|
+
Player.new('Mark', 'Orr', 3).title.should be_nil
|
94
|
+
Player.new('Mark', 'Orr', 3, :title => ' ').title.should be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should be one of national, candidate, FIDE, international or grand master" do
|
98
|
+
Player.new('Gary', 'Kasparov', 1, :title => 'GM').title.should == 'GM'
|
99
|
+
Player.new('Mark', 'Orr', 2, :title => ' im ').title.should == 'IM'
|
100
|
+
Player.new('Mark', 'Quinn', 2, :title => 'm').title.should == 'IM'
|
101
|
+
Player.new('Pia', 'Cramling', 3, :title => ' wg ').title.should == 'WGM'
|
102
|
+
Player.new('Philip', 'Short', 4, :title => 'F ').title.should == 'FM'
|
103
|
+
Player.new('Gearoidin', 'Ui Laighleis', 5, :title => 'wc').title.should == 'WCM'
|
104
|
+
Player.new('Gearoidin', 'Ui Laighleis', 7, :title => 'wm').title.should == 'WIM'
|
105
|
+
Player.new('Eamon', 'Keogh', 6, :title => 'nm').title.should == 'NM'
|
106
|
+
lambda { Player.new('Mark', 'Orr', 3, :title => 'Dr') }.should raise_error(/invalid chess title/)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "rating" do
|
111
|
+
it "defaults to nil" do
|
112
|
+
Player.new('Mark', 'Orr', 3).rating.should be_nil
|
113
|
+
Player.new('Mark', 'Orr', 3, :rating => ' ').rating.should be_nil
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should be a positive integer" do
|
117
|
+
Player.new('Gary', 'Kasparov', 1, :rating => 2800).rating.should == 2800
|
118
|
+
Player.new('Mark', 'Orr', 2, :rating => ' 2100 ').rating.should == 2100
|
119
|
+
lambda { Player.new('Mark', 'Orr', 3, :rating => -2100) }.should raise_error(/invalid positive integer/)
|
120
|
+
lambda { Player.new('Mark', 'Orr', 3, :rating => 'IM') }.should raise_error(/invalid positive integer/)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "rank" do
|
125
|
+
it "defaults to nil" do
|
126
|
+
Player.new('Mark', 'Orr', 3).rank.should be_nil
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should be a positive integer" do
|
130
|
+
Player.new('Mark', 'Orr', 3, :rank => 1).rank.should == 1
|
131
|
+
Player.new('Gary', 'Kasparov', 4, :rank => ' 29 ').rank.should == 29
|
132
|
+
lambda { Player.new('Mark', 'Orr', 3, :rank => 0) }.should raise_error(/invalid positive integer/)
|
133
|
+
lambda { Player.new('Mark', 'Orr', 3, :rank => ' -1 ') }.should raise_error(/invalid positive integer/)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "date of birth" do
|
138
|
+
it "defaults to nil" do
|
139
|
+
Player.new('Mark', 'Orr', 3).dob.should be_nil
|
140
|
+
Player.new('Mark', 'Orr', 3, :dob => ' ').dob.should be_nil
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should be a yyyy-mm-dd date" do
|
144
|
+
Player.new('Mark', 'Orr', 3, :dob => '1955-11-09').dob.should == '1955-11-09'
|
145
|
+
lambda { Player.new('Mark', 'Orr', 3, :dob => 'X') }.should raise_error(/invalid.*dob/)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "gender" do
|
150
|
+
it "defaults to nil" do
|
151
|
+
Player.new('Mark', 'Orr', 3).gender.should be_nil
|
152
|
+
Player.new('Mark', 'Orr', 3, :gender => ' ').gender.should be_nil
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should be either M or F" do
|
156
|
+
Player.new('Mark', 'Orr', 3, :gender => 'male').gender.should == 'M'
|
157
|
+
Player.new('April', 'Cronin', 3, :gender => 'woman').gender.should == 'F'
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should raise an exception if the gender is not specified properly" do
|
161
|
+
lambda { Player.new('Mark', 'Orr', 3, :gender => 'X') }.should raise_error(/invalid gender/)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context "results and points" do
|
166
|
+
it "should initialise to an empty array" do
|
167
|
+
results = Player.new('Mark', 'Orr', 3).results
|
168
|
+
results.should be_instance_of Array
|
169
|
+
results.size.should == 0
|
170
|
+
end
|
171
|
+
|
172
|
+
it "can be added to" do
|
173
|
+
player = Player.new('Mark', 'Orr', 3)
|
174
|
+
player.add_result(Result.new(1, 3, 'W', :opponent => 1))
|
175
|
+
player.add_result(Result.new(2, 3, 'D', :opponent => 2))
|
176
|
+
player.add_result(Result.new(3, 3, 'L', :opponent => 4))
|
177
|
+
results = player.results
|
178
|
+
results.should be_instance_of Array
|
179
|
+
results.size.should == 3
|
180
|
+
player.points.should == 1.5
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should not allow mismatched player numbers" do
|
184
|
+
player = Player.new('Mark', 'Orr', 3)
|
185
|
+
lambda { player.add_result(Result.new(1, 4, 'W', :opponent => 1)) }.should raise_error(/player number .* matched/)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should enforce unique round numbers" do
|
189
|
+
player = Player.new('Mark', 'Orr', 3)
|
190
|
+
player.add_result(Result.new(1, 3, 'W', :opponent => 1))
|
191
|
+
player.add_result(Result.new(2, 3, 'D', :opponent => 2))
|
192
|
+
lambda { player.add_result(Result.new(2, 3, 'L', :opponent => 4)) }.should raise_error(/round number .* unique/)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context "looking up results" do
|
197
|
+
before(:all) do
|
198
|
+
@p = Player.new('Mark', 'Orr', 1)
|
199
|
+
@p.add_result(Result.new(1, 1, 'W', :opponent => 37, :score => 'W', :colour => 'W'))
|
200
|
+
@p.add_result(Result.new(2, 1, 'W', :opponent => 13, :score => 'W', :colour => 'B'))
|
201
|
+
@p.add_result(Result.new(3, 1, 'W', :opponent => 7, :score => 'D', :colour => 'W'))
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should find results by round number" do
|
205
|
+
@p.find_result(1).opponent.should == 37
|
206
|
+
@p.find_result(2).opponent.should == 13
|
207
|
+
@p.find_result(3).opponent.should == 7
|
208
|
+
@p.find_result(4).should be_nil
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context "merge" do
|
213
|
+
before(:each) do
|
214
|
+
@p1 = Player.new('Mark', 'Orr', 1, :id => 1350)
|
215
|
+
@p2 = Player.new('Mark', 'Orr', 2, :rating => 2100, :title => 'IM', :fed => 'IRL')
|
216
|
+
@p3 = Player.new('Gearoidin', 'Ui Laighleis', 3, :rating => 1600, :title => 'WIM', :fed => 'IRL')
|
217
|
+
end
|
218
|
+
|
219
|
+
it "takes on the ID, rating, title and fed of the other player but not the player number" do
|
220
|
+
@p1.merge(@p2)
|
221
|
+
@p1.num.should == 1
|
222
|
+
@p1.id.should == 1350
|
223
|
+
@p1.rating.should == 2100
|
224
|
+
@p1.title.should == 'IM'
|
225
|
+
@p1.fed.should == 'IRL'
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should have a kind of symmetry" do
|
229
|
+
p1 = @p1.dup
|
230
|
+
p2 = @p2.dup
|
231
|
+
p1.merge(p2).eql?(@p2.merge(@p1))
|
232
|
+
end
|
233
|
+
|
234
|
+
it "cannot be done with unequal objects" do
|
235
|
+
lambda { @p1.merge(@p3) }.should raise_error(/cannot merge.*not equal/)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "renumber the player numbers" do
|
240
|
+
before(:each) do
|
241
|
+
@p = Player.new('Mark', 'Orr', 10)
|
242
|
+
@p.add_result(Result.new(1, 10, 'W', :opponent => 20))
|
243
|
+
@p.add_result(Result.new(2, 10, 'W', :opponent => 30))
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should renumber successfully if the map has the relevant player numbers" do
|
247
|
+
map = { 10 => 1, 20 => 2, 30 => 3 }
|
248
|
+
@p.renumber(map).num.should == 1
|
249
|
+
@p.results.map{ |r| r.opponent }.sort.join('').should == '23'
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should raise exception if a player number is not in the map" do
|
253
|
+
lambda { @p.renumber({ 100 => 1, 20 => 2, 30 => 3 }) }.should raise_error(/player.*10.*not found/)
|
254
|
+
lambda { @p.renumber({ 10 => 1, 200 => 2, 30 => 3 }) }.should raise_error(/opponent.*20.*not found/)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context "loose equality" do
|
259
|
+
before(:all) do
|
260
|
+
@mark1 = Player.new('Mark', 'Orr', 1)
|
261
|
+
@mark2 = Player.new('Mark', 'Orr', 2, :fed => 'IRL')
|
262
|
+
@mark3 = Player.new('Mark', 'Orr', 3, :fed => 'USA')
|
263
|
+
@mark4 = Player.new('Mark', 'Sax', 4, :def => 'HUN')
|
264
|
+
@john1 = Player.new('John', 'Orr', 5, :fed => 'IRL')
|
265
|
+
end
|
266
|
+
|
267
|
+
it "any player is equal to itself" do
|
268
|
+
(@mark1 == @mark1).should be_true
|
269
|
+
end
|
270
|
+
|
271
|
+
it "two players are equal if their names are the same and their federations do not conflict" do
|
272
|
+
(@mark1 == @mark2).should be_true
|
273
|
+
end
|
274
|
+
|
275
|
+
it "two players cannot be equal if they have different names" do
|
276
|
+
(@mark1 == @mark4).should be_false
|
277
|
+
(@mark1 == @john1).should be_false
|
278
|
+
end
|
279
|
+
|
280
|
+
it "two players cannot be equal if they have different federations" do
|
281
|
+
(@mark2 == @mark3).should be_false
|
282
|
+
(@mark1 == @mark3).should be_true
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
context "strict equality" do
|
287
|
+
before(:all) do
|
288
|
+
@mark1 = Player.new('Mark', 'Orr', 1)
|
289
|
+
@mark2 = Player.new('Mark', 'Orr', 2, :id => 1350, :rating => 2100, :title => 'IM')
|
290
|
+
@mark3 = Player.new('Mark', 'Orr', 3, :id => 1530)
|
291
|
+
@mark4 = Player.new('Mark', 'Orr', 4, :rating => 2200)
|
292
|
+
@mark5 = Player.new('Mark', 'Orr', 5, :title => 'GM')
|
293
|
+
end
|
294
|
+
|
295
|
+
it "any player is equal to itself" do
|
296
|
+
@mark1.eql?(@mark1).should be_true
|
297
|
+
@mark1.eql?(@mark1).should be_true
|
298
|
+
end
|
299
|
+
|
300
|
+
it "two players are equal as long as their ID, rating and title do not conflict" do
|
301
|
+
@mark1.eql?(@mark2).should be_true
|
302
|
+
@mark3.eql?(@mark4).should be_true
|
303
|
+
@mark4.eql?(@mark5).should be_true
|
304
|
+
end
|
305
|
+
|
306
|
+
it "two players are not equal if their ID, rating or title conflict" do
|
307
|
+
@mark2.eql?(@mark3).should be_false
|
308
|
+
@mark2.eql?(@mark4).should be_false
|
309
|
+
@mark2.eql?(@mark5).should be_false
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
data/spec/result_spec.rb
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
4
|
+
|
5
|
+
module ICU
|
6
|
+
describe Result do
|
7
|
+
context "a typical result" do
|
8
|
+
it "should have a round, player number and score plus optional opponent number, colour and rateable flag" do
|
9
|
+
lambda { Result.new(3, 5, 'W', :opponent => 11, :colour => 'W') }.should_not raise_error
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "round number" do
|
14
|
+
it "should be a positive integer" do
|
15
|
+
lambda { Result.new(-2, 2, 0) }.should raise_error(/invalid positive integer/)
|
16
|
+
lambda { Result.new(0, 2, 0) }.should raise_error(/invalid positive integer/)
|
17
|
+
Result.new(1, 2, 0).round.should == 1
|
18
|
+
Result.new(' 3 ', 2, 0).round.should == 3
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "player number" do
|
23
|
+
it "should be an integer" do
|
24
|
+
lambda { Result.new(1, ' ', 0) }.should raise_error(/invalid integer/)
|
25
|
+
Result.new(1, 2, 0).player.should == 2
|
26
|
+
Result.new(1, ' 0 ', 0).player.should == 0
|
27
|
+
Result.new(1, -5, 0).player.should == -5
|
28
|
+
Result.new(1, " 9 ", 0).player.should == 9
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "score" do
|
33
|
+
[1, 1.0, 'W', 'w', '+'].each do |score|
|
34
|
+
it "should be 'W' for #{score}, #{score.class}" do
|
35
|
+
Result.new(1, 2, score).score.should == 'W'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
[0, 0.0, 'L', 'l', '-'].each do |score|
|
39
|
+
it "should be 'L' for #{score}, #{score.class}" do
|
40
|
+
Result.new(1, 2, score).score.should == 'L'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
['½', 0.5, 'D', 'd', '='].each do |score|
|
44
|
+
it "should be 'L' for #{score}, #{score.class}" do
|
45
|
+
Result.new(1, 2, score).score.should == 'D'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
['', ' ', 'x', 2, -1.0, nil].each do |score|
|
49
|
+
it "should raise error for invalid score (#{score})" do
|
50
|
+
lambda { Result.new(1, 2, score) }.should raise_error(/invalid score/)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
it "should be expressable as a number" do
|
54
|
+
Result.new(1, 2, 'W').points.should == 1.0
|
55
|
+
Result.new(1, 2, 'L').points.should == 0.0
|
56
|
+
Result.new(1, 2, 'D').points.should == 0.5
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "colour" do
|
61
|
+
it "should be 'W' or 'B' or nil (unknown)" do
|
62
|
+
Result.new(4, 1, 0).colour.should be_nil
|
63
|
+
Result.new(4, 1, 0, :colour => 'W').colour.should == 'W'
|
64
|
+
Result.new(4, 1, 0, :colour => 'white').colour.should == 'W'
|
65
|
+
Result.new(4, 1, 0, :colour => ' b ').colour.should == 'B'
|
66
|
+
Result.new(4, 1, 0, :colour => ' BLACK ').colour.should == 'B'
|
67
|
+
lambda { Result.new(4, 1, 0, :colour => 'red') }.should raise_error(/invalid colour/)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "opponent number" do
|
72
|
+
it "should be nil (the default) or an integer" do
|
73
|
+
Result.new(4, 1, 0).opponent.should be_nil
|
74
|
+
Result.new(4, 1, 0, :opponent => nil).opponent.should be_nil
|
75
|
+
Result.new(4, 1, 0, :opponent => ' ').opponent.should be_nil
|
76
|
+
Result.new(4, 1, 0, :opponent => 0).opponent.should == 0
|
77
|
+
Result.new(4, 1, 0, :opponent => 2).opponent.should == 2
|
78
|
+
Result.new(4, 1, 0, :opponent => -6).opponent.should == -6
|
79
|
+
Result.new(4, 1, 0, :opponent => ' 10 ').opponent.should == 10
|
80
|
+
lambda { Result.new(4, 1, 0, :opponent => 'X') }.should raise_error(/invalid opponent number/)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should be different to player number" do
|
84
|
+
lambda { Result.new(4, 1, 0, :opponent => 1) }.should raise_error(/opponent .* player .* different/)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "rateable flag" do
|
89
|
+
it "should default to false if there is no opponent" do
|
90
|
+
Result.new(4, 1, 0).rateable.should be_false
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should default to true if there is an opponent" do
|
94
|
+
Result.new(4, 1, 0, :opponent => 10).rateable.should be_true
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should change if an opponent is added" do
|
98
|
+
r = Result.new(4, 1, 0)
|
99
|
+
r.opponent = 5;
|
100
|
+
r.rateable.should be_true
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should be settable to false from the constructor" do
|
104
|
+
Result.new(4, 1, 0, :opponent => 10, :rateable => false).rateable.should be_false
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should be settable to false using the accessor" do
|
108
|
+
r = Result.new(4, 1, 0, :opponent => 10)
|
109
|
+
r.rateable= false
|
110
|
+
r.rateable.should be_false
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should not be settable to true if there is no opponent" do
|
114
|
+
r = Result.new(4, 1, 0)
|
115
|
+
r.rateable= true
|
116
|
+
r.rateable.should be_false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "reversed result" do
|
121
|
+
it "should be nil if there is no opponent" do
|
122
|
+
Result.new(4, 1, 0).reverse.should be_nil
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should have player and opponent swapped" do
|
126
|
+
r = Result.new(4, 1, 0, :opponent => 2).reverse
|
127
|
+
r.player.should == 2
|
128
|
+
r.opponent.should == 1
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should have reversed result" do
|
132
|
+
Result.new(4, 1, 0, :opponent => 2).reverse.score.should == 'W'
|
133
|
+
Result.new(4, 1, 1, :opponent => 2).reverse.score.should == 'L'
|
134
|
+
Result.new(4, 1, '=', :opponent => 2).reverse.score.should == 'D'
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should preserve rateability" do
|
138
|
+
Result.new(4, 1, 0, :opponent => 2).reverse.rateable.should be_true
|
139
|
+
Result.new(4, 1, 0, :opponent => 2, :rateable => false).reverse.rateable.should be_false
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "renumber the player numbers in a result" do
|
144
|
+
before(:each) do
|
145
|
+
@r1 = Result.new(1, 4, 0)
|
146
|
+
@r2 = Result.new(2, 3, 1, :opponent => 4, :color => 'B')
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should renumber successfully if the map has the relevant player numbers" do
|
150
|
+
map = { 4 => 1, 3 => 2 }
|
151
|
+
@r1.renumber(map).player.should == 1
|
152
|
+
@r2.renumber(map).player.should == 2
|
153
|
+
@r1.opponent.should be_nil
|
154
|
+
@r2.opponent.should == 1
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should raise exception if a player number is not in the map" do
|
158
|
+
lambda { @r1.renumber({ 5 => 1, 3 => 2 }) }.should raise_error(/player.*4.*not found/)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "loose equality" do
|
163
|
+
before(:each) do
|
164
|
+
@r1 = Result.new(1, 1, 0, :opponent => 2, :colour => 'W')
|
165
|
+
@r2 = Result.new(1, 1, 0, :opponent => 2, :colour => 'W')
|
166
|
+
@r3 = Result.new(2, 1, 0, :opponent => 2, :colour => 'W')
|
167
|
+
@r4 = Result.new(1, 3, 0, :opponent => 2, :colour => 'W')
|
168
|
+
@r5 = Result.new(1, 1, 1, :opponent => 2, :colour => 'W')
|
169
|
+
@r6 = Result.new(1, 1, 0, :opponent => 3, :colour => 'W')
|
170
|
+
@r7 = Result.new(1, 1, 0, :opponent => 2, :colour => 'B')
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should be equal if the round, player numbers, result and colour all match" do
|
174
|
+
(@r1 == @r1).should be_true
|
175
|
+
(@r1 == @r2).should be_true
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should not be equal if the round, player numbers, result or colour do not match" do
|
179
|
+
(@r1 == @r3).should be_false
|
180
|
+
(@r1 == @r4).should be_false
|
181
|
+
(@r1 == @r5).should be_false
|
182
|
+
(@r1 == @r6).should be_false
|
183
|
+
(@r1 == @r7).should be_false
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "strict equality" do
|
188
|
+
before(:each) do
|
189
|
+
@r1 = Result.new(1, 1, 0, :opponent => 2, :colour => 'W')
|
190
|
+
@r2 = Result.new(1, 1, 0, :opponent => 2, :colour => 'W')
|
191
|
+
@r3 = Result.new(1, 1, 0, :opponent => 2, :colour => 'W', :rateable => false)
|
192
|
+
@r4 = Result.new(2, 1, 0, :opponent => 2, :colour => 'W')
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should only be equal if everything is the same" do
|
196
|
+
@r1.eql?(@r1).should be_true
|
197
|
+
@r1.eql?(@r2).should be_true
|
198
|
+
@r1.eql?(@r3).should be_false
|
199
|
+
@r1.eql?(@r4).should be_false
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|