sportdb 1.7.6 → 1.7.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -41,6 +41,7 @@ lib/sportdb/models/run.rb
41
41
  lib/sportdb/models/season.rb
42
42
  lib/sportdb/models/team.rb
43
43
  lib/sportdb/models/track.rb
44
+ lib/sportdb/models/utils.rb
44
45
  lib/sportdb/reader.rb
45
46
  lib/sportdb/schema.rb
46
47
  lib/sportdb/service.rb
@@ -80,6 +81,11 @@ lib/sportdb/utils.rb
80
81
  lib/sportdb/version.rb
81
82
  tasks/test.rb
82
83
  test/helper.rb
84
+ test/test_changes.rb
85
+ test/test_cursor.rb
86
+ test/test_date.rb
83
87
  test/test_lang.rb
84
88
  test/test_round.rb
89
+ test/test_scores.rb
85
90
  test/test_utils.rb
91
+ test/test_winner.rb
@@ -53,6 +53,7 @@ require 'sportdb/models/run'
53
53
  require 'sportdb/models/season'
54
54
  require 'sportdb/models/team'
55
55
  require 'sportdb/models/track'
56
+ require 'sportdb/models/utils' # e.g. GameCursor
56
57
  require 'sportdb/schema' # NB: requires sportdb/models (include SportDB::Models)
57
58
  require 'sportdb/utils'
58
59
  require 'sportdb/reader'
@@ -79,7 +80,7 @@ require 'sportdb/data/models' # add convenience finders for known fixtures
79
80
  module SportDb
80
81
 
81
82
  def self.banner
82
- "sportdb #{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
83
+ "sportdb/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
83
84
  end
84
85
 
85
86
  def self.root
@@ -96,6 +97,9 @@ module SportDb
96
97
 
97
98
  def self.lang
98
99
  # todo/fix: find a better way for single instance ??
100
+ # will get us ruby warning: instance variable @lang not initialized => find a better way!!!
101
+ # just use @lang w/o .nil? e.g.
102
+ # @lang =|| Lang.new why? why not?? or better use @@lang =|| Lang.new for class variable!!!
99
103
  if @lang.nil?
100
104
  @lang = Lang.new
101
105
  end
@@ -14,6 +14,9 @@ require 'yaml'
14
14
 
15
15
  ## shortcuts for models
16
16
 
17
+ ##
18
+ ## todo/fix: just use include SportDb::Models - why? why not? is it possible/working?
19
+
17
20
  Badge = SportDb::Models::Badge
18
21
  Event = SportDb::Models::Event
19
22
  Game = SportDb::Models::Game
@@ -11,7 +11,78 @@ class Game < ActiveRecord::Base
11
11
 
12
12
  has_many :goals
13
13
 
14
- before_save :calc_toto12x
14
+ before_save :calc_winner
15
+
16
+
17
+ def toto12x() toto1x2; end # alias for toto12x - todo/fix: use ruby alias helper
18
+ def toto1x2
19
+ ## note: will return string e.g. 1-X-2 (winner will return int e.g. 1-0-2)
20
+
21
+ ## fix: use switch/when expr/stmt instead of ifs
22
+ value = winner90 # 1 0 2 1 => team 1 0 => draw 2 => team
23
+ if value == 0
24
+ 'X'
25
+ elsif value == 1
26
+ '1'
27
+ elsif value == 2
28
+ '2'
29
+ elsif value == -1
30
+ nil # ??? - unknown -- include --??? why? why not??
31
+ else
32
+ nil
33
+ end
34
+ end
35
+
36
+
37
+ def winner1?() winner == 1; end
38
+ def winner2?() winner == 2; end
39
+ def draw? () winner == 0; end # use different name; use an alias (any better names more speaking???)
40
+
41
+
42
+ def calc_winner
43
+ if score1.nil? || score2.nil?
44
+ self.winner90 = nil
45
+ self.winner = nil
46
+ else
47
+ if score1 > score2
48
+ self.winner90 = 1
49
+ elsif score1 < score2
50
+ self.winner90 = 2
51
+ else # assume score1 == score2 - draw
52
+ self.winner90 = 0
53
+ end
54
+
55
+ ## todo/fix:
56
+ # check for next-game/pre-game !!!
57
+ # use 1st leg and 2nd leg - use for winner too
58
+ # or add new winner_total or winner_aggregated method ???
59
+
60
+ ## check for penalty - note: some games might only have penalty and no extra time (e.g. copa liberatadores)
61
+ if score1p.present? && score2p.present?
62
+ if score1p > score2p
63
+ self.winner = 1
64
+ elsif score1p < score2p
65
+ self.winner = 2
66
+ else
67
+ # issue warning! - should not happen; penalty goes on until winner found!
68
+ puts "*** warn: should not happen; penalty goes on until winner found"
69
+ end
70
+ ## check for extra time
71
+ elsif score1et.present? && score2et.present?
72
+ if score1et > score2et
73
+ self.winner = 1
74
+ elsif score1et < score2et
75
+ self.winner = 2
76
+ else # assume score1et == score2et - draw
77
+ self.winner = 0
78
+ end
79
+ else
80
+ # assume no penalty and no extra time; same as 90min result
81
+ self.winner = self.winner90
82
+ end
83
+ end
84
+ end
85
+
15
86
 
16
87
  ### getter/setters for deprecated attribs (score3,4,5,6) n national
17
88
 
@@ -196,20 +267,6 @@ class Game < ActiveRecord::Base
196
267
  end
197
268
 
198
269
 
199
-
200
- def calc_toto12x
201
- if score1.nil? || score2.nil?
202
- self.toto12x = nil
203
- elsif score1 == score2
204
- self.toto12x = 'X'
205
- elsif score1 > score2
206
- self.toto12x = '1'
207
- elsif score1 < score2
208
- self.toto12x = '2'
209
- end
210
- end
211
-
212
-
213
270
  def over? # game over?
214
271
  play_at <= Time.now
215
272
  end
@@ -218,33 +275,56 @@ class Game < ActiveRecord::Base
218
275
  def knockout?
219
276
  knockout == true
220
277
  end
221
-
278
+
222
279
  def complete?
223
280
  score1.present? && score2.present?
224
281
  end
225
282
 
283
+
226
284
  ############# convenience helpers for styling
227
285
  ##
228
286
 
229
287
  def team1_style_class
230
288
  buf = ''
231
289
  ## NB: remove if calc?
232
- buf << 'game-team-winner ' if complete? && (score1 > score2)
233
- buf << 'game-team-draw ' if complete? && (score1 == score2)
290
+
291
+ ### fix: loser
292
+ ## - add method for checking winner/loser on ko pairs using (1st leg/2nd leg totals) ??
293
+ ## use new winner_total method ??
294
+
295
+ if complete?
296
+ if winner1?
297
+ buf << 'game-team-winner '
298
+ elsif winner2?
299
+ buf << 'game-team-loser '
300
+ else # assume draw
301
+ buf << 'game-team-draw '
302
+ end
303
+ end
304
+
234
305
  buf << 'game-knockout ' if knockout?
235
- ### fix: loser - add method for checking winner/loser on ko pairs using (1st leg/2nd leg totals)
236
- buf << 'game-team-loser ' if complete? && (score1 < score2)
237
306
  buf
238
307
  end
239
-
308
+
240
309
  def team2_style_class
241
310
  buf = ''
242
311
  ## NB: remove if calc?
243
- buf << 'game-team-winner ' if complete? && (score2 > score1)
244
- buf << 'game-team-draw ' if complete? && (score2 == score1)
312
+
313
+ ### fix: loser
314
+ ## - add method for checking winner/loser on ko pairs using (1st leg/2nd leg totals) ??
315
+ ## use new winner_total method ??
316
+
317
+ if complete?
318
+ if winner1?
319
+ buf << 'game-team-loser '
320
+ elsif winner2?
321
+ buf << 'game-team-winner '
322
+ else # assume draw
323
+ buf << 'game-team-draw '
324
+ end
325
+ end
326
+
245
327
  buf << 'game-knockout ' if knockout?
246
- ### fix: loser - add method for checking winner/loser on ko pairs using (1st leg/2nd leg totals)
247
- buf << 'game-team-loser ' if complete? && (score2 < score1)
248
328
  buf
249
329
  end
250
330
 
@@ -262,25 +342,51 @@ class Game < ActiveRecord::Base
262
342
 
263
343
 
264
344
  def score_str
265
- return ' - ' if score1.blank? && score2.blank?
266
-
267
- if score1p.present? && score2p.present? # im Elfmeterschiessen i.E.?
268
- "#{score1_str} : #{score2_str} / #{score1et} : #{score2et} n.V. / #{score1p} : #{score2p} i.E."
269
- elsif score1et.present? && score2et.present? # nach Verlaengerung n.V.?
270
- "#{score1_str} : #{score2_str} / #{score1et} : #{score2et} n.V."
271
- else
272
- "#{score1_str} : #{score2_str}"
273
- end
274
- end
345
+ ## return ' - ' if score1.nil? && score2.nil?
275
346
 
276
- def score1_str
277
- if score1.blank? then '-' else score1.to_s end
278
- end
347
+ # note: make after extra time optional;
348
+ # e.g. copa liberatadores only has regular time plus penalty, for example
349
+
350
+ buf = ""
279
351
 
280
- def score2_str
281
- if score2.blank? then '-' else score2.to_s end
352
+ buf << "#{score1_str} : #{score2_str}"
353
+ buf << " / #{score1et_str} : #{score2et_str} n.V." if score1et.present? || score2et.present?
354
+ buf << " / #{score1p_str} : #{score2p_str} i.E." if score1p.present? || score2p.present?
355
+
356
+ buf
282
357
  end
283
358
 
359
+ def score1_str() score1.nil? ? '-' : score1.to_s; end
360
+ def score2_str() score2.nil? ? '-' : score2.to_s; end
361
+
362
+ def score1et_str() score1et.nil? ? '-' : score1et.to_s; end
363
+ def score2et_str() score2et.nil? ? '-' : score2et.to_s; end
364
+
365
+ def score1p_str() score1p.nil? ? '-' : score1p.to_s; end
366
+ def score2p_str() score2p.nil? ? '-' : score2p.to_s; end
367
+
368
+
369
+
370
+ ## todo/fix: find a better name?
371
+ ## todo: move to utils for reuse?
372
+
373
+ def check_for_changes( new_attributes )
374
+ changes_counter = 0
375
+ new_attributes.each do |key,new_value|
376
+ old_value = attributes[ key.to_s ]
377
+ ## todo/fix: also check for class/type matching ????
378
+ if new_value == old_value
379
+ # do nothing
380
+ else
381
+ changes_counter +=1
382
+ puts "change #{changes_counter} for #{key} old:>#{old_value}< : #{old_value.class.name} new:>#{new_value}< : #{new_value.class.name}"
383
+ end
384
+ end
385
+
386
+ # no changes found for counter==0;
387
+ # -- otherwise x changes found; return true
388
+ changes_counter == 0 ? false : true
389
+ end
284
390
 
285
391
  end # class Game
286
392
 
@@ -16,11 +16,20 @@ class Team < ActiveRecord::Base
16
16
  has_many :event_teams, :class_name => 'EventTeam' # join table (events+teams)
17
17
  has_many :events, :through => :event_teams
18
18
 
19
- ### fix - how to do it with has_many macro? use finder_sql?
19
+ ### fix!!! - how to do it with has_many macro? use finder_sql?
20
20
  def games
21
- Game.where( 'team1_id = ? or team2_id = ?', id, id ).order( 'play_at' ).all
21
+ Game.where( 'team1_id = ? or team2_id = ?', id, id ).order( 'play_at' )
22
22
  end
23
-
23
+
24
+ def upcoming_games
25
+ Game.where( 'team1_id = ? or team2_id = ?', id, id ).where( 'play_at > ?', Time.now ).order( 'play_at' )
26
+ end
27
+
28
+ def past_games
29
+ Game.where( 'team1_id = ? or team2_id = ?', id, id ).where( 'play_at < ?', Time.now ).order( 'play_at desc' )
30
+ end
31
+
32
+
24
33
  has_many :badges # Winner, 2nd, Cupsieger, Aufsteiger, Absteiger, etc.
25
34
 
26
35
  belongs_to :country, :class_name => 'WorldDb::Models::Country', :foreign_key => 'country_id'
@@ -0,0 +1,78 @@
1
+ module SportDb
2
+ module Models
3
+
4
+
5
+ class GameCursor
6
+
7
+ def initialize( games )
8
+ @games = games
9
+ end
10
+
11
+ def each
12
+ state = GameCursorState.new
13
+
14
+ @games.each do |game|
15
+ state.next( game )
16
+ yield( game, state ) # e.g. lets you use state.new_date? or state.new_week? or state.new_year? etc.
17
+ end
18
+ end # method each
19
+ end # class GameCursor
20
+
21
+
22
+ class GameCursorState
23
+
24
+ def initialize
25
+ @last_play_at = DateTime.new( 1971, 1, 1 )
26
+ @new_date = true
27
+ @new_year = true
28
+ @new_week = true
29
+ @index = -1 # zero-based index; thus start off with -1 (e.g. -1+=1 => 0)
30
+ end
31
+
32
+ attr_reader :index
33
+
34
+ def new_date?() @new_date; end
35
+ def new_year?() @new_year; end
36
+ def new_week?() @new_week; end
37
+
38
+
39
+ ## add new league ?
40
+ ## add new round ?
41
+ ## add new time ?
42
+
43
+ def next( game )
44
+ @index += 1 # zero-based index; start off with -1 (undefined/uninitialized)
45
+ game_play_at = game.play_at # cache play_at value ref
46
+
47
+ if @last_play_at.year == game_play_at.year &&
48
+ @last_play_at.month == game_play_at.month &&
49
+ @last_play_at.day == game_play_at.day
50
+ @new_date = false
51
+ else
52
+ @new_date = true
53
+
54
+ # check for new_year
55
+ if @last_play_at.year == game_play_at.year
56
+ @new_year = false
57
+ else
58
+ @new_year = true
59
+ end
60
+
61
+ # check for new_week
62
+ # -- todo: find a method for week number; do NOT use strftime; there must be something easier
63
+ # -- check if activesupport adds .week or similar ??? use it if it exists
64
+ if @last_play_at.strftime('%V') == game_play_at.strftime('%V')
65
+ @new_week = false
66
+ else
67
+ @new_week = true
68
+ end
69
+ end
70
+
71
+ @last_play_at = game.play_at
72
+ end # method next
73
+
74
+ end # class GameCursorState
75
+
76
+
77
+ end # module Models
78
+ end # module SportDb
@@ -816,31 +816,38 @@ private
816
816
  group_id: @group.present? ? @group.id : nil
817
817
  }
818
818
 
819
- game_attribs[ :pos ] = pos if pos.present?
819
+ game_attribs[ :pos ] = pos if pos.present?
820
820
 
821
- if game.present?
822
- logger.debug "update game #{game.id}:"
821
+ ####
822
+ # note: only update if any changes (or create if new record)
823
+ if game.present? &&
824
+ game.check_for_changes( game_attribs ) == false
825
+ logger.debug " skip update game #{game.id}; no changes found"
823
826
  else
824
- logger.debug "create game:"
825
- game = Game.new
826
-
827
- more_game_attribs = {
828
- round_id: @round.id,
829
- team1_id: team1.id,
830
- team2_id: team2.id
831
- }
827
+ if game.present?
828
+ logger.debug "update game #{game.id}:"
829
+ else
830
+ logger.debug "create game:"
831
+ game = Game.new
832
+
833
+ more_game_attribs = {
834
+ round_id: @round.id,
835
+ team1_id: team1.id,
836
+ team2_id: team2.id
837
+ }
832
838
 
833
- ## NB: use round.games.count for pos
834
- ## lets us add games out of order if later needed
835
- more_game_attribs[ :pos ] = @round.games.count+1 if pos.nil?
839
+ ## NB: use round.games.count for pos
840
+ ## lets us add games out of order if later needed
841
+ more_game_attribs[ :pos ] = @round.games.count+1 if pos.nil?
836
842
 
837
- game_attribs = game_attribs.merge( more_game_attribs )
838
- end
843
+ game_attribs = game_attribs.merge( more_game_attribs )
844
+ end
839
845
 
840
- logger.debug game_attribs.to_json
846
+ logger.debug game_attribs.to_json
847
+ game.update_attributes!( game_attribs )
848
+ end
841
849
 
842
- game.update_attributes!( game_attribs )
843
- end
850
+ end # method parse_game
844
851
 
845
852
 
846
853
  def parse_fixtures( reader )
@@ -194,12 +194,9 @@ create_table :games do |t|
194
194
  t.integer :score2ii # second third - team2 (opt)
195
195
  t.references :next_game # for hinspiel bei rueckspiel in knockout game
196
196
  t.references :prev_game
197
-
198
-
199
-
200
- ### todo> find a better name (toto is not international/english?)
201
- ## rename to score12x or pt12x or result12x
202
- t.string :toto12x # 1,2,X,nil calculate on save
197
+
198
+ t.integer :winner # 1,2,0,nil calculate on save - "real" winner (after 90 or extra time or penalty, aggregated first+second leg?)
199
+ t.integer :winner90 # 1,2,0,nil calculate on save - winner after 90 mins (or regugular play time depending on sport - add alias or find a better name!)
203
200
 
204
201
  t.timestamps
205
202
  end
@@ -387,8 +387,13 @@ module SportDb::FixtureHelpers
387
387
  find_leading_pos!( line )
388
388
  end
389
389
 
390
+
390
391
  def find_scores!( line )
391
392
 
393
+ # note: always call after find_dates !!!
394
+ # scores match date-like patterns!! e.g. 10-11 or 10:00 etc.
395
+ # -- note: score might have two digits too
396
+
392
397
  ### fix: depending on language allow 1:1 or 1-1
393
398
  ## do NOT allow mix and match
394
399
  ## e.g. default to en is 1-1
@@ -399,17 +404,31 @@ module SportDb::FixtureHelpers
399
404
  # and return it
400
405
  # NB: side effect - removes date from line string
401
406
 
407
+ # note: regex should NOT match regex extra time or penalty
408
+ # thus, we do NOT any longer allow spaces for now between
409
+ # score and marker (e.g. nV,iE, etc.)
410
+
402
411
  # e.g. 1:2 or 0:2 or 3:3 // 1-1 or 0-2 or 3-3
403
- regex = /\b(\d)[:\-](\d)\b/
404
-
405
- # e.g. 1:2nV => overtime
406
- regex_ot = /\b(\d)[:\-](\d)[ \t]?[nN][vV]\b/
407
-
408
- # e.g. 5:4iE => penalty
409
- regex_p = /\b(\d)[:\-](\d)[ \t]?[iI][eE]\b/
410
-
412
+ regex = /\b(\d{1,2})[:\-](\d{1,2})\b/
413
+
414
+ ## todo: add/allow english markers e.g. aet ??
415
+
416
+ ## fix: use case insansitive flag instead e.g. /i
417
+ # instead of [nN] etc.
418
+
419
+ # e.g. 1:2nV => after extra time a.e.t
420
+ regex_et = /\b(\d{1,2})[:\-](\d{1,2})[nN][vV]\b/
421
+
422
+ # e.g. 5:4iE => penalty / after penalty a.p
423
+ regex_p = /\b(\d{1,2})[:\-](\d{1,2})[iI][eE]\b/
424
+
411
425
  scores = []
412
-
426
+
427
+ ## todo: how to handle game w/o extra time
428
+ # but w/ optional penalty ??? e.g. used in copa liberatores, for example
429
+ # retrun 0,0 or nil,nil for extra time score ?? or -1, -1 ??
430
+ # for now use nil,nil
431
+
413
432
  if line =~ regex
414
433
  logger.debug " score: >#{$1}-#{$2}<"
415
434
 
@@ -417,24 +436,35 @@ module SportDb::FixtureHelpers
417
436
 
418
437
  scores << $1.to_i
419
438
  scores << $2.to_i
420
-
421
- if line =~ regex_ot
422
- logger.debug " score.ot: >#{$1}-#{$2}<"
423
-
424
- line.sub!( regex_ot, '[SCORE.OT]' )
439
+ end
440
+
441
+ ## todo:
442
+ ## reverse matching order ??? allows us to support spaces for nV and iE
443
+ ## why? why not??
425
444
 
426
- scores << $1.to_i
427
- scores << $2.to_i
445
+ if line =~ regex_et
446
+ logger.debug " score.et: >#{$1}-#{$2}<"
428
447
 
429
- if line =~ regex_p
430
- logger.debug " score.p: >#{$1}-#{$2}<"
448
+ line.sub!( regex_et, '[SCORE.ET]' )
449
+
450
+ ## check scores empty? - fill with nil,nil
451
+ scores += [nil,nil] if scores.size == 0
452
+
453
+ scores << $1.to_i
454
+ scores << $2.to_i
455
+ end
456
+
457
+ if line =~ regex_p
458
+ logger.debug " score.p: >#{$1}-#{$2}<"
431
459
 
432
- line.sub!( regex_p, '[SCORE.P]' )
460
+ line.sub!( regex_p, '[SCORE.P]' )
433
461
 
434
- scores << $1.to_i
435
- scores << $2.to_i
436
- end
437
- end
462
+ ## check scores empty? - fill with nil,nil
463
+ scores += [nil,nil] if scores.size == 0
464
+ scores += [nil,nil] if scores.size == 2
465
+
466
+ scores << $1.to_i
467
+ scores << $2.to_i
438
468
  end
439
469
  scores
440
470
  end # methdod find_scores!
@@ -1,6 +1,6 @@
1
1
 
2
2
  module SportDb
3
- VERSION = '1.7.6'
3
+ VERSION = '1.7.7'
4
4
  end
5
5
 
6
6
 
@@ -9,8 +9,45 @@ require 'minitest/autorun'
9
9
  # include MiniTest::Unit # lets us use TestCase instead of MiniTest::Unit::TestCase
10
10
 
11
11
 
12
- ## our own code
12
+ require 'pp'
13
+
14
+
15
+ # ruby gems
13
16
 
17
+ require 'active_record'
18
+
19
+ require 'worlddb'
14
20
  require 'logutils'
21
+ require 'logutils/db' # NB: explict require required for LogDb (not automatic)
22
+
23
+ ## our own code
24
+
15
25
  require 'sportdb'
16
26
 
27
+
28
+ def setup_in_memory_db
29
+ # Database Setup & Config
30
+
31
+ db_config = {
32
+ adapter: 'sqlite3',
33
+ database: ':memory:'
34
+ }
35
+
36
+ pp db_config
37
+
38
+ ActiveRecord::Base.logger = Logger.new( STDOUT )
39
+ ## ActiveRecord::Base.colorize_logging = false - no longer exists - check new api/config setting?
40
+
41
+ ## NB: every connect will create a new empty in memory db
42
+ ActiveRecord::Base.establish_connection( db_config )
43
+
44
+
45
+ ## build schema
46
+
47
+ LogDb.create
48
+ WorldDb.create
49
+ SportDb.create
50
+ end
51
+
52
+
53
+ setup_in_memory_db()
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ class TestChanges < MiniTest::Unit::TestCase
6
+
7
+ def test_scores
8
+ game1 = SportDb::Models::Game.new
9
+ game1.score1 = 1
10
+ game1.score2 = 2
11
+
12
+ game2 = SportDb::Models::Game.new
13
+ game2.score1 = 1
14
+ game2.score2 = 1
15
+ game2.score1p = 5
16
+ game2.score2p = 3
17
+
18
+ game_attribs = {
19
+ score1: 1,
20
+ score2: 2,
21
+ score1et: nil,
22
+ score2et: nil,
23
+ score1p: nil,
24
+ score2p: nil
25
+ }
26
+
27
+ assert_equal false, game1.check_for_changes( game_attribs )
28
+ assert_equal true, game2.check_for_changes( game_attribs )
29
+ end
30
+
31
+ def test_play_at
32
+ game1 = SportDb::Models::Game.new
33
+ game1.score1 = 1
34
+ game1.score2 = 2
35
+ game1.play_at = DateTime.new( 2012, 11, 5 )
36
+
37
+ game2 = SportDb::Models::Game.new
38
+ game2.score1 = 1
39
+ game2.score2 = 2
40
+ game2.play_at = DateTime.new( 2012, 12, 24 )
41
+
42
+ game_attribs = {
43
+ score1: 1,
44
+ score2: 2,
45
+ play_at: DateTime.new( 2012, 11, 5 )
46
+ }
47
+
48
+ assert_equal false, game1.check_for_changes( game_attribs )
49
+ assert_equal true, game2.check_for_changes( game_attribs )
50
+ end
51
+
52
+ def test_group_id
53
+ game1 = SportDb::Models::Game.new
54
+ game1.score1 = 1
55
+ game1.score2 = 2
56
+ game1.group_id = 1
57
+
58
+ game2 = SportDb::Models::Game.new
59
+ game2.score1 = 1
60
+ game2.score2 = 2
61
+ game2.group_id = 2
62
+
63
+ game_attribs = {
64
+ score1: 1,
65
+ score2: 2,
66
+ group_id: 1
67
+ }
68
+
69
+ assert_equal false, game1.check_for_changes( game_attribs )
70
+ assert_equal true, game2.check_for_changes( game_attribs )
71
+ end
72
+
73
+
74
+ end # class TestChanges
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ class TestCursor < MiniTest::Unit::TestCase
6
+
7
+ def test_games
8
+ games = []
9
+
10
+ games << SportDb::Models::Game.new( score1: 3, score2: 1, play_at: DateTime.new(2013, 8, 9) )
11
+ games << SportDb::Models::Game.new( score1: 1, score2: 3, play_at: DateTime.new(2013, 8, 10) )
12
+ games << SportDb::Models::Game.new( score1: 2, score2: 0, play_at: DateTime.new(2013, 8, 10) )
13
+ games << SportDb::Models::Game.new( score1: 3, score2: 2, play_at: DateTime.new(2013, 8, 12) ) # new_week
14
+
15
+ SportDb::Models::GameCursor.new( games ).each do |game,state|
16
+ if state.index == 0
17
+ assert_equal 3, game.score1
18
+ assert_equal 1, game.score2
19
+ assert_equal true, state.new_date?
20
+ assert_equal true, state.new_year?
21
+ assert_equal true, state.new_week?
22
+ end
23
+
24
+ if state.index == 1
25
+ assert_equal 1, game.score1
26
+ assert_equal 3, game.score2
27
+ assert_equal true, state.new_date?
28
+ assert_equal false, state.new_year?
29
+ assert_equal false, state.new_week?
30
+ end
31
+
32
+ if state.index == 2
33
+ assert_equal 2, game.score1
34
+ assert_equal 0, game.score2
35
+ assert_equal false, state.new_date?
36
+ assert_equal false, state.new_year?
37
+ assert_equal false, state.new_week?
38
+ end
39
+
40
+ if state.index == 3
41
+ assert_equal 3, game.score1
42
+ assert_equal 2, game.score2
43
+ assert_equal true, state.new_date?
44
+ assert_equal true, state.new_week?
45
+ assert_equal false, state.new_year?
46
+ end
47
+ end
48
+ end
49
+
50
+ end # class TestCursor
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ class TestDate < MiniTest::Unit::TestCase
6
+
7
+ def test_date
8
+ assert_datetime DateTime.new( 2013, 1, 19, 22 ), parse_date( '19.01.2013 22.00' )
9
+ assert_datetime DateTime.new( 2013, 1, 21, 21, 30 ), parse_date( '21.01.2013 21.30' )
10
+
11
+ assert_date DateTime.new( 2013, 1, 26 ), parse_date( '26.01.2013' )
12
+ end
13
+
14
+ private
15
+
16
+ ## todo: check if assert_datetime or assert_date exist already? what is the best practice to check dates ???
17
+ def assert_date( exp, act )
18
+ assert_equal exp.year, act.year
19
+ assert_equal exp.month, act.month
20
+ assert_equal exp.day, act.day
21
+ end
22
+
23
+ def assert_time( exp, act )
24
+ assert_equal exp.hour, act.hour
25
+ assert_equal exp.min, act.min
26
+ end
27
+
28
+ def assert_datetime( exp, act )
29
+ assert_date( exp, act )
30
+ assert_time( exp, act )
31
+ end
32
+
33
+ class Reader
34
+ include LogUtils::Logging # add logger
35
+ include SportDb::FixtureHelpers
36
+ end
37
+
38
+ def parse_date( line, opts={} )
39
+ # e.g. lets you pass in opts[:start_at] ???
40
+ reader = Reader.new
41
+ reader.find_date!( line, opts )
42
+ end
43
+
44
+ end # class TestScores
@@ -18,28 +18,29 @@ class TestRound < MiniTest::Unit::TestCase
18
18
 
19
19
  pos, title, title2, group_pos, group_title, ko = parse_round( line )
20
20
 
21
- assert( pos == 2 )
22
- assert( title == "2. Round" )
23
- assert( title2 == nil )
24
- assert( ko == false )
21
+ assert_equal 2, pos
22
+ assert_equal '2. Round', title
23
+ assert_equal nil, title2
24
+ assert_equal false, ko
25
25
 
26
26
  line = "(1) Matchday P.1 / 1st Leg // January 22-24"
27
27
 
28
28
  pos, title, title2, group_pos, group_title, ko = parse_round( line )
29
29
 
30
- assert( pos == 1 )
31
- assert( title == "Matchday P.1 / 1st Leg" )
32
- assert( title2 == "January 22-24" )
33
- assert( ko == false )
30
+ assert_equal 1, pos
31
+ assert_equal 'Matchday P.1 / 1st Leg', title
32
+ assert_equal 'January 22-24', title2
33
+ assert_equal false, ko
34
34
 
35
35
  line = "(4) Matchday 2 / Group 1 // February 19-21"
36
36
 
37
37
  pos, title, title2, group_pos, group_title, ko = parse_round( line )
38
38
 
39
- assert( pos == 4 )
40
- assert( title == "Matchday 2" )
41
- assert( title2 == "February 19-21" )
42
- assert( ko == false )
39
+ assert_equal 4, pos
40
+ assert_equal 'Matchday 2', title
41
+ assert_equal 'February 19-21', title2
42
+ assert_equal false, ko
43
+
43
44
 
44
45
  line = "(13) Round of 16 / 1st Leg // April 25, May 1-3"
45
46
 
@@ -101,7 +102,7 @@ class TestRound < MiniTest::Unit::TestCase
101
102
 
102
103
  pos, title, title2, group_pos, group_title, ko = parse_round( line )
103
104
 
104
- assert( pos = 2 )
105
+ assert( pos == 2 )
105
106
  assert( title == 'Jornada 2' )
106
107
  assert( title2 == '27, 28 y 29 de julio' )
107
108
  assert( ko == false )
@@ -110,7 +111,7 @@ class TestRound < MiniTest::Unit::TestCase
110
111
 
111
112
  pos, title, title2, group_pos, group_title, ko = parse_round( line )
112
113
 
113
- assert( pos = 18 )
114
+ assert( pos == 18 )
114
115
  assert( title == 'Cuartos de Final / Ida' )
115
116
  assert( title2 == '14/15 de noviembre' )
116
117
  assert( ko == false )
@@ -119,7 +120,7 @@ class TestRound < MiniTest::Unit::TestCase
119
120
 
120
121
  pos, title, title2, group_pos, group_title, ko = parse_round( line )
121
122
 
122
- assert( pos = 19 )
123
+ assert( pos == 19 )
123
124
  assert( title == 'Cuartos de Final / Vuelta' )
124
125
  assert( title2 == '17/18 de noviembre' )
125
126
  assert( ko == true )
@@ -133,7 +134,7 @@ class TestRound < MiniTest::Unit::TestCase
133
134
 
134
135
  pos, title, title2, group_pos, group_title, ko = parse_round( line )
135
136
 
136
- assert( pos = 5 )
137
+ assert( pos == 5 )
137
138
  assert( title == 'Spieltag 5' )
138
139
  assert( title2 == 'Di./Mi., 20.+21. Nov 2012' )
139
140
  assert( ko == false )
@@ -142,7 +143,7 @@ class TestRound < MiniTest::Unit::TestCase
142
143
 
143
144
  pos, title, title2, group_pos, group_title, ko = parse_round( line )
144
145
 
145
- assert( pos = 8 )
146
+ assert( pos == 8 )
146
147
  assert( title == 'Achtelfinale Rückspiele' )
147
148
  assert( title2 == 'Di./Mi., 5.+6./12.+13. Mär 2013' )
148
149
  assert( ko == true )
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ class TestScores < MiniTest::Unit::TestCase
6
+
7
+
8
+ def test_scores
9
+ assert_equal [10,0], parse_scores( '10:0' )
10
+ assert_equal [1,22], parse_scores( '1:22' )
11
+ assert_equal [1,22], parse_scores( '1-22' )
12
+
13
+ assert_equal [], parse_scores( '1-222' ) # do not support three digits
14
+ assert_equal [], parse_scores( '111-0' ) # do not support three digits
15
+ assert_equal [], parse_scores( '1:222' ) # do not support three digits
16
+ assert_equal [], parse_scores( '111:0' ) # do not support three digits
17
+
18
+ ## penality only
19
+ assert_equal [nil,nil,nil,nil,3,4], parse_scores( '3-4iE' )
20
+ assert_equal [nil,nil,nil,nil,3,4], parse_scores( '3:4iE' )
21
+
22
+ ## extra time only - allow ?? why not ?? only allow penalty w/ missing extra time?
23
+ ## todo/fix: issue warning or error in parser!!!
24
+ assert_equal [nil,nil,3,4], parse_scores( '3-4nV' )
25
+ assert_equal [nil,nil,3,4], parse_scores( '3:4nV' )
26
+
27
+ assert_equal [1,1,3,4], parse_scores( '3:4nV 1:1' )
28
+ assert_equal [1,1,3,4], parse_scores( '1:1 3:4nV' )
29
+
30
+ assert_equal [1,1,nil,nil,3,4], parse_scores( '3:4iE 1:1' )
31
+ assert_equal [1,1,nil,nil,3,4], parse_scores( '1:1 3:4iE' )
32
+ end
33
+
34
+ private
35
+ class Reader
36
+ include LogUtils::Logging # add logger
37
+ include SportDb::FixtureHelpers
38
+ end
39
+
40
+ def parse_scores( line )
41
+ reader = Reader.new
42
+ reader.find_scores!( line )
43
+ end
44
+
45
+ end # class TestScores
@@ -0,0 +1,95 @@
1
+ # encoding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ class TestWinner < MiniTest::Unit::TestCase
6
+
7
+ def test_1_2
8
+ game = SportDb::Models::Game.new
9
+ game.score1 = 1
10
+ game.score2 = 2
11
+ game.calc_winner
12
+
13
+ assert_equal 2, game.winner90
14
+ assert_equal 2, game.winner
15
+ assert_equal true, game.winner2?
16
+ assert_equal false, game.winner1?
17
+ assert_equal false, game.draw?
18
+ end
19
+
20
+ def test_1_1
21
+ game = SportDb::Models::Game.new
22
+ game.score1 = 1
23
+ game.score2 = 1
24
+ game.calc_winner
25
+
26
+ assert_equal 0, game.winner90
27
+ assert_equal 0, game.winner
28
+ assert_equal true, game.draw?
29
+ assert_equal false, game.winner1?
30
+ assert_equal false, game.winner2?
31
+ end
32
+
33
+ def test_2_1
34
+ game = SportDb::Models::Game.new
35
+ game.score1 = 2
36
+ game.score2 = 1
37
+ game.calc_winner
38
+
39
+ assert_equal 1, game.winner90
40
+ assert_equal 1, game.winner
41
+ assert_equal true, game.winner1?
42
+ assert_equal false, game.winner2?
43
+ assert_equal false, game.draw?
44
+ end
45
+
46
+ def test_1_1__2_1
47
+ game = SportDb::Models::Game.new
48
+ game.score1 = 1
49
+ game.score2 = 1
50
+ game.score1et = 2
51
+ game.score2et = 1
52
+ game.calc_winner
53
+
54
+ assert_equal 0, game.winner90
55
+ assert_equal 1, game.winner
56
+ assert_equal true, game.winner1?
57
+ assert_equal false, game.winner2?
58
+ assert_equal false, game.draw?
59
+ end
60
+
61
+ def test_1_1__2_2__3_5
62
+ game = SportDb::Models::Game.new
63
+ game.score1 = 1
64
+ game.score2 = 1
65
+ game.score1et = 2
66
+ game.score2et = 2
67
+ game.score1p = 3
68
+ game.score2p = 5
69
+ game.calc_winner
70
+
71
+ assert_equal 0, game.winner90
72
+ assert_equal 2, game.winner
73
+ assert_equal true, game.winner2?
74
+ assert_equal false, game.winner1?
75
+ assert_equal false, game.draw?
76
+ end
77
+
78
+ def test_1_1_x_3_5
79
+ game = SportDb::Models::Game.new
80
+ game.score1 = 1
81
+ game.score2 = 1
82
+ game.score1et = nil
83
+ game.score2et = nil
84
+ game.score1p = 3
85
+ game.score2p = 5
86
+ game.calc_winner
87
+
88
+ assert_equal 0, game.winner90
89
+ assert_equal 2, game.winner
90
+ assert_equal true, game.winner2?
91
+ assert_equal false, game.winner1?
92
+ assert_equal false, game.draw?
93
+ end
94
+
95
+ end # class TestWinner
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.6
4
+ version: 1.7.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-20 00:00:00.000000000 Z
12
+ date: 2013-10-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: worlddb
16
- requirement: &81394750 !ruby/object:Gem::Requirement
16
+ requirement: &70825440 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '1.7'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *81394750
24
+ version_requirements: *70825440
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: fetcher
27
- requirement: &81394520 !ruby/object:Gem::Requirement
27
+ requirement: &70825170 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0.3'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *81394520
35
+ version_requirements: *70825170
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: gli
38
- requirement: &81394270 !ruby/object:Gem::Requirement
38
+ requirement: &70824860 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.5.6
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *81394270
46
+ version_requirements: *70824860
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rdoc
49
- requirement: &81394020 !ruby/object:Gem::Requirement
49
+ requirement: &70824550 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '3.10'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *81394020
57
+ version_requirements: *70824550
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: hoe
60
- requirement: &81393780 !ruby/object:Gem::Requirement
60
+ requirement: &70824310 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '3.3'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *81393780
68
+ version_requirements: *70824310
69
69
  description: sportdb - sport.db command line tool
70
70
  email: opensport@googlegroups.com
71
71
  executables:
@@ -117,6 +117,7 @@ files:
117
117
  - lib/sportdb/models/season.rb
118
118
  - lib/sportdb/models/team.rb
119
119
  - lib/sportdb/models/track.rb
120
+ - lib/sportdb/models/utils.rb
120
121
  - lib/sportdb/reader.rb
121
122
  - lib/sportdb/schema.rb
122
123
  - lib/sportdb/service.rb
@@ -156,9 +157,14 @@ files:
156
157
  - lib/sportdb/version.rb
157
158
  - tasks/test.rb
158
159
  - test/helper.rb
160
+ - test/test_changes.rb
161
+ - test/test_cursor.rb
162
+ - test/test_date.rb
159
163
  - test/test_lang.rb
160
164
  - test/test_round.rb
165
+ - test/test_scores.rb
161
166
  - test/test_utils.rb
167
+ - test/test_winner.rb
162
168
  - .gemtest
163
169
  homepage: https://github.com/geraldb/sport.db.ruby
164
170
  licenses:
@@ -198,6 +204,11 @@ signing_key:
198
204
  specification_version: 3
199
205
  summary: sportdb - sport.db command line tool
200
206
  test_files:
207
+ - test/test_date.rb
201
208
  - test/test_lang.rb
209
+ - test/test_cursor.rb
202
210
  - test/test_round.rb
211
+ - test/test_scores.rb
212
+ - test/test_winner.rb
203
213
  - test/test_utils.rb
214
+ - test/test_changes.rb