sportdb-models 1.18.0 → 1.18.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{HISTORY.md → CHANGELOG.md} +0 -0
- data/Manifest.txt +1 -16
- data/Rakefile +6 -7
- data/lib/sportdb/models.rb +8 -30
- data/lib/sportdb/version.rb +1 -1
- data/test/test_assoc_reader.rb +1 -3
- data/test/test_changes.rb +9 -5
- data/test/test_cursor.rb +6 -1
- data/test/test_event_meta_reader.rb +0 -3
- data/test/test_event_reader.rb +2 -6
- data/test/test_event_table_reader.rb +1 -5
- metadata +24 -25
- data/config/fixtures/de.yml +0 -46
- data/config/fixtures/en.yml +0 -54
- data/config/fixtures/es.yml +0 -48
- data/config/fixtures/fr.yml +0 -53
- data/config/fixtures/it.yml +0 -55
- data/config/fixtures/pt.yml +0 -46
- data/config/fixtures/ro.yml +0 -55
- data/data/seasons.txt +0 -74
- data/data/setups/all.txt +0 -5
- data/lib/sportdb/csv_reader.rb +0 -241
- data/lib/sportdb/finders/date.rb +0 -446
- data/lib/sportdb/lang.rb +0 -216
- data/test/test_csv_reader.rb +0 -45
- data/test/test_date.rb +0 -100
- data/test/test_lang.rb +0 -130
data/lib/sportdb/lang.rb
DELETED
@@ -1,216 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module SportDb
|
4
|
-
|
5
|
-
class Lang
|
6
|
-
|
7
|
-
include LogUtils::Logging
|
8
|
-
|
9
|
-
attr_reader :lang
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
# fix/todo: load on demand; only if no fixtures loaded/configured use builtin
|
13
|
-
load_builtin_words
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
def load_builtin_words
|
18
|
-
builtin_words = {
|
19
|
-
'en' => 'fixtures/en',
|
20
|
-
'de' => 'fixtures/de',
|
21
|
-
'es' => 'fixtures/es',
|
22
|
-
'fr' => 'fixtures/fr',
|
23
|
-
'it' => 'fixtures/it',
|
24
|
-
'pt' => 'fixtures/pt',
|
25
|
-
'ro' => 'fixtures/ro'
|
26
|
-
}
|
27
|
-
|
28
|
-
load_words( builtin_words, SportDb.config_path )
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
def load_words( h, include_path )
|
33
|
-
@lang = 'en' # make default lang english/en
|
34
|
-
@words = {} # resets fixtures
|
35
|
-
@cache = {} # reset cached values
|
36
|
-
|
37
|
-
h.each_with_index do |(key,value),i|
|
38
|
-
name = value
|
39
|
-
path = "#{include_path}/#{name}.yml"
|
40
|
-
logger.debug( "loading words #{key} (#{i+1}/#{h.size}) in '#{name}' (#{path})..." )
|
41
|
-
@words[ key ] = YAML.load( File.read_utf8( path ))
|
42
|
-
end
|
43
|
-
|
44
|
-
@classifier = TextUtils::Classifier.new
|
45
|
-
@words.each_with_index do |(key,value),i|
|
46
|
-
logger.debug "train classifier for #{key} (#{i+1}/#{@words.size})"
|
47
|
-
@classifier.train( key, value )
|
48
|
-
end
|
49
|
-
|
50
|
-
@classifier.dump # for debugging dump all words
|
51
|
-
end
|
52
|
-
|
53
|
-
def classify( text )
|
54
|
-
@classifier.classify( text )
|
55
|
-
end
|
56
|
-
|
57
|
-
def classify_file( path )
|
58
|
-
@classifier.classify_file( path )
|
59
|
-
end
|
60
|
-
|
61
|
-
def lang=(value)
|
62
|
-
logger.debug "setting lang to #{value}"
|
63
|
-
|
64
|
-
if @lang != value
|
65
|
-
|
66
|
-
### todo: make reset cached values into method/function for reuse (see load_words)
|
67
|
-
# reset cached values on language change
|
68
|
-
logger.debug "reseting cached lang values (lang changed from #{@lang} to #{value})"
|
69
|
-
|
70
|
-
@cache = {}
|
71
|
-
end
|
72
|
-
|
73
|
-
@lang = value
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
def group
|
79
|
-
@cache[ :group ] ||= group_getter
|
80
|
-
end
|
81
|
-
|
82
|
-
def round
|
83
|
-
@cache[ :round ] ||= round_getter
|
84
|
-
end
|
85
|
-
|
86
|
-
def knockout_round
|
87
|
-
@cache[ :knockout_round ] ||= knockout_round_getter
|
88
|
-
end
|
89
|
-
|
90
|
-
def leg1
|
91
|
-
@cache[ :leg1 ] ||= leg1_getter
|
92
|
-
end
|
93
|
-
|
94
|
-
def leg2
|
95
|
-
@cache[ :leg2 ] ||= leg2_getter
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
def regex_group
|
101
|
-
@cache [ :regex_group ] ||= regex_group_getter
|
102
|
-
end
|
103
|
-
|
104
|
-
def regex_round
|
105
|
-
@cache[ :regex_round ] ||= regex_round_getter
|
106
|
-
end
|
107
|
-
|
108
|
-
def regex_knockout_round
|
109
|
-
@cache[ :regex_knockout_round ] ||= regex_knockout_round_getter
|
110
|
-
end
|
111
|
-
|
112
|
-
def regex_leg1
|
113
|
-
@cache[ :regex_leg1 ] ||= regex_leg1_getter
|
114
|
-
end
|
115
|
-
|
116
|
-
def regex_leg2
|
117
|
-
@cache[ :regex_leg2 ] ||= regex_leg2_getter
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
def group_getter
|
122
|
-
h = @words[ lang ]
|
123
|
-
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
124
|
-
values << h['group']
|
125
|
-
values
|
126
|
-
end
|
127
|
-
|
128
|
-
def round_getter
|
129
|
-
# e.g. Spieltag|Runde|Achtelfinale|Viertelfinale|Halbfinale|Finale
|
130
|
-
|
131
|
-
## fix/todo:
|
132
|
-
## sort by length first - to allow best match e.g.
|
133
|
-
## 3rd place play-off instead of Play-off ?? etc. - why? why not?
|
134
|
-
|
135
|
-
h = @words[ lang ]
|
136
|
-
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
137
|
-
values << h['round']
|
138
|
-
|
139
|
-
### add knockout rounds values too
|
140
|
-
values << "|" << h['round32']
|
141
|
-
values << "|" << h['round16']
|
142
|
-
values << "|" << h['quarterfinals']
|
143
|
-
values << "|" << h['semifinals']
|
144
|
-
values << "|" << h['fifthplace'] if h['fifthplace'] # nb: allow empty/is optional!!
|
145
|
-
values << "|" << h['thirdplace']
|
146
|
-
values << "|" << h['final']
|
147
|
-
values << "|" << h['playoffs'] if h['playoffs'] # nb: allow empty/is optional!!
|
148
|
-
values
|
149
|
-
end
|
150
|
-
|
151
|
-
def leg1_getter
|
152
|
-
h = @words[ lang ]
|
153
|
-
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
154
|
-
values << h['leg1']
|
155
|
-
values
|
156
|
-
end
|
157
|
-
|
158
|
-
def leg2_getter
|
159
|
-
h = @words[ lang ]
|
160
|
-
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
161
|
-
values << h['leg2']
|
162
|
-
values
|
163
|
-
end
|
164
|
-
|
165
|
-
def knockout_round_getter
|
166
|
-
h = @words[ lang ]
|
167
|
-
values = "" # NB: always construct a new string (do NOT use a reference to hash value)
|
168
|
-
values << h['round32']
|
169
|
-
values << "|" << h['round16']
|
170
|
-
values << "|" << h['quarterfinals']
|
171
|
-
values << "|" << h['semifinals']
|
172
|
-
values << "|" << h['fifthplace'] if h['fifthplace'] # nb: allow empty/is optional!!
|
173
|
-
values << "|" << h['thirdplace']
|
174
|
-
values << "|" << h['final']
|
175
|
-
values << "|" << h['playoffs'] if h['playoffs'] # nb: allow empty/is optional!!
|
176
|
-
values
|
177
|
-
end
|
178
|
-
|
179
|
-
def regex_group_getter
|
180
|
-
## todo: escape for regex?
|
181
|
-
## NB: let's ignore case (that is, UPCASE,downcase); always use /i flag
|
182
|
-
/#{group}/i
|
183
|
-
end
|
184
|
-
|
185
|
-
def regex_round_getter
|
186
|
-
## todo: escape for regex?
|
187
|
-
## todo: sort by length - biggest words go first? does regex match biggest word automatically?? - check
|
188
|
-
## todo/fix: make - optional e.g. convert to ( |-) or better [ \-] ??
|
189
|
-
## NB: let's ignore case (that is, UPCASE,downcase); always use /i flag
|
190
|
-
/#{round}/i
|
191
|
-
end
|
192
|
-
|
193
|
-
def regex_knockout_round_getter
|
194
|
-
## todo: escape for regex?
|
195
|
-
## todo: sort by length - biggest words go first? does regex match biggest word automatically?? - check
|
196
|
-
## todo/fix: make - optional e.g. convert to ( |-) or better [ \-] ??
|
197
|
-
## NB: let's ignore case (that is, UPCASE,downcase); always use /i flag
|
198
|
-
/#{knockout_round}/i
|
199
|
-
end
|
200
|
-
|
201
|
-
def regex_leg1_getter
|
202
|
-
## todo: escape for regex?
|
203
|
-
## NB: let's ignore case (that is, UPCASE,downcase); always use /i flag
|
204
|
-
/#{leg1}/i
|
205
|
-
end
|
206
|
-
|
207
|
-
def regex_leg2_getter
|
208
|
-
## todo: escape for regex?
|
209
|
-
## NB: let's ignore case (that is, UPCASE,downcase); always use /i flag
|
210
|
-
/#{leg2}/i
|
211
|
-
end
|
212
|
-
|
213
|
-
end # class Lang
|
214
|
-
|
215
|
-
|
216
|
-
end # module SportDb
|
data/test/test_csv_reader.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
###
|
4
|
-
# to run use
|
5
|
-
# ruby -I ./lib -I ./test test/test_csv_reader.rb
|
6
|
-
|
7
|
-
|
8
|
-
require 'helper'
|
9
|
-
|
10
|
-
class TestCsvReader < MiniTest::Test
|
11
|
-
|
12
|
-
def setup
|
13
|
-
WorldDb.delete!
|
14
|
-
SportDb.delete!
|
15
|
-
SportDb.read_builtin
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_bl_2014
|
19
|
-
de = Country.create!( key: 'de', name: 'Deutschland', code: 'GER', pop: 1, area: 1 )
|
20
|
-
|
21
|
-
teamreader = TestTeamReader.from_file( 'de-deutschland/teams', country_id: de.id )
|
22
|
-
teamreader.read()
|
23
|
-
|
24
|
-
leaguereader = TestLeagueReader.from_file( 'de-deutschland/leagues', country_id: de.id )
|
25
|
-
leaguereader.read()
|
26
|
-
|
27
|
-
eventreader = TestEventReader.from_file( 'de-deutschland/2013-14/1-bundesliga' )
|
28
|
-
eventreader.read
|
29
|
-
|
30
|
-
assert true ## if we get here; assume everything ok
|
31
|
-
|
32
|
-
text = File.read_utf8( "#{SportDb.test_data_path}/csv/de-2013-14--1-bundesliga.txt" )
|
33
|
-
|
34
|
-
## bl = Event.find_by_key!( 'de.2013/14' )
|
35
|
-
|
36
|
-
r = SportDb::CsvGameReader.from_string( 'de.2013/14', text )
|
37
|
-
r.read
|
38
|
-
|
39
|
-
## assert_equal 10, bl.teams.count
|
40
|
-
## assert_equal 36, bl.rounds.count
|
41
|
-
## assert_equal 180, bl.games.count # 36x5 = 180
|
42
|
-
end
|
43
|
-
|
44
|
-
end # class TestCsvReader
|
45
|
-
|
data/test/test_date.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
###
|
4
|
-
# to run use
|
5
|
-
# ruby -I ./lib -I ./test test/test_date.rb
|
6
|
-
|
7
|
-
require 'helper'
|
8
|
-
|
9
|
-
class TestDate < MiniTest::Test
|
10
|
-
|
11
|
-
def test_date
|
12
|
-
data = [
|
13
|
-
[ '19.01.2013 22.00', '2013-01-19 22:00' ],
|
14
|
-
[ '21.01.2013 21.30', '2013-01-21 21:30' ],
|
15
|
-
[ '26.01.2013', '2013-01-26' ],
|
16
|
-
[ '[26.01.2013]', '2013-01-26' ],
|
17
|
-
[ '[21.1.]', '2013-01-21 12:00' ]
|
18
|
-
]
|
19
|
-
|
20
|
-
assert_dates( data, start_at: DateTime.new( 2013, 1, 1 ) )
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_date_fr
|
24
|
-
data = [
|
25
|
-
[ '[Ven 08. Août]', '2014-08-08' ],
|
26
|
-
[ 'Ven 08. Août', '2014-08-08' ],
|
27
|
-
[ 'Ven 8. Août', '2014-08-08' ],
|
28
|
-
[ '[Sam 9. Août]', '2014-08-09' ],
|
29
|
-
[ '[Dim 10. Août]', '2014-08-10' ],
|
30
|
-
[ '[Sam 31. Janv]', '2015-01-31' ],
|
31
|
-
[ '[Sam 7. Févr]', '2015-02-07' ],
|
32
|
-
[ '[Sam 31. Jan]', '2015-01-31' ],
|
33
|
-
[ '[Sam 7. Fév]', '2015-02-07' ],
|
34
|
-
]
|
35
|
-
|
36
|
-
assert_dates( data, start_at: DateTime.new( 2014, 8, 1 ) )
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_date_en
|
40
|
-
data = [
|
41
|
-
[ 'Jun/12 2011 14:00', '2011-06-12 14:00' ],
|
42
|
-
[ 'Oct/12 2013 16:00', '2013-10-12 16:00' ],
|
43
|
-
|
44
|
-
[ 'Jan/26 2011', '2011-01-26' ],
|
45
|
-
[ 'Jan/26 2011', '2011-01-26 12:00' ],
|
46
|
-
|
47
|
-
[ 'Jan/26', '2013-01-26' ],
|
48
|
-
[ 'Jan/26', '2013-01-26 12:00' ],
|
49
|
-
[ '26 January', '2013-01-26' ],
|
50
|
-
[ '26 January', '2013-01-26 12:00' ],
|
51
|
-
|
52
|
-
[ 'Jun/13', '2013-06-13' ],
|
53
|
-
[ 'Jun/13', '2013-06-13 12:00' ],
|
54
|
-
[ '13 June', '2013-06-13' ],
|
55
|
-
[ '13 June', '2013-06-13 12:00' ]
|
56
|
-
]
|
57
|
-
|
58
|
-
assert_dates( data, start_at: DateTime.new( 2013, 1, 1 ) )
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def assert_dates( data, opts )
|
65
|
-
data.each do |rec|
|
66
|
-
line = rec[0]
|
67
|
-
str = rec[1]
|
68
|
-
if str.index( ':' )
|
69
|
-
assert_datetime( DateTime.strptime( str, '%Y-%m-%d %H:%M' ), parse_date( line, opts ))
|
70
|
-
else
|
71
|
-
assert_date( DateTime.strptime( str, '%Y-%m-%d' ), parse_date( line, opts ))
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
## todo: check if assert_datetime or assert_date exist already? what is the best practice to check dates ???
|
77
|
-
def assert_date( exp, act )
|
78
|
-
assert_equal exp.year, act.year
|
79
|
-
assert_equal exp.month, act.month
|
80
|
-
assert_equal exp.day, act.day
|
81
|
-
end
|
82
|
-
|
83
|
-
def assert_time( exp, act )
|
84
|
-
assert_equal exp.hour, act.hour
|
85
|
-
assert_equal exp.min, act.min
|
86
|
-
end
|
87
|
-
|
88
|
-
def assert_datetime( exp, act )
|
89
|
-
assert_date( exp, act )
|
90
|
-
assert_time( exp, act )
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
def parse_date( line, opts={} )
|
95
|
-
# e.g. lets you pass in opts[:start_at] ???
|
96
|
-
finder = SportDb::DateFinder.new
|
97
|
-
finder.find!( line, opts )
|
98
|
-
end
|
99
|
-
|
100
|
-
end # class TestScores
|
data/test/test_lang.rb
DELETED
@@ -1,130 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
###
|
4
|
-
# to run use
|
5
|
-
# ruby -I ./lib -I ./test test/test_lang.rb
|
6
|
-
# or better
|
7
|
-
# rake -I ./lib test
|
8
|
-
|
9
|
-
require 'helper'
|
10
|
-
|
11
|
-
class TestLang < MiniTest::Test
|
12
|
-
|
13
|
-
def test_getters
|
14
|
-
|
15
|
-
lang = SportDb.lang
|
16
|
-
lang.lang = 'en'
|
17
|
-
|
18
|
-
group = 'Group'
|
19
|
-
|
20
|
-
round = 'Round|Matchday|Week'
|
21
|
-
round << '|Round of 32|Last 32'
|
22
|
-
round << '|Round of 16|Last 16|8th finals'
|
23
|
-
round << '|Quarterfinals|Quarter-finals|Quarters|Quarterfinal|Last 8'
|
24
|
-
round << '|Semifinals|Semi-finals|Semis|Last 4'
|
25
|
-
round << '|Fifth place match|Fifth place|5th place match|5th place final|5th place|Match for fifth place|Match for 5th place'
|
26
|
-
round << '|Third place match|Third-place match|Third place|3rd place match|3rd place final|3rd place|Match for third place|Match for 3rd place|Third-place play-off|Third place play-off'
|
27
|
-
round << '|Final|Finals'
|
28
|
-
round << '|Playoff|Playoffs|Play-off|Play-offs|Play-off for quarter-finals'
|
29
|
-
|
30
|
-
knockout_round = 'Round of 32|Last 32'
|
31
|
-
knockout_round << '|Round of 16|Last 16|8th finals'
|
32
|
-
knockout_round << '|Quarterfinals|Quarter-finals|Quarters|Quarterfinal|Last 8'
|
33
|
-
knockout_round << '|Semifinals|Semi-finals|Semis|Last 4'
|
34
|
-
knockout_round << '|Fifth place match|Fifth place|5th place match|5th place final|5th place|Match for fifth place|Match for 5th place'
|
35
|
-
knockout_round << '|Third place match|Third-place match|Third place|3rd place match|3rd place final|3rd place|Match for third place|Match for 3rd place|Third-place play-off|Third place play-off'
|
36
|
-
knockout_round << '|Final|Finals'
|
37
|
-
knockout_round << '|Playoff|Playoffs|Play-off|Play-offs|Play-off for quarter-finals'
|
38
|
-
|
39
|
-
assert_equal group, lang.group
|
40
|
-
assert_equal round, lang.round
|
41
|
-
assert_equal knockout_round, lang.knockout_round
|
42
|
-
|
43
|
-
# NB: call twice to test caching with ||=
|
44
|
-
assert_equal group, lang.group
|
45
|
-
assert_equal round, lang.round
|
46
|
-
assert_equal knockout_round, lang.knockout_round
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_getters_de
|
51
|
-
lang = SportDb.lang
|
52
|
-
lang.lang = 'de'
|
53
|
-
|
54
|
-
group = 'Gruppe'
|
55
|
-
|
56
|
-
round = 'Spieltag|Runde'
|
57
|
-
round << '|Sechzehntelfinale|1/16 Finale'
|
58
|
-
round << '|Achtelfinale|1/8 Finale'
|
59
|
-
round << '|Viertelfinale|1/4 Finale'
|
60
|
-
round << '|Halbfinale|Semifinale|1/2 Finale'
|
61
|
-
round << '|Spiel um Platz 5'
|
62
|
-
round << '|Spiel um Platz 3'
|
63
|
-
round << '|Finale|Endspiel'
|
64
|
-
|
65
|
-
knockout_round = 'Sechzehntelfinale|1/16 Finale'
|
66
|
-
knockout_round << '|Achtelfinale|1/8 Finale'
|
67
|
-
knockout_round << '|Viertelfinale|1/4 Finale'
|
68
|
-
knockout_round << '|Halbfinale|Semifinale|1/2 Finale'
|
69
|
-
knockout_round << '|Spiel um Platz 5'
|
70
|
-
knockout_round << '|Spiel um Platz 3'
|
71
|
-
knockout_round << '|Finale|Endspiel'
|
72
|
-
|
73
|
-
|
74
|
-
assert_equal group, lang.group
|
75
|
-
assert_equal round, lang.round
|
76
|
-
assert_equal knockout_round, lang.knockout_round
|
77
|
-
|
78
|
-
# NB: call twice to test caching with ||=
|
79
|
-
|
80
|
-
assert_equal group, lang.group
|
81
|
-
assert_equal round, lang.round
|
82
|
-
assert_equal knockout_round, lang.knockout_round
|
83
|
-
end
|
84
|
-
|
85
|
-
def test_regex_knockout_round
|
86
|
-
lang = SportDb.lang
|
87
|
-
lang.lang = 'en'
|
88
|
-
|
89
|
-
lines = [
|
90
|
-
'(4) Quarter-finals',
|
91
|
-
'(5) Semi-finals',
|
92
|
-
'(6) Final',
|
93
|
-
'(1) Play-off 1st Leg // 11–15 October',
|
94
|
-
'(2) Play-off 2nd Leg // 15-19 November',
|
95
|
-
'(1) Play-off for quarter-finals',
|
96
|
-
'(4) Match for fifth place',
|
97
|
-
'(5) Match for third place',
|
98
|
-
## check for ALL UPCASE too
|
99
|
-
'(4) QUARTER-FINALS',
|
100
|
-
'(5) SEMI-FINALS',
|
101
|
-
'(6) FINAL'
|
102
|
-
]
|
103
|
-
|
104
|
-
lines.each do |line|
|
105
|
-
assert( line =~ lang.regex_knockout_round )
|
106
|
-
end
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_regex_knockout_round_de
|
111
|
-
lang = SportDb.lang
|
112
|
-
lang.lang = 'de'
|
113
|
-
|
114
|
-
lines = [
|
115
|
-
'(1) Achtelfinale // Di+Mi 14.+15. & 21.+22. Feb 2012',
|
116
|
-
'(2) Achtelfinale Rückspiele // Di+Mi 6.+7. & 13.+14. März 2012',
|
117
|
-
'(3) Viertelfinale // Di+Mi 27.+28. März 2012',
|
118
|
-
'(4) Viertelfinale Rückspiele // Di+Mi 3.+4. April 2012',
|
119
|
-
'(5) Halbfinale // Di+Mi 17.+18. April 2012',
|
120
|
-
'(6) Halbfinale Rückspiele // Di+Mi 24.+25. April 2012',
|
121
|
-
'(7) Finale // Sa 19. Mai 2012'
|
122
|
-
]
|
123
|
-
|
124
|
-
lines.each do |line|
|
125
|
-
assert( line =~ lang.regex_knockout_round )
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
end # class TestLang
|