sanichi-chess_icu 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.
@@ -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