icu_tournament 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -96,18 +96,22 @@ module ICU
96
96
  #
97
97
  # By default all available information is output for each player, however, this is customizable. The player number,
98
98
  # name, total points and results are always output but any of the remaining data (_gender_, _title_, _rating_ or _fide_rating_,
99
- # _fed_, _id_ or _fide_id_, _dob_ and _rank_) can be omitted, if desired, by specifying an array of columns to include.
100
- # To omitt all the optional data, supply an empty array:
99
+ # _fed_, _id_ or _fide_id_, _dob_ and _rank_) can be omitted, if desired, by specifying an array of columns to include
100
+ # or exclude. To omitt all the optional data, supply an empty array:
101
101
  #
102
- # krause = tournament.serialize('Krause', :columns => [])
102
+ # krause = tournament.serialize('Krause', :only => [])
103
103
  #
104
- # To omitt, for example, just federation and rating, include all columns but those two:
104
+ # To omitt just federation and rating but include all others:
105
105
  #
106
- # krause = tournament.serialize('Krause', :columns => [:gender, :title, :id, :dob, :rank])
106
+ # krause = tournament.serialize('Krause', :except => [:fed, :rating])
107
107
  #
108
- # To output FIDE IDs and ratings use the _fide_ option in conjunctions with the _id_ and _rating_ columns:
108
+ # To include only date of birth and title:
109
109
  #
110
- # krause = tournament.serialize('Krause', :columns => [:id, :rating], :fide => true)
110
+ # krause = tournament.serialize('Krause', :only => [:dob, :title])
111
+ #
112
+ # To output FIDE IDs and ratings use the _fide_ option in conjunctions with the _id_ and _rating_ options:
113
+ #
114
+ # krause = tournament.serialize('Krause', :only => [:gender, :id, :rating], :fide => true)
111
115
  #
112
116
  # == Parser Strictness
113
117
  #
@@ -194,6 +198,17 @@ module ICU
194
198
  class Krause
195
199
  attr_reader :error, :comments
196
200
 
201
+ OPTIONS =
202
+ [
203
+ [:gender, "Gender"],
204
+ [:title, "Title"],
205
+ [:rating, "Rating"],
206
+ [:fed, "Federation"],
207
+ [:id, "ID"],
208
+ [:dob, "DOB"],
209
+ [:rank, "Rank"],
210
+ ]
211
+
197
212
  # Parse Krause data returning a Tournament on success or raising an exception on error.
198
213
  def parse!(krs, arg={})
199
214
  @lineno = 0
@@ -500,16 +515,21 @@ module ICU
500
515
  class Player
501
516
  # Format a player's 001 record as it would appear in a Krause formatted file (including the final newline).
502
517
  def to_krause(rounds, arg)
503
- default = [:gender, :title, :rating, :fed, :id, :dob, :rank]
518
+ defaults = ICU::Tournament::Krause::OPTIONS.map(&:first)
504
519
 
505
520
  # Optional columns.
506
- optional = arg[:columns] if arg[:columns].instance_of?(Array)
507
- optional.map!(&:to_s).map!(&:to_sym) if optional
508
- optional = default.dup unless optional
521
+ case
522
+ when arg[:except].instance_of?(Array)
523
+ optional = (Set.new(defaults) - arg[:except].map!(&:to_s).map!(&:to_sym)).to_a
524
+ when arg[:only].instance_of?(Array)
525
+ optional = arg[:only].map!(&:to_s).map!(&:to_sym)
526
+ else
527
+ optional = defaults
528
+ end
509
529
  optional = optional.inject({}) { |m, a| m[a] = true; m }
510
530
 
511
531
  # Get the values to use.
512
- val = default.inject({}) do |m, a|
532
+ val = defaults.inject({}) do |m, a|
513
533
  if optional[a]
514
534
  if arg[:fide] && (a == :rating || a == :id)
515
535
  m[a] = send("fide_#{a}")
@@ -519,7 +539,7 @@ module ICU
519
539
  end
520
540
  m
521
541
  end
522
-
542
+
523
543
  # Output the mandatory and optional values.
524
544
  krause = '001'
525
545
  krause << sprintf(' %4d', @num)
@@ -532,7 +552,7 @@ module ICU
532
552
  krause << sprintf(' %10s', val[:dob])
533
553
  krause << sprintf(' %4.1f', points)
534
554
  krause << sprintf(' %4s', val[:rank])
535
-
555
+
536
556
  # And finally the round scores.
537
557
  (1..rounds).each do |r|
538
558
  result = find_result(r)
@@ -44,8 +44,11 @@ module ICU
44
44
  # spexport = tournament.serialize('SPExport')
45
45
  #
46
46
  # In either case the method returns a string representation of the tourament in SwissPerfect export
47
- # format with tab separators, space padding and (by default) the local player ID and total score
48
- # optional columns:
47
+ # format with tab separators, space padding and (by default) all the available information about the
48
+ # players. To customize what is displayed, use the _only_ option and supply an array of symbols or
49
+ # strings to specify which columns to include. For example:
50
+ #
51
+ # spexport = tournament.serialize('SPExport', :only => [:id, :points])
49
52
  #
50
53
  # No Name Loc Id Total 1 2 3
51
54
  #
@@ -54,20 +57,11 @@ module ICU
54
57
  # 3 Hulleman, Leon 6409 1 2:L 4:W 1:L
55
58
  # 4 Dunne, Thomas 10914 0 1:L 3:L 2:L
56
59
  #
57
- # To change which optional columns are output, use the _columns_ option with an array of the column attribute names.
58
60
  # The optional attribute names, together with their column header names in SwissPerfect, are as follows:
61
+ # _fed_ (Feder), _fide_id_ (Intl Id), _id_ (Loc Id), _fide_rating_ (Rtg), _rating_ (Loc), _title_ (Title),
62
+ # _points_: (Total). To omitt the optional columns completely, supply an empty array of column names:
59
63
  #
60
- # * _fed_: Feder
61
- # * _fide_id_: Intl Id
62
- # * _id_: Loc Id
63
- # * _fide_rating_: Rtg
64
- # * _rating_: Loc
65
- # * _title_: Title
66
- # * _points_: Total
67
- #
68
- # So, for example, to omitt the optional columns completely, supply an empty array of column names:
69
- #
70
- # tournament.serialize('SPExport', :columns => [])
64
+ # tournament.serialize('SPExport', :only => [])
71
65
  #
72
66
  # No Name 1 2 3
73
67
  #
@@ -78,19 +72,24 @@ module ICU
78
72
  #
79
73
  # Or supply whatever columns you want, for example:
80
74
  #
81
- # tournament.serialize('SPExport', :columns => [:fide_id, :fide_rating])
75
+ # tournament.serialize('SPExport', :only => %w{fide_id fide_rating})
76
+ #
77
+ # Or to omitt rather than include, use the logically opposite _except_ option:
78
+ #
79
+ # tournament.serialize('SPExport', :except => [:fide_id, :fide_rating])
82
80
  #
83
81
  # Note that the column order in the serialised string is the same as it is in the SwissPerfect application.
84
- # The order of column names in the _columns_ hash has no effect.
82
+ # The order of column names in the _only_ option has no effect.
85
83
  #
86
- # The default, when you leave out the _columns_ option is equivalent to:
84
+ # The default, when you leave out the _only_ or _except_ options, is equivalent to both of the following:
87
85
  #
88
- # tournament.serialize('SPExport', :columns => [:id, :points])
86
+ # tournament.serialize('SPExport', :only => %w{fed fide_id id fide_rating rating title points})
87
+ # tournament.serialize('SPExport', :except => [])
89
88
  #
90
89
  # The order of players in the serialized output is always by player number and as a side effect of serialization,
91
- # the player numbers will be adjusted to ensure they range from 1 to the total number of players maintaining the
92
- # original order. If you would prefer rank-order instead, then you must first renumber the players by rank (the
93
- # default renumbering method) before serializing. For example:
90
+ # the player numbers will be adjusted to ensure they range from 1 to the total number of players, maintaining the
91
+ # original order. If you would prefer rank-order instead, then you must first renumber the players by rank before
92
+ # serializing. For example:
94
93
  #
95
94
  # spexport = tournament.renumber(:rank).serialize('SPExport')
96
95
  #
@@ -98,7 +97,7 @@ module ICU
98
97
  #
99
98
  # spexport = tournament.renumber.serialize('SPExport')
100
99
  #
101
- # You may wish set the tie-break rules before ranking:
100
+ # You may wish to set the tie-break rules before ranking:
102
101
  #
103
102
  # tournament.tie_breaks = [:buchholz, :neustadtl]
104
103
  # spexport = tournament.rerank.renumber.serialize('SwissPerfect')
@@ -197,15 +196,22 @@ module ICU
197
196
  rounds = t.last_round
198
197
 
199
198
  # Optional columns.
200
- optional = arg[:columns] if arg[:columns].instance_of?(Array)
201
- optional = [:id, :points] unless optional
202
- optional.map!(&:to_s).map!(&:to_sym)
199
+ defaults = COLUMNS.map(&:first)
200
+ case
201
+ when arg[:except].instance_of?(Array)
202
+ optional = (Set.new(defaults) - arg[:except].map!(&:to_s).map!(&:to_sym)).to_a
203
+ when arg[:only].instance_of?(Array)
204
+ optional = arg[:only].map!(&:to_s).map!(&:to_sym)
205
+ else
206
+ optional = defaults
207
+ end
208
+ optional = optional.inject({}) { |m, a| m[a] = true; m }
203
209
 
204
210
  # Columns identifiers in SwissPerfect order.
205
211
  columns = Array.new
206
212
  columns.push(:num)
207
213
  columns.push(:name)
208
- COLUMNS.map(&:first).each { |x| columns.push(x) if optional.include?(x) && x != :num && x != :name }
214
+ defaults.each { |x| columns.push(x) if optional[x] && x != :num && x != :name }
209
215
 
210
216
  # Widths and formats for each column.
211
217
  width = Hash.new
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ICU
4
4
  class Tournament
5
- VERSION = "1.4.0"
5
+ VERSION = "1.4.1"
6
6
  end
7
7
  end
@@ -349,33 +349,41 @@ KRAUSE
349
349
  text.should match(/001 3 g Svidler,Peter RUS 1971-01-01 0.0 3/)
350
350
  end
351
351
 
352
- it "should omitt all optional data if columns option is an empty hash" do
353
- text = @t.serialize('Krause', :columns => [])
352
+ it "should omitt all optional data if the :only option is an empty hash" do
353
+ text = @t.serialize('Krause', :only => [])
354
354
  text.should match(/001 1 Ui Laighleis,Gearoidin 1.0 /)
355
355
  text.should match(/001 2 Orr,Mark 2.0 /)
356
356
  text.should match(/001 3 Svidler,Peter 0.0 /)
357
357
  end
358
358
 
359
359
  it "should should be able to include a subset of attributes, test 1" do
360
- text = @t.serialize('Krause', :columns => [:gender, "dob", :id, "rubbish"])
360
+ text = @t.serialize('Krause', :only => [:gender, "dob", :id, "rubbish"])
361
361
  text.should match(/001 1 w Ui Laighleis,Gearoidin 3364 1964-06-10 1.0 /)
362
362
  text.should match(/001 2 Orr,Mark 1350 1955-11-09 2.0 /)
363
363
  text.should match(/001 3 Svidler,Peter 16790 1971-01-01 0.0 /)
364
364
  end
365
365
 
366
366
  it "should should be able to include a subset of attributes, test 2" do
367
- text = @t.serialize('Krause', :columns => [:rank, "title", :fed, "rating"])
367
+ text = @t.serialize('Krause', :only => [:rank, "title", :fed, "rating"])
368
368
  text.should match(/001 1 Ui Laighleis,Gearoidin 1985 IRL 1.0 2/)
369
369
  text.should match(/001 2 m Orr,Mark 2258 IRL 2.0 1/)
370
370
  text.should match(/001 3 g Svidler,Peter 2663 RUS 0.0 3/)
371
371
  end
372
372
 
373
373
  it "should should be able to include all attributes" do
374
- text = @t.serialize('Krause', :columns => [:gender, :title, :rating, :fed, :id, :dob, :rank])
374
+ text = @t.serialize('Krause', :only => [:gender, :title, :rating, :fed, :id, :dob, :rank])
375
375
  text.should match(/001 1 w Ui Laighleis,Gearoidin 1985 IRL 3364 1964-06-10 1.0 2/)
376
376
  text.should match(/001 2 m Orr,Mark 2258 IRL 1350 1955-11-09 2.0 1/)
377
377
  text.should match(/001 3 g Svidler,Peter 2663 RUS 16790 1971-01-01 0.0 3/)
378
378
  end
379
+
380
+ it "the :only and :except options are logical opposites" do
381
+ @t.serialize('Krause', :only => [:gender, :title, :rating]).should == @t.serialize('Krause', :except => [:fed, :id, "dob", :rank])
382
+ @t.serialize('Krause', :only => [:gender]).should == @t.serialize('Krause', :except => [:fed, :id, :dob, :rank, :title, :rating])
383
+ @t.serialize('Krause', :only => [:gender, :title, "rating", :fed, :id, :dob]).should == @t.serialize('Krause', :except => [:rank])
384
+ @t.serialize('Krause', :only => [:gender, :title, :rating, :fed, "id", :dob, :rank]).should == @t.serialize('Krause', :except => [])
385
+ @t.serialize('Krause', :only => []).should == @t.serialize('Krause', :except => [:gender, :title, :rating, :fed, :id, :dob, :rank])
386
+ end
379
387
  end
380
388
 
381
389
  context "customised serialisation with FIDE IDs" do
@@ -406,29 +414,29 @@ KRAUSE
406
414
  text.should match(/001 3 g Svidler,Peter RUS 1971-01-01 0.0 3/)
407
415
  end
408
416
 
409
- it "should omitt all optional data if columns option is an empty hash" do
410
- text = @t.serialize('Krause', :columns => [])
417
+ it "should omitt all optional data if the :only option is an empty hash" do
418
+ text = @t.serialize('Krause', :only => [])
411
419
  text.should match(/001 1 Ui Laighleis,Gearoidin 1.0 /)
412
420
  text.should match(/001 2 Orr,Mark 2.0 /)
413
421
  text.should match(/001 3 Svidler,Peter 0.0 /)
414
422
  end
415
423
 
416
424
  it "should should be able to include a subset of attributes, test 1" do
417
- text = @t.serialize('Krause', :columns => [:gender, "dob", :id], :fide => true)
425
+ text = @t.serialize('Krause', :only => [:gender, "dob", :id], :fide => true)
418
426
  text.should match(/001 1 w Ui Laighleis,Gearoidin 2501171 1964-06-10 1.0 /)
419
427
  text.should match(/001 2 Orr,Mark 2500035 1955-11-09 2.0 /)
420
428
  text.should match(/001 3 Svidler,Peter 4102142 1971-01-01 0.0 /)
421
429
  end
422
430
 
423
431
  it "should should be able to include a subset of attributes, test 2" do
424
- text = @t.serialize('Krause', :columns => [:rank, "title", :fed, "rating", :rubbish], :fide => true)
432
+ text = @t.serialize('Krause', :only => [:rank, "title", :fed, "rating", :rubbish], :fide => true)
425
433
  text.should match(/001 1 Ui Laighleis,Gearoidin 1985 IRL 1.0 2/)
426
434
  text.should match(/001 2 m Orr,Mark 2258 IRL 2.0 1/)
427
435
  text.should match(/001 3 g Svidler,Peter 2663 RUS 0.0 3/)
428
436
  end
429
437
 
430
438
  it "should should be able to include all attributes" do
431
- text = @t.serialize('Krause', :columns => [:gender, :title, :rating, :fed, :id, :dob, :rank], :fide => true)
439
+ text = @t.serialize('Krause', :only => [:gender, :title, :rating, :fed, :id, :dob, :rank], :fide => true)
432
440
  text.should match(/001 1 w Ui Laighleis,Gearoidin 1985 IRL 2501171 1964-06-10 1.0 2/)
433
441
  text.should match(/001 2 m Orr,Mark 2258 IRL 2500035 1955-11-09 2.0 1/)
434
442
  text.should match(/001 3 g Svidler,Peter 2663 RUS 4102142 1971-01-01 0.0 3/)
@@ -58,7 +58,7 @@ module ICU
58
58
  end
59
59
 
60
60
  it "should serialize to the text export format" do
61
- @t.serialize('SPExport').should == @s
61
+ @t.serialize('SPExport', :only => [:id, :points]).should == @s
62
62
  end
63
63
  end
64
64
 
@@ -90,7 +90,7 @@ module ICU
90
90
  end
91
91
 
92
92
  it "should serialize to the text export format" do
93
- @t.rerank.renumber.serialize('SPExport').should == @s
93
+ @t.rerank.renumber.serialize('SPExport', :only => [:id, :points]).should == @s
94
94
  end
95
95
  end
96
96
 
@@ -142,28 +142,37 @@ EXPORT
142
142
  @r.player(3).spx_signature.should == "Orr, Mark|1350|0.5|123|DLL|---|TTF"
143
143
  end
144
144
 
145
- it "should have default columns" do
146
- @x.should match(/^No\s*Name\s*Loc Id\s*Total\s*1\s*2\s*3\s*/)
145
+ it "should show all columns by default" do
146
+ @x.should match(/^No\s*Name\s*Feder\s*Intl Id\s*Loc Id\s*Rtg\s*Loc\s*Title\s*Total\s*1\s*2\s*3\s*/)
147
147
  @x.should match(/1\s*Fischer,\s*Bobby\s*1\.5\s*3:D\s*0?:L?\s*2:W\s*/)
148
148
  end
149
149
 
150
150
  it "can have custom columns" do
151
- @x = @t.serialize('SPExport', :columns => [])
151
+ @x = @t.serialize('SPExport', :only => [])
152
152
  @x.should match(/^No\s*Name\s*1\s*2\s*3\s*/)
153
- @x = @t.serialize('SPExport', :columns => [:points])
153
+ @x = @t.serialize('SPExport', :only => [:points])
154
154
  @x.should match(/^No\s*Name\s*Total\s*1\s*2\s*3\s*/)
155
- @x = @t.serialize('SPExport', :columns => [:points, :id])
155
+ @x = @t.serialize('SPExport', :only => [:points, :id])
156
156
  @x.should match(/^No\s*Name\s*Loc Id\s*Total\s*1\s*2\s*3\s*/)
157
- @x = @t.serialize('SPExport', :columns => [:points, :id, :fed])
157
+ @x = @t.serialize('SPExport', :only => [:points, :id, :fed])
158
158
  @x.should match(/^No\s*Name\s*Feder\s*Loc Id\s*Total\s*1\s*2\s*3\s*/)
159
- @x = @t.serialize('SPExport', :columns => [:points, :id, :fed, "fed", :rubbish, :fide_id])
159
+ @x = @t.serialize('SPExport', :only => [:points, :id, :fed, "fed", :rubbish, "fide_id"])
160
160
  @x.should match(/^No\s*Name\s*Feder\s*Intl Id\s*Loc Id\s*Total\s*1\s*2\s*3\s*/)
161
- @x = @t.serialize('SPExport', :columns => [:fed, "fide_id", :points, :id, :rating])
161
+ @x = @t.serialize('SPExport', :only => [:fed, "fide_id", :points, :id, :rating])
162
162
  @x.should match(/^No\s*Name\s*Feder\s*Intl Id\s*Loc Id\s*Loc\s*Total\s*1\s*2\s*3\s*/)
163
- @x = @t.serialize('SPExport', :columns => [:fed, :fide_id, :fide_rating, :points, :id, :rating])
163
+ @x = @t.serialize('SPExport', :only => [:fed, :fide_id, "fide_rating", :points, :id, :rating])
164
164
  @x.should match(/^No\s*Name\s*Feder\s*Intl Id\s*Loc Id\s*Rtg\s*Loc\s*Total\s*1\s*2\s*3\s*/)
165
165
  @x.should match(/3\s*Orr,\s*Mark\s*IRL\s*2500035\s*1350\s*2250\s*2200\s*0.5\s*1:D\s*2:L\s*:\s*/)
166
166
  end
167
+
168
+ it "the :only and :except options are logical opposites" do
169
+ @t.serialize('SPExport', :only => [:points, :id, "fed"]).should == @t.serialize('SPExport', :except => [:fide_id, :rating, "fide_rating", :title])
170
+ @t.serialize('SPExport', :only => ["points"]).should == @t.serialize('SPExport', :except => ["fide_id", :rating, :fide_rating, :title, :id, :fed])
171
+ @t.serialize('SPExport', :only => [:rating, :fide_rating, :title, :id, :fed, :points]).should == @t.serialize('SPExport', :except => [:fide_id])
172
+ @t.serialize('SPExport', :only => %w{rating fide_rating fide_id title id fed points}).should == @t.serialize('SPExport', :except => [])
173
+ @t.serialize('SPExport', :only => []).should == @t.serialize('SPExport', :except => [:rating, :fide_rating, :fide_id, :title, :id, :fed, :points])
174
+ @t.serialize('SPExport', :except => []).should == @t.serialize('SPExport')
175
+ end
167
176
  end
168
177
 
169
178
  context "invisible bonuses" do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 4
8
- - 0
9
- version: 1.4.0
8
+ - 1
9
+ version: 1.4.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Mark Orr