@sports-alliance/sports-lib 7.0.8 → 7.0.9

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.
Files changed (326) hide show
  1. package/lib/esm/index.js +12034 -152
  2. package/package.json +2 -2
  3. package/lib/esm/activities/activity-parsing-options.js +0 -19
  4. package/lib/esm/activities/activity.interface.js +0 -1
  5. package/lib/esm/activities/activity.js +0 -281
  6. package/lib/esm/activities/activity.json.interface.js +0 -1
  7. package/lib/esm/activities/activity.spec.js +0 -348
  8. package/lib/esm/activities/activity.types.js +0 -1046
  9. package/lib/esm/activities/activityt-types.spec.js +0 -16
  10. package/lib/esm/activities/devices/device.interface.js +0 -1
  11. package/lib/esm/activities/devices/device.js +0 -26
  12. package/lib/esm/activities/devices/device.json.interface.js +0 -1
  13. package/lib/esm/constants/constants.js +0 -8
  14. package/lib/esm/creators/creator.interface.js +0 -1
  15. package/lib/esm/creators/creator.js +0 -37
  16. package/lib/esm/creators/creator.json.interface.js +0 -1
  17. package/lib/esm/creators/creator.spec.js +0 -25
  18. package/lib/esm/data/data-active-lap.js +0 -4
  19. package/lib/esm/data/data-active-lengths.js +0 -4
  20. package/lib/esm/data/data-aerobic-training-effect.js +0 -8
  21. package/lib/esm/data/data-anaerobic-training-effect.js +0 -8
  22. package/lib/esm/data/data-stance-time-balance-left.js +0 -4
  23. package/lib/esm/data/data-stance-time-balance-right.js +0 -4
  24. package/lib/esm/data/data-stance-time-balance.js +0 -3
  25. package/lib/esm/data/data-store.spec.js +0 -78
  26. package/lib/esm/data/data-total-cycles.js +0 -4
  27. package/lib/esm/data/data.absolute-pressure.js +0 -5
  28. package/lib/esm/data/data.accumulated-power.js +0 -8
  29. package/lib/esm/data/data.activity-types.js +0 -7
  30. package/lib/esm/data/data.air-power-avg.js +0 -4
  31. package/lib/esm/data/data.air-power-max.js +0 -4
  32. package/lib/esm/data/data.air-power-min.js +0 -4
  33. package/lib/esm/data/data.air-power.js +0 -8
  34. package/lib/esm/data/data.alti-baro-profile.js +0 -4
  35. package/lib/esm/data/data.altitude-avg.js +0 -4
  36. package/lib/esm/data/data.altitude-gps.js +0 -5
  37. package/lib/esm/data/data.altitude-max.js +0 -4
  38. package/lib/esm/data/data.altitude-min.js +0 -4
  39. package/lib/esm/data/data.altitude-smooth.js +0 -4
  40. package/lib/esm/data/data.altitude.js +0 -8
  41. package/lib/esm/data/data.array.js +0 -13
  42. package/lib/esm/data/data.ascent-time.js +0 -4
  43. package/lib/esm/data/data.ascent.js +0 -4
  44. package/lib/esm/data/data.auto-lap-distance.js +0 -5
  45. package/lib/esm/data/data.auto-lap-duration.js +0 -4
  46. package/lib/esm/data/data.auto-lap-used.js +0 -7
  47. package/lib/esm/data/data.auto-pause-used.js +0 -7
  48. package/lib/esm/data/data.avg-stride-length.js +0 -4
  49. package/lib/esm/data/data.balance.js +0 -6
  50. package/lib/esm/data/data.bare.js +0 -4
  51. package/lib/esm/data/data.battery-charge.js +0 -8
  52. package/lib/esm/data/data.battery-consumption.js +0 -8
  53. package/lib/esm/data/data.battery-current.js +0 -8
  54. package/lib/esm/data/data.battery-life-estimation.js +0 -4
  55. package/lib/esm/data/data.battery-voltage.js +0 -8
  56. package/lib/esm/data/data.bike-pod-used.js +0 -7
  57. package/lib/esm/data/data.boolean.js +0 -9
  58. package/lib/esm/data/data.cadence-avg.js +0 -4
  59. package/lib/esm/data/data.cadence-max.js +0 -4
  60. package/lib/esm/data/data.cadence-min.js +0 -4
  61. package/lib/esm/data/data.cadence.js +0 -8
  62. package/lib/esm/data/data.cycling-dynamics.js +0 -3
  63. package/lib/esm/data/data.cycling-position.js +0 -37
  64. package/lib/esm/data/data.cycling-seated-time.js +0 -5
  65. package/lib/esm/data/data.cycling-standing-time.js +0 -5
  66. package/lib/esm/data/data.descent-time.js +0 -4
  67. package/lib/esm/data/data.descent.js +0 -4
  68. package/lib/esm/data/data.description.js +0 -4
  69. package/lib/esm/data/data.device-location.js +0 -4
  70. package/lib/esm/data/data.device-names.js +0 -7
  71. package/lib/esm/data/data.distance.js +0 -15
  72. package/lib/esm/data/data.duration.js +0 -56
  73. package/lib/esm/data/data.ehpe.js +0 -5
  74. package/lib/esm/data/data.enabled-navigation-systems.js +0 -4
  75. package/lib/esm/data/data.end-altitude.js +0 -4
  76. package/lib/esm/data/data.end-position.js +0 -4
  77. package/lib/esm/data/data.energy.js +0 -8
  78. package/lib/esm/data/data.epoc.js +0 -5
  79. package/lib/esm/data/data.event.js +0 -3
  80. package/lib/esm/data/data.evpe.js +0 -4
  81. package/lib/esm/data/data.feeling.js +0 -15
  82. package/lib/esm/data/data.foot-pod-used.js +0 -7
  83. package/lib/esm/data/data.form-power.js +0 -4
  84. package/lib/esm/data/data.fused-altitude.js +0 -7
  85. package/lib/esm/data/data.fused-location.js +0 -7
  86. package/lib/esm/data/data.gnss-distance.js +0 -4
  87. package/lib/esm/data/data.grade-adjusted-pace-avg.js +0 -15
  88. package/lib/esm/data/data.grade-adjusted-pace-max.js +0 -15
  89. package/lib/esm/data/data.grade-adjusted-pace-min.js +0 -15
  90. package/lib/esm/data/data.grade-adjusted-pace.js +0 -25
  91. package/lib/esm/data/data.grade-adjusted-speed-avg.js +0 -46
  92. package/lib/esm/data/data.grade-adjusted-speed-max.js +0 -46
  93. package/lib/esm/data/data.grade-adjusted-speed-min.js +0 -46
  94. package/lib/esm/data/data.grade-adjusted-speed.js +0 -78
  95. package/lib/esm/data/data.grade-smooth.js +0 -7
  96. package/lib/esm/data/data.grade.js +0 -7
  97. package/lib/esm/data/data.ground-time.js +0 -8
  98. package/lib/esm/data/data.heart-rate-avg.js +0 -4
  99. package/lib/esm/data/data.heart-rate-max.js +0 -4
  100. package/lib/esm/data/data.heart-rate-min.js +0 -4
  101. package/lib/esm/data/data.heart-rate-used.js +0 -7
  102. package/lib/esm/data/data.heart-rate-zone-five-duration.js +0 -4
  103. package/lib/esm/data/data.heart-rate-zone-four-duration.js +0 -4
  104. package/lib/esm/data/data.heart-rate-zone-one-duration.js +0 -4
  105. package/lib/esm/data/data.heart-rate-zone-three-duration.js +0 -4
  106. package/lib/esm/data/data.heart-rate-zone-two-duration.js +0 -4
  107. package/lib/esm/data/data.heart-rate.js +0 -8
  108. package/lib/esm/data/data.ibi.js +0 -8
  109. package/lib/esm/data/data.interface.js +0 -5
  110. package/lib/esm/data/data.js +0 -62
  111. package/lib/esm/data/data.json.interface.js +0 -1
  112. package/lib/esm/data/data.latitude-degrees.js +0 -5
  113. package/lib/esm/data/data.left-balance.js +0 -4
  114. package/lib/esm/data/data.leg-stiffness.js +0 -16
  115. package/lib/esm/data/data.longitude-degrees.js +0 -5
  116. package/lib/esm/data/data.moving-time.js +0 -4
  117. package/lib/esm/data/data.number-of-satellites.js +0 -7
  118. package/lib/esm/data/data.number-of.samples.js +0 -4
  119. package/lib/esm/data/data.number.js +0 -13
  120. package/lib/esm/data/data.pace-avg.js +0 -8
  121. package/lib/esm/data/data.pace-max.js +0 -8
  122. package/lib/esm/data/data.pace-min.js +0 -8
  123. package/lib/esm/data/data.pace.js +0 -46
  124. package/lib/esm/data/data.pause.js +0 -4
  125. package/lib/esm/data/data.peak-epoc.js +0 -7
  126. package/lib/esm/data/data.peak-training-effect.js +0 -4
  127. package/lib/esm/data/data.percent.js +0 -4
  128. package/lib/esm/data/data.pool-length.js +0 -5
  129. package/lib/esm/data/data.position.interface.js +0 -1
  130. package/lib/esm/data/data.position.js +0 -18
  131. package/lib/esm/data/data.power-avg.js +0 -4
  132. package/lib/esm/data/data.power-down.js +0 -4
  133. package/lib/esm/data/data.power-intensity-factor.js +0 -5
  134. package/lib/esm/data/data.power-left.js +0 -4
  135. package/lib/esm/data/data.power-max.js +0 -4
  136. package/lib/esm/data/data.power-min.js +0 -4
  137. package/lib/esm/data/data.power-normalized.js +0 -4
  138. package/lib/esm/data/data.power-pedal-smoothness-left.js +0 -4
  139. package/lib/esm/data/data.power-pedal-smoothness-right.js +0 -4
  140. package/lib/esm/data/data.power-pod-used.js +0 -7
  141. package/lib/esm/data/data.power-right.js +0 -4
  142. package/lib/esm/data/data.power-torque-effectiveness-left.js +0 -4
  143. package/lib/esm/data/data.power-torque-effectiveness-right.js +0 -4
  144. package/lib/esm/data/data.power-training-stress-score.js +0 -5
  145. package/lib/esm/data/data.power-up.js +0 -4
  146. package/lib/esm/data/data.power-work.js +0 -5
  147. package/lib/esm/data/data.power-zone-five-duration.js +0 -4
  148. package/lib/esm/data/data.power-zone-four-duration.js +0 -4
  149. package/lib/esm/data/data.power-zone-one-duration.js +0 -4
  150. package/lib/esm/data/data.power-zone-three-duration.js +0 -4
  151. package/lib/esm/data/data.power-zone-two-duration.js +0 -4
  152. package/lib/esm/data/data.power.js +0 -8
  153. package/lib/esm/data/data.recovery-time.js +0 -7
  154. package/lib/esm/data/data.rider-position-change-event.js +0 -8
  155. package/lib/esm/data/data.right-balance.js +0 -4
  156. package/lib/esm/data/data.rpe.js +0 -23
  157. package/lib/esm/data/data.satellite-5-best-snr.js +0 -4
  158. package/lib/esm/data/data.sea-level-pressure.js +0 -5
  159. package/lib/esm/data/data.spec.js +0 -25
  160. package/lib/esm/data/data.speed-avg.js +0 -46
  161. package/lib/esm/data/data.speed-max.js +0 -46
  162. package/lib/esm/data/data.speed-min.js +0 -46
  163. package/lib/esm/data/data.speed-zone-five-duration.js +0 -4
  164. package/lib/esm/data/data.speed-zone-four-duration.js +0 -4
  165. package/lib/esm/data/data.speed-zone-one-duration.js +0 -4
  166. package/lib/esm/data/data.speed-zone-three-duration.js +0 -4
  167. package/lib/esm/data/data.speed-zone-two-duration.js +0 -4
  168. package/lib/esm/data/data.speed.js +0 -88
  169. package/lib/esm/data/data.sport-profile-name.js +0 -4
  170. package/lib/esm/data/data.stance-time.js +0 -5
  171. package/lib/esm/data/data.start-altitude.js +0 -4
  172. package/lib/esm/data/data.start-event.js +0 -4
  173. package/lib/esm/data/data.start-position.js +0 -4
  174. package/lib/esm/data/data.step-length.js +0 -4
  175. package/lib/esm/data/data.steps-old.js +0 -4
  176. package/lib/esm/data/data.steps.js +0 -4
  177. package/lib/esm/data/data.stop-all-event.js +0 -4
  178. package/lib/esm/data/data.stop-event.js +0 -4
  179. package/lib/esm/data/data.store.export.spec.js +0 -66
  180. package/lib/esm/data/data.store.js +0 -1213
  181. package/lib/esm/data/data.string.js +0 -13
  182. package/lib/esm/data/data.stryd-altitude.js +0 -4
  183. package/lib/esm/data/data.stryd-distance.js +0 -4
  184. package/lib/esm/data/data.stryd-speed.js +0 -4
  185. package/lib/esm/data/data.swim-pace-avg.js +0 -8
  186. package/lib/esm/data/data.swim-pace-max.js +0 -8
  187. package/lib/esm/data/data.swim-pace-min.js +0 -8
  188. package/lib/esm/data/data.swim-pace.js +0 -19
  189. package/lib/esm/data/data.swolf-25m.js +0 -4
  190. package/lib/esm/data/data.swolf-50m.js +0 -4
  191. package/lib/esm/data/data.target-distance.js +0 -4
  192. package/lib/esm/data/data.target-heart-rate-zone.js +0 -4
  193. package/lib/esm/data/data.target-power-zone.js +0 -4
  194. package/lib/esm/data/data.target-speed-zone.js +0 -4
  195. package/lib/esm/data/data.target-time.js +0 -4
  196. package/lib/esm/data/data.temperature-avg.js +0 -4
  197. package/lib/esm/data/data.temperature-max.js +0 -4
  198. package/lib/esm/data/data.temperature-min.js +0 -4
  199. package/lib/esm/data/data.temperature.js +0 -8
  200. package/lib/esm/data/data.time.js +0 -6
  201. package/lib/esm/data/data.timer-time.js +0 -4
  202. package/lib/esm/data/data.vertical-oscillation.js +0 -5
  203. package/lib/esm/data/data.vertical-ratio.js +0 -5
  204. package/lib/esm/data/data.vertical-speed-avg.js +0 -53
  205. package/lib/esm/data/data.vertical-speed-max.js +0 -53
  206. package/lib/esm/data/data.vertical-speed-min.js +0 -53
  207. package/lib/esm/data/data.vertical-speed.js +0 -103
  208. package/lib/esm/data/data.vo2-max.js +0 -7
  209. package/lib/esm/data/ibi/data.ibi.filters.js +0 -52
  210. package/lib/esm/data/ibi/data.ibi.js +0 -98
  211. package/lib/esm/data/ibi/data.ibi.spec.js +0 -66
  212. package/lib/esm/duration/duration.class.abstract.js +0 -36
  213. package/lib/esm/duration/duration.class.interface.js +0 -1
  214. package/lib/esm/errors/duration-exceeded-event-lib.error.js +0 -9
  215. package/lib/esm/errors/empty-event-sports-libs.error.js +0 -9
  216. package/lib/esm/errors/event-lib.error.js +0 -8
  217. package/lib/esm/errors/lib.error.js +0 -6
  218. package/lib/esm/errors/parsing-event-lib.error.js +0 -9
  219. package/lib/esm/events/adapters/exporters/exporter.gpx.js +0 -75
  220. package/lib/esm/events/adapters/exporters/exporter.interface.js +0 -1
  221. package/lib/esm/events/adapters/exporters/exporter.json.js +0 -20
  222. package/lib/esm/events/adapters/file-type.enum.js +0 -7
  223. package/lib/esm/events/adapters/importers/fit/importer.fit.ant-plus.device.names.js +0 -25
  224. package/lib/esm/events/adapters/importers/fit/importer.fit.coros.device.names.js +0 -5
  225. package/lib/esm/events/adapters/importers/fit/importer.fit.development.device.names.js +0 -4
  226. package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.device.names.js +0 -462
  227. package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.data.js +0 -877
  228. package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.mapper.js +0 -106
  229. package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.mapper.spec.js +0 -32
  230. package/lib/esm/events/adapters/importers/fit/importer.fit.hammerhead.device.names.js +0 -4
  231. package/lib/esm/events/adapters/importers/fit/importer.fit.integration.spec.js +0 -44
  232. package/lib/esm/events/adapters/importers/fit/importer.fit.js +0 -978
  233. package/lib/esm/events/adapters/importers/fit/importer.fit.lezyne.device.names.js +0 -3
  234. package/lib/esm/events/adapters/importers/fit/importer.fit.magellan.device.names.js +0 -5
  235. package/lib/esm/events/adapters/importers/fit/importer.fit.mapper.js +0 -231
  236. package/lib/esm/events/adapters/importers/fit/importer.fit.saris.device.names.js +0 -3
  237. package/lib/esm/events/adapters/importers/fit/importer.fit.spec.js +0 -326
  238. package/lib/esm/events/adapters/importers/fit/importer.fit.srm.device.names.js +0 -7
  239. package/lib/esm/events/adapters/importers/fit/importer.fit.suunto.device.names.js +0 -16
  240. package/lib/esm/events/adapters/importers/fit/importer.fit.wahoo.device.names.js +0 -10
  241. package/lib/esm/events/adapters/importers/gpx/gx-parser.js +0 -36
  242. package/lib/esm/events/adapters/importers/gpx/importer.gpx.integration.spec.js +0 -44
  243. package/lib/esm/events/adapters/importers/gpx/importer.gpx.js +0 -102
  244. package/lib/esm/events/adapters/importers/gpx/importer.gpx.mapper.js +0 -142
  245. package/lib/esm/events/adapters/importers/gpx/importer.gpx.spec.js +0 -71
  246. package/lib/esm/events/adapters/importers/json/importer.json.js +0 -160
  247. package/lib/esm/events/adapters/importers/sample-info.interface.js +0 -1
  248. package/lib/esm/events/adapters/importers/suunto/importer.suunto.activity.ids.js +0 -85
  249. package/lib/esm/events/adapters/importers/suunto/importer.suunto.device.names.js +0 -26
  250. package/lib/esm/events/adapters/importers/suunto/importer.suunto.integration.spec.js +0 -44
  251. package/lib/esm/events/adapters/importers/suunto/importer.suunto.json.js +0 -717
  252. package/lib/esm/events/adapters/importers/suunto/importer.suunto.sml.js +0 -125
  253. package/lib/esm/events/adapters/importers/tcx/importer.tcx.integration.spec.js +0 -46
  254. package/lib/esm/events/adapters/importers/tcx/importer.tcx.js +0 -442
  255. package/lib/esm/events/adapters/importers/tcx/importer.tcx.mapper.js +0 -91
  256. package/lib/esm/events/adapters/importers/tcx/utils.tcx.js +0 -36
  257. package/lib/esm/events/event.interface.js +0 -1
  258. package/lib/esm/events/event.js +0 -123
  259. package/lib/esm/events/event.json.interface.js +0 -1
  260. package/lib/esm/events/event.spec.js +0 -51
  261. package/lib/esm/events/utilities/activity.utilities.js +0 -1841
  262. package/lib/esm/events/utilities/activity.utilities.spec.js +0 -373
  263. package/lib/esm/events/utilities/event.utilities.js +0 -57
  264. package/lib/esm/events/utilities/grade-calculator/grade-calculator.js +0 -121
  265. package/lib/esm/events/utilities/grade-calculator/grade-calculator.spec.js +0 -93
  266. package/lib/esm/events/utilities/grade-calculator/low-pass-filter.js +0 -86
  267. package/lib/esm/events/utilities/helpers.js +0 -162
  268. package/lib/esm/geodesy/adapters/adapter.interface.js +0 -1
  269. package/lib/esm/geodesy/adapters/geolib.adapter.js +0 -28
  270. package/lib/esm/id/id.abstract.class.js +0 -9
  271. package/lib/esm/id/id.class.interface.js +0 -1
  272. package/lib/esm/id/id.class.spec.js +0 -13
  273. package/lib/esm/intensity-zones/intensity-zones.interface.js +0 -1
  274. package/lib/esm/intensity-zones/intensity-zones.js +0 -29
  275. package/lib/esm/intensity-zones/intensity-zones.json.interface.js +0 -1
  276. package/lib/esm/intensity-zones/intensity-zones.spec.js +0 -30
  277. package/lib/esm/laps/lap.interface.js +0 -1
  278. package/lib/esm/laps/lap.js +0 -29
  279. package/lib/esm/laps/lap.json.interface.js +0 -1
  280. package/lib/esm/laps/lap.types.js +0 -52
  281. package/lib/esm/meta-data/event-meta-data.interface.js +0 -6
  282. package/lib/esm/meta-data/meta-data.js +0 -57
  283. package/lib/esm/meta-data/meta-data.json.interface.js +0 -1
  284. package/lib/esm/privacy/privacy.class.interface.js +0 -5
  285. package/lib/esm/serializable/serializable.class.interface.js +0 -1
  286. package/lib/esm/service-tokens/oauth1-service-token.interface.js +0 -1
  287. package/lib/esm/service-tokens/oauth2-service-token.interface.js +0 -1
  288. package/lib/esm/specs/activities-parsing.integration.spec.js +0 -1847
  289. package/lib/esm/specs/activity-duration-stream.integration.spec.js +0 -57
  290. package/lib/esm/specs/fixtures/streams/strava/rides/3171472783.json +0 -52534
  291. package/lib/esm/specs/fixtures/streams/strava/rides/3171487458.json +0 -78818
  292. package/lib/esm/specs/fixtures/streams/strava/rides/343080886.json +0 -105090
  293. package/lib/esm/specs/fixtures/streams/strava/rides/5910143591.json +0 -110711
  294. package/lib/esm/specs/fixtures/streams/strava/runs/2451375851.json +0 -74846
  295. package/lib/esm/specs/fixtures/streams/strava/runs/2709634581.json +0 -66817
  296. package/lib/esm/specs/fixtures/streams/strava/runs/3156040843.json +0 -17594
  297. package/lib/esm/specs/fixtures/streams/strava/runs/3182900697.json +0 -17322
  298. package/lib/esm/specs/fixtures/streams/strava/runs/3183465494.json +0 -20463
  299. package/lib/esm/specs/fixtures/streams/strava/runs/3183490558.json +0 -58202
  300. package/lib/esm/specs/spec-utils.js +0 -159
  301. package/lib/esm/specs/strava-streams-compliance.spec.js +0 -951
  302. package/lib/esm/stats/stats.class.abstract.js +0 -32
  303. package/lib/esm/stats/stats.class.interface.js +0 -1
  304. package/lib/esm/stats/stats.json.interface.js +0 -1
  305. package/lib/esm/streams/compressed.stream.interface.js +0 -12
  306. package/lib/esm/streams/ibi-stream.js +0 -43
  307. package/lib/esm/streams/low-pass.stream.filter.js +0 -9
  308. package/lib/esm/streams/stream.filter.interface.js +0 -1
  309. package/lib/esm/streams/stream.interface.js +0 -1
  310. package/lib/esm/streams/stream.js +0 -72
  311. package/lib/esm/streams/stream.spec.js +0 -168
  312. package/lib/esm/tiles/tile.settings.interface.js +0 -41
  313. package/lib/esm/users/settings/dashboard/user.dashboard.settings.interface.js +0 -13
  314. package/lib/esm/users/settings/user.app.settings.interface.js +0 -5
  315. package/lib/esm/users/settings/user.chart.settings.interface.js +0 -23
  316. package/lib/esm/users/settings/user.map.settings.interface.js +0 -22
  317. package/lib/esm/users/settings/user.my-tracks.settings.interface.js +0 -1
  318. package/lib/esm/users/settings/user.settings.interface.js +0 -1
  319. package/lib/esm/users/settings/user.stats-settings.interface.js +0 -1
  320. package/lib/esm/users/settings/user.summaries.settings.interface.js +0 -1
  321. package/lib/esm/users/settings/user.unit.settings.interface.js +0 -73
  322. package/lib/esm/users/user.account.privileges.interface.js +0 -1
  323. package/lib/esm/users/user.export-to-csv.settings.interface.js +0 -1
  324. package/lib/esm/users/user.interface.js +0 -1
  325. package/lib/esm/users/user.js +0 -38
  326. package/lib/esm/users/user.service.meta.interface.js +0 -1
@@ -1,951 +0,0 @@
1
- import fs from 'fs';
2
- import { SportsLib } from '../index';
3
- import * as strava_3156040843 from './fixtures/streams/strava/runs/3156040843.json';
4
- import * as strava_3182900697 from './fixtures/streams/strava/runs/3182900697.json';
5
- import * as strava_2451375851 from './fixtures/streams/strava/runs/2451375851.json';
6
- import * as strava_3183465494 from './fixtures/streams/strava/runs/3183465494.json';
7
- import * as strava_3183490558 from './fixtures/streams/strava/runs/3183490558.json';
8
- import * as strava_2709634581 from './fixtures/streams/strava/runs/2709634581.json';
9
- import * as strava_343080886 from './fixtures/streams/strava/rides/343080886.json';
10
- import * as strava_5910143591 from './fixtures/streams/strava/rides/5910143591.json';
11
- import * as strava_3171438371_gpx from './fixtures/streams/strava/rides/3171472783.json';
12
- import * as strava_3171487458_tcx from './fixtures/streams/strava/rides/3171487458.json';
13
- import { DataAltitude } from '../data/data.altitude';
14
- import { DataHeartRate } from '../data/data.heart-rate';
15
- import { DataCadence } from '../data/data.cadence';
16
- import { DataTemperature } from '../data/data.temperature';
17
- import { DataPower } from '../data/data.power';
18
- import { DataDistance } from '../data/data.distance';
19
- import xmldom from '@xmldom/xmldom';
20
- import { DataGrade } from '../data/data.grade';
21
- export const GRADE_TOLERANCE = 1.7;
22
- function clone(obj) {
23
- return JSON.parse(JSON.stringify(obj));
24
- }
25
- describe('Strava stream compliance', () => {
26
- const domParser = new xmldom.DOMParser();
27
- const averageDeltaBetweenStreams = (actualStream, expectedStream) => {
28
- let deltaSum = 0;
29
- actualStream.forEach((value, index) => {
30
- deltaSum += Math.abs(value - expectedStream[index]);
31
- });
32
- return deltaSum / actualStream.length;
33
- };
34
- describe('Compliance with garmin edge export (hilly activity)', () => {
35
- // Given https://connect.garmin.com/modern/activity/7432332116 OR https://www.strava.com/activities/5910143591 (FTP 201 w @ Weight 78.3 kg)
36
- const path = __dirname + '/fixtures/rides/fit/7432332116.fit';
37
- const buffer = fs.readFileSync(path);
38
- it(`should have an average grade diff lower than ${GRADE_TOLERANCE}%`, done => {
39
- // Given
40
- const toleranceAvgGradeDelta = GRADE_TOLERANCE;
41
- const stravaGradeStream = clone(strava_5910143591.grade_smooth);
42
- // When
43
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
44
- // Then
45
- eventInterfacePromise.then((event) => {
46
- const streamData = event
47
- .getFirstActivity()
48
- .getSquashedStreamData(DataGrade.type)
49
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
50
- expect(stravaGradeStream.length).toEqual(streamData.length);
51
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
52
- console.log(`Delta is ${deltaBetweenStreams}`);
53
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
54
- done();
55
- });
56
- });
57
- });
58
- describe('Compliance with garmin Forerunner 945 export (hilly activity)', () => {
59
- // Given: https://connect.garmin.com/modern/activity/6782987395 OR https://www.strava.com/activities/2451375851
60
- const path = __dirname + '/fixtures/runs/fit/6782987395.fit';
61
- const buffer = fs.readFileSync(path);
62
- it(`should have an average grade diff lower than 2.1%`, done => {
63
- // Given
64
- const toleranceAvgGradeDelta = 2.1;
65
- const stravaGradeStream = clone(strava_2451375851.grade_smooth);
66
- // When
67
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
68
- // Then
69
- eventInterfacePromise.then((event) => {
70
- const streamData = event
71
- .getFirstActivity()
72
- .getSquashedStreamData(DataGrade.type)
73
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
74
- expect(stravaGradeStream.length).toEqual(streamData.length);
75
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
76
- console.log(`Delta is ${deltaBetweenStreams}`);
77
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
78
- done();
79
- });
80
- });
81
- });
82
- /*
83
- describe('Compliance with garmin fenix 6S Pro export (hilly activity)', () => {
84
- // Given: https://connect.garmin.com/modern/activity/7428153946 OR https://www.strava.com/activities/5889573727
85
- const path = __dirname + '/fixtures/runs/fit/7428153946.fit';
86
- const buffer = fs.readFileSync(path);
87
-
88
- it(`should have an average grade diff lower than ${GRADE_TOLERANCE}%`, done => {
89
- // Given
90
- const toleranceAvgGradeDelta = GRADE_TOLERANCE;
91
-
92
- const stravaGradeStream = clone(strava_5889573727.grade_smooth);
93
-
94
- // When
95
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
96
-
97
- // Then
98
- eventInterfacePromise.then((event: EventInterface) => {
99
- const streamData = <number[]>event.getFirstActivity().getSquashedStreamData(DataGrade.type);
100
- // .map(value => (value === null ? null : Math.round(value * 10) / 10));
101
- // expect(stravaGradeStream.length).toEqual(streamData.length);
102
- const deltaBetweenStreams = averageDeltaBetweenStreams(stravaGradeStream, streamData);
103
- console.log(`Delta is ${deltaBetweenStreams}`);
104
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
105
- done();
106
- });
107
- });
108
- });
109
- */
110
- describe('Compliance with suunto export (flat activity)', () => {
111
- // Given FIT Source (Suunto export): https://connect.garmin.com/modern/activity/6909950168 OR https://www.strava.com/activities/5423646653
112
- const path = __dirname + '/fixtures/runs/fit/6909950168.fit';
113
- const buffer = fs.readFileSync(path);
114
- it(`should match time`, done => {
115
- // Given
116
- const stravaCadenceStream = clone(strava_3156040843.time);
117
- // When
118
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
119
- // Then
120
- eventInterfacePromise.then((event) => {
121
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true).length);
122
- expect(stravaCadenceStream).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true));
123
- done();
124
- });
125
- });
126
- it(`should match altitude`, done => {
127
- // Given
128
- const stravaAltitudeStream = clone(strava_3156040843.altitude);
129
- // When
130
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
131
- // Then
132
- eventInterfacePromise.then((event) => {
133
- expect(stravaAltitudeStream.length).toEqual(event.getFirstActivity().getStreamData(DataAltitude.type).length);
134
- expect(stravaAltitudeStream).toEqual(event
135
- .getFirstActivity()
136
- .getStreamData(DataAltitude.type)
137
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
138
- done();
139
- });
140
- });
141
- it(`should match heart rate`, done => {
142
- // Given
143
- const stravaHeartRateStream = clone(strava_3156040843.heartrate);
144
- // When
145
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
146
- // Then
147
- eventInterfacePromise.then((event) => {
148
- expect(stravaHeartRateStream.length).toEqual(event.getFirstActivity().getStreamData(DataHeartRate.type).length);
149
- expect(stravaHeartRateStream).toEqual(event
150
- .getFirstActivity()
151
- .getStreamData(DataHeartRate.type)
152
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
153
- done();
154
- });
155
- });
156
- it(`should match cadence`, done => {
157
- // Given
158
- const stravaCadenceStream = clone(strava_3156040843.cadence);
159
- // When
160
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
161
- // Then
162
- eventInterfacePromise.then((event) => {
163
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().getStreamData(DataCadence.type).length);
164
- expect(stravaCadenceStream).toEqual(event
165
- .getFirstActivity()
166
- .getStreamData(DataCadence.type)
167
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
168
- done();
169
- });
170
- });
171
- it(`should match temperature`, done => {
172
- // Given
173
- const stravaTemperatureStream = clone(strava_3156040843.temp);
174
- // When
175
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
176
- // Then
177
- eventInterfacePromise.then((event) => {
178
- expect(stravaTemperatureStream.length).toEqual(event.getFirstActivity().getStreamData(DataTemperature.type).length);
179
- expect(stravaTemperatureStream).toEqual(event
180
- .getFirstActivity()
181
- .getStreamData(DataTemperature.type)
182
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
183
- done();
184
- });
185
- });
186
- /**
187
- * This test has not sense anymore since null watts provided from a squashed streams should considered as 0 watts
188
- */
189
- xit(`should match power`, done => {
190
- // Given
191
- const stravaPowerStream = clone(strava_3156040843.watts);
192
- // When
193
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
194
- // Then
195
- eventInterfacePromise.then((event) => {
196
- expect(stravaPowerStream.length).toEqual(event.getFirstActivity().getStreamData(DataPower.type).length);
197
- expect(stravaPowerStream).toEqual(event
198
- .getFirstActivity()
199
- .getStreamData(DataPower.type)
200
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
201
- done();
202
- });
203
- });
204
- it(`should match distance with x% error max`, done => {
205
- // Given
206
- const tolerance = 0.6; // percent
207
- const stravaDistanceStream = clone(strava_3156040843.distance);
208
- // When
209
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
210
- // Then
211
- eventInterfacePromise.then((event) => {
212
- const streamData = event
213
- .getFirstActivity()
214
- .getStreamData(DataDistance.type)
215
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
216
- expect(stravaDistanceStream.length).toEqual(streamData.length);
217
- const commonCount = stravaDistanceStream.filter((value) => streamData.indexOf(value) !== -1).length;
218
- expect(commonCount + Math.ceil((stravaDistanceStream.length * tolerance) / 100)).toBeGreaterThanOrEqual(stravaDistanceStream.length);
219
- // expect(stravaDistanceStream).toEqual(streamData);
220
- done();
221
- });
222
- });
223
- it(`should have an average grade diff lower than ${GRADE_TOLERANCE}%`, done => {
224
- // Given
225
- const toleranceAvgGradeDelta = GRADE_TOLERANCE;
226
- const stravaGradeStream = clone(strava_3156040843.grade_smooth);
227
- // When
228
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
229
- // Then
230
- eventInterfacePromise.then((event) => {
231
- const streamData = event
232
- .getFirstActivity()
233
- .getStreamData(DataGrade.type)
234
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
235
- expect(stravaGradeStream.length).toEqual(streamData.length);
236
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
237
- console.log(`Delta is ${deltaBetweenStreams}`);
238
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
239
- done();
240
- });
241
- });
242
- });
243
- describe('Compliance with suunto export (flat activity) without paused records', () => {
244
- // Given FIT Source (Suunto export): https://connect.garmin.com/modern/activity/6909950168 OR https://www.strava.com/activities/5423646653
245
- const path = __dirname + '/fixtures/runs/fit/6909950168-no-pause-records.fit';
246
- const buffer = fs.readFileSync(path);
247
- it(`should match time`, done => {
248
- // Given
249
- const stravaCadenceStream = clone(strava_3182900697.time);
250
- // When
251
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
252
- // Then
253
- eventInterfacePromise.then((event) => {
254
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true).length);
255
- expect(stravaCadenceStream).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true));
256
- done();
257
- });
258
- });
259
- it(`should match altitude`, done => {
260
- // Given
261
- const stravaAltitudeStream = clone(strava_3182900697.altitude);
262
- // When
263
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
264
- // Then
265
- eventInterfacePromise.then((event) => {
266
- expect(stravaAltitudeStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataAltitude.type).length);
267
- expect(stravaAltitudeStream).toEqual(event
268
- .getFirstActivity()
269
- .getSquashedStreamData(DataAltitude.type)
270
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
271
- done();
272
- });
273
- });
274
- it(`should match heart rate`, done => {
275
- // Given
276
- const stravaHeartRateStream = clone(strava_3182900697.heartrate);
277
- // When
278
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
279
- // Then
280
- eventInterfacePromise.then((event) => {
281
- expect(stravaHeartRateStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataHeartRate.type).length);
282
- expect(stravaHeartRateStream).toEqual(event
283
- .getFirstActivity()
284
- .getSquashedStreamData(DataHeartRate.type)
285
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
286
- done();
287
- });
288
- });
289
- it(`should match cadence`, done => {
290
- // Given
291
- const stravaCadenceStream = clone(strava_3182900697.cadence);
292
- // When
293
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
294
- // Then
295
- eventInterfacePromise.then((event) => {
296
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataCadence.type).length);
297
- expect(stravaCadenceStream).toEqual(event
298
- .getFirstActivity()
299
- .getSquashedStreamData(DataCadence.type)
300
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
301
- done();
302
- });
303
- });
304
- it(`should match distance with x% error max`, done => {
305
- // Given
306
- const tolerance = 0.6; // percent
307
- const stravaDistanceStream = clone(strava_3182900697.distance);
308
- // When
309
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
310
- // Then
311
- eventInterfacePromise.then((event) => {
312
- const streamData = event
313
- .getFirstActivity()
314
- .getSquashedStreamData(DataDistance.type)
315
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
316
- expect(stravaDistanceStream.length).toEqual(streamData.length);
317
- const commonCount = stravaDistanceStream.filter((value) => streamData.indexOf(value) !== -1).length;
318
- expect(commonCount + Math.ceil((stravaDistanceStream.length * tolerance) / 100)).toBeGreaterThanOrEqual(stravaDistanceStream.length);
319
- // expect(stravaDistanceStream).toEqual(streamData);
320
- done();
321
- });
322
- });
323
- it(`should have an average grade diff lower than ${GRADE_TOLERANCE}%`, done => {
324
- // Given
325
- const toleranceAvgGradeDelta = GRADE_TOLERANCE;
326
- const stravaGradeStream = clone(strava_3182900697.grade_smooth);
327
- // When
328
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
329
- // Then
330
- eventInterfacePromise.then((event) => {
331
- const streamData = event
332
- .getFirstActivity()
333
- .getSquashedStreamData(DataGrade.type)
334
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
335
- expect(stravaGradeStream.length).toEqual(streamData.length);
336
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
337
- console.log(`Delta is ${deltaBetweenStreams}`);
338
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
339
- done();
340
- });
341
- });
342
- });
343
- describe('Compliance with suunto export (uphill 1800 activity) without paused records ', () => {
344
- // Given FIT Source (Suunto export): https://connect.garmin.com/modern/activity/6910052863 OR https://www.strava.com/activities/5423660493
345
- const path = __dirname + '/fixtures/runs/fit/6910052863.fit';
346
- const buffer = fs.readFileSync(path);
347
- it(`should match time`, done => {
348
- // Given
349
- const stravaCadenceStream = clone(strava_2709634581.time);
350
- // When
351
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
352
- // Then
353
- eventInterfacePromise.then((event) => {
354
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().generateTimeStream().getData(true).length);
355
- expect(stravaCadenceStream).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true));
356
- done();
357
- });
358
- });
359
- it(`should match altitude`, done => {
360
- // Given
361
- const stravaAltitudeStream = clone(strava_2709634581.altitude);
362
- // When
363
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
364
- // Then
365
- eventInterfacePromise.then((event) => {
366
- expect(stravaAltitudeStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataAltitude.type).length);
367
- expect(stravaAltitudeStream).toEqual(event
368
- .getFirstActivity()
369
- .getSquashedStreamData(DataAltitude.type)
370
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
371
- done();
372
- });
373
- });
374
- it(`should match heart rate`, done => {
375
- // Given
376
- const stravaHeartRateStream = clone(strava_2709634581.heartrate);
377
- // When
378
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
379
- // Then
380
- eventInterfacePromise.then((event) => {
381
- expect(stravaHeartRateStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataHeartRate.type).length);
382
- expect(stravaHeartRateStream).toEqual(event
383
- .getFirstActivity()
384
- .getSquashedStreamData(DataHeartRate.type)
385
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
386
- done();
387
- });
388
- });
389
- it(`should match cadence`, done => {
390
- // Given
391
- const stravaCadenceStream = clone(strava_2709634581.cadence);
392
- // When
393
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
394
- // Then
395
- eventInterfacePromise.then((event) => {
396
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataCadence.type).length);
397
- expect(stravaCadenceStream).toEqual(event
398
- .getFirstActivity()
399
- .getSquashedStreamData(DataCadence.type)
400
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
401
- done();
402
- });
403
- });
404
- it.skip(`should match distance with x% error max`, done => {
405
- // Given
406
- const tolerance = 0.6; // percent
407
- const stravaDistanceStream = clone(strava_2709634581.distance);
408
- // When
409
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
410
- // Then
411
- eventInterfacePromise.then((event) => {
412
- const streamData = event
413
- .getFirstActivity()
414
- .getSquashedStreamData(DataDistance.type)
415
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
416
- // expect(stravaDistanceStream.length).toEqual(streamData.length);
417
- const commonCount = stravaDistanceStream.filter((value) => streamData.indexOf(value) !== -1).length;
418
- // expect(commonCount + Math.ceil((stravaDistanceStream.length * tolerance) / 100)).toBeGreaterThanOrEqual(stravaDistanceStream.length);
419
- expect(stravaDistanceStream).toEqual(streamData);
420
- done();
421
- });
422
- });
423
- it.skip(`should have an average grade diff lower than ${GRADE_TOLERANCE}%`, done => {
424
- // Given
425
- const toleranceAvgGradeDelta = GRADE_TOLERANCE;
426
- const stravaGradeStream = clone(strava_3182900697.grade_smooth);
427
- // When
428
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
429
- // Then
430
- eventInterfacePromise.then((event) => {
431
- const streamData = event
432
- .getFirstActivity()
433
- .getSquashedStreamData(DataGrade.type)
434
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
435
- expect(stravaGradeStream.length).toEqual(streamData.length);
436
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
437
- console.log(`Delta is ${deltaBetweenStreams}`);
438
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
439
- done();
440
- });
441
- });
442
- });
443
- describe('Compliance with COROS export', () => {
444
- // Given FIT Source (Coros export): https://connect.garmin.com/modern/activity/6916663933 OR https://www.strava.com/activities/5429996380
445
- const path = __dirname + '/fixtures/runs/fit/6916663933.fit';
446
- const buffer = fs.readFileSync(path);
447
- it(`should match time`, done => {
448
- // Given
449
- const stravaCadenceStream = clone(strava_3183465494.time);
450
- // When
451
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
452
- // Then
453
- eventInterfacePromise.then((event) => {
454
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true).length);
455
- expect(stravaCadenceStream).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true));
456
- done();
457
- });
458
- });
459
- it(`should match altitude`, done => {
460
- // Given
461
- const stravaAltitudeStream = clone(strava_3183465494.altitude);
462
- // When
463
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
464
- // Then
465
- eventInterfacePromise.then((event) => {
466
- expect(stravaAltitudeStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataAltitude.type).length);
467
- expect(stravaAltitudeStream).toEqual(event
468
- .getFirstActivity()
469
- .getSquashedStreamData(DataAltitude.type)
470
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
471
- done();
472
- });
473
- });
474
- it(`should match heart rate`, done => {
475
- // Given
476
- const stravaHeartRateStream = clone(strava_3183465494.heartrate);
477
- // When
478
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
479
- // Then
480
- eventInterfacePromise.then((event) => {
481
- expect(stravaHeartRateStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataHeartRate.type).length);
482
- expect(stravaHeartRateStream).toEqual(event
483
- .getFirstActivity()
484
- .getSquashedStreamData(DataHeartRate.type)
485
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
486
- done();
487
- });
488
- });
489
- it(`should match cadence`, done => {
490
- // Given
491
- const stravaCadenceStream = clone(strava_3183465494.cadence);
492
- // When
493
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
494
- // Then
495
- eventInterfacePromise.then((event) => {
496
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataCadence.type).length);
497
- expect(stravaCadenceStream).toEqual(event
498
- .getFirstActivity()
499
- .getSquashedStreamData(DataCadence.type)
500
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
501
- done();
502
- });
503
- });
504
- it(`should match distance`, done => {
505
- // Given
506
- const tolerance = 0.6; // percent
507
- const stravaDistanceStream = clone(strava_3183465494.distance);
508
- // When
509
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
510
- // Then
511
- eventInterfacePromise.then((event) => {
512
- const streamData = event
513
- .getFirstActivity()
514
- .getSquashedStreamData(DataDistance.type)
515
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
516
- expect(stravaDistanceStream.length).toEqual(streamData.length);
517
- expect(stravaDistanceStream).toEqual(streamData);
518
- done();
519
- });
520
- });
521
- it(`should have an average grade diff lower than ${GRADE_TOLERANCE}%`, done => {
522
- // Given
523
- const toleranceAvgGradeDelta = GRADE_TOLERANCE;
524
- const stravaGradeStream = clone(strava_3183465494.grade_smooth);
525
- // When
526
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
527
- // Then
528
- eventInterfacePromise.then((event) => {
529
- const streamData = event
530
- .getFirstActivity()
531
- .getSquashedStreamData(DataGrade.type)
532
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
533
- expect(stravaGradeStream.length).toEqual(streamData.length);
534
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
535
- console.log(`Delta is ${deltaBetweenStreams}`);
536
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
537
- done();
538
- });
539
- });
540
- });
541
- describe('Compliance with COROS export trail', () => {
542
- // Given FIT Source (Coros export): https://connect.garmin.com/modern/activity/6916728382 OR https://www.strava.com/activities/5430055225
543
- const path = __dirname + '/fixtures/runs/fit/6916728382.fit';
544
- const buffer = fs.readFileSync(path);
545
- it(`should match time`, done => {
546
- // Given
547
- const stravaCadenceStream = clone(strava_3183490558.time);
548
- // When
549
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
550
- // Then
551
- eventInterfacePromise.then((event) => {
552
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true).length);
553
- expect(stravaCadenceStream).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true));
554
- done();
555
- });
556
- });
557
- it(`should match altitude`, done => {
558
- // Given
559
- const stravaAltitudeStream = clone(strava_3183490558.altitude);
560
- // When
561
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
562
- // Then
563
- eventInterfacePromise.then((event) => {
564
- expect(stravaAltitudeStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataAltitude.type).length);
565
- expect(stravaAltitudeStream).toEqual(event
566
- .getFirstActivity()
567
- .getSquashedStreamData(DataAltitude.type)
568
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
569
- done();
570
- });
571
- });
572
- it(`should match heart rate`, done => {
573
- // Given
574
- const stravaHeartRateStream = clone(strava_3183490558.heartrate);
575
- // When
576
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
577
- // Then
578
- eventInterfacePromise.then((event) => {
579
- expect(stravaHeartRateStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataHeartRate.type).length);
580
- expect(stravaHeartRateStream).toEqual(event
581
- .getFirstActivity()
582
- .getSquashedStreamData(DataHeartRate.type)
583
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
584
- done();
585
- });
586
- });
587
- it(`should match cadence`, done => {
588
- // Given
589
- const stravaCadenceStream = clone(strava_3183490558.cadence);
590
- // When
591
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
592
- // Then
593
- eventInterfacePromise.then((event) => {
594
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataCadence.type).length);
595
- // @todo leaving this to fail to investigate how to fill linear as seen with Suunto
596
- expect(stravaCadenceStream).toEqual(event
597
- .getFirstActivity()
598
- .getSquashedStreamData(DataCadence.type)
599
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
600
- done();
601
- });
602
- });
603
- it.skip(`should match distance`, done => {
604
- // Given
605
- const tolerance = 0.6; // percent
606
- const stravaDistanceStream = clone(strava_3183490558.distance);
607
- // When
608
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
609
- // Then
610
- eventInterfacePromise.then((event) => {
611
- const streamData = event
612
- .getFirstActivity()
613
- .getSquashedStreamData(DataDistance.type)
614
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
615
- expect(stravaDistanceStream.length).toEqual(streamData.length);
616
- expect(stravaDistanceStream).toEqual(streamData);
617
- done();
618
- });
619
- });
620
- it.skip(`should have an average grade diff lower than ${GRADE_TOLERANCE}%`, done => {
621
- // Given
622
- const toleranceAvgGradeDelta = GRADE_TOLERANCE;
623
- const stravaGradeStream = clone(strava_3183490558.grade_smooth);
624
- // When
625
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
626
- // Then
627
- eventInterfacePromise.then((event) => {
628
- const streamData = event
629
- .getFirstActivity()
630
- .getSquashedStreamData(DataGrade.type)
631
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
632
- expect(stravaGradeStream.length).toEqual(streamData.length);
633
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
634
- console.log(`Delta is ${deltaBetweenStreams}`);
635
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
636
- done();
637
- });
638
- });
639
- });
640
- describe('Compliance with garmin export (hilly activity: https://connect.garmin.com/modern/activity/828989227 / https://www.strava.com/activities/343080886)', () => {
641
- describe('Fit file version', () => {
642
- // Given FIT Source: https://connect.garmin.com/modern/activity/828989227 OR https://www.strava.com/activities/343080886
643
- const path = __dirname + '/fixtures/rides/fit/828989227.fit';
644
- const buffer = fs.readFileSync(path);
645
- it(`should match time`, done => {
646
- // Given
647
- const stravaCadenceStream = clone(strava_343080886.time);
648
- // When
649
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
650
- // Then
651
- eventInterfacePromise.then((event) => {
652
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true).length);
653
- expect(stravaCadenceStream).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true));
654
- done();
655
- });
656
- });
657
- it(`should match altitude`, done => {
658
- // Given
659
- const stravaAltitudeStream = clone(strava_343080886.altitude);
660
- // When
661
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
662
- // Then
663
- eventInterfacePromise.then((event) => {
664
- expect(stravaAltitudeStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataAltitude.type).length);
665
- expect(stravaAltitudeStream).toEqual(event
666
- .getFirstActivity()
667
- .getSquashedStreamData(DataAltitude.type)
668
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
669
- done();
670
- });
671
- });
672
- it(`should match heart rate`, done => {
673
- // Given
674
- const stravaHeartRateStream = clone(strava_343080886.heartrate);
675
- // When
676
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
677
- // Then
678
- eventInterfacePromise.then((event) => {
679
- expect(stravaHeartRateStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataHeartRate.type).length);
680
- expect(stravaHeartRateStream).toEqual(event
681
- .getFirstActivity()
682
- .getSquashedStreamData(DataHeartRate.type)
683
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
684
- done();
685
- });
686
- });
687
- it(`should match cadence`, done => {
688
- // Given
689
- const stravaCadenceStream = clone(strava_343080886.cadence);
690
- // When
691
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
692
- // Then
693
- eventInterfacePromise.then((event) => {
694
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataCadence.type).length);
695
- expect(stravaCadenceStream).toEqual(event
696
- .getFirstActivity()
697
- .getSquashedStreamData(DataCadence.type)
698
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
699
- done();
700
- });
701
- });
702
- it(`should match distance with x% error max`, done => {
703
- // Given
704
- const tolerance = 0.0; // percent
705
- const stravaDistanceStream = clone(strava_343080886.distance);
706
- // When
707
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
708
- // Then
709
- eventInterfacePromise.then((event) => {
710
- expect(stravaDistanceStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataDistance.type).length);
711
- const streamData = event
712
- .getFirstActivity()
713
- .getSquashedStreamData(DataDistance.type)
714
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
715
- expect(stravaDistanceStream).toEqual(streamData);
716
- done();
717
- });
718
- });
719
- it(`should have an average grade diff lower than ${GRADE_TOLERANCE}%`, done => {
720
- // Given
721
- const toleranceAvgGradeDelta = GRADE_TOLERANCE;
722
- const stravaGradeStream = clone(strava_343080886.grade_smooth);
723
- // When
724
- const eventInterfacePromise = SportsLib.importFromFit(buffer);
725
- // Then
726
- eventInterfacePromise.then((event) => {
727
- const streamData = event
728
- .getFirstActivity()
729
- .getSquashedStreamData(DataGrade.type)
730
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
731
- expect(stravaGradeStream.length).toEqual(streamData.length);
732
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
733
- console.log(`Delta is ${deltaBetweenStreams}`);
734
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
735
- done();
736
- });
737
- });
738
- });
739
- describe('Tcx file version', () => {
740
- // Given FIT Source: https://connect.garmin.com/modern/activity/828989227 OR https://www.strava.com/activities/343080886
741
- const path = __dirname + '/fixtures/rides/tcx/828989227.tcx';
742
- const doc = domParser.parseFromString(fs.readFileSync(path).toString(), 'application/xml');
743
- it(`should match time`, done => {
744
- // Given
745
- const stravaCadenceStream = clone(strava_3171487458_tcx.time);
746
- // When
747
- const eventInterfacePromise = SportsLib.importFromTCX(doc);
748
- // Then
749
- eventInterfacePromise.then((event) => {
750
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true).length);
751
- expect(stravaCadenceStream).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true));
752
- done();
753
- });
754
- });
755
- it(`should match altitude`, done => {
756
- // Given
757
- const stravaAltitudeStream = clone(strava_3171487458_tcx.altitude);
758
- // When
759
- const eventInterfacePromise = SportsLib.importFromTCX(doc);
760
- // Then
761
- eventInterfacePromise.then((event) => {
762
- expect(stravaAltitudeStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataAltitude.type).length);
763
- expect(stravaAltitudeStream).toEqual(event
764
- .getFirstActivity()
765
- .getSquashedStreamData(DataAltitude.type)
766
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
767
- done();
768
- });
769
- });
770
- it(`should match heart rate`, done => {
771
- // Given
772
- const stravaHeartRateStream = clone(strava_3171487458_tcx.heartrate);
773
- // When
774
- const eventInterfacePromise = SportsLib.importFromTCX(doc);
775
- // Then
776
- eventInterfacePromise.then((event) => {
777
- expect(stravaHeartRateStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataHeartRate.type).length);
778
- expect(stravaHeartRateStream).toEqual(event
779
- .getFirstActivity()
780
- .getSquashedStreamData(DataHeartRate.type)
781
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
782
- done();
783
- });
784
- });
785
- it(`should match cadence`, done => {
786
- // Given
787
- const stravaCadenceStream = clone(strava_3171487458_tcx.cadence);
788
- // When
789
- const eventInterfacePromise = SportsLib.importFromTCX(doc);
790
- // Then
791
- eventInterfacePromise.then((event) => {
792
- expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataCadence.type).length);
793
- expect(stravaCadenceStream).toEqual(event
794
- .getFirstActivity()
795
- .getSquashedStreamData(DataCadence.type)
796
- .map(value => (value === null ? null : Math.round(value * 10) / 10)));
797
- done();
798
- });
799
- });
800
- it(`should match distance with x% error max`, done => {
801
- // Given
802
- const tolerance = 2.6; // percent
803
- const toleranceDelta = 0.1;
804
- const stravaDistanceStream = clone(strava_3171487458_tcx.distance);
805
- // When
806
- const eventInterfacePromise = SportsLib.importFromTCX(doc);
807
- // Then
808
- eventInterfacePromise.then((event) => {
809
- const streamData = event
810
- .getFirstActivity()
811
- .getSquashedStreamData(DataDistance.type)
812
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
813
- expect(stravaDistanceStream.length).toEqual(streamData.length);
814
- // const commonCount = stravaDistanceStream
815
- // .filter((value: number) => streamData.indexOf(value) !== -1).length;
816
- // We find the common then add the % tolerance and we check if its more than equal to the "strava" stream
817
- // expect(commonCount + Math.ceil((stravaDistanceStream.length * tolerance) / 100)).toBeGreaterThanOrEqual(stravaDistanceStream.length);
818
- expect(stravaDistanceStream).toMatchObject(streamData);
819
- // const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaDistanceStream);
820
- // expect(deltaBetweenStreams).toBeLessThan(toleranceDelta);
821
- done();
822
- });
823
- });
824
- it(`should have an average grade diff lower than ${GRADE_TOLERANCE}%`, done => {
825
- // Given
826
- const toleranceAvgGradeDelta = GRADE_TOLERANCE;
827
- const stravaGradeStream = clone(strava_343080886.grade_smooth);
828
- // When
829
- const eventInterfacePromise = SportsLib.importFromTCX(doc);
830
- // Then
831
- eventInterfacePromise.then((event) => {
832
- const streamData = event
833
- .getFirstActivity()
834
- .getSquashedStreamData(DataGrade.type)
835
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
836
- expect(stravaGradeStream.length).toEqual(streamData.length);
837
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
838
- console.log(`Delta is ${deltaBetweenStreams}`);
839
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
840
- done();
841
- });
842
- });
843
- });
844
- describe('GPX file version', () => {
845
- // Given GPX Source: https://connect.garmin.com/modern/activity/6870692308 OR https://www.strava.com/activities/5385683390
846
- // Given FIT Source: https://connect.garmin.com/modern/activity/828989227 OR https://www.strava.com/activities/343080886
847
- const path = __dirname + '/fixtures/rides/gpx/828989227.gpx';
848
- const gpxString = fs.readFileSync(path).toString();
849
- it(`should match time`, done => {
850
- // Given
851
- const stravaTimeStream = clone(strava_3171438371_gpx.time);
852
- // When
853
- const eventInterfacePromise = SportsLib.importFromGPX(gpxString, xmldom.DOMParser);
854
- // Then
855
- eventInterfacePromise.then((event) => {
856
- expect(stravaTimeStream.length).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true).length);
857
- expect(stravaTimeStream).toEqual(event.getFirstActivity().generateTimeStream([DataDistance.type, DataAltitude.type]).getData(true));
858
- done();
859
- });
860
- });
861
- // Strava adds their own altitude so no go from here
862
- // it(`should match altitude`, done => {
863
- //
864
- // // Given
865
- // const stravaAltitudeStream = clone(strava_3171438371_gpx.altitude);
866
- //
867
- // // When
868
- // const eventInterfacePromise = SportsLib.importFromGPX(gpxString);
869
- //
870
- // // Then
871
- // eventInterfacePromise.then((event: EventInterface) => {
872
- // expect(stravaAltitudeStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataAltitude.type).length);
873
- // expect(stravaAltitudeStream).toEqual(event.getFirstActivity().getSquashedStreamData(DataAltitude.type).map(value => value === null ? null : Math.round(value * 10) / 10));
874
- // done();
875
- // });
876
- // });
877
- // we skip this because https://support.strava.com/hc/en-us/community/posts/360054808092-Not-getting-Garmin-heart-rate-data-into-Strava
878
- // it(`should match heart rate`, done => {
879
- //
880
- // // Given
881
- // const stravaHeartRateStream = clone(strava_3171438371.heartrate);
882
- //
883
- // // When
884
- // const eventInterfacePromise = SportsLib.importFromGPX(gpxString);
885
- //
886
- // // Then
887
- // eventInterfacePromise.then((event: EventInterface) => {
888
- // expect(stravaHeartRateStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataHeartRate.type).length);
889
- // expect(stravaHeartRateStream).toEqual(event.getFirstActivity().getSquashedStreamData(DataHeartRate.type).map(value => value === null ? null : Math.round(value * 10) / 10));
890
- // done();
891
- // });
892
- // });
893
- // we skip this because https://support.strava.com/hc/en-us/community/posts/360054808092-Not-getting-Garmin-heart-rate-data-into-Strava
894
- // it(`should match cadence`, done => {
895
- //
896
- // // Given
897
- // const stravaCadenceStream = clone(strava_3171438371.cadence);
898
- //
899
- // // When
900
- // const eventInterfacePromise = SportsLib.importFromGPX(gpxString);
901
- //
902
- // // Then
903
- // eventInterfacePromise.then((event: EventInterface) => {
904
- // expect(stravaCadenceStream.length).toEqual(event.getFirstActivity().getSquashedStreamData(DataCadence.type).length);
905
- // expect(stravaCadenceStream).toEqual(event.getFirstActivity().getSquashedStreamData(DataCadence.type).map(value => value === null ? null : Math.round(value * 10) / 10));
906
- // done();
907
- // });
908
- // });
909
- // @todo try different geolib adapters etc to make this diff smaller or investigate more on how strava
910
- // Bumps the distance
911
- it(`should match distance with x% error max`, done => {
912
- // Given
913
- const deltaTolerance = 15; // percent
914
- const stravaDistanceStream = clone(strava_3171438371_gpx.distance);
915
- // When
916
- const eventInterfacePromise = SportsLib.importFromGPX(gpxString, xmldom.DOMParser);
917
- // Then
918
- eventInterfacePromise.then((event) => {
919
- const streamData = event
920
- .getFirstActivity()
921
- .getSquashedStreamData(DataDistance.type)
922
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
923
- expect(stravaDistanceStream.length).toEqual(streamData.length);
924
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaDistanceStream);
925
- expect(deltaBetweenStreams).toBeLessThan(deltaTolerance);
926
- done();
927
- });
928
- });
929
- // Tolerance is higher since distance is different unfortunately (see above test)
930
- it(`should have an average grade diff lower than 3.2%`, done => {
931
- // Given
932
- const toleranceAvgGradeDelta = 3.2;
933
- const stravaGradeStream = clone(strava_3171438371_gpx.grade_smooth);
934
- // When
935
- const eventInterfacePromise = SportsLib.importFromGPX(gpxString, xmldom.DOMParser);
936
- // Then
937
- eventInterfacePromise.then((event) => {
938
- const streamData = event
939
- .getFirstActivity()
940
- .getSquashedStreamData(DataGrade.type)
941
- .map(value => (value === null ? null : Math.round(value * 10) / 10));
942
- expect(stravaGradeStream.length).toEqual(streamData.length);
943
- const deltaBetweenStreams = averageDeltaBetweenStreams(streamData, stravaGradeStream);
944
- console.log(`Delta is ${deltaBetweenStreams}`);
945
- expect(deltaBetweenStreams).toBeLessThan(toleranceAvgGradeDelta);
946
- done();
947
- });
948
- });
949
- });
950
- });
951
- });