From 26486b65b9b806a1f98d9785d249fe4cb02489df Mon Sep 17 00:00:00 2001 From: evlist Date: Mon, 7 Nov 2022 22:12:50 +0100 Subject: [PATCH] Cleanup and starting to implements tracks. --- src/App.tsx | 2 +- src/db/gpx.test.ts | 26 ++++--- src/db/gpx.ts | 7 +- src/db/trk.ts | 15 ++++ src/db/types.d.ts | 26 ++++++- src/lib/ids.test.ts | 116 ++++++++++++++++++++++++++++ src/lib/ids.ts | 12 +-- src/lib/types.d.ts | 34 ++++++++ src/workers/dispatcher-main.test.js | 13 +++- 9 files changed, 225 insertions(+), 26 deletions(-) create mode 100644 src/db/trk.ts create mode 100644 src/lib/ids.test.ts create mode 100644 src/lib/types.d.ts diff --git a/src/App.tsx b/src/App.tsx index f81b859..83675b2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -95,7 +95,7 @@ export const setCenterAtom = atom(null, (get, set, center: geoPoint) => { // initDb(db); dispatch({ action: 'initDb' }); -dispatch({ action: 'putNewGpx', params: 'gpxid' }); +dispatch({ action: 'putNewGpx' }); /** * diff --git a/src/db/gpx.test.ts b/src/db/gpx.test.ts index 78850f9..b694f2a 100644 --- a/src/db/gpx.test.ts +++ b/src/db/gpx.test.ts @@ -7,19 +7,17 @@ declare global { const originalDb = globalThis.db; const originalDateNow = globalThis.Date.now; -beforeEach(() => { - globalThis.db = { put: jest.fn() }; - globalThis.Date.now = () => 0; -}); - -afterEach(() => { - globalThis.db = originalDb; - globalThis.Date.now = originalDateNow; -}); - describe('The gpx module', () => { + beforeEach(() => { + globalThis.db = { put: jest.fn() }; + globalThis.Date.now = () => 0; + }); + afterEach(() => { + globalThis.db = originalDb; + globalThis.Date.now = originalDateNow; + }); test('db.put() a new Gpx when required', () => { - putNewGpx('whatever'); + putNewGpx({ gpx: 'whatever' }); expect(globalThis.db.put).toBeCalledWith({ _id: 'gpx/whatever', doc: { @@ -45,7 +43,7 @@ describe('The gpx module', () => { desc: '', extensions: '', keywords: '', - link: '', + link: [], name: '', time: '1970-01-01T00:00:00.000Z', }, @@ -56,4 +54,8 @@ describe('The gpx module', () => { type: 'gpx', }); }); + test('db.put() generates an id if needed', () => { + const id = putNewGpx(); + expect(id).toEqual({ gpx: '0' }); + }); }); diff --git a/src/db/gpx.ts b/src/db/gpx.ts index 084451d..f39b977 100644 --- a/src/db/gpx.ts +++ b/src/db/gpx.ts @@ -19,7 +19,7 @@ const emptyGpx: Gpx = { desc: '', author: '', copyright: '', - link: '', + link: [], time: '', keywords: '', bounds: '', @@ -31,8 +31,8 @@ const emptyGpx: Gpx = { extensions: '', }; -export const putNewGpx = (id: string) => { - const uri = getUri('gpx', { gpx: id }); +export const putNewGpx = (id: IdGpx = { gpx: Date.now().toString() }) => { + const uri = getUri('gpx', id); put( uri, 'gpx', @@ -42,4 +42,5 @@ export const putNewGpx = (id: string) => { }, emptyGpx ); + return id; }; diff --git a/src/db/trk.ts b/src/db/trk.ts new file mode 100644 index 0000000..c266a97 --- /dev/null +++ b/src/db/trk.ts @@ -0,0 +1,15 @@ +import getUri from '../lib/ids'; +import { put } from './lib'; + +const emptyTrk: Trk = { + name: '', + cmt: '', + desc: '', + src: '', + link: [], + number: 0, + type: '', + extensions: {}, + trkseg: [], +}; + diff --git a/src/db/types.d.ts b/src/db/types.d.ts index 78d22cf..7bb60c9 100644 --- a/src/db/types.d.ts +++ b/src/db/types.d.ts @@ -3,7 +3,7 @@ interface Gpx { metadata?: Metadata; wpt?: any[]; rte?: any[]; - trk?: any[]; + trk?: Trk[]; extensions?: Extensions; } @@ -24,7 +24,7 @@ interface Metadata { desc?: string; author?: string; copyright?: string; - link?: string; + link?: Link[]; time?: string; keywords?: string; bounds?: string; @@ -32,3 +32,25 @@ interface Metadata { } interface Extensions {} + +interface Trk { + name?: string; + cmt?: string; + desc?: string; + src?: string; + link?: Link[]; + number?: number; + type?: string; + extensions?: Extensions; + trkseg?: any[]; +} + +interface Link { + $: Link_; + text?: string; + type?: string; +} + +interface Link_ { + href: string; +} diff --git a/src/lib/ids.test.ts b/src/lib/ids.test.ts new file mode 100644 index 0000000..83a3fdc --- /dev/null +++ b/src/lib/ids.test.ts @@ -0,0 +1,116 @@ +import { route } from 'docuri'; +import uri from './ids'; + +describe('Checking some DocURI features', () => { + test(', basic route', () => { + const gpx = route('gpx/:id'); + expect(gpx({ id: 10 })).toBe('gpx/10'); + }); + test(', basic route (vice-versa', () => { + const gpx = route('gpx/:id'); + expect(gpx('gpx/10')).toMatchObject({ id: '10' }); + }); +}); + +describe('Checking a multilevel route', () => { + test(', using the two levels', () => { + const gpx = route('gpx/:gpx/2trk/:trk'); + expect(gpx({ gpx: 10, trk: 0 })).toBe('gpx/10/2trk/0'); + }); + test(', using the two levels (vive-versa)', () => { + const gpx = route('gpx/:gpx/2trk/:trk'); + expect(gpx('gpx/10/2trk/0')).toMatchObject({ gpx: '10', trk: '0' }); + }); +}); + +describe('Checking a multilevel route with optional part', () => { + test(', using the two levels', () => { + const gpx = route('gpx/:gpx(/2trk/:trk)'); + expect(gpx({ gpx: 10, trk: 0 })).toBe('gpx/10/2trk/0'); + }); + test(', using the two levels (vive-versa)', () => { + const gpx = route('gpx/:gpx(/2trk/:trk)'); + expect(gpx('gpx/10/2trk/0')).toMatchObject({ gpx: '10', trk: '0' }); + }); + test(', using only one level', () => { + const gpx = route('gpx/:gpx(/2trk/:trk)'); + expect(gpx({ gpx: 10 })).toBe('gpx/10/2trk/'); //Unfortunately ! + }); + test(', using only one level (vive-versa)', () => { + const gpx = route('gpx/:gpx(/2trk/:trk)'); + expect(gpx('gpx/10')).toMatchObject({ gpx: '10' }); + }); +}); + +describe('Checking gpx ids', () => { + test(', vice', () => { + const gpx = uri('gpx', { gpx: 'id' }); + expect(gpx).toBe('gpx/id'); + }); + test(', and versa', () => { + const gpx = uri('gpx', 'gpx/id'); + expect(gpx).toMatchObject({ gpx: 'id' }); + }); +}); + +describe('Checking trk ids', () => { + test(', vice', () => { + const rte = uri('trk', { gpx: 'gpxid', trk: 'trkid' }); + expect(rte).toBe('gpx/gpxid/2trk/trkid'); + }); + test(', and versa', () => { + const rte = uri('trk', 'gpx/gpxid/2trk/trkid'); + expect(rte).toMatchObject({ gpx: 'gpxid', trk: 'trkid' }); + }); +}); + +describe('Checking trkseg ids', () => { + test(', vice', () => { + const rte = uri('trkseg', { + gpx: 'gpxid', + trk: 'trkid', + trkseg: 'trksegid', + }); + expect(rte).toBe('gpx/gpxid/2trk/trkid/trksegid'); + }); + test(', and versa', () => { + const rte = uri('trkseg', 'gpx/gpxid/2trk/trkid/trksegid'); + expect(rte).toMatchObject({ + gpx: 'gpxid', + trk: 'trkid', + trkseg: 'trksegid', + }); + }); +}); + +describe('Checking trkpt ids', () => { + test(', vice', () => { + const rte = uri('trkpt', { + gpx: 'gpxid', + trk: 'trkid', + trkseg: 'trksegid', + trkpt: 'trkptid', + }); + expect(rte).toBe('gpx/gpxid/2trk/trkid/trksegid/trkptid'); + }); + test(', and versa', () => { + const rte = uri('trkpt', 'gpx/gpxid/2trk/trkid/trksegid/trkptid'); + expect(rte).toMatchObject({ + gpx: 'gpxid', + trk: 'trkid', + trkseg: 'trksegid', + trkpt: 'trkptid', + }); + }); +}); + +describe('Checking settings id', () => { + test(', vice', () => { + const rte = uri('settings', {}); + expect(rte).toBe('settings'); + }); + test(', and versa', () => { + const rte = uri('settings', 'settings'); + expect(rte).toMatchObject({}); + }); +}); diff --git a/src/lib/ids.ts b/src/lib/ids.ts index 57aca42..46b2927 100644 --- a/src/lib/ids.ts +++ b/src/lib/ids.ts @@ -4,12 +4,12 @@ const routes = { dbdef: route('dbdef'), settings: route('settings'), gpx: route('gpx/:gpx'), - trk: route('gpx/:gpx/trk/:trk'), - trkseg: route('gpx/:gpx/trk/:trk/:trkseg'), - trkpt: route('gpx/:gpx/trk/:trk/:trkseg/:trkpt'), - wpt: route('gpx/:gpx/wpt/:wpt'), - rte: route('gpx/:gpx/rte/:rte'), - rtept: route('gpx/:gpx/rte/:rte/:rtept'), + wpt: route('gpx/:gpx/0wpt/:wpt'), + rte: route('gpx/:gpx/1rte/:rte'), + rtept: route('gpx/:gpx/1rte/:rte/:rtept'), + trk: route('gpx/:gpx/2trk/:trk'), + trkseg: route('gpx/:gpx/2trk/:trk/:trkseg'), + trkpt: route('gpx/:gpx/2trk/:trk/:trkseg/:trkpt'), }; type RouteKey = keyof typeof routes; diff --git a/src/lib/types.d.ts b/src/lib/types.d.ts new file mode 100644 index 0000000..2808948 --- /dev/null +++ b/src/lib/types.d.ts @@ -0,0 +1,34 @@ +interface IdGpx { + gpx: string; +} + +interface IdTrk { + gpx: string; + trk: string; +} +interface IdTrkseg { + gpx: string; + trk: string; + trkseg: string; +} +interface IdTrkpt { + gpx: string; + trk: string; + trkseg: string; + trkpt: string; +} +interface IdWpt { + gpx: string; + wpt: string; +} + +interface IdRte { + gpx: string; + rte: string; +} + +interface IdRtept { + gpx: string; + rte: string; + rtept: string; +} diff --git a/src/workers/dispatcher-main.test.js b/src/workers/dispatcher-main.test.js index 283d078..fac3fe6 100644 --- a/src/workers/dispatcher-main.test.js +++ b/src/workers/dispatcher-main.test.js @@ -1,4 +1,4 @@ -import dispatch, { init, worker } from './dispatcher-main' +import dispatch, { init, worker } from './dispatcher-main'; jest.mock('./get-worker', () => ({ getWorker: () => ({ @@ -21,8 +21,17 @@ describe('The dispatcher-main', () => { test('should return a promise if no callback is provided', () => { expect(dispatch('ping')).toBeInstanceOf(Promise); }); - test('should send back the message', () => { + test('should forward the message', () => { dispatch('ping'); expect(worker.port.postMessage).toBeCalledWith({ id: 0, payload: 'ping' }); }); + test('should return the response', () => { + var response; + const callback = (error, success) => { + response = success; + }; + dispatch('ping', callback); + worker.port.onmessage({ data: { id: 0, payload: 'pong' } }); + expect(response).toEqual('pong'); + }); });