fit4ruby 3.3.0 → 3.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c76d1a2e0091c4aa84e7e26a381630def4b5e5b0
4
- data.tar.gz: 21814b487808a93810dfedf2fe4908d7f9ecf246
2
+ SHA256:
3
+ metadata.gz: '0478b4abeb404d3c3dfab616289182d37b280c0090cb3be1771e9acd78a38ae0'
4
+ data.tar.gz: 11e8f45f61cb2780bdd155eb2cf87e0d7952a5b4a079d5fdf8b3f6df0849a9b3
5
5
  SHA512:
6
- metadata.gz: fbb6bf23b5adadb57b114444de5d067b13273bb73537e76b6a8b6436e61a5fea69af8f619625369ac5c6c9fd13018a31514e3e1662d8437f33ba71b8a52b949e
7
- data.tar.gz: 5404ca45effe3b389041a036711c55006c95f304f4afa91a888c2dfda4f38ad2fc55faf450e23791cfd571c6b0c9373865161b881e87e53e268af36e93f130a3
6
+ metadata.gz: fbd0bcb013b1736e18b307f389f95967b3cb34b96c0ed113fef48add5604d5ef39c745e53a7612b69b61cf1a16a8ce688d3bbcddd136985b8a6a79b24943c120
7
+ data.tar.gz: 8de75daacdbb990b3fc2334891d9fa39f20911255a788ab5c7863610ea7f0eb344612bf24fe740f143110477a04b4bad46398d6575944dca89a7bba3feb7591c
data/Gemfile.lock CHANGED
@@ -1,15 +1,34 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fit4ruby (0.0.1)
5
- bindata (>= 2.0.0)
4
+ fit4ruby (3.3.0)
5
+ bindata (= 2.3.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- bindata (2.1.0)
10
+ bindata (2.3.0)
11
+ coderay (1.1.2)
12
+ diff-lcs (1.3)
13
+ method_source (0.9.2)
14
+ pry (0.12.2)
15
+ coderay (~> 1.1.0)
16
+ method_source (~> 0.9.0)
11
17
  rake (0.9.6)
12
- yard (0.8.7.4)
18
+ rspec (3.8.0)
19
+ rspec-core (~> 3.8.0)
20
+ rspec-expectations (~> 3.8.0)
21
+ rspec-mocks (~> 3.8.0)
22
+ rspec-core (3.8.2)
23
+ rspec-support (~> 3.8.0)
24
+ rspec-expectations (3.8.4)
25
+ diff-lcs (>= 1.2.0, < 2.0)
26
+ rspec-support (~> 3.8.0)
27
+ rspec-mocks (3.8.1)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.8.0)
30
+ rspec-support (3.8.2)
31
+ yard (0.9.20)
13
32
 
14
33
  PLATFORMS
15
34
  ruby
@@ -17,5 +36,10 @@ PLATFORMS
17
36
  DEPENDENCIES
18
37
  bundler (>= 1.6.4)
19
38
  fit4ruby!
20
- rake
21
- yard
39
+ pry (>= 0.12)
40
+ rake (~> 0.9.6)
41
+ rspec (>= 3.8)
42
+ yard (~> 0.9.20)
43
+
44
+ BUNDLED WITH
45
+ 2.0.2
data/fit4ruby.gemspec CHANGED
@@ -28,4 +28,6 @@ EOT
28
28
  spec.add_development_dependency('yard', '~>0.9.20')
29
29
  spec.add_development_dependency('rake', '~>0.9.6')
30
30
  spec.add_development_dependency('bundler', '>=1.6.4')
31
+ spec.add_development_dependency('rspec', '>=3.8')
32
+ spec.add_development_dependency('pry', '>=0.12')
31
33
  end
@@ -24,6 +24,7 @@ require 'fit4ruby/UserProfile'
24
24
  require 'fit4ruby/PhysiologicalMetrics'
25
25
  require 'fit4ruby/Session'
26
26
  require 'fit4ruby/Lap'
27
+ require 'fit4ruby/Length'
27
28
  require 'fit4ruby/Record'
28
29
  require 'fit4ruby/HRV'
29
30
  require 'fit4ruby/HeartRateZones'
@@ -40,7 +41,7 @@ module Fit4Ruby
40
41
  attr_accessor :file_id, :field_descriptions, :developer_data_ids, :epo_data,
41
42
  :file_creator, :device_infos, :sensor_settings, :data_sources,
42
43
  :user_data, :user_profiles, :physiological_metrics,
43
- :sessions, :laps, :records, :hrv,
44
+ :sessions, :laps, :records, :lengths, :hrv,
44
45
  :heart_rate_zones, :events, :personal_records
45
46
 
46
47
  # Create a new Activity object.
@@ -65,15 +66,21 @@ module Fit4Ruby
65
66
  @events = []
66
67
  @sessions = []
67
68
  @laps = []
69
+ @lengths = []
68
70
  @records = []
69
71
  @hrv = []
70
72
  @heart_rate_zones = []
71
73
  @personal_records = []
72
74
 
73
75
  @cur_session_laps = []
76
+
74
77
  @cur_lap_records = []
78
+ @cur_lap_lengths = []
79
+
80
+ @cur_length_records = []
75
81
 
76
82
  @lap_counter = 1
83
+ @length_counter = 1
77
84
 
78
85
  set_field_values(field_values)
79
86
  end
@@ -141,11 +148,20 @@ module Fit4Ruby
141
148
 
142
149
  # Laps must have a consecutively growing message index.
143
150
  @laps.each.with_index do |lap, index|
144
- lap.check(index)
151
+ lap.check(index, self)
145
152
  # If we have heart rate zone records, there should be one for each
146
153
  # lap
147
154
  @heart_rate_zones[index].check(index) if @heart_rate_zones[index]
148
155
  end
156
+
157
+ # Lengths must have a consecutively growing message index.
158
+ @lengths.each.with_index do |length, index|
159
+ length.check(index)
160
+ # If we have heart rate zone records, there should be one for each
161
+ # length
162
+ @heart_rate_zones[index].check(index) if @heart_rate_zones[index]
163
+ end
164
+
149
165
  @sessions.each { |s| s.check(self) }
150
166
  end
151
167
 
@@ -206,17 +222,22 @@ module Fit4Ruby
206
222
  d
207
223
  end
208
224
 
209
- # Call this method to update the aggregated data fields stored in Lap and
210
- # Session objects.
225
+ # Call this method to update the aggregated data fields stored in Lap,
226
+ # Length, and Session objects.
211
227
  def aggregate
212
228
  @laps.each { |l| l.aggregate }
229
+ @lengths.each { |l| l.aggregate }
213
230
  @sessions.each { |s| s.aggregate }
214
231
  end
215
232
 
216
233
  # Convenience method that averages the speed over all sessions.
217
234
  def avg_speed
218
235
  speed = 0.0
219
- @sessions.each { |s| speed += s.avg_speed if s.avg_speed }
236
+ @sessions.each do |s|
237
+ if (spd = s.avg_speed || s.enhanced_avg_speed)
238
+ speed += spd
239
+ end
240
+ end
220
241
  speed / @sessions.length
221
242
  end
222
243
 
@@ -292,8 +313,8 @@ module Fit4Ruby
292
313
  @device_infos + @sensor_settings +
293
314
  @data_sources + @user_profiles +
294
315
  @physiological_metrics + @events +
295
- @sessions + @laps + @records + @heart_rate_zones +
296
- @personal_records).sort.each do |s|
316
+ @sessions + @laps + @records + @lengths +
317
+ @heart_rate_zones + @personal_records).sort.each do |s|
297
318
  s.write(io, id_mapper)
298
319
  end
299
320
  super
@@ -404,6 +425,16 @@ module Fit4Ruby
404
425
  new_fit_data_record('lap', field_values)
405
426
  end
406
427
 
428
+ # Add a new Length to the Activity. All previoulsy added Record objects are
429
+ # associated with this Length unless they have been associated with another
430
+ # Length before.
431
+ # @param field_values [Hash] A Hash that provides initial values for
432
+ # certain fields of the FitDataRecord.
433
+ # @return [Length]
434
+ def new_length(field_values = {})
435
+ new_fit_data_record('length', field_values)
436
+ end
437
+
407
438
  # Add a new HeartRateZones record to the Activity.
408
439
  # @param field_values [Heash] A Hash that provides initial values for
409
440
  # certain fields of the FitDataRecord.
@@ -496,8 +527,12 @@ module Fit4Ruby
496
527
  @cur_session_laps = []
497
528
  when 'lap'
498
529
  record = create_new_lap(field_values)
530
+ when 'length'
531
+ record = create_new_length(field_values)
499
532
  when 'record'
500
- @cur_lap_records << (record = Record.new(field_values))
533
+ record = Record.new(field_values)
534
+ @cur_lap_records << record
535
+ @cur_length_records << record
501
536
  @records << record
502
537
  when 'hrv'
503
538
  @hrv << (record = HRV.new(field_values))
@@ -515,16 +550,29 @@ module Fit4Ruby
515
550
  private
516
551
 
517
552
  def create_new_lap(field_values)
518
- lap = Lap.new(@cur_lap_records, @laps.last, field_values)
553
+ lap = Lap.new(@cur_lap_records, @laps.last,
554
+ field_values,
555
+ @length_counter, @cur_lap_lengths)
519
556
  lap.message_index = @lap_counter - 1
520
557
  @lap_counter += 1
521
558
  @cur_session_laps << lap
522
559
  @laps << lap
523
560
  @cur_lap_records = []
561
+ @cur_lap_lengths = []
524
562
 
525
563
  lap
526
564
  end
527
565
 
566
+ def create_new_length(field_values)
567
+ length = Length.new(@cur_length_records, @lengths.last, field_values)
568
+ length.message_index = @length_counter - 1
569
+ @length_counter += 1
570
+ @cur_lap_lengths << length
571
+ @lengths << length
572
+ @cur_length_records = []
573
+
574
+ length
575
+ end
528
576
  end
529
577
 
530
578
  end
@@ -21,7 +21,7 @@ module Fit4Ruby
21
21
 
22
22
  RecordOrder = [ 'user_data', 'user_profile',
23
23
  'device_info', 'data_sources', 'event',
24
- 'record', 'lap', 'session', 'heart_rate_zones',
24
+ 'record', 'lap', 'length', 'session', 'heart_rate_zones',
25
25
  'personal_records' ]
26
26
 
27
27
  attr_reader :message
@@ -355,6 +355,7 @@ module Fit4Ruby
355
355
  entry 2697, 'fenix5'
356
356
  entry 2957, 'fenix5_gps_galileo' # Just a guess
357
357
  entry 3111, 'fenix5x_plus'
358
+ entry 3126, 'instinct'
358
359
  entry 10007, 'sdm4'
359
360
  entry 20119, 'training_center'
360
361
  entry 65532, 'android_antplus_plugin'
@@ -593,7 +594,7 @@ module Fit4Ruby
593
594
  dict 'swim_stroke'
594
595
  entry 0, 'freestyle'
595
596
  entry 1, 'backstroke'
596
- entry 2, 'breaststrike'
597
+ entry 2, 'breaststroke'
597
598
  entry 3, 'butterfly'
598
599
  entry 4, 'drill'
599
600
  entry 5, 'mixed'
@@ -131,6 +131,7 @@ module Fit4Ruby
131
131
  field 144, 'enum', 'true_up_enabled'
132
132
  field 148, 'enum', 'undocumented_field_148'
133
133
  field 149, 'enum', 'undocumented_field_149'
134
+ field 168, 'enum', 'undocumented_field_168'
134
135
 
135
136
  message 3, 'user_profile'
136
137
  field 0, 'string', 'friendly_name'
@@ -161,7 +162,7 @@ module Fit4Ruby
161
162
  field 34, 'uint16', 'undocumented_field_34'
162
163
  field 35, 'uint32', 'undocumented_field_35'
163
164
  field 36, 'uint8', 'undocumented_field_36'
164
- field 37, 'uint16', 'undocumented_field_37'
165
+ field 37, 'uint16', 'functional_threshold_speed', :scale => 36, :unit => 'm/s'
165
166
  field 38, 'uint16', 'undocumented_field_38'
166
167
  field 39, 'float32', 'undocumented_field_39'
167
168
  field 40, 'float32', 'undocumented_field_40'
@@ -372,7 +373,7 @@ module Fit4Ruby
372
373
  field 44, 'uint16', 'pool_length', :scale => 100, :unit => 'm'
373
374
  field 45, 'uint16', 'undefined_value_45'
374
375
  field 46, 'enum', 'pool_length_unit', :dict => 'display_measure'
375
- field 47, 'uint16', 'num_active_length', :unit => 'lengths'
376
+ field 47, 'uint16', 'num_active_lengths', :unit => 'lengths'
376
377
  field 48, 'uint32', 'total_work', :unit => 'J'
377
378
  field 57, 'sint8', 'avg_temperature', :unit => 'C'
378
379
  field 58, 'sint8', 'max_temperature', :unit => 'C'
@@ -445,6 +446,8 @@ module Fit4Ruby
445
446
  field 185, 'uint8', 'undocumented_field_185'
446
447
  field 187, 'float32', 'undocumented_field_187'
447
448
  field 188, 'enum', 'undocumented_field_188'
449
+ field 189, 'uint16', 'undocumented_field_189'
450
+ field 190, 'uint16', 'undocumented_field_190'
448
451
  field 253, 'uint32', 'timestamp', :type => 'date_time'
449
452
  field 254, 'uint16', 'message_index'
450
453
 
@@ -496,7 +499,7 @@ module Fit4Ruby
496
499
  field 37, 'uint16', 'avg_stroke_distance', :scale => 100, :unit => 'm'
497
500
  field 38, 'enum', 'swim_stroke', :dict => 'swim_stroke'
498
501
  field 39, 'enum', 'sub_sport', :dict => 'sub_sport'
499
- field 40, 'uint16', 'num_active_length', :unit => 'lengths'
502
+ field 40, 'uint16', 'num_active_lengths', :unit => 'lengths'
500
503
  field 41, 'uint32', 'total_work', :unit => 'J'
501
504
  field 50, 'sint8', 'avg_temperature', :unit => 'C'
502
505
  field 51, 'sint8', 'max_temperature', :unit => 'C'
@@ -808,7 +811,7 @@ module Fit4Ruby
808
811
  field 10, 'uint8', 'avg_resting_heart_rate', :unit => 'bpm'
809
812
  field 11, 'uint16', 'running_lactate_threshold_heart_rate', :unit => 'bpm'
810
813
  field 12, 'uint16', 'functional_threshold_power', :unit => 'W'
811
- field 13, 'uint16', 'undocumented_field_13'
814
+ field 13, 'uint16', 'functional_threshold_speed', :scale => 36, :unit => 'm/s'
812
815
  field 14, 'uint8', 'undocumented_field_14'
813
816
  field 15, 'uint8', 'undocumented_field_15'
814
817
  field 16, 'uint32', 'undocumented_field_16'
@@ -821,7 +824,7 @@ module Fit4Ruby
821
824
  message 101, 'length'
822
825
  field 0, 'enum', 'event', :dict => 'event'
823
826
  field 1, 'enum', 'event_type', :dict => 'event_type'
824
- field 2, 'uint32', 'date_time', :type => 'date_time'
827
+ field 2, 'uint32', 'start_time', :type => 'date_time'
825
828
  field 3, 'uint32', 'total_elapsed_time', :scale => 1000, :unit => 's'
826
829
  field 4, 'uint32', 'total_timer_time', :scale => 1000, :unit => 's'
827
830
  field 5, 'uint16', 'total_strokes', :unit => 'strokes'
@@ -833,6 +836,8 @@ module Fit4Ruby
833
836
  field 12, 'enum', 'length_type', :dict => 'length_type'
834
837
  field 18, 'uint16', 'player_score'
835
838
  field 19, 'uint16', 'opponent_score'
839
+ field 20, 'uint16', 'stroke_count', :unit => 'counts'
840
+ field 21, 'uint16', 'zone_count', :unit => 'counts'
836
841
  field 253, 'uint32', 'timestamp', :type => 'date_time'
837
842
  field 254, 'uint16', 'message_index'
838
843
 
@@ -901,8 +906,8 @@ module Fit4Ruby
901
906
  field 12, 'enum', 'undocumented_field_12'
902
907
  field 13, 'uint8', 'undocumented_field_13'
903
908
  field 14, 'uint16', 'running_lactate_threshold_heart_rate', :unit => 'bpm'
904
- field 15, 'uint16', 'running_lactate_threshold_speed', :scale => 1000, :unit => 'm/s'
905
- field 16, 'uint16', 'undocumented_field_16' # very correlated to 14 and 15
909
+ field 15, 'uint16', 'undocumented_field_15'
910
+ field 16, 'uint16', 'running_lactate_threshold_speed', :scale => 36, :unit => 'm/s'
906
911
  field 17, 'sint8', 'performance_condition'
907
912
  field 18, 'uint8', 'undocumented_field_18'
908
913
  field 19, 'uint8', 'undocumented_field_19'
@@ -1008,6 +1013,7 @@ module Fit4Ruby
1008
1013
  field 65, 'uint32', 'undocumented_field_65'
1009
1014
  field 70, 'uint32', 'undocumented_field_70'
1010
1015
  field 71, 'enum', 'undocumented_field_71'
1016
+ field 73, 'uint16z', 'undocumented_field_73'
1011
1017
  field 254, 'uint16', 'message_index'
1012
1018
 
1013
1019
  # Not part of the official ANT SDK doc.
@@ -1120,6 +1126,7 @@ module Fit4Ruby
1120
1126
  message 269, 'undocumented_269'
1121
1127
  field 0, 'uint8', 'undocumented_field_0'
1122
1128
  field 1, 'uint8', 'undocumented_field_1'
1129
+ field 2, 'uint8', 'undocumented_field_2'
1123
1130
  field 253, 'uint32', 'timestamp', :type => 'date_time'
1124
1131
 
1125
1132
  # Not part of the official ANT SDK doc.
data/lib/fit4ruby/Lap.rb CHANGED
@@ -19,13 +19,24 @@ module Fit4Ruby
19
19
 
20
20
  include RecordAggregator
21
21
 
22
- attr_reader :records
22
+ attr_reader :records, :lengths
23
23
 
24
- def initialize(records, previous_lap, field_values)
24
+ # Create a new Lap object.
25
+ # @param records [Array of Records] Records to associate with the Lap.
26
+ # @param lengths [Array of Lengths] Lengths to associate with the Lap.
27
+ # @param first_length_index [Fixnum] Index of the first Length in this Lap.
28
+ # @param previous_lap [Lap] Previous Lap on same Session.
29
+ # @param field_values [Hash] Hash that provides initial values for certain
30
+ # fields.
31
+ def initialize(records, previous_lap, field_values, first_length_index, lengths)
25
32
  super('lap')
33
+ @lengths = lengths
26
34
  @meta_field_units['avg_stride_length'] = 'm'
27
35
  @records = records
28
36
  @previous_lap = previous_lap
37
+ @lengths.each { |length| @records += length.records }
38
+ @first_length_index = first_length_index
39
+ @num_lengths = @lengths.length
29
40
 
30
41
  if previous_lap && previous_lap.records && previous_lap.records.last
31
42
  # Set the start time of the new lap to the timestamp of the last record
@@ -43,10 +54,25 @@ module Fit4Ruby
43
54
  set_field_values(field_values)
44
55
  end
45
56
 
46
- def check(index)
57
+ def check(index, activity)
47
58
  unless @message_index == index
48
59
  Log.fatal "message_index must be #{index}, not #{@message_index}"
49
60
  end
61
+
62
+ return if @num_lengths.zero?
63
+
64
+ unless @first_length_index
65
+ Log.fatal 'first_length_index is not set'
66
+ end
67
+
68
+ @first_length_index.upto(@first_length_index - @num_lengths) do |i|
69
+ if (length = activity.lengths[i])
70
+ @lengths << length
71
+ else
72
+ Log.fatal "Lap references length #{i} which is not contained in "
73
+ "the FIT file."
74
+ end
75
+ end
50
76
  end
51
77
 
52
78
  # Compute the average stride length for this Session.
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = Length.rb -- Fit4Ruby - FIT file processing library for Ruby
5
+ #
6
+ # Copyright (c) 2014, 2015 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 'fit4ruby/FitDataRecord'
14
+ require 'fit4ruby/RecordAggregator'
15
+
16
+ module Fit4Ruby
17
+
18
+ class Length < FitDataRecord
19
+
20
+ include RecordAggregator
21
+
22
+ attr_reader :records
23
+
24
+ def initialize(records, previous_length, field_values)
25
+ super('length')
26
+ @records = records
27
+ @previous_length = previous_length
28
+
29
+ if previous_length && previous_length.records && previous_length.records.last
30
+ # Set the start time of the new length to the timestamp of the last record
31
+ # of the previous length.
32
+ @start_time = previous_length.records.last.timestamp
33
+ elsif records.first
34
+ # Or to the timestamp of the first record.
35
+ @start_time = records.first.timestamp
36
+ end
37
+
38
+ if records.last
39
+ @total_elapsed_time = records.last.timestamp - @start_time
40
+ end
41
+
42
+ set_field_values(field_values)
43
+ end
44
+
45
+ def check(index)
46
+ unless @message_index == index
47
+ Log.fatal "message_index must be #{index}, not #{@message_index}"
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -1,4 +1,4 @@
1
1
  module Fit4Ruby
2
2
  # The version number of the library.
3
- VERSION = '3.3.0'
3
+ VERSION = '3.4.0'
4
4
  end
data/spec/FitFile_spec.rb CHANGED
@@ -17,9 +17,10 @@ require 'fit4ruby'
17
17
  ENV['TZ'] = 'UTC'
18
18
 
19
19
  describe Fit4Ruby do
20
-
21
- before(:each) do
22
- ts = Time.now
20
+ let(:fit_file) { 'test.fit' }
21
+ let(:timestamp) { Time.now }
22
+ let(:activity) do
23
+ ts = timestamp
23
24
  a = Fit4Ruby::Activity.new
24
25
  a.total_timer_time = 30 * 60.0
25
26
  a.new_user_data({ :age => 33, :height => 1.78, :weight => 73.0,
@@ -99,20 +100,65 @@ describe Fit4Ruby do
99
100
  :event_type => 'marker', :recovery_hr => 132 })
100
101
 
101
102
  a.aggregate
103
+ a
104
+ end
102
105
 
103
- @activity = a
106
+ before do
107
+ File.delete(fit_file) if File.exist?(fit_file)
108
+ expect(File.exist?(fit_file)).to be false
104
109
  end
105
110
 
106
- it 'should write an Activity FIT file and read it back' do
107
- fit_file = 'test.fit'
111
+ after { File.delete(fit_file) }
108
112
 
109
- File.delete(fit_file) if File.exists?(fit_file)
110
- Fit4Ruby.write(fit_file, @activity)
111
- expect(File.exists?(fit_file)).to be true
113
+ it 'should write an Activity FIT file and read it back' do
114
+ Fit4Ruby.write(fit_file, activity)
115
+ expect(File.exist?(fit_file)).to be true
112
116
 
113
117
  b = Fit4Ruby.read(fit_file)
114
- expect(b.inspect).to eq(@activity.inspect)
115
- File.delete(fit_file)
118
+ expect(b.laps.count).to eq 6
119
+ expect(b.lengths.count).to eq 0
120
+ expect(b.inspect).to eq(activity.inspect)
121
+ end
122
+
123
+ context 'activity with Lengths' do
124
+ let(:activity) do
125
+ ts = timestamp
126
+ laps = 0
127
+ lengths = 0
128
+ a = Fit4Ruby::Activity.new
129
+
130
+ a.total_timer_time = 30 * 60.0
131
+ a.new_device_info({ :timestamp => ts,
132
+ :device_index => 0, :manufacturer => 'garmin',
133
+ :serial_number => 123456789 })
134
+
135
+ 0.upto(a.total_timer_time / 60) do |mins|
136
+ ts += 60
137
+ if mins > 0 && mins % 5 == 0
138
+ a.new_lap({ :timestamp => ts, :sport => 'swimming',
139
+ :message_index => laps, :total_cycles => 195 })
140
+ laps += 1
141
+
142
+ a.new_length({ :timestamp => ts, :event => 'length',
143
+ :message_index => lengths, :total_strokes => 45 })
144
+ lengths += 1
145
+ end
146
+ end
147
+ a
148
+ end
149
+
150
+ it 'should write an Activity FIT file and read it back' do
151
+ Fit4Ruby.write(fit_file, activity)
152
+ expect(File.exist?(fit_file)).to be true
153
+
154
+ b = Fit4Ruby.read(fit_file)
155
+ expect(b.laps.count).to eq 6
156
+ expect(b.lengths.count).to eq 6
157
+ expect(b.laps.select { |l| l.sport == 'swimming' }.count).to eq 6
158
+ expect(b.lengths.select { |l| l.total_strokes == 45 }.count).to eq 6
159
+ expect(b.inspect).to eq(activity.inspect)
160
+ end
161
+
116
162
  end
117
163
 
118
164
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fit4ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.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: 2019-09-03 00:00:00.000000000 Z
11
+ date: 2019-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bindata
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.6.4
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '3.8'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '3.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0.12'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0.12'
69
97
  description: |
70
98
  This library can read and write FIT files and convert them into a Ruby data
71
99
  structure for easy processing. This library was written for Garmin devices
@@ -118,6 +146,7 @@ files:
118
146
  - lib/fit4ruby/HRV.rb
119
147
  - lib/fit4ruby/HeartRateZones.rb
120
148
  - lib/fit4ruby/Lap.rb
149
+ - lib/fit4ruby/Length.rb
121
150
  - lib/fit4ruby/Log.rb
122
151
  - lib/fit4ruby/Metrics.rb
123
152
  - lib/fit4ruby/Monitoring.rb
@@ -161,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
161
190
  version: '0'
162
191
  requirements: []
163
192
  rubyforge_project:
164
- rubygems_version: 2.2.5
193
+ rubygems_version: 2.7.6.2
165
194
  signing_key:
166
195
  specification_version: 4
167
196
  summary: Library to read and write GARMIN FIT files.