f1results 0.6 → 2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/f1results +15 -9
- data/lib/f1results.rb +3 -2
- data/lib/f1results/agent.rb +64 -76
- data/lib/f1results/event.rb +14 -18
- data/lib/f1results/parser.rb +87 -0
- data/lib/f1results/result.rb +25 -17
- data/lib/f1results/version.rb +1 -1
- data/test/agent_test.rb +57 -48
- data/test/event_test.rb +0 -5
- data/test/parser_test.rb +76 -0
- data/test/result_test.rb +22 -18
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20e8936ca3cd5baf306ab90eb7ba9e6324c275f6
|
4
|
+
data.tar.gz: 6c019079bb2e03f2e55cd45616f27c64236160ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3512907a131f27c0d834016b79061e342dc3a93d30bd2288544ba2109dd1bd13c1e0455bbdc72063c19387ebb7974c7c01d2d13e53fe1a2d942064403c7604fc
|
7
|
+
data.tar.gz: 81d89f42b758c3a673b0cedbe231150aef324bf22491a1da822b7aa0a4ac0cb8e7ae872734201f1b911b8a00e428bb5bc3117cf6c8328bf5ef9ea781c9d32883
|
data/bin/f1results
CHANGED
@@ -12,7 +12,7 @@ url = nil
|
|
12
12
|
|
13
13
|
optparse = OptionParser.new do |opts|
|
14
14
|
opts.on('-y', '--year=YEAR', Integer) { |val| year = val }
|
15
|
-
opts.on('-c', '--country=COUNTRY', String) { |val| country = val.
|
15
|
+
opts.on('-c', '--country=COUNTRY', String) { |val| country = val.titleize }
|
16
16
|
opts.on('-e', '--event=EVENT', String) { |val| event_type = val.downcase.to_sym }
|
17
17
|
opts.on('-u', '--url=URL', String) { |val| url = val }
|
18
18
|
opts.parse!
|
@@ -24,33 +24,39 @@ begin
|
|
24
24
|
else
|
25
25
|
F1Results.fetch_with_url(url)
|
26
26
|
end
|
27
|
-
rescue
|
28
|
-
|
29
|
-
puts "No results for #{event_summary}"
|
27
|
+
rescue RuntimeError => e
|
28
|
+
puts e
|
30
29
|
exit
|
31
30
|
end
|
32
31
|
|
33
|
-
title = url.nil? ? "#{event.year} #{event.
|
32
|
+
title = url.nil? ? "#{event.year} #{event.country} #{event.type_name}\n#{event.name}" : event.name
|
34
33
|
table = Terminal::Table.new title: title, rows: event.to_a
|
35
34
|
|
36
35
|
if event.practice?
|
37
|
-
table.headings = %W(Pos
|
36
|
+
table.headings = %W(Pos No Driver Team Time Gap Laps)
|
38
37
|
table.align_column 0, :right
|
39
38
|
table.align_column 1, :right
|
40
39
|
table.align_column 4, :right
|
40
|
+
table.align_column 5, :right
|
41
41
|
table.align_column 6, :right
|
42
42
|
|
43
43
|
elsif event.qualifying?
|
44
|
-
table.headings = %W(Pos Driver Team Q1 Q2 Q3 Laps)
|
44
|
+
table.headings = %W(Pos No Driver Team Q1 Q2 Q3 Laps)
|
45
45
|
table.align_column 0, :right
|
46
|
+
table.align_column 1, :right
|
47
|
+
table.align_column 4, :right
|
48
|
+
table.align_column 5, :right
|
46
49
|
table.align_column 6, :right
|
50
|
+
table.align_column 7, :right
|
47
51
|
|
48
52
|
elsif event.race?
|
49
|
-
table.headings = %W(Pos Driver
|
53
|
+
table.headings = %W(Pos No Driver Team Laps Time/Retired Points)
|
50
54
|
table.align_column 0, :right
|
51
|
-
table.align_column
|
55
|
+
table.align_column 1, :right
|
52
56
|
table.align_column 4, :right
|
53
57
|
table.align_column 5, :right
|
58
|
+
table.align_column 6, :right
|
54
59
|
end
|
55
60
|
|
61
|
+
puts event.results[0].inspect
|
56
62
|
puts table
|
data/lib/f1results.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'f1results/version'
|
2
2
|
require 'f1results/agent'
|
3
|
+
require 'f1results/parser'
|
3
4
|
require 'f1results/event'
|
4
5
|
require 'f1results/result'
|
5
6
|
|
@@ -16,12 +17,12 @@ module F1Results
|
|
16
17
|
|
17
18
|
def self.fetch(year, country, type = :race)
|
18
19
|
event = Event.new(year: year, country: country, type: type)
|
19
|
-
event.
|
20
|
+
event.get_results
|
20
21
|
return event
|
21
22
|
end
|
22
23
|
|
23
24
|
def self.fetch_with_url(url)
|
24
25
|
agent = Agent.new
|
25
|
-
return agent.
|
26
|
+
return agent.get_results_with_url(url)
|
26
27
|
end
|
27
28
|
end
|
data/lib/f1results/agent.rb
CHANGED
@@ -2,103 +2,91 @@ require 'mechanize'
|
|
2
2
|
|
3
3
|
module F1Results
|
4
4
|
class Agent < ::Mechanize
|
5
|
-
attr_accessor :event
|
6
5
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
else
|
11
|
-
self.event = event
|
12
|
-
end
|
13
|
-
super
|
14
|
-
end
|
15
|
-
|
16
|
-
def fetch_results
|
17
|
-
return fetch_results_with_url(@default_url)
|
6
|
+
def get_url(event)
|
7
|
+
@event = event
|
8
|
+
return url
|
18
9
|
end
|
19
10
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
@event.name = parse_event_title
|
26
|
-
@event.results = parse_event_results
|
27
|
-
return @event
|
28
|
-
rescue Mechanize::ResponseCodeError, Net::HTTPNotFound
|
29
|
-
raise "No results found at #{url}"
|
30
|
-
end
|
11
|
+
def get_results(new_event)
|
12
|
+
@event = new_event
|
13
|
+
event.url ||= url
|
14
|
+
update_results
|
15
|
+
return event
|
31
16
|
end
|
32
17
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
18
|
+
def get_results_with_url(new_url)
|
19
|
+
event.url = new_url
|
20
|
+
update_results
|
21
|
+
return event
|
37
22
|
end
|
38
23
|
|
39
24
|
private
|
40
25
|
|
41
|
-
def
|
42
|
-
|
26
|
+
def event
|
27
|
+
@event ||= Event.new
|
43
28
|
end
|
44
29
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
def parse_event_results
|
54
|
-
results = []
|
55
|
-
table = page.parser.xpath('//tbody')
|
56
|
-
|
57
|
-
# Remove driver abbreviation from cell
|
58
|
-
table.xpath('//span[@class="tla"]').each(&:remove)
|
59
|
-
|
60
|
-
# Turn HTML table into an array of arrays
|
61
|
-
data = table.xpath('//tr').map do |row|
|
62
|
-
row.xpath('./td|./th').map do |cell|
|
63
|
-
cell = cell.text.gsub(/[[:space:]]+/, ' ').strip
|
64
|
-
cell.blank? ? nil : cell
|
65
|
-
end
|
30
|
+
def url
|
31
|
+
base_path = "content/fom-website/en/results.html/#{event.year}/"
|
32
|
+
year_url = URI.join F1Results::BASEURL, base_path, 'races.html'
|
33
|
+
begin
|
34
|
+
get(year_url)
|
35
|
+
rescue Mechanize::ResponseCodeError, Net::HTTPNotFound
|
36
|
+
raise "No results found for #{event.year}"
|
66
37
|
end
|
67
38
|
|
68
|
-
|
69
|
-
|
70
|
-
data.reject! { |row| row.any? { |cell| regex =~ cell } }
|
39
|
+
file_name = html_file_name
|
40
|
+
key = meeting_key
|
71
41
|
|
72
|
-
|
42
|
+
uri = URI.join F1Results::BASEURL, base_path, "races/#{key}/#{file_name}"
|
43
|
+
return uri.to_s
|
44
|
+
end
|
73
45
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
46
|
+
def update_results
|
47
|
+
begin
|
48
|
+
get(event.url)
|
49
|
+
new_event = Parser.new(page).parse
|
50
|
+
event.results = new_event.results
|
51
|
+
event.type ||= new_event.type
|
52
|
+
event.country ||= new_event.country
|
53
|
+
event.name ||= new_event.name
|
54
|
+
rescue Mechanize::ResponseCodeError, Net::HTTPNotFound
|
55
|
+
raise "No results found at #{url}"
|
81
56
|
end
|
57
|
+
end
|
82
58
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
results << result
|
59
|
+
def meeting_key
|
60
|
+
country = event.country.parameterize
|
61
|
+
options = page.parser.xpath('//select[@name="meetingKey"]/option')
|
62
|
+
meeting_key_node = options.detect do |node|
|
63
|
+
node.attr('value') =~ /^\d+\/#{country}/ || node.text.parameterize =~ /#{country}/
|
89
64
|
end
|
90
|
-
|
91
|
-
return
|
65
|
+
raise "No country '#{event.country}' found for #{event.year}" if meeting_key_node.nil?
|
66
|
+
return meeting_key_node.attr('value')
|
92
67
|
end
|
93
68
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
cell.to_s.strip.parameterize('_').to_sym
|
69
|
+
def html_file_name
|
70
|
+
result_types = {}
|
71
|
+
page.parser.xpath('//a[@data-name="resultType"]').each do |node|
|
72
|
+
key = node.text.parameterize('_').to_sym
|
73
|
+
value = node.attr('data-value')
|
74
|
+
result_types[key] = value
|
101
75
|
end
|
76
|
+
|
77
|
+
# TODO: add support for Starting Grid, Warm Up, Pit Stop Summary, Fastest Laps
|
78
|
+
file_name = case
|
79
|
+
when event.race?
|
80
|
+
'race-result'
|
81
|
+
when event.qualifying?
|
82
|
+
result_types[:qualifying] || result_types[:overall_qualifying]
|
83
|
+
when event.practice?
|
84
|
+
event.type_name.parameterize
|
85
|
+
else
|
86
|
+
raise "No results for event type '#{event.type}' at #{event.year} #{event.country}"
|
87
|
+
end
|
88
|
+
return file_name + '.html'
|
102
89
|
end
|
90
|
+
|
103
91
|
end
|
104
92
|
end
|
data/lib/f1results/event.rb
CHANGED
@@ -2,7 +2,7 @@ require 'active_support/core_ext/string'
|
|
2
2
|
|
3
3
|
module F1Results
|
4
4
|
class Event
|
5
|
-
attr_accessor :year, :country, :type, :name, :results
|
5
|
+
attr_accessor :year, :country, :country_slug, :type, :name, :results, :url
|
6
6
|
|
7
7
|
TYPE_ALIASES = {
|
8
8
|
p1: :practice1,
|
@@ -17,14 +17,6 @@ module F1Results
|
|
17
17
|
args.each { |k,v| send("#{k}=", v) }
|
18
18
|
end
|
19
19
|
|
20
|
-
def country_name
|
21
|
-
@country.to_s.titleize
|
22
|
-
end
|
23
|
-
|
24
|
-
def country_slug
|
25
|
-
@country.to_s.parameterize
|
26
|
-
end
|
27
|
-
|
28
20
|
def type=(type)
|
29
21
|
type = type.to_s.downcase.gsub(' ', '').to_sym
|
30
22
|
@type = TYPE_ALIASES[type] || type
|
@@ -55,21 +47,25 @@ module F1Results
|
|
55
47
|
@results.map(&:to_a)
|
56
48
|
end
|
57
49
|
|
58
|
-
def
|
59
|
-
@results
|
50
|
+
def [](i)
|
51
|
+
@results[i]
|
52
|
+
end
|
53
|
+
|
54
|
+
def winning
|
55
|
+
self[0]
|
60
56
|
end
|
61
57
|
|
62
|
-
def
|
63
|
-
|
58
|
+
def losing
|
59
|
+
self[-1]
|
64
60
|
end
|
65
61
|
|
66
|
-
def
|
67
|
-
agent = F1Results::Agent.new
|
68
|
-
agent.
|
62
|
+
def get_results
|
63
|
+
agent = F1Results::Agent.new
|
64
|
+
agent.get_results(self)
|
69
65
|
end
|
70
66
|
|
71
|
-
def
|
72
|
-
agent = F1Results::Agent.new
|
67
|
+
def get_results_with_url(url)
|
68
|
+
agent = F1Results::Agent.new
|
73
69
|
agent.fetch_results_with_url(url)
|
74
70
|
end
|
75
71
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module F1Results
|
2
|
+
class Parser
|
3
|
+
def initialize(page)
|
4
|
+
@page = page
|
5
|
+
@event = Event.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse
|
9
|
+
@event.name = event_name
|
10
|
+
@event.type = event_type
|
11
|
+
@event.country = event_country
|
12
|
+
@event.results = event_results
|
13
|
+
# TODO: date
|
14
|
+
return @event
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def event_name
|
20
|
+
# TODO: make helper method for .gsub(/[[:space:]]+/, ' ').strip
|
21
|
+
return @page.parser.xpath('//title').text
|
22
|
+
.gsub(/[[:space:]]+/, ' ').strip
|
23
|
+
end
|
24
|
+
|
25
|
+
def event_type
|
26
|
+
if match = @event.name.match(/(?:.+) - (.+)/)
|
27
|
+
result_title = match[1]
|
28
|
+
.gsub(/(?<=RACE )RESULT/, '')
|
29
|
+
.gsub(/OVERALL(?= QUALIFYING)/, '')
|
30
|
+
.gsub(/(?<=PRACTICE)( )(?=[1|2|3])/, '')
|
31
|
+
.parameterize('_')
|
32
|
+
return result_title.to_sym
|
33
|
+
else
|
34
|
+
return nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def event_country
|
39
|
+
node = @page.parser.at_xpath('//select[@name="meetingKey"]/option[@selected]')
|
40
|
+
slug = node.attr('value').split('/')[-1]
|
41
|
+
text = node.text
|
42
|
+
return text
|
43
|
+
end
|
44
|
+
|
45
|
+
def event_results
|
46
|
+
results = []
|
47
|
+
table = @page.parser.xpath('//tbody')
|
48
|
+
|
49
|
+
# Remove driver abbreviation from driver cell
|
50
|
+
table.xpath('//span[@class="uppercase hide-for-desktop"]').each(&:remove)
|
51
|
+
|
52
|
+
# Turn HTML table into an array of arrays
|
53
|
+
data = table.xpath('//tr').map do |row|
|
54
|
+
row.xpath('./td|./th').map do |cell|
|
55
|
+
cell = cell.text.gsub(/[[:space:]]+/, ' ').strip
|
56
|
+
cell.blank? ? nil : cell
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Shift top row of table and convert cell text into symbols
|
61
|
+
header = data.shift.map do |cell|
|
62
|
+
cell.to_s.parameterize('_').to_sym
|
63
|
+
end
|
64
|
+
|
65
|
+
# Set result class type
|
66
|
+
result_class = case
|
67
|
+
when @event.practice?
|
68
|
+
PracticeResult
|
69
|
+
when @event.qualifying?
|
70
|
+
QualifyingResult
|
71
|
+
else
|
72
|
+
RaceResult
|
73
|
+
end
|
74
|
+
|
75
|
+
# Make each table row a Result
|
76
|
+
data.each_with_index do |row, i|
|
77
|
+
hash = Hash[header.zip(row)]
|
78
|
+
hash[:position] = i + 1
|
79
|
+
|
80
|
+
result = result_class.new(hash)
|
81
|
+
results << result
|
82
|
+
end
|
83
|
+
|
84
|
+
return results
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/f1results/result.rb
CHANGED
@@ -1,15 +1,10 @@
|
|
1
1
|
module F1Results
|
2
2
|
class Result
|
3
|
-
attr_accessor :
|
3
|
+
attr_accessor :position, :driver, :driver_number, :driver_country_abbr, :team, :time, :gap, :laps
|
4
|
+
attr_reader :position_name
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
alias :name= :driver=
|
8
|
-
alias :no= :driver_number=
|
9
|
-
alias :country= :driver_country_abbr=
|
10
|
-
alias :best_time= :time=
|
11
|
-
alias :race_time= :time=
|
12
|
-
alias :fastest= :time=
|
6
|
+
alias_method :no=, :driver_number=
|
7
|
+
alias_method :car=, :team=
|
13
8
|
|
14
9
|
def initialize(args = {})
|
15
10
|
args.each do |k, v|
|
@@ -18,16 +13,18 @@ module F1Results
|
|
18
13
|
end
|
19
14
|
end
|
20
15
|
|
21
|
-
def
|
22
|
-
@
|
16
|
+
def position_name=(n)
|
17
|
+
@position_name = case
|
23
18
|
when n.to_s.empty?
|
24
19
|
nil
|
25
20
|
when n.to_i == 0
|
26
21
|
n
|
27
22
|
else
|
28
|
-
n.to_i
|
23
|
+
@position = n.to_i
|
29
24
|
end
|
30
25
|
end
|
26
|
+
alias_method :p=, :position_name=
|
27
|
+
alias_method :pos=, :position_name=
|
31
28
|
|
32
29
|
def driver_number
|
33
30
|
@driver_number.to_i == 0 ? nil : @driver_number.to_i
|
@@ -38,35 +35,42 @@ module F1Results
|
|
38
35
|
end
|
39
36
|
|
40
37
|
def gap
|
38
|
+
# TODO: parse gap properly
|
41
39
|
@gap.to_f == 0.0 ? nil : @gap.to_f
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
45
43
|
class PracticeResult < Result
|
46
44
|
def to_a
|
47
|
-
[
|
45
|
+
[position_name, driver_number, driver, team, time, gap, laps]
|
48
46
|
end
|
47
|
+
|
48
|
+
# TODO: to_h, to_s
|
49
49
|
end
|
50
50
|
|
51
51
|
class QualifyingResult < Result
|
52
52
|
attr_accessor :q1, :q2, :q3
|
53
53
|
|
54
54
|
def to_a
|
55
|
-
[
|
55
|
+
[position_name, driver_number, driver, team, q1, q2, q3, laps]
|
56
|
+
end
|
57
|
+
|
58
|
+
def q1
|
59
|
+
@time || @q1
|
56
60
|
end
|
57
61
|
|
58
62
|
def time
|
59
|
-
q3 || q2 || q1
|
63
|
+
@q3 || @q2 || @q1 || @time
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
63
67
|
class RaceResult < Result
|
64
68
|
attr_accessor :retired, :points
|
65
69
|
|
66
|
-
|
70
|
+
alias_method :pts=, :points=
|
67
71
|
|
68
72
|
def to_a
|
69
|
-
[
|
73
|
+
[position_name, driver_number, driver, team, laps, time_or_retired, points]
|
70
74
|
end
|
71
75
|
|
72
76
|
def time_or_retired=(str)
|
@@ -76,6 +80,7 @@ module F1Results
|
|
76
80
|
@retired = str
|
77
81
|
end
|
78
82
|
end
|
83
|
+
alias_method :time_retired=, :time_or_retired=
|
79
84
|
|
80
85
|
def time_or_retired
|
81
86
|
time || retired
|
@@ -85,4 +90,7 @@ module F1Results
|
|
85
90
|
@points.to_i
|
86
91
|
end
|
87
92
|
end
|
93
|
+
|
94
|
+
# TODO: PitStop < Result
|
95
|
+
# TODO: FastestLap < Result
|
88
96
|
end
|
data/lib/f1results/version.rb
CHANGED
data/test/agent_test.rb
CHANGED
@@ -7,68 +7,77 @@ class AgentTest < MiniTest::Test
|
|
7
7
|
@agent = F1Results::Agent.new
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
event = F1Results::Event.new(year:
|
12
|
-
|
13
|
-
@agent.
|
14
|
-
assert_equal '2015 FORMULA 1 ROLEX AUSTRALIAN GRAND PRIX', event.name
|
15
|
-
assert_equal 17, event.results.length
|
16
|
-
assert_equal 'Lewis Hamilton', event.winner
|
17
|
-
assert_equal 'Kevin Magnussen', event.loser
|
10
|
+
def test_get_url_2016_australia_practice1
|
11
|
+
event = F1Results::Event.new(year: 2016, country: 'Australia', type: :practice1)
|
12
|
+
url = 'http://www.formula1.com/content/fom-website/en/results.html/2016/races/938/australia/practice-1.html'
|
13
|
+
assert_equal url, @agent.get_url(event)
|
18
14
|
end
|
19
15
|
|
20
|
-
def
|
21
|
-
event = F1Results::Event.new(year:
|
22
|
-
|
23
|
-
@agent.
|
24
|
-
assert_equal '2015 FORMULA 1 ROLEX AUSTRALIAN GRAND PRIX', event.name
|
25
|
-
assert_equal 20, event.results.length
|
26
|
-
assert_equal 'Lewis Hamilton', event.winner
|
27
|
-
assert_equal 'Roberto Merhi', event.loser
|
16
|
+
def test_get_url_2016_australia_qualifying
|
17
|
+
event = F1Results::Event.new(year: 2016, country: 'Australia', type: :qualifying)
|
18
|
+
url = 'http://www.formula1.com/content/fom-website/en/results.html/2016/races/938/australia/qualifying.html'
|
19
|
+
assert_equal url, @agent.get_url(event)
|
28
20
|
end
|
29
21
|
|
30
|
-
def
|
31
|
-
event = F1Results::Event.new(year:
|
32
|
-
|
33
|
-
@agent.
|
34
|
-
assert_equal '2015 FORMULA 1 ROLEX AUSTRALIAN GRAND PRIX', event.name
|
35
|
-
assert_equal 16, event.results.length
|
36
|
-
assert_equal 'Nico Rosberg', event.winner
|
37
|
-
assert_equal 'Romain Grosjean', event.loser
|
22
|
+
def test_get_url_2016_australia_race
|
23
|
+
event = F1Results::Event.new(year: 2016, country: 'Australia', type: :race)
|
24
|
+
url = 'http://www.formula1.com/content/fom-website/en/results.html/2016/races/938/australia/race-result.html'
|
25
|
+
assert_equal url, @agent.get_url(event)
|
38
26
|
end
|
39
27
|
|
40
|
-
def
|
41
|
-
event = F1Results::Event.new(year:
|
42
|
-
|
43
|
-
@agent.
|
44
|
-
assert_equal '2015 FORMULA 1 PETRONAS MALAYSIA GRAND PRIX', event.name
|
45
|
-
assert_equal 20, event.results.length
|
46
|
-
assert_equal 'Lewis Hamilton', event.winner
|
47
|
-
assert_equal 'Roberto Merhi', event.loser
|
28
|
+
def test_get_url_1984_brazil_qualifying
|
29
|
+
event = F1Results::Event.new(year: 1984, country: 'Brazil', type: :qualifying)
|
30
|
+
url = 'http://www.formula1.com/content/fom-website/en/results.html/1984/races/466/brazil/qualifying-0.html'
|
31
|
+
assert_equal url, @agent.get_url(event)
|
48
32
|
end
|
49
33
|
|
50
|
-
def
|
51
|
-
event =
|
52
|
-
|
53
|
-
assert_equal
|
54
|
-
assert event.race?
|
55
|
-
assert_equal 20, event.results.length
|
56
|
-
assert_equal 'Sebastian Vettel', event.winner
|
57
|
-
assert_equal 'Nico Hulkenberg', event.loser
|
34
|
+
def test_get_url_1984_brazil_race
|
35
|
+
event = F1Results::Event.new(year: 1984, country: 'Brazil', type: :race)
|
36
|
+
url = 'http://www.formula1.com/content/fom-website/en/results.html/1984/races/466/brazil/race-result.html'
|
37
|
+
assert_equal url, @agent.get_url(event)
|
58
38
|
end
|
59
39
|
|
60
|
-
def
|
61
|
-
|
40
|
+
def test_get_url_1950_indianapolis_500_qualifying
|
41
|
+
event = F1Results::Event.new(year: 1950, country: 'United States', type: :qualifying)
|
42
|
+
url = 'http://www.formula1.com/content/fom-website/en/results.html/1950/races/96/indianapolis-500/qualifying-0.html'
|
43
|
+
assert_equal url, @agent.get_url(event)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_get_url_1950_indianapolis_500_race
|
47
|
+
event = F1Results::Event.new(year: 1950, country: 'United States', type: :race)
|
48
|
+
url = 'http://www.formula1.com/content/fom-website/en/results.html/1950/races/96/indianapolis-500/race-result.html'
|
49
|
+
assert_equal url, @agent.get_url(event)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_get_results_1950_indianapolis_500_race
|
53
|
+
event = F1Results::Event.new(year: 1950, country: 'United States', type: :race)
|
54
|
+
event = @agent.get_results(event)
|
55
|
+
assert_equal 36, event.results.length
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_api
|
59
|
+
event = F1Results.fetch(1950, 'United States', :race)
|
60
|
+
assert_equal 36, event.results.length
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_event_with_bad_year
|
64
|
+
assert_raise_with_message RuntimeError, 'No results found for 1900' do
|
62
65
|
event = F1Results::Event.new(year: 1900, country: 'Australia', type: :race)
|
63
|
-
@agent.event
|
64
|
-
|
66
|
+
@agent.get_url(event)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_event_with_bad_grand_prix
|
71
|
+
assert_raise_with_message RuntimeError, "No country 'New Zealand' found for 2016" do
|
72
|
+
event = F1Results::Event.new(year: 2016, country: 'New Zealand', type: :race)
|
73
|
+
@agent.get_url(event)
|
65
74
|
end
|
66
75
|
end
|
67
76
|
|
68
|
-
def
|
69
|
-
|
70
|
-
event = F1Results::Event.new(year:
|
71
|
-
event
|
77
|
+
def test_event_with_bad_event_name
|
78
|
+
assert_raise_with_message RuntimeError, "No results for event type 'practice4' at 2016 Australia" do
|
79
|
+
event = F1Results::Event.new(year: 2016, country: 'Australia', type: :practice4)
|
80
|
+
@agent.get_url(event)
|
72
81
|
end
|
73
82
|
end
|
74
83
|
end
|
data/test/event_test.rb
CHANGED
@@ -49,11 +49,6 @@ class EventTest < MiniTest::Test
|
|
49
49
|
refute @event.practice?
|
50
50
|
end
|
51
51
|
|
52
|
-
def test_country_name
|
53
|
-
@event.country = 'great britain'
|
54
|
-
assert_equal 'Great Britain', @event.country_name
|
55
|
-
end
|
56
|
-
|
57
52
|
def test_to_array
|
58
53
|
@event.results << F1Results::RaceResult.new(position: 1, driver: 'Mark Webber', driver_country_abbr: 'AUS', team: 'Red Bull Racing-Renault', time: '1:25:11.288', points: 2)
|
59
54
|
@event.results << F1Results::RaceResult.new(position: 2, driver: 'Fernando Alonso', driver_country_abbr: 'ESP', team: 'Ferrari', time: '+3.0 secs', points: 1)
|
data/test/parser_test.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ParserTest < MiniTest::Test
|
4
|
+
include Fixtures
|
5
|
+
|
6
|
+
def test_2016_australia_practice1
|
7
|
+
event = events(:'2016_australia_practice_1')
|
8
|
+
assert_equal '2016 FORMULA 1 ROLEX AUSTRALIAN GRAND PRIX - PRACTICE 1', event.name
|
9
|
+
assert_equal 'Australia', event.country
|
10
|
+
assert_equal :practice1, event.type
|
11
|
+
assert_equal 22, event.results.length
|
12
|
+
assert_equal 'Lewis Hamilton', event.winning.driver
|
13
|
+
assert_equal 'Carlos Sainz', event.losing.driver
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_2016_australia_qualifying
|
17
|
+
event = events(:'2016_australia_qualifying')
|
18
|
+
assert_equal '2016 FORMULA 1 ROLEX AUSTRALIAN GRAND PRIX - QUALIFYING', event.name
|
19
|
+
assert_equal 'Australia', event.country
|
20
|
+
assert_equal :qualifying, event.type
|
21
|
+
assert_equal 22, event.results.length
|
22
|
+
assert_equal 'Lewis Hamilton', event.winning.driver
|
23
|
+
assert_equal 'Pascal Wehrlein', event.losing.driver
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_2016_australia_race
|
27
|
+
event = events(:'2016_australia_race_result')
|
28
|
+
assert_equal '2016 FORMULA 1 ROLEX AUSTRALIAN GRAND PRIX - RACE RESULT', event.name
|
29
|
+
assert_equal 'Australia', event.country
|
30
|
+
assert_equal :race, event.type
|
31
|
+
assert_equal 22, event.results.length
|
32
|
+
assert_equal 'Nico Rosberg', event.winning.driver
|
33
|
+
assert_equal 'Daniil Kvyat', event.losing.driver
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_1984_brazil_qualifying
|
37
|
+
event = events(:'1984_brazil_qualifying_0')
|
38
|
+
assert_equal 'Brazilian Grand Prix 1984 - OVERALL QUALIFYING', event.name
|
39
|
+
assert_equal 'Brazil', event.country
|
40
|
+
assert_equal :qualifying, event.type
|
41
|
+
assert_equal 24, event.results.length
|
42
|
+
assert_equal 'Elio de Angelis', event.winning.driver
|
43
|
+
assert_equal 'Jonathan Palmer', event.losing.driver
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_1984_brazil_race
|
47
|
+
event = events(:'1984_brazil_race_result')
|
48
|
+
assert_equal 'Brazilian Grand Prix 1984 - RACE RESULT', event.name
|
49
|
+
assert_equal 'Brazil', event.country
|
50
|
+
assert_equal :race, event.type
|
51
|
+
assert_equal 24, event.results.length
|
52
|
+
assert_equal 'Alain Prost', event.winning.driver
|
53
|
+
assert_equal 'Ayrton Senna', event.losing.driver
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_1950_indianapolis_500_qualifying
|
57
|
+
event = events(:'1950_indianapolis_500_qualifying_0')
|
58
|
+
assert_equal '1950 Indianapolis 500 - QUALIFYING', event.name
|
59
|
+
assert_equal 'United States', event.country
|
60
|
+
assert_equal :qualifying, event.type
|
61
|
+
assert_equal 1, event.results.length
|
62
|
+
assert_equal 'Walt Faulkner', event.winning.driver
|
63
|
+
assert_equal 'Walt Faulkner', event.losing.driver
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_1950_indianapolis_500_race
|
67
|
+
event = events(:'1950_indianapolis_500_race_result')
|
68
|
+
assert_equal '1950 Indianapolis 500 - RACE RESULT', event.name
|
69
|
+
assert_equal 'United States', event.country
|
70
|
+
assert_equal :race, event.type
|
71
|
+
# Note: 3 ties, so 36 finishers, 33 positions in this race
|
72
|
+
assert_equal 36, event.results.length
|
73
|
+
assert_equal 'Johnnie Parsons', event.winning.driver
|
74
|
+
assert_equal 'Duke Dinsmore', event.losing.driver
|
75
|
+
end
|
76
|
+
end
|
data/test/result_test.rb
CHANGED
@@ -30,31 +30,34 @@ class ResultTest < MiniTest::Test
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_parse_practice
|
33
|
-
|
34
|
-
|
35
|
-
assert_equal
|
36
|
-
assert_equal '
|
37
|
-
assert_equal '
|
38
|
-
assert_equal
|
33
|
+
hash = { pos: '2', no: '26', driver: 'Daniil Kvyat', car: 'Red Bull Racing TAG Heuer', time: '1:30.146', gap: '+0.421s', laps: '14' }
|
34
|
+
result = F1Results::PracticeResult.new hash
|
35
|
+
assert_equal 2, result.position
|
36
|
+
assert_equal 'Daniil Kvyat', result.driver
|
37
|
+
assert_equal 'Red Bull Racing TAG Heuer', result.team
|
38
|
+
assert_equal '1:30.146', result.time
|
39
|
+
assert_equal 14, result.laps
|
39
40
|
end
|
40
41
|
|
41
42
|
def test_parse_qualifying
|
42
|
-
|
43
|
-
|
44
|
-
assert_equal
|
45
|
-
assert_equal '
|
46
|
-
assert_equal '
|
47
|
-
assert_equal '1:
|
48
|
-
assert_equal '1:
|
49
|
-
assert_equal
|
43
|
+
hash = { pos: '8', no: '3', driver: 'Daniel Ricciardo', car: 'Red Bull Racing TAG Heuer', q1: '1:26.945', q2: '1:25.599', q3: '1:25.589', laps: '15' }
|
44
|
+
result = F1Results::QualifyingResult.new hash
|
45
|
+
assert_equal 8, result.position
|
46
|
+
assert_equal 'Daniel Ricciardo', result.driver
|
47
|
+
assert_equal 'Red Bull Racing TAG Heuer', result.team
|
48
|
+
assert_equal '1:26.945', result.q1
|
49
|
+
assert_equal '1:25.599', result.q2
|
50
|
+
assert_equal '1:25.589', result.q3
|
51
|
+
assert_equal 15, result.laps
|
50
52
|
end
|
51
53
|
|
52
54
|
def test_parse_race
|
53
|
-
|
55
|
+
hash = { pos: '3', no: '5', driver: 'Sebastian Vettel', car: 'Ferrari', laps: '57', time_retired: '+9.643s', pts: '15' }
|
56
|
+
result = F1Results::RaceResult.new hash
|
54
57
|
assert_equal 3, result.position
|
55
58
|
assert_equal 'Sebastian Vettel', result.driver
|
56
59
|
assert_equal 'Ferrari', result.team
|
57
|
-
assert_equal '+
|
60
|
+
assert_equal '+9.643s', result.time
|
58
61
|
assert_equal 15, result.points
|
59
62
|
end
|
60
63
|
|
@@ -67,8 +70,9 @@ class ResultTest < MiniTest::Test
|
|
67
70
|
end
|
68
71
|
|
69
72
|
def test_race_to_a
|
70
|
-
|
71
|
-
|
73
|
+
hash = { pos: '3', no: '5', driver: 'Sebastian Vettel', car: 'Ferrari', laps: '57', time_retired: '+9.643s', pts: '15' }
|
74
|
+
result = F1Results::RaceResult.new hash
|
75
|
+
assert_equal [3, 5, 'Sebastian Vettel', 'Ferrari', 57, '+9.643s', 15], result.to_a
|
72
76
|
end
|
73
77
|
|
74
78
|
def test_unknown_key_doesnt_raise_error
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: f1results
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0
|
4
|
+
version: '2.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Darren Jeacocke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mechanize
|
@@ -108,10 +108,12 @@ files:
|
|
108
108
|
- lib/f1results.rb
|
109
109
|
- lib/f1results/agent.rb
|
110
110
|
- lib/f1results/event.rb
|
111
|
+
- lib/f1results/parser.rb
|
111
112
|
- lib/f1results/result.rb
|
112
113
|
- lib/f1results/version.rb
|
113
114
|
- test/agent_test.rb
|
114
115
|
- test/event_test.rb
|
116
|
+
- test/parser_test.rb
|
115
117
|
- test/result_test.rb
|
116
118
|
homepage: https://github.com/daz/f1results
|
117
119
|
licenses:
|