postrunner 0.0.11 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # = PostRunner_spec.rb -- PostRunner - Manage the data from your Garmin sport devices.
5
5
  #
6
- # Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
6
+ # Copyright (c) 2014, 2015, 2016 by Chris Schlaeger <cs@taskjuggler.org>
7
7
  #
8
8
  # This program is free software; you can redistribute it and/or modify
9
9
  # it under the terms of version 2 of the GNU General Public License as
@@ -21,31 +21,37 @@ describe PostRunner::Main do
21
21
  args = [ '--dbdir', @db_dir ] + args
22
22
  old_stdout = $stdout
23
23
  $stdout = (stdout = StringIO.new)
24
- PostRunner::Main.new(args)
24
+ @postrunner = nil
25
+ GC.start
26
+ @postrunner = PostRunner::Main.new(args)
25
27
  $stdout = old_stdout
26
28
  stdout.string
27
29
  end
28
30
 
29
31
  before(:all) do
30
- @work_dir = tmp_dir_name(__FILE__)
31
- Dir.mkdir(@work_dir)
32
+ capture_stdio
33
+ create_working_dirs
34
+
32
35
  @db_dir = File.join(@work_dir, '.postrunner')
33
- @file1 = File.join(@work_dir, 'FILE1.FIT')
34
- @file2 = File.join(@work_dir, 'FILE2.FIT')
35
- create_fit_file(@file1, '2014-07-01-8:00')
36
- create_fit_file(@file2, '2014-07-02-8:00')
36
+ @opts = { :t => '2014-07-01-8:00', :speed => 11.0 }
37
+ @file1 = create_fit_activity_file(@work_dir, @opts)
38
+ @opts[:t] = '2014-07-02-8:00'
39
+ @file2 = create_fit_activity_file(@work_dir, @opts)
40
+ @opts[:t] = '2014-07-03-8:00'
41
+ @opts[:speed] = 12.5
42
+ @file3 = create_fit_activity_file(@work_dir, @opts)
37
43
  end
38
44
 
39
45
  after(:all) do
40
- FileUtils.rm_rf(@work_dir)
46
+ cleanup
41
47
  end
42
48
 
43
49
  it 'should abort without arguments' do
44
- lambda { postrunner([]) }.should raise_error Fit4Ruby::Error
50
+ expect { postrunner([]) }.to raise_error(Fit4Ruby::Error)
45
51
  end
46
52
 
47
53
  it 'should abort with bad command' do
48
- lambda { postrunner(%w( foobar)) }.should raise_error Fit4Ruby::Error
54
+ expect { postrunner(%w( foobar)) }.to raise_error(Fit4Ruby::Error)
49
55
  end
50
56
 
51
57
  it 'should support the -v option' do
@@ -73,77 +79,76 @@ describe PostRunner::Main do
73
79
  end
74
80
 
75
81
  it 'should list the imported file' do
76
- postrunner(%w( list )).index('FILE1').should be_a(Fixnum)
82
+ expect(postrunner(%w( list )).index(File.basename(@file1))).to be_a(Fixnum)
77
83
  end
78
84
 
79
- it 'should import the other FIT file' do
80
- postrunner([ 'import', @work_dir ])
85
+ it 'should import the 2nd FIT file' do
86
+ postrunner([ 'import', @file2 ])
81
87
  list = postrunner(%w( list ))
82
- list.index('FILE1.FIT').should be_a(Fixnum)
83
- list.index('FILE2.FIT').should be_a(Fixnum)
84
- rc = YAML::load_file(File.join(@db_dir, 'config.yml'))
85
- rc[:import_dir].should == @work_dir
86
-
87
- template = "<a href=\"%s.html\"><img src=\"icons/%s.png\" " +
88
- "class=\"active_button\">"
89
- html1 = File.read(File.join(@db_dir, 'html', 'FILE1.html'))
90
- html1.include?(template % ['FILE2', 'forward']).should be_true
91
- html2 = File.read(File.join(@db_dir, 'html', 'FILE2.html'))
92
- html2.include?(template % ['FILE1', 'back']).should be_true
88
+ expect(list.index(File.basename(@file1))).to be_a(Fixnum)
89
+ expect(list.index(File.basename(@file2))).to be_a(Fixnum)
93
90
  end
94
91
 
95
92
  it 'should delete the first file' do
96
93
  postrunner(%w( delete :2 ))
97
94
  list = postrunner(%w( list ))
98
- list.index('FILE1.FIT').should be_nil
99
- list.index('FILE2.FIT').should be_a(Fixnum)
95
+ expect(list.index(File.basename(@file1))).to be_nil
96
+ expect(list.index(File.basename(@file2))).to be_a(Fixnum)
100
97
  end
101
98
 
102
99
  it 'should not import the deleted file again' do
103
- postrunner(%w( import . ))
100
+ postrunner([ 'import', @file1 ])
104
101
  list = postrunner(%w( list ))
105
- list.index('FILE1.FIT').should be_nil
106
- list.index('FILE2.FIT').should be_a(Fixnum)
102
+ expect(list.index(File.basename(@file1))).to be_nil
103
+ expect(list.index(File.basename(@file2))).to be_a(Fixnum)
107
104
  end
108
105
 
109
106
  it 'should rename FILE2.FIT activity' do
110
107
  postrunner(%w( rename foobar :1 ))
111
108
  list = postrunner(%w( list ))
112
- list.index(@file2).should be_nil
113
- list.index('foobar').should be_a(Fixnum)
109
+ expect(list.index(File.basename(@file2))).to be_nil
110
+ expect(list.index('foobar')).to be_a(Fixnum)
114
111
  end
115
112
 
116
113
  it 'should fail when setting bad attribute' do
117
- lambda { postrunner(%w( set foo bar :1)) }.should raise_error Fit4Ruby::Error
114
+ expect { postrunner(%w( set foo bar :1)) }.to raise_error(Fit4Ruby::Error)
118
115
  end
119
116
 
120
- it 'should set name for FILE2.FIT activity' do
117
+ it 'should set name for 2nd activity' do
121
118
  postrunner(%w( set name foobar :1 ))
122
119
  list = postrunner(%w( list ))
123
- list.index(@file2).should be_nil
124
- list.index('foobar').should be_a(Fixnum)
120
+ expect(list.index(@file2)).to be_nil
121
+ expect(list.index('foobar')).to be_a(Fixnum)
125
122
  end
126
123
 
127
- it 'should set activity type for FILE2.FIT activity' do
124
+ it 'should set activity type for 2nd activity' do
128
125
  postrunner(%w( set type Cycling :1 ))
129
126
  list = postrunner(%w( summary :1 ))
130
- list.index('Running').should be_nil
131
- list.index('Cycling').should be_a(Fixnum)
127
+ expect(list.index('Running')).to be_nil
128
+ expect(list.index('Cycling')).to be_a(Fixnum)
129
+ end
130
+
131
+ it 'should list the events of an activity' do
132
+ postrunner(%w( events :1 ))
133
+ end
134
+
135
+ it 'should list the data sources of an activity' do
136
+ postrunner(%w( sources :1 ))
132
137
  end
133
138
 
134
139
  it 'should fail when setting bad activity type' do
135
- lambda { postrunner(%w( set type foobar :1)) }.should raise_error Fit4Ruby::Error
140
+ expect { postrunner(%w( set type foobar :1)) }.to raise_error(Fit4Ruby::Error)
136
141
  end
137
142
 
138
143
  it 'should set activity subtype for FILE2.FIT activity' do
139
144
  postrunner(%w( set subtype Road :1 ))
140
145
  list = postrunner(%w( summary :1 ))
141
- list.index('Generic').should be_nil
142
- list.index('Road').should be_a(Fixnum)
146
+ expect(list.index('Generic')).to be_nil
147
+ expect(list.index('Road')).to be_a(Fixnum)
143
148
  end
144
149
 
145
150
  it 'should fail when setting bad activity subtype' do
146
- lambda { postrunner(%w( set subtype foobar :1)) }.should raise_error Fit4Ruby::Error
151
+ expect { postrunner(%w( set subtype foobar :1)) }.to raise_error(Fit4Ruby::Error)
147
152
  end
148
153
 
149
154
  it 'should dump an activity from the archive' do
@@ -162,25 +167,24 @@ describe PostRunner::Main do
162
167
  postrunner(%w( units metric ))
163
168
  end
164
169
 
165
- it 'should properly upgrade to a new version' do
166
- # Change version in config file to 0.0.0.
167
- rc = PostRunner::RuntimeConfig.new(@db_dir)
168
- rc.set_option(:version, '0.0.0')
169
- # Check that the config file really was changed.
170
- rc = PostRunner::RuntimeConfig.new(@db_dir)
171
- rc.get_option(:version).should == '0.0.0'
172
-
173
- archive_file = File.join(@db_dir, 'archive.yml')
174
- archive = YAML.load_file(archive_file)
175
- archive.each { |a| a.remove_instance_variable:@sport }
176
- File.write(archive_file, archive.to_yaml)
170
+ it 'should list records' do
171
+ # Add slow running activity
172
+ postrunner([ 'import', '--force', @file1 ])
173
+ list = postrunner([ 'records' ])
174
+ expect(list.index(File.basename(@file1))).to be_a(Fixnum)
177
175
 
178
- # Run some command.
179
- postrunner(%w( list ))
176
+ # Add fast running activity
177
+ postrunner([ 'import', @file3 ])
178
+ list = postrunner([ 'records' ])
179
+ expect(list.index(File.basename(@file3))).to be_a(Fixnum)
180
+ expect(list.index(File.basename(@file1))).to be_nil
181
+ end
180
182
 
181
- # Check that version matches the current version again.
182
- rc = PostRunner::RuntimeConfig.new(@db_dir)
183
- rc.get_option(:version).should == PostRunner::VERSION
183
+ it 'should ignore records of an activity' do
184
+ postrunner(%w( set norecord true :1 ))
185
+ list = postrunner([ 'records' ])
186
+ expect(list.index(File.basename(@file1))).to be_a(Fixnum)
187
+ expect(list.index(File.basename(@file3))).to be_nil
184
188
  end
185
189
 
186
190
  end
data/spec/View_spec.rb CHANGED
@@ -52,7 +52,7 @@ module PostRunner
52
52
  pages.current_page = file
53
53
  PostRunner::View.new("Test File: #{file}", views, pages).body.
54
54
  write(file)
55
- File.exists?(file).should be true
55
+ expect(File.exists?(file)).to be true
56
56
  end
57
57
  end
58
58
  end
data/spec/spec_helper.rb CHANGED
@@ -19,6 +19,16 @@ require 'fileutils'
19
19
  $:.unshift(File.join(File.dirname(__FILE__), '..', '..', lib_dir, 'lib'))
20
20
  end
21
21
 
22
+ require 'fit4ruby'
23
+ require 'perobs'
24
+ require 'postrunner/FitFileStore'
25
+ require 'postrunner/PersonalRecords'
26
+
27
+ def capture_stdio
28
+ @log = StringIO.new
29
+ Fit4Ruby::Log.open(@log)
30
+ end
31
+
22
32
  def tmp_dir_name(caller_file)
23
33
  begin
24
34
  dir_name = File.join(Dir.tmpdir,
@@ -28,6 +38,29 @@ def tmp_dir_name(caller_file)
28
38
  dir_name
29
39
  end
30
40
 
41
+ def create_working_dirs
42
+ @work_dir = tmp_dir_name(__FILE__)
43
+ Dir.mkdir(@work_dir)
44
+ @fit_dir = File.join(@work_dir, 'fit')
45
+ Dir.mkdir(@fit_dir)
46
+ @html_dir = File.join(@work_dir, 'html')
47
+ Dir.mkdir(@html_dir)
48
+ end
49
+
50
+ def cleanup
51
+ FileUtils.rm_rf(@work_dir)
52
+ end
53
+
54
+ def create_fit_file_store
55
+ store = PEROBS::Store.new(File.join(@work_dir, 'db'))
56
+ store['config'] = store.new(PEROBS::Hash)
57
+ store['config']['data_dir'] = @work_dir
58
+ store['config']['html_dir'] = @html_dir
59
+ store['config']['unit_system'] = :metric
60
+ @ffs = store['file_store'] = store.new(PostRunner::FitFileStore)
61
+ @records = store['records'] = store.new(PostRunner::PersonalRecords)
62
+ end
63
+
31
64
  def create_fit_file(name, date, duration_minutes = 30)
32
65
  Fit4Ruby.write(name, create_fit_activity(
33
66
  { :t => date, :duration => duration_minutes }))
@@ -63,14 +96,17 @@ def create_fit_activity(config)
63
96
  :garmin_product => 'sdm4',
64
97
  :device_index => 1, :battery_status => 'ok' })
65
98
  laps = 0
99
+ curr_speed = (config[:speed] ? config[:speed] : 10.0) / 3.6 # as m/s
100
+ curr_distance = 0.0 # as m
66
101
  0.upto((a.total_timer_time / 60) - 1) do |mins|
102
+ curr_speed -= 0.05 if curr_speed > 2.5
67
103
  a.new_record({
68
104
  :timestamp => ts,
69
105
  :position_lat => 51.5512 - mins * 0.0008,
70
106
  :position_long => 11.647 + mins * 0.002,
71
- :distance => 200.0 * mins,
107
+ :distance => curr_distance += curr_speed * 60,
72
108
  :altitude => 100 + mins * 3,
73
- :speed => 3.1,
109
+ :speed => curr_speed,
74
110
  :vertical_oscillation => 90 + mins * 0.2,
75
111
  :stance_time => 235.0 * mins * 0.01,
76
112
  :stance_time_percent => 32.0,
@@ -112,4 +148,42 @@ def create_fit_activity(config)
112
148
  a
113
149
  end
114
150
 
151
+ def tables_to_arrays(str)
152
+ mode = :searching_table
153
+ arrays = []
154
+ array = []
155
+ str.each_line do |line|
156
+ case mode
157
+ when :searching_table
158
+ if line[0] == '+'
159
+ mode = :header
160
+ end
161
+ when :header
162
+ if line[0] == '|'
163
+ mode = :separation_line
164
+ else
165
+ mode = :searching_table
166
+ end
167
+ when :separation_line
168
+ if line[0] == '+'
169
+ mode = :body
170
+ else
171
+ mode = :searching_table
172
+ end
173
+ when :body
174
+ if line[0] == '|'
175
+ array << line[1..-3].split('|').map(&:strip)
176
+ elsif line[0] == '+'
177
+ arrays << array
178
+ array = []
179
+ mode = :searching_table
180
+ else
181
+ array = []
182
+ mode = :searching_table
183
+ end
184
+ end
185
+ end
186
+
187
+ arrays
188
+ end
115
189
 
metadata CHANGED
@@ -1,125 +1,126 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postrunner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Schlaeger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-26 00:00:00.000000000 Z
11
+ date: 2016-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fit4ruby
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.8
19
+ version: 0.0.9
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.0.8
26
+ version: 0.0.9
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: perobs
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.0
33
+ version: '2.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.0.0
40
+ version: '2.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: nokogiri
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.6'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.6'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.6'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.6'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: 0.9.6
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.9.6
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ~>
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 2.14.1
89
+ version: 3.4.1
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ~>
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 2.14.1
96
+ version: 3.4.1
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: yard
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ~>
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: 0.8.7
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ~>
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: 0.8.7
111
111
  description: This application will allow you to manage and analyze .FIT files such
112
112
  as those generated by Garmin GPS devices. The application was developed and tested
113
113
  with the Garmin Forerunner 620 and Fenix 3. Other devices may work as well. They
114
- need to export the data as USB Mass Storage devices.
114
+ need to export the data as USB Mass Storage devices. It is an offline alternative
115
+ to Garmin Connect.
115
116
  email:
116
- - chris@taskjuggler.org
117
+ - cs@taskjuggler.org
117
118
  executables:
118
119
  - postrunner
119
120
  extensions: []
120
121
  extra_rdoc_files: []
121
122
  files:
122
- - .gitignore
123
+ - ".gitignore"
123
124
  - COPYING
124
125
  - Gemfile
125
126
  - README.md
@@ -136,14 +137,22 @@ files:
136
137
  - lib/postrunner/ChartView.rb
137
138
  - lib/postrunner/DataSources.rb
138
139
  - lib/postrunner/DeviceList.rb
140
+ - lib/postrunner/DirUtils.rb
139
141
  - lib/postrunner/EPO_Downloader.rb
142
+ - lib/postrunner/EventList.rb
143
+ - lib/postrunner/FFS_Activity.rb
144
+ - lib/postrunner/FFS_Device.rb
145
+ - lib/postrunner/FitFileStore.rb
140
146
  - lib/postrunner/FlexiTable.rb
147
+ - lib/postrunner/HRV_Analyzer.rb
141
148
  - lib/postrunner/HTMLBuilder.rb
149
+ - lib/postrunner/LinearPredictor.rb
142
150
  - lib/postrunner/Log.rb
143
151
  - lib/postrunner/Main.rb
144
152
  - lib/postrunner/MonitoringDB.rb
145
153
  - lib/postrunner/NavButtonRow.rb
146
154
  - lib/postrunner/PagingButtons.rb
155
+ - lib/postrunner/Percentiles.rb
147
156
  - lib/postrunner/PersonalRecords.rb
148
157
  - lib/postrunner/QueryResult.rb
149
158
  - lib/postrunner/RecordListPageView.rb
@@ -286,9 +295,12 @@ files:
286
295
  - misc/jquery/jquery-2.1.1.min.js
287
296
  - misc/openlayers/ol.css
288
297
  - misc/openlayers/ol.js
298
+ - misc/postrunner/trackview.js
289
299
  - postrunner.gemspec
290
300
  - spec/ActivitySummary_spec.rb
301
+ - spec/FitFileStore_spec.rb
291
302
  - spec/FlexiTable_spec.rb
303
+ - spec/PersonalRecords_spec.rb
292
304
  - spec/PostRunner_spec.rb
293
305
  - spec/View_spec.rb
294
306
  - spec/spec_helper.rb
@@ -302,23 +314,25 @@ require_paths:
302
314
  - lib
303
315
  required_ruby_version: !ruby/object:Gem::Requirement
304
316
  requirements:
305
- - - '>='
317
+ - - ">="
306
318
  - !ruby/object:Gem::Version
307
319
  version: '2.0'
308
320
  required_rubygems_version: !ruby/object:Gem::Requirement
309
321
  requirements:
310
- - - '>='
322
+ - - ">="
311
323
  - !ruby/object:Gem::Version
312
324
  version: '0'
313
325
  requirements: []
314
326
  rubyforge_project:
315
- rubygems_version: 2.0.3
327
+ rubygems_version: 2.4.5.1
316
328
  signing_key:
317
329
  specification_version: 4
318
330
  summary: Application to manage and analyze Garmin FIT files.
319
331
  test_files:
320
332
  - spec/ActivitySummary_spec.rb
333
+ - spec/FitFileStore_spec.rb
321
334
  - spec/FlexiTable_spec.rb
335
+ - spec/PersonalRecords_spec.rb
322
336
  - spec/PostRunner_spec.rb
323
337
  - spec/View_spec.rb
324
338
  - spec/spec_helper.rb