postrunner 0.0.11 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,6 +17,7 @@ require 'postrunner/View'
17
17
  require 'postrunner/ViewFrame'
18
18
  require 'postrunner/ViewButtons'
19
19
  require 'postrunner/PagingButtons'
20
+ require 'postrunner/Activity'
20
21
 
21
22
  module PostRunner
22
23
 
@@ -27,16 +28,15 @@ module PostRunner
27
28
  include Fit4Ruby::Converters
28
29
 
29
30
  # Create a RecordListPageView object.
30
- # @param db [ActivityDB] Activity database
31
+ # @param ffs [FitFileStore] Activity database
31
32
  # @param records [PersonalRecords] Database with personal records
32
33
  # @param page_count [Fixnum] Number of total pages
33
34
  # @param page_index [Fixnum] Index of the page
34
- def initialize(db, records, page_count, page_index)
35
- @db = db
36
- @unit_system = @db.cfg[:unit_system]
35
+ def initialize(ffs, records, page_count, page_index)
36
+ #@unit_system = ffs.store['config']['unit_system']
37
37
  @records = records
38
38
 
39
- views = @db.views
39
+ views = ffs.views
40
40
  views.current_page = "records-0.html"
41
41
 
42
42
  pages = PagingButtons.new((0..(page_count - 1)).map do |i|
@@ -55,7 +55,7 @@ module PostRunner
55
55
  ViewFrame.new("All-time #{@sport_name} Records",
56
56
  frame_width, @records.all_time).to_html(@doc)
57
57
 
58
- @records.yearly.sort{ |y1, y2| y2[0] <=> y1[0] }.
58
+ @records.yearly.sort{ |y1, y2| y2[0].to_i <=> y1[0].to_i }.
59
59
  each do |year, record|
60
60
  next if record.empty?
61
61
  ViewFrame.new("#{year} #{@sport_name} Records",
@@ -57,6 +57,10 @@ module PostRunner
57
57
  if profile.activity_class
58
58
  t.row([ 'Activity Class:', profile.activity_class ])
59
59
  end
60
+ if profile.metmax
61
+ t.row([ 'METmax:', "#{profile.metmax} MET" ])
62
+ t.row([ 'VO2max:', "#{'%.1f' % (profile.metmax * 3.5)} ml/kg/min" ])
63
+ end
60
64
  t
61
65
  end
62
66
 
@@ -11,5 +11,5 @@
11
11
  #
12
12
 
13
13
  module PostRunner
14
- VERSION = "0.0.11"
14
+ VERSION = "0.1.0"
15
15
  end
@@ -0,0 +1,99 @@
1
+ /*
2
+ * TrackView.rb -- PostRunner - Manage the data from your Garmin sport devices.
3
+ *
4
+ * Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of version 2 of the GNU General Public License as
8
+ * published by the Free Software Foundation.
9
+ */
10
+
11
+ var pr_trackview_init = function(center_long, center_lat) {
12
+ lm_w = 40;
13
+ lm_h = 100;
14
+
15
+ pr_transformer = function(coords, i, arr) {
16
+ arr[i] = ol.proj.transform(coords, 'EPSG:4326', 'EPSG:900913');
17
+ };
18
+
19
+ pr_track_points.forEach(pr_transformer);
20
+ pr_lap_markers.forEach(pr_transformer);
21
+
22
+ var map = new ol.Map({
23
+ view: new ol.View({
24
+ center: ol.proj.transform([ center_long, center_lat ],
25
+ 'EPSG:4326', 'EPSG:900913'),
26
+ zoom: 14,
27
+ }),
28
+ layers: [
29
+ new ol.layer.Tile({
30
+ source: new ol.source.MapQuest({layer: 'osm'})
31
+ }),
32
+ new ol.layer.Vector({
33
+ source: source_vector = new ol.source.Vector({
34
+ features: [
35
+ new ol.Feature({
36
+ geometry: new ol.geom.LineString(pr_track_points)
37
+ })
38
+ ]
39
+ }),
40
+ style: [
41
+ new ol.style.Style({
42
+ stroke: new ol.style.Stroke({
43
+ color: 'red',
44
+ width: 5
45
+ }),
46
+ fill: new ol.style.Fill({
47
+ color: 'white'
48
+ })
49
+ })
50
+ ]
51
+ }),
52
+ new ol.layer.Vector({
53
+ source: lap_marker_source = new ol.source.Vector(),
54
+ style: function(feature, resolution) {
55
+ return [
56
+ new ol.style.Style({
57
+ stroke: new ol.style.Stroke({
58
+ color: 'black',
59
+ width: 2
60
+ }),
61
+ fill: new ol.style.Fill({
62
+ color: feature.get('color')
63
+ }),
64
+ text: new ol.style.Text({
65
+ font: '' + (lm_w / resolution) + 'px helvetica,sans-serif',
66
+ text: resolution < (lm_w / 8.0) ? feature.get('name') : '',
67
+ fill: new ol.style.Fill({
68
+ color: 'black'
69
+ })
70
+ })
71
+ })
72
+ ];
73
+ }
74
+ })
75
+ ],
76
+ target: "map"
77
+ });
78
+ for (var i in pr_lap_markers) {
79
+ x = pr_lap_markers[i][0];
80
+ y = pr_lap_markers[i][1];
81
+ lap_marker_source.addFeature(
82
+ new ol.Feature({
83
+ geometry: new ol.geom.Polygon([[[ x - lm_w, y + lm_h ],
84
+ [ x, y ],
85
+ [ x + lm_w, y + lm_h ],
86
+ [ x - lm_w, y + lm_h ]]])
87
+ })
88
+ );
89
+ lap_marker_source.addFeature(
90
+ new ol.Feature({
91
+ geometry: new ol.geom.Circle([ x, y + lm_h ], lm_w),
92
+ name: (i == 0 ? 'S' : i == pr_lap_markers.length - 1 ? 'F' : i),
93
+ color: (i == 0 ? 'green' :
94
+ i == pr_lap_markers.length - 1 ? 'red' : 'yellow'),
95
+ })
96
+ );
97
+ };
98
+ };
99
+
data/postrunner.gemspec CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "postrunner"
8
8
  spec.version = PostRunner::VERSION
9
9
  spec.authors = ["Chris Schlaeger"]
10
- spec.email = ["chris@taskjuggler.org"]
10
+ spec.email = ["cs@taskjuggler.org"]
11
11
  spec.summary = %q{Application to manage and analyze Garmin FIT files.}
12
- spec.description = %q{This application will allow you to manage and analyze .FIT files such as those generated by Garmin GPS devices. The application was developed and tested with the Garmin Forerunner 620 and Fenix 3. Other devices may work as well. They need to export the data as USB Mass Storage devices.}
12
+ spec.description = %q{This application will allow you to manage and analyze .FIT files such as those generated by Garmin GPS devices. The application was developed and tested with the Garmin Forerunner 620 and Fenix 3. Other devices may work as well. They need to export the data as USB Mass Storage devices. It is an offline alternative to Garmin Connect.}
13
13
  spec.homepage = 'https://github.com/scrapper/postrunner'
14
14
  spec.license = "GNU GPL version 2"
15
15
 
@@ -19,12 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
  spec.required_ruby_version = '>=2.0'
21
21
 
22
- spec.add_dependency 'fit4ruby', '~> 0.0.8'
23
- spec.add_dependency 'perobs', '~> 1.0.0'
22
+ spec.add_dependency 'fit4ruby', '~> 0.0.9'
23
+ spec.add_dependency 'perobs', '~> 2.2'
24
24
  spec.add_dependency 'nokogiri', '~> 1.6'
25
25
 
26
26
  spec.add_development_dependency 'bundler', '~> 1.6'
27
27
  spec.add_development_dependency 'rake', '~> 0.9.6'
28
- spec.add_development_dependency 'rspec', '~> 2.14.1'
28
+ spec.add_development_dependency 'rspec', '~> 3.4.1'
29
29
  spec.add_development_dependency 'yard', '~> 0.8.7'
30
30
  end
@@ -18,16 +18,27 @@ end
18
18
 
19
19
  describe PostRunner::ActivitySummary do
20
20
 
21
+ before(:all) do
22
+ capture_stdio
23
+ create_working_dirs
24
+ create_fit_file_store
25
+ end
26
+
21
27
  before(:each) do
22
- fa = create_fit_activity('2014-08-26-19:00', 30)
23
- a = Activity.new(fa, 'running')
24
- @as = PostRunner::ActivitySummary.new(a, :metric,
28
+ acfg = { :t => '2014-08-26T19:00', :duration => 30, :serial => 123456790 }
29
+ fn = create_fit_activity_file(@fit_dir, acfg)
30
+ fa = @ffs.add_fit_file(fn)
31
+ @as = PostRunner::ActivitySummary.new(fa, :metric,
25
32
  { :name => 'test', :type => 'Running',
26
33
  :sub_type => 'Street' })
27
34
  end
28
35
 
36
+ after(:all) do
37
+ cleanup
38
+ end
39
+
29
40
  it 'should create a metric summary' do
30
- puts @as.to_s #TODO: Fix aggregation first
41
+ @as.to_s #TODO: Fix aggregation first
31
42
  end
32
43
 
33
44
  end
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = PostRunner_spec.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014, 2015, 2016 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'spec_helper'
14
+
15
+ require 'fit4ruby/FileNameCoder'
16
+ require 'postrunner/RuntimeConfig'
17
+ require 'postrunner/FitFileStore'
18
+ require 'postrunner/PersonalRecords'
19
+
20
+ describe PostRunner::FitFileStore do
21
+
22
+ before(:all) do
23
+ capture_stdio
24
+ create_working_dirs
25
+ create_fit_file_store
26
+
27
+ # Create some test fit files
28
+ @fit_file_names = []
29
+ [
30
+ { :t => '2015-10-21T21:00', :duration => 10, :serial => 123456790 },
31
+ { :t => '2015-10-22T08:10', :duration => 15, :serial => 123456791 },
32
+ { :t => '2015-11-01T13:30', :duration => 20, :serial => 123456790 }
33
+ ].each do |config|
34
+ f = create_fit_activity_file(@fit_dir, config)
35
+ @fit_file_names << f
36
+ end
37
+ @activities = []
38
+ end
39
+
40
+ after(:all) do
41
+ cleanup
42
+ end
43
+
44
+ it 'should be empty at start' do
45
+ expect(@ffs.devices.length).to eq(0)
46
+ expect(@ffs.activities.length).to eq(0)
47
+ end
48
+
49
+ it 'should store a FIT file' do
50
+ @activities << @ffs.add_fit_file(@fit_file_names[0])
51
+ expect(@activities[-1]).not_to be_nil
52
+
53
+ expect(@ffs.devices.length).to eq(1)
54
+ expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true
55
+ expect(@ffs.activities.length).to eq(1)
56
+ expect(@ffs.ref_by_activity(@activities[0])).to eq(1)
57
+ end
58
+
59
+ it 'should not store the same FIT file twice' do
60
+ expect(@ffs.add_fit_file(@fit_file_names[0])).to be_nil
61
+
62
+ expect(@ffs.devices.length).to eq(1)
63
+ expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true
64
+ expect(@ffs.activities.length).to eq(1)
65
+ end
66
+
67
+ it 'should store another FIT file as 2nd device' do
68
+ @activities << @ffs.add_fit_file(@fit_file_names[1])
69
+ expect(@activities[-1]).not_to be_nil
70
+
71
+ expect(@ffs.devices.length).to eq(2)
72
+ expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true
73
+ expect(@ffs.devices.include?('garmin-fenix3-123456791')).to be true
74
+ expect(@ffs.activities.length).to eq(2)
75
+ expect(@ffs.ref_by_activity(@activities[1])).to eq(1)
76
+ end
77
+
78
+ it 'should store another activity of a known device' do
79
+ @activities << @ffs.add_fit_file(@fit_file_names[2])
80
+ expect(@activities[-1]).not_to be_nil
81
+
82
+ expect(@ffs.devices.length).to eq(2)
83
+ expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true
84
+ expect(@ffs.devices.include?('garmin-fenix3-123456791')).to be true
85
+ expect(@ffs.activities.length).to eq(3)
86
+ expect(@ffs.ref_by_activity(@activities[2])).to eq(1)
87
+ end
88
+
89
+ it 'should find activities by index' do
90
+ expect(@ffs.find('0')).to eq([])
91
+ expect(@ffs.find('1')).to eq([ @activities[2] ])
92
+ expect(@ffs.find('2')).to eq([ @activities[1] ])
93
+ expect(@ffs.find('3')).to eq([ @activities[0] ])
94
+ expect(@ffs.find('1-2')).to eq([ @activities[2], @activities[1] ])
95
+ expect(@ffs.find('2-1')).to eq([])
96
+ expect(@ffs.find('')).to eq([])
97
+ end
98
+
99
+ it 'should check all stored fit files' do
100
+ @ffs.check
101
+ end
102
+
103
+ it 'should know the successor of each activity' do
104
+ expect(@ffs.successor(@activities[2])).to be_nil
105
+ expect(@ffs.successor(@activities[1])).to eq(@activities[2])
106
+ expect(@ffs.successor(@activities[0])).to eq(@activities[1])
107
+ end
108
+
109
+ it 'should know the predecessor of each activity' do
110
+ expect(@ffs.predecessor(@activities[2])).to eq(@activities[1])
111
+ expect(@ffs.predecessor(@activities[1])).to eq(@activities[0])
112
+ expect(@ffs.predecessor(@activities[0])).to be_nil
113
+ end
114
+
115
+ it 'should delete activities' do
116
+ @ffs.delete_activity(@activities[1])
117
+ expect(@ffs.find('1')).to eq([ @activities[2] ])
118
+ expect(@ffs.find('2')).to eq([ @activities[0] ])
119
+ expect(@ffs.find('3')).to eq([])
120
+
121
+ @ffs.delete_activity(@activities[2])
122
+ expect(@ffs.find('1')).to eq([ @activities[0] ])
123
+ expect(@ffs.find('2')).to eq([])
124
+ end
125
+
126
+ it 'should rename an activity' do
127
+ @ffs.rename_activity(@activities[0], 'new name')
128
+ expect(@activities[0].name).to eq('new name')
129
+ expect(@activities[0].fit_file_name).to eq(File.basename(@fit_file_names[0]))
130
+ end
131
+
132
+ end
133
+
@@ -26,7 +26,7 @@ describe PostRunner::FlexiTable do
26
26
  |ccc|ddddd|
27
27
  +---+-----+
28
28
  EOT
29
- t.to_s.should == ref
29
+ expect(t.to_s).to eq(ref)
30
30
  end
31
31
 
32
32
  end
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = PostRunner_spec.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
+ #
6
+ # Copyright (c) 2014, 2015, 2016 by Chris Schlaeger <cs@taskjuggler.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'spec_helper'
14
+ require 'perobs'
15
+
16
+ require 'fit4ruby/FileNameCoder'
17
+ require 'postrunner/FitFileStore'
18
+ require 'postrunner/PersonalRecords'
19
+
20
+ describe PostRunner::PersonalRecords do
21
+
22
+ class Mock_Activity < PEROBS::Object
23
+
24
+ po_attr :name, :fit_file_name
25
+
26
+ def initialize(store, name = nil)
27
+ super(store)
28
+ init_attr(:name, name)
29
+ init_attr(:fit_file_name, name)
30
+ end
31
+
32
+ end
33
+
34
+ class Mock_FitFileStore < PEROBS::Object
35
+
36
+ po_attr :activities
37
+
38
+ def initialize(store)
39
+ super
40
+ init_attr(:activities, @store.new(PEROBS::Array))
41
+ end
42
+
43
+ def add_activity(a)
44
+ @activities << a
45
+ end
46
+
47
+ def ref_by_activity(a)
48
+ @activities.index(a) + 1
49
+ end
50
+
51
+ end
52
+
53
+ before(:all) do
54
+ @log = StringIO.new
55
+ Fit4Ruby::Log.open(@log)
56
+ @work_dir = tmp_dir_name(__FILE__)
57
+ Dir.mkdir(@work_dir)
58
+
59
+ # Create the FitFileStore
60
+ @store = PEROBS::Store.new(File.join(@work_dir, 'db'))
61
+ @store['config'] = @store.new(PEROBS::Hash)
62
+ @store['config']['data_dir'] = @work_dir
63
+ @ffs = @store['file_store'] = @store.new(Mock_FitFileStore)
64
+ @records = @store['records'] = @store.new(PostRunner::PersonalRecords)
65
+ end
66
+
67
+ after(:all) do
68
+ FileUtils.rm_rf(@work_dir)
69
+ end
70
+
71
+ it 'should initialize properly' do
72
+ expect(@records.to_s).to eq('')
73
+ end
74
+
75
+ it 'should register a record' do
76
+ a = @store.new(Mock_Activity, 'Activity 1')
77
+ @ffs.add_activity(a)
78
+ t = Time.parse('2014-11-08T09:16:00')
79
+ expect(@records.register_result(a, 'running', 5000.0, 20 * 60,
80
+ t)).to be true
81
+ expect(@records.register_result(a, 'running', 5000.0, nil, t)).to be true
82
+ expect(@records.activity_records(a).length).to eq(4)
83
+ expect(tables_to_arrays(@records.to_s)).to eq([
84
+ [["5 km", "0:20:00", "4:00", "1", "Activity 1", "2014-11-08"],
85
+ ["Longest Distance", "5.000 km", "-", "1", "Activity 1", "2014-11-08"]],
86
+ [["5 km", "0:20:00", "4:00", "1", "Activity 1", "2014-11-08"],
87
+ ["Longest Distance", "5.000 km", "-", "1", "Activity 1", "2014-11-08"]]
88
+ ])
89
+ end
90
+
91
+ it 'should register another record' do
92
+ a = @store.new(Mock_Activity, 'Activity 2')
93
+ @ffs.add_activity(a)
94
+ t = Time.parse('2014-11-09T09:16:00')
95
+ expect(@records.register_result(a, 'running', 10000.0,
96
+ 42 * 60, t)).to be true
97
+ expect(@records.register_result(a, 'running', 10000.0,
98
+ nil, t)).to be true
99
+ expect(@records.activity_records(a).length).to eq(4)
100
+ expect(tables_to_arrays(@records.to_s)).to eq([
101
+ [["5 km", "0:20:00", "4:00", "1", "Activity 1", "2014-11-08"],
102
+ ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
103
+ ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]],
104
+ [["5 km", "0:20:00", "4:00", "1", "Activity 1", "2014-11-08"],
105
+ ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
106
+ ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]],
107
+ ])
108
+ end
109
+
110
+ it 'should replace an old record with a new one' do
111
+ a = @store.new(Mock_Activity, 'Activity 3')
112
+ @ffs.add_activity(a)
113
+ t = Time.parse('2014-11-11T09:16:00')
114
+ expect(@records.register_result(a, 'running', 5000.0,
115
+ 19 * 60, t)).to be true
116
+ expect(@records.activity_records(a).length).to eq (2)
117
+ expect(@records.activity_records(@ffs.activities[0]).length).to eq(0)
118
+ expect(tables_to_arrays(@records.to_s)).to eq([
119
+ [["5 km", "0:19:00", "3:47", "3", "Activity 3", "2014-11-11"],
120
+ ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
121
+ ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]],
122
+ [["5 km", "0:19:00", "3:47", "3", "Activity 3", "2014-11-11"],
123
+ ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
124
+ ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]],
125
+ ])
126
+ end
127
+
128
+ it 'should add a new table for a new year' do
129
+ a = @store.new(Mock_Activity, 'Activity 4')
130
+ @ffs.add_activity(a)
131
+ t = Time.parse('2015-01-01T06:00:00')
132
+ expect(@records.register_result(a, 'running', 5000.0,
133
+ 21 * 60, t)).to be true
134
+ expect(@records.activity_records(a).length).to eq(1)
135
+ expect(tables_to_arrays(@records.to_s)).to eq([
136
+ [["5 km", "0:19:00", "3:47", "3", "Activity 3", "2014-11-11"],
137
+ ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
138
+ ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]],
139
+ [["5 km", "0:21:00", "4:12", "4", "Activity 4", "2015-01-01"]],
140
+ [["5 km", "0:19:00", "3:47", "3", "Activity 3", "2014-11-11"],
141
+ ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
142
+ ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]],
143
+ ])
144
+ end
145
+
146
+ it 'should not add a new record for poor result' do
147
+ a = @store.new(Mock_Activity, 'Activity 5')
148
+ @ffs.add_activity(a)
149
+ t = Time.parse('2015-01-02T10:00:00')
150
+ expect(@records.register_result(a, 'running', 5000.0, 22 * 60,
151
+ t)).to be false
152
+ expect(@records.activity_records(a).length).to eq(0)
153
+ end
154
+
155
+ it 'should not delete a record for non-record activity' do
156
+ expect(@records.delete_activity(@ffs.activities[0])).to be false
157
+ end
158
+
159
+ it 'should delete a record for a record activity' do
160
+ expect(@records.delete_activity(@ffs.activities[2])).to be true
161
+ expect(tables_to_arrays(@records.to_s)).to eq([
162
+ [["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
163
+ ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]],
164
+ [["5 km", "0:21:00", "4:12", "4", "Activity 4", "2015-01-01"]],
165
+ [["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
166
+ ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]],
167
+ ])
168
+ end
169
+
170
+ it 'should add a new distance record' do
171
+ a = @store.new(Mock_Activity, 'Activity 6')
172
+ @ffs.add_activity(a)
173
+ t = Time.parse('2015-01-10T07:00:00')
174
+ expect(@records.register_result(a, 'running', 15000.0, nil, t)).to be true
175
+ expect(@records.activity_records(a).length).to eq(2)
176
+ expect(tables_to_arrays(@records.to_s)).to eq([
177
+ [ ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
178
+ ["Longest Distance", "15.000 km", "-", "6", "Activity 6", "2015-01-10"]],
179
+ [["5 km", "0:21:00", "4:12", "4", "Activity 4", "2015-01-01"],
180
+ ["Longest Distance", "15.000 km", "-", "6", "Activity 6", "2015-01-10"]],
181
+ [["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"],
182
+ ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]],
183
+ ])
184
+ end
185
+
186
+ it 'should not register a record for a bogus sport' do
187
+ a = @store.new(Mock_Activity, 'Activity 5')
188
+ @ffs.add_activity(a)
189
+ t = Time.parse('2015-04-01T11:11:11')
190
+ expect(@records.register_result(a, 'foobaring', 5000.0, 10 * 60,
191
+ t)).to be false
192
+ end
193
+
194
+ it 'should not register a record for unknown distance' do
195
+ a = @store.new(Mock_Activity, 'Activity 6')
196
+ @ffs.add_activity(a)
197
+ expect { @records.register_result(a, 'cycling', 42.0, 10 * 60,
198
+ Time.parse('2015-04-01T11:11:11'))}.to raise_error(Fit4Ruby::Error)
199
+ end
200
+
201
+ it 'should delete all records' do
202
+ @records.delete_all_records
203
+ expect(@records.to_s).to eq('')
204
+ end
205
+
206
+ end