sanichi-chess_icu 0.1.0 → 0.2.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/README.rdoc +43 -3
- data/Rakefile +11 -5
- data/VERSION.yml +2 -2
- data/lib/tournament_fcsv.rb +18 -9
- data/spec/tournament_fcsv_spec.rb +49 -18
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -1,11 +1,51 @@
|
|
1
|
-
|
1
|
+
= ChessIcu
|
2
2
|
|
3
3
|
For parsing files of chess tournament data into ruby classes.
|
4
4
|
|
5
|
+
|
5
6
|
== Install
|
6
7
|
|
7
8
|
sudo gem install sanichi-chess_icu --source http://gems.github.com
|
8
|
-
|
9
|
+
|
10
|
+
|
9
11
|
== Usage
|
10
12
|
|
11
|
-
|
13
|
+
A tournament (ICU::Tournament) has two or more players (ICU::Player), and each player has one or more results (ICU::Result).
|
14
|
+
|
15
|
+
Tournament objects are created by parsing files of various formats. An instance of a class taylored for the type of data
|
16
|
+
in the file is first created (see below), and then it's parse or parse! method is called with the file's contents as argument.
|
17
|
+
|
18
|
+
data = open('tournament.csv') { |f| f.read }
|
19
|
+
tournament = parser.parse(data)
|
20
|
+
|
21
|
+
On success, the parse method returns an object of type ICU::Tournament. On error, it returns nil and an error message
|
22
|
+
can be retrieved from the parser instance:
|
23
|
+
|
24
|
+
parser.error # => error message or nil on success
|
25
|
+
|
26
|
+
Alternatively, if an exception is preferred on error, the parse! method can be used:
|
27
|
+
|
28
|
+
tournament = parser.parse!(data)
|
29
|
+
|
30
|
+
The file formats supported in the current version are:
|
31
|
+
|
32
|
+
* Foreign CSV
|
33
|
+
|
34
|
+
|
35
|
+
=== Foreign CSV
|
36
|
+
|
37
|
+
This is a format specific to the ICU[http://icu.ie] ({specification}[http://www.icu.ie/articles/display.php?id=172])
|
38
|
+
and is used by players to submit their individual results in foreign tournaments for domestic rating.
|
39
|
+
It's parsed by instances of ICU::Tournament::ForeignCSV.
|
40
|
+
|
41
|
+
parser = ICU::Tournament::ForeignCSV.new
|
42
|
+
|
43
|
+
|
44
|
+
== TODO
|
45
|
+
|
46
|
+
Future versions of this software will be able to parse more common formats such as SwissPerfect and FIDE's Krause format.
|
47
|
+
|
48
|
+
|
49
|
+
== Author
|
50
|
+
|
51
|
+
Mark Orr, rating officer for the Irish Chess Union (ICU[http://icu.ie]).
|
data/Rakefile
CHANGED
@@ -26,7 +26,13 @@ Spec::Rake::SpecTask.new(:spec) do |spec|
|
|
26
26
|
spec.spec_opts = ['--colour --format nested --loadby mtime --reverse']
|
27
27
|
end
|
28
28
|
|
29
|
-
Rake::
|
29
|
+
Spec::Rake::SpecTask.new(:fcsv) do |spec|
|
30
|
+
spec.libs << 'lib' << 'spec'
|
31
|
+
spec.spec_files = FileList['spec/tournament_fcsv_spec.rb']
|
32
|
+
spec.spec_opts = ['--colour --format nested']
|
33
|
+
end
|
34
|
+
|
35
|
+
Rake::RDocTask.new(:doc) do |doc|
|
30
36
|
if File.exist?('VERSION.yml')
|
31
37
|
config = YAML.load(File.read('VERSION.yml'))
|
32
38
|
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
@@ -34,8 +40,8 @@ Rake::RDocTask.new do |doc|
|
|
34
40
|
version = ""
|
35
41
|
end
|
36
42
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
43
|
+
doc.rdoc_dir = 'doc'
|
44
|
+
doc.title = "ChessIcu #{version}"
|
45
|
+
doc.rdoc_files.include('README*')
|
46
|
+
doc.rdoc_files.include('lib/**/*.rb')
|
41
47
|
end
|
data/VERSION.yml
CHANGED
data/lib/tournament_fcsv.rb
CHANGED
@@ -3,18 +3,23 @@ require 'fastercsv'
|
|
3
3
|
module ICU
|
4
4
|
class Tournament
|
5
5
|
class ForeignCSV
|
6
|
-
attr_reader :
|
7
|
-
|
8
|
-
# Constructor.
|
9
|
-
def initialize(csv)
|
10
|
-
@state, @line, @round, @sum = 0, 0, nil, nil
|
11
|
-
parse(csv)
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
6
|
+
attr_reader :error
|
15
7
|
|
8
|
+
# Parse CSV data returning a Tournament on success or a nil on failure (and a message retrievable via the error method).
|
16
9
|
def parse(csv)
|
10
|
+
begin
|
11
|
+
parse!(csv)
|
12
|
+
rescue => ex
|
13
|
+
@error = ex.message
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Parse CSV data returning a Tournament on success or raising an exception on error.
|
19
|
+
def parse!(csv)
|
20
|
+
@state, @line, @round, @sum, @error = 0, 0, nil, nil, nil
|
17
21
|
@tournament = Tournament.new('Dummy', '2000-01-01')
|
22
|
+
|
18
23
|
FasterCSV.parse(csv, :row_sep => :auto) do |r|
|
19
24
|
@line += 1 # increment line number
|
20
25
|
next if r.size == 0 # skip empty lines
|
@@ -51,7 +56,11 @@ module ICU
|
|
51
56
|
raise "line #{@line}: premature termination - expected #{exp}"
|
52
57
|
end
|
53
58
|
raise "line #{@line}: no players found in file" if @tournament.players.size == 0
|
59
|
+
|
60
|
+
@tournament
|
54
61
|
end
|
62
|
+
|
63
|
+
private
|
55
64
|
|
56
65
|
def event
|
57
66
|
abort "the 'Event' keyword", 0 unless @r[0].match(/^(Event|Tournament)$/i)
|
@@ -31,8 +31,8 @@ Player,3364,Ui Laighleis,Gearoidin
|
|
31
31
|
4,1,B,Powell,Linda,1850,,WLS
|
32
32
|
Total,2
|
33
33
|
CSV
|
34
|
-
@f = ForeignCSV.new
|
35
|
-
@t = @f.
|
34
|
+
@f = ForeignCSV.new
|
35
|
+
@t = @f.parse!(@csv)
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should have a name" do
|
@@ -81,8 +81,8 @@ Player,1350,Orr,Mark
|
|
81
81
|
2,1,B,Fischer,Bobby,2700,GM,USA
|
82
82
|
Total,1.5
|
83
83
|
CSV
|
84
|
-
@f = ForeignCSV.new
|
85
|
-
@t = @f.
|
84
|
+
@f = ForeignCSV.new
|
85
|
+
@t = @f.parse!(@csv)
|
86
86
|
end
|
87
87
|
|
88
88
|
it "should have the usual basic details" do
|
@@ -123,8 +123,8 @@ Player,1350,Orr,Mark
|
|
123
123
|
2,=,W,Ui Laighleis,Gearoidin,1800,,IRL
|
124
124
|
Total,1.0
|
125
125
|
CSV
|
126
|
-
@f = ForeignCSV.new
|
127
|
-
@t = @f.
|
126
|
+
@f = ForeignCSV.new
|
127
|
+
@t = @f.parse!(@csv)
|
128
128
|
end
|
129
129
|
|
130
130
|
it "should have the usual basic details" do
|
@@ -162,8 +162,8 @@ Player ,3364 , ui Laighleis, gearoidin
|
|
162
162
|
Total,1.0
|
163
163
|
|
164
164
|
CSV
|
165
|
-
@f = ForeignCSV.new
|
166
|
-
@t = @f.
|
165
|
+
@f = ForeignCSV.new
|
166
|
+
@t = @f.parse!(@csv)
|
167
167
|
end
|
168
168
|
|
169
169
|
it "should have the correct basic details" do
|
@@ -184,9 +184,40 @@ CSV
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
+
context "#parse" do
|
188
|
+
before(:each) do
|
189
|
+
@f = ForeignCSV.new
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should behave just like #parse! on success" do
|
193
|
+
csv = <<CSV
|
194
|
+
Event,"Bratto Open, 2001"
|
195
|
+
Start,7th March 2001
|
196
|
+
Rounds,2
|
197
|
+
Website,http://www.federscacchi.it/
|
198
|
+
|
199
|
+
Player,3364,Ui Laighleis,Gearoidin
|
200
|
+
1,=,W,Kasparov,Gary,2800,GM,RUS
|
201
|
+
2,=,B,Orr,Mark,2100,IM,IRL
|
202
|
+
Total,1.0
|
203
|
+
CSV
|
204
|
+
@f.parse(csv).should be_an_instance_of(ICU::Tournament)
|
205
|
+
@f.error.should be_nil
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should not throw an exception but return nil on error" do
|
209
|
+
@f.parse(' ').should be_nil
|
210
|
+
@f.error.should match(/event/)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
187
214
|
context "invalid files" do
|
215
|
+
before(:each) do
|
216
|
+
@f = ForeignCSV.new
|
217
|
+
end
|
218
|
+
|
188
219
|
it "a blank file is invalid" do
|
189
|
-
lambda {
|
220
|
+
lambda { @f.parse!(' ') }.should raise_error(/event/i)
|
190
221
|
end
|
191
222
|
|
192
223
|
it "the event should come first" do
|
@@ -196,7 +227,7 @@ Event,"Bratto Open, 2001"
|
|
196
227
|
Rounds,2
|
197
228
|
Website,http://www.federscacchi.it/
|
198
229
|
CSV
|
199
|
-
lambda {
|
230
|
+
lambda { @f.parse!(csv) }.should raise_error(/line 1.*event/i)
|
200
231
|
end
|
201
232
|
|
202
233
|
it "the start should come second" do
|
@@ -206,7 +237,7 @@ Rounds,2
|
|
206
237
|
Start,7th March 2001
|
207
238
|
Website,http://www.federscacchi.it/
|
208
239
|
CSV
|
209
|
-
lambda {
|
240
|
+
lambda { @f.parse!(csv) }.should raise_error(/line 2.*start/i)
|
210
241
|
end
|
211
242
|
|
212
243
|
it "the number of rounds should come third" do
|
@@ -216,7 +247,7 @@ Start,7th March 2001
|
|
216
247
|
Website,http://www.federscacchi.it/
|
217
248
|
Rounds,2
|
218
249
|
CSV
|
219
|
-
lambda {
|
250
|
+
lambda { @f.parse!(csv) }.should raise_error(/line 3.*rounds/i)
|
220
251
|
end
|
221
252
|
|
222
253
|
it "there should be a web site" do
|
@@ -226,7 +257,7 @@ Start,7th March 2001
|
|
226
257
|
Rounds,2
|
227
258
|
|
228
259
|
CSV
|
229
|
-
lambda {
|
260
|
+
lambda { @f.parse!(csv) }.should raise_error(/line 4.*site/i)
|
230
261
|
end
|
231
262
|
|
232
263
|
it "should have at least one player" do
|
@@ -236,7 +267,7 @@ Start,7th March 2001
|
|
236
267
|
Rounds,2
|
237
268
|
Website,http://www.federscacchi.it/
|
238
269
|
CSV
|
239
|
-
lambda {
|
270
|
+
lambda { @f.parse!(csv) }.should raise_error(/line 4.*no players/i)
|
240
271
|
end
|
241
272
|
|
242
273
|
it "the player needs to have a valid ID number" do
|
@@ -248,7 +279,7 @@ Website,http://www.federscacchi.it/
|
|
248
279
|
|
249
280
|
Player,0,Ui Laighleis,Gearoidin
|
250
281
|
CSV
|
251
|
-
lambda {
|
282
|
+
lambda { @f.parse!(csv) }.should raise_error(/line 6.*number/i)
|
252
283
|
end
|
253
284
|
|
254
285
|
it "should have the right number of results for each player" do
|
@@ -262,7 +293,7 @@ Player,3364,Ui Laighleis,Gearoidin
|
|
262
293
|
1,=,W,Kasparov,Gary,2800,GM,RUS
|
263
294
|
Total,0.5
|
264
295
|
CSV
|
265
|
-
lambda {
|
296
|
+
lambda { @f.parse!(csv) }.should raise_error(/line 8.*round/i)
|
266
297
|
end
|
267
298
|
|
268
299
|
it "should have correct totals" do
|
@@ -277,7 +308,7 @@ Player,3364,Ui Laighleis,Gearoidin
|
|
277
308
|
2,=,B,Orr,Mark,2100,IM,IRL
|
278
309
|
Total,1.5
|
279
310
|
CSV
|
280
|
-
lambda {
|
311
|
+
lambda { @f.parse!(csv) }.should raise_error(/line 9.*total/i)
|
281
312
|
end
|
282
313
|
|
283
314
|
|
@@ -298,7 +329,7 @@ Player,1350,Orr,Mark
|
|
298
329
|
2,=,B,Kasparov,Gary,2850,GM,RUS
|
299
330
|
Total,1.0
|
300
331
|
CSV
|
301
|
-
lambda {
|
332
|
+
lambda { @f.parse!(csv) }.should raise_error(/line 13.*same name.*conflicting/i)
|
302
333
|
end
|
303
334
|
end
|
304
335
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sanichi-chess_icu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Orr
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-04-
|
12
|
+
date: 2009-04-12 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|