fitreader 0.1.1 → 0.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/README.md +101 -8
- data/fitreader.gemspec +1 -2
- data/lib/fitreader/degraded_record.rb +2 -3
- data/lib/fitreader/errors.rb +4 -4
- data/lib/fitreader/fitfile.rb +10 -9
- data/lib/fitreader/message_type.rb +12 -0
- data/lib/fitreader/record.rb +15 -15
- data/lib/fitreader/version.rb +1 -1
- data/lib/fitreader.rb +19 -11
- data/spec/fitreader_interfaces_spec.rb +45 -0
- data/spec/fitreader_readfile_spec.rb +17 -0
- data/spec/fitreader_static_spec.rb +17 -0
- metadata +9 -18
- data/spec/fitreader_spec.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6dc32742ab1e01f369d27408f7cab25fcde47e24
|
4
|
+
data.tar.gz: 41f1381a24b1985958e115f3f1033866ad9a005b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b89c5a123826b9a1ff2ae79b5f7be047f9bb35d44af1db1664de2289bde313465635a145b555228559c01d2f1de4f8f051933bd1e39b7e8758019c514fbe535
|
7
|
+
data.tar.gz: 2b9af2f2aa0b6502f8b7465acebed731ee819b207640898b659b16c0514d73e04caacebd04afc5375daa5da2b66fa84bd4e652f0edfc29831c35312204c628b4
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Fitreader
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
Fitreader is a small gem used for read and decoding FIT files generated by various sports devices. Currently it has only been designed specifically to read files produced by a Garmin Edge 1000. It will probably mostly work out of the box with other file sources, but will probably not work 100% perfectly unless it's a Garmin cycling computer.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -22,20 +20,115 @@ Or install it yourself as:
|
|
22
20
|
|
23
21
|
## Usage
|
24
22
|
|
25
|
-
|
23
|
+
To use this gem in a ruby or rails application, simply add
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
gem 'fitreader'
|
27
|
+
```
|
28
|
+
|
29
|
+
to the Gemfile and then
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'fitreader'
|
33
|
+
```
|
34
|
+
|
35
|
+
to the class you wish to call it from. After that, it's a simple matter of calling
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
Fitreader.read(path_to_fit_file)
|
39
|
+
```
|
40
|
+
|
41
|
+
All of the interface and convenience functions can be found in lib/fitreader.rb.
|
42
|
+
|
43
|
+
After reading a FIT file, the file header can be inspected by calling
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
Fitreader.header
|
47
|
+
```
|
48
|
+
|
49
|
+
A digest of the records found in the file is shown with
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
Fitreader.available_records
|
53
|
+
```
|
54
|
+
|
55
|
+
which will return a list similar to the following, showing respectively the global_message_number (as defined in the FIT SDK), the name of the record type, and the number of records parsed
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
[[0, :file_id, 1],
|
59
|
+
[3, :user_profile, 1],
|
60
|
+
[7, :zones_target, 1],
|
61
|
+
[18, :session, 1],
|
62
|
+
[19, :lap, 1],
|
63
|
+
[20, :record, 2899],
|
64
|
+
[21, :event, 73],
|
65
|
+
[22, :source, 58],
|
66
|
+
[23, :device_info, 14],
|
67
|
+
[34, :activity, 1],
|
68
|
+
[49, :file_creator, 1],
|
69
|
+
[72, :training_file, 1],
|
70
|
+
[104, :battery_info, 40],
|
71
|
+
[147, :sensor_info, 3]]
|
72
|
+
```
|
73
|
+
|
74
|
+
Armed with this information, we can call
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
Fitreader.get_message_type filter
|
78
|
+
```
|
79
|
+
|
80
|
+
where filter is either the global_number or the name supplied by the previous command, for example
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
Fitreader.get_message_type 18
|
84
|
+
Fitreader.get_message_type :session
|
85
|
+
```
|
86
|
+
|
87
|
+
will both fetch the session record(s) in the form of a MessageType object. This object contains three fields: a definition, an array of records and an array of undefined_records.
|
88
|
+
|
89
|
+
The definition contains metadata from a combination of the FIT file itself and the SKD. I will write more detailed information, but basically this information tells us how to interpret the actual data. Of most relevance, it tells us the name and datatype of each field we will find in records of this type.
|
90
|
+
|
91
|
+
The records array contains a list or Record objects. A Record object contains a fields array and an error_fields array. The fields array is a list of the actual data contined within this record, for example timestamp, or coordinated, etc. The particular FieldData object includes the name of the field (also found in the definition), along with the raw_value and the processed value which may differ in the case of, for example, a coordinate.
|
92
|
+
|
93
|
+
The error_fields array contains any fields defined in the FIT file itself that aren't defined within the SDK. Without the SKD we can most likely never know what the field represents or whether the raw value would need further processing to make sense to us. These are included mostly for debugging and future convenience sake.
|
94
|
+
|
95
|
+
The results of this function are probably a lot more data that we generally need, so a convenience function is included that distills the results of the previous call into a more efficient dataset
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
Fitreader.record_values 20
|
99
|
+
Fitreader.record_values :record
|
100
|
+
```
|
101
|
+
|
102
|
+
This will return an array of hashes, one hash for each record of the specified type. The hashes contain only the field name and value, for example
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
{:timestamp=>2016-04-09 11:19:51 UTC,
|
106
|
+
:position_lat=>57.711100755259395,
|
107
|
+
:position_long=>11.992837116122246,
|
108
|
+
:distance=>78.94,
|
109
|
+
:altitude=>14.200000000000045,
|
110
|
+
:speed=>3.835,
|
111
|
+
:heart_rate=>103,
|
112
|
+
:cadence=>0,
|
113
|
+
:temperature=>12,
|
114
|
+
:fractional_cadence=>0.0},
|
115
|
+
```
|
116
|
+
|
117
|
+
Some things to watch out for:
|
118
|
+
|
119
|
+
- speed is recorded as m/s in my files, rather than kph as one might expect.
|
26
120
|
|
27
121
|
## Development
|
28
122
|
|
29
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `
|
123
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rspec spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
124
|
|
31
|
-
To install this gem onto your local machine
|
125
|
+
To install this gem onto your local machine from a clone of the repo, run `bundle exec rake install`.
|
32
126
|
|
33
127
|
## Contributing
|
34
128
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
129
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/samsari/fitreader.
|
36
130
|
|
37
131
|
|
38
132
|
## License
|
39
133
|
|
40
134
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
41
|
-
|
data/fitreader.gemspec
CHANGED
@@ -30,9 +30,8 @@ Gem::Specification.new do |spec|
|
|
30
30
|
|
31
31
|
spec.add_development_dependency "bundler", "~> 1.12"
|
32
32
|
spec.add_development_dependency "rake", "~> 10.0"
|
33
|
-
# spec.add_development_dependency "minitest", "~> 5.0"
|
34
33
|
spec.add_development_dependency "rspec", "~> 3.5"
|
35
34
|
spec.add_development_dependency "pry"
|
36
35
|
|
37
|
-
spec.add_dependency('bindata')
|
36
|
+
# spec.add_dependency('bindata')
|
38
37
|
end
|
@@ -3,13 +3,12 @@ require 'fitreader/errors'
|
|
3
3
|
|
4
4
|
module Fitreader
|
5
5
|
class DegradedRecord
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :fields
|
7
7
|
def initialize(definition, bytes)
|
8
|
-
@definition = definition
|
9
8
|
@fields = {}
|
10
9
|
|
11
10
|
start = 0
|
12
|
-
|
11
|
+
definition.field_definitions.each do |f|
|
13
12
|
raw = bytes[start...start+=f.size]
|
14
13
|
b = Static.base[f.base_num]
|
15
14
|
data = unpack_data(f, b, raw)
|
data/lib/fitreader/errors.rb
CHANGED
@@ -10,9 +10,9 @@ module Fitreader
|
|
10
10
|
end
|
11
11
|
|
12
12
|
class UnknownMessageTypeError < RuntimeError
|
13
|
-
attr :definition
|
14
|
-
def initialize(definition)
|
15
|
-
|
16
|
-
end
|
13
|
+
# attr :definition
|
14
|
+
# def initialize(definition)
|
15
|
+
# @definition = definition
|
16
|
+
# end
|
17
17
|
end
|
18
18
|
end
|
data/lib/fitreader/fitfile.rb
CHANGED
@@ -3,23 +3,23 @@ require 'fitreader/record_header'
|
|
3
3
|
require 'fitreader/definition'
|
4
4
|
require 'fitreader/record'
|
5
5
|
require 'fitreader/degraded_record'
|
6
|
+
require 'fitreader/message_type'
|
6
7
|
require 'fitreader/static'
|
7
8
|
|
8
9
|
module Fitreader
|
9
10
|
class FitFile
|
10
|
-
attr_reader :header, :
|
11
|
+
attr_reader :header, :messages, :file
|
11
12
|
|
12
13
|
def initialize(path)
|
13
14
|
@file = File.open(path, 'rb')
|
14
15
|
@header = FileHeader.new(@file.read(14))
|
15
16
|
if valid?
|
16
17
|
@defs = {}
|
17
|
-
@
|
18
|
-
@error_records = []
|
18
|
+
@messages = {}
|
19
19
|
while @file.pos < @header.num_records do
|
20
20
|
process_next_record
|
21
21
|
end
|
22
|
-
puts "number of bad records found: #{@error_records.length}"
|
22
|
+
# puts "number of bad records found: #{@error_records.length}"
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -35,17 +35,18 @@ module Fitreader
|
|
35
35
|
dr = Definition.new(h.local_num, @file.read(5))
|
36
36
|
dr.add_fields(@file.read(dr.num_fields*3))
|
37
37
|
@defs[h.local_num] = dr
|
38
|
+
|
39
|
+
m = MessageType.new(dr)
|
40
|
+
@messages[dr.global_num] = m
|
38
41
|
elsif h.header_type == :data
|
39
42
|
unless dr.nil?
|
40
43
|
begin
|
41
44
|
data = @file.read(dr.content_length)
|
42
45
|
datr = Record.new(dr, data)
|
43
|
-
@records.push
|
44
|
-
rescue UnknownMessageTypeError
|
45
|
-
# @error_records.push(error.definition)
|
46
|
-
puts error
|
46
|
+
@messages[dr.global_num].records.push datr
|
47
|
+
rescue UnknownMessageTypeError
|
47
48
|
degraded = DegradedRecord.new(dr, data)
|
48
|
-
@
|
49
|
+
@messages[dr.global_num].undefined_records.push degraded
|
49
50
|
end
|
50
51
|
else
|
51
52
|
msg = "no record def found! #{h.local_msg_num}"
|
data/lib/fitreader/record.rb
CHANGED
@@ -5,32 +5,32 @@ module Fitreader
|
|
5
5
|
class Record
|
6
6
|
attr_reader :definition, :fields, :error_fields
|
7
7
|
def initialize(definition, bytes)
|
8
|
-
|
8
|
+
# definition = definition
|
9
9
|
@fields = {}
|
10
10
|
@error_fields = {}
|
11
11
|
|
12
|
-
unless
|
12
|
+
unless definition.fit_msg.nil?
|
13
13
|
start = 0
|
14
|
-
|
14
|
+
definition.field_definitions.each do |f|
|
15
15
|
raw = bytes[start...start+=f.size]
|
16
16
|
b = Static.base[f.base_num]
|
17
17
|
data = unpack_data(f, b, raw)
|
18
18
|
begin
|
19
|
-
process_data(f.def_num, b[:invalid], data)
|
19
|
+
process_data(f.def_num, b[:invalid], data, definition)
|
20
20
|
rescue UnknownFieldTypeError => error
|
21
21
|
push_error error.reason, error.field, error.data
|
22
22
|
# puts error unless error.reason == :invalid
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
if
|
26
|
+
if definition.global_num == 21
|
27
27
|
process_event
|
28
|
-
elsif
|
28
|
+
elsif definition.global_num == 23
|
29
29
|
process_deviceinfo
|
30
30
|
end
|
31
31
|
else
|
32
|
-
msg = "no known message type: #{
|
33
|
-
raise UnknownMessageTypeError.new
|
32
|
+
msg = "no known message type: #{definition.global_num}"
|
33
|
+
raise UnknownMessageTypeError.new, msg, caller
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -52,8 +52,8 @@ module Fitreader
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def process_data(fieldDefNum, invalid, data)
|
56
|
-
field_def =
|
55
|
+
def process_data(fieldDefNum, invalid, data, definition)
|
56
|
+
field_def = definition.fit_msg[fieldDefNum]
|
57
57
|
unless field_def.nil?
|
58
58
|
# populate invalid
|
59
59
|
if data.is_a?(Array)
|
@@ -66,12 +66,12 @@ module Fitreader
|
|
66
66
|
unless invalid
|
67
67
|
@fields[fieldDefNum] = FieldData.new(fieldDefNum, data, field_def)
|
68
68
|
else
|
69
|
-
msg = "invalid field data (#{data}) processed for field number [#{fieldDefNum}::#{field_def[:name]}] in message (#{
|
70
|
-
raise UnknownFieldTypeError.new(
|
69
|
+
msg = "invalid field data (#{data}) processed for field number [#{fieldDefNum}::#{field_def[:name]}] in message (#{definition.global_num}::#{definition.name})"
|
70
|
+
raise UnknownFieldTypeError.new(definition, fieldDefNum, data, :invalid), msg, caller
|
71
71
|
end
|
72
72
|
else
|
73
|
-
msg = "invalid field [#{fieldDefNum}] encountered for message [#{
|
74
|
-
raise UnknownFieldTypeError.new(
|
73
|
+
msg = "invalid field [#{fieldDefNum}] encountered for message [#{definition.global_num}::#{definition.name}] with data [#{data}]"
|
74
|
+
raise UnknownFieldTypeError.new(definition, fieldDefNum, data, :unknown), msg, caller
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -98,7 +98,7 @@ module Fitreader
|
|
98
98
|
# :battery_info 40
|
99
99
|
# :sensor_info 3
|
100
100
|
def type
|
101
|
-
case
|
101
|
+
case definition.name
|
102
102
|
when :file_id, :user_profile, :zones_target, :session
|
103
103
|
:ride
|
104
104
|
when condition
|
data/lib/fitreader/version.rb
CHANGED
data/lib/fitreader.rb
CHANGED
@@ -13,30 +13,38 @@ module Fitreader
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.available_records
|
16
|
-
@f.
|
17
|
-
.
|
16
|
+
@f.messages
|
17
|
+
.select { |x,y| !y.definition.name.nil? }
|
18
|
+
.select { |x,y| !y.records.length.zero? }
|
19
|
+
.collect { |x| [x[0], x[1].definition.name, x[1].records.length] }
|
18
20
|
.sort
|
19
|
-
.collect { |k, v| k << v.length }
|
20
21
|
end
|
21
22
|
|
22
|
-
def self.
|
23
|
+
def self.get_message_type(filter)
|
23
24
|
if filter.is_a?(Symbol)
|
24
|
-
@f.
|
25
|
+
res = @f.messages.find { |_,y| y.definition.name == filter}
|
26
|
+
res[1] unless res.nil?
|
27
|
+
binding.pry
|
25
28
|
elsif filter.is_a?(Integer)
|
26
|
-
@f.
|
29
|
+
@f.messages[filter]
|
27
30
|
else
|
28
31
|
raise ArgumentError, "needs a string or a symbol"
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
32
35
|
def self.record_values(filter)
|
33
|
-
|
34
|
-
records.collect {|x| x.fields.values.collect{|z| [z.name, z.value]}}.collect{|y| y.to_h}
|
36
|
+
message = get_message_type filter
|
37
|
+
message.records.collect {|x| x.fields.values.collect{|z| [z.name, z.value]}}.collect{|y| y.to_h}
|
35
38
|
end
|
36
39
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
+
def self.error_messages
|
41
|
+
@f.messages.select { |_,v| !v.undefined_records.empty? }
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.error_fields(filter)
|
45
|
+
message = get_message_type filter
|
46
|
+
message.records.select{|x| !x.error_fields.empty?}.collect{|y| y.error_fields}
|
47
|
+
end
|
40
48
|
|
41
49
|
# def self.filter_by_scope(filter)
|
42
50
|
# valid = Static.scope.include? filter
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'fitreader'
|
3
|
+
|
4
|
+
describe Fitreader do
|
5
|
+
describe 'has functioning interfaces' do
|
6
|
+
before do
|
7
|
+
@path = File.join(File.dirname(__FILE__), '2016-04-09-13-19-18.fit')
|
8
|
+
Fitreader.read(@path)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'has a valid header' do
|
12
|
+
expect(Fitreader.header).not_to be_nil
|
13
|
+
expect(Fitreader.header.num_records).to be(89139)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'has valid records' do
|
17
|
+
expect(Fitreader.available_records).not_to be_nil
|
18
|
+
expect(Fitreader.available_records.length).to be(14)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'can fetch an existing message by number' do
|
22
|
+
expect(Fitreader.get_message_type 18).to be_a(Fitreader::MessageType)
|
23
|
+
end
|
24
|
+
it 'can fetch an existing message by name' do
|
25
|
+
expect(Fitreader.get_message_type :session).to be_a(Fitreader::MessageType)
|
26
|
+
end
|
27
|
+
it 'cannot fetch a non existing message by number' do
|
28
|
+
expect(Fitreader.get_message_type 1234).to be(nil)
|
29
|
+
end
|
30
|
+
it 'cannot fetch a non existing message by name' do
|
31
|
+
expect(Fitreader.get_message_type :non_existant).to be(nil)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'can return name-value data' do
|
35
|
+
expect(Fitreader.record_values :session).to be_a(Array)
|
36
|
+
end
|
37
|
+
it 'can return error-fields' do
|
38
|
+
expect(Fitreader.error_fields :record).to be_a(Array)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'can return error-messages' do
|
42
|
+
expect(Fitreader.error_messages).to be_a(Hash)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'fitreader'
|
2
|
+
|
3
|
+
describe Fitreader do
|
4
|
+
describe 'read fit file' do
|
5
|
+
before do
|
6
|
+
@path = File.join(File.dirname(__FILE__), '2016-04-09-13-19-18.fit')
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'test file exists' do
|
10
|
+
expect(File.exist?(@path)).to eql(true)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'parses file without exceptions' do
|
14
|
+
expect { Fitreader.read(@path) }.not_to raise_error
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'fitreader'
|
3
|
+
|
4
|
+
describe Fitreader::Static do
|
5
|
+
it 'const is loaded' do
|
6
|
+
expect(Fitreader::Static.enums.class).to eql(Hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'const has data' do
|
10
|
+
expect(Fitreader::Static.enums[:enum_file][1]).to eql(:device)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'scope is readable' do
|
14
|
+
expect(Fitreader::Static.scope).to include(:ride)
|
15
|
+
expect(Fitreader::Static.scope).not_to include(:bike)
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fitreader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Brodie
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: bindata
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
69
|
description:
|
84
70
|
email:
|
85
71
|
- richard@samsari.org
|
@@ -105,6 +91,7 @@ files:
|
|
105
91
|
- lib/fitreader/field_definition.rb
|
106
92
|
- lib/fitreader/file_header.rb
|
107
93
|
- lib/fitreader/fitfile.rb
|
94
|
+
- lib/fitreader/message_type.rb
|
108
95
|
- lib/fitreader/record.rb
|
109
96
|
- lib/fitreader/record_header.rb
|
110
97
|
- lib/fitreader/sdk/constants.yml
|
@@ -113,7 +100,9 @@ files:
|
|
113
100
|
- lib/fitreader/version.rb
|
114
101
|
- schema
|
115
102
|
- spec/2016-04-09-13-19-18.fit
|
116
|
-
- spec/
|
103
|
+
- spec/fitreader_interfaces_spec.rb
|
104
|
+
- spec/fitreader_readfile_spec.rb
|
105
|
+
- spec/fitreader_static_spec.rb
|
117
106
|
- test/fitreader_test.rb
|
118
107
|
- test/test_helper.rb
|
119
108
|
homepage: https://github.com/samsari/fitreader
|
@@ -142,6 +131,8 @@ specification_version: 4
|
|
142
131
|
summary: Library for reading FIT files generated by Garmin devices.
|
143
132
|
test_files:
|
144
133
|
- spec/2016-04-09-13-19-18.fit
|
145
|
-
- spec/
|
134
|
+
- spec/fitreader_interfaces_spec.rb
|
135
|
+
- spec/fitreader_readfile_spec.rb
|
136
|
+
- spec/fitreader_static_spec.rb
|
146
137
|
- test/fitreader_test.rb
|
147
138
|
- test/test_helper.rb
|
data/spec/fitreader_spec.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'fitreader'
|
3
|
-
|
4
|
-
describe Fitreader::Static do
|
5
|
-
it 'const is loaded' do
|
6
|
-
expect(Fitreader::Static.enums.class).to eql(Hash)
|
7
|
-
end
|
8
|
-
|
9
|
-
it 'const has data' do
|
10
|
-
expect(Fitreader::Static.enums[:enum_file][1]).to eql(:device)
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'scope is readable' do
|
14
|
-
expect(Fitreader::Static.scope).to include(:ride)
|
15
|
-
expect(Fitreader::Static.scope).not_to include(:bike)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe Fitreader do
|
20
|
-
describe 'read fit file' do
|
21
|
-
before do
|
22
|
-
@path = File.join(File.dirname(__FILE__), '2016-04-09-13-19-18.fit')
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'test file exists' do
|
26
|
-
expect(File.exist?(@path)).to eql(true)
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'parses file without exceptions' do
|
30
|
-
expect { Fitreader.read(@path) }.not_to raise_error
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe 'has functioning interfaces' do
|
35
|
-
before do
|
36
|
-
@path = File.join(File.dirname(__FILE__), '2016-04-09-13-19-18.fit')
|
37
|
-
Fitreader.read(@path)
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'has a valid header' do
|
41
|
-
expect(Fitreader.header).not_to be_nil
|
42
|
-
expect(Fitreader.header.num_records).to be(89139)
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'has valid records' do
|
46
|
-
expect(Fitreader.available_records).not_to be_nil
|
47
|
-
expect(Fitreader.available_records.length).to be(14)
|
48
|
-
binding.pry
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'can return name-value data' do
|
52
|
-
expect(Fitreader.record_values :session).to be(Array)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|