sanichi-chess_icu 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,276 @@
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 player number/)
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 ID/)
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 == 'Ireland'
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('Pia', 'Cramling', 3, :title => ' wg ').title.should == 'WGM'
101
+ Player.new('Philip', 'Short', 4, :title => 'F ').title.should == 'FM'
102
+ Player.new('Gearoidin', 'Ui Laighleis', 5, :title => 'wc').title.should == 'WCM'
103
+ Player.new('Eamon', 'Keogh', 6, :title => 'nm').title.should == 'NM'
104
+ lambda { Player.new('Mark', 'Orr', 3, :title => 'Dr') }.should raise_error(/invalid chess title/)
105
+ end
106
+ end
107
+
108
+ context "rating" do
109
+ it "defaults to nil" do
110
+ Player.new('Mark', 'Orr', 3).rating.should be_nil
111
+ Player.new('Mark', 'Orr', 3, :rating => ' ').rating.should be_nil
112
+ end
113
+
114
+ it "should be a positive integer" do
115
+ Player.new('Gary', 'Kasparov', 1, :rating => 2800).rating.should == 2800
116
+ Player.new('Mark', 'Orr', 2, :rating => ' 2100 ').rating.should == 2100
117
+ lambda { Player.new('Mark', 'Orr', 3, :rating => -2100) }.should raise_error(/invalid rating/)
118
+ lambda { Player.new('Mark', 'Orr', 3, :rating => 'IM') }.should raise_error(/invalid rating/)
119
+ end
120
+ end
121
+
122
+ context "rank" do
123
+ it "defaults to nil" do
124
+ Player.new('Mark', 'Orr', 3).rank.should be_nil
125
+ end
126
+
127
+ it "should be a positive integer" do
128
+ Player.new('Mark', 'Orr', 3, :rank => 1).rank.should == 1
129
+ Player.new('Gary', 'Kasparov', 4, :rank => ' 29 ').rank.should == 29
130
+ lambda { Player.new('Mark', 'Orr', 3, :rank => 0) }.should raise_error(/invalid rank/)
131
+ lambda { Player.new('Mark', 'Orr', 3, :rank => ' -1 ') }.should raise_error(/invalid rank/)
132
+ end
133
+ end
134
+
135
+ context "date of birth" do
136
+ it "defaults to nil" do
137
+ Player.new('Mark', 'Orr', 3).dob.should be_nil
138
+ Player.new('Mark', 'Orr', 3, :dob => ' ').dob.should be_nil
139
+ end
140
+
141
+ it "should be a yyyy-mm-dd date" do
142
+ Player.new('Mark', 'Orr', 3, :dob => '1955-11-09').dob.should == '1955-11-09'
143
+ lambda { Player.new('Mark', 'Orr', 3, :dob => 'X') }.should raise_error(/invalid DOB/)
144
+ end
145
+ end
146
+
147
+ context "results and points" do
148
+ it "should initialise to an empty array" do
149
+ results = Player.new('Mark', 'Orr', 3).results
150
+ results.should be_instance_of Array
151
+ results.size.should == 0
152
+ end
153
+
154
+ it "can be added to" do
155
+ player = Player.new('Mark', 'Orr', 3)
156
+ player.add_result(Result.new(1, 3, 'W', :opponent => 1))
157
+ player.add_result(Result.new(2, 3, 'D', :opponent => 2))
158
+ player.add_result(Result.new(3, 3, 'L', :opponent => 4))
159
+ results = player.results
160
+ results.should be_instance_of Array
161
+ results.size.should == 3
162
+ player.points.should == 1.5
163
+ end
164
+
165
+ it "should not allow mismatched player numbers" do
166
+ player = Player.new('Mark', 'Orr', 3)
167
+ lambda { player.add_result(Result.new(1, 4, 'W', :opponent => 1)) }.should raise_error(/player number .* matched/)
168
+ end
169
+
170
+ it "should enforce unique round numbers" do
171
+ player = Player.new('Mark', 'Orr', 3)
172
+ player.add_result(Result.new(1, 3, 'W', :opponent => 1))
173
+ player.add_result(Result.new(2, 3, 'D', :opponent => 2))
174
+ lambda { player.add_result(Result.new(2, 3, 'L', :opponent => 4)) }.should raise_error(/round number .* unique/)
175
+ end
176
+ end
177
+
178
+ context "looking up results" do
179
+ before(:all) do
180
+ @p = Player.new('Mark', 'Orr', 1)
181
+ @p.add_result(Result.new(1, 1, 'W', :opponent => 37, :score => 'W', :colour => 'W'))
182
+ @p.add_result(Result.new(2, 1, 'W', :opponent => 13, :score => 'W', :colour => 'B'))
183
+ @p.add_result(Result.new(3, 1, 'W', :opponent => 7, :score => 'D', :colour => 'W'))
184
+ end
185
+
186
+ it "should find results by round number" do
187
+ @p.find_result(1).opponent.should == 37
188
+ @p.find_result(2).opponent.should == 13
189
+ @p.find_result(3).opponent.should == 7
190
+ @p.find_result(4).should be_nil
191
+ end
192
+ end
193
+
194
+ context "subsumption" do
195
+ before(:each) do
196
+ @p1 = Player.new('Mark', 'Orr', 1, :id => 1350)
197
+ @p2 = Player.new('Mark', 'Orr', 2, :rating => 2100, :title => 'IM', :fed => 'IRL')
198
+ @p3 = Player.new('Gearoidin', 'Ui Laighleis', 3, :rating => 1600, :title => 'WIM', :fed => 'IRL')
199
+ end
200
+
201
+ it "takes on the ID, rating, title and fed of the other player but not the player number" do
202
+ @p1.subsume(@p2)
203
+ @p1.num.should == 1
204
+ @p1.id.should == 1350
205
+ @p1.rating.should == 2100
206
+ @p1.title.should == 'IM'
207
+ @p1.fed.should == 'IRL'
208
+ end
209
+
210
+ it "should have a kind of symmetry" do
211
+ p1 = @p1.dup
212
+ p2 = @p2.dup
213
+ p1.subsume(p2).eql?(@p2.subsume(@p1))
214
+ end
215
+
216
+ it "cannot be done with unequal objects" do
217
+ lambda { @p1.subsume(@p3) }.should raise_error(/cannot merge.*not strictly equal/)
218
+ end
219
+ end
220
+
221
+ context "loose equality" do
222
+ before(:all) do
223
+ @mark1 = Player.new('Mark', 'Orr', 1)
224
+ @mark2 = Player.new('Mark', 'Orr', 2, :fed => 'IRL')
225
+ @mark3 = Player.new('Mark', 'Orr', 3, :fed => 'USA')
226
+ @mark4 = Player.new('Mark', 'Sax', 4, :def => 'HUN')
227
+ @john1 = Player.new('John', 'Orr', 5, :fed => 'IRL')
228
+ end
229
+
230
+ it "any player is equal to itself" do
231
+ (@mark1 == @mark1).should be_true
232
+ end
233
+
234
+ it "two players are equal if their names are the same and their federations do not conflict" do
235
+ (@mark1 == @mark2).should be_true
236
+ end
237
+
238
+ it "two players cannot be equal if they have different names" do
239
+ (@mark1 == @mark4).should be_false
240
+ (@mark1 == @john1).should be_false
241
+ end
242
+
243
+ it "two players cannot be equal if they have different federations" do
244
+ (@mark2 == @mark3).should be_false
245
+ (@mark1 == @mark3).should be_true
246
+ end
247
+ end
248
+
249
+ context "strict equality" do
250
+ before(:all) do
251
+ @mark1 = Player.new('Mark', 'Orr', 1)
252
+ @mark2 = Player.new('Mark', 'Orr', 2, :id => 1350, :rating => 2100, :title => 'IM')
253
+ @mark3 = Player.new('Mark', 'Orr', 3, :id => 1530)
254
+ @mark4 = Player.new('Mark', 'Orr', 4, :rating => 2200)
255
+ @mark5 = Player.new('Mark', 'Orr', 5, :title => 'GM')
256
+ end
257
+
258
+ it "any player is equal to itself" do
259
+ @mark1.eql?(@mark1).should be_true
260
+ @mark1.eql?(@mark1).should be_true
261
+ end
262
+
263
+ it "two players are equal as long as their ID, rating and title do not conflict" do
264
+ @mark1.eql?(@mark2).should be_true
265
+ @mark3.eql?(@mark4).should be_true
266
+ @mark4.eql?(@mark5).should be_true
267
+ end
268
+
269
+ it "two players are not equal if their ID, rating or title conflict" do
270
+ @mark2.eql?(@mark3).should be_false
271
+ @mark2.eql?(@mark4).should be_false
272
+ @mark2.eql?(@mark5).should be_false
273
+ end
274
+ end
275
+ end
276
+ end
@@ -0,0 +1,165 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ module ICU
4
+ describe Result do
5
+ context "a typical result" do
6
+ it "should have a round, player number and score plus optional opponent number, colour and rateable flag" do
7
+ lambda { Result.new(3, 5, 'W', :opponent => 11, :colour => 'W') }.should_not raise_error
8
+ end
9
+ end
10
+
11
+ context "round number" do
12
+ it "should be a positive integer" do
13
+ lambda { Result.new(-2, 2, 0) }.should raise_error(/invalid round number/)
14
+ lambda { Result.new(0, 2, 0) }.should raise_error(/invalid round number/)
15
+ Result.new(1, 2, 0).round.should == 1
16
+ Result.new(' 3 ', 2, 0).round.should == 3
17
+ end
18
+ end
19
+
20
+ context "player number" do
21
+ it "should be an integer" do
22
+ lambda { Result.new(1, ' ', 0) }.should raise_error(/invalid player number/)
23
+ Result.new(1, 2, 0).player.should == 2
24
+ Result.new(1, ' 0 ', 0).player.should == 0
25
+ Result.new(1, -5, 0).player.should == -5
26
+ Result.new(1, " 9 ", 0).player.should == 9
27
+ end
28
+ end
29
+
30
+ context "score" do
31
+ [1, 1.0, 'W', 'w', '+'].each do |score|
32
+ it "should be 'W' for #{score}, #{score.class}" do
33
+ Result.new(1, 2, score).score.should == 'W'
34
+ end
35
+ end
36
+ [0, 0.0, 'L', 'l', '-'].each do |score|
37
+ it "should be 'L' for #{score}, #{score.class}" do
38
+ Result.new(1, 2, score).score.should == 'L'
39
+ end
40
+ end
41
+ ['½', 0.5, 'D', 'd', '='].each do |score|
42
+ it "should be 'L' for #{score}, #{score.class}" do
43
+ Result.new(1, 2, score).score.should == 'D'
44
+ end
45
+ end
46
+ ['', ' ', 'x', 2, -1.0, nil].each do |score|
47
+ it "should raise error for invalid score (#{score})" do
48
+ lambda { Result.new(1, 2, score) }.should raise_error(/invalid score/)
49
+ end
50
+ end
51
+ it "should be expressable as a number" do
52
+ Result.new(1, 2, 'W').points.should == 1.0
53
+ Result.new(1, 2, 'L').points.should == 0.0
54
+ Result.new(1, 2, 'D').points.should == 0.5
55
+ end
56
+ end
57
+
58
+ context "colour" do
59
+ it "should be 'W' or 'B' or nil (unknown)" do
60
+ Result.new(4, 1, 0).colour.should be_nil
61
+ Result.new(4, 1, 0, :colour => 'W').colour.should == 'W'
62
+ Result.new(4, 1, 0, :colour => 'white').colour.should == 'W'
63
+ Result.new(4, 1, 0, :colour => ' b ').colour.should == 'B'
64
+ Result.new(4, 1, 0, :colour => ' BLACK ').colour.should == 'B'
65
+ lambda { Result.new(4, 1, 0, :colour => 'red') }.should raise_error(/invalid colour/)
66
+ end
67
+ end
68
+
69
+ context "opponent number" do
70
+ it "should be nil (the default) or an integer" do
71
+ Result.new(4, 1, 0).opponent.should be_nil
72
+ Result.new(4, 1, 0, :opponent => nil).opponent.should be_nil
73
+ Result.new(4, 1, 0, :opponent => ' ').opponent.should be_nil
74
+ Result.new(4, 1, 0, :opponent => 0).opponent.should == 0
75
+ Result.new(4, 1, 0, :opponent => 2).opponent.should == 2
76
+ Result.new(4, 1, 0, :opponent => -6).opponent.should == -6
77
+ Result.new(4, 1, 0, :opponent => ' 10 ').opponent.should == 10
78
+ lambda { Result.new(4, 1, 0, :opponent => 'X') }.should raise_error(/invalid opponent number/)
79
+ end
80
+
81
+ it "should be different to player number" do
82
+ lambda { Result.new(4, 1, 0, :opponent => 1) }.should raise_error(/opponent .* player .* different/)
83
+ end
84
+ end
85
+
86
+ context "rateable flag" do
87
+ it "should default to false if there is no opponent" do
88
+ Result.new(4, 1, 0).rateable.should be_false
89
+ end
90
+
91
+ it "should default to true if there is an opponent" do
92
+ Result.new(4, 1, 0, :opponent => 10).rateable.should be_true
93
+ end
94
+
95
+ it "should change if an opponent is added" do
96
+ r = Result.new(4, 1, 0)
97
+ r.opponent = 5;
98
+ r.rateable.should be_true
99
+ end
100
+
101
+ it "should be settable to false from the constructor" do
102
+ Result.new(4, 1, 0, :opponent => 10, :rateable => false).rateable.should be_false
103
+ end
104
+
105
+ it "should be settable to false using the accessor" do
106
+ r = Result.new(4, 1, 0, :opponent => 10)
107
+ r.rateable= false
108
+ r.rateable.should be_false
109
+ end
110
+
111
+ it "should not be settable to true if there is no opponent" do
112
+ r = Result.new(4, 1, 0)
113
+ r.rateable= true
114
+ r.rateable.should be_false
115
+ end
116
+ end
117
+
118
+ context "reversed result" do
119
+ it "should be nil if there is no opponent" do
120
+ Result.new(4, 1, 0).reverse.should be_nil
121
+ end
122
+
123
+ it "should have player and opponent swapped" do
124
+ r = Result.new(4, 1, 0, :opponent => 2).reverse
125
+ r.player.should == 2
126
+ r.opponent.should == 1
127
+ end
128
+
129
+ it "should have reversed result" do
130
+ Result.new(4, 1, 0, :opponent => 2).reverse.score.should == 'W'
131
+ Result.new(4, 1, 1, :opponent => 2).reverse.score.should == 'L'
132
+ Result.new(4, 1, '=', :opponent => 2).reverse.score.should == 'D'
133
+ end
134
+
135
+ it "should preserve rateability" do
136
+ Result.new(4, 1, 0, :opponent => 2).reverse.rateable.should be_true
137
+ Result.new(4, 1, 0, :opponent => 2, :rateable => false).reverse.rateable.should be_false
138
+ end
139
+ end
140
+
141
+ context "loose equality" do
142
+ before(:each) do
143
+ @r1 = Result.new(1, 1, 0, :opponent => 2, :colour => 'W')
144
+ @r2 = Result.new(1, 1, 0, :opponent => 2, :colour => 'W')
145
+ @r3 = Result.new(2, 1, 0, :opponent => 2, :colour => 'W')
146
+ @r4 = Result.new(1, 3, 0, :opponent => 2, :colour => 'W')
147
+ @r5 = Result.new(1, 1, 1, :opponent => 2, :colour => 'W')
148
+ @r6 = Result.new(1, 1, 0, :opponent => 3, :colour => 'W')
149
+ @r7 = Result.new(1, 1, 0, :opponent => 2, :colour => 'B')
150
+ end
151
+
152
+ it "should be equal if the round, player numbers, result and colour all match" do
153
+ (@r1 == @r2).should be_true
154
+ end
155
+
156
+ it "should not be equal if the round, player numbers, result or colour do not match" do
157
+ (@r1 == @r3).should be_false
158
+ (@r1 == @r4).should be_false
159
+ (@r1 == @r5).should be_false
160
+ (@r1 == @r6).should be_false
161
+ (@r1 == @r7).should be_false
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require File.dirname(__FILE__) + '/../lib/chess_icu'
@@ -0,0 +1,306 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ module ICU
4
+ class Tournament
5
+ describe ForeignCSV do
6
+ def check_player(num, first, last, results, rateable, points, other={})
7
+ p = @t.player(num)
8
+ p.first_name.should == first
9
+ p.last_name.should == last
10
+ p.id.should == other[:id]
11
+ p.rating.should == other[:rating]
12
+ p.fed.should == other[:fed]
13
+ p.title.should == other[:title]
14
+ p.results.size.should == results
15
+ p.results.select{|r| r.rateable}.size.should == rateable
16
+ p.points.should == points
17
+ end
18
+
19
+ context "a typical tournament" do
20
+ before(:all) do
21
+ @csv = <<CSV
22
+ Event,"Bangor Open, 2003"
23
+ Start,1st July 2003
24
+ Rounds,4
25
+ Website,http://www.icu.ie/tournaments/display.php?id=371
26
+
27
+ Player,3364,Ui Laighleis,Gearoidin
28
+ 1,0,B,Cronin,April,2005,,IRL
29
+ 2,=,W,Connolly,Suzanne,1950,,IRL
30
+ 3,=,-
31
+ 4,1,B,Powell,Linda,1850,,WLS
32
+ Total,2
33
+ CSV
34
+ @f = ForeignCSV.new(@csv)
35
+ @t = @f.tournament
36
+ end
37
+
38
+ it "should have a name" do
39
+ @t.name.should == 'Bangor Open, 2003'
40
+ end
41
+
42
+ it "should have a start date" do
43
+ @t.start.should == '2003-07-01'
44
+ end
45
+
46
+ it "should have a number of rounds" do
47
+ @t.rounds.should == 4
48
+ end
49
+
50
+ it "should have a website" do
51
+ @t.site.should == 'http://www.icu.ie/tournaments/display.php?id=371'
52
+ end
53
+
54
+ it "should have some players" do
55
+ @t.should have(4).players
56
+ end
57
+
58
+ it "should have correct player details" do
59
+ check_player(1, 'Gearoidin', 'Ui Laighleis', 4, 3, 2.0, :id => 3364)
60
+ check_player(2, 'April', 'Cronin', 1, 0, 1.0, :rating => 2005, :fed => 'IRL')
61
+ check_player(3, 'Suzanne', 'Connolly', 1, 0, 0.5, :rating => 1950, :fed => 'IRL')
62
+ check_player(4, 'Linda', 'Powell', 1, 0, 0.0, :rating => 1850, :fed => 'WLS')
63
+ end
64
+ end
65
+
66
+ context "a tournament with more than one player" do
67
+ before(:all) do
68
+ @csv = <<CSV
69
+ Event,"Edinburgh Masters, 2007"
70
+ Start,3rd January 2007
71
+ Rounds,2
72
+ Website,http://www.chesscenter.com/twic/twic.html
73
+
74
+ Player,3364,Ui Laighleis,Gearoidin
75
+ 1,=,W,Kasparov,Gary,2800,GM,RUS
76
+ 2,=,B,Cronin,April,2005,,IRL
77
+ Total,1.0
78
+
79
+ Player,1350,Orr,Mark
80
+ 1,=,W,Cronin,April,2005,,IRL
81
+ 2,1,B,Fischer,Bobby,2700,GM,USA
82
+ Total,1.5
83
+ CSV
84
+ @f = ForeignCSV.new(@csv)
85
+ @t = @f.tournament
86
+ end
87
+
88
+ it "should have the usual basic details" do
89
+ @t.name.should == 'Edinburgh Masters, 2007'
90
+ @t.start.should == '2007-01-03'
91
+ @t.rounds.should == 2
92
+ @t.site.should == 'http://www.chesscenter.com/twic/twic.html'
93
+ end
94
+
95
+ it "should have the correct number of players" do
96
+ @t.should have(5).players
97
+ end
98
+
99
+ it "should have correct player details" do
100
+ check_player(1, 'Gearoidin', 'Ui Laighleis', 2, 2, 1.0, :id => 3364)
101
+ check_player(4, 'Mark', 'Orr', 2, 2, 1.5, :id => 1350)
102
+ check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :rating => 2800, :fed => 'RUS', :title => 'GM')
103
+ check_player(3, 'April', 'Cronin', 2, 0, 1.0, :rating => 2005, :fed => 'IRL')
104
+ check_player(5, 'Bobby', 'Fischer', 1, 0, 0.0, :rating => 2700, :fed => 'USA', :title => 'GM')
105
+ end
106
+ end
107
+
108
+ context "a tournament where someone is both a player and an opponent" do
109
+ before(:all) do
110
+ @csv = <<CSV
111
+ Event,"Bratto Open, 2001"
112
+ Start,7th March 2001
113
+ Rounds,2
114
+ Website,http://www.federscacchi.it/
115
+
116
+ Player,3364,Ui Laighleis,Gearoidin
117
+ 1,=,W,Kasparov,Gary,2800,,RUS
118
+ 2,=,B,Orr,Mark,2100,IM,IRL
119
+ Total,1.0
120
+
121
+ Player,1350,Orr,Mark
122
+ 1,=,W,Cronin,April,2005,,IRL
123
+ 2,=,W,Ui Laighleis,Gearoidin,1800,,IRL
124
+ Total,1.0
125
+ CSV
126
+ @f = ForeignCSV.new(@csv)
127
+ @t = @f.tournament
128
+ end
129
+
130
+ it "should have the usual basic details" do
131
+ @t.name.should == 'Bratto Open, 2001'
132
+ @t.start.should == '2001-03-07'
133
+ @t.rounds.should == 2
134
+ @t.site.should == 'http://www.federscacchi.it/'
135
+ end
136
+
137
+ it "should have the correct number of players" do
138
+ @t.should have(4).players
139
+ end
140
+
141
+ it "should have correct player details" do
142
+ check_player(1, 'Gearoidin', 'Ui Laighleis', 2, 2, 1.0, :rating => 1800, :fed => 'IRL', :id => 3364)
143
+ check_player(3, 'Mark', 'Orr', 2, 2, 1.0, :rating => 2100, :fed => 'IRL', :id => 1350, :title => 'IM')
144
+ check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :rating => 2800, :fed => 'RUS')
145
+ check_player(4, 'April', 'Cronin', 1, 0, 0.5, :rating => 2005, :fed => 'IRL')
146
+ end
147
+ end
148
+
149
+ context "a file that contains spurious white space and other untidiness" do
150
+ before(:all) do
151
+ @csv = <<CSV
152
+
153
+ Event," Bratto Open, 2001 "
154
+ Start, 7th March 2001
155
+ Rounds, 2
156
+ Website, http://www.federscacchi.it/
157
+ Player ,3364 , ui Laighleis, gearoidin
158
+
159
+ 1, = ,W, kasparov, gary, 2800 , g , Rus
160
+
161
+ 2 ,=, b, Orr , Mark,2100, iM , irl
162
+ Total,1.0
163
+
164
+ CSV
165
+ @f = ForeignCSV.new(@csv)
166
+ @t = @f.tournament
167
+ end
168
+
169
+ it "should have the correct basic details" do
170
+ @t.name.should == 'Bratto Open, 2001'
171
+ @t.start.should == '2001-03-07'
172
+ @t.rounds.should == 2
173
+ @t.site.should == 'http://www.federscacchi.it/'
174
+ end
175
+
176
+ it "should have the correct number of players" do
177
+ @t.should have(3).players
178
+ end
179
+
180
+ it "should have correct player details" do
181
+ check_player(1, 'Gearoidin', 'Ui Laighleis', 2, 2, 1.0, :id => 3364)
182
+ check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :rating => 2800, :fed => 'RUS', :title => 'GM')
183
+ check_player(3, 'Mark', 'Orr', 1, 0, 0.5, :rating => 2100, :fed => 'IRL', :title => 'IM')
184
+ end
185
+ end
186
+
187
+ context "invalid files" do
188
+ it "a blank file is invalid" do
189
+ lambda { ForeignCSV.new(' ') }.should raise_error(/event/i)
190
+ end
191
+
192
+ it "the event should come first" do
193
+ csv = <<CSV
194
+ Start,7th March 2001
195
+ Event,"Bratto Open, 2001"
196
+ Rounds,2
197
+ Website,http://www.federscacchi.it/
198
+ CSV
199
+ lambda { ForeignCSV.new(csv) }.should raise_error(/line 1.*event/i)
200
+ end
201
+
202
+ it "the start should come second" do
203
+ csv = <<CSV
204
+ Event,"Bratto Open, 2001"
205
+ Rounds,2
206
+ Start,7th March 2001
207
+ Website,http://www.federscacchi.it/
208
+ CSV
209
+ lambda { ForeignCSV.new(csv) }.should raise_error(/line 2.*start/i)
210
+ end
211
+
212
+ it "the number of rounds should come third" do
213
+ csv = <<CSV
214
+ Event,"Bratto Open, 2001"
215
+ Start,7th March 2001
216
+ Website,http://www.federscacchi.it/
217
+ Rounds,2
218
+ CSV
219
+ lambda { ForeignCSV.new(csv) }.should raise_error(/line 3.*rounds/i)
220
+ end
221
+
222
+ it "there should be a web site" do
223
+ csv = <<CSV
224
+ Event,"Bratto Open, 2001"
225
+ Start,7th March 2001
226
+ Rounds,2
227
+
228
+ CSV
229
+ lambda { ForeignCSV.new(csv) }.should raise_error(/line 4.*site/i)
230
+ end
231
+
232
+ it "should have at least one player" do
233
+ csv = <<CSV
234
+ Event,"Bratto Open, 2001"
235
+ Start,7th March 2001
236
+ Rounds,2
237
+ Website,http://www.federscacchi.it/
238
+ CSV
239
+ lambda { ForeignCSV.new(csv) }.should raise_error(/line 4.*no players/i)
240
+ end
241
+
242
+ it "the player needs to have a valid ID number" do
243
+ csv = <<CSV
244
+ Event,"Bratto Open, 2001"
245
+ Start,7th March 2001
246
+ Rounds,2
247
+ Website,http://www.federscacchi.it/
248
+
249
+ Player,0,Ui Laighleis,Gearoidin
250
+ CSV
251
+ lambda { ForeignCSV.new(csv) }.should raise_error(/line 6.*number/i)
252
+ end
253
+
254
+ it "should have the right number of results for each player" do
255
+ csv = <<CSV
256
+ Event,"Bratto Open, 2001"
257
+ Start,7th March 2001
258
+ Rounds,2
259
+ Website,http://www.federscacchi.it/
260
+
261
+ Player,3364,Ui Laighleis,Gearoidin
262
+ 1,=,W,Kasparov,Gary,2800,GM,RUS
263
+ Total,0.5
264
+ CSV
265
+ lambda { ForeignCSV.new(csv) }.should raise_error(/line 8.*round/i)
266
+ end
267
+
268
+ it "should have correct totals" do
269
+ csv = <<CSV
270
+ Event,"Bratto Open, 2001"
271
+ Start,7th March 2001
272
+ Rounds,2
273
+ Website,http://www.federscacchi.it/
274
+
275
+ Player,3364,Ui Laighleis,Gearoidin
276
+ 1,=,W,Kasparov,Gary,2800,GM,RUS
277
+ 2,=,B,Orr,Mark,2100,IM,IRL
278
+ Total,1.5
279
+ CSV
280
+ lambda { ForeignCSV.new(csv) }.should raise_error(/line 9.*total/i)
281
+ end
282
+
283
+
284
+ it "players who match by name and federation should match in all other details" do
285
+ csv = <<CSV
286
+ Event,"Bratto Open, 2001"
287
+ Start,7th March 2001
288
+ Rounds,2
289
+ Website,http://www.federscacchi.it/
290
+
291
+ Player,3364,Ui Laighleis,Gearoidin
292
+ 1,=,W,Kasparov,Gary,2800,GM,RUS
293
+ 2,=,B,Orr,Mark,2100,IM,IRL
294
+ Total,1.0
295
+
296
+ Player,1350,Orr,Mark
297
+ 1,=,W,Fischer,Bobby,2700,,USA
298
+ 2,=,B,Kasparov,Gary,2850,GM,RUS
299
+ Total,1.0
300
+ CSV
301
+ lambda { ForeignCSV.new(csv) }.should raise_error(/line 13.*same name.*conflicting/i)
302
+ end
303
+ end
304
+ end
305
+ end
306
+ end