sportdb-readers 0.5.0 → 1.0.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.
@@ -2,130 +2,69 @@
2
2
  module SportDb
3
3
  class Package
4
4
 
5
- CONF_RE = Datafile::CONF_RE
6
- CLUB_PROPS_RE = Datafile::CLUB_PROPS_RE
7
- LEAGUES_RE = Datafile::LEAGUES_RE
8
- CLUBS_RE = Datafile::CLUBS_RE
9
-
10
-
11
- ## note: if pattern includes directory add here (otherwise move to more "generic" datafile) - why? why not?
12
- MATCH_RE = %r{ /(?: \d{4}-\d{2} ## season folder e.g. /2019-20
13
- | \d{4} ## season year-only folder e.g. /2019
14
- )
15
- /[a-z0-9_-]+\.txt$ ## txt e.g /1-premierleague.txt
16
- }x
17
-
18
-
19
- attr_reader :pack ## allow access to embedded ("low-level") delegate package
20
-
21
- def initialize( path_or_pack )
22
- if path_or_pack.is_a?( Datafile::Package )
23
- @pack = path_or_pack
24
- else ## assume it's a (string) path
25
- path = path_or_pack
26
- if !File.exist?( path ) ## file or directory
27
- puts "** !!! ERROR !!! file NOT found >#{path}<; cannot open package"
28
- exit 1
29
- end
30
-
31
- if File.directory?( path )
32
- @pack = Datafile::DirPackage.new( path ) ## delegate to "generic" package
33
- elsif File.file?( path ) && File.extname( path ) == '.zip' # note: includes dot (.) eg .zip
34
- @pack = Datafile::ZipPackage.new( path )
35
- else
36
- puts "** !!! ERROR !!! cannot open package - directory or file with .zip extension required"
37
- exit 1
38
- end
39
- end
40
- end
41
-
42
- def each_conf( &blk ) @pack.each( pattern: CONF_RE, &blk ); end
43
- def each_match( &blk ) @pack.each( pattern: MATCH_RE, &blk ); end
44
- def each_club_props( &blk ) @pack.each( pattern: CLUB_PROPS_RE, &blk ); end
45
-
46
- def each_leagues( &blk ) @pack.each( pattern: LEAGUES_RE, &blk ); end
47
- def each_clubs( &blk ) @pack.each( pattern: CLUBS_RE, &blk ); end
48
-
5
+ ## note: add readers here; for full class def see the sourcein sportdb-formats!!!
49
6
 
50
7
  def read_leagues
51
- each_leagues do |entry|
52
- SportDb.parse_leagues( entry.read )
53
- end
8
+ each_leagues { |entry| SportDb.parse_leagues( entry.read ) }
54
9
  end
55
10
 
56
11
  def read_clubs
57
- each_clubs do |entry|
58
- SportDb.parse_clubs( entry.read )
59
- end
12
+ each_clubs { |entry| SportDb.parse_clubs( entry.read ) }
60
13
  end
61
14
 
62
-
63
- def read_club_props( sync: true ) ## todo/fix: remove sync!! - why? why not?
64
- each_club_props do |entry|
65
- SportDb.parse_club_props( entry.read, sync: sync )
66
- end
15
+ def read_club_props
16
+ each_club_props { |entry| SportDb.parse_club_props( entry.read ) }
67
17
  end
68
18
 
69
- def read_conf( *names,
70
- season: nil, sync: true )
19
+
20
+ def read_conf( *names, season: nil )
71
21
  if names.empty? ## no (entry) names passed in; read in all
72
22
  each_conf do |entry|
73
- SportDb.parse_conf( entry.read, season: season, sync: sync )
23
+ SportDb.parse_conf( entry.read, season: season )
74
24
  end
75
25
  else
76
26
  names.each do |name|
77
27
  entry = @pack.find( name )
78
- SportDb.parse_conf( entry.read, season: season, sync: sync )
28
+ SportDb.parse_conf( entry.read, season: season )
79
29
  end
80
30
  end
81
31
  end
82
32
 
83
- def read_match( *names,
84
- season: nil, sync: true )
33
+ def read_match( *names, season: nil )
85
34
  if names.empty? ## no (entry) names passed in; read in all
86
35
  each_match do |entry|
87
- SportDb.parse_match( entry.read, season: season, sync: sync )
36
+ SportDb.parse_match( entry.read, season: season )
88
37
  end
89
38
  else
90
39
  names.each do |name|
91
40
  entry = @pack.find( name )
92
- SportDb.parse_match( entry.read, season: season, sync: sync )
41
+ SportDb.parse_match( entry.read, season: season )
93
42
  end
94
43
  end
95
44
  end
96
45
 
97
46
 
98
- def read( *names,
99
- season: nil, sync: true )
47
+ def read( *names, season: nil )
100
48
  if names.empty? ## read all datafiles
101
49
  read_leagues()
102
50
  read_clubs()
103
- read_club_props( sync: sync ) ## todo/fix: remove sync - why? why not?
104
- read_conf( season: season, sync: sync )
105
- read_match( season: season, sync: sync )
51
+ read_club_props()
52
+ read_conf( season: season )
53
+ read_match( season: season )
106
54
  else
107
55
  names.each do |name|
108
56
  entry = @pack.find( name )
109
57
  ## fix/todo: add read_leagues, read_clubs too!!!
110
- if Datafile.match_conf( name ) ## check if datafile matches conf(iguration) naming (e.g. .conf.txt)
111
- SportDb.parse_conf( entry.read, season: season, sync: sync )
112
- elsif Datafile.match_club_props( name )
113
- SportDb.parse_club_props( entry.read, sync: sync )
114
- else ## assume "regular" match datafile
115
- SportDb.parse_match( entry.read, season: season, sync: sync )
58
+ if match_conf?( name ) ## check if datafile matches conf(iguration) naming (e.g. .conf.txt)
59
+ SportDb.parse_conf( entry.read, season: season )
60
+ elsif match_club_props?( name )
61
+ SportDb.parse_club_props( entry.read )
62
+ else ## assume "regular" match datafile or check pattern and report error on fail - why? why not?
63
+ SportDb.parse_match( entry.read, season: season )
116
64
  end
117
65
  end
118
66
  end
119
67
  end
120
68
  end # class Package
121
69
 
122
-
123
- class DirPackage < Package
124
- def initialize( path ) super( Datafile::DirPackage.new( path ) ); end
125
- end
126
-
127
- class ZipPackage < Package
128
- def initialize( path ) super( Datafile::ZipPackage.new( path ) ); end
129
- end
130
-
131
70
  end # module SportDb
@@ -4,8 +4,8 @@
4
4
  module SportDb
5
5
  module Readers
6
6
 
7
- MAJOR = 0 ## todo: namespace inside version or something - why? why not??
8
- MINOR = 5
7
+ MAJOR = 1 ## todo: namespace inside version or something - why? why not??
8
+ MINOR = 0
9
9
  PATCH = 0
10
10
  VERSION = [MAJOR,MINOR,PATCH].join('.')
11
11
 
data/test/helper.rb CHANGED
@@ -1,19 +1,23 @@
1
- ## $:.unshift(File.dirname(__FILE__))
1
+ ## note: use the local version of sportdb gems
2
+ $LOAD_PATH.unshift( File.expand_path( '../sportdb-formats/lib' ))
3
+ $LOAD_PATH.unshift( File.expand_path( '../sportdb-config/lib' ))
4
+ $LOAD_PATH.unshift( File.expand_path( '../sportdb-models/lib' ))
5
+ $LOAD_PATH.unshift( File.expand_path( '../sportdb-sync/lib' ))
6
+
2
7
 
3
8
  ## minitest setup
4
9
  require 'minitest/autorun'
5
10
 
6
11
 
7
- ## note: use the local version of sportdb gems
8
- $LOAD_PATH.unshift( File.expand_path( '../sportdb-match-formats/lib' ))
9
-
10
12
 
11
13
  ## our own code
12
14
  require 'sportdb/readers'
13
15
 
14
-
15
-
16
-
17
16
  ## use (switch to) "external" datasets
18
17
  SportDb::Import.config.leagues_dir = "../../../openfootball/leagues"
19
18
  SportDb::Import.config.clubs_dir = "../../../openfootball/clubs"
19
+
20
+
21
+ COUNTRIES = SportDb::Import.catalog.countries
22
+ LEAGUES = SportDb::Import.catalog.leagues
23
+ CLUBS = SportDb::Import.catalog.clubs
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_conf_reader.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+
11
+ class TestConfReader < MiniTest::Test
12
+
13
+ def setup
14
+ SportDb.connect( adapter: 'sqlite3',
15
+ database: ':memory:' )
16
+ SportDb.create_all ## build schema
17
+
18
+ ## turn on logging to console
19
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
20
+ end
21
+
22
+ def test_read
23
+ # path = "../../../openfootball/austria/2018-19/.conf.txt"
24
+ path = "../../../openfootball/england/2015-16/.conf.txt"
25
+ # path = "../../../openfootball/england/2017-18/.conf.txt"
26
+ # path = "../../../openfootball/england/2018-19/.conf.txt"
27
+ # path = "../../../openfootball/england/2019-20/.conf.txt"
28
+ SportDb::ConfReaderV2.read( path )
29
+ end # method test_read
30
+
31
+
32
+ def test_read_champs
33
+ txt =<<TXT
34
+ = UEFA Champions League 2017/18
35
+
36
+ Manchester United › ENG
37
+ Liverpool › ENG
38
+ Chelsea › ENG
39
+ Manchester City › ENG
40
+ Tottenham Hotspur › ENG
41
+
42
+ Atlético Madrid › ESP
43
+ Barcelona › ESP
44
+ Sevilla › ESP
45
+ Real Madrid › ESP
46
+
47
+ Roma › ITA
48
+ Juventus › ITA
49
+ Napoli › ITA
50
+
51
+ Bayern München › GER
52
+ Borussia Dortmund › GER
53
+ RB Leipzig › GER
54
+
55
+ Benfica › POR
56
+ Sporting CP › POR
57
+ Porto › POR
58
+
59
+ CSKA Moscow › RUS
60
+ Spartak Moscow › RUS
61
+
62
+ Paris Saint-Germain › FRA
63
+ Basel › SUI
64
+ Celtic › SCO
65
+ Anderlecht › BEL
66
+ Qarabağ › AZE
67
+ Olympiacos › GRE
68
+ Maribor › SVN
69
+ Shakhtar Donetsk › UKR
70
+ Feyenoord › NED
71
+ Beşiktaş › TUR
72
+ Monaco › MCO
73
+ APOEL › CYP
74
+ TXT
75
+
76
+ SportDb::ConfReaderV2.parse( txt )
77
+ end
78
+ end # class TestConfReader
@@ -0,0 +1,487 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_match_reader_champs.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+
11
+ class TestMatchReaderChamps < MiniTest::Test
12
+
13
+ def setup
14
+ SportDb.connect( adapter: 'sqlite3',
15
+ database: ':memory:' )
16
+ SportDb.create_all ## build schema
17
+
18
+ ## turn on logging to console
19
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
20
+ end
21
+
22
+
23
+ def test_read_group
24
+ txt = <<TXT
25
+ = UEFA Champions League 2017/18
26
+
27
+ Group A | Manchester United Basel CSKA Moscow Benfica
28
+ Group B | Paris Saint-Germain Bayern München Celtic Anderlecht
29
+ Group C | Roma Chelsea Atlético Madrid Qarabağ
30
+ Group D | Barcelona Juventus Sporting CP Olympiacos
31
+ Group E | Liverpool Sevilla Spartak Moscow Maribor
32
+ Group F | Manchester City Shakhtar Donetsk Napoli Feyenoord
33
+ Group G | Beşiktaş Porto RB Leipzig Monaco
34
+ Group H | Tottenham Hotspur Real Madrid Borussia Dortmund APOEL
35
+
36
+
37
+
38
+ Matchday 1 | Sep/12 - Sep/13 ## Tu+We 12-13 September 2017
39
+ Matchday 2 | Sep/26 - Sep/27 ## Tu+We 26-27 September 2017
40
+ Matchday 3 | Oct/17 - Oct/18 ## Tu+We 17-18 October 2017
41
+ Matchday 4 | Oct/31 - Nov/1 ## Tu+We 31 October - 1 November 2017
42
+ Matchday 5 | Nov/21 - Nov/22 ## Tu+We 21-22 November 2017
43
+ Matchday 6 | Dec/5 - Dec/6 ## Tu+We 5-6 December 2017
44
+
45
+
46
+
47
+ Group A:
48
+
49
+ [Tue Sep/12]
50
+ 20.45 Benfica 1-2 CSKA Moscow @ Estádio da Luz, Lisbon
51
+ [Seferović 50'; Vitinho 63' (pen.) Zhamaletdinov 71']
52
+ 20.45 Manchester United 3-0 Basel @ Old Trafford, Manchester
53
+ [Fellaini 35' Lukaku 53' Rashford 84']
54
+
55
+ [Wed Sep/27]
56
+ 20.45 Basel 5-0 Benfica @ St. Jakob-Park, Basel
57
+ [Lang 2' Oberlin 20', 69' Van Wolfswinkel 60' (pen.) Riveros 76']
58
+ 20.45 CSKA Moscow 1-4 Manchester United @ VEB Arena, Moscow
59
+ [Kuchayev 90'; Lukaku 4', 27' Martial 19' (pen.) Mkhitaryan 57']
60
+
61
+ [Wed Oct/18]
62
+ 20.45 CSKA Moscow 0-2 Basel @ VEB Arena, Moscow
63
+ [-; Xhaka 29' Oberlin 90']
64
+ 20.45 Benfica 0-1 Manchester United @ Estádio da Luz, Lisbon
65
+ [-; Rashford 64']
66
+
67
+ [Tue Oct/31]
68
+ 20.45 Basel 1-2 CSKA Moscow @ St. Jakob-Park, Basel
69
+ [Zuffi 32'; Dzagoev 65' Wernbloom 79']
70
+ 20.45 Manchester United 2-0 Benfica @ Old Trafford, Manchester
71
+ [Svilar 45' (o.g.) Blind 78' (pen.)]
72
+
73
+ [Wed Nov/22]
74
+ 18.00 CSKA Moscow 2-0 Benfica @ VEB Arena, Moscow
75
+ [Shchennikov 13' Jardel 56' (o.g.)]
76
+ 20.45 Basel 1-0 Manchester United @ St. Jakob-Park, Basel
77
+ [Lang 89']
78
+
79
+ [Tue Dec/5]
80
+ 20.45 Benfica 0-2 Basel @ Estádio da Luz, Lisbon
81
+ [-; Elyounoussi 5' Oberlin 65']
82
+ 20.45 Manchester United 2-1 CSKA Moscow @ Old Trafford, Manchester
83
+ [Lukaku 64' Rashford 66'; Vitinho 45']
84
+
85
+
86
+
87
+ Group B:
88
+
89
+ [Tue Sep/12]
90
+ 20.45 Bayern München 3-0 Anderlecht @ Allianz Arena, München
91
+ [Lewandowski 12' (pen.) Thiago 65' Kimmich 90']
92
+ 20.45 Celtic 0-5 Paris Saint-Germain @ Celtic Park, Glasgow
93
+ [-; Neymar 19' Mbappé 34' Cavani 40' (pen.), 85' Lustig 83' (o.g.)]
94
+
95
+ [Wed Sep/27]
96
+ 20.45 Paris Saint-Germain 3-0 Bayern München @ Parc des Princes, Paris
97
+ [Dani Alves 2' Cavani 31' Neymar 63']
98
+ 20.45 Anderlecht 0-3 Celtic @ Constant Vanden Stock Stadium, Anderlecht
99
+ [-; Griffiths 38' Roberts 50' Sinclair 90+3']
100
+
101
+ [Wed Oct/18]
102
+ 20.45 Anderlecht 0-4 Paris Saint-Germain @ Constant Vanden Stock Stadium, Anderlecht
103
+ [-; Mbappé 3' Cavani 44' Neymar 66' Di María 88']
104
+ 20.45 Bayern München 3-0 Celtic @ Allianz Arena, München
105
+ [Müller 17' Kimmich 29' Hummels 51']
106
+
107
+ [Tue Oct/31]
108
+ 20.45 Paris Saint-Germain 5-0 Anderlecht @ Parc des Princes, Paris
109
+ [Verratti 30' Neymar 45+4' Kurzawa 52', 72', 78']
110
+ 20.45 Celtic 1-2 Bayern München @ Celtic Park, Glasgow
111
+ [McGregor 74'; Coman 22' Martínez 77']
112
+
113
+ [Wed Nov/22]
114
+ 20.45 Anderlecht 1-2 Bayern München @ Constant Vanden Stock Stadium, Anderlecht
115
+ [Hanni 63'; Lewandowski 51' Tolisso 77']
116
+ 20.45 Paris Saint-Germain 7-1 Celtic @ Parc des Princes, Paris
117
+ [Neymar 9', 22' Cavani 28', 79' Mbappé 35' Verratti 75' Dani Alves 80'; Dembélé 1']
118
+
119
+ [Tue Dec/5]
120
+ 20.45 Bayern München 3-1 Paris Saint-Germain @ Allianz Arena, München
121
+ [Lewandowski 8' Tolisso 37', 69'; Mbappé 50']
122
+ 20.45 Celtic 0-1 Anderlecht @ Celtic Park, Glasgow
123
+ [-; Šimunović 62' (o.g.)]
124
+
125
+
126
+ Group C:
127
+
128
+ [Tue Sep/12]
129
+ 20.45 Chelsea 6-0 Qarabağ @ Stamford Bridge, London
130
+ [Pedro 5' Zappacosta 30' Azpilicueta 55' Bakayoko 71' Batshuayi 76' Medvedev 82' (o.g.)]
131
+ 20.45 Roma 0-0 Atlético Madrid @ Stadio Olimpico, Rome
132
+
133
+ [Wed Sep/27]
134
+ 18.00 Qarabağ 1-2 Roma @ Olympic Stadium, Baku [A]
135
+ [Pedro Henrique 28'; Manolas 7' Džeko 15']
136
+ 20.45 Atlético Madrid 1-2 Chelsea @ Wanda Metropolitano, Madrid
137
+ [Griezmann 40' (pen.); Morata 60' Batshuayi 90+3']
138
+
139
+ [Wed Oct/18]
140
+ 18.00 Qarabağ 0-0 Atlético Madrid @ Olympic Stadium, Baku [A]
141
+ 20.45 Chelsea 3-3 Roma @ Stamford Bridge, London
142
+ [David Luiz 11' Hazard 37', 75'; Kolarov 40' Džeko 64', 70']
143
+
144
+ [Tue Oct/31]
145
+ 20.45 Atlético Madrid 1-1 Qarabağ @ Wanda Metropolitano, Madrid
146
+ [Partey 56'; Míchel 40']
147
+ 20.45 Roma 3-0 Chelsea @ Stadio Olimpico, Rome
148
+ [El Shaarawy 1', 36' Perotti 63']
149
+
150
+ [Wed Nov/22]
151
+ 18.00 Qarabağ 0-4 Chelsea @ Olympic Stadium, Baku [A]
152
+ [-; Hazard 21' (pen.) Willian 36', 85' Fàbregas 73' (pen.)]
153
+ 20.45 Atlético Madrid 2-0 Roma @ Wanda Metropolitano, Madrid
154
+ [Griezmann 69' Gameiro 85']
155
+
156
+ [Tue Dec/5]
157
+ 20.45 Chelsea 1-1 Atlético Madrid @ Stamford Bridge, London
158
+ [Savić 75' (o.g.); Saúl 56']
159
+ 20.45 Roma 1-0 Qarabağ @ Stadio Olimpico, Rome
160
+ [Perotti 53']
161
+
162
+ ###
163
+ # [^A]: Qarabağ played their home matches at Olympic Stadium, Baku,
164
+ # instead of their regular stadium Azersun Arena, Baku.
165
+
166
+
167
+
168
+ Group D:
169
+
170
+ [Tue Sep/12]
171
+ 20.45 Barcelona 3-0 Juventus @ Camp Nou, Barcelona
172
+ [Messi 45', 69' Rakitić 56']
173
+ 20.45 Olympiacos 2-3 Sporting CP @ Karaiskakis Stadium, Piraeus
174
+ [Pardo 89', 90+3'; Doumbia 2' Gelson M. 13' Fernandes 43']
175
+
176
+ [Wed Sep/27]
177
+ 20.45 Sporting CP 0-1 Barcelona @ Estádio José Alvalade, Lisbon
178
+ [-; Coates 49' (o.g.)]
179
+ 20.45 Juventus 2-0 Olympiacos @ Juventus Stadium, Turin
180
+ [Higuaín 69' Mandžukić 80']
181
+
182
+ [Wed Oct/18]
183
+ 20.45 Juventus 2-1 Sporting CP @ Juventus Stadium, Turin
184
+ [Pjanić 29' Mandžukić 84'; Alex Sandro 12' (o.g.)]
185
+ 20.45 Barcelona 3-1 Olympiacos @ Camp Nou, Barcelona
186
+ [Nikolaou 18' (o.g.) Messi 61' Digne 64'; Nikolaou 90']
187
+
188
+ [Tue Oct/31]
189
+ 20.45 Sporting CP 1-1 Juventus @ Estádio José Alvalade, Lisbon
190
+ [Bruno César 20'; Higuaín 79']
191
+ 20.45 Olympiacos 0-0 Barcelona @ Karaiskakis Stadium, Piraeus
192
+
193
+ [Wed Nov/22]
194
+ 20.45 Juventus 0-0 Barcelona @ Juventus Stadium, Turin
195
+ 20.45 Sporting CP 3-1 Olympiacos @ Estádio José Alvalade, Lisbon
196
+ [Dost 40', 66' Bruno César 43'; Odjidja-Ofoe 86']
197
+
198
+ [Tue Dec/5]
199
+ 20.45 Barcelona 2-0 Sporting CP @ Camp Nou, Barcelona
200
+ [Alcácer 59' Mathieu 90+1' (o.g.)]
201
+ 20.45 Olympiacos 0-2 Juventus @ Karaiskakis Stadium, Piraeus
202
+ [-; Cuadrado 15' Bernardeschi 90']
203
+
204
+
205
+ Group E:
206
+
207
+ [Wed Sep/13]
208
+ 20.45 Maribor 1-1 Spartak Moscow @ Ljudski vrt, Maribor
209
+ [Bohar 85'; Samedov 59']
210
+ 20.45 Liverpool 2-2 Sevilla @ Anfield, Liverpool
211
+ [Firmino 21' Salah 37'; Ben Yedder 5' Correa 72']
212
+
213
+ [Tue Sep/26]
214
+ 20.45 Sevilla 3-0 Maribor @ Ramón Sánchez Pizjuán, Seville
215
+ [Ben Yedder 27', 38', 83' (pen.)]
216
+ 20.45 Spartak Moscow 1-1 Liverpool @ Otkritie Arena, Moscow
217
+ [Fernando 23'; Coutinho 31']
218
+
219
+ [Tue Oct/17]
220
+ 20.45 Spartak Moscow 5-1 Sevilla @ Otkritie Arena, Moscow
221
+ [Promes 18', 90' Melgarejo 58' Glushakov 67' Luiz Adriano 74'; Kjær 30']
222
+ 20.45 Maribor 0-7 Liverpool @ Ljudski vrt, Maribor
223
+ [-; Firmino 4', 54' Coutinho 13' Salah 19', 40' Oxlade-Chamberlain 86' Alexander-Arnold 90']
224
+
225
+ [Wed Nov/1]
226
+ 20.45 Sevilla 2-1 Spartak Moscow @ Ramón Sánchez Pizjuán, Seville
227
+ [Lenglet 30' Banega 59'; Zé Luís 78']
228
+ 20.45 Liverpool 3-0 Maribor @ Anfield, Liverpool
229
+ [Salah 49' Can 64' Sturridge 90']
230
+
231
+ [Tue Nov/21]
232
+ 18.00 Spartak Moscow 1-1 Maribor @ Otkritie Arena, Moscow
233
+ [Zé Luís 82'; Mešanović 90+2']
234
+ 20.45 Sevilla 3-3 Liverpool @ Ramón Sánchez Pizjuán, Seville
235
+ [Ben Yedder 51', 60' (pen.) Pizarro 90+3'; Firmino 2', 30' Mané 22']
236
+
237
+ [Wed Dec/6]
238
+ 20.45 Maribor 1-1 Sevilla @ Ljudski vrt, Maribor
239
+ [Tavares 10'; Ganso 75']
240
+ 20.45 Liverpool 7-0 Spartak Moscow @ Anfield, Liverpool
241
+ [Coutinho 4' (pen.), 15', 50' Firmino 19' Mané 47', 76' Salah 86']
242
+
243
+
244
+ Group F:
245
+
246
+ [Wed Sep/13]
247
+ 20.45 Feyenoord 0-4 Manchester City @ De Kuip, Rotterdam
248
+ [-; Stones 2', 63' Agüero 10' Gabriel Jesus 25']
249
+ 20.45 Shakhtar Donetsk 2-1 Napoli @ Metalist Stadium, Kharkiv [B]
250
+ [Taison 15' Ferreyra 58'; Milik 72' (pen.)]
251
+
252
+ [Tue Sep/26]
253
+ 20.45 Napoli 3-1 Feyenoord @ Stadio San Paolo, Naples
254
+ [Insigne 7' Mertens 49' Callejón 70'; Amrabat 90+3']
255
+ 20.45 Manchester City 2-0 Shakhtar Donetsk @ City of Manchester Stadium, Manchester
256
+ [De Bruyne 48' Sterling 90']
257
+
258
+ [Tue Oct/17]
259
+ 20.45 Manchester City 2-1 Napoli @ City of Manchester Stadium, Manchester
260
+ [Sterling 9' Gabriel Jesus 13'; Diawara 73' (pen.)]
261
+ 20.45 Feyenoord 1-2 Shakhtar Donetsk @ De Kuip, Rotterdam
262
+ [Berghuis 8'; Bernard 24', 54']
263
+
264
+ [Wed Nov/1]
265
+ 20.45 Napoli 2-4 Manchester City @ Stadio San Paolo, Naples
266
+ [Insigne 21' Jorginho 62' (pen.); Otamendi 34' Stones 48' Agüero 69' Sterling 90+2']
267
+ 20.45 Shakhtar Donetsk 3-1 Feyenoord @ Metalist Stadium, Kharkiv [B]
268
+ [Ferreyra 14' Marlos 17', 68'; Jørgensen 12']
269
+
270
+ [Tue Nov/21]
271
+ 20.45 Manchester City 1-0 Feyenoord @ City of Manchester Stadium, Manchester
272
+ [Sterling 88']
273
+ 20.45 Napoli 3-0 Shakhtar Donetsk @ Stadio San Paolo, Naples
274
+ [Insigne 56' Zieliński 81' Mertens 83']
275
+
276
+ [Wed Dec/6]
277
+ 20.45 Feyenoord 2-1 Napoli @ De Kuip, Rotterdam
278
+ [Jørgensen 33' St. Juste 90+1'; Zieliński 2']
279
+ 20.45 Shakhtar Donetsk 2-1 Manchester City @ Metalist Stadium, Kharkiv [B]
280
+ [Bernard 26' Ismaily 32'; Agüero 90+2' (pen.)]
281
+
282
+ ###
283
+ # [^B]: Shakhtar Donetsk played their home matches at Metalist Stadium, Kharkiv,
284
+ # instead of their regular stadium Donbass Arena, Donetsk,
285
+ # due to the war conditions in Eastern Ukraine.
286
+
287
+
288
+ Group G:
289
+
290
+ [Wed Sep/13]
291
+ 20.45 RB Leipzig 1-1 Monaco @ Red Bull Arena, Leipzig
292
+ [Forsberg 33'; Tielemans 34']
293
+ 20.45 Porto 1-3 Beşiktaş @ Estádio do Dragão, Porto
294
+ [Tošić 21' (o.g.); Talisca 13' Tosun 28' Babel 86']
295
+
296
+ [Tue Sep/26]
297
+ 20.45 Beşiktaş 2-0 RB Leipzig @ Vodafone Park, Istanbul
298
+ [Babel 11' Talisca 43']
299
+ 20.45 Monaco 0-3 Porto @ Stade Louis II, Monaco
300
+ [-; Aboubakar 31', 69' Layún 89']
301
+
302
+ [Tue Oct/17]
303
+ 20.45 Monaco 1-2 Beşiktaş @ Stade Louis II, Monaco
304
+ [Falcao 30'; Tosun 34', 54']
305
+ 20.45 RB Leipzig 3-2 Porto @ Red Bull Arena, Leipzig
306
+ [Orban 8' Forsberg 38' Augustin 41'; Aboubakar 18' Marcano 44']
307
+
308
+ [Wed Nov/1]
309
+ 18.00 Beşiktaş 1-1 Monaco @ Vodafone Park, Istanbul
310
+ [Tosun 54' (pen.); Lopes 45+1']
311
+ 20.45 Porto 3-1 RB Leipzig @ Estádio do Dragão, Porto
312
+ [Herrera 13' Danilo 61' Pereira 90+3'; Werner 48']
313
+
314
+ [Tue Nov/21]
315
+ 18.00 Beşiktaş 1-1 Porto @ Vodafone Park, Istanbul
316
+ [Talisca 41'; Felipe 29']
317
+ 20.45 Monaco 1-4 RB Leipzig @ Stade Louis II, Monaco
318
+ [Falcao 43'; Jemerson 6' (o.g.) Werner 9', 31' (pen.) Keïta 45']
319
+
320
+ [Wed Dec/6]
321
+ 20.45 RB Leipzig 1-2 Beşiktaş @ Red Bull Arena, Leipzig
322
+ [Keïta 87'; Negredo 10' (pen.) Talisca 90']
323
+ 20.45 Porto 5-2 Monaco @ Estádio do Dragão, Porto
324
+ [Aboubakar 9', 33' Brahimi 45' Alex Telles 65' Soares 88'; Glik 61' (pen.) Falcao 78']
325
+
326
+
327
+ Group H:
328
+
329
+ [Wed Sep/13]
330
+ 20.45 Real Madrid 3-0 APOEL @ Santiago Bernabéu, Madrid
331
+ [Ronaldo 12', 51' (pen.) Ramos 61']
332
+ 20.45 Tottenham Hotspur 3-1 Borussia Dortmund @ Wembley Stadium, London
333
+ [Son Heung-min 4' Kane 15', 60'; Yarmolenko 11']
334
+
335
+ [Tue Sep/26]
336
+ 20.45 Borussia Dortmund 1-3 Real Madrid @ Westfalenstadion, Dortmund
337
+ [Aubameyang 54'; Bale 18' Ronaldo 50', 79']
338
+ 20.45 APOEL 0-3 Tottenham Hotspur @ GSP Stadium, Nicosia
339
+ [-; Kane 39', 62', 67']
340
+
341
+ [Tue Oct/17]
342
+ 20.45 APOEL 1-1 Borussia Dortmund @ GSP Stadium, Nicosia
343
+ [Poté 62'; Papastathopoulos 67']
344
+ 20.45 Real Madrid 1-1 Tottenham Hotspur @ Santiago Bernabéu, Madrid
345
+ [Ronaldo 43' (pen.); Varane 28' (o.g.)]
346
+
347
+ [Wed Nov/1]
348
+ 20.45 Borussia Dortmund 1-1 APOEL @ Westfalenstadion, Dortmund
349
+ [Guerreiro 29'; Poté 51']
350
+ 20.45 Tottenham Hotspur 3-1 Real Madrid @ Wembley Stadium, London
351
+ [Alli 27', 56' Eriksen 65'; Ronaldo 80']
352
+
353
+ [Tue Nov/21]
354
+ 20.45 APOEL 0-6 Real Madrid @ GSP Stadium, Nicosia
355
+ [-; Modrić 23' Benzema 39', 45+1' Nacho 41' Ronaldo 49', 54']
356
+ 20.45 Borussia Dortmund 1-2 Tottenham Hotspur @ Westfalenstadion, Dortmund
357
+ [Aubameyang 31'; Kane 49' Son Heung-min 76']
358
+
359
+ [Wed Dec/6]
360
+ 20.45 Real Madrid 3-2 Borussia Dortmund @ Santiago Bernabéu, Madrid
361
+ [Mayoral 8' Ronaldo 12' Vázquez 81'; Aubameyang 43', 49']
362
+ 20.45 Tottenham Hotspur 3-0 APOEL @ Wembley Stadium, London
363
+ [Llorente 20' Son Heung-min 37' N'Koudou 80']
364
+ TXT
365
+
366
+ SportDb::MatchReaderV2.parse( txt )
367
+ end
368
+
369
+ def test_read_finals
370
+ txt =<<TXT
371
+ = UEFA Champions League 2017/18
372
+
373
+ Round of 16 - 1st Leg
374
+
375
+ [Tue Feb/13]
376
+ 20.45 Juventus 2-2 Tottenham Hotspur @ Juventus Stadium, Turin
377
+ [Higuaín 2', 9' (pen.); Kane 35' Eriksen 71']
378
+ 20.45 Basel 0-4 Manchester City @ St. Jakob-Park, Basel
379
+ [-; Gündoğan 14', 53' B. Silva 18' Agüero 23']
380
+
381
+ [Wed Feb/14]
382
+ 20.45 Porto 0-5 Liverpool @ Estádio do Dragão, Porto
383
+ [-; Mané 25', 53', 85' Salah 29' Firmino 69']
384
+ 20.45 Real Madrid 3-1 Paris Saint-Germain @ Santiago Bernabéu, Madrid
385
+ [Ronaldo 45' (pen.), 83' Marcelo 86'; Rabiot 33']
386
+
387
+ [Tue Feb/20]
388
+ 20.45 Bayern München 5-0 Beşiktaş @ Allianz Arena, München
389
+ [Müller 43', 66' Coman 53' Lewandowski 79', 88']
390
+ 20.45 Chelsea 1-1 Barcelona @ Stamford Bridge, London
391
+ [Willian 62'; Messi 75']
392
+
393
+ [Wed Feb/21]
394
+ 20.45 Shakhtar Donetsk 2-1 Roma @ Metalist Stadium, Kharkiv [†]
395
+ [Ferreyra 52' Fred 71'; Ünder 41']
396
+ 20.45 Sevilla 0-0 Manchester United @ Ramón Sánchez Pizjuán, Seville
397
+
398
+
399
+ Round of 16 - 2nd Leg
400
+
401
+ [Tue Mar/6]
402
+ 20.45 Liverpool 0-0 Porto @ Anfield, Liverpool
403
+ 20.45 Paris Saint-Germain 1-2 Real Madrid @ Parc des Princes, Paris
404
+ [Cavani 71'; Ronaldo 51' Casemiro 80']
405
+
406
+ [Wed Mar/7]
407
+ 20.45 Manchester City 1-2 Basel @ City of Manchester Stadium, Manchester
408
+ [Gabriel Jesus 8'; Elyounoussi 17' Lang 71']
409
+ 20.45 Tottenham Hotspur 1-2 Juventus @ Wembley Stadium, London
410
+ [Son Heung-min 39'; Higuaín 64' Dybala 67']
411
+
412
+ [Tue Mar/13]
413
+ 20.45 Roma 1-0 Shakhtar Donetsk @ Stadio Olimpico, Rome
414
+ [Džeko 52']
415
+ 20.45 Manchester United 1-2 Sevilla @ Old Trafford, Manchester
416
+ [Lukaku 84'; Ben Yedder 74', 78']
417
+
418
+ [Wed Mar/14]
419
+ 20.45 Barcelona 3-0 Chelsea @ Camp Nou, Barcelona
420
+ [Messi 3', 63' Dembélé 20']
421
+ 18.00 Beşiktaş 1-3 Bayern München @ Vodafone Park, Istanbul
422
+ [Vágner Love 59'; Thiago 18' Gönül 46' (o.g.) Wagner 84']
423
+
424
+
425
+ Quarter-finals - 1st Leg
426
+
427
+ [Tue Apr/3]
428
+ 20.45 Juventus 0-3 Real Madrid @ Juventus Stadium, Turin
429
+ [-; Ronaldo 3', 64' Marcelo 72']
430
+ 20.45 Sevilla 1-2 Bayern München @ Ramón Sánchez Pizjuán, Seville
431
+ [Sarabia 31'; Navas 37' (o.g.) Thiago 68']
432
+
433
+ [Wed Apr/4]
434
+ 20.45 Barcelona 4-1 Roma @ Camp Nou, Barcelona
435
+ [De Rossi 38' (o.g.) Manolas 55' (o.g.) Piqué 59' L. Suárez 87'; Džeko 80']
436
+ 20.45 Liverpool 3-0 Manchester City @ Anfield, Liverpool
437
+ [Salah 12' Oxlade-Chamberlain 21' Mané 31']
438
+
439
+
440
+ Quarter-finals - 2nd Leg
441
+
442
+ [Tue Apr/10]
443
+ 20.45 Roma 3-0 Barcelona @ Stadio Olimpico, Rome
444
+ [Džeko 6' De Rossi 58' (pen.) Manolas 82']
445
+ 20.45 Manchester City 1-2 Liverpool @ City of Manchester Stadium, Manchester
446
+ [Gabriel Jesus 2'; Salah 56' Firmino 77']
447
+
448
+ [Wed Apr/11]
449
+ 20.45 Real Madrid 1-3 Juventus @ Santiago Bernabéu, Madrid
450
+ [Ronaldo 90+8' (pen.); Mandžukić 2', 37' Matuidi 61']
451
+ 20.45 Bayern München 0-0 Sevilla @ Allianz Arena, München
452
+
453
+
454
+
455
+ Semi-finals - 1st Leg
456
+
457
+ [Tue Apr/24]
458
+ 20.45 Liverpool 5-2 Roma @ Anfield, Liverpool
459
+ [Salah 36', 45+1' Mané 56' Firmino 61', 69'; Džeko 81' Perotti 85' (pen.)]
460
+
461
+ [Wed Apr/25]
462
+ 20.45 Bayern München 1-2 Real Madrid @ Allianz Arena, München
463
+ [Kimmich 28'; Marcelo 44' Asensio 57']
464
+
465
+
466
+ Semi-finals - 2nd Leg
467
+
468
+ [Tue May/1]
469
+ 20.45 Real Madrid 2-2 Bayern München @ Santiago Bernabéu, Madrid
470
+ [Benzema 11', 46'; Kimmich 3' Rodríguez 63']
471
+
472
+ [Wed May/2]
473
+ 20.45 Roma 4-2 Liverpool @ Stadio Olimpico, Rome
474
+ [Milner 15' (o.g.) Džeko 52' Nainggolan 86', 90+4' (pen.); Mané 9' Wijnaldum 25']
475
+
476
+ Final
477
+
478
+ [Sat May/26]
479
+ 20.45 Real Madrid 3-1 Liverpool @ NSC Olimpiyskiy Stadium, Kiev
480
+ [Benzema 51' Bale 64', 83'; Mané 55']
481
+ TXT
482
+
483
+ SportDb::MatchReaderV2.parse( txt )
484
+ end
485
+
486
+
487
+ end # class TestMatchReaderChamps