@sports-alliance/sports-lib 7.0.7 → 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.
- package/.editorconfig +14 -0
- package/.eslintignore +4 -0
- package/.eslintrc.js +9 -0
- package/.prettierignore +25 -0
- package/.prettierrc.json +12 -0
- package/CODE_OF_CONDUCT.md +76 -0
- package/jest.config.js +23 -0
- package/lib/esm/index.js +12034 -152
- package/package.json +3 -2
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.esm.json +8 -0
- package/tsconfig.lib.json +8 -0
- package/lib/esm/activities/activity-parsing-options.js +0 -19
- package/lib/esm/activities/activity.interface.js +0 -1
- package/lib/esm/activities/activity.js +0 -281
- package/lib/esm/activities/activity.json.interface.js +0 -1
- package/lib/esm/activities/activity.spec.js +0 -348
- package/lib/esm/activities/activity.types.js +0 -1046
- package/lib/esm/activities/activityt-types.spec.js +0 -16
- package/lib/esm/activities/devices/device.interface.js +0 -1
- package/lib/esm/activities/devices/device.js +0 -26
- package/lib/esm/activities/devices/device.json.interface.js +0 -1
- package/lib/esm/constants/constants.js +0 -8
- package/lib/esm/creators/creator.interface.js +0 -1
- package/lib/esm/creators/creator.js +0 -37
- package/lib/esm/creators/creator.json.interface.js +0 -1
- package/lib/esm/creators/creator.spec.js +0 -25
- package/lib/esm/data/data-active-lap.js +0 -4
- package/lib/esm/data/data-active-lengths.js +0 -4
- package/lib/esm/data/data-aerobic-training-effect.js +0 -8
- package/lib/esm/data/data-anaerobic-training-effect.js +0 -8
- package/lib/esm/data/data-stance-time-balance-left.js +0 -4
- package/lib/esm/data/data-stance-time-balance-right.js +0 -4
- package/lib/esm/data/data-stance-time-balance.js +0 -3
- package/lib/esm/data/data-store.spec.js +0 -78
- package/lib/esm/data/data-total-cycles.js +0 -4
- package/lib/esm/data/data.absolute-pressure.js +0 -5
- package/lib/esm/data/data.accumulated-power.js +0 -8
- package/lib/esm/data/data.activity-types.js +0 -7
- package/lib/esm/data/data.air-power-avg.js +0 -4
- package/lib/esm/data/data.air-power-max.js +0 -4
- package/lib/esm/data/data.air-power-min.js +0 -4
- package/lib/esm/data/data.air-power.js +0 -8
- package/lib/esm/data/data.alti-baro-profile.js +0 -4
- package/lib/esm/data/data.altitude-avg.js +0 -4
- package/lib/esm/data/data.altitude-gps.js +0 -5
- package/lib/esm/data/data.altitude-max.js +0 -4
- package/lib/esm/data/data.altitude-min.js +0 -4
- package/lib/esm/data/data.altitude-smooth.js +0 -4
- package/lib/esm/data/data.altitude.js +0 -8
- package/lib/esm/data/data.array.js +0 -13
- package/lib/esm/data/data.ascent-time.js +0 -4
- package/lib/esm/data/data.ascent.js +0 -4
- package/lib/esm/data/data.auto-lap-distance.js +0 -5
- package/lib/esm/data/data.auto-lap-duration.js +0 -4
- package/lib/esm/data/data.auto-lap-used.js +0 -7
- package/lib/esm/data/data.auto-pause-used.js +0 -7
- package/lib/esm/data/data.avg-stride-length.js +0 -4
- package/lib/esm/data/data.balance.js +0 -6
- package/lib/esm/data/data.bare.js +0 -4
- package/lib/esm/data/data.battery-charge.js +0 -8
- package/lib/esm/data/data.battery-consumption.js +0 -8
- package/lib/esm/data/data.battery-current.js +0 -8
- package/lib/esm/data/data.battery-life-estimation.js +0 -4
- package/lib/esm/data/data.battery-voltage.js +0 -8
- package/lib/esm/data/data.bike-pod-used.js +0 -7
- package/lib/esm/data/data.boolean.js +0 -9
- package/lib/esm/data/data.cadence-avg.js +0 -4
- package/lib/esm/data/data.cadence-max.js +0 -4
- package/lib/esm/data/data.cadence-min.js +0 -4
- package/lib/esm/data/data.cadence.js +0 -8
- package/lib/esm/data/data.cycling-dynamics.js +0 -3
- package/lib/esm/data/data.cycling-position.js +0 -37
- package/lib/esm/data/data.cycling-seated-time.js +0 -5
- package/lib/esm/data/data.cycling-standing-time.js +0 -5
- package/lib/esm/data/data.descent-time.js +0 -4
- package/lib/esm/data/data.descent.js +0 -4
- package/lib/esm/data/data.description.js +0 -4
- package/lib/esm/data/data.device-location.js +0 -4
- package/lib/esm/data/data.device-names.js +0 -7
- package/lib/esm/data/data.distance.js +0 -15
- package/lib/esm/data/data.duration.js +0 -56
- package/lib/esm/data/data.ehpe.js +0 -5
- package/lib/esm/data/data.enabled-navigation-systems.js +0 -4
- package/lib/esm/data/data.end-altitude.js +0 -4
- package/lib/esm/data/data.end-position.js +0 -4
- package/lib/esm/data/data.energy.js +0 -8
- package/lib/esm/data/data.epoc.js +0 -5
- package/lib/esm/data/data.event.js +0 -3
- package/lib/esm/data/data.evpe.js +0 -4
- package/lib/esm/data/data.feeling.js +0 -15
- package/lib/esm/data/data.foot-pod-used.js +0 -7
- package/lib/esm/data/data.form-power.js +0 -4
- package/lib/esm/data/data.fused-altitude.js +0 -7
- package/lib/esm/data/data.fused-location.js +0 -7
- package/lib/esm/data/data.gnss-distance.js +0 -4
- package/lib/esm/data/data.grade-adjusted-pace-avg.js +0 -15
- package/lib/esm/data/data.grade-adjusted-pace-max.js +0 -15
- package/lib/esm/data/data.grade-adjusted-pace-min.js +0 -15
- package/lib/esm/data/data.grade-adjusted-pace.js +0 -25
- package/lib/esm/data/data.grade-adjusted-speed-avg.js +0 -46
- package/lib/esm/data/data.grade-adjusted-speed-max.js +0 -46
- package/lib/esm/data/data.grade-adjusted-speed-min.js +0 -46
- package/lib/esm/data/data.grade-adjusted-speed.js +0 -78
- package/lib/esm/data/data.grade-smooth.js +0 -7
- package/lib/esm/data/data.grade.js +0 -7
- package/lib/esm/data/data.ground-time.js +0 -8
- package/lib/esm/data/data.heart-rate-avg.js +0 -4
- package/lib/esm/data/data.heart-rate-max.js +0 -4
- package/lib/esm/data/data.heart-rate-min.js +0 -4
- package/lib/esm/data/data.heart-rate-used.js +0 -7
- package/lib/esm/data/data.heart-rate-zone-five-duration.js +0 -4
- package/lib/esm/data/data.heart-rate-zone-four-duration.js +0 -4
- package/lib/esm/data/data.heart-rate-zone-one-duration.js +0 -4
- package/lib/esm/data/data.heart-rate-zone-three-duration.js +0 -4
- package/lib/esm/data/data.heart-rate-zone-two-duration.js +0 -4
- package/lib/esm/data/data.heart-rate.js +0 -8
- package/lib/esm/data/data.ibi.js +0 -8
- package/lib/esm/data/data.interface.js +0 -5
- package/lib/esm/data/data.js +0 -62
- package/lib/esm/data/data.json.interface.js +0 -1
- package/lib/esm/data/data.latitude-degrees.js +0 -5
- package/lib/esm/data/data.left-balance.js +0 -4
- package/lib/esm/data/data.leg-stiffness.js +0 -16
- package/lib/esm/data/data.longitude-degrees.js +0 -5
- package/lib/esm/data/data.moving-time.js +0 -4
- package/lib/esm/data/data.number-of-satellites.js +0 -7
- package/lib/esm/data/data.number-of.samples.js +0 -4
- package/lib/esm/data/data.number.js +0 -13
- package/lib/esm/data/data.pace-avg.js +0 -8
- package/lib/esm/data/data.pace-max.js +0 -8
- package/lib/esm/data/data.pace-min.js +0 -8
- package/lib/esm/data/data.pace.js +0 -46
- package/lib/esm/data/data.pause.js +0 -4
- package/lib/esm/data/data.peak-epoc.js +0 -7
- package/lib/esm/data/data.peak-training-effect.js +0 -4
- package/lib/esm/data/data.percent.js +0 -4
- package/lib/esm/data/data.pool-length.js +0 -5
- package/lib/esm/data/data.position.interface.js +0 -1
- package/lib/esm/data/data.position.js +0 -18
- package/lib/esm/data/data.power-avg.js +0 -4
- package/lib/esm/data/data.power-down.js +0 -4
- package/lib/esm/data/data.power-intensity-factor.js +0 -5
- package/lib/esm/data/data.power-left.js +0 -4
- package/lib/esm/data/data.power-max.js +0 -4
- package/lib/esm/data/data.power-min.js +0 -4
- package/lib/esm/data/data.power-normalized.js +0 -4
- package/lib/esm/data/data.power-pedal-smoothness-left.js +0 -4
- package/lib/esm/data/data.power-pedal-smoothness-right.js +0 -4
- package/lib/esm/data/data.power-pod-used.js +0 -7
- package/lib/esm/data/data.power-right.js +0 -4
- package/lib/esm/data/data.power-torque-effectiveness-left.js +0 -4
- package/lib/esm/data/data.power-torque-effectiveness-right.js +0 -4
- package/lib/esm/data/data.power-training-stress-score.js +0 -5
- package/lib/esm/data/data.power-up.js +0 -4
- package/lib/esm/data/data.power-work.js +0 -5
- package/lib/esm/data/data.power-zone-five-duration.js +0 -4
- package/lib/esm/data/data.power-zone-four-duration.js +0 -4
- package/lib/esm/data/data.power-zone-one-duration.js +0 -4
- package/lib/esm/data/data.power-zone-three-duration.js +0 -4
- package/lib/esm/data/data.power-zone-two-duration.js +0 -4
- package/lib/esm/data/data.power.js +0 -8
- package/lib/esm/data/data.recovery-time.js +0 -7
- package/lib/esm/data/data.rider-position-change-event.js +0 -8
- package/lib/esm/data/data.right-balance.js +0 -4
- package/lib/esm/data/data.rpe.js +0 -23
- package/lib/esm/data/data.satellite-5-best-snr.js +0 -4
- package/lib/esm/data/data.sea-level-pressure.js +0 -5
- package/lib/esm/data/data.spec.js +0 -25
- package/lib/esm/data/data.speed-avg.js +0 -46
- package/lib/esm/data/data.speed-max.js +0 -46
- package/lib/esm/data/data.speed-min.js +0 -46
- package/lib/esm/data/data.speed-zone-five-duration.js +0 -4
- package/lib/esm/data/data.speed-zone-four-duration.js +0 -4
- package/lib/esm/data/data.speed-zone-one-duration.js +0 -4
- package/lib/esm/data/data.speed-zone-three-duration.js +0 -4
- package/lib/esm/data/data.speed-zone-two-duration.js +0 -4
- package/lib/esm/data/data.speed.js +0 -88
- package/lib/esm/data/data.sport-profile-name.js +0 -4
- package/lib/esm/data/data.stance-time.js +0 -5
- package/lib/esm/data/data.start-altitude.js +0 -4
- package/lib/esm/data/data.start-event.js +0 -4
- package/lib/esm/data/data.start-position.js +0 -4
- package/lib/esm/data/data.step-length.js +0 -4
- package/lib/esm/data/data.steps-old.js +0 -4
- package/lib/esm/data/data.steps.js +0 -4
- package/lib/esm/data/data.stop-all-event.js +0 -4
- package/lib/esm/data/data.stop-event.js +0 -4
- package/lib/esm/data/data.store.export.spec.js +0 -66
- package/lib/esm/data/data.store.js +0 -1213
- package/lib/esm/data/data.string.js +0 -13
- package/lib/esm/data/data.stryd-altitude.js +0 -4
- package/lib/esm/data/data.stryd-distance.js +0 -4
- package/lib/esm/data/data.stryd-speed.js +0 -4
- package/lib/esm/data/data.swim-pace-avg.js +0 -8
- package/lib/esm/data/data.swim-pace-max.js +0 -8
- package/lib/esm/data/data.swim-pace-min.js +0 -8
- package/lib/esm/data/data.swim-pace.js +0 -19
- package/lib/esm/data/data.swolf-25m.js +0 -4
- package/lib/esm/data/data.swolf-50m.js +0 -4
- package/lib/esm/data/data.target-distance.js +0 -4
- package/lib/esm/data/data.target-heart-rate-zone.js +0 -4
- package/lib/esm/data/data.target-power-zone.js +0 -4
- package/lib/esm/data/data.target-speed-zone.js +0 -4
- package/lib/esm/data/data.target-time.js +0 -4
- package/lib/esm/data/data.temperature-avg.js +0 -4
- package/lib/esm/data/data.temperature-max.js +0 -4
- package/lib/esm/data/data.temperature-min.js +0 -4
- package/lib/esm/data/data.temperature.js +0 -8
- package/lib/esm/data/data.time.js +0 -6
- package/lib/esm/data/data.timer-time.js +0 -4
- package/lib/esm/data/data.vertical-oscillation.js +0 -5
- package/lib/esm/data/data.vertical-ratio.js +0 -5
- package/lib/esm/data/data.vertical-speed-avg.js +0 -53
- package/lib/esm/data/data.vertical-speed-max.js +0 -53
- package/lib/esm/data/data.vertical-speed-min.js +0 -53
- package/lib/esm/data/data.vertical-speed.js +0 -103
- package/lib/esm/data/data.vo2-max.js +0 -7
- package/lib/esm/data/ibi/data.ibi.filters.js +0 -52
- package/lib/esm/data/ibi/data.ibi.js +0 -98
- package/lib/esm/data/ibi/data.ibi.spec.js +0 -66
- package/lib/esm/duration/duration.class.abstract.js +0 -36
- package/lib/esm/duration/duration.class.interface.js +0 -1
- package/lib/esm/errors/duration-exceeded-event-lib.error.js +0 -9
- package/lib/esm/errors/empty-event-sports-libs.error.js +0 -9
- package/lib/esm/errors/event-lib.error.js +0 -8
- package/lib/esm/errors/lib.error.js +0 -6
- package/lib/esm/errors/parsing-event-lib.error.js +0 -9
- package/lib/esm/events/adapters/exporters/exporter.gpx.js +0 -75
- package/lib/esm/events/adapters/exporters/exporter.interface.js +0 -1
- package/lib/esm/events/adapters/exporters/exporter.json.js +0 -20
- package/lib/esm/events/adapters/file-type.enum.js +0 -7
- package/lib/esm/events/adapters/importers/fit/importer.fit.ant-plus.device.names.js +0 -25
- package/lib/esm/events/adapters/importers/fit/importer.fit.coros.device.names.js +0 -5
- package/lib/esm/events/adapters/importers/fit/importer.fit.development.device.names.js +0 -4
- package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.device.names.js +0 -462
- package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.data.js +0 -877
- package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.mapper.js +0 -106
- package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.mapper.spec.js +0 -32
- package/lib/esm/events/adapters/importers/fit/importer.fit.hammerhead.device.names.js +0 -4
- package/lib/esm/events/adapters/importers/fit/importer.fit.integration.spec.js +0 -44
- package/lib/esm/events/adapters/importers/fit/importer.fit.js +0 -978
- package/lib/esm/events/adapters/importers/fit/importer.fit.lezyne.device.names.js +0 -3
- package/lib/esm/events/adapters/importers/fit/importer.fit.magellan.device.names.js +0 -5
- package/lib/esm/events/adapters/importers/fit/importer.fit.mapper.js +0 -231
- package/lib/esm/events/adapters/importers/fit/importer.fit.saris.device.names.js +0 -3
- package/lib/esm/events/adapters/importers/fit/importer.fit.spec.js +0 -326
- package/lib/esm/events/adapters/importers/fit/importer.fit.srm.device.names.js +0 -7
- package/lib/esm/events/adapters/importers/fit/importer.fit.suunto.device.names.js +0 -16
- package/lib/esm/events/adapters/importers/fit/importer.fit.wahoo.device.names.js +0 -10
- package/lib/esm/events/adapters/importers/gpx/gx-parser.js +0 -36
- package/lib/esm/events/adapters/importers/gpx/importer.gpx.integration.spec.js +0 -44
- package/lib/esm/events/adapters/importers/gpx/importer.gpx.js +0 -102
- package/lib/esm/events/adapters/importers/gpx/importer.gpx.mapper.js +0 -142
- package/lib/esm/events/adapters/importers/gpx/importer.gpx.spec.js +0 -71
- package/lib/esm/events/adapters/importers/json/importer.json.js +0 -160
- package/lib/esm/events/adapters/importers/sample-info.interface.js +0 -1
- package/lib/esm/events/adapters/importers/suunto/importer.suunto.activity.ids.js +0 -85
- package/lib/esm/events/adapters/importers/suunto/importer.suunto.device.names.js +0 -26
- package/lib/esm/events/adapters/importers/suunto/importer.suunto.integration.spec.js +0 -44
- package/lib/esm/events/adapters/importers/suunto/importer.suunto.json.js +0 -717
- package/lib/esm/events/adapters/importers/suunto/importer.suunto.sml.js +0 -125
- package/lib/esm/events/adapters/importers/tcx/importer.tcx.integration.spec.js +0 -46
- package/lib/esm/events/adapters/importers/tcx/importer.tcx.js +0 -442
- package/lib/esm/events/adapters/importers/tcx/importer.tcx.mapper.js +0 -91
- package/lib/esm/events/adapters/importers/tcx/utils.tcx.js +0 -36
- package/lib/esm/events/event.interface.js +0 -1
- package/lib/esm/events/event.js +0 -123
- package/lib/esm/events/event.json.interface.js +0 -1
- package/lib/esm/events/event.spec.js +0 -51
- package/lib/esm/events/utilities/activity.utilities.js +0 -1841
- package/lib/esm/events/utilities/activity.utilities.spec.js +0 -373
- package/lib/esm/events/utilities/event.utilities.js +0 -57
- package/lib/esm/events/utilities/grade-calculator/grade-calculator.js +0 -121
- package/lib/esm/events/utilities/grade-calculator/grade-calculator.spec.js +0 -93
- package/lib/esm/events/utilities/grade-calculator/low-pass-filter.js +0 -86
- package/lib/esm/events/utilities/helpers.js +0 -162
- package/lib/esm/geodesy/adapters/adapter.interface.js +0 -1
- package/lib/esm/geodesy/adapters/geolib.adapter.js +0 -28
- package/lib/esm/id/id.abstract.class.js +0 -9
- package/lib/esm/id/id.class.interface.js +0 -1
- package/lib/esm/id/id.class.spec.js +0 -13
- package/lib/esm/intensity-zones/intensity-zones.interface.js +0 -1
- package/lib/esm/intensity-zones/intensity-zones.js +0 -29
- package/lib/esm/intensity-zones/intensity-zones.json.interface.js +0 -1
- package/lib/esm/intensity-zones/intensity-zones.spec.js +0 -30
- package/lib/esm/laps/lap.interface.js +0 -1
- package/lib/esm/laps/lap.js +0 -29
- package/lib/esm/laps/lap.json.interface.js +0 -1
- package/lib/esm/laps/lap.types.js +0 -52
- package/lib/esm/meta-data/event-meta-data.interface.js +0 -6
- package/lib/esm/meta-data/meta-data.js +0 -57
- package/lib/esm/meta-data/meta-data.json.interface.js +0 -1
- package/lib/esm/privacy/privacy.class.interface.js +0 -5
- package/lib/esm/serializable/serializable.class.interface.js +0 -1
- package/lib/esm/service-tokens/oauth1-service-token.interface.js +0 -1
- package/lib/esm/service-tokens/oauth2-service-token.interface.js +0 -1
- package/lib/esm/specs/activities-parsing.integration.spec.js +0 -1847
- package/lib/esm/specs/activity-duration-stream.integration.spec.js +0 -57
- package/lib/esm/specs/fixtures/streams/strava/rides/3171472783.json +0 -52534
- package/lib/esm/specs/fixtures/streams/strava/rides/3171487458.json +0 -78818
- package/lib/esm/specs/fixtures/streams/strava/rides/343080886.json +0 -105090
- package/lib/esm/specs/fixtures/streams/strava/rides/5910143591.json +0 -110711
- package/lib/esm/specs/fixtures/streams/strava/runs/2451375851.json +0 -74846
- package/lib/esm/specs/fixtures/streams/strava/runs/2709634581.json +0 -66817
- package/lib/esm/specs/fixtures/streams/strava/runs/3156040843.json +0 -17594
- package/lib/esm/specs/fixtures/streams/strava/runs/3182900697.json +0 -17322
- package/lib/esm/specs/fixtures/streams/strava/runs/3183465494.json +0 -20463
- package/lib/esm/specs/fixtures/streams/strava/runs/3183490558.json +0 -58202
- package/lib/esm/specs/spec-utils.js +0 -159
- package/lib/esm/specs/strava-streams-compliance.spec.js +0 -951
- package/lib/esm/stats/stats.class.abstract.js +0 -32
- package/lib/esm/stats/stats.class.interface.js +0 -1
- package/lib/esm/stats/stats.json.interface.js +0 -1
- package/lib/esm/streams/compressed.stream.interface.js +0 -12
- package/lib/esm/streams/ibi-stream.js +0 -43
- package/lib/esm/streams/low-pass.stream.filter.js +0 -9
- package/lib/esm/streams/stream.filter.interface.js +0 -1
- package/lib/esm/streams/stream.interface.js +0 -1
- package/lib/esm/streams/stream.js +0 -72
- package/lib/esm/streams/stream.spec.js +0 -168
- package/lib/esm/tiles/tile.settings.interface.js +0 -41
- package/lib/esm/users/settings/dashboard/user.dashboard.settings.interface.js +0 -13
- package/lib/esm/users/settings/user.app.settings.interface.js +0 -5
- package/lib/esm/users/settings/user.chart.settings.interface.js +0 -23
- package/lib/esm/users/settings/user.map.settings.interface.js +0 -22
- package/lib/esm/users/settings/user.my-tracks.settings.interface.js +0 -1
- package/lib/esm/users/settings/user.settings.interface.js +0 -1
- package/lib/esm/users/settings/user.stats-settings.interface.js +0 -1
- package/lib/esm/users/settings/user.summaries.settings.interface.js +0 -1
- package/lib/esm/users/settings/user.unit.settings.interface.js +0 -73
- package/lib/esm/users/user.account.privileges.interface.js +0 -1
- package/lib/esm/users/user.export-to-csv.settings.interface.js +0 -1
- package/lib/esm/users/user.interface.js +0 -1
- package/lib/esm/users/user.js +0 -38
- 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
|
-
});
|