From 3dc9b7d7032ede55b66c27cecdaf6465ed3a9945 Mon Sep 17 00:00:00 2001 From: vcoppe Date: Tue, 16 Apr 2024 11:48:42 +0200 Subject: [PATCH] 1-to-1 mapping between gpx schema and types --- .gitignore | 1 + gpx/src/index.ts | 2 +- gpx/src/io.ts | 288 +++------------ gpx/src/types.ts | 28 +- gpx/test-data/with_power_2.gpx | 320 ++++++++++++---- gpx/test-data/with_power_3.gpx | 658 --------------------------------- gpx/test/io.test.ts | 109 +++--- 7 files changed, 364 insertions(+), 1042 deletions(-) create mode 100644 .gitignore delete mode 100644 gpx/test-data/with_power_3.gpx diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..496ee2ca --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/gpx/src/index.ts b/gpx/src/index.ts index 38858912..64d0c99f 100644 --- a/gpx/src/index.ts +++ b/gpx/src/index.ts @@ -1,4 +1,4 @@ -export { type GPXFile, type Metadata, type Waypoint, type Track, type TrackSegment, type TrackPoint, type Author } from './types'; +export * from './types'; export { parseGPX } from './io'; diff --git a/gpx/src/io.ts b/gpx/src/io.ts index fbc50a58..aed93beb 100644 --- a/gpx/src/io.ts +++ b/gpx/src/io.ts @@ -1,247 +1,61 @@ import { XMLParser } from "fast-xml-parser"; -import { Author, GPXFile, Link, Metadata, Track, TrackPoint, TrackPointExtensions, TrackSegment, TrackStyleExtension, Waypoint } from "./types"; - -const arrayTypes = ['trk', 'trkseg', 'trkpt', 'wpt']; +import { GPXFile } from "./types"; export function parseGPX(gpxData: string): GPXFile { const parser = new XMLParser({ - isArray: (name: string) => arrayTypes.includes(name), ignoreAttributes: false, attributeNamePrefix: "", + removeNSPrefix: true, + isArray: (name: string) => { + return name === 'trk' || name === 'trkseg' || name === 'trkpt' || name === 'wpt'; + }, + attributeValueProcessor(attrName, attrValue, jPath) { + if (attrName === 'lat' || attrName === 'lon') { + return parseFloat(attrValue); + } + return attrValue; + }, + transformTagName(tagName: string) { + if (tagName === 'power') { + // Transform the simple tag to the more complex tag, the nested tag is then handled by the tagValueProcessor + return 'PowerExtension'; + } + return tagName; + }, + tagValueProcessor(tagName, tagValue, jPath, hasAttributes, isLeafNode) { + if (isLeafNode) { + if (tagName === 'ele') { + return parseFloat(tagValue); + } + + if (tagName === 'time') { + return new Date(tagValue); + } + + if (tagName === 'hr' || tagName === 'cad' || tagName === 'atemp' || tagName === 'PowerInWatts' || tagName === 'opacity' || tagName === 'weight') { + return parseFloat(tagValue); + } + + if (tagName === 'PowerExtension') { + // Finish the transformation of the simple tag to the more complex tag + // Note that this only targets the transformed tag, since it must be a leaf node + return { + 'PowerInWatts': parseFloat(tagValue) + }; + } + } + + return tagValue; + }, + transformAttributeName(attributeName) { + if (attributeName !== 'lat' && attributeName !== 'lon' && attributeName !== 'creator' && attributeName !== 'href') { + return `@_${attributeName}`; + } + return attributeName; + }, }); + const parsed = parser.parse(gpxData); - const result: GPXFile = { - creator: parsed.gpx.creator ? parsed.gpx.creator : "", - metadata: parseMetadata(parsed.gpx.metadata), - waypoints: parsed.gpx.wpt ? parsed.gpx.wpt.map(parseWaypoint) : [], - tracks: parsed.gpx.trk ? parsed.gpx.trk.map(parseTrack) : [], - }; - - return result; + return parsed.gpx; } - -function parseMetadata(metadata: any): Metadata { - const result: Metadata = {}; - - if (metadata.name) { - result.name = metadata.name; - } - - if (metadata.desc) { - result.desc = metadata.desc; - } - - if (metadata.author) { - result.author = parseAuthor(metadata.author); - } - - if (metadata.link) { - result.link = parseLink(metadata.link); - } - - if (metadata.time) { - result.time = new Date(metadata.time); - } - - return result; -} - -function parseAuthor(author: any): Author { - const result: Author = {}; - - if (author.name) { - result.name = author.name; - } - - if (author.email) { - result.email = author.email; - } - - if (author.link) { - result.link = parseLink(author.link); - } - - return result; -} - -function parseLink(link: any): Link { - const result: Link = { - href: link.href, - }; - - if (link.text) { - result.text = link.text; - } - - if (link.type) { - result.type = link.type; - } - - return result; -} - -function parseWaypoint(waypoint: any): Waypoint { - const result: Waypoint = { - lat: parseFloat(waypoint.lat), - lon: parseFloat(waypoint.lon), - }; - - if (waypoint.ele) { - result.ele = parseFloat(waypoint.ele); - } - - if (waypoint.time) { - result.time = new Date(waypoint.time); - } - - if (waypoint.name) { - result.name = waypoint.name; - } - - if (waypoint.cmt) { - result.cmt = waypoint.cmt; - } - - if (waypoint.desc) { - result.desc = waypoint.desc; - } - - if (waypoint.link) { - result.link = parseLink(waypoint.link); - } - - if (waypoint.sym) { - result.sym = waypoint.sym; - } - - if (waypoint.type) { - result.type = waypoint.type; - } - - return result; -} - -function parseTrack(track: any): Track { - const result: Track = { - trkseg: track.trkseg.map(parseTrackSegment), - }; - - if (track.name) { - result.name = track.name; - } - - if (track.cmt) { - result.cmt = track.cmt; - } - - if (track.desc) { - result.desc = track.desc; - } - - if (track.src) { - result.src = track.src; - } - - if (track.link) { - result.link = parseLink(track.link); - } - - if (track.type) { - result.type = track.type; - } - - if (track.extensions && track.extensions.hasOwnProperty('gpx_style:line')) { - result.style = parseTrackStyleExtension(track.extensions['gpx_style:line']); - } - - return result; -} - -function parseTrackStyleExtension(extensions: any): TrackStyleExtension { - const result: TrackStyleExtension = {}; - - if (extensions.color) { - result.color = extensions.color; - } - - if (extensions.opacity) { - result.opacity = parseFloat(extensions.opacity); - } - - if (extensions.weight) { - result.weight = parseFloat(extensions.weight); - } - - return result; -} - -function parseTrackSegment(segment: any): TrackSegment { - return { - trkpt: segment.trkpt.map(parseTrackPoint), - }; -} - -function parseTrackPoint(point: any): TrackPoint { - const result: TrackPoint = { - lat: parseFloat(point.lat), - lon: parseFloat(point.lon), - }; - - if (point.ele) { - result.ele = parseFloat(point.ele); - } - - if (point.time) { - result.time = new Date(point.time); - } - - if (point.extensions) { - result.extensions = parseTrackPointExtensions(point.extensions); - } - - return result; -} - -function parseTrackPointExtensions(extensions: any): TrackPointExtensions { - const result: TrackPointExtensions = {}; - - if (extensions.hasOwnProperty('gpxtpx:TrackPointExtension')) { - const gpxtpxExtensions = extensions['gpxtpx:TrackPointExtension']; - - if (gpxtpxExtensions.hasOwnProperty('gpxtpx:hr')) { - result.hr = parseFloat(gpxtpxExtensions['gpxtpx:hr']); - } - - if (gpxtpxExtensions.hasOwnProperty('gpxtpx:cad')) { - result.cad = parseFloat(gpxtpxExtensions['gpxtpx:cad']); - } - - if (gpxtpxExtensions.hasOwnProperty('gpxtpx:atemp')) { - result.atemp = parseFloat(gpxtpxExtensions['gpxtpx:atemp']); - } - - if (gpxtpxExtensions.hasOwnProperty('gpxtpx:Extensions')) { - const gpxtpxInnerExtensions = gpxtpxExtensions['gpxtpx:Extensions']; - - if (gpxtpxInnerExtensions.surface) { - result.surface = gpxtpxInnerExtensions.surface; - } - } - } - - if (extensions.power) { - result.power = parseFloat(extensions.power); - } else if (extensions.hasOwnProperty('gpxpx:PowerExtension')) { - const gpxpxExtensions = extensions['gpxpx:PowerExtension']; - - if (gpxpxExtensions.hasOwnProperty('gpxpx:PowerInWatts')) { - result.power = parseFloat(gpxpxExtensions['gpxpx:PowerInWatts']); - } - } else if (extensions.hasOwnProperty('gpxpx:PowerInWatts')) { - result.power = parseFloat(extensions['gpxpx:PowerInWatts']); - } - - - return result; -} \ No newline at end of file diff --git a/gpx/src/types.ts b/gpx/src/types.ts index b08202d0..952b7f33 100644 --- a/gpx/src/types.ts +++ b/gpx/src/types.ts @@ -1,8 +1,8 @@ export type GPXFile = { creator: string; metadata: Metadata; - waypoints: Waypoint[]; - tracks: Track[]; + wpt: Waypoint[]; + trk: Track[]; }; export type Metadata = { @@ -40,10 +40,14 @@ export type Track = { link?: Link; type?: string; trkseg: TrackSegment[]; - style?: TrackStyleExtension; + extensions?: TrackExtensions; }; -export type TrackStyleExtension = { +export type TrackExtensions = { + line?: LineStyleExtension; +}; + +export type LineStyleExtension = { color?: string; opacity?: number; weight?: number; @@ -62,12 +66,22 @@ export type TrackPoint = { }; export type TrackPointExtensions = { + TrackPointExtension?: TrackPointExtension; + PowerExtension?: PowerExtension; +}; + +export type TrackPointExtension = { hr?: number; cad?: number; atemp?: number; - power?: number; - surface?: string; -}; + Extensions?: { + surface?: string; + }; +} + +export type PowerExtension = { + PowerInWatts?: number; +} export type Author = { name?: string; diff --git a/gpx/test-data/with_power_2.gpx b/gpx/test-data/with_power_2.gpx index 09ba84da..b0a53073 100644 --- a/gpx/test-data/with_power_2.gpx +++ b/gpx/test-data/with_power_2.gpx @@ -18,481 +18,641 @@ 109.0 - 200 + + 200 + 110.8 - 200 + + 200 + 110.3 - 200 + + 200 + 110.0 - 200 + + 200 + 110.3 - 200 + + 200 + 109.3 - 200 + + 200 + 107.0 - 200 + + 200 + 106.0 - 200 + + 200 + 108.5 - 200 + + 200 + 109.8 - 200 + + 200 + 110.8 - 200 + + 200 + 112.0 - 200 + + 200 + 112.8 - 200 + + 200 + 113.5 - 200 + + 200 + 114.3 - 200 + + 200 + 115.3 - 200 + + 200 + 114.8 - 200 + + 200 + 114.3 - 200 + + 200 + 114.3 - 200 + + 200 + 114.5 - 200 + + 200 + 115.0 - 200 + + 200 + 115.8 - 200 + + 200 + 115.8 - 200 + + 200 + 116.0 - 200 + + 200 + 115.8 - 200 + + 200 + 115.5 - 200 + + 200 + 114.5 - 200 + + 200 + 112.5 - 200 + + 200 + 110.8 - 200 + + 200 + 109.0 - 200 + + 200 + 106.3 - 200 + + 200 + 104.3 - 200 + + 200 + 104.0 - 200 + + 200 + 103.8 - 200 + + 200 + 103.3 - 200 + + 200 + 103.5 - 200 + + 200 + 103.8 - 200 + + 200 + 104.8 - 200 + + 200 + 105.8 - 200 + + 200 + 106.8 - 200 + + 200 + 107.8 - 200 + + 200 + 108.5 - 200 + + 200 + 109.3 - 200 + + 200 + 110.0 - 200 + + 200 + 110.5 - 200 + + 200 + 110.8 - 200 + + 200 + 111.8 - 200 + + 200 + 112.8 - 200 + + 200 + 113.3 - 200 + + 200 + 113.5 - 200 + + 200 + 113.5 - 200 + + 200 + 113.8 - 200 + + 200 + 114.8 - 200 + + 200 + 115.8 - 200 + + 200 + 118.5 - 200 + + 200 + 119.5 - 200 + + 200 + 121.3 - 200 + + 200 + 122.0 - 200 + + 200 + 122.8 - 200 + + 200 + 123.5 - 200 + + 200 + 126.3 - 200 + + 200 + 128.0 - 200 + + 200 + 129.0 - 200 + + 200 + 130.0 - 200 + + 200 + 130.8 - 200 + + 200 + 131.8 - 200 + + 200 + 132.3 - 200 + + 200 + 132.8 - 200 + + 200 + 135.8 - 200 + + 200 + 135.5 - 200 + + 200 + 132.5 - 200 + + 200 + 134.0 - 200 + + 200 + 136.8 - 200 + + 200 + 137.5 - 200 + + 200 + 137.3 - 200 + + 200 + 137.5 - 200 + + 200 + 137.3 - 200 + + 200 + 134.8 - 200 + + 200 + 132.3 - 200 + + 200 + 129.5 - 210 + + 210 + diff --git a/gpx/test-data/with_power_3.gpx b/gpx/test-data/with_power_3.gpx deleted file mode 100644 index 3b9e7935..00000000 --- a/gpx/test-data/with_power_3.gpx +++ /dev/null @@ -1,658 +0,0 @@ - - - - with_power - - gpx.studio - - - - - with_power - Cycling - - - 109.0 - - - 200 - - - - - 110.8 - - - 200 - - - - - 110.3 - - - 200 - - - - - 110.0 - - - 200 - - - - - 110.3 - - - 200 - - - - - 109.3 - - - 200 - - - - - 107.0 - - - 200 - - - - - 106.0 - - - 200 - - - - - 108.5 - - - 200 - - - - - 109.8 - - - 200 - - - - - 110.8 - - - 200 - - - - - 112.0 - - - 200 - - - - - 112.8 - - - 200 - - - - - 113.5 - - - 200 - - - - - 114.3 - - - 200 - - - - - 115.3 - - - 200 - - - - - 114.8 - - - 200 - - - - - 114.3 - - - 200 - - - - - 114.3 - - - 200 - - - - - 114.5 - - - 200 - - - - - 115.0 - - - 200 - - - - - 115.8 - - - 200 - - - - - 115.8 - - - 200 - - - - - 116.0 - - - 200 - - - - - 115.8 - - - 200 - - - - - 115.5 - - - 200 - - - - - 114.5 - - - 200 - - - - - 112.5 - - - 200 - - - - - 110.8 - - - 200 - - - - - 109.0 - - - 200 - - - - - 106.3 - - - 200 - - - - - 104.3 - - - 200 - - - - - 104.0 - - - 200 - - - - - 103.8 - - - 200 - - - - - 103.3 - - - 200 - - - - - 103.5 - - - 200 - - - - - 103.8 - - - 200 - - - - - 104.8 - - - 200 - - - - - 105.8 - - - 200 - - - - - 106.8 - - - 200 - - - - - 107.8 - - - 200 - - - - - 108.5 - - - 200 - - - - - 109.3 - - - 200 - - - - - 110.0 - - - 200 - - - - - 110.5 - - - 200 - - - - - 110.8 - - - 200 - - - - - 111.8 - - - 200 - - - - - 112.8 - - - 200 - - - - - 113.3 - - - 200 - - - - - 113.5 - - - 200 - - - - - 113.5 - - - 200 - - - - - 113.8 - - - 200 - - - - - 114.8 - - - 200 - - - - - 115.8 - - - 200 - - - - - 118.5 - - - 200 - - - - - 119.5 - - - 200 - - - - - 121.3 - - - 200 - - - - - 122.0 - - - 200 - - - - - 122.8 - - - 200 - - - - - 123.5 - - - 200 - - - - - 126.3 - - - 200 - - - - - 128.0 - - - 200 - - - - - 129.0 - - - 200 - - - - - 130.0 - - - 200 - - - - - 130.8 - - - 200 - - - - - 131.8 - - - 200 - - - - - 132.3 - - - 200 - - - - - 132.8 - - - 200 - - - - - 135.8 - - - 200 - - - - - 135.5 - - - 200 - - - - - 132.5 - - - 200 - - - - - 134.0 - - - 200 - - - - - 136.8 - - - 200 - - - - - 137.5 - - - 200 - - - - - 137.3 - - - 200 - - - - - 137.5 - - - 200 - - - - - 137.3 - - - 200 - - - - - 134.8 - - - 200 - - - - - 132.3 - - - 200 - - - - - 129.5 - - 210 - - - - - \ No newline at end of file diff --git a/gpx/test/io.test.ts b/gpx/test/io.test.ts index 7bc59b6d..dd8e1fd5 100644 --- a/gpx/test/io.test.ts +++ b/gpx/test/io.test.ts @@ -13,9 +13,9 @@ describe("Parsing tests", () => { expect(result.metadata.author.name).toBe("gpx.studio"); expect(result.metadata.author.link.href).toBe("https://gpx.studio"); - expect(result.tracks.length).toBe(1); + expect(result.trk.length).toBe(1); - const track = result.tracks[0]; + const track = result.trk[0]; expect(track.name).toBe("simple"); expect(track.type).toBe("Cycling"); expect(track.trkseg.length).toBe(1); @@ -40,14 +40,14 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - expect(result.tracks.length).toBe(2); + expect(result.trk.length).toBe(2); - const track_1 = result.tracks[0]; + const track_1 = result.trk[0]; expect(track_1.name).toBe("track 1"); expect(track_1.trkseg.length).toBe(1); expect(track_1.trkseg[0].trkpt.length).toBe(49); - const track_2 = result.tracks[1]; + const track_2 = result.trk[1]; expect(track_2.name).toBe("track 2"); expect(track_2.trkseg.length).toBe(1); expect(track_2.trkseg[0].trkpt.length).toBe(28); @@ -58,9 +58,9 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - expect(result.tracks.length).toBe(1); + expect(result.trk.length).toBe(1); - const track = result.tracks[0]; + const track = result.trk[0]; expect(track.trkseg.length).toBe(2); expect(track.trkseg[0].trkpt.length).toBe(49); expect(track.trkseg[1].trkpt.length).toBe(28); @@ -71,9 +71,9 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - expect(result.waypoints.length).toBe(1); + expect(result.wpt.length).toBe(1); - const waypoint = result.waypoints[0]; + const waypoint = result.wpt[0]; expect(waypoint.lat).toBe(50.7836710064975); expect(waypoint.lon).toBe(4.410764082658738); expect(waypoint.ele).toBe(122.0); @@ -88,7 +88,7 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - const track = result.tracks[0]; + const track = result.trk[0]; const segment = track.trkseg[0]; for (let i = 0; i < segment.trkpt.length; i++) { @@ -104,16 +104,17 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - const track = result.tracks[0]; + const track = result.trk[0]; const segment = track.trkseg[0]; for (let i = 0; i < segment.trkpt.length; i++) { expect(segment.trkpt[i]).toHaveProperty('extensions'); - expect(segment.trkpt[i].extensions).toHaveProperty('hr'); + expect(segment.trkpt[i].extensions).toHaveProperty('TrackPointExtension'); + expect(segment.trkpt[i].extensions.TrackPointExtension).toHaveProperty('hr'); } - expect(segment.trkpt[0].extensions.hr).toBe(150); - expect(segment.trkpt[segment.trkpt.length - 1].extensions.hr).toBe(160); + expect(segment.trkpt[0].extensions.TrackPointExtension.hr).toBe(150); + expect(segment.trkpt[segment.trkpt.length - 1].extensions.TrackPointExtension.hr).toBe(160); }); it("Cadence", () => { @@ -121,16 +122,17 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - const track = result.tracks[0]; + const track = result.trk[0]; const segment = track.trkseg[0]; for (let i = 0; i < segment.trkpt.length; i++) { expect(segment.trkpt[i]).toHaveProperty('extensions'); - expect(segment.trkpt[i].extensions).toHaveProperty('cad'); + expect(segment.trkpt[i].extensions).toHaveProperty('TrackPointExtension'); + expect(segment.trkpt[i].extensions.TrackPointExtension).toHaveProperty('cad'); } - expect(segment.trkpt[0].extensions.cad).toBe(80); - expect(segment.trkpt[segment.trkpt.length - 1].extensions.cad).toBe(90); + expect(segment.trkpt[0].extensions.TrackPointExtension.cad).toBe(80); + expect(segment.trkpt[segment.trkpt.length - 1].extensions.TrackPointExtension.cad).toBe(90); }); it("Temperature", () => { @@ -138,16 +140,17 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - const track = result.tracks[0]; + const track = result.trk[0]; const segment = track.trkseg[0]; for (let i = 0; i < segment.trkpt.length; i++) { expect(segment.trkpt[i]).toHaveProperty('extensions'); - expect(segment.trkpt[i].extensions).toHaveProperty('atemp'); + expect(segment.trkpt[i].extensions).toHaveProperty('TrackPointExtension'); + expect(segment.trkpt[i].extensions.TrackPointExtension).toHaveProperty('atemp'); } - expect(segment.trkpt[0].extensions.atemp).toBe(21); - expect(segment.trkpt[segment.trkpt.length - 1].extensions.atemp).toBe(22); + expect(segment.trkpt[0].extensions.TrackPointExtension.atemp).toBe(21); + expect(segment.trkpt[segment.trkpt.length - 1].extensions.TrackPointExtension.atemp).toBe(22); }); it("Power 1", () => { @@ -155,16 +158,17 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - const track = result.tracks[0]; + const track = result.trk[0]; const segment = track.trkseg[0]; for (let i = 0; i < segment.trkpt.length; i++) { expect(segment.trkpt[i]).toHaveProperty('extensions'); - expect(segment.trkpt[i].extensions).toHaveProperty('power'); + expect(segment.trkpt[i].extensions).toHaveProperty('PowerExtension'); + expect(segment.trkpt[i].extensions.PowerExtension).toHaveProperty('PowerInWatts'); } - expect(segment.trkpt[0].extensions.power).toBe(200); - expect(segment.trkpt[segment.trkpt.length - 1].extensions.power).toBe(210); + expect(segment.trkpt[0].extensions.PowerExtension.PowerInWatts).toBe(200); + expect(segment.trkpt[segment.trkpt.length - 1].extensions.PowerExtension.PowerInWatts).toBe(210); }); it("Power 2", () => { @@ -172,33 +176,17 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - const track = result.tracks[0]; + const track = result.trk[0]; const segment = track.trkseg[0]; for (let i = 0; i < segment.trkpt.length; i++) { expect(segment.trkpt[i]).toHaveProperty('extensions'); - expect(segment.trkpt[i].extensions).toHaveProperty('power'); + expect(segment.trkpt[i].extensions).toHaveProperty('PowerExtension'); + expect(segment.trkpt[i].extensions.PowerExtension).toHaveProperty('PowerInWatts'); } - expect(segment.trkpt[0].extensions.power).toBe(200); - expect(segment.trkpt[segment.trkpt.length - 1].extensions.power).toBe(210); - }); - - it("Power 3", () => { - const path = "test-data/with_power_3.gpx"; - const data = fs.readFileSync(path, 'utf8'); - const result = parseGPX(data); - - const track = result.tracks[0]; - const segment = track.trkseg[0]; - - for (let i = 0; i < segment.trkpt.length; i++) { - expect(segment.trkpt[i]).toHaveProperty('extensions'); - expect(segment.trkpt[i].extensions).toHaveProperty('power'); - } - - expect(segment.trkpt[0].extensions.power).toBe(200); - expect(segment.trkpt[segment.trkpt.length - 1].extensions.power).toBe(210); + expect(segment.trkpt[0].extensions.PowerExtension.PowerInWatts).toBe(200); + expect(segment.trkpt[segment.trkpt.length - 1].extensions.PowerExtension.PowerInWatts).toBe(210); }); it("Surface", () => { @@ -206,16 +194,18 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - const track = result.tracks[0]; + const track = result.trk[0]; const segment = track.trkseg[0]; for (let i = 0; i < segment.trkpt.length; i++) { expect(segment.trkpt[i]).toHaveProperty('extensions'); - expect(segment.trkpt[i].extensions).toHaveProperty('surface'); + expect(segment.trkpt[i].extensions).toHaveProperty('TrackPointExtension'); + expect(segment.trkpt[i].extensions.TrackPointExtension).toHaveProperty('Extensions'); + expect(segment.trkpt[i].extensions.TrackPointExtension.Extensions).toHaveProperty('surface'); } - expect(segment.trkpt[0].extensions.surface).toBe("asphalt"); - expect(segment.trkpt[segment.trkpt.length - 1].extensions.surface).toBe("cobblestone"); + expect(segment.trkpt[0].extensions.TrackPointExtension.Extensions.surface).toBe("asphalt"); + expect(segment.trkpt[segment.trkpt.length - 1].extensions.TrackPointExtension.Extensions.surface).toBe("cobblestone"); }); it("Track style", () => { @@ -223,16 +213,17 @@ describe("Parsing tests", () => { const data = fs.readFileSync(path, 'utf8'); const result = parseGPX(data); - const track = result.tracks[0]; + const track = result.trk[0]; - expect(track).toHaveProperty('style'); + expect(track).toHaveProperty('extensions'); + expect(track.extensions).toHaveProperty('line'); - expect(track.style).toHaveProperty('color'); - expect(track.style).toHaveProperty('opacity'); - expect(track.style).toHaveProperty('weight'); + expect(track.extensions.line).toHaveProperty('color'); + expect(track.extensions.line).toHaveProperty('opacity'); + expect(track.extensions.line).toHaveProperty('weight'); - expect(track.style.color).toBe("2d3ee9"); - expect(track.style.opacity).toBe(0.5); - expect(track.style.weight).toBe(5); + expect(track.extensions.line.color).toBe("2d3ee9"); + expect(track.extensions.line.opacity).toBe(0.5); + expect(track.extensions.line.weight).toBe(5); }); }); \ No newline at end of file