From 22441fd9ef96af1b54fda3f14af62669738434f1 Mon Sep 17 00:00:00 2001 From: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com> Date: Tue, 6 Feb 2024 23:04:48 +0100 Subject: [PATCH] Run linter --- docs/profile-boilerplate.js | 10 +- format/address.js | 16 +- format/coord.js | 4 +- format/date.js | 18 +- format/filters.js | 6 +- format/lines-req.js | 6 +- format/location-filter.js | 8 +- format/location-identifier.js | 14 +- format/location.js | 18 +- format/locations-req.js | 8 +- format/nearby-req.js | 8 +- format/poi.js | 12 +- format/products-filter.js | 36 +- format/radar-req.js | 8 +- format/reachable-from-req.js | 8 +- format/rectangle.js | 6 +- format/refresh-journey-req.js | 14 +- format/remarks-req.js | 26 +- format/station-board-req.js | 20 +- format/station.js | 8 +- format/stop-req.js | 6 +- format/time.js | 18 +- format/trip-req.js | 6 +- index.js | 492 ++++++------- lib/default-profile.js | 100 +-- lib/errors.js | 54 +- lib/find-in-tree.js | 22 +- lib/luxon-timezones.js | 4 +- lib/profile-hooks.js | 8 +- lib/request.js | 158 ++--- lib/slice-leg.js | 64 +- lib/validate-profile.js | 30 +- p/avv/index.js | 12 +- p/bart/index.js | 12 +- p/bls/index.js | 12 +- p/bvg/index.js | 120 ++-- p/bvg/products.js | 4 +- p/cfl/index.js | 12 +- p/cfl/products.js | 4 +- p/cmta/index.js | 12 +- p/cmta/products.js | 4 +- p/dart/index.js | 12 +- p/db-busradar-nrw/index.js | 12 +- p/db/ageGroup.js | 20 +- p/db/index.js | 242 +++---- p/db/loyalty-cards.js | 22 +- p/db/products.js | 4 +- p/db/routing-modes.js | 4 +- p/insa/index.js | 12 +- p/insa/products.js | 4 +- p/invg/index.js | 12 +- p/invg/products.js | 4 +- p/irish-rail/index.js | 12 +- p/irish-rail/products.js | 4 +- p/ivb/index.js | 22 +- p/kvb/index.js | 22 +- p/mobil-nrw/index.js | 12 +- p/mobil-nrw/products.js | 4 +- p/mobiliteit-lu/index.js | 12 +- p/mobiliteit-lu/products.js | 4 +- p/nahsh/index.js | 62 +- p/nahsh/products.js | 4 +- p/nvv/index.js | 12 +- p/nvv/products.js | 4 +- p/oebb/index.js | 40 +- p/oebb/products.js | 4 +- p/ooevv/index.js | 12 +- p/pkp/index.js | 22 +- p/pkp/products.js | 4 +- p/rejseplanen/index.js | 12 +- p/rejseplanen/products.js | 4 +- p/rmv/index.js | 12 +- p/rmv/products.js | 4 +- p/rsag/index.js | 12 +- p/rsag/products.js | 4 +- p/saarfahrplan/index.js | 22 +- p/saarfahrplan/products.js | 4 +- p/salzburg/index.js | 12 +- p/sbahn-muenchen/index.js | 12 +- p/sbahn-muenchen/products.js | 4 +- p/sncb/index.js | 50 +- p/sncb/products.js | 4 +- p/stv/index.js | 12 +- p/svv/index.js | 12 +- p/svv/products.js | 4 +- p/tpg/index.js | 12 +- p/vbb/index.js | 60 +- p/vbb/parse-loc-dhid.js | 16 +- p/vbb/products.js | 4 +- p/vbn/index.js | 12 +- p/vbn/products.js | 4 +- p/vkg/index.js | 12 +- p/vmt/index.js | 12 +- p/vmt/products.js | 4 +- p/vor/index.js | 12 +- p/vos/index.js | 12 +- p/vrn/index.js | 12 +- p/vrn/products.js | 4 +- p/vsn/index.js | 12 +- p/vsn/products.js | 4 +- p/vvt/index.js | 12 +- p/vvv/index.js | 12 +- p/zvv/index.js | 12 +- p/zvv/products.js | 4 +- parse/arrival-or-departure.js | 54 +- parse/arrival.js | 8 +- parse/common.js | 132 ++-- parse/date-time.js | 40 +- parse/departure.js | 8 +- parse/find-remarks.js | 10 +- parse/hint.js | 32 +- parse/icon.js | 14 +- parse/journey-leg.js | 146 ++-- parse/journey.js | 38 +- parse/line.js | 32 +- parse/location.js | 100 +-- parse/movement.js | 16 +- parse/nearby.js | 10 +- parse/operator.js | 12 +- parse/platform.js | 12 +- parse/polyline.js | 38 +- parse/products-bitmask.js | 18 +- parse/prognosis-type.js | 6 +- parse/scheduled-days.js | 34 +- parse/stopover.js | 38 +- parse/trip.js | 40 +- parse/warning.js | 64 +- parse/when.js | 22 +- retry.js | 34 +- test/bvg-arrivals.js | 32 +- test/bvg-journey.js | 32 +- test/bvg-radar.js | 32 +- test/bvg-trip-with-occupancy.js | 32 +- test/db-arrivals.js | 32 +- test/db-deps-with-destination.js | 34 +- test/db-journey-2.js | 32 +- test/db-journey-additional-stopover.js | 40 +- test/db-journey-fpB-fpE-2-years.js | 30 +- test/db-journey-overnight.js | 52 +- test/db-journey-polyline.js | 32 +- test/db-journey-tzoffset-0.js | 50 +- test/db-journey.js | 32 +- test/db-netz-remarks.js | 28 +- test/db-stop.js | 32 +- test/e2e/bls.js | 34 +- test/e2e/bvg.js | 332 ++++----- test/e2e/cfl.js | 202 +++--- test/e2e/cmta.js | 178 ++--- test/e2e/common.js | 16 +- test/e2e/dart.js | 34 +- test/e2e/db-busradar-nrw.js | 110 +-- test/e2e/db.js | 392 +++++------ test/e2e/insa.js | 204 +++--- test/e2e/invg.js | 206 +++--- test/e2e/ivb.js | 34 +- test/e2e/kvb.js | 34 +- test/e2e/lib/arrivals.js | 24 +- test/e2e/lib/departures-in-direction.js | 22 +- test/e2e/lib/departures.js | 24 +- test/e2e/lib/earlier-later-journeys.js | 58 +- .../e2e/lib/journeys-fails-with-no-product.js | 14 +- test/e2e/lib/journeys-station-to-address.js | 36 +- test/e2e/lib/journeys-station-to-poi.js | 44 +- test/e2e/lib/journeys-station-to-station.js | 28 +- test/e2e/lib/journeys-walking-speed.js | 34 +- test/e2e/lib/journeys-with-detour.js | 16 +- test/e2e/lib/leg-cycle-alternatives.js | 42 +- test/e2e/lib/lines.js | 18 +- test/e2e/lib/reachable-from.js | 38 +- test/e2e/lib/refresh-journey.js | 28 +- test/e2e/lib/remarks.js | 20 +- test/e2e/lib/server-info.js | 30 +- test/e2e/lib/util.js | 78 +-- test/e2e/lib/validate-fptf-with.js | 28 +- test/e2e/lib/validators.js | 662 +++++++++--------- test/e2e/lib/vbb-bvg-validators.js | 20 +- test/e2e/mobil-nrw.js | 172 ++--- test/e2e/mobiliteit-lu.js | 198 +++--- test/e2e/nahsh.js | 284 ++++---- test/e2e/nvv.js | 188 ++--- test/e2e/oebb.js | 312 ++++----- test/e2e/ooevv.js | 34 +- test/e2e/pkp.js | 118 ++-- test/e2e/rejseplanen.js | 142 ++-- test/e2e/rmv.js | 76 +- test/e2e/rsag.js | 78 +-- test/e2e/saarfahrplan.js | 212 +++--- test/e2e/salzburg.js | 34 +- test/e2e/sbahn-muenchen.js | 198 +++--- test/e2e/sncb.js | 78 +-- test/e2e/stv.js | 34 +- test/e2e/svv.js | 76 +- test/e2e/tpg.js | 34 +- test/e2e/vbb.js | 306 ++++---- test/e2e/vbn.js | 76 +- test/e2e/vor.js | 34 +- test/e2e/vrn.js | 164 ++--- test/e2e/vsn.js | 140 ++-- test/e2e/vvv.js | 34 +- test/e2e/zvv.js | 108 +-- test/fixtures/bvg-arrivals.js | 18 +- test/fixtures/bvg-journey.js | 4 +- test/fixtures/bvg-radar.js | 4 +- test/fixtures/bvg-trip-with-occupancy.js | 4 +- test/fixtures/db-arrivals.js | 4 +- test/fixtures/db-journey-2.js | 4 +- .../db-journey-overnight-1.expected.js | 8 +- test/fixtures/db-journey-polyline.js | 4 +- test/fixtures/db-journey.js | 4 +- test/fixtures/db-stop.js | 10 +- test/fixtures/insa-stop.js | 4 +- test/fixtures/oebb-trip.js | 16 +- test/fixtures/rejseplanen-trip.js | 4 +- test/fixtures/rsag-journey.js | 4 +- test/fixtures/vbb-departures.js | 4 +- test/fixtures/vbb-journeys.js | 4 +- test/fixtures/vbb-on-demand-trip.js | 4 +- test/fixtures/vsn-departures.js | 4 +- test/fixtures/vsn-remarks.js | 4 +- test/format/db-journeys-query.js | 28 +- test/format/products-filter.js | 28 +- test/insa-stop.js | 32 +- test/lib/request.js | 236 +++---- test/mobiliteit-lu-line.js | 24 +- test/oebb-trip.js | 32 +- test/parse/date-time.js | 58 +- test/parse/hint.js | 28 +- test/parse/icon.js | 34 +- test/parse/line.js | 28 +- test/parse/location.js | 104 +-- test/parse/operator.js | 14 +- test/parse/warning.js | 44 +- test/parse/when.js | 32 +- test/rejseplanen-trip.js | 32 +- test/retry.js | 58 +- test/rsag-journey.js | 32 +- test/sncb-journey-with-chki.js | 32 +- test/throttle.js | 44 +- test/vbb-departures.js | 32 +- test/vbb-journeys.js | 32 +- test/vbb-on-demand-trip.js | 32 +- test/vsn-departures.js | 32 +- test/vsn-remarks.js | 32 +- throttle.js | 12 +- tools/debug-cli/cli.js | 42 +- tools/endpoint-hci-version/cli.js | 30 +- 246 files changed, 5677 insertions(+), 5677 deletions(-) diff --git a/docs/profile-boilerplate.js b/docs/profile-boilerplate.js index 0cc80cd0d..ffc5784ac 100644 --- a/docs/profile-boilerplate.js +++ b/docs/profile-boilerplate.js @@ -17,7 +17,7 @@ const products = [ short: 'M', default: true, }, -] +]; const transformReqBody = (body) => { // get these from the recorded app requests @@ -25,8 +25,8 @@ const transformReqBody = (body) => { // body.ver = … // body.auth = { … } // body.lang = … - return body -} + return body; +}; const insaProfile = { // locale: …, @@ -38,8 +38,8 @@ const insaProfile = { trip: false, radar: false, -} +}; export { insaProfile, -} +}; diff --git a/format/address.js b/format/address.js index 414a40cb2..6621ff6d8 100644 --- a/format/address.js +++ b/format/address.js @@ -1,9 +1,9 @@ -import {formatLocationIdentifier} from './location-identifier.js' -import {formatCoord} from './coord.js' +import {formatLocationIdentifier} from './location-identifier.js'; +import {formatCoord} from './coord.js'; const formatAddress = (a) => { if (a.type !== 'location' || !a.latitude || !a.longitude || !a.address) { - throw new TypeError('invalid address') + throw new TypeError('invalid address'); } const data = { @@ -11,17 +11,17 @@ const formatAddress = (a) => { O: a.address, X: formatCoord(a.longitude), Y: formatCoord(a.latitude), - } + }; if (a.id) { - data.L = a.id + data.L = a.id; } return { type: 'A', // address name: a.address, lid: formatLocationIdentifier(data), - } -} + }; +}; export { formatAddress, -} +}; diff --git a/format/coord.js b/format/coord.js index bc8404d6b..58ce094b4 100644 --- a/format/coord.js +++ b/format/coord.js @@ -1,5 +1,5 @@ -const formatCoord = x => Math.round(x * 1000000) +const formatCoord = x => Math.round(x * 1000000); export { formatCoord, -} +}; diff --git a/format/date.js b/format/date.js index a8ca5527a..b249d63dc 100644 --- a/format/date.js +++ b/format/date.js @@ -1,23 +1,23 @@ -import {DateTime, IANAZone} from 'luxon' -import {luxonIANAZonesByProfile as timezones} from '../lib/luxon-timezones.js' +import {DateTime, IANAZone} from 'luxon'; +import {luxonIANAZonesByProfile as timezones} from '../lib/luxon-timezones.js'; // todo: change to `(profile) => (when) => {}` const formatDate = (profile, when) => { - let timezone + let timezone; if (timezones.has(profile)) { - timezone = timezones.get(profile) + timezone = timezones.get(profile); } else { - timezone = new IANAZone(profile.timezone) - timezones.set(profile, timezone) + timezone = new IANAZone(profile.timezone); + timezones.set(profile, timezone); } return DateTime.fromMillis(Number(when), { locale: profile.locale, zone: timezone, }) - .toFormat('yyyyMMdd') -} + .toFormat('yyyyMMdd'); +}; export { formatDate, -} +}; diff --git a/format/filters.js b/format/filters.js index 4d64e5caf..3eecd8f6b 100644 --- a/format/filters.js +++ b/format/filters.js @@ -1,12 +1,12 @@ -const bike = {type: 'BC', mode: 'INC'} +const bike = {type: 'BC', mode: 'INC'}; const accessibility = { none: {type: 'META', mode: 'INC', meta: 'notBarrierfree'}, partial: {type: 'META', mode: 'INC', meta: 'limitedBarrierfree'}, complete: {type: 'META', mode: 'INC', meta: 'completeBarrierfree'}, -} +}; export { bike, accessibility, -} +}; diff --git a/format/lines-req.js b/format/lines-req.js index 629a1d668..6d78a93c5 100644 --- a/format/lines-req.js +++ b/format/lines-req.js @@ -4,9 +4,9 @@ const formatLinesReq = (ctx, query) => { req: { input: query, }, - } -} + }; +}; export { formatLinesReq, -} +}; diff --git a/format/location-filter.js b/format/location-filter.js index 8aebfcf8d..f0da4a6ad 100644 --- a/format/location-filter.js +++ b/format/location-filter.js @@ -1,6 +1,6 @@ const formatLocationFilter = (stops, addresses, poi) => { if (stops && addresses && poi) { - return 'ALL' + return 'ALL'; } return (stops ? 'S' @@ -8,9 +8,9 @@ const formatLocationFilter = (stops, addresses, poi) => { ? 'A' : '') + (poi ? 'P' - : '') -} + : ''); +}; export { formatLocationFilter, -} +}; diff --git a/format/location-identifier.js b/format/location-identifier.js index a8d282d95..59cb284e3 100644 --- a/format/location-identifier.js +++ b/format/location-identifier.js @@ -1,18 +1,18 @@ -const sep = '@' +const sep = '@'; const formatLocationIdentifier = (data) => { - let str = '' + let str = ''; for (let key in data) { if (!Object.prototype.hasOwnProperty.call(data, key)) { - continue + continue; } - str += key + '=' + data[key] + sep // todo: escape, but how? + str += key + '=' + data[key] + sep; // todo: escape, but how? } - return str -} + return str; +}; export { formatLocationIdentifier, -} +}; diff --git a/format/location.js b/format/location.js index 35fb24f2c..28650fadd 100644 --- a/format/location.js +++ b/format/location.js @@ -1,25 +1,25 @@ const formatLocation = (profile, l, name = 'location') => { if ('string' === typeof l) { - return profile.formatStation(l) + return profile.formatStation(l); } if ('object' === typeof l && !Array.isArray(l)) { if (l.type === 'station' || l.type === 'stop') { - return profile.formatStation(l.id) + return profile.formatStation(l.id); } if (l.poi) { - return profile.formatPoi(l) + return profile.formatPoi(l); } if ('string' === typeof l.address) { - return profile.formatAddress(l) + return profile.formatAddress(l); } if (!l.type) { - throw new TypeError(`missing ${name}.type`) + throw new TypeError(`missing ${name}.type`); } - throw new TypeError(`invalid ${name}.type: ${l.type}`) + throw new TypeError(`invalid ${name}.type: ${l.type}`); } - throw new TypeError(name + ': valid station, address or poi required.') -} + throw new TypeError(name + ': valid station, address or poi required.'); +}; export { formatLocation, -} +}; diff --git a/format/locations-req.js b/format/locations-req.js index 9e2efb3fe..704af61d4 100644 --- a/format/locations-req.js +++ b/format/locations-req.js @@ -1,5 +1,5 @@ const formatLocationsReq = (ctx, query) => { - const {profile, opt} = ctx + const {profile, opt} = ctx; return { cfg: {polyEnc: 'GPA'}, @@ -14,9 +14,9 @@ const formatLocationsReq = (ctx, query) => { maxLoc: opt.results, field: 'S', // todo: what is this? }}, - } -} + }; +}; export { formatLocationsReq, -} +}; diff --git a/format/nearby-req.js b/format/nearby-req.js index eb02ae703..5e4f8f7ee 100644 --- a/format/nearby-req.js +++ b/format/nearby-req.js @@ -1,5 +1,5 @@ const formatNearbyReq = (ctx, location) => { - const {profile, opt} = ctx + const {profile, opt} = ctx; return { cfg: {polyEnc: 'GPA'}, @@ -20,9 +20,9 @@ const formatNearbyReq = (ctx, location) => { getStops: Boolean(opt.stops), maxLoc: opt.results, }, - } -} + }; +}; export { formatNearbyReq, -} +}; diff --git a/format/poi.js b/format/poi.js index 9621b4098..485864946 100644 --- a/format/poi.js +++ b/format/poi.js @@ -1,10 +1,10 @@ -import {formatLocationIdentifier} from './location-identifier.js' -import {formatCoord} from './coord.js' +import {formatLocationIdentifier} from './location-identifier.js'; +import {formatCoord} from './coord.js'; const formatPoi = (p) => { // todo: use Number.isFinite()! if (p.type !== 'location' || !p.latitude || !p.longitude || !p.id || !p.name) { - throw new TypeError('invalid POI') + throw new TypeError('invalid POI'); } return { @@ -17,9 +17,9 @@ const formatPoi = (p) => { X: formatCoord(p.longitude), Y: formatCoord(p.latitude), }), - } -} + }; +}; export { formatPoi, -} +}; diff --git a/format/products-filter.js b/format/products-filter.js index c2de4cbb6..6158ec0e6 100644 --- a/format/products-filter.js +++ b/format/products-filter.js @@ -1,45 +1,45 @@ -import isObj from 'lodash/isObject.js' +import isObj from 'lodash/isObject.js'; -const hasProp = (o, k) => Object.prototype.hasOwnProperty.call(o, k) +const hasProp = (o, k) => Object.prototype.hasOwnProperty.call(o, k); const formatProductsFilter = (ctx, filter) => { if (!isObj(filter)) { - throw new TypeError('products filter must be an object') + throw new TypeError('products filter must be an object'); } - const {profile} = ctx + const {profile} = ctx; - const byProduct = {} - const defaultProducts = {} + const byProduct = {}; + const defaultProducts = {}; for (let product of profile.products) { - byProduct[product.id] = product - defaultProducts[product.id] = product.default + byProduct[product.id] = product; + defaultProducts[product.id] = product.default; } - filter = Object.assign({}, defaultProducts, filter) + filter = Object.assign({}, defaultProducts, filter); - let res = 0, products = 0 + let res = 0, products = 0; for (let product in filter) { if (!hasProp(filter, product) || filter[product] !== true) { - continue + continue; } if (!byProduct[product]) { - throw new TypeError('unknown product ' + product) + throw new TypeError('unknown product ' + product); } - products++ + products++; for (let bitmask of byProduct[product].bitmasks) { - res = res | bitmask + res = res | bitmask; } } if (products === 0) { - throw new Error('no products used') + throw new Error('no products used'); } return { type: 'PROD', mode: 'INC', value: String(res), - } -} + }; +}; export { formatProductsFilter, -} +}; diff --git a/format/radar-req.js b/format/radar-req.js index 0a5358b65..54d007230 100644 --- a/format/radar-req.js +++ b/format/radar-req.js @@ -1,5 +1,5 @@ const formatRadarReq = (ctx, north, west, south, east) => { - const {profile, opt} = ctx + const {profile, opt} = ctx; return { meth: 'JourneyGeoPos', @@ -21,9 +21,9 @@ const formatRadarReq = (ctx, north, west, south, east) => { // - CALC_REPORT (as seen in the INSA Young app) trainPosMode: 'CALC', }, - } -} + }; +}; export { formatRadarReq, -} +}; diff --git a/format/reachable-from-req.js b/format/reachable-from-req.js index 7878f74cd..1a0f49066 100644 --- a/format/reachable-from-req.js +++ b/format/reachable-from-req.js @@ -1,5 +1,5 @@ const formatReachableFromReq = (ctx, address) => { - const {profile, opt} = ctx + const {profile, opt} = ctx; return { meth: 'LocGeoReach', @@ -16,9 +16,9 @@ const formatReachableFromReq = (ctx, address) => { profile.formatProductsFilter(ctx, opt.products || {}), ], }, - } -} + }; +}; export { formatReachableFromReq, -} +}; diff --git a/format/rectangle.js b/format/rectangle.js index a46a89505..c36fd8271 100644 --- a/format/rectangle.js +++ b/format/rectangle.js @@ -8,9 +8,9 @@ const formatRectangle = (profile, north, west, south, east) => { x: profile.formatCoord(east), y: profile.formatCoord(north), }, - } -} + }; +}; export { formatRectangle, -} +}; diff --git a/format/refresh-journey-req.js b/format/refresh-journey-req.js index ecc930b40..92f23b185 100644 --- a/format/refresh-journey-req.js +++ b/format/refresh-journey-req.js @@ -1,24 +1,24 @@ const formatRefreshJourneyReq = (ctx, refreshToken) => { - const {profile, opt} = ctx + const {profile, opt} = ctx; const req = { getIST: true, // todo: make an option getPasslist: Boolean(opt.stopovers), getPolyline: Boolean(opt.polylines), getTariff: Boolean(opt.tickets), - } + }; if (profile.refreshJourneyUseOutReconL) { - req.outReconL = [{ctx: refreshToken}] + req.outReconL = [{ctx: refreshToken}]; } else { - req.ctxRecon = refreshToken + req.ctxRecon = refreshToken; } return { meth: 'Reconstruction', req, - } -} + }; +}; export { formatRefreshJourneyReq, -} +}; diff --git a/format/remarks-req.js b/format/remarks-req.js index 75cf96aad..ba45bc3ec 100644 --- a/format/remarks-req.js +++ b/format/remarks-req.js @@ -1,17 +1,17 @@ const formatRemarksReq = (ctx) => { - const {profile, opt} = ctx + const {profile, opt} = ctx; - const himFltrL = [] + const himFltrL = []; // todo: https://github.com/marudor/BahnhofsAbfahrten/blob/95fef0217d01344642dd423457473fe9b8b6056e/src/types/HAFAS/index.ts#L76-L91 if (opt.products) { - himFltrL.push(profile.formatProductsFilter(ctx, opt.products)) + himFltrL.push(profile.formatProductsFilter(ctx, opt.products)); } const req = { himFltrL, - } + }; if (profile.remarksGetPolyline) { - req.getPolyline = Boolean(opt.polylines) + req.getPolyline = Boolean(opt.polylines); } // todo: stLoc, dirLoc // todo: comp, dept, onlyHimId, onlyToday @@ -19,20 +19,20 @@ const formatRemarksReq = (ctx) => { // see https://github.com/marudor/BahnhofsAbfahrten/blob/46a74957d68edc15713112df44e1a25150f5a178/src/types/HAFAS/HimSearch.ts#L3-L18 if (opt.results !== null) { - req.maxNum = opt.results + req.maxNum = opt.results; } if (opt.from !== null) { - req.dateB = profile.formatDate(profile, opt.from) - req.timeB = profile.formatTime(profile, opt.from) + req.dateB = profile.formatDate(profile, opt.from); + req.timeB = profile.formatTime(profile, opt.from); } if (opt.to !== null) { - req.dateE = profile.formatDate(profile, opt.to) - req.timeE = profile.formatTime(profile, opt.to) + req.dateE = profile.formatDate(profile, opt.to); + req.timeE = profile.formatTime(profile, opt.to); } - return {meth: 'HimSearch', req} -} + return {meth: 'HimSearch', req}; +}; export { formatRemarksReq, -} +}; diff --git a/format/station-board-req.js b/format/station-board-req.js index 1904cc3b5..9a8e779f1 100644 --- a/format/station-board-req.js +++ b/format/station-board-req.js @@ -1,11 +1,11 @@ const formatStationBoardReq = (ctx, station, type) => { - const {profile, opt} = ctx + const {profile, opt} = ctx; const jnyFltrL = [ profile.formatProductsFilter(ctx, opt.products || {}), - ] + ]; if (opt.line !== null) { - jnyFltrL.push({type: 'LINEID', mode: 'INC', value: opt.line}) + jnyFltrL.push({type: 'LINEID', mode: 'INC', value: opt.line}); } const req = { @@ -18,25 +18,25 @@ const formatStationBoardReq = (ctx, station, type) => { : undefined, jnyFltrL, dur: opt.duration, - } + }; if (opt.results !== null) { req.maxJny = opt.results === Infinity ? 10000 - : opt.results + : opt.results; } if (profile.departuresGetPasslist) { - req.getPasslist = Boolean(opt.stopovers) + req.getPasslist = Boolean(opt.stopovers); } if (profile.departuresStbFltrEquiv) { - req.stbFltrEquiv = !opt.includeRelatedStations + req.stbFltrEquiv = !opt.includeRelatedStations; } return { meth: 'StationBoard', req, - } -} + }; +}; export { formatStationBoardReq, -} +}; diff --git a/format/station.js b/format/station.js index c6e92cdc8..dc9e793c0 100644 --- a/format/station.js +++ b/format/station.js @@ -1,4 +1,4 @@ -import {formatLocationIdentifier} from './location-identifier.js' +import {formatLocationIdentifier} from './location-identifier.js'; const formatStation = (id) => { return { @@ -9,9 +9,9 @@ const formatStation = (id) => { L: id, // todo: `p` – timestamp of when the ID was obtained }), - } -} + }; +}; export { formatStation, -} +}; diff --git a/format/stop-req.js b/format/stop-req.js index 25d45a55e..11f3a5f43 100644 --- a/format/stop-req.js +++ b/format/stop-req.js @@ -5,9 +5,9 @@ const formatStopReq = (ctx, stopRef) => { req: { locL: [stopRef], }, - } -} + }; +}; export { formatStopReq, -} +}; diff --git a/format/time.js b/format/time.js index 75e3397ac..8b4e6c183 100644 --- a/format/time.js +++ b/format/time.js @@ -1,23 +1,23 @@ -import {DateTime, IANAZone} from 'luxon' -import {luxonIANAZonesByProfile as timezones} from '../lib/luxon-timezones.js' +import {DateTime, IANAZone} from 'luxon'; +import {luxonIANAZonesByProfile as timezones} from '../lib/luxon-timezones.js'; // todo: change to `(profile) => (when) => {}` const formatTime = (profile, when) => { - let timezone + let timezone; if (timezones.has(profile)) { - timezone = timezones.get(profile) + timezone = timezones.get(profile); } else { - timezone = new IANAZone(profile.timezone) - timezones.set(profile, timezone) + timezone = new IANAZone(profile.timezone); + timezones.set(profile, timezone); } return DateTime.fromMillis(Number(when), { locale: profile.locale, zone: timezone, }) - .toFormat('HHmmss') -} + .toFormat('HHmmss'); +}; export { formatTime, -} +}; diff --git a/format/trip-req.js b/format/trip-req.js index 3d3e3eb61..7a4af097c 100644 --- a/format/trip-req.js +++ b/format/trip-req.js @@ -10,9 +10,9 @@ const formatTripReq = ({opt}, id) => { // date: profile.formatDate(profile, opt.when), getPolyline: Boolean(opt.polyline), }, - } -} + }; +}; export { formatTripReq, -} +}; diff --git a/index.js b/index.js index 8ad089ab8..d665b9cf0 100644 --- a/index.js +++ b/index.js @@ -1,69 +1,69 @@ -import isObj from 'lodash/isObject.js' -import sortBy from 'lodash/sortBy.js' -import omit from 'lodash/omit.js' +import isObj from 'lodash/isObject.js'; +import sortBy from 'lodash/sortBy.js'; +import omit from 'lodash/omit.js'; -import {defaultProfile} from './lib/default-profile.js' -import {validateProfile} from './lib/validate-profile.js' -import {INVALID_REQUEST} from './lib/errors.js' -import {sliceLeg} from './lib/slice-leg.js' -import {HafasError} from './lib/errors.js' +import {defaultProfile} from './lib/default-profile.js'; +import {validateProfile} from './lib/validate-profile.js'; +import {INVALID_REQUEST} from './lib/errors.js'; +import {sliceLeg} from './lib/slice-leg.js'; +import {HafasError} from './lib/errors.js'; // background info: https://github.com/public-transport/hafas-client/issues/286 const FORBIDDEN_USER_AGENTS = [ 'my-awesome-program', // previously used in readme.md, p/*/readme.md & docs/*.md 'hafas-client-example', // previously used in p/*/example.js 'link-to-your-project-or-email', // now used throughout -] +]; -const isNonEmptyString = str => 'string' === typeof str && str.length > 0 +const isNonEmptyString = str => 'string' === typeof str && str.length > 0; const validateLocation = (loc, name = 'location') => { if (!isObj(loc)) { - throw new TypeError(name + ' must be an object.') + throw new TypeError(name + ' must be an object.'); } else if (loc.type !== 'location') { - throw new TypeError('invalid location object.') + throw new TypeError('invalid location object.'); } else if ('number' !== typeof loc.latitude) { - throw new TypeError(name + '.latitude must be a number.') + throw new TypeError(name + '.latitude must be a number.'); } else if ('number' !== typeof loc.longitude) { - throw new TypeError(name + '.longitude must be a number.') + throw new TypeError(name + '.longitude must be a number.'); } -} +}; const validateWhen = (when, name = 'when') => { if (Number.isNaN(Number(when))) { - throw new TypeError(name + ' is invalid') + throw new TypeError(name + ' is invalid'); } -} +}; const createClient = (profile, userAgent, opt = {}) => { - profile = Object.assign({}, defaultProfile, profile) - validateProfile(profile) + profile = Object.assign({}, defaultProfile, profile); + validateProfile(profile); if ('string' !== typeof userAgent) { - throw new TypeError('userAgent must be a string') + throw new TypeError('userAgent must be a string'); } if (FORBIDDEN_USER_AGENTS.includes(userAgent.toLowerCase())) { - throw new TypeError(`userAgent should tell the HAFAS API operators how to contact you. If you have copied "${userAgent}" value from the documentation, please adapt it.`) + throw new TypeError(`userAgent should tell the HAFAS API operators how to contact you. If you have copied "${userAgent}" value from the documentation, please adapt it.`); } const _stationBoard = async (station, type, resultsField, parse, opt = {}) => { if (isObj(station)) { - station = profile.formatStation(station.id) + station = profile.formatStation(station.id); } else if ('string' === typeof station) { - station = profile.formatStation(station) + station = profile.formatStation(station); } else { - throw new TypeError('station must be an object or a string.') + throw new TypeError('station must be an object or a string.'); } if ('string' !== typeof type || !type) { - throw new TypeError('type must be a non-empty string.') + throw new TypeError('type must be a non-empty string.'); } if (!profile.departuresGetPasslist && 'stopovers' in opt) { - throw new Error('opt.stopovers is not supported by this endpoint') + throw new Error('opt.stopovers is not supported by this endpoint'); } if (!profile.departuresStbFltrEquiv && 'includeRelatedStations' in opt) { - throw new Error('opt.includeRelatedStations is not supported by this endpoint') + throw new Error('opt.includeRelatedStations is not supported by this endpoint'); } opt = Object.assign({ @@ -80,66 +80,66 @@ const createClient = (profile, userAgent, opt = {}) => { // departures at related stations // e.g. those that belong together on the metro map. includeRelatedStations: true, - }, opt) - opt.when = new Date(opt.when || Date.now()) + }, opt); + opt.when = new Date(opt.when || Date.now()); if (Number.isNaN(Number(opt.when))) { - throw new Error('opt.when is invalid') + throw new Error('opt.when is invalid'); } - const req = profile.formatStationBoardReq({profile, opt}, station, type) + const req = profile.formatStationBoardReq({profile, opt}, station, type); - const {res, common} = await profile.request({profile, opt}, userAgent, req) + const {res, common} = await profile.request({profile, opt}, userAgent, req); - const ctx = {profile, opt, common, res} + const ctx = {profile, opt, common, res}; const jnyL = Array.isArray(res.jnyL) ? res.jnyL - : [] + : []; const results = jnyL.map(res => parse(ctx, res)) - .sort((a, b) => new Date(a.when) - new Date(b.when)) // todo + .sort((a, b) => new Date(a.when) - new Date(b.when)); // todo return { [resultsField]: results, realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; const departures = async (station, opt = {}) => { - return await _stationBoard(station, 'DEP', 'departures', profile.parseDeparture, opt) - } + return await _stationBoard(station, 'DEP', 'departures', profile.parseDeparture, opt); + }; const arrivals = async (station, opt = {}) => { - return await _stationBoard(station, 'ARR', 'arrivals', profile.parseArrival, opt) - } + return await _stationBoard(station, 'ARR', 'arrivals', profile.parseArrival, opt); + }; const journeys = async (from, to, opt = {}) => { - from = profile.formatLocation(profile, from, 'from') - to = profile.formatLocation(profile, to, 'to') + from = profile.formatLocation(profile, from, 'from'); + to = profile.formatLocation(profile, to, 'to'); if ('earlierThan' in opt && 'laterThan' in opt) { - throw new TypeError('opt.earlierThan and opt.laterThan are mutually exclusive.') + throw new TypeError('opt.earlierThan and opt.laterThan are mutually exclusive.'); } if ('departure' in opt && 'arrival' in opt) { - throw new TypeError('opt.departure and opt.arrival are mutually exclusive.') + throw new TypeError('opt.departure and opt.arrival are mutually exclusive.'); } - let journeysRef = null + let journeysRef = null; if ('earlierThan' in opt) { if (!isNonEmptyString(opt.earlierThan)) { - throw new TypeError('opt.earlierThan must be a non-empty string.') + throw new TypeError('opt.earlierThan must be a non-empty string.'); } if ('departure' in opt || 'arrival' in opt) { - throw new TypeError('opt.earlierThan and opt.departure/opt.arrival are mutually exclusive.') + throw new TypeError('opt.earlierThan and opt.departure/opt.arrival are mutually exclusive.'); } - journeysRef = opt.earlierThan + journeysRef = opt.earlierThan; } if ('laterThan' in opt) { if (!isNonEmptyString(opt.laterThan)) { - throw new TypeError('opt.laterThan must be a non-empty string.') + throw new TypeError('opt.laterThan must be a non-empty string.'); } if ('departure' in opt || 'arrival' in opt) { - throw new TypeError('opt.laterThan and opt.departure/opt.arrival are mutually exclusive.') + throw new TypeError('opt.laterThan and opt.departure/opt.arrival are mutually exclusive.'); } - journeysRef = opt.laterThan + journeysRef = opt.laterThan; } opt = Object.assign({ @@ -160,53 +160,53 @@ const createClient = (profile, userAgent, opt = {}) => { entrances: true, // parse & expose entrances of stops/stations? remarks: true, // parse & expose hints & warnings? scheduledDays: false, // parse & expose dates each journey is valid on? - }, opt) + }, opt); if (opt.via) { - opt.via = profile.formatLocation(profile, opt.via, 'opt.via') + opt.via = profile.formatLocation(profile, opt.via, 'opt.via'); } if (opt.when !== undefined) { - throw new Error('opt.when is not supported anymore. Use opt.departure/opt.arrival.') + throw new Error('opt.when is not supported anymore. Use opt.departure/opt.arrival.'); } - let when = new Date(), outFrwd = true + let when = new Date(), outFrwd = true; if (opt.departure !== undefined && opt.departure !== null) { - when = new Date(opt.departure) + when = new Date(opt.departure); if (Number.isNaN(Number(when))) { - throw new TypeError('opt.departure is invalid') + throw new TypeError('opt.departure is invalid'); } } else if (opt.arrival !== undefined && opt.arrival !== null) { if (!profile.journeysOutFrwd) { - throw new Error('opt.arrival is unsupported') + throw new Error('opt.arrival is unsupported'); } - when = new Date(opt.arrival) + when = new Date(opt.arrival); if (Number.isNaN(Number(when))) { - throw new TypeError('opt.arrival is invalid') + throw new TypeError('opt.arrival is invalid'); } - outFrwd = false + outFrwd = false; } const filters = [ profile.formatProductsFilter({profile}, opt.products || {}), - ] + ]; if ( opt.accessibility && profile.filters && profile.filters.accessibility && profile.filters.accessibility[opt.accessibility] ) { - filters.push(profile.filters.accessibility[opt.accessibility]) + filters.push(profile.filters.accessibility[opt.accessibility]); } if (!['slow', 'normal', 'fast'].includes(opt.walkingSpeed)) { - throw new Error('opt.walkingSpeed must be one of these values: "slow", "normal", "fast".') + throw new Error('opt.walkingSpeed must be one of these values: "slow", "normal", "fast".'); } - const gisFltrL = [] + const gisFltrL = []; if (profile.journeysWalkingSpeed) { gisFltrL.push({ meta: 'foot_speed_' + opt.walkingSpeed, mode: 'FB', type: 'M', - }) + }); } const query = { @@ -230,33 +230,33 @@ const createClient = (profile, userAgent, opt = {}) => { getPolyline: Boolean(opt.polylines), // todo: `getConGroups: false` what is this? // todo: what is getEco, fwrd? - } + }; if (journeysRef) { - query.ctxScr = journeysRef + query.ctxScr = journeysRef; } else { - query.outDate = profile.formatDate(profile, when) - query.outTime = profile.formatTime(profile, when) + query.outDate = profile.formatDate(profile, when); + query.outTime = profile.formatTime(profile, when); } if (opt.results !== null) { - query.numF = opt.results + query.numF = opt.results; } if (profile.journeysOutFrwd) { - query.outFrwd = outFrwd + query.outFrwd = outFrwd; } const {res, common} = await profile.request({profile, opt}, userAgent, { cfg: {polyEnc: 'GPA'}, meth: 'TripSearch', req: profile.transformJourneysQuery({profile, opt}, query), - }) + }); if (!Array.isArray(res.outConL)) { - return [] + return []; } // todo: outConGrpL - const ctx = {profile, opt, common, res} + const ctx = {profile, opt, common, res}; const journeys = res.outConL - .map(j => profile.parseJourney(ctx, j)) + .map(j => profile.parseJourney(ctx, j)); return { earlierRef: res.outCtxScrB || null, @@ -265,12 +265,12 @@ const createClient = (profile, userAgent, opt = {}) => { realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; const refreshJourney = async (refreshToken, opt = {}) => { if ('string' !== typeof refreshToken || !refreshToken) { - throw new TypeError('refreshToken must be a non-empty string.') + throw new TypeError('refreshToken must be a non-empty string.'); } opt = Object.assign({ @@ -281,63 +281,63 @@ const createClient = (profile, userAgent, opt = {}) => { entrances: true, // parse & expose entrances of stops/stations? remarks: true, // parse & expose hints & warnings? scheduledDays: false, // parse & expose dates the journey is valid on? - }, opt) + }, opt); - const req = profile.formatRefreshJourneyReq({profile, opt}, refreshToken) + const req = profile.formatRefreshJourneyReq({profile, opt}, refreshToken); - const {res, common} = await profile.request({profile, opt}, userAgent, req) + const {res, common} = await profile.request({profile, opt}, userAgent, req); if (!Array.isArray(res.outConL) || !res.outConL[0]) { - throw new HafasError('invalid response, expected outConL[0]', null, {}) + throw new HafasError('invalid response, expected outConL[0]', null, {}); } - const ctx = {profile, opt, common, res} + const ctx = {profile, opt, common, res}; return { journey: profile.parseJourney(ctx, res.outConL[0]), realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; // Although the DB Navigator app passes the *first* stopover of the trip // (instead of the previous one), it seems to work with the previous one as well. const journeysFromTrip = async (fromTripId, previousStopover, to, opt = {}) => { if (!isNonEmptyString(fromTripId)) { - throw new Error('fromTripId must be a non-empty string.') + throw new Error('fromTripId must be a non-empty string.'); } if ('string' === typeof to) { - to = profile.formatStation(to) + to = profile.formatStation(to); } else if (isObj(to) && (to.type === 'station' || to.type === 'stop')) { - to = profile.formatStation(to.id) + to = profile.formatStation(to.id); } else { - throw new Error('to must be a valid stop or station.') + throw new Error('to must be a valid stop or station.'); } if (!isObj(previousStopover)) { - throw new Error('previousStopover must be an object.') + throw new Error('previousStopover must be an object.'); } - let prevStop = previousStopover.stop + let prevStop = previousStopover.stop; if (isObj(prevStop)) { - prevStop = profile.formatStation(prevStop.id) + prevStop = profile.formatStation(prevStop.id); } else if ('string' === typeof prevStop) { - prevStop = profile.formatStation(prevStop) + prevStop = profile.formatStation(prevStop); } else { - throw new Error('previousStopover.stop must be a valid stop or station.') + throw new Error('previousStopover.stop must be a valid stop or station.'); } - let depAtPrevStop = previousStopover.departure || previousStopover.plannedDeparture + let depAtPrevStop = previousStopover.departure || previousStopover.plannedDeparture; if (!isNonEmptyString(depAtPrevStop)) { - throw new Error('previousStopover.(planned)departure must be a string') + throw new Error('previousStopover.(planned)departure must be a string'); } - depAtPrevStop = Date.parse(depAtPrevStop) + depAtPrevStop = Date.parse(depAtPrevStop); if (Number.isNaN(depAtPrevStop)) { - throw new Error('previousStopover.(planned)departure is invalid') + throw new Error('previousStopover.(planned)departure is invalid'); } if (depAtPrevStop > Date.now()) { - throw new Error('previousStopover.(planned)departure must be in the past') + throw new Error('previousStopover.(planned)departure must be in the past'); } opt = Object.assign({ @@ -349,29 +349,29 @@ const createClient = (profile, userAgent, opt = {}) => { subStops: true, // parse & expose sub-stops of stations? entrances: true, // parse & expose entrances of stops/stations? remarks: true, // parse & expose hints & warnings? - }, opt) + }, opt); // make clear that `departure`/`arrival`/`when` are not supported if (opt.departure) { - throw new Error('journeysFromTrip + opt.departure is not supported by HAFAS.') + throw new Error('journeysFromTrip + opt.departure is not supported by HAFAS.'); } if (opt.arrival) { - throw new Error('journeysFromTrip + opt.arrival is not supported by HAFAS.') + throw new Error('journeysFromTrip + opt.arrival is not supported by HAFAS.'); } if (opt.when) { - throw new Error('journeysFromTrip + opt.when is not supported by HAFAS.') + throw new Error('journeysFromTrip + opt.when is not supported by HAFAS.'); } const filters = [ profile.formatProductsFilter({profile}, opt.products || {}), - ] + ]; if ( opt.accessibility && profile.filters && profile.filters.accessibility && profile.filters.accessibility[opt.accessibility] ) { - filters.push(profile.filters.accessibility[opt.accessibility]) + filters.push(profile.filters.accessibility[opt.accessibility]); } // todo: support walking speed filter @@ -403,18 +403,18 @@ const createClient = (profile, userAgent, opt = {}) => { getPolyline: Boolean(opt.polylines), minChgTime: opt.transferTime, getTariff: Boolean(opt.tickets), - } + }; const {res, common} = await profile.request({profile, opt}, userAgent, { cfg: {polyEnc: 'GPA'}, meth: 'SearchOnTrip', req: query, - }) + }); if (!Array.isArray(res.outConL)) { - return [] + return []; } - const ctx = {profile, opt, common, res} + const ctx = {profile, opt, common, res}; const journeys = res.outConL .map(rawJourney => profile.parseJourney(ctx, rawJourney)) .map((journey) => { @@ -422,11 +422,11 @@ const createClient = (profile, userAgent, opt = {}) => { // stopovers of the trip, even though it should only return stopovers // between the specified `depAtPrevStop` and the arrival at the // interchange station. We slice the leg accordingly. - const fromLegI = journey.legs.findIndex(l => l.tripId === fromTripId) + const fromLegI = journey.legs.findIndex(l => l.tripId === fromTripId); if (fromLegI < 0) { - return journey + return journey; } - const fromLeg = journey.legs[fromLegI] + const fromLeg = journey.legs[fromLegI]; return { ...journey, legs: [ @@ -434,20 +434,20 @@ const createClient = (profile, userAgent, opt = {}) => { sliceLeg(fromLeg, previousStopover.stop, fromLeg.destination), ...journey.legs.slice(fromLegI + 2), ], - } - }) + }; + }); return { journeys, realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; const locations = async (query, opt = {}) => { if (!isNonEmptyString(query)) { - throw new TypeError('query must be a non-empty string.') + throw new TypeError('query must be a non-empty string.'); } opt = Object.assign({ fuzzy: true, // find only exact matches? @@ -458,26 +458,26 @@ const createClient = (profile, userAgent, opt = {}) => { subStops: true, // parse & expose sub-stops of stations? entrances: true, // parse & expose entrances of stops/stations? linesOfStops: false, // parse & expose lines at each stop/station? - }, opt) + }, opt); - const req = profile.formatLocationsReq({profile, opt}, query) + const req = profile.formatLocationsReq({profile, opt}, query); - const {res, common} = await profile.request({profile, opt}, userAgent, req) + const {res, common} = await profile.request({profile, opt}, userAgent, req); if (!res.match || !Array.isArray(res.match.locL)) { - return [] + return []; } - const ctx = {profile, opt, common, res} - return res.match.locL.map(loc => profile.parseLocation(ctx, loc)) - } + const ctx = {profile, opt, common, res}; + return res.match.locL.map(loc => profile.parseLocation(ctx, loc)); + }; const stop = async (stop, opt = {}) => { if ('object' === typeof stop) { - stop = profile.formatStation(stop.id) + stop = profile.formatStation(stop.id); } else if ('string' === typeof stop) { - stop = profile.formatStation(stop) + stop = profile.formatStation(stop); } else { - throw new TypeError('stop must be an object or a string.') + throw new TypeError('stop must be an object or a string.'); } opt = Object.assign({ @@ -485,24 +485,24 @@ const createClient = (profile, userAgent, opt = {}) => { subStops: true, // parse & expose sub-stops of stations? entrances: true, // parse & expose entrances of stops/stations? remarks: true, // parse & expose hints & warnings? - }, opt) + }, opt); - const req = profile.formatStopReq({profile, opt}, stop) + const req = profile.formatStopReq({profile, opt}, stop); - const {res, common} = await profile.request({profile, opt}, userAgent, req) + const {res, common} = await profile.request({profile, opt}, userAgent, req); if (!res || !Array.isArray(res.locL) || !res.locL[0]) { throw new HafasError('invalid response, expected locL[0]', null, { // This problem occurs on invalid input. 🙄 code: INVALID_REQUEST, - }) + }); } - const ctx = {profile, opt, res, common} - return profile.parseLocation(ctx, res.locL[0]) - } + const ctx = {profile, opt, res, common}; + return profile.parseLocation(ctx, res.locL[0]); + }; const nearby = async (location, opt = {}) => { - validateLocation(location, 'location') + validateLocation(location, 'location'); opt = Object.assign({ results: 8, // maximum number of results @@ -512,26 +512,26 @@ const createClient = (profile, userAgent, opt = {}) => { subStops: true, // parse & expose sub-stops of stations? entrances: true, // parse & expose entrances of stops/stations? linesOfStops: false, // parse & expose lines at each stop/station? - }, opt) + }, opt); - const req = profile.formatNearbyReq({profile, opt}, location) + const req = profile.formatNearbyReq({profile, opt}, location); - const {res, common} = await profile.request({profile, opt}, userAgent, req) + const {res, common} = await profile.request({profile, opt}, userAgent, req); if (!Array.isArray(res.locL)) { - return [] + return []; } // todo: parse `.dur` – walking duration? - const ctx = {profile, opt, common, res} - const results = res.locL.map(loc => profile.parseNearby(ctx, loc)) + const ctx = {profile, opt, common, res}; + const results = res.locL.map(loc => profile.parseNearby(ctx, loc)); return Number.isInteger(opt.results) ? results.slice(0, opt.results) - : results - } + : results; + }; const trip = async (id, opt = {}) => { if (!isNonEmptyString(id)) { - throw new TypeError('id must be a non-empty string.') + throw new TypeError('id must be a non-empty string.'); } opt = Object.assign({ stopovers: true, // return stations on the way? @@ -540,27 +540,27 @@ const createClient = (profile, userAgent, opt = {}) => { entrances: true, // parse & expose entrances of stops/stations? remarks: true, // parse & expose hints & warnings? scheduledDays: false, // parse & expose dates trip is valid on? - }, opt) + }, opt); - const req = profile.formatTripReq({profile, opt}, id) + const req = profile.formatTripReq({profile, opt}, id); - const {res, common} = await profile.request({profile, opt}, userAgent, req) - const ctx = {profile, opt, common, res} + const {res, common} = await profile.request({profile, opt}, userAgent, req); + const ctx = {profile, opt, common, res}; - const trip = profile.parseTrip(ctx, res.journey) + const trip = profile.parseTrip(ctx, res.journey); return { trip, realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; // todo [breaking]: rename to trips()? const tripsByName = async (lineNameOrFahrtNr = '*', opt = {}) => { if (!isNonEmptyString(lineNameOrFahrtNr)) { - throw new TypeError('lineNameOrFahrtNr must be a non-empty string.') + throw new TypeError('lineNameOrFahrtNr must be a non-empty string.'); } opt = Object.assign({ when: null, @@ -571,7 +571,7 @@ const createClient = (profile, userAgent, opt = {}) => { lineName: null, operatorNames: null, additionalFilters: [], // undocumented - }, opt) + }, opt); const req = { // fields: https://github.com/marudor/BahnhofsAbfahrten/blob/f619e754f212980261eb7e2b151cd73ba0213da8/packages/types/HAFAS/JourneyMatch.ts#L4-L23 @@ -585,33 +585,33 @@ const createClient = (profile, userAgent, opt = {}) => { // todo: `onlyRT: true` reduces the number of results, but filters recent trips 🤔 // todo: `onlyTN: true` yields a `NO_MATCH` error // todo: useAeqi - } + }; if (opt.when !== null) { - req.date = profile.formatDate(profile, new Date(opt.when)) - req.time = profile.formatTime(profile, new Date(opt.when)) + req.date = profile.formatDate(profile, new Date(opt.when)); + req.time = profile.formatTime(profile, new Date(opt.when)); } // todo: fromWhen doesn't work yet, but untilWhen does if (opt.fromWhen !== null) { - req.dateB = profile.formatDate(profile, new Date(opt.fromWhen)) - req.timeB = profile.formatTime(profile, new Date(opt.fromWhen)) + req.dateB = profile.formatDate(profile, new Date(opt.fromWhen)); + req.timeB = profile.formatTime(profile, new Date(opt.fromWhen)); } if (opt.untilWhen !== null) { - req.dateE = profile.formatDate(profile, new Date(opt.untilWhen)) - req.timeE = profile.formatTime(profile, new Date(opt.untilWhen)) + req.dateE = profile.formatDate(profile, new Date(opt.untilWhen)); + req.timeE = profile.formatTime(profile, new Date(opt.untilWhen)); } - const filter = (mode, type, value) => ({mode, type, value}) + const filter = (mode, type, value) => ({mode, type, value}); if (opt.currentlyStoppingAt !== null) { if (!isNonEmptyString(opt.currentlyStoppingAt)) { - throw new TypeError('opt.currentlyStoppingAt must be a non-empty string.') + throw new TypeError('opt.currentlyStoppingAt must be a non-empty string.'); } - req.jnyFltrL.push(filter('INC', 'STATIONS', opt.currentlyStoppingAt)) + req.jnyFltrL.push(filter('INC', 'STATIONS', opt.currentlyStoppingAt)); } if (opt.lineName !== null) { if (!isNonEmptyString(opt.lineName)) { - throw new TypeError('opt.lineName must be a non-empty string.') + throw new TypeError('opt.lineName must be a non-empty string.'); } // todo: does this target `line` or `lineId`? - req.jnyFltrL.push(filter('INC', 'LINE', opt.lineName)) + req.jnyFltrL.push(filter('INC', 'LINE', opt.lineName)); } if (opt.operatorNames !== null) { if ( @@ -619,49 +619,49 @@ const createClient = (profile, userAgent, opt = {}) => { || opt.operatorNames.length === 0 || !opt.operatorNames.every(isNonEmptyString) ) { - throw new TypeError('opt.operatorNames must be an array of non-empty strings.') + throw new TypeError('opt.operatorNames must be an array of non-empty strings.'); } // todo: is the an escaping mechanism for "," - req.jnyFltrL.push(filter('INC', 'OP', opt.operatorNames.join(','))) + req.jnyFltrL.push(filter('INC', 'OP', opt.operatorNames.join(','))); } - req.jnyFltrL = [...req.jnyFltrL, ...opt.additionalFilters] + req.jnyFltrL = [...req.jnyFltrL, ...opt.additionalFilters]; const {res, common} = await profile.request({profile, opt}, userAgent, { cfg: {polyEnc: 'GPA'}, meth: 'JourneyMatch', req, - }) + }); // todo [breaking]: catch `NO_MATCH` errors, return [] - const ctx = {profile, opt, common, res} + const ctx = {profile, opt, common, res}; - const trips = res.jnyL.map(t => profile.parseTrip(ctx, t)) + const trips = res.jnyL.map(t => profile.parseTrip(ctx, t)); return { trips, realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; const radar = async ({north, west, south, east}, opt) => { if ('number' !== typeof north) { - throw new TypeError('north must be a number.') + throw new TypeError('north must be a number.'); } if ('number' !== typeof west) { - throw new TypeError('west must be a number.') + throw new TypeError('west must be a number.'); } if ('number' !== typeof south) { - throw new TypeError('south must be a number.') + throw new TypeError('south must be a number.'); } if ('number' !== typeof east) { - throw new TypeError('east must be a number.') + throw new TypeError('east must be a number.'); } if (north <= south) { - throw new Error('north must be larger than south.') + throw new Error('north must be larger than south.'); } if (east <= west) { - throw new Error('east must be larger than west.') + throw new Error('east must be larger than west.'); } opt = Object.assign({ @@ -673,32 +673,32 @@ const createClient = (profile, userAgent, opt = {}) => { polylines: true, // return a track shape for each vehicle? subStops: true, // parse & expose sub-stops of stations? entrances: true, // parse & expose entrances of stops/stations? - }, opt || {}) - opt.when = new Date(opt.when || Date.now()) + }, opt || {}); + opt.when = new Date(opt.when || Date.now()); if (Number.isNaN(Number(opt.when))) { - throw new TypeError('opt.when is invalid') + throw new TypeError('opt.when is invalid'); } - const req = profile.formatRadarReq({profile, opt}, north, west, south, east) + const req = profile.formatRadarReq({profile, opt}, north, west, south, east); - const {res, common} = await profile.request({profile, opt}, userAgent, req) + const {res, common} = await profile.request({profile, opt}, userAgent, req); if (!Array.isArray(res.jnyL)) { - return [] + return []; } - const ctx = {profile, opt, common, res} + const ctx = {profile, opt, common, res}; - const movements = res.jnyL.map(m => profile.parseMovement(ctx, m)) + const movements = res.jnyL.map(m => profile.parseMovement(ctx, m)); return { movements, realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; const reachableFrom = async (address, opt = {}) => { - validateLocation(address, 'address') + validateLocation(address, 'address'); opt = Object.assign({ when: Date.now(), @@ -708,36 +708,36 @@ const createClient = (profile, userAgent, opt = {}) => { subStops: true, // parse & expose sub-stops of stations? entrances: true, // parse & expose entrances of stops/stations? polylines: false, // return leg shapes? - }, opt) + }, opt); if (Number.isNaN(Number(opt.when))) { - throw new TypeError('opt.when is invalid') + throw new TypeError('opt.when is invalid'); } - const req = profile.formatReachableFromReq({profile, opt}, address) + const req = profile.formatReachableFromReq({profile, opt}, address); - const {res, common} = await profile.request({profile, opt}, userAgent, req) + const {res, common} = await profile.request({profile, opt}, userAgent, req); if (!Array.isArray(res.posL)) { throw new HafasError('invalid response, expected posL[0]', null, { shouldRetry: true, - }) + }); } - const byDuration = [] - let i = 0, lastDuration = NaN + const byDuration = []; + let i = 0, lastDuration = NaN; for (const pos of sortBy(res.posL, 'dur')) { - const loc = common.locations[pos.locX] + const loc = common.locations[pos.locX]; if (!loc) { - continue + continue; } if (pos.dur !== lastDuration) { - lastDuration = pos.dur - i = byDuration.length + lastDuration = pos.dur; + i = byDuration.length; byDuration.push({ duration: pos.dur, stations: [loc], - }) + }); } else { - byDuration[i].stations.push(loc) + byDuration[i].stations.push(loc); } } @@ -746,8 +746,8 @@ const createClient = (profile, userAgent, opt = {}) => { realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; const remarks = async (opt = {}) => { opt = { @@ -758,50 +758,50 @@ const createClient = (profile, userAgent, opt = {}) => { products: null, // filter by affected products polylines: false, // return leg shapes? (not supported by all endpoints) ...opt, - } + }; if (opt.from !== null) { - opt.from = new Date(opt.from) - validateWhen(opt.from, 'opt.from') + opt.from = new Date(opt.from); + validateWhen(opt.from, 'opt.from'); } if (opt.to !== null) { - opt.to = new Date(opt.to) - validateWhen(opt.to, 'opt.to') + opt.to = new Date(opt.to); + validateWhen(opt.to, 'opt.to'); } - const req = profile.formatRemarksReq({profile, opt}) + const req = profile.formatRemarksReq({profile, opt}); const { res, common, - } = await profile.request({profile, opt}, userAgent, req) + } = await profile.request({profile, opt}, userAgent, req); - const ctx = {profile, opt, common, res} + const ctx = {profile, opt, common, res}; const remarks = (res.msgL || []) - .map(w => profile.parseWarning(ctx, w)) + .map(w => profile.parseWarning(ctx, w)); return { remarks, realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; const lines = async (query, opt = {}) => { if (!isNonEmptyString(query)) { - throw new TypeError('query must be a non-empty string.') + throw new TypeError('query must be a non-empty string.'); } - const req = profile.formatLinesReq({profile, opt}, query) + const req = profile.formatLinesReq({profile, opt}, query); const { res, common, - } = await profile.request({profile, opt}, userAgent, req) + } = await profile.request({profile, opt}, userAgent, req); if (!Array.isArray(res.lineL)) { - return [] + return []; } - const ctx = {profile, opt, common, res} + const ctx = {profile, opt, common, res}; const lines = res.lineL.map(l => { - const parseDirRef = i => (res.common.dirL[i] || {}).txt || null + const parseDirRef = i => (res.common.dirL[i] || {}).txt || null; return { ...omit(l.line, ['id', 'fahrtNr']), id: l.lineId, @@ -812,31 +812,31 @@ const createClient = (profile, userAgent, opt = {}) => { trips: Array.isArray(l.jnyL) ? l.jnyL.map(t => profile.parseTrip(ctx, t)) : null, - } - }) + }; + }); return { lines, realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; const serverInfo = async (opt = {}) => { opt = { versionInfo: true, // query HAFAS versions? ...opt, - } + }; const {res, common} = await profile.request({profile, opt}, userAgent, { meth: 'ServerInfo', req: { getVersionInfo: opt.versionInfo, }, - }) + }); - const ctx = {profile, opt, common, res} + const ctx = {profile, opt, common, res}; return { // todo: what are .serverVersion & .clientVersion? hciVersion: res.hciVersion || null, @@ -848,8 +848,8 @@ const createClient = (profile, userAgent, opt = {}) => { realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0' ? parseInt(res.planrtTS) : null, - } - } + }; + }; const client = { departures, @@ -859,35 +859,35 @@ const createClient = (profile, userAgent, opt = {}) => { stop, nearby, serverInfo, - } + }; if (profile.trip) { - client.trip = trip + client.trip = trip; } if (profile.radar) { - client.radar = radar + client.radar = radar; } if (profile.refreshJourney) { - client.refreshJourney = refreshJourney + client.refreshJourney = refreshJourney; } if (profile.journeysFromTrip) { - client.journeysFromTrip = journeysFromTrip + client.journeysFromTrip = journeysFromTrip; } if (profile.reachableFrom) { - client.reachableFrom = reachableFrom + client.reachableFrom = reachableFrom; } if (profile.tripsByName) { - client.tripsByName = tripsByName + client.tripsByName = tripsByName; } if (profile.remarks !== false) { - client.remarks = remarks + client.remarks = remarks; } if (profile.lines !== false) { - client.lines = lines + client.lines = lines; } - Object.defineProperty(client, 'profile', {value: profile}) - return client -} + Object.defineProperty(client, 'profile', {value: profile}); + return client; +}; export { createClient, -} +}; diff --git a/lib/default-profile.js b/lib/default-profile.js index 098c77435..0dff18585 100644 --- a/lib/default-profile.js +++ b/lib/default-profile.js @@ -1,60 +1,60 @@ -import {request} from '../lib/request.js' +import {request} from '../lib/request.js'; -import {formatStationBoardReq} from '../format/station-board-req.js' -import {formatLocationsReq} from '../format/locations-req.js' -import {formatStopReq} from '../format/stop-req.js' -import {formatNearbyReq} from '../format/nearby-req.js' -import {formatTripReq} from '../format/trip-req.js' -import {formatRadarReq} from '../format/radar-req.js' -import {formatReachableFromReq} from '../format/reachable-from-req.js' -import {formatRefreshJourneyReq} from '../format/refresh-journey-req.js' -import {formatRemarksReq} from '../format/remarks-req.js' -import {formatLinesReq} from '../format/lines-req.js' +import {formatStationBoardReq} from '../format/station-board-req.js'; +import {formatLocationsReq} from '../format/locations-req.js'; +import {formatStopReq} from '../format/stop-req.js'; +import {formatNearbyReq} from '../format/nearby-req.js'; +import {formatTripReq} from '../format/trip-req.js'; +import {formatRadarReq} from '../format/radar-req.js'; +import {formatReachableFromReq} from '../format/reachable-from-req.js'; +import {formatRefreshJourneyReq} from '../format/refresh-journey-req.js'; +import {formatRemarksReq} from '../format/remarks-req.js'; +import {formatLinesReq} from '../format/lines-req.js'; -import {parseDateTime} from '../parse/date-time.js' -import {parsePlatform} from '../parse/platform.js' -import {parseBitmask as parseProductsBitmask} from '../parse/products-bitmask.js' -import {parseIcon} from '../parse/icon.js' -import {parseWhen} from '../parse/when.js' -import {parsePrognosisType} from '../parse/prognosis-type.js' -import {parseScheduledDays} from '../parse/scheduled-days.js' -import {parseDeparture} from '../parse/departure.js' -import {parseArrival} from '../parse/arrival.js' -import {parseTrip} from '../parse/trip.js' -import {parseJourneyLeg} from '../parse/journey-leg.js' -import {parseJourney} from '../parse/journey.js' -import {parseLine} from '../parse/line.js' -import {parseLocation} from '../parse/location.js' -import {parseCommonData as parseCommon} from '../parse/common.js' -import {parsePolyline} from '../parse/polyline.js' -import {parseMovement} from '../parse/movement.js' -import {parseNearby} from '../parse/nearby.js' -import {parseOperator} from '../parse/operator.js' -import {parseHint} from '../parse/hint.js' -import {parseWarning} from '../parse/warning.js' -import {parseStopover} from '../parse/stopover.js' +import {parseDateTime} from '../parse/date-time.js'; +import {parsePlatform} from '../parse/platform.js'; +import {parseBitmask as parseProductsBitmask} from '../parse/products-bitmask.js'; +import {parseIcon} from '../parse/icon.js'; +import {parseWhen} from '../parse/when.js'; +import {parsePrognosisType} from '../parse/prognosis-type.js'; +import {parseScheduledDays} from '../parse/scheduled-days.js'; +import {parseDeparture} from '../parse/departure.js'; +import {parseArrival} from '../parse/arrival.js'; +import {parseTrip} from '../parse/trip.js'; +import {parseJourneyLeg} from '../parse/journey-leg.js'; +import {parseJourney} from '../parse/journey.js'; +import {parseLine} from '../parse/line.js'; +import {parseLocation} from '../parse/location.js'; +import {parseCommonData as parseCommon} from '../parse/common.js'; +import {parsePolyline} from '../parse/polyline.js'; +import {parseMovement} from '../parse/movement.js'; +import {parseNearby} from '../parse/nearby.js'; +import {parseOperator} from '../parse/operator.js'; +import {parseHint} from '../parse/hint.js'; +import {parseWarning} from '../parse/warning.js'; +import {parseStopover} from '../parse/stopover.js'; -import {formatAddress} from '../format/address.js' -import {formatCoord} from '../format/coord.js' -import {formatDate} from '../format/date.js' -import {formatLocationFilter} from '../format/location-filter.js' -import {formatProductsFilter} from '../format/products-filter.js' -import {formatPoi} from '../format/poi.js' -import {formatStation} from '../format/station.js' -import {formatTime} from '../format/time.js' -import {formatLocation} from '../format/location.js' -import {formatRectangle} from '../format/rectangle.js' -import * as filters from '../format/filters.js' +import {formatAddress} from '../format/address.js'; +import {formatCoord} from '../format/coord.js'; +import {formatDate} from '../format/date.js'; +import {formatLocationFilter} from '../format/location-filter.js'; +import {formatProductsFilter} from '../format/products-filter.js'; +import {formatPoi} from '../format/poi.js'; +import {formatStation} from '../format/station.js'; +import {formatTime} from '../format/time.js'; +import {formatLocation} from '../format/location.js'; +import {formatRectangle} from '../format/rectangle.js'; +import * as filters from '../format/filters.js'; -const DEBUG = (/(^|,)hafas-client(,|$)/).test(process.env.DEBUG || '') +const DEBUG = (/(^|,)hafas-client(,|$)/).test(process.env.DEBUG || ''); const logRequest = DEBUG ? (_, req, reqId) => console.error(String(req.body)) - : () => {} + : () => {}; const logResponse = DEBUG ? (_, res, body, reqId) => console.error(body) - : () => {} + : () => {}; -const id = (ctx, x) => x +const id = (ctx, x) => x; const defaultProfile = { request, @@ -133,8 +133,8 @@ const defaultProfile = { // `remarks()` method: support for `getPolyline` field? remarksGetPolyline: true, // `remarks()` method: support for `getPolyline` field? lines: true, -} +}; export { defaultProfile, -} +}; diff --git a/lib/errors.js b/lib/errors.js index 0960ecadf..318190702 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -1,59 +1,59 @@ -const ACCESS_DENIED = 'ACCESS_DENIED' -const INVALID_REQUEST = 'INVALID_REQUEST' -const NOT_FOUND = 'NOT_FOUND' -const SERVER_ERROR = 'SERVER_ERROR' +const ACCESS_DENIED = 'ACCESS_DENIED'; +const INVALID_REQUEST = 'INVALID_REQUEST'; +const NOT_FOUND = 'NOT_FOUND'; +const SERVER_ERROR = 'SERVER_ERROR'; class HafasError extends Error { constructor (cleanMessage, hafasCode, props) { const msg = hafasCode ? hafasCode + ': ' + cleanMessage - : cleanMessage - super(msg) + : cleanMessage; + super(msg); // generic props - this.isHafasError = true + this.isHafasError = true; // error-specific props - this.code = null + this.code = null; // By default, we take the blame, unless we know for sure. - this.isCausedByServer = false - this.hafasCode = hafasCode - Object.assign(this, props) + this.isCausedByServer = false; + this.hafasCode = hafasCode; + Object.assign(this, props); - return this + return this; } } class HafasAccessDeniedError extends HafasError { constructor (cleanMessage, hafasCode, props) { - super(cleanMessage, hafasCode, props) - this.code = ACCESS_DENIED - return this + super(cleanMessage, hafasCode, props); + this.code = ACCESS_DENIED; + return this; } } class HafasInvalidRequestError extends HafasError { constructor (cleanMessage, hafasCode, props) { - super(cleanMessage, hafasCode, props) - this.code = INVALID_REQUEST - return this + super(cleanMessage, hafasCode, props); + this.code = INVALID_REQUEST; + return this; } } class HafasNotFoundError extends HafasError { constructor (cleanMessage, hafasCode, props) { - super(cleanMessage, hafasCode, props) - this.code = NOT_FOUND - return this + super(cleanMessage, hafasCode, props); + this.code = NOT_FOUND; + return this; } } class HafasServerError extends HafasError { constructor (cleanMessage, hafasCode, props) { - super(cleanMessage, hafasCode, props) - this.code = SERVER_ERROR - this.isCausedByServer = true - return this + super(cleanMessage, hafasCode, props); + this.code = SERVER_ERROR; + this.isCausedByServer = true; + return this; } } @@ -286,7 +286,7 @@ const byErrorCode = Object.assign(Object.create(null), { shouldRetry: true, }, }, -}) +}); export { ACCESS_DENIED, @@ -299,4 +299,4 @@ export { HafasNotFoundError, HafasServerError, byErrorCode, -} +}; diff --git a/lib/find-in-tree.js b/lib/find-in-tree.js index ebe0af414..b89097343 100644 --- a/lib/find-in-tree.js +++ b/lib/find-in-tree.js @@ -1,23 +1,23 @@ -import objectScan from 'object-scan' +import objectScan from 'object-scan'; const createFindInTree = (needles) => { const scanner = objectScan(needles, { filterFn: ({value, parents, matchedBy, context}) => { matchedBy.forEach((needle) => { - context[needle].push([value, parents]) - }) + context[needle].push([value, parents]); + }); }, - }) + }); return (haystack) => { - const context = Object.create(null) + const context = Object.create(null); needles.forEach((needle) => { - context[needle] = [] - }) - return scanner(haystack, context) - } -} + context[needle] = []; + }); + return scanner(haystack, context); + }; +}; export { createFindInTree, -} +}; diff --git a/lib/luxon-timezones.js b/lib/luxon-timezones.js index 39027dcd6..0c127b64b 100644 --- a/lib/luxon-timezones.js +++ b/lib/luxon-timezones.js @@ -1,6 +1,6 @@ // hafas-client profile -> luxon.IANAZone -const luxonIANAZonesByProfile = new WeakMap() +const luxonIANAZonesByProfile = new WeakMap(); export { luxonIANAZonesByProfile, -} +}; diff --git a/lib/profile-hooks.js b/lib/profile-hooks.js index 6668d9f9a..e06bf3f18 100644 --- a/lib/profile-hooks.js +++ b/lib/profile-hooks.js @@ -14,10 +14,10 @@ const parseHook = (oldParse, newParse) => { return newParse({ ...ctx, parsed: oldParse({...ctx, parsed: {}}, ...args), - }, ...args) - } -} + }, ...args); + }; +}; export { parseHook, -} +}; diff --git a/lib/request.js b/lib/request.js index 760aa37dc..ff65e91e3 100644 --- a/lib/request.js +++ b/lib/request.js @@ -1,80 +1,80 @@ -import ProxyAgent from 'https-proxy-agent' -import {isIP} from 'net' -import {Agent as HttpsAgent} from 'https' -import roundRobin from '@derhuerst/round-robin-scheduler' -import {randomBytes} from 'crypto' -import createHash from 'create-hash' -import {Buffer} from 'node:buffer' -import {stringify} from 'qs' -import {Request, fetch} from 'cross-fetch' -import {parse as parseContentType} from 'content-type' -import {HafasError, byErrorCode} from './errors.js' - -const proxyAddress = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || null -const localAddresses = process.env.LOCAL_ADDRESS || null +import ProxyAgent from 'https-proxy-agent'; +import {isIP} from 'net'; +import {Agent as HttpsAgent} from 'https'; +import roundRobin from '@derhuerst/round-robin-scheduler'; +import {randomBytes} from 'crypto'; +import createHash from 'create-hash'; +import {Buffer} from 'node:buffer'; +import {stringify} from 'qs'; +import {Request, fetch} from 'cross-fetch'; +import {parse as parseContentType} from 'content-type'; +import {HafasError, byErrorCode} from './errors.js'; + +const proxyAddress = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || null; +const localAddresses = process.env.LOCAL_ADDRESS || null; if (proxyAddress && localAddresses) { - console.error('Both env vars HTTPS_PROXY/HTTP_PROXY and LOCAL_ADDRESS are not supported.') - process.exit(1) + console.error('Both env vars HTTPS_PROXY/HTTP_PROXY and LOCAL_ADDRESS are not supported.'); + process.exit(1); } const plainAgent = new HttpsAgent({ keepAlive: true, -}) -let getAgent = () => plainAgent +}); +let getAgent = () => plainAgent; if (proxyAddress) { const agent = new ProxyAgent(proxyAddress, { keepAlive: true, keepAliveMsecs: 10 * 1000, // 10s - }) - getAgent = () => agent + }); + getAgent = () => agent; } else if (localAddresses) { const agents = process.env.LOCAL_ADDRESS.split(',') .map((addr) => { - const family = isIP(addr) + const family = isIP(addr); if (family === 0) { - throw new Error('invalid local address:' + addr) + throw new Error('invalid local address:' + addr); } return new HttpsAgent({ localAddress: addr, family, keepAlive: true, - }) - }) - const pool = roundRobin(agents) - getAgent = () => pool.get() + }); + }); + const pool = roundRobin(agents); + getAgent = () => pool.get(); } const id = randomBytes(3) - .toString('hex') + .toString('hex'); const randomizeUserAgent = (userAgent) => { - let ua = userAgent + let ua = userAgent; for ( let i = Math.round(5 + Math.random() * 5); i < ua.length; i += Math.round(5 + Math.random() * 5) ) { - ua = ua.slice(0, i) + id + ua.slice(i) - i += id.length + ua = ua.slice(0, i) + id + ua.slice(i); + i += id.length; } - return ua -} + return ua; +}; const md5 = input => createHash('md5') .update(input) - .digest() + .digest(); const checkIfResponseIsOk = (_) => { const { body, errProps: baseErrProps, - } = _ + } = _; const errProps = { ...baseErrProps, - } + }; if (body.id) { - errProps.hafasResponseId = body.id + errProps.hafasResponseId = body.id; } // Because we want more accurate stack traces, we don't construct the error here, @@ -82,37 +82,37 @@ const checkIfResponseIsOk = (_) => { const getError = (_) => { // mutating here is ugly but pragmatic if (_.errTxt) { - errProps.hafasMessage = _.errTxt + errProps.hafasMessage = _.errTxt; } if (_.errTxtOut) { - errProps.hafasDescription = _.errTxtOut + errProps.hafasDescription = _.errTxtOut; } if (_.err in byErrorCode) { - return byErrorCode[_.err] + return byErrorCode[_.err]; } return { Error: HafasError, message: body.errTxt || 'unknown error', props: {}, - } - } + }; + }; if (body.err && body.err !== 'OK') { - const {Error: HafasError, message, props} = getError(body) - throw new HafasError(message, body.err, {...errProps, ...props}) + const {Error: HafasError, message, props} = getError(body); + throw new HafasError(message, body.err, {...errProps, ...props}); } if (!body.svcResL || !body.svcResL[0]) { - throw new HafasError('invalid/unsupported response structure', null, errProps) + throw new HafasError('invalid/unsupported response structure', null, errProps); } if (body.svcResL[0].err !== 'OK') { - const {Error: HafasError, message, props} = getError(body.svcResL[0]) - throw new HafasError(message, body.svcResL[0].err, {...errProps, ...props}) + const {Error: HafasError, message, props} = getError(body.svcResL[0]); + throw new HafasError(message, body.svcResL[0].err, {...errProps, ...props}); } -} +}; const request = async (ctx, userAgent, reqData) => { - const {profile, opt} = ctx + const {profile, opt} = ctx; const rawReqBody = profile.transformReqBody(ctx, { // todo: is it `eng` actually? @@ -124,7 +124,7 @@ const request = async (ctx, userAgent, reqData) => { ext: profile.ext, // ? ver: profile.ver, // HAFAS protocol version auth: profile.auth, // static authentication - }) + }); const req = profile.transformReq(ctx, { agent: getAgent(), @@ -142,39 +142,39 @@ const request = async (ctx, userAgent, reqData) => { }, redirect: 'follow', query: {}, - }) + }); if (profile.addChecksum || profile.addMicMac) { if (!Buffer.isBuffer(profile.salt) && 'string' !== typeof profile.salt) { - throw new TypeError('profile.salt must be a Buffer or a string.') + throw new TypeError('profile.salt must be a Buffer or a string.'); } // Buffer.from(buf, 'hex') just returns buf - const salt = Buffer.from(profile.salt, 'hex') + const salt = Buffer.from(profile.salt, 'hex'); if (profile.addChecksum) { const checksum = md5(Buffer.concat([ Buffer.from(req.body, 'utf8'), salt, - ])) - req.query.checksum = checksum.toString('hex') + ])); + req.query.checksum = checksum.toString('hex'); } if (profile.addMicMac) { - const mic = md5(Buffer.from(req.body, 'utf8')) - req.query.mic = mic.toString('hex') + const mic = md5(Buffer.from(req.body, 'utf8')); + req.query.mic = mic.toString('hex'); - const micAsHex = Buffer.from(mic.toString('hex'), 'utf8') - const mac = md5(Buffer.concat([micAsHex, salt])) - req.query.mac = mac.toString('hex') + const micAsHex = Buffer.from(mic.toString('hex'), 'utf8'); + const mac = md5(Buffer.concat([micAsHex, salt])); + req.query.mac = mac.toString('hex'); } } const reqId = randomBytes(3) - .toString('hex') - const url = profile.endpoint + '?' + stringify(req.query) - const fetchReq = new Request(url, req) - profile.logRequest(ctx, fetchReq, reqId) + .toString('hex'); + const url = profile.endpoint + '?' + stringify(req.query); + const fetchReq = new Request(url, req); + profile.logRequest(ctx, fetchReq, reqId); - const res = await fetch(url, req) + const res = await fetch(url, req); const errProps = { // todo [breaking]: assign as non-enumerable property @@ -182,40 +182,40 @@ const request = async (ctx, userAgent, reqData) => { // todo [breaking]: assign as non-enumerable property response: res, url, - } + }; if (!res.ok) { // todo [breaking]: make this a FetchError or a HafasClientError? - const err = new Error(res.statusText) - Object.assign(err, errProps) - throw err + const err = new Error(res.statusText); + Object.assign(err, errProps); + throw err; } - let cType = res.headers.get('content-type') + let cType = res.headers.get('content-type'); if (cType) { - const {type} = parseContentType(cType) + const {type} = parseContentType(cType); if (type !== 'application/json') { - throw new HafasError('invalid/unsupported response content-type: ' + cType, null, errProps) + throw new HafasError('invalid/unsupported response content-type: ' + cType, null, errProps); } } - const body = await res.text() - profile.logResponse(ctx, res, body, reqId) + const body = await res.text(); + profile.logResponse(ctx, res, body, reqId); - const b = JSON.parse(body) + const b = JSON.parse(body); checkIfResponseIsOk({ body: b, errProps, - }) + }); - const svcRes = b.svcResL[0].res + const svcRes = b.svcResL[0].res; return { res: svcRes, common: profile.parseCommon({...ctx, res: svcRes}), - } -} + }; +}; export { checkIfResponseIsOk, request, -} +}; diff --git a/lib/slice-leg.js b/lib/slice-leg.js index 81d51fb93..94e3f4f51 100644 --- a/lib/slice-leg.js +++ b/lib/slice-leg.js @@ -1,63 +1,63 @@ const findById = (needle) => { - const needleStopId = needle.id + const needleStopId = needle.id; const needleStationId = needle.station ? needle.station.id - : null + : null; return (stop) => { if (needleStopId === stop.id) { - return true + return true; } const stationId = stop.station ? stop.station.id - : null + : null; if (needleStationId && stationId && needleStationId === stationId) { - return true + return true; } // todo: `needleStationId === stop.id`? `needleStopId === stationId`? - return false - } -} + return false; + }; +}; const sliceLeg = (leg, from, to) => { if (!Array.isArray(leg.stopovers)) { - throw new Error('leg.stopovers must be an array.') + throw new Error('leg.stopovers must be an array.'); } - const stops = leg.stopovers.map(st => st.stop) - const fromI = stops.findIndex(findById(from)) + const stops = leg.stopovers.map(st => st.stop); + const fromI = stops.findIndex(findById(from)); if (fromI === -1) { - throw new Error('from not found in stopovers') + throw new Error('from not found in stopovers'); } - const fromStopover = leg.stopovers[fromI] + const fromStopover = leg.stopovers[fromI]; - const toI = stops.findIndex(findById(to)) + const toI = stops.findIndex(findById(to)); if (toI === -1) { - throw new Error('to not found in stopovers') + throw new Error('to not found in stopovers'); } - const toStopover = leg.stopovers[toI] + const toStopover = leg.stopovers[toI]; if (fromI === 0 && toI === leg.stopovers.length - 1) { - return leg + return leg; } - const newLeg = Object.assign({}, leg) - newLeg.stopovers = leg.stopovers.slice(fromI, toI + 1) + const newLeg = Object.assign({}, leg); + newLeg.stopovers = leg.stopovers.slice(fromI, toI + 1); - newLeg.origin = fromStopover.stop - newLeg.departure = fromStopover.departure - newLeg.departureDelay = fromStopover.departureDelay - newLeg.scheduledDeparture = fromStopover.scheduledDeparture - newLeg.departurePlatform = fromStopover.departurePlatform + newLeg.origin = fromStopover.stop; + newLeg.departure = fromStopover.departure; + newLeg.departureDelay = fromStopover.departureDelay; + newLeg.scheduledDeparture = fromStopover.scheduledDeparture; + newLeg.departurePlatform = fromStopover.departurePlatform; - newLeg.destination = toStopover.stop - newLeg.arrival = toStopover.arrival - newLeg.arrivalDelay = toStopover.arrivalDelay - newLeg.scheduledArrival = toStopover.scheduledArrival - newLeg.arrivalPlatform = toStopover.arrivalPlatform + newLeg.destination = toStopover.stop; + newLeg.arrival = toStopover.arrival; + newLeg.arrivalDelay = toStopover.arrivalDelay; + newLeg.scheduledArrival = toStopover.scheduledArrival; + newLeg.arrivalPlatform = toStopover.arrivalPlatform; - return newLeg -} + return newLeg; +}; export { sliceLeg, -} +}; diff --git a/lib/validate-profile.js b/lib/validate-profile.js index 552ddecbf..468d01bb5 100644 --- a/lib/validate-profile.js +++ b/lib/validate-profile.js @@ -44,54 +44,54 @@ const types = { formatTime: 'function', formatLocation: 'function', formatRectangle: 'function', -} +}; const validateProfile = (profile) => { for (let key of Object.keys(types)) { - const type = types[key] + const type = types[key]; if (type === 'array') { if (!Array.isArray(profile[key])) { - throw new TypeError(`profile.${key} must be an array.`) + throw new TypeError(`profile.${key} must be an array.`); } } else if (type !== typeof profile[key]) { - throw new TypeError(`profile.${key} must be a ${type}.`) + throw new TypeError(`profile.${key} must be a ${type}.`); } if (type === 'object' && profile[key] === null) { - throw new TypeError(`profile.${key} must not be null.`) + throw new TypeError(`profile.${key} must not be null.`); } } if (!Array.isArray(profile.products)) { - throw new TypeError('profile.products must be an array.') + throw new TypeError('profile.products must be an array.'); } if (profile.products.length === 0) { - throw new Error('profile.products is empty.') + throw new Error('profile.products is empty.'); } for (let product of profile.products) { if ('string' !== typeof product.id) { - throw new TypeError('profile.products[].id must be a string.') + throw new TypeError('profile.products[].id must be a string.'); } if ('boolean' !== typeof product.default) { - throw new TypeError('profile.products[].default must be a boolean.') + throw new TypeError('profile.products[].default must be a boolean.'); } if (!Array.isArray(product.bitmasks)) { - throw new TypeError(product.id + '.bitmasks must be an array.') + throw new TypeError(product.id + '.bitmasks must be an array.'); } for (let bitmask of product.bitmasks) { if ('number' !== typeof bitmask) { - throw new TypeError(product.id + '.bitmasks[] must be a number.') + throw new TypeError(product.id + '.bitmasks[] must be a number.'); } } } if ('trip' in profile && 'boolean' !== typeof profile.trip) { - throw new Error('profile.trip must be a boolean.') + throw new Error('profile.trip must be a boolean.'); } if ('journeyLeg' in profile) { - throw new Error('profile.journeyLeg has been removed. Use profile.trip.') + throw new Error('profile.journeyLeg has been removed. Use profile.trip.'); } -} +}; export { validateProfile, -} +}; diff --git a/p/avv/index.js b/p/avv/index.js index d79592b31..7abc5f059 100644 --- a/p/avv/index.js +++ b/p/avv/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'regional-train', @@ -82,7 +82,7 @@ const products = [{ name: 'Fähre', short: 'Fähre', default: true, -}] +}]; const profile = { ...baseProfile, @@ -98,8 +98,8 @@ const profile = { reachableFrom: true, remarks: true, remarksGetPolyline: false, -} +}; export { profile, -} +}; diff --git a/p/bart/index.js b/p/bart/index.js index 191e4f902..6ab930b9e 100644 --- a/p/bart/index.js +++ b/p/bart/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'bart', @@ -47,7 +47,7 @@ const products = [{ name: 'cable car', short: 'cable car', default: true, -}] +}]; const profile = { ...baseProfile, @@ -62,8 +62,8 @@ const profile = { reachableFrom: true, refreshJourneyUseOutReconL: true, -} +}; export { profile, -} +}; diff --git a/p/bls/index.js b/p/bls/index.js index ddf63b1b6..86651ff57 100644 --- a/p/bls/index.js +++ b/p/bls/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'ice', @@ -75,7 +75,7 @@ const products = [{ name: 'Autoverlad', short: 'Autoverlad', default: true, -}] +}]; const profile = { ...baseProfile, @@ -89,8 +89,8 @@ const profile = { radar: true, refreshJourneyUseOutReconL: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/bvg/index.js b/p/bvg/index.js index 914bde810..94b796668 100644 --- a/p/bvg/index.js +++ b/p/bvg/index.js @@ -1,99 +1,99 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import {parseHook} from '../../lib/profile-hooks.js' +import {parseHook} from '../../lib/profile-hooks.js'; -import {parseAndAddLocationDHID} from '../vbb/parse-loc-dhid.js' +import {parseAndAddLocationDHID} from '../vbb/parse-loc-dhid.js'; -import {parseLocation as _parseLocation} from '../../parse/location.js' -import {parseArrival as _parseArrival} from '../../parse/arrival.js' -import {parseDeparture as _parseDeparture} from '../../parse/departure.js' -import {parseStopover as _parseStopover} from '../../parse/stopover.js' -import {parseJourneyLeg as _parseJourneyLeg} from '../../parse/journey-leg.js' +import {parseLocation as _parseLocation} from '../../parse/location.js'; +import {parseArrival as _parseArrival} from '../../parse/arrival.js'; +import {parseDeparture as _parseDeparture} from '../../parse/departure.js'; +import {parseStopover as _parseStopover} from '../../parse/stopover.js'; +import {parseJourneyLeg as _parseJourneyLeg} from '../../parse/journey-leg.js'; -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; // todo: there's also a referenced icon `{"res":"occup_fig_{low,mid}"}` const addOccupancy = (item, occupancyCodes) => { const remIdx = (item.remarks || []) - .findIndex(r => r.code && occupancyCodes.has(r.code)) + .findIndex(r => r.code && occupancyCodes.has(r.code)); if (remIdx < 0) { - return + return; } - const rem = item.remarks[remIdx] + const rem = item.remarks[remIdx]; - item.occupancy = occupancyCodes.get(rem.code) + item.occupancy = occupancyCodes.get(rem.code); item.remarks = [ ...item.remarks.slice(0, remIdx), ...item.remarks.slice(remIdx + 1), - ] -} + ]; +}; const stopoverOccupancyCodes = new Map([ ['text.occup.loc.max.11', 'low'], ['text.occup.loc.max.12', 'medium'], ['text.occup.loc.max.13', 'high'], -]) +]); const journeyLegOccupancyCodes = new Map([ ['text.occup.jny.max.11', 'low'], ['text.occup.jny.max.12', 'medium'], ['text.occup.jny.max.13', 'high'], -]) +]); const parseLocation = ({parsed}, l) => { - parseAndAddLocationDHID(parsed, l) - return parsed -} + parseAndAddLocationDHID(parsed, l); + return parsed; +}; // todo: S45, S46? -const ringbahnClockwise = /^ringbahn s\s?41$/i -const ringbahnAnticlockwise = /^ringbahn s\s?42$/i +const ringbahnClockwise = /^ringbahn s\s?41$/i; +const ringbahnAnticlockwise = /^ringbahn s\s?42$/i; const parseDepartureRenameRingbahn = ({parsed}, dep) => { if (parsed.line && parsed.line.product === 'suburban') { - const d = parsed.direction && parsed.direction.trim() + const d = parsed.direction && parsed.direction.trim(); if (ringbahnClockwise.test(d)) { - parsed.direction = 'Ringbahn S41 ⟳' + parsed.direction = 'Ringbahn S41 ⟳'; } else if (ringbahnAnticlockwise.test(d)) { - parsed.direction = 'Ringbahn S42 ⟲' + parsed.direction = 'Ringbahn S42 ⟲'; } } - return parsed -} + return parsed; +}; const parseArrivalRenameRingbahn = ({parsed}, arr) => { if (parsed.line && parsed.line.product === 'suburban') { - const p = parsed.provenance && parsed.provenance.trim() + const p = parsed.provenance && parsed.provenance.trim(); if (ringbahnClockwise.test(p)) { - parsed.provenance = 'Ringbahn S41 ⟳' + parsed.provenance = 'Ringbahn S41 ⟳'; } else if (ringbahnAnticlockwise.test(p)) { - parsed.provenance = 'Ringbahn S42 ⟲' + parsed.provenance = 'Ringbahn S42 ⟲'; } } - return parsed -} + return parsed; +}; const parseArrDepWithOccupancy = ({parsed}, d) => { - addOccupancy(parsed, stopoverOccupancyCodes) - return parsed -} + addOccupancy(parsed, stopoverOccupancyCodes); + return parsed; +}; const parseStopoverWithOccupancy = ({parsed}, st, date) => { - addOccupancy(parsed, stopoverOccupancyCodes) - return parsed -} + addOccupancy(parsed, stopoverOccupancyCodes); + return parsed; +}; const parseJourneyLegWithBerlkönig = (ctx, leg, date) => { if (leg.type === 'KISS') { - const icon = ctx.common.icons[leg.icoX] + const icon = ctx.common.icons[leg.icoX]; if (icon && icon.type === 'prod_berl') { const res = _parseJourneyLeg(ctx, { ...leg, type: 'WALK', - }, date) - delete res.walking + }, date); + delete res.walking; - const mcp = leg.dep.mcp || {} - const mcpData = mcp.mcpData || {} + const mcp = leg.dep.mcp || {}; + const mcpData = mcp.mcpData || {}; // todo: mcp.lid // todo: mcpData.occupancy, mcpData.type // todo: journey.trfRes.bkgData @@ -106,33 +106,33 @@ const parseJourneyLegWithBerlkönig = (ctx, leg, date) => { mode: 'taxi', product: 'berlkoenig', // todo: operator - } - return res + }; + return res; } } - return _parseJourneyLeg(ctx, leg, date) -} + return _parseJourneyLeg(ctx, leg, date); +}; const parseJourneyLegWithOccupancy = ({parsed}, leg, date) => { if (leg.type === 'JNY') { - addOccupancy(parsed, journeyLegOccupancyCodes) + addOccupancy(parsed, journeyLegOccupancyCodes); } - return parsed -} + return parsed; +}; // use the Berlkönig ride sharing service? // todo: https://github.com/alexander-albers/tripkit/issues/26#issuecomment-825437320 const requestJourneysWithBerlkoenig = ({opt}, query) => { if ('numF' in query && opt.berlkoenig) { // todo: check if this is still true - throw new Error('The `berlkoenig` and `results` options are mutually exclusive.') + throw new Error('The `berlkoenig` and `results` options are mutually exclusive.'); } - query.jnyFltrL.push({type: 'GROUP', mode: 'INC', value: 'OEV'}) + query.jnyFltrL.push({type: 'GROUP', mode: 'INC', value: 'OEV'}); if (opt.berlkoenig) { - query.jnyFltrL.push({type: 'GROUP', mode: 'INC', value: 'BERLKOENIG'}) + query.jnyFltrL.push({type: 'GROUP', mode: 'INC', value: 'BERLKOENIG'}); } - query.gisFltrL = [{meta: 'foot_speed_normal', type: 'M', mode: 'FB'}] - return query -} + query.gisFltrL = [{meta: 'foot_speed_normal', type: 'M', mode: 'FB'}]; + return query; +}; // todo: adapt/extend `vbb-parse-ticket` to support the BVG markup @@ -165,8 +165,8 @@ const profile = { radar: true, refreshJourney: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/bvg/products.js b/p/bvg/products.js index bf005ebe1..7565a0190 100644 --- a/p/bvg/products.js +++ b/p/bvg/products.js @@ -55,8 +55,8 @@ const products = [ short: 'R', default: true, }, -] +]; export { products, -} +}; diff --git a/p/cfl/index.js b/p/cfl/index.js index e8e380b29..815079519 100644 --- a/p/cfl/index.js +++ b/p/cfl/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -19,8 +19,8 @@ const profile = { radar: true, reachableFrom: true, remarksGetPolyline: false, -} +}; export { profile, -} +}; diff --git a/p/cfl/products.js b/p/cfl/products.js index 51b9aba8b..8ace308c8 100644 --- a/p/cfl/products.js +++ b/p/cfl/products.js @@ -40,8 +40,8 @@ const products = [ short: 'Fun', // abbreviation for funicular? default: true, }, -] +]; export { products, -} +}; diff --git a/p/cmta/index.js b/p/cmta/index.js index 37947829d..683a719fd 100644 --- a/p/cmta/index.js +++ b/p/cmta/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -19,8 +19,8 @@ const profile = { refreshJourney: true, reachableFrom: true, remarks: true, // `.svcResL[0].res.msgL[]` is missing though 🤔 -} +}; export { profile, -} +}; diff --git a/p/cmta/products.js b/p/cmta/products.js index 3ba7f6f83..877642b72 100644 --- a/p/cmta/products.js +++ b/p/cmta/products.js @@ -23,8 +23,8 @@ const products = [ short: 'M', default: true, }, -] +]; export { products, -} +}; diff --git a/p/dart/index.js b/p/dart/index.js index a99faccfe..e8c003aab 100644 --- a/p/dart/index.js +++ b/p/dart/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'bus', @@ -12,7 +12,7 @@ const products = [{ name: 'Bus', short: 'Bus', default: true, -}] +}]; const profile = { ...baseProfile, @@ -25,8 +25,8 @@ const profile = { trip: true, reachableFrom: true, radar: true, -} +}; export { profile, -} +}; diff --git a/p/db-busradar-nrw/index.js b/p/db-busradar-nrw/index.js index e7703aac3..c029c5431 100644 --- a/p/db-busradar-nrw/index.js +++ b/p/db-busradar-nrw/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); // DB Busradar NRW app does not allow selecting specific modes of transport to filter results, // so the bitmasks had to be determined by querying some stations and looking at the results.. @@ -76,7 +76,7 @@ const products = [ short: 'AST', default: true, }, -] +]; const profile = { ...baseProfile, @@ -91,8 +91,8 @@ const profile = { radar: true, remarks: true, // `.svcResL[0].res.msgL[]` is missing though 🤔 lines: false, // `.svcResL[0].res.lineL[]` is missing 🤔 -} +}; export { profile, -} +}; diff --git a/p/db/ageGroup.js b/p/db/ageGroup.js index 77620509b..ad79638a3 100644 --- a/p/db/ageGroup.js +++ b/p/db/ageGroup.js @@ -11,29 +11,29 @@ const ageGroup = { ADULT: 65, SENIOR: Infinity, }, -} +}; const ageGroupFromAge = (age) => { - const {upperBoundOf} = ageGroup + const {upperBoundOf} = ageGroup; if (age < upperBoundOf.BABY) { - return ageGroup.BABY + return ageGroup.BABY; } if (age < upperBoundOf.CHILD) { - return ageGroup.CHILD + return ageGroup.CHILD; } if (age < upperBoundOf.YOUNG) { - return ageGroup.YOUNG + return ageGroup.YOUNG; } if (age < upperBoundOf.ADULT) { - return ageGroup.ADULT + return ageGroup.ADULT; } if (age < upperBoundOf.SENIOR) { - return ageGroup.SENIOR + return ageGroup.SENIOR; } - throw new TypeError(`Invalid age '${age}'`) -} + throw new TypeError(`Invalid age '${age}'`); +}; export { ageGroup, ageGroupFromAge, -} +}; diff --git a/p/db/index.js b/p/db/index.js index 27d7d2964..eaba8da55 100644 --- a/p/db/index.js +++ b/p/db/index.js @@ -1,72 +1,72 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) - -import trim from 'lodash/trim.js' -import uniqBy from 'lodash/uniqBy.js' -import slugg from 'slugg' -import without from 'lodash/without.js' -import {parseHook} from '../../lib/profile-hooks.js' - -import {parseJourney as _parseJourney} from '../../parse/journey.js' -import {parseJourneyLeg as _parseJourneyLeg} from '../../parse/journey-leg.js' -import {parseLine as _parseLine} from '../../parse/line.js' -import {parseArrival as _parseArrival} from '../../parse/arrival.js' -import {parseDeparture as _parseDeparture} from '../../parse/departure.js' -import {parseHint as _parseHint} from '../../parse/hint.js' -import {parseLocation as _parseLocation} from '../../parse/location.js' -import {formatStation as _formatStation} from '../../format/station.js' -import {bike} from '../../format/filters.js' - -const baseProfile = require('./base.json') -import {products} from './products.js' -import {formatLoyaltyCard} from './loyalty-cards.js' -import {ageGroup, ageGroupFromAge} from './ageGroup.js' -import {routingModes} from './routing-modes.js' +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); + +import trim from 'lodash/trim.js'; +import uniqBy from 'lodash/uniqBy.js'; +import slugg from 'slugg'; +import without from 'lodash/without.js'; +import {parseHook} from '../../lib/profile-hooks.js'; + +import {parseJourney as _parseJourney} from '../../parse/journey.js'; +import {parseJourneyLeg as _parseJourneyLeg} from '../../parse/journey-leg.js'; +import {parseLine as _parseLine} from '../../parse/line.js'; +import {parseArrival as _parseArrival} from '../../parse/arrival.js'; +import {parseDeparture as _parseDeparture} from '../../parse/departure.js'; +import {parseHint as _parseHint} from '../../parse/hint.js'; +import {parseLocation as _parseLocation} from '../../parse/location.js'; +import {formatStation as _formatStation} from '../../format/station.js'; +import {bike} from '../../format/filters.js'; + +const baseProfile = require('./base.json'); +import {products} from './products.js'; +import {formatLoyaltyCard} from './loyalty-cards.js'; +import {ageGroup, ageGroupFromAge} from './ageGroup.js'; +import {routingModes} from './routing-modes.js'; const transformReqBody = (ctx, body) => { - const req = body.svcReqL[0] || {} + const req = body.svcReqL[0] || {}; // see https://pastebin.com/qZ9WS3Cx const rtMode = 'routingMode' in ctx.opt ? ctx.opt.routingMode - : routingModes.REALTIME + : routingModes.REALTIME; req.cfg = { ...req.cfg, rtMode, - } + }; - return body -} + return body; +}; const transformReq = (ctx, req) => { - const body = JSON.parse(req.body) + const body = JSON.parse(req.body); // stop() a.k.a. LocDetails seems broken with ver >1.16, all other methods work if (body.svcReqL[0].meth === 'LocDetails') { req.body = JSON.stringify({ ...body, ver: '1.16', - }) + }); } - return req -} + return req; +}; const slices = (n, arr) => { - const initialState = {slices: [], count: Infinity} + const initialState = {slices: [], count: Infinity}; return arr.reduce(({slices, count}, item) => { if (count >= n) { - slices.push([item]) - count = 1 + slices.push([item]); + count = 1; } else { - slices[slices.length - 1].push(item) - count++ + slices[slices.length - 1].push(item); + count++; } - return {slices, count} - }, initialState).slices -} + return {slices, count}; + }, initialState).slices; +}; const parseGrid = (g) => { // todo: g.type, e.g. `S` @@ -84,8 +84,8 @@ const parseGrid = (g) => { || Array.isArray(item.remarkRefs) && item.remarkRefs[0] && item.remarkRefs[0].hint || {}, )), - } -} + }; +}; const ausstattungKeys = Object.assign(Object.create(null), { '3-s-zentrale': '3SZentrale', @@ -98,117 +98,117 @@ const ausstattungKeys = Object.assign(Object.create(null), { 'stufenfreier-zugang': 'stepFreeAccess', 'ein-umsteigehilfe': 'boardingAid', 'taxi-am-bahnhof': 'taxis', -}) +}); const parseAusstattungVal = (val) => { - val = val.toLowerCase() + val = val.toLowerCase(); return val === 'ja' ? true : val === 'nein' ? false - : val -} + : val; +}; const parseAusstattungGrid = (g) => { // filter duplicate hint rows - const rows = uniqBy(g.rows, ([key, val]) => key + ':' + val) + const rows = uniqBy(g.rows, ([key, val]) => key + ':' + val); - const res = {} - Object.defineProperty(res, 'raw', {value: rows}) + const res = {}; + Object.defineProperty(res, 'raw', {value: rows}); for (let [key, val] of rows) { - key = ausstattungKeys[slugg(key)] + key = ausstattungKeys[slugg(key)]; if (key) { - res[key] = parseAusstattungVal(val) + res[key] = parseAusstattungVal(val); } } - return res -} + return res; +}; const parseReisezentrumÖffnungszeiten = (g) => { - const res = {} + const res = {}; for (const [dayOfWeek, val] of g.rows) { - res[dayOfWeek] = val + res[dayOfWeek] = val; } - res.raw = g.rows - return res -} + res.raw = g.rows; + return res; +}; const parseLocWithDetails = ({parsed, common}, l) => { if (!parsed) { - return parsed + return parsed; } if (parsed.type !== 'stop' && parsed.type !== 'station') { - return parsed + return parsed; } if (Array.isArray(l.gridL)) { const resolveCells = grid => ({ ...grid, rows: grid.rows.map(row => row.map(cell => cell && cell.text)), - }) + }); let grids = l.gridL .map(grid => parseGrid(grid, common)) - .map(resolveCells) + .map(resolveCells); - const ausstattung = grids.find(g => slugg(g.title) === 'ausstattung') + const ausstattung = grids.find(g => slugg(g.title) === 'ausstattung'); if (ausstattung) { - parsed.facilities = parseAusstattungGrid(ausstattung) + parsed.facilities = parseAusstattungGrid(ausstattung); } - const öffnungszeiten = grids.find(g => slugg(g.title) === 'offnungszeiten-reisezentrum') + const öffnungszeiten = grids.find(g => slugg(g.title) === 'offnungszeiten-reisezentrum'); if (öffnungszeiten) { - parsed.reisezentrumOpeningHours = parseReisezentrumÖffnungszeiten(öffnungszeiten) + parsed.reisezentrumOpeningHours = parseReisezentrumÖffnungszeiten(öffnungszeiten); } - grids = without(grids, ausstattung, öffnungszeiten) + grids = without(grids, ausstattung, öffnungszeiten); if (grids.length > 0) { - parsed.grids = grids + parsed.grids = grids; } } - return parsed -} + return parsed; +}; // https://www.bahn.de/p/view/service/buchung/auslastungsinformation.shtml -const loadFactors = [] -loadFactors[1] = 'low-to-medium' -loadFactors[2] = 'high' -loadFactors[3] = 'very-high' -loadFactors[4] = 'exceptionally-high' +const loadFactors = []; +loadFactors[1] = 'low-to-medium'; +loadFactors[2] = 'high'; +loadFactors[3] = 'very-high'; +loadFactors[4] = 'exceptionally-high'; const parseLoadFactor = (opt, tcocL, tcocX) => { const cls = opt.firstClass ? 'FIRST' - : 'SECOND' + : 'SECOND'; const load = tcocX.map(i => tcocL[i]) - .find(lf => lf.c === cls) - return load && loadFactors[load.r] || null -} + .find(lf => lf.c === cls); + return load && loadFactors[load.r] || null; +}; const parseArrOrDepWithLoadFactor = ({parsed, res, opt}, d) => { if (d.stbStop.dTrnCmpSX && Array.isArray(d.stbStop.dTrnCmpSX.tcocX)) { - const load = parseLoadFactor(opt, res.common.tcocL || [], d.stbStop.dTrnCmpSX.tcocX) + const load = parseLoadFactor(opt, res.common.tcocL || [], d.stbStop.dTrnCmpSX.tcocX); if (load) { - parsed.loadFactor = load + parsed.loadFactor = load; } } - return parsed -} + return parsed; +}; const transformJourneysQuery = ({opt}, query) => { - const filters = query.jnyFltrL + const filters = query.jnyFltrL; if (opt.bike) { - filters.push(bike) + filters.push(bike); } if ('age' in opt && 'ageGroup' in opt) { throw new TypeError(`\ opt.age and opt.ageGroup are mutually exclusive. -Pass in just opt.age, and the age group will calculated automatically.`) +Pass in just opt.age, and the age group will calculated automatically.`); } const tvlrAgeGroup = 'age' in opt ? ageGroupFromAge(opt.age) - : opt.ageGroup + : opt.ageGroup; query.trfReq = { // todo: what are these? @@ -229,10 +229,10 @@ Pass in just opt.age, and the age group will calculated automatically.`) : null, }], cType: 'PK', - } + }; - return query -} + return query; +}; // todo: fix this // line: { @@ -247,19 +247,19 @@ Pass in just opt.age, and the age group will calculated automatically.`) // } const parseLineWithAdditionalName = ({parsed}, l) => { if (l.nameS && ['bus', 'tram', 'ferry'].includes(l.product)) { - parsed.name = l.nameS + parsed.name = l.nameS; } if (l.addName) { - parsed.additionalName = parsed.name - parsed.name = l.addName + parsed.additionalName = parsed.name; + parsed.name = l.addName; } - return parsed -} + return parsed; +}; // todo: sotRating, conSubscr, isSotCon, showARSLink, sotCtxt // todo: conSubscr, showARSLink, useableTime const parseJourneyWithPrice = ({parsed}, raw) => { - parsed.price = null + parsed.price = null; // todo: find cheapest, find discounts // todo: write a parser like vbb-parse-ticket // { @@ -308,29 +308,29 @@ const parseJourneyWithPrice = ({parsed}, raw) => { && Array.isArray(raw.trfRes.fareSetL[0].fareL) && raw.trfRes.fareSetL[0].fareL[0] ) { - const tariff = raw.trfRes.fareSetL[0].fareL[0] + const tariff = raw.trfRes.fareSetL[0].fareL[0]; if (tariff.price && tariff.price.amount >= 0) { // wat parsed.price = { amount: tariff.price.amount / 100, currency: 'EUR', hint: null, - } + }; } } - return parsed -} + return parsed; +}; const parseJourneyLegWithLoadFactor = ({parsed, res, opt}, raw) => { - const tcocX = raw.jny && raw.jny.dTrnCmpSX && raw.jny.dTrnCmpSX.tcocX + const tcocX = raw.jny && raw.jny.dTrnCmpSX && raw.jny.dTrnCmpSX.tcocX; if (Array.isArray(tcocX) && Array.isArray(res.common.tcocL)) { - const load = parseLoadFactor(opt, res.common.tcocL, tcocX) + const load = parseLoadFactor(opt, res.common.tcocL, tcocX); if (load) { - parsed.loadFactor = load + parsed.loadFactor = load; } } - return parsed -} + return parsed; +}; // todo: // [ { type: 'hint', @@ -522,7 +522,7 @@ const hintsByCode = Object.assign(Object.create(null), { code: 'intercity-2', summary: 'Intercity 2', }, -}) +}); const codesByText = Object.assign(Object.create(null), { 'journey cancelled': 'journey-cancelled', // todo: German variant @@ -531,39 +531,39 @@ const codesByText = Object.assign(Object.create(null), { 'signalstörung': 'signal-failure', 'additional stop': 'additional-stopover', // todo: German variant 'platform change': 'changed platform', // todo: use dash, German variant -}) +}); const parseHintByCode = ({parsed}, raw) => { // plain-text hints used e.g. for stop metadata if (raw.type === 'K') { - return {type: 'hint', text: raw.txtN} + return {type: 'hint', text: raw.txtN}; } if (raw.type === 'A') { const hint = hintsByCode[raw.code && raw.code.trim() - .toLowerCase()] + .toLowerCase()]; if (hint) { - return Object.assign({text: raw.txtN}, hint) + return Object.assign({text: raw.txtN}, hint); } } if (parsed && raw.txtN) { - const text = trim(raw.txtN.toLowerCase(), ' ()') + const text = trim(raw.txtN.toLowerCase(), ' ()'); if (codesByText[text]) { - parsed.code = codesByText[text] + parsed.code = codesByText[text]; } } - return parsed -} + return parsed; +}; -const isIBNR = /^\d{6,}$/ +const isIBNR = /^\d{6,}$/; const formatStation = (id) => { if (!isIBNR.test(id)) { - throw new Error('station ID must be an IBNR.') + throw new Error('station ID must be an IBNR.'); } - return _formatStation(id) -} + return _formatStation(id); +}; // todo: find option for absolute number of results @@ -595,8 +595,8 @@ const profile = { radar: true, reachableFrom: true, lines: false, // `.svcResL[0].res.lineL[]` is missing 🤔 -} +}; export { profile, -} +}; diff --git a/p/db/loyalty-cards.js b/p/db/loyalty-cards.js index af05b73a2..a727bb87b 100644 --- a/p/db/loyalty-cards.js +++ b/p/db/loyalty-cards.js @@ -7,7 +7,7 @@ const c = { VOORDEELURENABO: Symbol('Voordeelurenabo'), SHCARD: Symbol('SH-Card'), GENERALABONNEMENT: Symbol('General-Abonnement'), -} +}; // see https://gist.github.com/juliuste/202bb04f450a79f8fa12a2ec3abcd72d const formatLoyaltyCard = (data) => { @@ -15,37 +15,37 @@ const formatLoyaltyCard = (data) => { if (data.discount === 25) { return data.class === 1 ? 1 - : 2 + : 2; } if (data.discount === 50) { return data.class === 1 ? 3 - : 4 + : 4; } } if (data.type === c.VORTEILSCARD) { - return 9 + return 9; } if (data.type === c.HALBTAXABO) { return data.railplus ? 10 - : 11 + : 11; } if (data.type === c.VOORDEELURENABO) { return data.railplus ? 12 - : 13 + : 13; } if (data.type === c.SHCARD) { - return 14 + return 14; } if (data.type === c.GENERALABONNEMENT) { - return 15 + return 15; } - return 0 -} + return 0; +}; export { c as data, formatLoyaltyCard, -} +}; diff --git a/p/db/products.js b/p/db/products.js index 92207a5fb..4e5f44d14 100644 --- a/p/db/products.js +++ b/p/db/products.js @@ -80,8 +80,8 @@ const products = [ short: 'Taxi', default: true, }, -] +]; export { products, -} +}; diff --git a/p/db/routing-modes.js b/p/db/routing-modes.js index 5bafa4f3c..b356ffeb6 100644 --- a/p/db/routing-modes.js +++ b/p/db/routing-modes.js @@ -6,8 +6,8 @@ const routingModes = { REALTIME: 'REALTIME', SERVER_DEFAULT: 'SERVER_DEFAULT', HYBRID: 'HYBRID', -} +}; export { routingModes, -} +}; diff --git a/p/insa/index.js b/p/insa/index.js index 882e6c6df..a95b65288 100644 --- a/p/insa/index.js +++ b/p/insa/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -17,8 +17,8 @@ const profile = { radar: true, refreshJourneyUseOutReconL: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/insa/products.js b/p/insa/products.js index 72f614c06..9e972aa7d 100644 --- a/p/insa/products.js +++ b/p/insa/products.js @@ -55,8 +55,8 @@ const products = [ short: 'TT', default: true, }, -] +]; export { products, -} +}; diff --git a/p/invg/index.js b/p/invg/index.js index aa5c3f457..f71b9caf2 100644 --- a/p/invg/index.js +++ b/p/invg/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -17,8 +17,8 @@ const profile = { trip: true, radar: true, refreshJourney: true, -} +}; export { profile, -} +}; diff --git a/p/invg/products.js b/p/invg/products.js index 8b838735c..9672d67cf 100644 --- a/p/invg/products.js +++ b/p/invg/products.js @@ -64,8 +64,8 @@ const products = [ short: 'on demand', default: false, }, -] +]; export { products, -} +}; diff --git a/p/irish-rail/index.js b/p/irish-rail/index.js index e41ade1fb..3aa7bf19d 100644 --- a/p/irish-rail/index.js +++ b/p/irish-rail/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -19,8 +19,8 @@ const profile = { refreshJourney: false, // fails with `CGI_READ_FAILED` trip: true, radar: true, -} +}; export { profile, -} +}; diff --git a/p/irish-rail/products.js b/p/irish-rail/products.js index d975b19de..334ba86db 100644 --- a/p/irish-rail/products.js +++ b/p/irish-rail/products.js @@ -33,8 +33,8 @@ const products = [ short: 'LUAS', default: true, }, -] +]; export { products, -} +}; diff --git a/p/ivb/index.js b/p/ivb/index.js index 337a70dc0..4d5fb5bac 100644 --- a/p/ivb/index.js +++ b/p/ivb/index.js @@ -1,11 +1,11 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import {readFileSync} from 'fs' -import {Agent} from 'https' -const baseProfile = require('./base.json') +import {readFileSync} from 'fs'; +import {Agent} from 'https'; +const baseProfile = require('./base.json'); const products = [{ id: 'train-and-s-bahn', @@ -77,14 +77,14 @@ const products = [{ name: 'Anrufsammeltaxi', short: 'AST', default: true, -}] +}]; // `fahrplan.ivb.at:443` doesn't provide the necessary CA certificate chain for // Node.js to trust the certificate, so we manually add it. // todo: fix this properly, e.g. by letting them know -const ca = readFileSync(new URL('./digicert-tls-rsa-sha256-2020-ca1.crt.pem', import.meta.url).pathname) -const agent = new Agent({ca}) -const transformReq = (ctx, req) => ({...req, agent}) +const ca = readFileSync(new URL('./digicert-tls-rsa-sha256-2020-ca1.crt.pem', import.meta.url).pathname); +const agent = new Agent({ca}); +const transformReq = (ctx, req) => ({...req, agent}); const profile = { ...baseProfile, @@ -99,8 +99,8 @@ const profile = { refreshJourneyUseOutReconL: true, trip: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/kvb/index.js b/p/kvb/index.js index f2103c850..45ef053bd 100644 --- a/p/kvb/index.js +++ b/p/kvb/index.js @@ -1,11 +1,11 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import {readFileSync} from 'fs' -import {Agent} from 'https' -const baseProfile = require('./base.json') +import {readFileSync} from 'fs'; +import {Agent} from 'https'; +const baseProfile = require('./base.json'); const products = [{ id: 'stadtbahn', @@ -49,14 +49,14 @@ const products = [{ name: 'Fernverkehr', short: 'Fernverkehr', default: true, -}] +}]; // `auskunft.kvb.koeln:443` doesn't provide the necessary CA certificate chain for // Node.js to trust the certificate, so we manually add it. // todo: fix this properly, e.g. by letting them know -const ca = readFileSync(new URL('./thawte-rsa-ca-2018.pem', import.meta.url).pathname) -const agent = new Agent({ca}) -const transformReq = (ctx, req) => ({...req, agent}) +const ca = readFileSync(new URL('./thawte-rsa-ca-2018.pem', import.meta.url).pathname); +const agent = new Agent({ca}); +const transformReq = (ctx, req) => ({...req, agent}); const profile = { ...baseProfile, @@ -69,8 +69,8 @@ const profile = { refreshJourneyUseOutReconL: true, trip: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/mobil-nrw/index.js b/p/mobil-nrw/index.js index 8cf5fdb8e..1877ccdcb 100644 --- a/p/mobil-nrw/index.js +++ b/p/mobil-nrw/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -18,8 +18,8 @@ const profile = { reachableFrom: true, refreshJourneyUseOutReconL: true, remarks: true, -} +}; export { profile, -} +}; diff --git a/p/mobil-nrw/products.js b/p/mobil-nrw/products.js index 52230d4bf..f7afed383 100644 --- a/p/mobil-nrw/products.js +++ b/p/mobil-nrw/products.js @@ -73,8 +73,8 @@ const products = [ short: 'EC/IC', default: true, }, -] +]; export { products, -} +}; diff --git a/p/mobiliteit-lu/index.js b/p/mobiliteit-lu/index.js index ea1847ca8..24f61ec63 100644 --- a/p/mobiliteit-lu/index.js +++ b/p/mobiliteit-lu/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -18,8 +18,8 @@ const profile = { reachableFrom: true, refreshJourneyUseOutReconL: true, -} +}; export { profile, -} +}; diff --git a/p/mobiliteit-lu/products.js b/p/mobiliteit-lu/products.js index 61a734843..d1b1955fa 100644 --- a/p/mobiliteit-lu/products.js +++ b/p/mobiliteit-lu/products.js @@ -39,8 +39,8 @@ const products = [ short: 'Tram', default: true, }, -] +]; export { products, -} +}; diff --git a/p/nahsh/index.js b/p/nahsh/index.js index 8ef9197f7..2939b9aa0 100644 --- a/p/nahsh/index.js +++ b/p/nahsh/index.js @@ -1,31 +1,31 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import {parseHook} from '../../lib/profile-hooks.js' +import {parseHook} from '../../lib/profile-hooks.js'; -import {parseLocation as _parseLocation} from '../../parse/location.js' -import {parseJourney as _parseJourney} from '../../parse/journey.js' -import {parseMovement as _parseMovement} from '../../parse/movement.js' -const baseProfile = require('./base.json') -import {products} from './products.js' +import {parseLocation as _parseLocation} from '../../parse/location.js'; +import {parseJourney as _parseJourney} from '../../parse/journey.js'; +import {parseMovement as _parseMovement} from '../../parse/movement.js'; +const baseProfile = require('./base.json'); +import {products} from './products.js'; // todo: journey prices const fixLocation = ({parsed}, l) => { // weird fix for empty lines, e.g. IC/EC at Flensburg Hbf if (parsed.lines) { - parsed.lines = parsed.lines.filter(x => x.id && x.name) + parsed.lines = parsed.lines.filter(x => x.id && x.name); } // remove leading zeroes, todo if (parsed.id && parsed.id.length > 0) { - parsed.id = parsed.id.replace(/^0+/, '') + parsed.id = parsed.id.replace(/^0+/, ''); } - return parsed -} + return parsed; +}; const parseJourneyWithTickets = ({parsed}, j) => { if ( @@ -33,45 +33,45 @@ const parseJourneyWithTickets = ({parsed}, j) => { && Array.isArray(j.trfRes.fareSetL) && j.trfRes.fareSetL.length > 0 ) { - parsed.tickets = [] + parsed.tickets = []; for (let t of j.trfRes.fareSetL) { - const tariff = t.desc + const tariff = t.desc; if (!tariff || !Array.isArray(t.fareL)) { - continue + continue; } for (let v of t.fareL) { - const variant = v.name + const variant = v.name; if (!variant) { - continue + continue; } const ticket = { name: [tariff, variant].join(' - '), tariff, variant, - } + }; if (v.prc && Number.isInteger(v.prc) && v.cur) { - ticket.amount = v.prc / 100 - ticket.currency = v.cur + ticket.amount = v.prc / 100; + ticket.currency = v.cur; } else { - ticket.amount = null - ticket.hint = 'No pricing information available.' + ticket.amount = null; + ticket.hint = 'No pricing information available.'; } - parsed.tickets.push(ticket) + parsed.tickets.push(ticket); } } } - return parsed -} + return parsed; +}; const fixMovement = ({parsed}, m) => { // filter out empty nextStopovers entries parsed.nextStopovers = parsed.nextStopovers.filter((f) => { - return f.stop !== null || f.arrival !== null || f.departure !== null - }) - return parsed -} + return f.stop !== null || f.arrival !== null || f.departure !== null; + }); + return parsed; +}; const profile = { ...baseProfile, @@ -88,8 +88,8 @@ const profile = { trip: true, radar: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/nahsh/products.js b/p/nahsh/products.js index 09265bb91..ddfa7ddbd 100644 --- a/p/nahsh/products.js +++ b/p/nahsh/products.js @@ -79,8 +79,8 @@ const products = [ short: 'on-call', default: true, }, -] +]; export { products, -} +}; diff --git a/p/nvv/index.js b/p/nvv/index.js index ea2539344..53538dcd5 100644 --- a/p/nvv/index.js +++ b/p/nvv/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -17,8 +17,8 @@ const profile = { trip: true, radar: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/nvv/products.js b/p/nvv/products.js index 7b2edc9b7..14b6b0a6a 100644 --- a/p/nvv/products.js +++ b/p/nvv/products.js @@ -56,8 +56,8 @@ const products = [ short: 'Sammeltaxi', default: true, }, -] +]; export { products, -} +}; diff --git a/p/oebb/index.js b/p/oebb/index.js index a768b081b..1c2b52c0d 100644 --- a/p/oebb/index.js +++ b/p/oebb/index.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); // todo: https://gist.github.com/anonymous/a5fc856bc80ae7364721943243f934f4#file-haf_config_base-properties-L5 // todo: https://gist.github.com/anonymous/a5fc856bc80ae7364721943243f934f4#file-haf_config_base-properties-L47-L234 -import {parseHook} from '../../lib/profile-hooks.js' +import {parseHook} from '../../lib/profile-hooks.js'; -import {parseLocation as _parseLocation} from '../../parse/location.js' -import {parseMovement as _parseMovement} from '../../parse/movement.js' -const baseProfile = require('./base.json') -import {products} from './products.js' +import {parseLocation as _parseLocation} from '../../parse/location.js'; +import {parseMovement as _parseMovement} from '../../parse/movement.js'; +const baseProfile = require('./base.json'); +import {products} from './products.js'; // ÖBB has some 'stations' **in austria** with no departures/products, // like station entrances, that are actually POIs. @@ -27,26 +27,26 @@ const fixWeirdPOIs = ({parsed}) => { id: parsed.id, poi: true, name: parsed.name, - }, parsed.location) + }, parsed.location); } - return parsed -} + return parsed; +}; const fixMovement = ({parsed}, m) => { // filter out POIs // todo: make use of them, as some of them specify fare zones parsed.nextStopovers = parsed.nextStopovers.filter(st => { - let s = st.stop || {} + let s = st.stop || {}; if (s.station) { - s = s.station + s = s.station; } - return s.type === 'stop' || s.type === 'station' - }) + return s.type === 'stop' || s.type === 'station'; + }); parsed.frames = parsed.frames.filter((f) => { - return f.origin.type !== 'location' && f.destination.type !== 'location' - }) - return parsed -} + return f.origin.type !== 'location' && f.destination.type !== 'location'; + }); + return parsed; +}; const profile = { ...baseProfile, @@ -64,8 +64,8 @@ const profile = { radar: true, reachableFrom: true, // lines: false, // `.svcResL[0].res.lineL[]` is missing 🤔 -} +}; export { profile, -} +}; diff --git a/p/oebb/products.js b/p/oebb/products.js index f0f4fbe18..0271cd533 100644 --- a/p/oebb/products.js +++ b/p/oebb/products.js @@ -79,8 +79,8 @@ const products = [ short: 'on-call/lift', default: true, }, -] +]; export { products, -} +}; diff --git a/p/ooevv/index.js b/p/ooevv/index.js index dfc8ab326..de1786efc 100644 --- a/p/ooevv/index.js +++ b/p/ooevv/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'train-and-s-bahn', @@ -75,7 +75,7 @@ const products = [{ name: 'Anrufsammeltaxi', short: 'AST', default: true, -}] +}]; const profile = { ...baseProfile, @@ -96,8 +96,8 @@ const profile = { refreshJourneyUseOutReconL: true, trip: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/pkp/index.js b/p/pkp/index.js index fdc318304..5a0c4949e 100644 --- a/p/pkp/index.js +++ b/p/pkp/index.js @@ -1,20 +1,20 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import {parseHook} from '../../lib/profile-hooks.js' +import {parseHook} from '../../lib/profile-hooks.js'; -import {parseLocation} from '../../parse/location.js' -const baseProfile = require('./base.json') -import {products} from './products.js' +import {parseLocation} from '../../parse/location.js'; +const baseProfile = require('./base.json'); +import {products} from './products.js'; const trimStopName = ({parsed}, l) => { if (parsed.type === 'stop' || parsed.type === 'station' && parsed.name) { - parsed.name = parsed.name.replace(/(^-|-$)/g, '') + parsed.name = parsed.name.replace(/(^-|-$)/g, ''); } - return parsed -} + return parsed; +}; const profile = { ...baseProfile, @@ -30,8 +30,8 @@ const profile = { refreshJourney: false, reachableFrom: true, remarks: false, // seems like ver >= 1.20 is required -} +}; export { profile, -} +}; diff --git a/p/pkp/products.js b/p/pkp/products.js index a170800ae..22ca2b0fa 100644 --- a/p/pkp/products.js +++ b/p/pkp/products.js @@ -31,8 +31,8 @@ const products = [ short: 'B', default: true, }, -] +]; export { products, -} +}; diff --git a/p/rejseplanen/index.js b/p/rejseplanen/index.js index 4f46dc2c8..4cad30b91 100644 --- a/p/rejseplanen/index.js +++ b/p/rejseplanen/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -16,8 +16,8 @@ const profile = { refreshJourneyUseOutReconL: true, trip: true, radar: true, -} +}; export { profile, -} +}; diff --git a/p/rejseplanen/products.js b/p/rejseplanen/products.js index e04e90063..297785c44 100644 --- a/p/rejseplanen/products.js +++ b/p/rejseplanen/products.js @@ -39,8 +39,8 @@ const products = [ short: 'S', default: true, }, -] +]; export { products, -} +}; diff --git a/p/rmv/index.js b/p/rmv/index.js index c61455b48..ddbeb5b03 100644 --- a/p/rmv/index.js +++ b/p/rmv/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -18,8 +18,8 @@ const profile = { radar: true, refreshJourney: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/rmv/products.js b/p/rmv/products.js index 5869c0125..8121bf477 100644 --- a/p/rmv/products.js +++ b/p/rmv/products.js @@ -80,8 +80,8 @@ const products = [ default: true, }, // todo: remaining bitmask `1015` -] +]; export { products, -} +}; diff --git a/p/rsag/index.js b/p/rsag/index.js index f3eba7adf..8b787d05a 100644 --- a/p/rsag/index.js +++ b/p/rsag/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -17,8 +17,8 @@ const profile = { radar: true, reachableFrom: true, refreshJourneyUseOutReconL: true, -} +}; export { profile, -} +}; diff --git a/p/rsag/products.js b/p/rsag/products.js index 0442aeba1..fa764d113 100644 --- a/p/rsag/products.js +++ b/p/rsag/products.js @@ -79,8 +79,8 @@ const products = [ short: 'AST', default: true, }, -] +]; export { products, -} +}; diff --git a/p/saarfahrplan/index.js b/p/saarfahrplan/index.js index a9a141219..02b1093f8 100644 --- a/p/saarfahrplan/index.js +++ b/p/saarfahrplan/index.js @@ -1,19 +1,19 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import {parseHook} from '../../lib/profile-hooks.js' +import {parseHook} from '../../lib/profile-hooks.js'; -import {parseMovement as _parseMovement} from '../../parse/movement.js' -const baseProfile = require('./base.json') -import {products} from './products.js' +import {parseMovement as _parseMovement} from '../../parse/movement.js'; +const baseProfile = require('./base.json'); +import {products} from './products.js'; const fixMovement = ({parsed}, m) => { // filter out empty stopovers - parsed.nextStopovers = parsed.nextStopovers.filter(st => Boolean(st.stop)) - return parsed -} + parsed.nextStopovers = parsed.nextStopovers.filter(st => Boolean(st.stop)); + return parsed; +}; const profile = { ...baseProfile, @@ -30,8 +30,8 @@ const profile = { trip: true, radar: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/saarfahrplan/products.js b/p/saarfahrplan/products.js index a43d2f54b..4dc0e6dc9 100644 --- a/p/saarfahrplan/products.js +++ b/p/saarfahrplan/products.js @@ -88,8 +88,8 @@ const products = [ default: true, }, // todo: `1`, `2`, `4` bitmasks? -] +]; export { products, -} +}; diff --git a/p/salzburg/index.js b/p/salzburg/index.js index 9d949143f..fdc486636 100644 --- a/p/salzburg/index.js +++ b/p/salzburg/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'train-and-s-bahn', @@ -75,7 +75,7 @@ const products = [{ name: 'Anrufsammeltaxi', short: 'AST', default: true, -}] +}]; const profile = { ...baseProfile, @@ -89,8 +89,8 @@ const profile = { refreshJourneyUseOutReconL: true, trip: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/sbahn-muenchen/index.js b/p/sbahn-muenchen/index.js index 44c6ab61c..cdbd8c1cf 100644 --- a/p/sbahn-muenchen/index.js +++ b/p/sbahn-muenchen/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -20,8 +20,8 @@ const profile = { radar: true, refreshJourney: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/sbahn-muenchen/products.js b/p/sbahn-muenchen/products.js index 70dd882d0..7e21b485d 100644 --- a/p/sbahn-muenchen/products.js +++ b/p/sbahn-muenchen/products.js @@ -72,8 +72,8 @@ const products = [ short: 'Sammeltaxi', default: true, }, -] +]; export { products, -} +}; diff --git a/p/sncb/index.js b/p/sncb/index.js index ee9b4d15e..1756f5385 100644 --- a/p/sncb/index.js +++ b/p/sncb/index.js @@ -1,32 +1,32 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import {readFileSync} from 'fs' -import {Agent} from 'https' -import {strictEqual as eql} from 'assert' -import {parseHook} from '../../lib/profile-hooks.js' -import {parseLine} from '../../parse/line.js' -const baseProfile = require('./base.json') -import {products} from './products.js' +import {readFileSync} from 'fs'; +import {Agent} from 'https'; +import {strictEqual as eql} from 'assert'; +import {parseHook} from '../../lib/profile-hooks.js'; +import {parseLine} from '../../parse/line.js'; +const baseProfile = require('./base.json'); +import {products} from './products.js'; // `www.belgianrail.be:443` doesn't provide the necessary CA certificate // chain for Node.js to trust the certificate, so we manually add it. // todo: fix this properly, e.g. by letting them know -const ca = readFileSync(new URL('./digicert-sha2-secure-server-ca.crt.pem', import.meta.url).pathname) -const agent = new Agent({ca}) -const transformReq = (ctx, req) => ({...req, agent}) +const ca = readFileSync(new URL('./digicert-sha2-secure-server-ca.crt.pem', import.meta.url).pathname); +const agent = new Agent({ca}); +const transformReq = (ctx, req) => ({...req, agent}); // todo: this is ugly const lineNameWithoutFahrtNr = ({parsed}) => { - const {name, fahrtNr} = parsed + const {name, fahrtNr} = parsed; if (!name || !fahrtNr || !(/s\d/i).test(name)) { - return parsed + return parsed; } - const i = name.indexOf(fahrtNr) + const i = name.indexOf(fahrtNr); if (i < 0) { - return parsed + return parsed; } if ( @@ -36,22 +36,22 @@ const lineNameWithoutFahrtNr = ({parsed}) => { return { ...parsed, name: name.slice(0, i - 1) + name.slice(i + fahrtNr.length + 1), - } + }; } - return parsed -} + return parsed; +}; eql(lineNameWithoutFahrtNr({ parsed: {name: 'THA 123', fahrtNr: '123'}, -}).name, 'THA 123') +}).name, 'THA 123'); eql(lineNameWithoutFahrtNr({ parsed: {name: 'S1 123', fahrtNr: '123'}, -}).name, 'S1') +}).name, 'S1'); eql(lineNameWithoutFahrtNr({ parsed: {name: 'S1-123', fahrtNr: '123'}, -}).name, 'S1-123') +}).name, 'S1-123'); eql(lineNameWithoutFahrtNr({ parsed: {name: 'S1 123a', fahrtNr: '123'}, -}).name, 'S1 123a') +}).name, 'S1 123a'); const profile = { ...baseProfile, @@ -68,8 +68,8 @@ const profile = { refreshJourney: true, radar: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/sncb/products.js b/p/sncb/products.js index 13e70fb54..0de1f383f 100644 --- a/p/sncb/products.js +++ b/p/sncb/products.js @@ -56,8 +56,8 @@ const products = [ // todo: 2, 8, 32, 128 short: 'tram', default: true, }, -] +]; export { products, -} +}; diff --git a/p/stv/index.js b/p/stv/index.js index 4f88b03c6..fae4f9bdb 100644 --- a/p/stv/index.js +++ b/p/stv/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'train-and-s-bahn', @@ -75,7 +75,7 @@ const products = [{ name: 'Anrufsammeltaxi', short: 'AST', default: true, -}] +}]; const profile = { ...baseProfile, @@ -87,8 +87,8 @@ const profile = { refreshJourneyUseOutReconL: true, trip: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/svv/index.js b/p/svv/index.js index 24d1f1879..8f745adb4 100644 --- a/p/svv/index.js +++ b/p/svv/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -17,8 +17,8 @@ const profile = { refreshJourney: true, reachableFrom: true, refreshJourneyUseOutReconL: true, -} +}; export { profile, -} +}; diff --git a/p/svv/products.js b/p/svv/products.js index f620f9112..84f89ca31 100644 --- a/p/svv/products.js +++ b/p/svv/products.js @@ -63,8 +63,8 @@ const products = [ short: 'F', default: true, }, -] +]; export { products, -} +}; diff --git a/p/tpg/index.js b/p/tpg/index.js index 02f2eb2a2..6de5f9781 100644 --- a/p/tpg/index.js +++ b/p/tpg/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'tgv', @@ -68,7 +68,7 @@ const products = [{ name: 'Tram', short: 'Tram', default: true, -}] +}]; const profile = { ...baseProfile, @@ -82,8 +82,8 @@ const profile = { radar: true, refreshJourneyUseOutReconL: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/vbb/index.js b/p/vbb/index.js index 059c4c043..d99cddfcb 100644 --- a/p/vbb/index.js +++ b/p/vbb/index.js @@ -1,28 +1,28 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import {parseHook} from '../../lib/profile-hooks.js' +import {parseHook} from '../../lib/profile-hooks.js'; -import {parseAndAddLocationDHID} from './parse-loc-dhid.js' -import {parseLine as _parseLine} from '../../parse/line.js' -import {parseLocation as _parseLocation} from '../../parse/location.js' -import {parseJourney as _parseJourney} from '../../parse/journey.js' -import {parseDeparture as _parseDeparture} from '../../parse/departure.js' +import {parseAndAddLocationDHID} from './parse-loc-dhid.js'; +import {parseLine as _parseLine} from '../../parse/line.js'; +import {parseLocation as _parseLocation} from '../../parse/location.js'; +import {parseJourney as _parseJourney} from '../../parse/journey.js'; +import {parseDeparture as _parseDeparture} from '../../parse/departure.js'; -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const parseLineWithShortName = ({parsed}, p) => { - parsed.name = p.name.replace(/^(bus|tram)\s+/i, '') - return parsed -} + parsed.name = p.name.replace(/^(bus|tram)\s+/i, ''); + return parsed; +}; const parseLocation = ({parsed}, l) => { - parseAndAddLocationDHID(parsed, l) - return parsed -} + parseAndAddLocationDHID(parsed, l); + return parsed; +}; // todo: move this to parse/tickets.js? const parseJourneyWithTickets = ({parsed}, j) => { @@ -33,7 +33,7 @@ const parseJourneyWithTickets = ({parsed}, j) => { parsed.tickets = j.trfRes.fareSetL .map((s) => { if (!Array.isArray(s.fareL) || s.fareL.length === 0) { - return null + return null; } return { name: s.name, @@ -43,30 +43,30 @@ const parseJourneyWithTickets = ({parsed}, j) => { name: f.name, price: f.price, })), - } + }; }) - .filter(set => Boolean(set)) + .filter(set => Boolean(set)); // todo: j.trfRes.totalPrice // todo: j.trfRes.msgL } - return parsed -} + return parsed; +}; -const ringbahnClockwise = /^ringbahn s\s?41$/i -const ringbahnAnticlockwise = /^ringbahn s\s?42$/i +const ringbahnClockwise = /^ringbahn s\s?41$/i; +const ringbahnAnticlockwise = /^ringbahn s\s?42$/i; const parseDepartureRenameRingbahn = ({parsed}) => { if (parsed.line && parsed.line.product === 'suburban') { - const d = parsed.direction && parsed.direction.trim() + const d = parsed.direction && parsed.direction.trim(); if (ringbahnClockwise.test(d)) { - parsed.direction = 'Ringbahn S41 ⟳' + parsed.direction = 'Ringbahn S41 ⟳'; } else if (ringbahnAnticlockwise.test(d)) { - parsed.direction = 'Ringbahn S42 ⟲' + parsed.direction = 'Ringbahn S42 ⟲'; } } - return parsed -} + return parsed; +}; const profile = { ...baseProfile, @@ -85,8 +85,8 @@ const profile = { trip: true, radar: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/vbb/parse-loc-dhid.js b/p/vbb/parse-loc-dhid.js index d98cfcea9..f7624522c 100644 --- a/p/vbb/parse-loc-dhid.js +++ b/p/vbb/parse-loc-dhid.js @@ -1,23 +1,23 @@ -const dhidPrefix = 'A×' +const dhidPrefix = 'A×'; const parseAndAddLocationDHID = (loc, l) => { if (!Array.isArray(l.gidL)) { - return + return; } - const dhidGid = l.gidL.find(gid => gid.slice(0, dhidPrefix.length) === dhidPrefix) + const dhidGid = l.gidL.find(gid => gid.slice(0, dhidPrefix.length) === dhidPrefix); if (!dhidGid) { - return + return; } - const dhid = dhidGid.slice(dhidPrefix.length) + const dhid = dhidGid.slice(dhidPrefix.length); // It seems that the DHID of the parent station is being used, not of the stop. // if (!loc.ids) loc.ids = {} // loc.ids.dhid = dhid // todo: use loc.ids.stationDHID instead? - loc.stationDHID = dhid -} + loc.stationDHID = dhid; +}; export { parseAndAddLocationDHID, -} +}; diff --git a/p/vbb/products.js b/p/vbb/products.js index bf005ebe1..7565a0190 100644 --- a/p/vbb/products.js +++ b/p/vbb/products.js @@ -55,8 +55,8 @@ const products = [ short: 'R', default: true, }, -] +]; export { products, -} +}; diff --git a/p/vbn/index.js b/p/vbn/index.js index 5eeb56888..82f2f6ad3 100644 --- a/p/vbn/index.js +++ b/p/vbn/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -21,8 +21,8 @@ const profile = { radar: true, reachableFrom: true, refreshJourneyUseOutReconL: true, -} +}; export { profile, -} +}; diff --git a/p/vbn/products.js b/p/vbn/products.js index 5be30e611..817e1427d 100644 --- a/p/vbn/products.js +++ b/p/vbn/products.js @@ -71,8 +71,8 @@ const products = [ short: 'AST', default: true, }, -] +]; export { products, -} +}; diff --git a/p/vkg/index.js b/p/vkg/index.js index f59ef35c9..1950a8c56 100644 --- a/p/vkg/index.js +++ b/p/vkg/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ // todo: what is `8`? id: 'trains', @@ -75,7 +75,7 @@ const products = [{ // todo: what is `8`? name: 'Anrufsammeltaxi', short: 'AST', default: true, -}] +}]; const profile = { ...baseProfile, @@ -88,8 +88,8 @@ const profile = { refreshJourneyUseOutReconL: true, trip: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/vmt/index.js b/p/vmt/index.js index 39fccee7b..c39635f9f 100644 --- a/p/vmt/index.js +++ b/p/vmt/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -21,8 +21,8 @@ const profile = { trip: true, reachableFrom: true, remarks: false, // seems like ver >= 1.20 is required -} +}; export { profile, -} +}; diff --git a/p/vmt/products.js b/p/vmt/products.js index a1c3bf531..f413a8ca6 100644 --- a/p/vmt/products.js +++ b/p/vmt/products.js @@ -34,8 +34,8 @@ const products = [ short: 'bus', default: true, }, -] +]; export { products, -} +}; diff --git a/p/vor/index.js b/p/vor/index.js index dfc8ab326..de1786efc 100644 --- a/p/vor/index.js +++ b/p/vor/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'train-and-s-bahn', @@ -75,7 +75,7 @@ const products = [{ name: 'Anrufsammeltaxi', short: 'AST', default: true, -}] +}]; const profile = { ...baseProfile, @@ -96,8 +96,8 @@ const profile = { refreshJourneyUseOutReconL: true, trip: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/vos/index.js b/p/vos/index.js index fbd07ba0c..793fee895 100644 --- a/p/vos/index.js +++ b/p/vos/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'ice', @@ -75,7 +75,7 @@ const products = [{ name: 'Anrufverkehr', short: 'AST', default: true, -}] +}]; const profile = { ...baseProfile, @@ -89,8 +89,8 @@ const profile = { radar: true, refreshJourneyUseOutReconL: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/vrn/index.js b/p/vrn/index.js index 4deb4c7cc..b960785fc 100644 --- a/p/vrn/index.js +++ b/p/vrn/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -18,8 +18,8 @@ const profile = { reachableFrom: true, refreshJourney: true, refreshJourneyUseOutReconL: true, -} +}; export { profile, -} +}; diff --git a/p/vrn/products.js b/p/vrn/products.js index 4fc8ef5ef..dcf028089 100644 --- a/p/vrn/products.js +++ b/p/vrn/products.js @@ -56,8 +56,8 @@ const products = [ short: 'ICE/IC/EC/EN', default: false, }, -] +]; export { products, -} +}; diff --git a/p/vsn/index.js b/p/vsn/index.js index efe9e6180..5735211be 100644 --- a/p/vsn/index.js +++ b/p/vsn/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -21,8 +21,8 @@ const profile = { trip: true, radar: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/vsn/products.js b/p/vsn/products.js index c0c4df019..ae9498f76 100644 --- a/p/vsn/products.js +++ b/p/vsn/products.js @@ -79,8 +79,8 @@ const products = [ short: 'AST', default: true, }, -] +]; export { products, -} +}; diff --git a/p/vvt/index.js b/p/vvt/index.js index 368cdbbb9..e11c13f92 100644 --- a/p/vvt/index.js +++ b/p/vvt/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ // todo: what is `8`? id: 'trains', @@ -75,7 +75,7 @@ const products = [{ // todo: what is `8`? name: 'Anrufsammeltaxi', short: 'AST', default: true, -}] +}]; const profile = { ...baseProfile, @@ -88,8 +88,8 @@ const profile = { trip: true, refreshJourneyUseOutReconL: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/vvv/index.js b/p/vvv/index.js index 2a8da9127..21235c347 100644 --- a/p/vvv/index.js +++ b/p/vvv/index.js @@ -1,9 +1,9 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') +const baseProfile = require('./base.json'); const products = [{ id: 'train-and-s-bahn', @@ -75,7 +75,7 @@ const products = [{ name: 'Anrufsammeltaxi', short: 'AST', default: true, -}] +}]; const profile = { ...baseProfile, @@ -94,8 +94,8 @@ const profile = { refreshJourneyUseOutReconL: true, trip: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/zvv/index.js b/p/zvv/index.js index a59785a78..75f2789ec 100644 --- a/p/zvv/index.js +++ b/p/zvv/index.js @@ -1,10 +1,10 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -const baseProfile = require('./base.json') -import {products} from './products.js' +const baseProfile = require('./base.json'); +import {products} from './products.js'; const profile = { ...baseProfile, @@ -17,8 +17,8 @@ const profile = { radar: true, refreshJourneyUseOutReconL: true, reachableFrom: true, -} +}; export { profile, -} +}; diff --git a/p/zvv/products.js b/p/zvv/products.js index b16e2b9a1..944410ed5 100644 --- a/p/zvv/products.js +++ b/p/zvv/products.js @@ -55,8 +55,8 @@ const products = [ short: 'Night Train', default: true, }, -] +]; export { products, -} +}; diff --git a/parse/arrival-or-departure.js b/parse/arrival-or-departure.js index 798ed57b1..b0ea6ef3e 100644 --- a/parse/arrival-or-departure.js +++ b/parse/arrival-or-departure.js @@ -1,7 +1,7 @@ -import {findRemarks} from './find-remarks.js' +import {findRemarks} from './find-remarks.js'; -const ARRIVAL = 'a' -const DEPARTURE = 'd' +const ARRIVAL = 'a'; +const DEPARTURE = 'd'; // todo: pt.jny.dirFlg – https://github.com/alexander-albers/tripkit/blob/07047c6ddef24339ebd49a86a78158bca8047421/Sources/TripKit/Provider/AbstractHafasClientInterfaceProvider.swift#L347-L353 & https://github.com/alexander-albers/tripkit/commit/07047c6ddef24339ebd49a86a78158bca8047421#commitcomment-68471656 // todo: d.stbStop.dProgType/d.stbStop.aProgType @@ -9,19 +9,19 @@ const DEPARTURE = 'd' const createParseArrOrDep = (prefix) => { if (prefix !== ARRIVAL && prefix !== DEPARTURE) { - throw new Error('invalid prefix') + throw new Error('invalid prefix'); } const parseArrOrDep = (ctx, d) => { // d = raw arrival/departure - const {profile, opt} = ctx - const {locL} = ctx.res.common + const {profile, opt} = ctx; + const {locL} = ctx.res.common; - const tPlanned = d.stbStop[prefix + 'TimeS'] - const tPrognosed = d.stbStop[prefix + 'TimeR'] - const tzOffset = d.stbStop[prefix + 'TZOffset'] || null - const cancelled = Boolean(d.stbStop[prefix + 'Cncl']) - const plPlanned = d.stbStop[prefix + 'PlatfS'] || d.stbStop[prefix + 'PltfS'] && d.stbStop[prefix + 'PltfS'].txt || null - const plPrognosed = d.stbStop[prefix + 'PlatfR'] || d.stbStop[prefix + 'PltfR'] && d.stbStop[prefix + 'PltfR'].txt || null + const tPlanned = d.stbStop[prefix + 'TimeS']; + const tPrognosed = d.stbStop[prefix + 'TimeR']; + const tzOffset = d.stbStop[prefix + 'TZOffset'] || null; + const cancelled = Boolean(d.stbStop[prefix + 'Cncl']); + const plPlanned = d.stbStop[prefix + 'PlatfS'] || d.stbStop[prefix + 'PltfS'] && d.stbStop[prefix + 'PltfS'].txt || null; + const plPrognosed = d.stbStop[prefix + 'PlatfR'] || d.stbStop[prefix + 'PltfR'] && d.stbStop[prefix + 'PltfR'].txt || null; const res = { tripId: d.jid, @@ -36,14 +36,14 @@ const createParseArrOrDep = (prefix) => { remarks: [], origin: null, destination: null, - } + }; if (prefix === DEPARTURE && Array.isArray(d.prodL) && d.prodL[0] && locL[d.prodL[0].tLocX]) { - res.destination = profile.parseLocation(ctx, locL[d.prodL[0].tLocX]) + res.destination = profile.parseLocation(ctx, locL[d.prodL[0].tLocX]); } if (prefix === ARRIVAL && Array.isArray(d.prodL) && d.prodL[0] && locL[d.prodL[0].fLocX]) { - res.origin = profile.parseLocation(ctx, locL[d.prodL[0].fLocX]) + res.origin = profile.parseLocation(ctx, locL[d.prodL[0].fLocX]); } if (d.pos) { @@ -51,12 +51,12 @@ const createParseArrOrDep = (prefix) => { type: 'location', latitude: d.pos.y / 1000000, longitude: d.pos.x / 1000000, - } + }; } if (cancelled) { - res.cancelled = true - Object.defineProperty(res, 'canceled', {value: true}) + res.cancelled = true; + Object.defineProperty(res, 'canceled', {value: true}); } if (opt.remarks) { @@ -66,27 +66,27 @@ const createParseArrOrDep = (prefix) => { ...d.stbStop.remL || [], ...d.stbStop.msgL || [], ]) - .map(([remark]) => remark) + .map(([remark]) => remark); } if (opt.stopovers && Array.isArray(d.stopL)) { // Filter stations the train passes without stopping, as this doesn't comply with FPTF (yet). const stopovers = d.stopL .map(st => profile.parseStopover(ctx, st, d.date)) - .filter(st => !st.passBy) + .filter(st => !st.passBy); if (prefix === ARRIVAL) { - res.previousStopovers = stopovers + res.previousStopovers = stopovers; } else if (prefix === DEPARTURE) { - res.nextStopovers = stopovers + res.nextStopovers = stopovers; } } - return res - } + return res; + }; - return parseArrOrDep -} + return parseArrOrDep; +}; export { createParseArrOrDep, -} +}; diff --git a/parse/arrival.js b/parse/arrival.js index dfd7e4b40..43016349e 100644 --- a/parse/arrival.js +++ b/parse/arrival.js @@ -1,8 +1,8 @@ -import {createParseArrOrDep} from './arrival-or-departure.js' +import {createParseArrOrDep} from './arrival-or-departure.js'; -const ARRIVAL = 'a' -const parseArrival = createParseArrOrDep(ARRIVAL) +const ARRIVAL = 'a'; +const parseArrival = createParseArrOrDep(ARRIVAL); export { parseArrival, -} +}; diff --git a/parse/common.js b/parse/common.js index aa86b5e39..0e86b6de6 100644 --- a/parse/common.js +++ b/parse/common.js @@ -1,5 +1,5 @@ -import omit from 'lodash/omit.js' -import {createFindInTree} from '../lib/find-in-tree.js' +import omit from 'lodash/omit.js'; +import {createFindInTree} from '../lib/find-in-tree.js'; const findInTree = createFindInTree([ '**.oprX', @@ -17,77 +17,77 @@ const findInTree = createFindInTree([ '**.rRefL', '**.msgL', '**.remL', -]) +]); // there are circular references (e.g. warning -> loc -> warning) // todo: parse either on-the-fly or in a recursive/iterative process const parseCommonData = (_ctx) => { - const {profile, opt, res} = _ctx - const c = res.common || {} - const matches = findInTree(res) + const {profile, opt, res} = _ctx; + const c = res.common || {}; + const matches = findInTree(res); - const common = {} - const ctx = {..._ctx, common} + const common = {}; + const ctx = {..._ctx, common}; - common.operators = [] + common.operators = []; if (Array.isArray(c.opL)) { - common.operators = c.opL.map(op => profile.parseOperator(ctx, op)) + common.operators = c.opL.map(op => profile.parseOperator(ctx, op)); matches['**.oprX'].forEach(([idx, parents]) => { if ('number' === typeof idx) { - parents[0].operator = common.operators[idx] + parents[0].operator = common.operators[idx]; } - }) + }); } - common.icons = [] + common.icons = []; if (Array.isArray(c.icoL)) { - common.icons = c.icoL.map(icon => profile.parseIcon(ctx, icon)) + common.icons = c.icoL.map(icon => profile.parseIcon(ctx, icon)); matches['**.icoX'].forEach(([idx, parents]) => { if ('number' === typeof idx) { - parents[0].icon = common.icons[idx] + parents[0].icon = common.icons[idx]; } - }) + }); } - common.lines = [] + common.lines = []; if (Array.isArray(c.prodL)) { - common.lines = c.prodL.map(l => profile.parseLine(ctx, l)) + common.lines = c.prodL.map(l => profile.parseLine(ctx, l)); matches['**.prodX'].forEach(([idx, parents]) => { if ('number' === typeof idx) { - parents[0].line = common.lines[idx] + parents[0].line = common.lines[idx]; } - }) + }); matches['**.pRefL'].forEach(([idxs, parents]) => { parents[0].lines = idxs.filter(idx => Boolean(common.lines[idx])) - .map(idx => common.lines[idx]) - }) + .map(idx => common.lines[idx]); + }); // todo // **.dep.dProdX: departureLine -> common.lines[idx] // **.arr.aProdX: arrivalLine -> common.lines[idx] } - common.hints = [] + common.hints = []; if (Array.isArray(c.remL)) { - common.hints = c.remL.map(hint => profile.parseHint(ctx, hint)) + common.hints = c.remL.map(hint => profile.parseHint(ctx, hint)); matches['**.remX'].forEach(([idx, parents]) => { if ('number' === typeof idx) { - parents[0].hint = common.hints[idx] + parents[0].hint = common.hints[idx]; } - }) + }); matches['**.remL'].forEach(([idxs, parents]) => { if (!Array.isArray(idxs)) { - return + return; } parents[0].hints = idxs .filter(idx => Boolean(common.hints[idx])) - .map(idx => common.hints[idx]) - }) + .map(idx => common.hints[idx]); + }); matches['**.rRefL'].forEach(([idxs, parents]) => { parents[0].hints = idxs .filter(idx => Boolean(common.hints[idx])) - .map(idx => common.hints[idx]) - }) + .map(idx => common.hints[idx]); + }); } // resolve .msgL[] references @@ -95,83 +95,83 @@ const parseCommonData = (_ctx) => { // `common.himL[]` items? const parseRemarkRef = (ref) => { if (ref.type === 'REM' && ref.hint) { - return omit(ref, ['type', 'remX']) + return omit(ref, ['type', 'remX']); } if (ref.type === 'HIM' && ref.warning) { - return omit(ref, ['type', 'himX']) + return omit(ref, ['type', 'himX']); } - return null - } + return null; + }; matches['**.msgL'].forEach(([refs, parents]) => { // todo: store as parents[0].(hints|warnings) parents[0].remarkRefs = refs .map(parseRemarkRef) - .filter(ref => ref !== null) - }) + .filter(ref => ref !== null); + }); - common.locations = [] + common.locations = []; if (Array.isArray(c.locL)) { - common.locations = c.locL.map(loc => profile.parseLocation(ctx, loc)) + common.locations = c.locL.map(loc => profile.parseLocation(ctx, loc)); for (let i = 0; i < common.locations.length; i++) { - const raw = c.locL[i] - const loc = common.locations[i] + const raw = c.locL[i]; + const loc = common.locations[i]; if ('number' === typeof raw.mMastLocX) { - loc.station = Object.assign({}, common.locations[raw.mMastLocX]) - loc.station.type = 'station' + loc.station = Object.assign({}, common.locations[raw.mMastLocX]); + loc.station.type = 'station'; } else if (raw.isMainMast) { - loc.type = 'station' + loc.type = 'station'; } } // todo: correct props? matches['**.locX'].forEach(([idx, parents]) => { if ('number' === typeof idx) { - parents[0].location = common.locations[idx] + parents[0].location = common.locations[idx]; } - }) + }); matches['**.ani.fLocX'].forEach(([idxs, parents]) => { - parents[0].fromLocations = idxs.map(idx => common.locations[idx]) - }) + parents[0].fromLocations = idxs.map(idx => common.locations[idx]); + }); matches['**.ani.tLocX'].forEach(([idxs, parents]) => { - parents[0].toLocations = idxs.map(idx => common.locations[idx]) - }) + parents[0].toLocations = idxs.map(idx => common.locations[idx]); + }); matches['**.fLocX'].forEach(([idx, parents]) => { if ('number' === typeof idx) { - parents[0].fromLocation = common.locations[idx] + parents[0].fromLocation = common.locations[idx]; } - }) + }); matches['**.tLocX'].forEach(([idx, parents]) => { if ('number' === typeof idx) { - parents[0].toLocation = common.locations[idx] + parents[0].toLocation = common.locations[idx]; } - }) + }); } - common.warnings = [] + common.warnings = []; if (Array.isArray(c.himL)) { - common.warnings = c.himL.map(w => profile.parseWarning(ctx, w)) + common.warnings = c.himL.map(w => profile.parseWarning(ctx, w)); matches['**.himX'].forEach(([idx, parents]) => { if ('number' === typeof idx) { - parents[0].warning = common.warnings[idx] + parents[0].warning = common.warnings[idx]; } - }) + }); } - common.polylines = [] + common.polylines = []; if ((opt.polylines || opt.polyline) && Array.isArray(c.polyL)) { - common.polylines = c.polyL.map(p => profile.parsePolyline(ctx, p)) + common.polylines = c.polyL.map(p => profile.parsePolyline(ctx, p)); // todo: **.ani.poly -> parsePolyline() matches['**.polyG.polyXL'].forEach(([idxs, parents]) => { - const idx = idxs.find(idx => Boolean(common.polylines[idx])) // find any given polyline - parents[1].polyline = common.polylines[idx] - }) + const idx = idxs.find(idx => Boolean(common.polylines[idx])); // find any given polyline + parents[1].polyline = common.polylines[idx]; + }); } - return common -} + return common; +}; export { parseCommonData, -} +}; diff --git a/parse/date-time.js b/parse/date-time.js index 9a982c56f..554580953 100644 --- a/parse/date-time.js +++ b/parse/date-time.js @@ -1,49 +1,49 @@ -import {DateTime, FixedOffsetZone, IANAZone} from 'luxon' -import {luxonIANAZonesByProfile as timezones} from '../lib/luxon-timezones.js' +import {DateTime, FixedOffsetZone, IANAZone} from 'luxon'; +import {luxonIANAZonesByProfile as timezones} from '../lib/luxon-timezones.js'; const parseDaysOffset = (_, time) => { return time.length > 6 ? parseInt(time.slice(0, -6)) - : 0 -} + : 0; +}; const parseDateTime = (ctx, date, time, tzOffset = null, timestamp = false) => { - const {profile} = ctx + const {profile} = ctx; - const pDate = [date.substr(-8, 4), date.substr(-4, 2), date.substr(-2, 2)] + const pDate = [date.substr(-8, 4), date.substr(-4, 2), date.substr(-2, 2)]; if (!pDate[0] || !pDate[1] || !pDate[2]) { - throw new Error('invalid date format: ' + date) + throw new Error('invalid date format: ' + date); } - const pTime = [time.substr(-6, 2), time.substr(-4, 2), time.substr(-2, 2)] + const pTime = [time.substr(-6, 2), time.substr(-4, 2), time.substr(-2, 2)]; if (!pTime[0] || !pTime[1] || !pTime[2]) { - throw new Error('invalid time format: ' + time) + throw new Error('invalid time format: ' + time); } - const daysOffset = parseDaysOffset(ctx, time) + const daysOffset = parseDaysOffset(ctx, time); - let timezone + let timezone; if (tzOffset !== null) { - timezone = FixedOffsetZone.instance(tzOffset) + timezone = FixedOffsetZone.instance(tzOffset); } else if (timezones.has(profile)) { - timezone = timezones.get(profile) + timezone = timezones.get(profile); } else { - timezone = new IANAZone(profile.timezone) - timezones.set(profile, timezone) + timezone = new IANAZone(profile.timezone); + timezones.set(profile, timezone); } let dt = DateTime.fromISO(pDate.join('-') + 'T' + pTime.join(':'), { locale: profile.locale, zone: timezone, - }) + }); if (daysOffset > 0) { - dt = dt.plus({days: daysOffset}) + dt = dt.plus({days: daysOffset}); } return timestamp ? dt.toMillis() - : dt.toISO({suppressMilliseconds: true}) -} + : dt.toISO({suppressMilliseconds: true}); +}; export { parseDateTime, -} +}; diff --git a/parse/departure.js b/parse/departure.js index b8587cab3..be6df61b9 100644 --- a/parse/departure.js +++ b/parse/departure.js @@ -1,8 +1,8 @@ -import {createParseArrOrDep} from './arrival-or-departure.js' +import {createParseArrOrDep} from './arrival-or-departure.js'; -const DEPARTURE = 'd' -const parseDeparture = createParseArrOrDep(DEPARTURE) +const DEPARTURE = 'd'; +const parseDeparture = createParseArrOrDep(DEPARTURE); export { parseDeparture, -} +}; diff --git a/parse/find-remarks.js b/parse/find-remarks.js index f0a470ec2..33942e570 100644 --- a/parse/find-remarks.js +++ b/parse/find-remarks.js @@ -1,4 +1,4 @@ -import flatMap from 'lodash/flatMap.js' +import flatMap from 'lodash/flatMap.js'; // There are two kinds of notes: "remarks" (in `remL`) and HAFAS // Information Manager (HIM) notes (in `himL`). The former describe @@ -14,10 +14,10 @@ const findRemarks = (refs) => { return flatMap(refs, (ref) => { return [ref.warning, ref.hint] .filter(rem => Boolean(rem)) - .map(rem => [rem, ref]) - }) -} + .map(rem => [rem, ref]); + }); +}; export { findRemarks, -} +}; diff --git a/parse/hint.js b/parse/hint.js index f2e75de98..dcc75a2bb 100644 --- a/parse/hint.js +++ b/parse/hint.js @@ -1,7 +1,7 @@ const codesByIcon = Object.assign(Object.create(null), { cancel: 'cancelled', himWarn: 'disturbance', -}) +}); const linkTypesByCode = Object.assign(Object.create(null), { BB: 'stop-website', @@ -12,7 +12,7 @@ const linkTypesByCode = Object.assign(Object.create(null), { OZ: 'transit-authority', // todo: `{type: 'I',code: 'TD',icoX: 1,txtN: '8010224'}` // todo: `{type: 'I',code: 'TE',icoX: 1,txtN: '8024001'}` -}) +}); // todo: pass in tag list from hint reference, e.g.: // "tagL": [ @@ -117,20 +117,20 @@ const parseHint = (ctx, h) => { if (h.code in linkTypesByCode) { const text = h.txtN === 'NULL' ? null - : h.txtN - return {type: linkTypesByCode[h.code], text} + : h.txtN; + return {type: linkTypesByCode[h.code], text}; } if (h.code === 'TW' && h.txtN[0] === '$') { - return {type: 'local-fare-zone', text: h.txtN.slice(1)} + return {type: 'local-fare-zone', text: h.txtN.slice(1)}; } if (h.code === 'TW' && h.txtN[0] === '#') { - return {type: 'foreign-id', text: h.txtN.slice(1)} + return {type: 'foreign-id', text: h.txtN.slice(1)}; } } - const text = h.txtN && h.txtN.trim() || '' - const icon = h.icon || null - const code = h.code || icon && icon.type && codesByIcon[icon.type] || null + const text = h.txtN && h.txtN.trim() || ''; + const icon = h.icon || null; + const code = h.code || icon && icon.type && codesByIcon[icon.type] || null; if (h.type === 'M') { return { @@ -138,7 +138,7 @@ const parseHint = (ctx, h) => { summary: h.txtS && h.txtS.trim() || '', code, text, - } + }; } if (h.type === 'L') { @@ -147,14 +147,14 @@ const parseHint = (ctx, h) => { code: 'alternative-trip', text, tripId: h.jid, - } + }; } if (h.type === 'A' || h.type === 'I') { return { type: 'hint', code, text, - } + }; } if ( @@ -167,12 +167,12 @@ const parseHint = (ctx, h) => { type: 'status', code, text, - } + }; } - return null -} + return null; +}; export { parseHint, -} +}; diff --git a/parse/icon.js b/parse/icon.js index ad06ec60d..16f763ee3 100644 --- a/parse/icon.js +++ b/parse/icon.js @@ -1,20 +1,20 @@ const parseIcon = (ctx, i) => { if (i.res === 'Empty') { - return null + return null; } const res = { type: i.res || null, title: i.text || i.txt || i.txtS || null, - } + }; if (i.fg) { - res.fgColor = i.fg + res.fgColor = i.fg; } if (i.bg) { - res.bgColor = i.bg + res.bgColor = i.bg; } - return res -} + return res; +}; export { parseIcon, -} +}; diff --git a/parse/journey-leg.js b/parse/journey-leg.js index d825b7d9e..8e66d345a 100644 --- a/parse/journey-leg.js +++ b/parse/journey-leg.js @@ -1,52 +1,52 @@ -import {findRemarks} from './find-remarks.js' +import {findRemarks} from './find-remarks.js'; -const clone = obj => Object.assign({}, obj) +const clone = obj => Object.assign({}, obj); const addRemark = (stopoverOrLeg, remark) => { if (!Array.isArray(stopoverOrLeg.remarks)) { - stopoverOrLeg.remarks = [] + stopoverOrLeg.remarks = []; } - stopoverOrLeg.remarks.push(remark) -} + stopoverOrLeg.remarks.push(remark); +}; const applyRemarks = (leg, refs) => { for (let [remark, ref] of findRemarks(refs)) { - const {fromLocation, toLocation} = ref + const {fromLocation, toLocation} = ref; - let wholeLeg = true, fromI = 0, toI = 0 + let wholeLeg = true, fromI = 0, toI = 0; if (Array.isArray(leg.stopovers)) { - toI = leg.stopovers.length - 1 + toI = leg.stopovers.length - 1; // this fails if `s.stop` is a new object (not reference-equal) // todo: do this index- or ID-based if (fromLocation) { - fromI = leg.stopovers.findIndex(s => s.stop === fromLocation) + fromI = leg.stopovers.findIndex(s => s.stop === fromLocation); if (fromI < 0) { - continue + continue; } } if (toLocation) { - toI = leg.stopovers.findIndex(s => s.stop === toLocation) + toI = leg.stopovers.findIndex(s => s.stop === toLocation); if (toI < 0) { - continue + continue; } } - wholeLeg = fromI === 0 && toI === leg.stopovers.length - 1 + wholeLeg = fromI === 0 && toI === leg.stopovers.length - 1; } if (wholeLeg) { - addRemark(leg, remark) + addRemark(leg, remark); } else { for (let i = fromI; i <= toI; i++) { - const stopover = leg.stopovers[i] + const stopover = leg.stopovers[i]; if (stopover) { - addRemark(stopover, remark) + addRemark(stopover, remark); } } } // todo: `ref.tagL` } -} +}; // todo: pt.status, pt.isPartCncl // todo: pt.chRatingRT, pt.chgDurR, pt.minChg @@ -59,137 +59,137 @@ const applyRemarks = (leg, refs) => { // todo: what is pt.jny.lPassSt? const parseJourneyLeg = (ctx, pt, date) => { // pt = raw leg - const {profile, opt} = ctx + const {profile, opt} = ctx; const res = { origin: clone(pt.dep.location) || null, destination: clone(pt.arr.location), - } + }; // HAFAS seems to have a bug where a journey's first leg has a `dTZOffset` of `0`. // https://github.com/public-transport/hafas-client/issues/237 if (pt.type === 'WALK' && pt.dep.dTZOffset != pt.arr.aTZOffset) { if (pt.dep.dTZOffset == 0) { - pt.dep.dTZOffset = pt.arr.aTZOffset + pt.dep.dTZOffset = pt.arr.aTZOffset; } if (pt.arr.aTZOffset == 0) { - pt.arr.aTZOffset = pt.dep.dTZOffset + pt.arr.aTZOffset = pt.dep.dTZOffset; } } - const dep = profile.parseWhen(ctx, date, pt.dep.dTimeS, pt.dep.dTimeR, pt.dep.dTZOffset, pt.dep.dCncl) - res.departure = dep.when - res.plannedDeparture = dep.plannedWhen + const dep = profile.parseWhen(ctx, date, pt.dep.dTimeS, pt.dep.dTimeR, pt.dep.dTZOffset, pt.dep.dCncl); + res.departure = dep.when; + res.plannedDeparture = dep.plannedWhen; // todo: pt.dep.dProgType - res.departureDelay = dep.delay + res.departureDelay = dep.delay; if (dep.prognosedWhen) { - res.prognosedDeparture = dep.prognosedWhen + res.prognosedDeparture = dep.prognosedWhen; } - const arr = profile.parseWhen(ctx, date, pt.arr.aTimeS, pt.arr.aTimeR, pt.arr.aTZOffset, pt.arr.aCncl) - res.arrival = arr.when - res.plannedArrival = arr.plannedWhen + const arr = profile.parseWhen(ctx, date, pt.arr.aTimeS, pt.arr.aTimeR, pt.arr.aTZOffset, pt.arr.aCncl); + res.arrival = arr.when; + res.plannedArrival = arr.plannedWhen; // todo: pt.arr.aProgType - res.arrivalDelay = arr.delay + res.arrivalDelay = arr.delay; if (arr.prognosedWhen) { - res.prognosedArrival = arr.prognosedWhen + res.prognosedArrival = arr.prognosedWhen; } if (pt.jny && 'isRchbl' in pt.jny) { - res.reachable = Boolean(pt.jny.isRchbl) + res.reachable = Boolean(pt.jny.isRchbl); } if (pt.jny && pt.jny.polyline) { - res.polyline = pt.jny.polyline || null + res.polyline = pt.jny.polyline || null; } else if (pt.jny && pt.jny.poly) { - res.polyline = profile.parsePolyline(ctx, pt.jny.poly) + res.polyline = profile.parsePolyline(ctx, pt.jny.poly); } if (pt.type === 'WALK' || pt.type === 'TRSF' || pt.type === 'DEVI' || pt.type === 'CHKI') { - res.public = true - res.walking = true - res.distance = pt.gis && pt.gis.dist || null + res.public = true; + res.walking = true; + res.distance = pt.gis && pt.gis.dist || null; if (pt.type === 'TRSF') { - res.transfer = true + res.transfer = true; } if (pt.type === 'DEVI') { // todo: pt.resState, pt.resRecommendation - res.transfer = true + res.transfer = true; } if (pt.type === 'CHKI') { - res.checkin = true + res.checkin = true; } // https://gist.github.com/derhuerst/426d4b95aeae701843b1e9c23105b8d4#file-tripsearch-2018-12-05-http-L4207-L4229 if (opt.remarks && pt.gis && Array.isArray(pt.gis.msgL)) { - applyRemarks(res, pt.gis.msgL) + applyRemarks(res, pt.gis.msgL); } } else if (pt.type === 'JNY') { // todo: pull `public` value from `profile.products` - res.tripId = pt.jny.jid - res.line = pt.jny.line || null + res.tripId = pt.jny.jid; + res.line = pt.jny.line || null; // todo [breaking]: don't call parseStationName() here, add parseDirection() hook // todo: support pt.jny.dirL[] - res.direction = pt.jny.dirTxt && profile.parseStationName(ctx, pt.jny.dirTxt) || null + res.direction = pt.jny.dirTxt && profile.parseStationName(ctx, pt.jny.dirTxt) || null; if (pt.jny.pos) { res.currentLocation = { type: 'location', latitude: pt.jny.pos.y / 1000000, longitude: pt.jny.pos.x / 1000000, - } + }; } const arrPl = profile.parsePlatform(ctx, pt.arr.aPlatfS || (pt.arr.aPltfS !== undefined ? pt.arr.aPltfS.txt : null), pt.arr.aPlatfR || (pt.arr.aPltfR !== undefined ? pt.arr.aPltfR.txt - : null), pt.arr.aCncl) - res.arrivalPlatform = arrPl.platform - res.plannedArrivalPlatform = arrPl.plannedPlatform + : null), pt.arr.aCncl); + res.arrivalPlatform = arrPl.platform; + res.plannedArrivalPlatform = arrPl.plannedPlatform; if (arrPl.prognosedPlatform) { - res.prognosedArrivalPlatform = arrPl.prognosedPlatform + res.prognosedArrivalPlatform = arrPl.prognosedPlatform; } - res.arrivalPrognosisType = profile.parsePrognosisType(ctx, pt.arr.aProgType) || null + res.arrivalPrognosisType = profile.parsePrognosisType(ctx, pt.arr.aProgType) || null; const depPl = profile.parsePlatform(ctx, pt.dep.dPlatfS || (pt.dep.dPltfS !== undefined ? pt.dep.dPltfS.txt : null), pt.dep.dPlatfR || (pt.dep.dPltfR !== undefined ? pt.dep.dPltfR.txt - : null), pt.dep.dCncl) - res.departurePlatform = depPl.platform - res.plannedDeparturePlatform = depPl.plannedPlatform + : null), pt.dep.dCncl); + res.departurePlatform = depPl.platform; + res.plannedDeparturePlatform = depPl.plannedPlatform; if (depPl.prognosedPlatform) { - res.prognosedDeparturePlatform = depPl.prognosedPlatform + res.prognosedDeparturePlatform = depPl.prognosedPlatform; } - res.departurePrognosisType = profile.parsePrognosisType(ctx, pt.dep.dProgType) || null + res.departurePrognosisType = profile.parsePrognosisType(ctx, pt.dep.dProgType) || null; if (opt.stopovers && pt.jny.stopL) { - const stopL = pt.jny.stopL - res.stopovers = stopL.map(s => profile.parseStopover(ctx, s, date)) + const stopL = pt.jny.stopL; + res.stopovers = stopL.map(s => profile.parseStopover(ctx, s, date)); if (opt.remarks && Array.isArray(pt.jny.msgL)) { - applyRemarks(res, pt.jny.msgL) + applyRemarks(res, pt.jny.msgL); // todo: parse & use `code: EXTERNAL_ID` remarks? } // filter stations the train passes without stopping, as this doesn't comply with fptf (yet) - res.stopovers = res.stopovers.filter((x) => !x.passBy) + res.stopovers = res.stopovers.filter((x) => !x.passBy); } else if (opt.remarks && Array.isArray(pt.jny.msgL)) { - applyRemarks(res, pt.jny.msgL) + applyRemarks(res, pt.jny.msgL); } - const freq = pt.jny.freq || {} + const freq = pt.jny.freq || {}; // todo: expose `res.cycle` even if only one field exists (breaking) // todo [breaking]: rename to something more intuitive, e.g. res.headways.{min,max,nrOfTrips} if (freq.minC && freq.maxC) { res.cycle = { min: freq.minC * 60, max: freq.maxC * 60, - } + }; // nr of connections in this frequency, from now on if (freq.numC) { - res.cycle.nr = freq.numC + res.cycle.nr = freq.numC; } } @@ -197,29 +197,29 @@ const parseJourneyLeg = (ctx, pt, date) => { // pt = raw leg const parseAlternative = (a) => { // todo: parse this just like a `leg` (breaking) // todo: parse `a.stopL`, `a.ctxRecon`, `a.msgL` - const st0 = Array.isArray(a.stopL) && a.stopL[0] || {} + const st0 = Array.isArray(a.stopL) && a.stopL[0] || {}; const when = st0 ? profile.parseWhen(ctx, date, st0.dTimeS, st0.dTimeR, st0.dTZOffset, st0.dCncl) - : null + : null; return { tripId: a.jid, line: a.line || null, direction: a.dirTxt || null, ...when, - } - } - res.alternatives = freq.jnyL.map(parseAlternative) + }; + }; + res.alternatives = freq.jnyL.map(parseAlternative); } } if (pt.arr.aCncl || pt.dep.dCncl) { - res.cancelled = true - Object.defineProperty(res, 'canceled', {value: true}) + res.cancelled = true; + Object.defineProperty(res, 'canceled', {value: true}); } - return res -} + return res; +}; export { parseJourneyLeg, -} +}; diff --git a/parse/journey.js b/parse/journey.js index b1cd8bd6d..b39fc7eeb 100644 --- a/parse/journey.js +++ b/parse/journey.js @@ -1,4 +1,4 @@ -import {findRemarks} from './find-remarks.js' +import {findRemarks} from './find-remarks.js'; // todo: c.conSubscr (e.g. `F`) // todo: c.trfRes x vbb-parse-ticket @@ -13,16 +13,16 @@ import {findRemarks} from './find-remarks.js' // todo: c.intvlSubscr (e.g. `F`) const parseJourney = (ctx, j) => { // j = raw jouney - const {profile, opt} = ctx + const {profile, opt} = ctx; - const legs = [] + const legs = []; for (const l of j.secL) { - let date = j.date + let date = j.date; // Next-day DEVI legs in an overnight journey lack both // - the "01" prefix in {dep.d,arr.a}Time{S,R} and // - the jny.trainStartDate field. // However, we can use the previous leg's effective date. - const prevLeg = legs[legs.length - 1] || null + const prevLeg = legs[legs.length - 1] || null; if (l.type === 'DEVI' && prevLeg?.arrival) { // todo: parse effective date from jny.ctxRecon/gis.ctx instead? // todo: prefer plannedArrival? @@ -30,47 +30,47 @@ const parseJourney = (ctx, j) => { // j = raw jouney prevLeg.arrival.slice(0, 4), // year prevLeg.arrival.slice(5, 7), // month prevLeg.arrival.slice(8, 10), // day - ].join('') + ].join(''); } - const leg = profile.parseJourneyLeg(ctx, l, date) - legs.push(leg) + const leg = profile.parseJourneyLeg(ctx, l, date); + legs.push(leg); } const res = { type: 'journey', legs, refreshToken: j.recon && j.recon.ctx || j.ctxRecon || null, - } + }; - const freq = j.freq || {} + const freq = j.freq || {}; if (freq.minC || freq.maxC) { - res.cycle = {} + res.cycle = {}; if (freq.minC) { - res.cycle.min = freq.minC * 60 + res.cycle.min = freq.minC * 60; } if (freq.maxC) { - res.cycle.max = freq.maxC * 60 + res.cycle.max = freq.maxC * 60; } // nr of connections in this frequency, from now on if (freq.numC) { - res.cycle.nr = freq.numC + res.cycle.nr = freq.numC; } } if (opt.remarks && Array.isArray(j.msgL)) { res.remarks = findRemarks(j.msgL) - .map(([remark]) => remark) + .map(([remark]) => remark); } if (opt.scheduledDays && j.sDays) { // todo [breaking]: rename to scheduledDates - res.scheduledDays = profile.parseScheduledDays(ctx, j.sDays) + res.scheduledDays = profile.parseScheduledDays(ctx, j.sDays); } - return res -} + return res; +}; export { parseJourney, -} +}; diff --git a/parse/line.js b/parse/line.js index 7129166f8..995a15f17 100644 --- a/parse/line.js +++ b/parse/line.js @@ -1,10 +1,10 @@ -import slugg from 'slugg' +import slugg from 'slugg'; const parseLine = ({profile}, p) => { if (!p) { - return null + return null; } // todo: handle this upstream - const name = p.line || p.addName || p.name || null // wtf + const name = p.line || p.addName || p.name || null; // wtf const res = { type: 'line', // This is terrible, but FPTF demands an ID. Let's pray for HAFAS. @@ -16,42 +16,42 @@ const parseLine = ({profile}, p) => { fahrtNr: p.prodCtx && p.prodCtx.num || null, name, public: true, - } + }; // todo: what is p.number? // todo: what is p.prodCtx.catCode? if (p.prodCtx && 'string' === typeof p.prodCtx.admin) { - res.adminCode = p.prodCtx.admin + res.adminCode = p.prodCtx.admin; } if (p.prodCtx && 'string' === typeof p.prodCtx.catOut) { - const productName = p.prodCtx.catOut.trim() + const productName = p.prodCtx.catOut.trim(); if (productName != '') { - res.productName = productName + res.productName = productName; } } if ('cls' in p) { // todo: use profile.products.find() for this - const byBitmask = [] + const byBitmask = []; for (let product of profile.products) { for (let bitmask of product.bitmasks) { - byBitmask[bitmask] = product + byBitmask[bitmask] = product; } } // todo: what if `p.cls` is the sum of two bitmasks? - const product = byBitmask[parseInt(p.cls)] - res.mode = product && product.mode || null - res.product = product && product.id || null + const product = byBitmask[parseInt(p.cls)]; + res.mode = product && product.mode || null; + res.product = product && product.id || null; } if (p.operator) { - res.operator = p.operator + res.operator = p.operator; } // todo: move up - return res -} + return res; +}; export { parseLine, -} +}; diff --git a/parse/location.js b/parse/location.js index 224a9dcb1..c62599da1 100644 --- a/parse/location.js +++ b/parse/location.js @@ -1,11 +1,11 @@ -import {parse} from 'qs' -import get from 'lodash/get.js' +import {parse} from 'qs'; +import get from 'lodash/get.js'; -const POI = 'P' -const STATION = 'S' -const ADDRESS = 'A' +const POI = 'P'; +const STATION = 'S'; +const ADDRESS = 'A'; -const leadingZeros = /^0+/ +const leadingZeros = /^0+/; // todo: what is l.wt? is it "weight"? // - `6733` for 8013074 with p/vmt @@ -15,35 +15,35 @@ const leadingZeros = /^0+/ // todo: `i` param in `lid` (e.g. `A=1@O=Zöberitz@X=12033455@Y=51504612@U=80@L=8013414@i=A×de:15088:8013414@`) const parseLocation = (ctx, l) => { - const {profile, opt} = ctx + const {profile, opt} = ctx; - const lid = parse(l.lid, {delimiter: '@'}) + const lid = parse(l.lid, {delimiter: '@'}); const res = { type: 'location', id: (l.extId || lid.L || '').replace(leadingZeros, '') || null, - } + }; if (l.crd) { - res.latitude = l.crd.y / 1000000 - res.longitude = l.crd.x / 1000000 + res.latitude = l.crd.y / 1000000; + res.longitude = l.crd.x / 1000000; } else if ('X' in lid && 'Y' in lid) { - res.latitude = lid.Y / 1000000 - res.longitude = lid.X / 1000000 + res.latitude = lid.Y / 1000000; + res.longitude = lid.X / 1000000; } if (l.type === STATION) { // todo: https://github.com/public-transport/hafas-client/issues/151 - const locL = get(ctx.res, ['common', 'locL'], []) + const locL = get(ctx.res, ['common', 'locL'], []); const mMastLocX = 'mMastLocX' in l ? l.mMastLocX - : NaN + : NaN; const subStops = (l.stopLocL || []) .filter(locX => locX !== mMastLocX) .map(locX => locL[locX]) .filter(s => Boolean(s)) .map(s => profile.parseLocation(ctx, s)) - .filter(stop => Boolean(stop)) + .filter(stop => Boolean(stop)); const stop = { type: l.isMainMast || subStops.length > 0 @@ -56,24 +56,24 @@ const parseLocation = (ctx, l) => { location: 'number' === typeof res.latitude ? res : null, // todo: remove `.id` - } + }; if (opt.subStops && subStops.length > 0) { - stop.stops = subStops + stop.stops = subStops; } if ('pCls' in l) { - stop.products = profile.parseProductsBitmask(ctx, l.pCls) + stop.products = profile.parseProductsBitmask(ctx, l.pCls); } if ('meta' in l) { - stop.isMeta = Boolean(l.meta) + stop.isMeta = Boolean(l.meta); } - const mMastLoc = locL[mMastLocX] + const mMastLoc = locL[mMastLocX]; if (mMastLoc) { stop.station = { ...profile.parseLocation(ctx, mMastLoc), type: 'station', // todo: this should be handled differently - } + }; } if (opt.entrances) { @@ -82,14 +82,14 @@ const parseLocation = (ctx, l) => { .filter(l => Boolean(l)) .map(l => profile.parseLocation(ctx, l)) .filter(loc => Boolean(loc)) - .map(loc => loc.location) + .map(loc => loc.location); if (entrances.length > 0) { - stop.entrances = entrances + stop.entrances = entrances; } } if (opt.linesOfStops && Array.isArray(l.lines)) { - stop.lines = l.lines + stop.lines = l.lines; } const locHints = (l.remarkRefs || []) @@ -97,72 +97,72 @@ const parseLocation = (ctx, l) => { .filter(({tagL}) => tagL.includes('RES_LOC') || tagL.find(t => t.slice(0, 8) === 'RES_LOC_'), // e.g. `RES_LOC_H3` ) - .map(ref => ref.hint) + .map(ref => ref.hint); const hints = [ ...l.hints || [], ...locHints, - ] - const byType = type => hints.find(h => h.type === type) + ]; + const byType = type => hints.find(h => h.type === type); - const transitAuthority = (byType('transit-authority') || {}).text + const transitAuthority = (byType('transit-authority') || {}).text; if (transitAuthority) { - stop.transitAuthority = transitAuthority + stop.transitAuthority = transitAuthority; } - const dhid = (byType('stop-dhid') || {}).text + const dhid = (byType('stop-dhid') || {}).text; if (dhid) { if (!stop.ids) { - stop.ids = {} + stop.ids = {}; } - stop.ids.dhid = dhid + stop.ids.dhid = dhid; } const otherIds = hints .filter(h => h.type === 'foreign-id') .filter(h => 'string' === typeof h.text && h.text.includes(':')) .map(({text}) => { - const i = text.indexOf(':') - return [text.slice(0, i), text.slice(i + 1)] + const i = text.indexOf(':'); + return [text.slice(0, i), text.slice(i + 1)]; }) - .filter(([src]) => src !== 'NULL') + .filter(([src]) => src !== 'NULL'); if (otherIds.length > 0) { if (!stop.ids) { - stop.ids = {} + stop.ids = {}; } for (const [src, id] of otherIds) { - stop.ids[src] = id + stop.ids[src] = id; } } - return stop + return stop; } if (l.type === ADDRESS) { - res.address = l.name + res.address = l.name; } else { - res.name = l.name + res.name = l.name; } if (l.type === POI) { - res.poi = true + res.poi = true; } - return res -} + return res; +}; // We use a "visited list" to prevent endless recursion. // todo: can we use a WeakMap here? -const seen = Symbol('parseLocation seen items') +const seen = Symbol('parseLocation seen items'); const parseLocationWithoutCycles = (ctx, l, ...args) => { if (ctx[seen] && ctx[seen].includes(l)) { - return null + return null; } const newSeen = ctx[seen] ? [...ctx[seen], l] - : [l] - return parseLocation({...ctx, [seen]: newSeen}, l, ...args) -} + : [l]; + return parseLocation({...ctx, [seen]: newSeen}, l, ...args); +}; export { parseLocationWithoutCycles as parseLocation, -} +}; diff --git a/parse/movement.js b/parse/movement.js index ff429ae45..ba9691c62 100644 --- a/parse/movement.js +++ b/parse/movement.js @@ -5,7 +5,7 @@ // todo: what is m.ani.dirGeo[n]? maybe the speed? // todo: what is m.ani.proc[n]? wut? const parseMovement = (ctx, m) => { // m = raw movement - const {profile, opt} = ctx + const {profile, opt} = ctx; const res = { direction: m.dirTxt @@ -26,7 +26,7 @@ const parseMovement = (ctx, m) => { // m = raw movement .filter(s => Boolean(s.location)) .map(s => profile.parseStopover(ctx, s, m.date)), frames: [], - } + }; if (m.ani) { // todo: ani.dirGeo, ani.fLocX, ani.proc, ani.procAbs, ani.state, ani.stcOutputX @@ -37,22 +37,22 @@ const parseMovement = (ctx, m) => { // m = raw movement origin: m.ani.fromLocations[i] || null, destination: m.ani.toLocations[i] || null, t: m.ani.mSec[i], - }) + }); } } if (opt.polylines) { if (m.ani.poly) { - res.polyline = profile.parsePolyline(ctx, m.ani.poly) + res.polyline = profile.parsePolyline(ctx, m.ani.poly); } else if (m.ani.polyline) { - res.polyline = m.ani.polyline + res.polyline = m.ani.polyline; } } } - return res -} + return res; +}; export { parseMovement, -} +}; diff --git a/parse/nearby.js b/parse/nearby.js index 26756600b..68bbafef7 100644 --- a/parse/nearby.js +++ b/parse/nearby.js @@ -5,11 +5,11 @@ // todo: what is s.dur? const parseNearby = (ctx, n) => { // n = raw nearby location - const res = ctx.profile.parseLocation(ctx, n) - res.distance = n.dist - return res -} + const res = ctx.profile.parseLocation(ctx, n); + res.distance = n.dist; + return res; +}; export { parseNearby, -} +}; diff --git a/parse/operator.js b/parse/operator.js index 7a2488356..8e7a99186 100644 --- a/parse/operator.js +++ b/parse/operator.js @@ -1,17 +1,17 @@ -import slugg from 'slugg' +import slugg from 'slugg'; const parseOperator = (ctx, a) => { - const name = a.name && a.name.trim() + const name = a.name && a.name.trim(); if (!name) { - return null + return null; } return { type: 'operator', id: slugg(a.name), // todo: find a more reliable way name, - } -} + }; +}; export { parseOperator, -} +}; diff --git a/parse/platform.js b/parse/platform.js index 5e347a4ea..fe2b96336 100644 --- a/parse/platform.js +++ b/parse/platform.js @@ -1,20 +1,20 @@ const parsePlatform = (ctx, platfS, platfR, cncl = false) => { - let planned = platfS || null - let prognosed = platfR || null + let planned = platfS || null; + let prognosed = platfR || null; if (cncl) { return { platform: null, plannedPlatform: planned, prognosedPlatform: prognosed, - } + }; } return { platform: prognosed || planned, plannedPlatform: planned, - } -} + }; +}; export { parsePlatform, -} +}; diff --git a/parse/polyline.js b/parse/polyline.js index bc83da62c..8582ab3bd 100644 --- a/parse/polyline.js +++ b/parse/polyline.js @@ -1,16 +1,16 @@ -import _googlePolyline from 'google-polyline' -import distance from 'gps-distance' +import _googlePolyline from 'google-polyline'; +import distance from 'gps-distance'; -const {decode} = _googlePolyline +const {decode} = _googlePolyline; // todo: what is p.delta? // todo: what is p.type? // todo: what is p.crdEncS? // todo: what is p.crdEncF? const parsePolyline = (ctx, p) => { // p = raw polyline - const points = decode(p.crdEncYX) + const points = decode(p.crdEncYX); if (points.length === 0) { - return null + return null; } const res = points.map(([lat, lon]) => ({ @@ -20,31 +20,31 @@ const parsePolyline = (ctx, p) => { // p = raw polyline type: 'Point', coordinates: [lon, lat], }, - })) + })); if (Array.isArray(p.ppLocRefL)) { for (let ref of p.ppLocRefL) { - const p = res[ref.ppIdx] + const p = res[ref.ppIdx]; if (p && ref.location) { - p.properties = ref.location + p.properties = ref.location; } } // Often there is one more point right next to each point at a station. // We filter them here if they are < 5m from each other. for (let i = 1; i < res.length; i++) { - const p1 = res[i - 1].geometry.coordinates - const p2 = res[i].geometry.coordinates - const d = distance(p1[1], p1[0], p2[1], p2[0]) + const p1 = res[i - 1].geometry.coordinates; + const p2 = res[i].geometry.coordinates; + const d = distance(p1[1], p1[0], p2[1], p2[0]); if (d >= 0.005) { - continue + continue; } - const l1 = Object.keys(res[i - 1].properties).length - const l2 = Object.keys(res[i].properties).length + const l1 = Object.keys(res[i - 1].properties).length; + const l2 = Object.keys(res[i].properties).length; if (l1 === 0 && l2 > 0) { - res.splice(i - 1, 1) + res.splice(i - 1, 1); } else if (l2 === 0 && l1 > 0) { - res.splice(i, 1) + res.splice(i, 1); } } } @@ -52,9 +52,9 @@ const parsePolyline = (ctx, p) => { // p = raw polyline return { type: 'FeatureCollection', features: res, - } -} + }; +}; export { parsePolyline, -} +}; diff --git a/parse/products-bitmask.js b/parse/products-bitmask.js index 404d55f90..550407ac8 100644 --- a/parse/products-bitmask.js +++ b/parse/products-bitmask.js @@ -1,26 +1,26 @@ const parseBitmask = ({profile}, bitmask) => { - const res = {} + const res = {}; for (let product of profile.products) { - res[product.id] = false + res[product.id] = false; } const bits = bitmask.toString(2) .split('') .map(i => parseInt(i)) - .reverse() + .reverse(); for (let i = 0; i < bits.length; i++) { if (!bits[i]) { - continue + continue; } // ignore `0` - const product = profile.products.find(p => p.bitmasks.includes(Math.pow(2, i))) + const product = profile.products.find(p => p.bitmasks.includes(Math.pow(2, i))); if (product) { - res[product.id] = true + res[product.id] = true; } } - return res -} + return res; +}; export { parseBitmask, -} +}; diff --git a/parse/prognosis-type.js b/parse/prognosis-type.js index 99ae07b82..dbb462a8d 100644 --- a/parse/prognosis-type.js +++ b/parse/prognosis-type.js @@ -3,9 +3,9 @@ const parsePrognosisType = (_, progType) => { PROGNOSED: 'prognosed', CALCULATED: 'calculated', // todo: are there more? - }[progType] || null -} + }[progType] || null; +}; export { parsePrognosisType, -} +}; diff --git a/parse/scheduled-days.js b/parse/scheduled-days.js index 912ed533b..474c59deb 100644 --- a/parse/scheduled-days.js +++ b/parse/scheduled-days.js @@ -1,4 +1,4 @@ -import {DateTime} from 'luxon' +import {DateTime} from 'luxon'; // todo: DRY with parse/date-time.js const parseDate = (date) => { @@ -6,42 +6,42 @@ const parseDate = (date) => { year: parseInt(date.substr(-8, 4)), month: parseInt(date.substr(-4, 2)), day: parseInt(date.substr(-2, 2)), - } + }; if (!Number.isInteger(res.year) || !Number.isInteger(res.month) || !Number.isInteger(res.day)) { - throw new Error('invalid date format: ' + date) + throw new Error('invalid date format: ' + date); } - return res -} + return res; +}; const parseScheduledDays = (ctx, sDays) => { - const {profile} = ctx + const {profile} = ctx; // sDaysB is a bitmap mapping all days from fpB (first date of schedule) to fpE (last date in schedule). - const {fpB, fpE} = ctx.res + const {fpB, fpE} = ctx.res; if (!sDays.sDaysB || !fpB || !fpE) { - return null + return null; } - const sDaysB = Buffer.from(sDays.sDaysB, 'hex') - const res = Object.create(null) + const sDaysB = Buffer.from(sDays.sDaysB, 'hex'); + const res = Object.create(null); - const _fpB = parseDate(fpB) + const _fpB = parseDate(fpB); let d = DateTime.fromObject({ year: _fpB.year, month: _fpB.month, day: _fpB.day, hour: 0, minute: 0, second: 0, millisecond: 0, }, { zone: profile.timezone, locale: profile.locale, - }) + }); for (let b = 0; b < sDaysB.length; b++) { for (let i = 0; i < 8; i++) { - res[d.toISODate()] = (sDaysB[b] & Math.pow(2, 7 - i)) > 0 - d = d.plus({days: 1}) + res[d.toISODate()] = (sDaysB[b] & Math.pow(2, 7 - i)) > 0; + d = d.plus({days: 1}); } } - return res -} + return res; +}; export { parseScheduledDays, -} +}; diff --git a/parse/stopover.js b/parse/stopover.js index 76ae9b8f1..392f8f3b9 100644 --- a/parse/stopover.js +++ b/parse/stopover.js @@ -1,12 +1,12 @@ -import {findRemarks} from './find-remarks.js' +import {findRemarks} from './find-remarks.js'; const parseStopover = (ctx, st, date) => { // st = raw stopover - const {profile, opt} = ctx + const {profile, opt} = ctx; - const arr = profile.parseWhen(ctx, date, st.aTimeS, st.aTimeR, st.aTZOffset, st.aCncl) - const arrPl = profile.parsePlatform(ctx, st.aPlatfS || st.aPltfS && st.aPltfS.txt || null, st.aPlatfR || st.aPltfR && st.aPltfR.txt || null, st.aCncl) - const dep = profile.parseWhen(ctx, date, st.dTimeS, st.dTimeR, st.dTZOffset, st.dCncl) - const depPl = profile.parsePlatform(ctx, st.dPlatfS || st.dPltfS && st.dPltfS.txt || null, st.dPlatfR || st.dPltfR && st.dPltfR.txt || null, st.dCncl) + const arr = profile.parseWhen(ctx, date, st.aTimeS, st.aTimeR, st.aTZOffset, st.aCncl); + const arrPl = profile.parsePlatform(ctx, st.aPlatfS || st.aPltfS && st.aPltfS.txt || null, st.aPlatfR || st.aPltfR && st.aPltfR.txt || null, st.aCncl); + const dep = profile.parseWhen(ctx, date, st.dTimeS, st.dTimeR, st.dTZOffset, st.dCncl); + const depPl = profile.parsePlatform(ctx, st.dPlatfS || st.dPltfS && st.dPltfS.txt || null, st.dPlatfR || st.dPltfR && st.dPltfR.txt || null, st.dCncl); const res = { stop: st.location || null, @@ -22,43 +22,43 @@ const parseStopover = (ctx, st, date) => { // st = raw stopover departurePlatform: depPl.platform, departurePrognosisType: profile.parsePrognosisType(ctx, st.dProgType), plannedDeparturePlatform: depPl.plannedPlatform, - } + }; if (arr.prognosedWhen) { - res.prognosedArrival = arr.prognosedWhen + res.prognosedArrival = arr.prognosedWhen; } if (arrPl.prognosedPlatform) { - res.prognosedArrivalPlatform = arrPl.prognosedPlatform + res.prognosedArrivalPlatform = arrPl.prognosedPlatform; } if (dep.prognosedWhen) { - res.prognosedDeparture = dep.prognosedWhen + res.prognosedDeparture = dep.prognosedWhen; } if (depPl.prognosedPlatform) { - res.prognosedDeparturePlatform = depPl.prognosedPlatform + res.prognosedDeparturePlatform = depPl.prognosedPlatform; } // mark stations the train passes without stopping if (st.dInS === false && st.aOutS === false) { - res.passBy = true + res.passBy = true; } if (st.aCncl || st.dCncl) { - res.cancelled = true - Object.defineProperty(res, 'canceled', {value: true}) + res.cancelled = true; + Object.defineProperty(res, 'canceled', {value: true}); } if (st.isAdd) { - res.additional = true + res.additional = true; } if (opt.remarks && Array.isArray(st.msgL)) { res.remarks = findRemarks(st.msgL) - .map(([remark]) => remark) + .map(([remark]) => remark); } - return res -} + return res; +}; export { parseStopover, -} +}; diff --git a/parse/trip.js b/parse/trip.js index 207da87d8..eef80bf83 100644 --- a/parse/trip.js +++ b/parse/trip.js @@ -1,9 +1,9 @@ -import minBy from 'lodash/minBy.js' -import maxBy from 'lodash/maxBy.js' -import last from 'lodash/last.js' +import minBy from 'lodash/minBy.js'; +import maxBy from 'lodash/maxBy.js'; +import last from 'lodash/last.js'; const parseTrip = (ctx, t) => { // t = raw trip - const {profile, opt} = ctx + const {profile, opt} = ctx; // pretend the trip is a leg in a journey const fakeLeg = { @@ -15,39 +15,39 @@ const parseTrip = (ctx, t) => { // t = raw trip ? maxBy(t.stopL, 'idx') || last(t.stopL) : {}, jny: t, - } + }; // todo: this breaks if the trip starts on a different day // how does HAFAS do this? - const today = () => profile.formatDate(profile, Date.now()) - const date = t.date || today() + const today = () => profile.formatDate(profile, Date.now()); + const date = t.date || today(); - const trip = profile.parseJourneyLeg(ctx, fakeLeg, date) - trip.id = trip.tripId - delete trip.tripId - delete trip.reachable + const trip = profile.parseJourneyLeg(ctx, fakeLeg, date); + trip.id = trip.tripId; + delete trip.tripId; + delete trip.reachable; if (opt.scheduledDays) { - const nrOfStopovers = t.stopL.length + const nrOfStopovers = t.stopL.length; // trips seem to use sDaysL[], journeys use sDays const sDaysL = Array.isArray(t.sDaysL) ? t.sDaysL - : [] + : []; const matchingSDays = sDaysL.filter((sDays) => { - return sDays.fLocIdx === 0 && sDays.tLocIdx === nrOfStopovers - 1 - }) + return sDays.fLocIdx === 0 && sDays.tLocIdx === nrOfStopovers - 1; + }); // if there are >1 sDays, we don't know how to interpret them const sDays = matchingSDays.length === 1 ? matchingSDays[0] - : null + : null; // todo [breaking]: rename to scheduledDates - trip.scheduledDays = profile.parseScheduledDays(ctx, sDays) + trip.scheduledDays = profile.parseScheduledDays(ctx, sDays); } - return trip -} + return trip; +}; export { parseTrip, -} +}; diff --git a/parse/warning.js b/parse/warning.js index b0c5ecce4..888abcf24 100644 --- a/parse/warning.js +++ b/parse/warning.js @@ -1,9 +1,9 @@ -import brToNewline from '@derhuerst/br2nl' -import omit from 'lodash/omit.js' +import brToNewline from '@derhuerst/br2nl'; +import omit from 'lodash/omit.js'; const typesByIcon = Object.assign(Object.create(null), { HimWarn: 'status', -}) +}); const parseMsgEdge = (ctx) => (e) => { const res = omit(e, [ @@ -12,27 +12,27 @@ const parseMsgEdge = (ctx) => (e) => { 'fromLocation', 'tLocX', 'toLocation', - ]) - res.icon = e.icon || null - res.fromLocation = Array.isArray(e.fromLocations) && e.fromLocations[0] || e.fromLocation || null - res.toLocation = Array.isArray(e.toLocations) && e.toLocations[0] || e.toLocation || null - return res -} + ]); + res.icon = e.icon || null; + res.fromLocation = Array.isArray(e.fromLocations) && e.fromLocations[0] || e.fromLocation || null; + res.toLocation = Array.isArray(e.toLocations) && e.toLocations[0] || e.toLocation || null; + return res; +}; -const fallbackTime = '000000' // midnight +const fallbackTime = '000000'; // midnight const parseMsgEvent = (ctx) => (e) => { - const {profile} = ctx // todo: test that covers this + const {profile} = ctx; // todo: test that covers this return { fromLocation: Array.isArray(e.fromLocations) && e.fromLocations[0] || e.fromLocation || null, toLocation: Array.isArray(e.toLocations) && e.toLocations[0] || e.toLocation || null, start: profile.parseDateTime(ctx, e.fDate, e.fTime || fallbackTime, null), end: profile.parseDateTime(ctx, e.tDate, e.tTime || fallbackTime, null), sections: e.sectionNums || [], // todo: parse - } -} + }; +}; const parseWarning = (ctx, w) => { - const {profile, res: resp, common} = ctx + const {profile, res: resp, common} = ctx; // todo: https://github.com/marudor/BahnhofsAbfahrten/blob/46a74957d68edc15713112df44e1a25150f5a178/src/types/HAFAS/HimSearch.ts#L31-L53 // todo: act, pub, lead, tckr @@ -55,8 +55,8 @@ const parseWarning = (ctx, w) => { // tTime: '120000' } // todo: w.regionRefL & res.common.himMsgRegionL - const icon = w.icon || null - const type = icon && icon.type && typesByIcon[icon.type] || 'warning' + const icon = w.icon || null; + const type = icon && icon.type && typesByIcon[icon.type] || 'warning'; const res = { id: w.hid || null, @@ -69,63 +69,63 @@ const parseWarning = (ctx, w) => { : null, // todo: decode HTML entities? icon, // todo: parse icon priority: w.prio, - } + }; if ('prod' in w) { - res.products = profile.parseProductsBitmask(ctx, w.prod) + res.products = profile.parseProductsBitmask(ctx, w.prod); } if ('comp' in w) { - res.company = w.comp || null + res.company = w.comp || null; } // todo: parse to sth meaningful if ('cat' in w) { - res.category = w.cat + res.category = w.cat; } if (w.catRefL && resp.common && resp.common.himMsgCatL) { res.categories = w.catRefL .map(i => resp.common.himMsgCatL[i]) .filter(e => Boolean(e)) - .map(cat => cat.id) + .map(cat => cat.id); } if (w.edgeRefL && resp.common && resp.common.himMsgEdgeL) { res.edges = w.edgeRefL .map(i => resp.common.himMsgEdgeL[i]) .filter(e => Boolean(e)) - .map(parseMsgEdge(ctx)) + .map(parseMsgEdge(ctx)); } if (w.eventRefL && resp.common && resp.common.himMsgEventL) { res.events = w.eventRefL .map(i => resp.common.himMsgEventL[i]) .filter(e => Boolean(e)) - .map(parseMsgEvent(ctx)) + .map(parseMsgEvent(ctx)); } if (w.affProdRefL) { res.affectedLines = w.affProdRefL .map(i => common.lines[i]) - .filter(l => Boolean(l)) + .filter(l => Boolean(l)); } if (w.fromLocations) { - res.fromStops = w.fromLocations + res.fromStops = w.fromLocations; } if (w.toLocations) { - res.toStops = w.toLocations + res.toStops = w.toLocations; } if (w.sDate && w.sTime) { - res.validFrom = profile.parseDateTime(ctx, w.sDate, w.sTime, null) + res.validFrom = profile.parseDateTime(ctx, w.sDate, w.sTime, null); } if (w.eDate && w.eTime) { - res.validUntil = profile.parseDateTime(ctx, w.eDate, w.eTime, null) + res.validUntil = profile.parseDateTime(ctx, w.eDate, w.eTime, null); } if (w.lModDate && w.lModTime) { - res.modified = profile.parseDateTime(ctx, w.lModDate, w.lModTime, null) + res.modified = profile.parseDateTime(ctx, w.lModDate, w.lModTime, null); } - return res -} + return res; +}; export { parseWarning, -} +}; diff --git a/parse/when.js b/parse/when.js index d36d34158..f79aaa8ca 100644 --- a/parse/when.js +++ b/parse/when.js @@ -1,18 +1,18 @@ const parseWhen = (ctx, date, timeS, timeR, tzOffset, cncl = false) => { - const parse = ctx.profile.parseDateTime + const parse = ctx.profile.parseDateTime; let planned = timeS ? parse(ctx, date, timeS, tzOffset, false) - : null + : null; let prognosed = timeR ? parse(ctx, date, timeR, tzOffset, false) - : null - let delay = null + : null; + let delay = null; if (planned && prognosed) { - const tPlanned = parse(ctx, date, timeS, tzOffset, true) - const tPrognosed = parse(ctx, date, timeR, tzOffset, true) - delay = Math.round((tPrognosed - tPlanned) / 1000) + const tPlanned = parse(ctx, date, timeS, tzOffset, true); + const tPrognosed = parse(ctx, date, timeR, tzOffset, true); + delay = Math.round((tPrognosed - tPlanned) / 1000); } if (cncl) { @@ -21,15 +21,15 @@ const parseWhen = (ctx, date, timeS, timeR, tzOffset, cncl = false) => { plannedWhen: planned, prognosedWhen: prognosed, delay, - } + }; } return { when: prognosed || planned, plannedWhen: planned, delay, - } -} + }; +}; export { parseWhen, -} +}; diff --git a/retry.js b/retry.js index 09e9dd825..4b9e4dbec 100644 --- a/retry.js +++ b/retry.js @@ -1,41 +1,41 @@ -import retry from 'p-retry' -import {defaultProfile} from './lib/default-profile.js' +import retry from 'p-retry'; +import {defaultProfile} from './lib/default-profile.js'; const retryDefaults = { retries: 3, factor: 3, minTimeout: 5 * 1000, -} +}; const withRetrying = (profile, retryOpts = {}) => { - retryOpts = Object.assign({}, retryDefaults, retryOpts) + retryOpts = Object.assign({}, retryDefaults, retryOpts); // https://github.com/public-transport/hafas-client/issues/76#issuecomment-574408717 - const {request} = {...defaultProfile, ...profile} + const {request} = {...defaultProfile, ...profile}; const retryingRequest = (...args) => { const attempt = () => { return request(...args) .catch((err) => { if (err.isHafasError) { - throw err + throw err; } // continue if (err.code === 'ENOTFOUND') { // abort - const abortErr = new retry.AbortError(err) - Object.assign(abortErr, err) - throw abortErr + const abortErr = new retry.AbortError(err); + Object.assign(abortErr, err); + throw abortErr; } - throw err // continue - }) - } - return retry(attempt, retryOpts) - } + throw err; // continue + }); + }; + return retry(attempt, retryOpts); + }; return { ...profile, request: retryingRequest, - } -} + }; +}; export { withRetrying, -} +}; diff --git a/test/bvg-arrivals.js b/test/bvg-arrivals.js index 377173c0c..a006689e1 100644 --- a/test/bvg-arrivals.js +++ b/test/bvg-arrivals.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/bvg/index.js' -const res = require('./fixtures/bvg-arrivals.json') -import {bvgArrivals as expected} from './fixtures/bvg-arrivals.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/bvg/index.js'; +const res = require('./fixtures/bvg-arrivals.json'); +import {bvgArrivals as expected} from './fixtures/bvg-arrivals.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { direction: null, @@ -22,13 +22,13 @@ const opt = { includeRelatedStations: true, when: '2021-10-28T10:35:00+02:00', products: {}, -} +}; tap.test('parses an arrival correctly (BVG)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const arrivals = res.jnyL.map(d => profile.parseArrival(ctx, d)) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const arrivals = res.jnyL.map(d => profile.parseArrival(ctx, d)); - t.same(arrivals, expected) - t.end() -}) + t.same(arrivals, expected); + t.end(); +}); diff --git a/test/bvg-journey.js b/test/bvg-journey.js index e96276856..0054972b9 100644 --- a/test/bvg-journey.js +++ b/test/bvg-journey.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/bvg/index.js' -const res = require('./fixtures/bvg-journey.json') -import {bvgJourney as expected} from './fixtures/bvg-journey.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/bvg/index.js'; +const res = require('./fixtures/bvg-journey.json'); +import {bvgJourney as expected} from './fixtures/bvg-journey.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: null, @@ -29,13 +29,13 @@ const opt = { scheduledDays: true, departure: '2019-08-18T14:03:50+02:00', products: {}, -} +}; tap.test('parses a journey correctly (BVG)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const journey = profile.parseJourney(ctx, res.outConL[0]) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const journey = profile.parseJourney(ctx, res.outConL[0]); - t.same(journey, expected) - t.end() -}) + t.same(journey, expected); + t.end(); +}); diff --git a/test/bvg-radar.js b/test/bvg-radar.js index db0321270..ab02faec4 100644 --- a/test/bvg-radar.js +++ b/test/bvg-radar.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/bvg/index.js' -const res = require('./fixtures/bvg-radar.json') -import {bvgRadar as expected} from './fixtures/bvg-radar.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/bvg/index.js'; +const res = require('./fixtures/bvg-radar.json'); +import {bvgRadar as expected} from './fixtures/bvg-radar.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: 256, @@ -20,13 +20,13 @@ const opt = { polylines: true, when: '2019-08-19T21:00:00+02:00', products: {}, -} +}; tap.test('parses a radar() response correctly (BVG)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const movements = res.jnyL.map(m => profile.parseMovement(ctx, m)) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const movements = res.jnyL.map(m => profile.parseMovement(ctx, m)); - t.same(movements, expected) - t.end() -}) + t.same(movements, expected); + t.end(); +}); diff --git a/test/bvg-trip-with-occupancy.js b/test/bvg-trip-with-occupancy.js index 8e4da50f2..dca4b3f0b 100644 --- a/test/bvg-trip-with-occupancy.js +++ b/test/bvg-trip-with-occupancy.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/bvg/index.js' -const res = require('./fixtures/bvg-trip-with-occupancy.json') -import {bvgTripWithOccupancy as expected} from './fixtures/bvg-trip-with-occupancy.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/bvg/index.js'; +const res = require('./fixtures/bvg-trip-with-occupancy.json'); +import {bvgTripWithOccupancy as expected} from './fixtures/bvg-trip-with-occupancy.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { stopovers: true, @@ -21,13 +21,13 @@ const opt = { remarks: true, scheduledDays: true, when: '2021-10-28T09:28:00+02:00', -} +}; tap.test('parses an trip with occupancy correctly (BVG)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const trip = profile.parseTrip(ctx, res.journey) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const trip = profile.parseTrip(ctx, res.journey); - t.same(trip, expected) - t.end() -}) + t.same(trip, expected); + t.end(); +}); diff --git a/test/db-arrivals.js b/test/db-arrivals.js index c9ac14765..636aa774d 100644 --- a/test/db-arrivals.js +++ b/test/db-arrivals.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' -const res = require('./fixtures/db-arrivals.json') -import {dbArrivals as expected} from './fixtures/db-arrivals.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; +const res = require('./fixtures/db-arrivals.json'); +import {dbArrivals as expected} from './fixtures/db-arrivals.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { direction: null, @@ -22,13 +22,13 @@ const opt = { includeRelatedStations: true, when: '2019-08-19T20:30:00+02:00', products: {}, -} +}; tap.test('parses an arrival correctly (DB)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const arrivals = res.jnyL.map(d => profile.parseArrival(ctx, d)) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const arrivals = res.jnyL.map(d => profile.parseArrival(ctx, d)); - t.same(arrivals, expected) - t.end() -}) + t.same(arrivals, expected); + t.end(); +}); diff --git a/test/db-deps-with-destination.js b/test/db-deps-with-destination.js index a233dd6e5..9cc293919 100644 --- a/test/db-deps-with-destination.js +++ b/test/db-deps-with-destination.js @@ -1,16 +1,16 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' -const res = require('./fixtures/db-deps-with-destination.json') +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; +const res = require('./fixtures/db-deps-with-destination.json'); -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { direction: null, @@ -21,15 +21,15 @@ const opt = { includeRelatedStations: true, when: '2022-10-15T15:45:00+02:00', products: {}, -} +}; tap.test('parses departure.destination correctly (DB)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const departure = profile.parseDeparture(ctx, res.jnyL[0]) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const departure = profile.parseDeparture(ctx, res.jnyL[0]); - t.ok(departure.destination, 'missing departure.destination') - t.equal(departure.destination.type, 'stop', 'invalid departure.destination.type') - t.equal(departure.destination.id, '930200', 'invalid departure.destination.id') - t.end() -}) + t.ok(departure.destination, 'missing departure.destination'); + t.equal(departure.destination.type, 'stop', 'invalid departure.destination.type'); + t.equal(departure.destination.id, '930200', 'invalid departure.destination.id'); + t.end(); +}); diff --git a/test/db-journey-2.js b/test/db-journey-2.js index 7e89ad1c3..f5c274756 100644 --- a/test/db-journey-2.js +++ b/test/db-journey-2.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' -const res = require('./fixtures/db-journey-2.json') -import {dbJourney as expected} from './fixtures/db-journey-2.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; +const res = require('./fixtures/db-journey-2.json'); +import {dbJourney as expected} from './fixtures/db-journey-2.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: 4, @@ -29,13 +29,13 @@ const opt = { scheduledDays: false, departure: '2020-11-16T10:00:00+01:00', products: {}, -} +}; tap.test('parses a journey remarks without failing', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const journey = profile.parseJourney(ctx, res.outConL[2]) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const journey = profile.parseJourney(ctx, res.outConL[2]); - t.same(journey, expected) - t.end() -}) + t.same(journey, expected); + t.end(); +}); diff --git a/test/db-journey-additional-stopover.js b/test/db-journey-additional-stopover.js index 628435735..e891eb316 100644 --- a/test/db-journey-additional-stopover.js +++ b/test/db-journey-additional-stopover.js @@ -1,35 +1,35 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' +import {createRequire} from 'module'; -const require = createRequire(import.meta.url) +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; -const resAdditionalStopover = require('./fixtures/db-journey-additional-stopover.json') +const resAdditionalStopover = require('./fixtures/db-journey-additional-stopover.json'); -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: 1, stopovers: true, -} +}; // https://github.com/public-transport/hafas-client/issues/303 tap.test('parses a journey having a leg with an additional stopover', (t) => { - const common = profile.parseCommon({profile, opt, res: resAdditionalStopover}) - const ctx = {profile, opt, common, res: resAdditionalStopover} - const journey = profile.parseJourney(ctx, resAdditionalStopover.outConL[0]) - const stopovers = journey.legs[0].stopovers - - const stopoverRegular = stopovers[6] - const stopoverAdditional = stopovers[7] - t.notOk('additional' in stopoverRegular, 'regular stopover has attribute additional') - t.equal(stopoverAdditional.additional, true, 'additional stopover doesn\'t have attribute additional') - t.end() -}) + const common = profile.parseCommon({profile, opt, res: resAdditionalStopover}); + const ctx = {profile, opt, common, res: resAdditionalStopover}; + const journey = profile.parseJourney(ctx, resAdditionalStopover.outConL[0]); + const stopovers = journey.legs[0].stopovers; + + const stopoverRegular = stopovers[6]; + const stopoverAdditional = stopovers[7]; + t.notOk('additional' in stopoverRegular, 'regular stopover has attribute additional'); + t.equal(stopoverAdditional.additional, true, 'additional stopover doesn\'t have attribute additional'); + t.end(); +}); diff --git a/test/db-journey-fpB-fpE-2-years.js b/test/db-journey-fpB-fpE-2-years.js index 277b000a5..a26a8efa3 100644 --- a/test/db-journey-fpB-fpE-2-years.js +++ b/test/db-journey-fpB-fpE-2-years.js @@ -1,16 +1,16 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' -const res = require('./fixtures/db-journey-fpB-fpE-2-years.json') +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; +const res = require('./fixtures/db-journey-fpB-fpE-2-years.json'); -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: 1, @@ -28,12 +28,12 @@ const opt = { entrances: false, remarks: false, scheduledDays: true, -} +}; tap.test('parses journey.scheduledDays correctly with planning period of >1 year', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const journey = profile.parseJourney(ctx, res.outConL[0]) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const journey = profile.parseJourney(ctx, res.outConL[0]); // "fpB": "20211212", // "fpE": "20231209", @@ -771,6 +771,6 @@ tap.test('parses journey.scheduledDays correctly with planning period of >1 year '2023-12-07': false, '2023-12-08': false, '2023-12-09': false, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/db-journey-overnight.js b/test/db-journey-overnight.js index 14e52c45f..c76b0ebf2 100644 --- a/test/db-journey-overnight.js +++ b/test/db-journey-overnight.js @@ -1,19 +1,19 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' -const res0 = require('./fixtures/db-journey-overnight-0.json') -const expected0 = require('./fixtures/db-journey-overnight-0.expected.json') -const res1 = require('./fixtures/db-journey-overnight-1.json') -import {overnightJourney as expected1} from './fixtures/db-journey-overnight-1.expected.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; +const res0 = require('./fixtures/db-journey-overnight-0.json'); +const expected0 = require('./fixtures/db-journey-overnight-0.expected.json'); +const res1 = require('./fixtures/db-journey-overnight-1.json'); +import {overnightJourney as expected1} from './fixtures/db-journey-overnight-1.expected.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const baseOpt = { results: null, @@ -30,7 +30,7 @@ const baseOpt = { remarks: true, scheduledDays: false, products: {}, -} +}; tap.test('parses a journey across day with correct timestamps', (t) => { const opt = { @@ -38,15 +38,15 @@ tap.test('parses a journey across day with correct timestamps', (t) => { results: 4, stopovers: true, departure: '2023-11-13T22:00:00+01:00', - } + }; - const common = profile.parseCommon({profile, opt, res: res0}) - const ctx = {profile, opt, common, res: res0} - const journey = profile.parseJourney(ctx, res0.outConL[16]) + const common = profile.parseCommon({profile, opt, res: res0}); + const ctx = {profile, opt, common, res: res0}; + const journey = profile.parseJourney(ctx, res0.outConL[16]); - t.same(journey, expected0) - t.end() -}) + t.same(journey, expected0); + t.end(); +}); tap.test('parses a journey across dates with correct timestamps', (t) => { const opt = { @@ -54,12 +54,12 @@ tap.test('parses a journey across dates with correct timestamps', (t) => { results: 1, stopovers: true, departure: '2023-11-24T22:00+01:00', - } + }; - const common = profile.parseCommon({profile, opt, res: res1}) - const ctx = {profile, opt, common, res: res1} - const journey = profile.parseJourney(ctx, res1.outConL[0]) + const common = profile.parseCommon({profile, opt, res: res1}); + const ctx = {profile, opt, common, res: res1}; + const journey = profile.parseJourney(ctx, res1.outConL[0]); - t.same(journey, expected1) - t.end() -}) + t.same(journey, expected1); + t.end(); +}); diff --git a/test/db-journey-polyline.js b/test/db-journey-polyline.js index db83a2f73..cb101d0cf 100644 --- a/test/db-journey-polyline.js +++ b/test/db-journey-polyline.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' -const res = require('./fixtures/db-journey-polyline.json') -import {dbJourneyPolyline as expected} from './fixtures/db-journey-polyline.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; +const res = require('./fixtures/db-journey-polyline.json'); +import {dbJourneyPolyline as expected} from './fixtures/db-journey-polyline.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: null, @@ -29,13 +29,13 @@ const opt = { scheduledDays: false, departure: '2020-07-27T10:00+02:00', products: {}, -} +}; tap.test('parses a journey with an embedded polyline correctly', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const journey = profile.parseJourney(ctx, res.outConL[0]) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const journey = profile.parseJourney(ctx, res.outConL[0]); - t.same(journey, expected) - t.end() -}) + t.same(journey, expected); + t.end(); +}); diff --git a/test/db-journey-tzoffset-0.js b/test/db-journey-tzoffset-0.js index 136d2fcb1..da6e9773f 100644 --- a/test/db-journey-tzoffset-0.js +++ b/test/db-journey-tzoffset-0.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' -const resDTZOffset0 = require('./fixtures/db-journey-dtzoffset-0.json') -const resATZOffset0 = require('./fixtures/db-journey-atzoffset-0.json') +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; +const resDTZOffset0 = require('./fixtures/db-journey-dtzoffset-0.json'); +const resATZOffset0 = require('./fixtures/db-journey-atzoffset-0.json'); -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { stopovers: false, @@ -20,26 +20,26 @@ const opt = { subStops: true, entrances: true, remarks: true, -} +}; // https://github.com/public-transport/hafas-client/issues/237 tap.test('parses a journey whose first leg has a dTZOffset of 0 (#237)', (t) => { - const common = profile.parseCommon({profile, opt, res: resDTZOffset0}) - const ctx = {profile, opt, common, res: resDTZOffset0} - const journey = profile.parseJourney(ctx, resDTZOffset0.outConL[0]) + const common = profile.parseCommon({profile, opt, res: resDTZOffset0}); + const ctx = {profile, opt, common, res: resDTZOffset0}; + const journey = profile.parseJourney(ctx, resDTZOffset0.outConL[0]); - const firstLeg = journey.legs[0] - t.notOk((/Z$/).test(firstLeg.departure), 'firstLeg.departure has TZ offset "Z"') - t.end() -}) + const firstLeg = journey.legs[0]; + t.notOk((/Z$/).test(firstLeg.departure), 'firstLeg.departure has TZ offset "Z"'); + t.end(); +}); tap.test('parses a journey whose first leg has a aTZOffset of 0 (#237)', (t) => { - const common = profile.parseCommon({profile, opt, res: resATZOffset0}) - const ctx = {profile, opt, common, res: resATZOffset0} - const journey = profile.parseJourney(ctx, resATZOffset0.outConL[0]) - - const lastLeg = journey.legs[0] - t.notOk((/Z$/).test(lastLeg.departure), 'lastLeg.departure has TZ offset "Z"') - t.end() -}) + const common = profile.parseCommon({profile, opt, res: resATZOffset0}); + const ctx = {profile, opt, common, res: resATZOffset0}; + const journey = profile.parseJourney(ctx, resATZOffset0.outConL[0]); + + const lastLeg = journey.legs[0]; + t.notOk((/Z$/).test(lastLeg.departure), 'lastLeg.departure has TZ offset "Z"'); + t.end(); +}); diff --git a/test/db-journey.js b/test/db-journey.js index a4203e93a..9554c62d3 100644 --- a/test/db-journey.js +++ b/test/db-journey.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' -const res = require('./fixtures/db-journey.json') -import {dbJourney as expected} from './fixtures/db-journey.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; +const res = require('./fixtures/db-journey.json'); +import {dbJourney as expected} from './fixtures/db-journey.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: null, @@ -29,13 +29,13 @@ const opt = { scheduledDays: false, departure: '2020-04-10T20:33+02:00', products: {}, -} +}; tap.test('parses a journey with a DEVI leg correctly (DB)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const journey = profile.parseJourney(ctx, res.outConL[2]) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const journey = profile.parseJourney(ctx, res.outConL[2]); - t.same(journey, expected) - t.end() -}) + t.same(journey, expected); + t.end(); +}); diff --git a/test/db-netz-remarks.js b/test/db-netz-remarks.js index 773d6c8a0..fdf6cfc92 100644 --- a/test/db-netz-remarks.js +++ b/test/db-netz-remarks.js @@ -1,13 +1,13 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {parseCommonData as parseCommon} from '../parse/common.js' -import {defaultProfile} from '../lib/default-profile.js' -const res = require('./fixtures/db-netz-remarks.json') +import {parseCommonData as parseCommon} from '../parse/common.js'; +import {defaultProfile} from '../lib/default-profile.js'; +const res = require('./fixtures/db-netz-remarks.json'); const profile = { ...defaultProfile, @@ -18,16 +18,16 @@ const profile = { {id: 'b', bitmasks: [16, 32, 64, 128], name: 'B'}, {id: 'c', bitmasks: [256, 512], name: 'C'}, ], -} +}; const opt = { remarks: true, -} +}; tap.test('parseCommon parses a DB Netz response properly', (t) => { - const {warnings} = profile.parseCommon({profile, opt, res}) - t.pass('parsed without throwing') - const warning = warnings.find(w => w.id === 'HIM_FREETEXT_447862') + const {warnings} = profile.parseCommon({profile, opt, res}); + t.pass('parsed without throwing'); + const warning = warnings.find(w => w.id === 'HIM_FREETEXT_447862'); t.same(warning, { id: 'HIM_FREETEXT_447862', @@ -100,6 +100,6 @@ tap.test('parseCommon parses a DB Netz response properly', (t) => { validFrom: '2019-12-15T00:00:00+01:00', validUntil: '2020-05-29T04:00:00+02:00', modified: '2019-10-26T04:09:19+02:00', - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/db-stop.js b/test/db-stop.js index ffc8f4a7f..ec8aad70a 100644 --- a/test/db-stop.js +++ b/test/db-stop.js @@ -1,30 +1,30 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/db/index.js' -const res = require('./fixtures/db-stop.json') -import {dbStop as expected} from './fixtures/db-stop.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/db/index.js'; +const res = require('./fixtures/db-stop.json'); +import {dbStop as expected} from './fixtures/db-stop.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { linesOfStops: false, // parse & expose lines at the stop/station? subStops: true, entrances: true, remarks: true, -} +}; tap.test('parses a stop() response correctly (DB)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const stop = profile.parseLocation(ctx, res.locL[0]) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const stop = profile.parseLocation(ctx, res.locL[0]); - t.same(stop, expected) - t.end() -}) + t.same(stop, expected); + t.end(); +}); diff --git a/test/e2e/bls.js b/test/e2e/bls.js index 1da50abdf..c2fbacd72 100644 --- a/test/e2e/bls.js +++ b/test/e2e/bls.js @@ -1,13 +1,13 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as blsProfile} from '../../p/bls/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as blsProfile} from '../../p/bls/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(blsProfile.timezone, blsProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(blsProfile.timezone, blsProfile.locale, T_MOCK); const cfg = { when, @@ -17,13 +17,13 @@ const cfg = { minLongitude: 4.4604, maxLatitude: 47.2969, maxLongitude: 7.8607, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(blsProfile, 'public-transport/hafas-client:test') +const client = createClient(blsProfile, 'public-transport/hafas-client:test'); -const bernDennigkofengässli = '8590093' +const bernDennigkofengässli = '8590093'; tap.test('Dennigkofengässli to Schänzlihalde', async (t) => { const schänzlihalde = { @@ -32,12 +32,12 @@ tap.test('Dennigkofengässli to Schänzlihalde', async (t) => { address: 'Bern, Schänzlihalde 17', latitude: 46.952835, longitude: 7.447527, - } + }; const res = await client.journeys(bernDennigkofengässli, schänzlihalde, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -45,6 +45,6 @@ tap.test('Dennigkofengässli to Schänzlihalde', async (t) => { validate, fromId: bernDennigkofengässli, to: schänzlihalde, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/bvg.js b/test/e2e/bvg.js index 9b869c573..65607d818 100644 --- a/test/e2e/bvg.js +++ b/test/e2e/bvg.js @@ -1,34 +1,34 @@ // todo: DRY with vbb tests -import tap from 'tap' - -import isRoughlyEqual from 'is-roughly-equal' -import {DateTime} from 'luxon' -import flatMap from 'lodash/flatMap.js' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as bvgProfile} from '../../p/bvg/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {createVbbBvgValidators} from './lib/vbb-bvg-validators.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testJourneysWalkingSpeed} from './lib/journeys-walking-speed.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testLegCycleAlternatives} from './lib/leg-cycle-alternatives.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' -import {testArrivals} from './lib/arrivals.js' -import {testJourneysWithDetour} from './lib/journeys-with-detour.js' -import {testReachableFrom} from './lib/reachable-from.js' -import {testRemarks} from './lib/remarks.js' -import {testLines} from './lib/lines.js' - -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(bvgProfile.timezone, bvgProfile.locale, T_MOCK) +import tap from 'tap'; + +import isRoughlyEqual from 'is-roughly-equal'; +import {DateTime} from 'luxon'; +import flatMap from 'lodash/flatMap.js'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as bvgProfile} from '../../p/bvg/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {createVbbBvgValidators} from './lib/vbb-bvg-validators.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testJourneysWalkingSpeed} from './lib/journeys-walking-speed.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testLegCycleAlternatives} from './lib/leg-cycle-alternatives.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testJourneysWithDetour} from './lib/journeys-with-detour.js'; +import {testReachableFrom} from './lib/reachable-from.js'; +import {testRemarks} from './lib/remarks.js'; +import {testLines} from './lib/lines.js'; + +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(bvgProfile.timezone, bvgProfile.locale, T_MOCK); const { cfg, @@ -38,34 +38,34 @@ const { validateMovement, } = createVbbBvgValidators({ when, -}) +}); const validate = createValidate(cfg, { station: validateStation, journeyLeg: validateJourneyLeg, departure: validateDeparture, movement: validateMovement, -}) +}); -const client = createClient(bvgProfile, 'public-transport/hafas-client:test') +const client = createClient(bvgProfile, 'public-transport/hafas-client:test'); -const amrumerStr = '900009101' -const spichernstr = '900042101' -const bismarckstr = '900024201' -const westhafen = '900001201' -const wedding = '900009104' -const württembergallee = '900026153' -const tiergarten = '900003103' -const jannowitzbrücke = '900100004' +const amrumerStr = '900009101'; +const spichernstr = '900042101'; +const bismarckstr = '900024201'; +const westhafen = '900001201'; +const wedding = '900009104'; +const württembergallee = '900026153'; +const tiergarten = '900003103'; +const jannowitzbrücke = '900100004'; -const hour = 60 * 60 * 1000 +const hour = 60 * 60 * 1000; tap.test('journeys – Spichernstr. to Bismarckstr.', async (t) => { const res = await client.journeys(spichernstr, bismarckstr, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -73,11 +73,11 @@ tap.test('journeys – Spichernstr. to Bismarckstr.', async (t) => { validate, fromId: spichernstr, toId: bismarckstr, - }) + }); // todo: find a journey where there ticket info is always available - t.end() -}) + t.end(); +}); tap.test('journeys – only subway', async (t) => { const res = await client.journeys(spichernstr, bismarckstr, { @@ -92,27 +92,27 @@ tap.test('journeys – only subway', async (t) => { express: false, regional: false, }, - }) + }); - validate(t, res, 'journeysResult', 'res') + validate(t, res, 'journeysResult', 'res'); - t.ok(res.journeys.length > 1) + t.ok(res.journeys.length > 1); for (let i = 0; i < res.journeys.length; i++) { - const journey = res.journeys[i] + const journey = res.journeys[i]; for (let j = 0; j < journey.legs.length; j++) { - const leg = journey.legs[j] + const leg = journey.legs[j]; - const name = `res.journeys[${i}].legs[${j}].line` + const name = `res.journeys[${i}].legs[${j}].line`; if (leg.line) { - t.equal(leg.line.mode, 'train', name + '.mode is invalid') - t.equal(leg.line.product, 'subway', name + '.product is invalid') + t.equal(leg.line.mode, 'train', name + '.mode is invalid'); + t.equal(leg.line.product, 'subway', name + '.product is invalid'); } - t.ok(journey.legs.some(l => l.line), name + '.legs has no subway leg') + t.ok(journey.legs.some(l => l.line), name + '.legs has no subway leg'); } } - t.end() -}) + t.end(); +}); tap.test('journeys – fails with no product', async (t) => { await journeysFailsWithNoProduct({ @@ -122,9 +122,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: bismarckstr, when, products: bvgProfile.products, - }) - t.end() -}) + }); + t.end(); +}); // BerlKönig for public use is suspended during COVID-19. tap.skip('journeys – BerlKönig', async (t) => { @@ -134,7 +134,7 @@ tap.skip('journeys – BerlKönig', async (t) => { }) .startOf('day') .plus({days: 1, hours: 18}) - .toISO() + .toISO(); const {journeys} = await client.journeys({ type: 'location', @@ -151,18 +151,18 @@ tap.skip('journeys – BerlKönig', async (t) => { }, { berlkoenig: true, departure: when, - }) + }); const withBerlkoenig = flatMap(journeys, j => j.legs) - .find(l => l.line && l.line.product === 'berlkoenig') - t.ok(withBerlkoenig, 'journey with BerlKönig not found') + .find(l => l.line && l.line.product === 'berlkoenig'); + t.ok(withBerlkoenig, 'journey with BerlKönig not found'); - t.ok(withBerlkoenig.line) - t.equal(withBerlkoenig.line.public, true) - t.equal(withBerlkoenig.line.mode, 'taxi') - t.equal(withBerlkoenig.line.product, 'berlkoenig') - t.end() -}) + t.ok(withBerlkoenig.line); + t.equal(withBerlkoenig.line.public, true); + t.equal(withBerlkoenig.line.mode, 'taxi'); + t.equal(withBerlkoenig.line.product, 'berlkoenig'); + t.end(); +}); // todo: opt.walkingSpeed doesn't seem to work right now tap.skip('journeys: walkingSpeed', async (t) => { @@ -171,8 +171,8 @@ tap.skip('journeys: walkingSpeed', async (t) => { address: 'Havelchaussee', latitude: 52.443576, longitude: 13.198973, - } - const wannsee = '900053301' + }; + const wannsee = '900053301'; await testJourneysWalkingSpeed({ test: t, @@ -182,8 +182,8 @@ tap.skip('journeys: walkingSpeed', async (t) => { to: wannsee, products: {bus: false}, minTimeDifference: 5 * 60 * 1000, - }) -}) + }); +}); tap.test('earlier/later journeys', async (t) => { await testEarlierLaterJourneys({ @@ -193,10 +193,10 @@ tap.test('earlier/later journeys', async (t) => { fromId: spichernstr, toId: bismarckstr, when, - }) + }); - t.end() -}) + t.end(); +}); if (!process.env.VCR_MODE) { tap.test('journeys – leg cycle & alternatives', async (t) => { @@ -205,9 +205,9 @@ if (!process.env.VCR_MODE) { fetchJourneys: client.journeys, fromId: tiergarten, toId: jannowitzbrücke, - }) - t.end() - }) + }); + t.end(); + }); } tap.test('refreshJourney', async (t) => { @@ -219,24 +219,24 @@ tap.test('refreshJourney', async (t) => { fromId: spichernstr, toId: bismarckstr, when, - }) - t.end() -}) + }); + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(spichernstr, amrumerStr, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('journeys – station to address', async (t) => { const torfstr = { @@ -244,11 +244,11 @@ tap.test('journeys – station to address', async (t) => { address: '13353 Berlin-Wedding, Torfstr. 17', latitude: 52.541797, longitude: 13.350042, - } + }; const res = await client.journeys(spichernstr, torfstr, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -256,9 +256,9 @@ tap.test('journeys – station to address', async (t) => { validate, fromId: spichernstr, to: torfstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys – station to POI', async (t) => { const atze = { @@ -268,11 +268,11 @@ tap.test('journeys – station to POI', async (t) => { name: 'Berlin, Atze Musiktheater für Kinder', latitude: 52.543333, longitude: 13.351686, - } + }; const res = await client.journeys(spichernstr, atze, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -280,9 +280,9 @@ tap.test('journeys – station to POI', async (t) => { validate, fromId: spichernstr, to: atze, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys: via works – with detour', async (t) => { // Going from Westhafen to Wedding via Württembergalle without detour @@ -292,32 +292,32 @@ tap.test('journeys: via works – with detour', async (t) => { results: 1, departure: when, stopovers: true, - }) + }); await testJourneysWithDetour({ test: t, res, validate, detourIds: [württembergallee], - }) - t.end() -}) + }); + t.end(); +}); // todo: without detour test tap.test('departures', async (t) => { const res = await client.departures(spichernstr, { duration: 5, when, - }) + }); await testDepartures({ test: t, res, validate, id: spichernstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -329,11 +329,11 @@ tap.test('departures with station object', async (t) => { latitude: 1.23, longitude: 2.34, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('departures at Spichernstr. in direction of Westhafen', async (t) => { await testDeparturesInDirection({ @@ -344,34 +344,34 @@ tap.test('departures at Spichernstr. in direction of Westhafen', async (t) => { directionIds: [westhafen], when, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures at 7-digit station', async (t) => { - const eisenach = '8010097' // see derhuerst/vbb-hafas#22 - await client.departures(eisenach, {when}) - t.pass('did not fail') - t.end() -}) + const eisenach = '8010097'; // see derhuerst/vbb-hafas#22 + await client.departures(eisenach, {when}); + t.pass('did not fail'); + t.end(); +}); tap.test('arrivals', async (t) => { const res = await client.arrivals(spichernstr, { duration: 5, when, - }) + }); await testArrivals({ test: t, res, validate, id: spichernstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('nearby', async (t) => { - const berlinerStr = '900044201' - const landhausstr = '900043252' + const berlinerStr = '900044201'; + const landhausstr = '900043252'; // Berliner Str./Bundesallee const nearby = await client.nearby({ @@ -381,45 +381,45 @@ tap.test('nearby', async (t) => { }, { // Even though HAFAS reports Landhausstr. to be 179m, we have to pass way more here. 🙄 distance: 600, - }) + }); - validate(t, nearby, 'locations', 'nearby') + validate(t, nearby, 'locations', 'nearby'); - t.equal(nearby[0].id, berlinerStr) - t.equal(nearby[0].name, 'U Berliner Str. (Berlin)') - t.ok(nearby[0].distance > 0) - t.ok(nearby[0].distance < 100) + t.equal(nearby[0].id, berlinerStr); + t.equal(nearby[0].name, 'U Berliner Str. (Berlin)'); + t.ok(nearby[0].distance > 0); + t.ok(nearby[0].distance < 100); - const res = nearby.find(s => s.id === landhausstr) - t.ok(res, `Landhausstr. ${landhausstr} is not among the nearby stops`) - t.equal(nearby[1].name, 'Landhausstr. (Berlin)') - t.ok(nearby[1].distance > 100) - t.ok(nearby[1].distance < 200) + const res = nearby.find(s => s.id === landhausstr); + t.ok(res, `Landhausstr. ${landhausstr} is not among the nearby stops`); + t.equal(nearby[1].name, 'Landhausstr. (Berlin)'); + t.ok(nearby[1].distance > 100); + t.ok(nearby[1].distance < 200); - t.end() -}) + t.end(); +}); tap.test('locations', async (t) => { - const locations = await client.locations('Alexanderplatz', {results: 20}) + const locations = await client.locations('Alexanderplatz', {results: 20}); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs - t.ok(locations.find(s => !s.name && s.address)) // addresses + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs + t.ok(locations.find(s => !s.name && s.address)); // addresses - t.end() -}) + t.end(); +}); tap.test('stop', async (t) => { - const s = await client.stop(spichernstr) + const s = await client.stop(spichernstr); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, spichernstr) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, spichernstr); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -429,11 +429,11 @@ tap.test('radar', async (t) => { east: 13.41709, }, { duration: 5 * 60, when, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.test('reachableFrom', async (t) => { const torfstr17 = { @@ -441,7 +441,7 @@ tap.test('reachableFrom', async (t) => { address: '13353 Berlin-Wedding, Torfstr. 17', latitude: 52.541797, longitude: 13.350042, - } + }; await testReachableFrom({ test: t, @@ -450,9 +450,9 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('remarks', async (t) => { await testRemarks({ @@ -460,9 +460,9 @@ tap.test('remarks', async (t) => { fetchRemarks: client.remarks, when, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('lines', async (t) => { await testLines({ @@ -470,6 +470,6 @@ tap.test('lines', async (t) => { fetchLines: client.lines, validate, query: 'M10', - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/cfl.js b/test/e2e/cfl.js index d79f84bef..65ea61a1a 100644 --- a/test/e2e/cfl.js +++ b/test/e2e/cfl.js @@ -1,26 +1,26 @@ -import tap from 'tap' -import assert from 'assert' -import isRoughlyEqual from 'is-roughly-equal' +import tap from 'tap'; +import assert from 'assert'; +import isRoughlyEqual from 'is-roughly-equal'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as cflProfile} from '../../p/cfl/index.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as cflProfile} from '../../p/cfl/index.js'; import { createValidateLine, createValidateJourneyLeg, createValidateMovement, -} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testArrivals} from './lib/arrivals.js' - -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(cflProfile.timezone, cflProfile.locale, T_MOCK) +} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testArrivals} from './lib/arrivals.js'; + +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(cflProfile.timezone, cflProfile.locale, T_MOCK); const cfg = { when, @@ -29,58 +29,58 @@ const cfg = { maxLatitude: 52.9, minLongitude: -0.63, maxLongitude: 14.07, -} +}; -const _validateLine = createValidateLine(cfg) +const _validateLine = createValidateLine(cfg); const validateLine = (validate, l, name) => { if (!l.direction) { - l = Object.assign({}, l, {direction: 'foo'}) + l = Object.assign({}, l, {direction: 'foo'}); } - _validateLine(validate, l, name) -} + _validateLine(validate, l, name); +}; -const _validateJourneyLeg = createValidateJourneyLeg(cfg) +const _validateJourneyLeg = createValidateJourneyLeg(cfg); const validateJourneyLeg = (validate, l, name) => { if (!l.direction) { - l = Object.assign({}, l, {direction: 'foo'}) + l = Object.assign({}, l, {direction: 'foo'}); } - _validateJourneyLeg(validate, l, name) -} + _validateJourneyLeg(validate, l, name); +}; -const _validateMovement = createValidateMovement(cfg) +const _validateMovement = createValidateMovement(cfg); const validateMovement = (val, m, name = 'movement') => { // todo: fix this upstream - const withFakeLocation = Object.assign({}, m) + const withFakeLocation = Object.assign({}, m); withFakeLocation.location = Object.assign({}, m.location, { latitude: 50, longitude: 12, - }) - _validateMovement(val, withFakeLocation, name) + }); + _validateMovement(val, withFakeLocation, name); - assert.ok(m.location.latitude <= 55, name + '.location.latitude is too small') - assert.ok(m.location.latitude >= 45, name + '.location.latitude is too large') - assert.ok(m.location.longitude >= 1, name + '.location.longitude is too small') - assert.ok(m.location.longitude <= 11, name + '.location.longitude is too small') -} + assert.ok(m.location.latitude <= 55, name + '.location.latitude is too small'); + assert.ok(m.location.latitude >= 45, name + '.location.latitude is too large'); + assert.ok(m.location.longitude >= 1, name + '.location.longitude is too small'); + assert.ok(m.location.longitude <= 11, name + '.location.longitude is too small'); +}; const validate = createValidate(cfg, { line: validateLine, journeyLeg: validateJourneyLeg, movement: validateMovement, -}) +}); -const client = createClient(cflProfile, 'public-transport/hafas-client:test') +const client = createClient(cflProfile, 'public-transport/hafas-client:test'); -const ettelbruck = '9258199' -const mersch = '9864348' -const luxembourgGareCentrale = '9217081' +const ettelbruck = '9258199'; +const mersch = '9864348'; +const luxembourgGareCentrale = '9217081'; tap.test('journeys – Ettelbruck to Luxembourg', async (t) => { const res = await client.journeys(ettelbruck, luxembourgGareCentrale, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -88,9 +88,9 @@ tap.test('journeys – Ettelbruck to Luxembourg', async (t) => { validate, fromId: ettelbruck, toId: luxembourgGareCentrale, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -102,9 +102,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: luxembourgGareCentrale, when, products: cflProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Luxembourg to 9071 Ettelbruck, Rue des Romains 4', async (t) => { const rueDeRomain = { @@ -112,12 +112,12 @@ tap.test('Luxembourg to 9071 Ettelbruck, Rue des Romains 4', async (t) => { address: '9071 Ettelbruck, Rue des Romains 4', latitude: 49.847469, longitude: 6.097608, - } + }; const res = await client.journeys(luxembourgGareCentrale, rueDeRomain, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -125,12 +125,12 @@ tap.test('Luxembourg to 9071 Ettelbruck, Rue des Romains 4', async (t) => { validate, fromId: luxembourgGareCentrale, to: rueDeRomain, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Luxembourg to Centre Hospitalier du Nord', async (t) => { - const luxembourg = '9217081' + const luxembourg = '9217081'; const centreHospitalier = { type: 'location', id: '990027653', @@ -138,11 +138,11 @@ tap.test('Luxembourg to Centre Hospitalier du Nord', async (t) => { name: 'Centre Hospitalier du Nord (CHDN), Ettelbruck', latitude: 49.853168, longitude: 6.096268, - } + }; const res = await client.journeys(luxembourgGareCentrale, centreHospitalier, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -150,9 +150,9 @@ tap.test('Luxembourg to Centre Hospitalier du Nord', async (t) => { validate, fromId: luxembourg, to: centreHospitalier, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys: via works – with detour // todo: without detour @@ -165,53 +165,53 @@ tap.test('earlier/later journeys', async (t) => { fromId: luxembourgGareCentrale, toId: ettelbruck, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('trip', async (t) => { const {journeys} = await client.journeys(luxembourgGareCentrale, ettelbruck, { results: 1, departure: when, - }) + }); - const p = journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Ettelbruck.', async (t) => { const res = await client.departures(ettelbruck, { duration: 20, when, - }) + }); await testDepartures({ test: t, res, validate, id: ettelbruck, - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Ettelbruck.', async (t) => { const res = await client.arrivals(ettelbruck, { duration: 20, when, - }) + }); await testArrivals({ test: t, res, validate, id: ettelbruck, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -223,42 +223,42 @@ tap.test('departures with station object', async (t) => { latitude: 49.847298, longitude: 6.106157, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); // todo: nearby tap.test('locations named Mersch', async (t) => { const locations = await client.locations('Mersch', { results: 20, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); t.ok(locations.some((loc) => { if (loc.station && loc.station.id === mersch) { - return true + return true; } - return loc.id === mersch - })) + return loc.id === mersch; + })); - t.end() -}) + t.end(); +}); tap.test('stop Mersch', async (t) => { - const s = await client.stop(mersch) + const s = await client.stop(mersch); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, mersch) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, mersch); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -268,8 +268,8 @@ tap.test('radar', async (t) => { east: 6.15, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); diff --git a/test/e2e/cmta.js b/test/e2e/cmta.js index 1219364fd..81968e64b 100644 --- a/test/e2e/cmta.js +++ b/test/e2e/cmta.js @@ -1,22 +1,22 @@ -import tap from 'tap' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as cmtaProfile} from '../../p/cmta/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testArrivals} from './lib/arrivals.js' -import {testJourneysWithDetour} from './lib/journeys-with-detour.js' -import {testReachableFrom} from './lib/reachable-from.js' - -const T_MOCK = 1670310000 * 1000 // 2022-12-06T08:00:00+01:00 -const when = createWhen(cmtaProfile.timezone, cmtaProfile.locale, T_MOCK) +import tap from 'tap'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as cmtaProfile} from '../../p/cmta/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testJourneysWithDetour} from './lib/journeys-with-detour.js'; +import {testReachableFrom} from './lib/reachable-from.js'; + +const T_MOCK = 1670310000 * 1000; // 2022-12-06T08:00:00+01:00 +const when = createWhen(cmtaProfile.timezone, cmtaProfile.locale, T_MOCK); const cfg = { when, @@ -26,22 +26,22 @@ const cfg = { maxLatitude: 33, minLongitude: -100, maxLongitude: -95, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(cmtaProfile, 'public-transport/hafas-client:test') +const client = createClient(cmtaProfile, 'public-transport/hafas-client:test'); -const broadieOaks = '2370' -const domain = '5919' -const capitol591 = '591' +const broadieOaks = '2370'; +const domain = '5919'; +const capitol591 = '591'; tap.test('journeys – Broadie Oaks to Domain', async (t) => { const res = await client.journeys(broadieOaks, domain, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -49,9 +49,9 @@ tap.test('journeys – Broadie Oaks to Domain', async (t) => { validate, fromId: broadieOaks, toId: domain, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -63,9 +63,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: domain, when, products: cmtaProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Domain to 1104 Elm Street, Austin, TX 78703', async (t) => { const someAddress = { @@ -73,12 +73,12 @@ tap.test('Domain to 1104 Elm Street, Austin, TX 78703', async (t) => { address: '1104 ELM ST, Austin, TX 78703', latitude: 30.279220, longitude: -97.758292, - } + }; const res = await client.journeys(domain, someAddress, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -86,9 +86,9 @@ tap.test('Domain to 1104 Elm Street, Austin, TX 78703', async (t) => { validate, fromId: domain, to: someAddress, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Domain to WHOLE FOODS MARKET - ARBOR TRAILS', async (t) => { const wholeFoodsMarket = { @@ -98,11 +98,11 @@ tap.test('Domain to WHOLE FOODS MARKET - ARBOR TRAILS', async (t) => { name: 'WHOLE FOODS MARKET - ARBOR TRAILS', latitude: 30.22026, longitude: -97.84174, - } + }; const res = await client.journeys(domain, wholeFoodsMarket, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -110,9 +110,9 @@ tap.test('Domain to WHOLE FOODS MARKET - ARBOR TRAILS', async (t) => { validate, fromId: domain, to: wholeFoodsMarket, - }) - t.end() -}) + }); + t.end(); +}); // todo: walkingSpeed "2107 MELRIDGE PL" -> 000002148 // todo: via works – with detour @@ -126,10 +126,10 @@ tap.test('earlier/later journeys', async (t) => { fromId: broadieOaks, toId: domain, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('refreshJourney', async (t) => { await testRefreshJourney({ @@ -140,38 +140,38 @@ tap.test('refreshJourney', async (t) => { fromId: broadieOaks, toId: domain, when, - }) - t.end() -}) + }); + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(broadieOaks, domain, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Broadie Oaks', async (t) => { const res = await client.departures(broadieOaks, { duration: 10, when, - }) + }); await testDepartures({ test: t, res, validate, id: broadieOaks, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -183,53 +183,53 @@ tap.test('departures with station object', async (t) => { latitude: 1.23, longitude: 2.34, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('arrivals at Broadie Oaks', async (t) => { const res = await client.arrivals(broadieOaks, { duration: 10, when, - }) + }); await testArrivals({ test: t, res, validate, id: broadieOaks, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby tap.test('locations named "Capitol"', async (t) => { const locations = await client.locations('Capitol', { results: 10, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 10) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 10); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs t.ok(locations.some((l) => { - return l.station && l.station.id === capitol591 || l.id === capitol591 - })) + return l.station && l.station.id === capitol591 || l.id === capitol591; + })); - t.end() -}) + t.end(); +}); tap.test('station Domain', async (t) => { - const s = await client.stop(domain) + const s = await client.stop(domain); - validate(t, s, ['stop', 'station'], 'station') - t.equal(s.id, domain) + validate(t, s, ['stop', 'station'], 'station'); + t.equal(s.id, domain); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -239,11 +239,11 @@ tap.test('radar', async (t) => { east: -97.786692, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.test('reachableFrom', async (t) => { await testReachableFrom({ @@ -258,6 +258,6 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/common.js b/test/e2e/common.js index 542753b24..61058de24 100644 --- a/test/e2e/common.js +++ b/test/e2e/common.js @@ -1,12 +1,12 @@ -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../../index.js' -import {profile as vbbProfile} from '../../p/vbb/index.js' +import {createClient} from '../../index.js'; +import {profile as vbbProfile} from '../../p/vbb/index.js'; -const client = createClient(vbbProfile, 'public-transport/hafas-client:test') +const client = createClient(vbbProfile, 'public-transport/hafas-client:test'); tap.test('exposes the profile', (t) => { - t.ok(client.profile) - t.equal(client.profile.endpoint, vbbProfile.endpoint) - t.end() -}) + t.ok(client.profile); + t.equal(client.profile.endpoint, vbbProfile.endpoint); + t.end(); +}); diff --git a/test/e2e/dart.js b/test/e2e/dart.js index 7edb4b832..39c72a35d 100644 --- a/test/e2e/dart.js +++ b/test/e2e/dart.js @@ -1,12 +1,12 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as dartProfile} from '../../p/dart/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as dartProfile} from '../../p/dart/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(dartProfile.timezone, dartProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(dartProfile.timezone, dartProfile.locale, T_MOCK); const cfg = { when, @@ -16,20 +16,20 @@ const cfg = { maxLongitude: -88.176, minLatitude: 37.745, minLongitude: -96.877, -} -const validate = createValidate(cfg) +}; +const validate = createValidate(cfg); -const client = createClient(dartProfile, 'public-transport/hafas-client:test') +const client = createClient(dartProfile, 'public-transport/hafas-client:test'); -const mlkJrParkwayAdamsAve = '951013488' // MARTIN LUTHER KING JR PKWY/ADAMS AVE +const mlkJrParkwayAdamsAve = '951013488'; // MARTIN LUTHER KING JR PKWY/ADAMS AVE tap.test('locations named "martin luther kind adams"', async (t) => { - const locations = await client.locations('martin luther kind adams') + const locations = await client.locations('martin luther kind adams'); - validate(t, locations, 'locations', 'locations') + validate(t, locations, 'locations', 'locations'); t.ok(locations.some((l) => { - return l.station && l.station.id === mlkJrParkwayAdamsAve || l.id === mlkJrParkwayAdamsAve - }), '"MARTIN LUTHER KING JR PKWY/ADAMS AVE" not found') + return l.station && l.station.id === mlkJrParkwayAdamsAve || l.id === mlkJrParkwayAdamsAve; + }), '"MARTIN LUTHER KING JR PKWY/ADAMS AVE" not found'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/db-busradar-nrw.js b/test/e2e/db-busradar-nrw.js index 4b56397a5..3585db7af 100644 --- a/test/e2e/db-busradar-nrw.js +++ b/test/e2e/db-busradar-nrw.js @@ -1,17 +1,17 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as dbBusradarNrwProfile} from '../../p/db-busradar-nrw/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testDepartures} from './lib/departures.js' -import {testArrivals} from './lib/arrivals.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as dbBusradarNrwProfile} from '../../p/db-busradar-nrw/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testDepartures} from './lib/departures.js'; +import {testArrivals} from './lib/arrivals.js'; -const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o) +const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o); -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(dbBusradarNrwProfile.timezone, dbBusradarNrwProfile.locale, T_MOCK) +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(dbBusradarNrwProfile.timezone, dbBusradarNrwProfile.locale, T_MOCK); const cfg = { when, @@ -21,44 +21,44 @@ const cfg = { maxLatitude: 55, minLongitude: 4, maxLongitude: 14, -} +}; -const validate = createValidate(cfg, {}) +const validate = createValidate(cfg, {}); -const client = createClient(dbBusradarNrwProfile, 'public-transport/hafas-client:test') +const client = createClient(dbBusradarNrwProfile, 'public-transport/hafas-client:test'); -const hagenBauhaus = '3307002' -const bielefeldHbf = '8000036' -const hagenVorhalle = '8000977' +const hagenBauhaus = '3307002'; +const bielefeldHbf = '8000036'; +const hagenVorhalle = '8000977'; tap.test('departures at Hagen Bauhaus', async (t) => { const res = await client.departures(hagenBauhaus, { duration: 120, when, - }) + }); await testDepartures({ test: t, res, validate, id: hagenBauhaus, - }) - t.end() -}) + }); + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.departures(hagenBauhaus, { results: 1, duration: 120, when, - }) + }); - const p = res.departures[0] || {} - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.departures[0] || {}; + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -70,55 +70,55 @@ tap.test('departures with station object', async (t) => { latitude: 51.375141, longitude: 7.455626, }, - }, {when, duration: 120}) + }, {when, duration: 120}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); // todo: departures at hagenBauhaus in direction of … tap.test('arrivals at Hagen Bauhaus', async (t) => { const res = await client.arrivals(hagenBauhaus, { duration: 120, when, - }) + }); await testArrivals({ test: t, res, validate, id: hagenBauhaus, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby tap.test('locations named Vorhalle', async (t) => { const locations = await client.locations('vorhalle', { results: 10, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); t.ok(locations.some((l) => { return l.station && l.station.id === hagenVorhalle - || l.id === hagenVorhalle - })) + || l.id === hagenVorhalle; + })); - t.end() -}) + t.end(); +}); tap.test('station Hagen-Vorhalle', async (t) => { - const s = await client.stop(hagenVorhalle) + const s = await client.stop(hagenVorhalle); - validate(t, s, ['stop', 'station'], 'station') - t.equal(s.id, hagenVorhalle) + validate(t, s, ['stop', 'station'], 'station'); + t.equal(s.id, hagenVorhalle); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -128,12 +128,12 @@ tap.test('radar', async (t) => { east: 7.8, }, { duration: 5 * 60, when, results: 10, - }) + }); const validate = createValidate({ ...cfg, stationCoordsOptional: true, - }, {}) - validate(t, res, 'radarResult', 'res') - t.end() -}) + }, {}); + validate(t, res, 'radarResult', 'res'); + t.end(); +}); diff --git a/test/e2e/db.js b/test/e2e/db.js index 284de6554..e458b8450 100644 --- a/test/e2e/db.js +++ b/test/e2e/db.js @@ -1,37 +1,37 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' -import maxBy from 'lodash/maxBy.js' -import flatMap from 'lodash/flatMap.js' -import last from 'lodash/last.js' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as dbProfile} from '../../p/db/index.js' -import {routingModes} from '../../p/db/routing-modes.js' +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; +import maxBy from 'lodash/maxBy.js'; +import flatMap from 'lodash/flatMap.js'; +import last from 'lodash/last.js'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as dbProfile} from '../../p/db/index.js'; +import {routingModes} from '../../p/db/routing-modes.js'; import { createValidateStation, createValidateTrip, -} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testLegCycleAlternatives} from './lib/leg-cycle-alternatives.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' -import {testArrivals} from './lib/arrivals.js' -import {testJourneysWithDetour} from './lib/journeys-with-detour.js' -import {testReachableFrom} from './lib/reachable-from.js' -import {testServerInfo} from './lib/server-info.js' - -const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o) -const minute = 60 * 1000 - -const T_MOCK = 1696921200 * 1000 // 2023-10-10T08:00:00+01:00 -const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK) +} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testLegCycleAlternatives} from './lib/leg-cycle-alternatives.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testJourneysWithDetour} from './lib/journeys-with-detour.js'; +import {testReachableFrom} from './lib/reachable-from.js'; +import {testServerInfo} from './lib/server-info.js'; + +const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o); +const minute = 60 * 1000; + +const T_MOCK = 1696921200 * 1000; // 2023-10-10T08:00:00+01:00 +const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK); const cfg = { when, @@ -41,45 +41,45 @@ const cfg = { maxLatitude: 55.030671, minLongitude: 6.896517, maxLongitude: 16.180237, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); const assertValidPrice = (t, p) => { - t.ok(p) + t.ok(p); if (p.amount !== null) { - t.equal(typeof p.amount, 'number') - t.ok(p.amount > 0) + t.equal(typeof p.amount, 'number'); + t.ok(p.amount > 0); } if (p.hint !== null) { - t.equal(typeof p.hint, 'string') - t.ok(p.hint) + t.equal(typeof p.hint, 'string'); + t.ok(p.hint); } -} - -const client = createClient(dbProfile, 'public-transport/hafas-client:test') - -const berlinHbf = '8011160' -const münchenHbf = '8000261' -const jungfernheide = '8011167' -const blnSchwedterStr = '732652' -const westhafen = '8089116' -const wedding = '8089131' -const württembergallee = '731084' -const regensburgHbf = '8000309' -const blnOstbahnhof = '8010255' -const blnTiergarten = '8089091' -const blnJannowitzbrücke = '8089019' -const potsdamHbf = '8012666' -const berlinSüdkreuz = '8011113' -const kölnHbf = '8000207' +}; + +const client = createClient(dbProfile, 'public-transport/hafas-client:test'); + +const berlinHbf = '8011160'; +const münchenHbf = '8000261'; +const jungfernheide = '8011167'; +const blnSchwedterStr = '732652'; +const westhafen = '8089116'; +const wedding = '8089131'; +const württembergallee = '731084'; +const regensburgHbf = '8000309'; +const blnOstbahnhof = '8010255'; +const blnTiergarten = '8089091'; +const blnJannowitzbrücke = '8089019'; +const potsdamHbf = '8012666'; +const berlinSüdkreuz = '8011113'; +const kölnHbf = '8000207'; tap.test('journeys – Berlin Schwedter Str. to München Hbf', async (t) => { const res = await client.journeys(blnSchwedterStr, münchenHbf, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -87,16 +87,16 @@ tap.test('journeys – Berlin Schwedter Str. to München Hbf', async (t) => { validate, fromId: blnSchwedterStr, toId: münchenHbf, - }) + }); // todo: find a journey where there pricing info is always available for (let journey of res.journeys) { if (journey.price) { - assertValidPrice(t, journey.price) + assertValidPrice(t, journey.price); } } - t.end() -}) + t.end(); +}); // todo: journeys, only one product @@ -108,9 +108,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: münchenHbf, when, products: dbProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Berlin Schwedter Str. to Torfstraße 17', async (t) => { const torfstr = { @@ -118,11 +118,11 @@ tap.test('Berlin Schwedter Str. to Torfstraße 17', async (t) => { address: 'Torfstraße 17', latitude: 52.5416823, longitude: 13.3491223, - } + }; const res = await client.journeys(blnSchwedterStr, torfstr, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -130,9 +130,9 @@ tap.test('Berlin Schwedter Str. to Torfstraße 17', async (t) => { validate, fromId: blnSchwedterStr, to: torfstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Berlin Schwedter Str. to ATZE Musiktheater', async (t) => { const atze = { @@ -142,11 +142,11 @@ tap.test('Berlin Schwedter Str. to ATZE Musiktheater', async (t) => { name: 'Berlin, Atze Musiktheater für Kinder (Kultur und U', latitude: 52.542417, longitude: 13.350437, - } + }; const res = await client.journeys(blnSchwedterStr, atze, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -154,9 +154,9 @@ tap.test('Berlin Schwedter Str. to ATZE Musiktheater', async (t) => { validate, fromId: blnSchwedterStr, to: atze, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys: via works – with detour', async (t) => { // Going from Westhafen to Wedding via Württembergalle without detour @@ -166,16 +166,16 @@ tap.test('journeys: via works – with detour', async (t) => { results: 1, departure: when, stopovers: true, - }) + }); await testJourneysWithDetour({ test: t, res, validate, detourIds: [württembergallee], - }) - t.end() -}) + }); + t.end(); +}); // todo: walkingSpeed "Berlin - Charlottenburg, Hallerstraße" -> jungfernheide // todo: without detour @@ -186,11 +186,11 @@ tap.test('journeys – all routing modes work', async (t) => { results: 1, departure: when, routingMode: mode, - }) + }); } - t.end() -}) + t.end(); +}); // todo: with the DB endpoint, earlierRef/laterRef is missing queries many days in the future tap.skip('earlier/later journeys, Jungfernheide -> München Hbf', async (t) => { @@ -201,10 +201,10 @@ tap.skip('earlier/later journeys, Jungfernheide -> München Hbf', async (t) => { fromId: jungfernheide, toId: münchenHbf, when, - }) + }); - t.end() -}) + t.end(); +}); if (!process.env.VCR_MODE) { tap.test('journeys – leg cycle & alternatives', async (t) => { @@ -214,9 +214,9 @@ if (!process.env.VCR_MODE) { fromId: blnTiergarten, toId: blnJannowitzbrücke, when, - }) - t.end() - }) + }); + t.end(); + }); } tap.test('refreshJourney', async (t) => { @@ -228,140 +228,140 @@ tap.test('refreshJourney', async (t) => { fromId: jungfernheide, toId: münchenHbf, when, - }) - t.end() -}) + }); + t.end(); +}); tap.skip('journeysFromTrip – U Mehringdamm to U Naturkundemuseum, reroute to Spittelmarkt.', async (t) => { - const blnMehringdamm = '730939' - const blnStadtmitte = '732541' - const blnNaturkundemuseum = '732539' - const blnSpittelmarkt = '732543' + const blnMehringdamm = '730939'; + const blnStadtmitte = '732541'; + const blnNaturkundemuseum = '732539'; + const blnSpittelmarkt = '732543'; const isU6Leg = leg => leg.line && leg.line.name && leg.line.name.toUpperCase() - .replace(/\s+/g, '') === 'U6' + .replace(/\s+/g, '') === 'U6'; const sameStopOrStation = (stopA) => (stopB) => { if (stopA.id && stopB.id && stopA.id === stopB.id) { - return true + return true; } - const statA = stopA.stat && stopA.stat.id || NaN - const statB = stopB.stat && stopB.stat.id || NaN - return statA === statB || stopA.id === statB || stopB.id === statA - } - const departureOf = st => Number(new Date(st.departure || st.scheduledDeparture)) - const arrivalOf = st => Number(new Date(st.arrival || st.scheduledArrival)) + const statA = stopA.stat && stopA.stat.id || NaN; + const statB = stopB.stat && stopB.stat.id || NaN; + return statA === statB || stopA.id === statB || stopB.id === statA; + }; + const departureOf = st => Number(new Date(st.departure || st.scheduledDeparture)); + const arrivalOf = st => Number(new Date(st.arrival || st.scheduledArrival)); // `journeysFromTrip` only supports queries *right now*, so we can't use `when` as in all // other tests. To make the test less brittle, we pick a connection that is served all night. 🙄 - const when = new Date() - const validate = createValidate({...cfg, when}) + const when = new Date(); + const validate = createValidate({...cfg, when}); const findTripBetween = async (stopAId, stopBId, products = {}) => { const {journeys} = await client.journeys(stopAId, stopBId, { departure: new Date(when - 10 * minute), transfers: 0, products, results: 8, stopovers: false, remarks: false, - }) + }); for (const j of journeys) { - const l = j.legs.find(isU6Leg) + const l = j.legs.find(isU6Leg); if (!l) { - continue + continue; } const t = await client.trip(l.tripId, { stopovers: true, remarks: false, - }) + }); const pastStopovers = t.stopovers - .filter(st => departureOf(st) < Date.now()) // todo: <= ? + .filter(st => departureOf(st) < Date.now()); // todo: <= ? const hasStoppedAtA = pastStopovers - .find(sameStopOrStation({id: stopAId})) + .find(sameStopOrStation({id: stopAId})); const willStopAtB = t.stopovers .filter(st => arrivalOf(st) > Date.now()) // todo: >= ? - .find(sameStopOrStation({id: stopBId})) + .find(sameStopOrStation({id: stopBId})); if (hasStoppedAtA && willStopAtB) { - const prevStopover = maxBy(pastStopovers, departureOf) - return {trip: t, prevStopover} + const prevStopover = maxBy(pastStopovers, departureOf); + return {trip: t, prevStopover}; } } - return {trip: null, prevStopover: null} - } + return {trip: null, prevStopover: null}; + }; // Find a vehicle from U Mehringdamm to U Stadtmitte (to the north) that is currently // between these two stations. const {trip, prevStopover} = await findTripBetween(blnMehringdamm, blnStadtmitte, { regionalExpress: false, regional: false, suburban: false, - }) - t.ok(trip, 'precondition failed: trip not found') - t.ok(prevStopover, 'precondition failed: previous stopover missing') + }); + t.ok(trip, 'precondition failed: trip not found'); + t.ok(prevStopover, 'precondition failed: previous stopover missing'); // todo: "Error: Suche aus dem Zug: Vor Abfahrt des Zuges" const newJourneys = await client.journeysFromTrip(trip.id, prevStopover, blnSpittelmarkt, { results: 3, stopovers: true, remarks: false, - }) + }); // Validate with fake prices. const withFakePrice = (j) => { - const clone = Object.assign({}, j) - clone.price = {amount: 123, currency: 'EUR'} - return clone - } + const clone = Object.assign({}, j); + clone.price = {amount: 123, currency: 'EUR'}; + return clone; + }; // todo: there is no such validator! - validate(t, newJourneys.map(withFakePrice), 'journeysFromTrip', 'newJourneys') + validate(t, newJourneys.map(withFakePrice), 'journeysFromTrip', 'newJourneys'); for (let i = 0; i < newJourneys.length; i++) { - const j = newJourneys[i] - const n = `newJourneys[${i}]` + const j = newJourneys[i]; + const n = `newJourneys[${i}]`; - const legOnTrip = j.legs.find(l => l.tripId === trip.id) - t.ok(legOnTrip, n + ': leg with trip ID not found') - t.equal(last(legOnTrip.stopovers).stop.id, blnStadtmitte) + const legOnTrip = j.legs.find(l => l.tripId === trip.id); + t.ok(legOnTrip, n + ': leg with trip ID not found'); + t.equal(last(legOnTrip.stopovers).stop.id, blnStadtmitte); } -}) +}); tap.test('trip details', async (t) => { const res = await client.journeys(berlinHbf, münchenHbf, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); const validate = createValidate(cfg, { trip: (cfg) => { - const validateTrip = createValidateTrip(cfg) + const validateTrip = createValidateTrip(cfg); const validateTripWithFakeDirection = (val, trip, name) => { validateTrip(val, { ...trip, direction: trip.direction || 'foo', // todo, see #49 - }, name) - } - return validateTripWithFakeDirection + }, name); + }; + return validateTripWithFakeDirection; }, - }) - validate(t, tripRes, 'tripResult', 'tripRes') + }); + validate(t, tripRes, 'tripResult', 'tripRes'); - t.end() -}) + t.end(); +}); tap.test('departures at Berlin Schwedter Str.', async (t) => { const res = await client.departures(blnSchwedterStr, { duration: 5, when, - }) + }); await testDepartures({ test: t, res, validate, id: blnSchwedterStr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -373,11 +373,11 @@ tap.test('departures with station object', async (t) => { latitude: 1.23, longitude: 2.34, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('departures at Berlin Hbf in direction of Berlin Ostbahnhof', async (t) => { await testDeparturesInDirection({ @@ -388,23 +388,23 @@ tap.test('departures at Berlin Hbf in direction of Berlin Ostbahnhof', async (t) directionIds: [blnOstbahnhof, '8089185', '732676'], when, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Berlin Schwedter Str.', async (t) => { const res = await client.arrivals(blnSchwedterStr, { duration: 5, when, - }) + }); await testArrivals({ test: t, res, validate, id: blnSchwedterStr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('nearby Berlin Jungfernheide', async (t) => { const nearby = await client.nearby({ @@ -413,55 +413,55 @@ tap.test('nearby Berlin Jungfernheide', async (t) => { longitude: 13.299433, }, { results: 2, distance: 400, - }) + }); - validate(t, nearby, 'locations', 'nearby') + validate(t, nearby, 'locations', 'nearby'); - t.equal(nearby.length, 2) + t.equal(nearby.length, 2); - const s0 = nearby[0] - t.equal(s0.id, jungfernheide) - t.equal(s0.name, 'Berlin Jungfernheide') - t.ok(isRoughlyEqual(0.0005, s0.location.latitude, 52.530408)) - t.ok(isRoughlyEqual(0.0005, s0.location.longitude, 13.299424)) - t.ok(s0.distance >= 0) - t.ok(s0.distance <= 100) + const s0 = nearby[0]; + t.equal(s0.id, jungfernheide); + t.equal(s0.name, 'Berlin Jungfernheide'); + t.ok(isRoughlyEqual(0.0005, s0.location.latitude, 52.530408)); + t.ok(isRoughlyEqual(0.0005, s0.location.longitude, 13.299424)); + t.ok(s0.distance >= 0); + t.ok(s0.distance <= 100); - t.end() -}) + t.end(); +}); tap.test('locations named Jungfernheide', async (t) => { const locations = await client.locations('Jungfernheide', { results: 10, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 10) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 10); t.ok(locations.some((l) => { - return l.station && l.station.id === jungfernheide || l.id === jungfernheide - }), 'Jungfernheide not found') + return l.station && l.station.id === jungfernheide || l.id === jungfernheide; + }), 'Jungfernheide not found'); - t.end() -}) + t.end(); +}); tap.test('stop', async (t) => { - const s = await client.stop(regensburgHbf) + const s = await client.stop(regensburgHbf); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, regensburgHbf) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, regensburgHbf); - t.end() -}) + t.end(); +}); tap.test('line with additionalName', async (t) => { const {departures} = await client.departures(potsdamHbf, { when, duration: 12 * 60, // 12 minutes products: {bus: false, suburban: false, tram: false}, - }) - t.ok(departures.some(d => d.line && d.line.additionalName)) - t.end() -}) + }); + t.ok(departures.some(d => d.line && d.line.additionalName)); + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -471,11 +471,11 @@ tap.test('radar', async (t) => { east: 13.41709, }, { duration: 5 * 60, when, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.test('reachableFrom', {timeout: 20 * 1000}, async (t) => { const torfstr17 = { @@ -483,7 +483,7 @@ tap.test('reachableFrom', {timeout: 20 * 1000}, async (t) => { address: 'Torfstraße 17', latitude: 52.5416823, longitude: 13.3491223, - } + }; await testReachableFrom({ test: t, @@ -492,13 +492,13 @@ tap.test('reachableFrom', {timeout: 20 * 1000}, async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('serverInfo works', async (t) => { await testServerInfo({ test: t, fetchServerInfo: client.serverInfo, - }) -}) + }); +}); diff --git a/test/e2e/insa.js b/test/e2e/insa.js index 128574120..367e8b4a2 100644 --- a/test/e2e/insa.js +++ b/test/e2e/insa.js @@ -1,28 +1,28 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as insaProfile} from '../../p/insa/index.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as insaProfile} from '../../p/insa/index.js'; import { createValidateMovement, createValidateJourneyLeg, -} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' -import {testArrivals} from './lib/arrivals.js' -import {testJourneysWithDetour} from './lib/journeys-with-detour.js' - -const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o) - -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(insaProfile.timezone, insaProfile.locale, T_MOCK) +} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testJourneysWithDetour} from './lib/journeys-with-detour.js'; + +const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o); + +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(insaProfile.timezone, insaProfile.locale, T_MOCK); const cfg = { when, @@ -32,7 +32,7 @@ const cfg = { maxLatitude: 53.2, minLongitude: 9, // considering e.g. IC 245 maxLongitude: 13.4, -} +}; const withFakeDirection = (validate) => (val, item, name) => { validate(val, { @@ -40,31 +40,31 @@ const withFakeDirection = (validate) => (val, item, name) => { direction: item.direction === null ? 'foo' : item.direction, - }, name) -} + }, name); +}; const validators = { movement: withFakeDirection(createValidateMovement(cfg)), journeyLeg: withFakeDirection(createValidateJourneyLeg(cfg)), -} +}; -const validate = createValidate(cfg, validators) +const validate = createValidate(cfg, validators); -const client = createClient(insaProfile, 'public-transport/hafas-client:test') +const client = createClient(insaProfile, 'public-transport/hafas-client:test'); -const magdeburgHbf = '8010224' -const magdeburgBuckau = '8013456' -const spielhagenstr = '7336' -const hasselbachplatz = '90443' -const stendal = '8010334' -const dessau = '8010077' -const universitaet = '19686' +const magdeburgHbf = '8010224'; +const magdeburgBuckau = '8013456'; +const spielhagenstr = '7336'; +const hasselbachplatz = '90443'; +const stendal = '8010334'; +const dessau = '8010077'; +const universitaet = '19686'; tap.test('journeys – Magdeburg Hbf to Magdeburg-Buckau', async (t) => { const res = await client.journeys(magdeburgHbf, magdeburgBuckau, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -72,9 +72,9 @@ tap.test('journeys – Magdeburg Hbf to Magdeburg-Buckau', async (t) => { validate, fromId: magdeburgHbf, toId: magdeburgBuckau, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -86,9 +86,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: magdeburgBuckau, when, products: insaProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Magdeburg Hbf to 39104 Magdeburg, Sternstr. 10', async (t) => { const sternStr = { @@ -96,12 +96,12 @@ tap.test('Magdeburg Hbf to 39104 Magdeburg, Sternstr. 10', async (t) => { address: 'Magdeburg - Altenstadt, Sternstraße 10', latitude: 52.118414, longitude: 11.422332, - } + }; const res = await client.journeys(magdeburgHbf, sternStr, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -109,9 +109,9 @@ tap.test('Magdeburg Hbf to 39104 Magdeburg, Sternstr. 10', async (t) => { validate, fromId: magdeburgHbf, to: sternStr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Magdeburg Hbf to Kloster Unser Lieben Frauen', async (t) => { const kloster = { @@ -121,11 +121,11 @@ tap.test('Magdeburg Hbf to Kloster Unser Lieben Frauen', async (t) => { name: 'Magdeburg, Kloster Unser Lieben Frauen (Denkmal)', latitude: 52.127601, longitude: 11.636437, - } + }; const res = await client.journeys(magdeburgHbf, kloster, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -133,9 +133,9 @@ tap.test('Magdeburg Hbf to Kloster Unser Lieben Frauen', async (t) => { validate, fromId: magdeburgHbf, to: kloster, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys: via works – with detour', async (t) => { // Going from Magdeburg, Hasselbachplatz (Sternstr.) (Tram/Bus) to Stendal @@ -146,16 +146,16 @@ tap.test('journeys: via works – with detour', async (t) => { results: 1, departure: when, stopovers: true, - }) + }); await testJourneysWithDetour({ test: t, res, validate, detourIds: [dessau], - }) - t.end() -}) + }); + t.end(); +}); // todo: without detour @@ -167,39 +167,39 @@ tap.test('earlier/later journeys', async (t) => { fromId: magdeburgHbf, toId: magdeburgBuckau, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(magdeburgHbf, magdeburgBuckau, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Magdeburg Universität', async (t) => { const res = await client.departures(universitaet, { duration: 30, when, - }) + }); await testDepartures({ test: t, res, validate, id: universitaet, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -213,11 +213,11 @@ tap.test('departures with station object', async (t) => { }, }, { duration: 30, when, - }) + }); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); // todo: deps empty, wrong loc ID? tap.test('departures at Universität in direction of Spielhagenstr.', async (t) => { @@ -229,52 +229,52 @@ tap.test('departures at Universität in direction of Spielhagenstr.', async (t) directionIds: [spielhagenstr], when, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Magdeburg Universität', async (t) => { const res = await client.arrivals(universitaet, { duration: 30, when, - }) + }); await testArrivals({ test: t, res, validate, id: universitaet, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby tap.test('locations named Magdeburg', async (t) => { - const nordpark = '7480' + const nordpark = '7480'; const locations = await client.locations('nordpark', { results: 20, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs t.ok(locations.some((l) => { - return l.station && l.station.id === nordpark || l.id === nordpark - })) + return l.station && l.station.id === nordpark || l.id === nordpark; + })); - t.end() -}) + t.end(); +}); tap.test('station Magdeburg-Buckau', async (t) => { - const s = await client.stop(magdeburgBuckau) + const s = await client.stop(magdeburgBuckau); - validate(t, s, ['stop', 'station'], 'station') - t.equal(s.id, magdeburgBuckau) + validate(t, s, ['stop', 'station'], 'station'); + t.equal(s.id, magdeburgBuckau); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -284,13 +284,13 @@ tap.test('radar', async (t) => { east: 11.651451, }, { duration: 5 * 60, when, results: 10, - }) + }); const customCfg = Object.assign({}, cfg, { stationCoordsOptional: true, // see #28 - }) - const validate = createValidate(customCfg, validators) - validate(t, res, 'radarResult', 'res') + }); + const validate = createValidate(customCfg, validators); + validate(t, res, 'radarResult', 'res'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/invg.js b/test/e2e/invg.js index 0c55023b5..e5e34ab86 100644 --- a/test/e2e/invg.js +++ b/test/e2e/invg.js @@ -1,70 +1,70 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as invgProfile} from '../../p/invg/index.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as invgProfile} from '../../p/invg/index.js'; import { createValidateJourneyLeg, createValidateMovement, -} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testArrivals} from './lib/arrivals.js' - -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(invgProfile.timezone, invgProfile.locale, T_MOCK) +} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testArrivals} from './lib/arrivals.js'; + +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(invgProfile.timezone, invgProfile.locale, T_MOCK); const cfg = { when, products: invgProfile.products, -} +}; -const _validateJourneyLeg = createValidateJourneyLeg(cfg) +const _validateJourneyLeg = createValidateJourneyLeg(cfg); const validateJourneyLeg = (val, leg, name = 'journeyLeg') => { _validateJourneyLeg(val, { ...leg, direction: leg.direction || 'foo', - }, name) -} + }, name); +}; -const _validateMovement = createValidateMovement(cfg) +const _validateMovement = createValidateMovement(cfg); const validateMovement = (val, m, name = 'movement') => { _validateMovement(val, { ...m, direction: m.direction || 'foo', - }, name) -} + }, name); +}; const validate = createValidate(cfg, { journeyLeg: validateJourneyLeg, movement: validateMovement, -}) +}); -const client = createClient(invgProfile, 'public-transport/hafas-client:test') +const client = createClient(invgProfile, 'public-transport/hafas-client:test'); -const ingolstadtHbf = '8000183' -const telemannstr = '71802' +const ingolstadtHbf = '8000183'; +const telemannstr = '71802'; const uhlandstr1 = { type: 'location', address: 'Ingolstadt, Uhlandstraße 1', latitude: 48.775236, longitude: 11.441138, -} +}; tap.test('journeys – Ingolstadt Hbf to Audi Parkplatz', async (t) => { - const telemannstr = '71801' + const telemannstr = '71801'; const res = await client.journeys(ingolstadtHbf, telemannstr, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -72,9 +72,9 @@ tap.test('journeys – Ingolstadt Hbf to Audi Parkplatz', async (t) => { validate, fromId: ingolstadtHbf, toId: telemannstr, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -86,15 +86,15 @@ tap.test('journeys – fails with no product', async (t) => { toId: telemannstr, when, products: invgProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Ingolstadt Hbf to Uhlandstr. 1', async (t) => { const res = await client.journeys(ingolstadtHbf, uhlandstr1, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -102,9 +102,9 @@ tap.test('Ingolstadt Hbf to Uhlandstr. 1', async (t) => { validate, fromId: ingolstadtHbf, to: uhlandstr1, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Ingolstadt Hbf to Städtisches Freibad', async (t) => { const freibad = { @@ -114,11 +114,11 @@ tap.test('Ingolstadt Hbf to Städtisches Freibad', async (t) => { name: 'Ingolstadt, Städtisches Freibad (Sport)', latitude: 48.761473, longitude: 11.418602, - } + }; const res = await client.journeys(ingolstadtHbf, freibad, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -126,9 +126,9 @@ tap.test('Ingolstadt Hbf to Städtisches Freibad', async (t) => { validate, fromId: ingolstadtHbf, to: freibad, - }) - t.end() -}) + }); + t.end(); +}); // todo: via works – with detour // todo: without detour @@ -141,10 +141,10 @@ tap.test('earlier/later journeys', async (t) => { fromId: ingolstadtHbf, toId: telemannstr, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('refreshJourney', async (t) => { await testRefreshJourney({ @@ -155,24 +155,24 @@ tap.test('refreshJourney', async (t) => { fromId: ingolstadtHbf, toId: telemannstr, when, - }) - t.end() -}) + }); + t.end(); +}); tap.test('trip details', async (t) => { const {journeys} = await client.journeys(ingolstadtHbf, telemannstr, { results: 1, departure: when, - }) + }); - const p = journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Ingolstadt Hbf', async (t) => { const ids = [ @@ -180,20 +180,20 @@ tap.test('departures at Ingolstadt Hbf', async (t) => { '80301', // stop "Ingolstadt, Hauptbahnhof Stadtauswärts" '80302', // stop "Ingolstadt, Hauptbahnhof Stadteinwärts" '80303', // stop "Ingolstadt, Hauptbahnhof Stadtauswärts" - ] + ]; const res = await client.departures(ingolstadtHbf, { duration: 10, when, - }) + }); await testDepartures({ test: t, res, validate, ids, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -205,31 +205,31 @@ tap.test('departures with station object', async (t) => { latitude: 48.822834, longitude: 11.461148, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('arrivals at Ingolstadt Hbf', async (t) => { const ids = [ ingolstadtHbf, // station '80301', // stop "Ingolstadt, Hauptbahnhof Stadtauswärts" '80302', // stop "Ingolstadt, Hauptbahnhof Stadteinwärts" - ] + ]; const res = await client.arrivals(ingolstadtHbf, { duration: 10, when, - }) + }); await testArrivals({ test: t, res, validate, ids, - }) - t.end() -}) + }); + t.end(); +}); tap.test('nearby', async (t) => { const nearby = await client.nearby({ @@ -238,45 +238,45 @@ tap.test('nearby', async (t) => { address: 'Ingolstadt, Rathausplatz 1', latitude: 48.76292, longitude: 11.424624, - }, {distance: 500}) + }, {distance: 500}); - validate(t, nearby, 'locations', 'nearby') + validate(t, nearby, 'locations', 'nearby'); - const rathausplatz = '60706' - const harderstr = '28402' - t.ok(nearby.find(l => l.id === rathausplatz)) - t.ok(nearby.find(l => l.id === harderstr)) + const rathausplatz = '60706'; + const harderstr = '28402'; + t.ok(nearby.find(l => l.id === rathausplatz)); + t.ok(nearby.find(l => l.id === harderstr)); - t.end() -}) + t.end(); +}); tap.test('locations named "freibad"', async (t) => { - const freibadIngolstadt = '980000591' + const freibadIngolstadt = '980000591'; const locations = await client.locations('freibad', { results: 5, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 10) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 10); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.id && s.name)) // POIs + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.id && s.name)); // POIs t.ok(locations.some((l) => { - return l.station && l.station.id === freibadIngolstadt || l.id === freibadIngolstadt - })) + return l.station && l.station.id === freibadIngolstadt || l.id === freibadIngolstadt; + })); - t.end() -}) + t.end(); +}); tap.test('stop Ettinger Str.', async (t) => { - const ettingerStr = '18304' - const s = await client.stop(ettingerStr) + const ettingerStr = '18304'; + const s = await client.stop(ettingerStr); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, ettingerStr) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, ettingerStr); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -286,8 +286,8 @@ tap.test('radar', async (t) => { east: 11.43733, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); diff --git a/test/e2e/ivb.js b/test/e2e/ivb.js index 6eef9ffd5..5244d2340 100644 --- a/test/e2e/ivb.js +++ b/test/e2e/ivb.js @@ -1,12 +1,12 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as ivbProfile} from '../../p/ivb/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as ivbProfile} from '../../p/ivb/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(ivbProfile.timezone, ivbProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(ivbProfile.timezone, ivbProfile.locale, T_MOCK); const cfg = { when, @@ -16,20 +16,20 @@ const cfg = { maxLongitude: 17.0892, minLatitude: 45.7206, minLongitude: 7.8635, -} -const validate = createValidate(cfg) +}; +const validate = createValidate(cfg); -const client = createClient(ivbProfile, 'public-transport/hafas-client:test') +const client = createClient(ivbProfile, 'public-transport/hafas-client:test'); -const innsbruckGriesauweg = '476162400' +const innsbruckGriesauweg = '476162400'; tap.test('locations named "griesauweg"', async (t) => { - const locations = await client.locations('griesauweg') + const locations = await client.locations('griesauweg'); - validate(t, locations, 'locations', 'locations') + validate(t, locations, 'locations', 'locations'); t.ok(locations.some((l) => { - return l.station && l.station.id === innsbruckGriesauweg || l.id === innsbruckGriesauweg - }), 'Innsbruck Griesauweg not found') + return l.station && l.station.id === innsbruckGriesauweg || l.id === innsbruckGriesauweg; + }), 'Innsbruck Griesauweg not found'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/kvb.js b/test/e2e/kvb.js index 00efd86b2..eb09c6546 100644 --- a/test/e2e/kvb.js +++ b/test/e2e/kvb.js @@ -1,12 +1,12 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as kvbProfile} from '../../p/kvb/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as kvbProfile} from '../../p/kvb/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(kvbProfile.timezone, kvbProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(kvbProfile.timezone, kvbProfile.locale, T_MOCK); const cfg = { when, @@ -16,20 +16,20 @@ const cfg = { maxLongitude: 7.8333, minLatitude: 50.3253, minLongitude: 6.2320, -} -const validate = createValidate(cfg) +}; +const validate = createValidate(cfg); -const client = createClient(kvbProfile, 'public-transport/hafas-client:test') +const client = createClient(kvbProfile, 'public-transport/hafas-client:test'); -const heumarkt = '900000001' +const heumarkt = '900000001'; tap.test('locations named "heumarkt"', async (t) => { - const locations = await client.locations('heumarkt') + const locations = await client.locations('heumarkt'); - validate(t, locations, 'locations', 'locations') + validate(t, locations, 'locations', 'locations'); t.ok(locations.some((l) => { - return l.station && l.station.id === heumarkt || l.id === heumarkt - }), 'Heumarkt not found') + return l.station && l.station.id === heumarkt || l.id === heumarkt; + }), 'Heumarkt not found'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/lib/arrivals.js b/test/e2e/lib/arrivals.js index 0faf29ff2..11ef3f35f 100644 --- a/test/e2e/lib/arrivals.js +++ b/test/e2e/lib/arrivals.js @@ -1,31 +1,31 @@ const testArrivals = async (cfg) => { - const {test: t, res, validate} = cfg + const {test: t, res, validate} = cfg; const ids = cfg.ids || (cfg.id ? [cfg.id] - : []) - const {arrivals: arrs} = res + : []); + const {arrivals: arrs} = res; - validate(t, res, 'arrivalsResponse', 'res') + validate(t, res, 'arrivalsResponse', 'res'); for (let i = 0; i < arrs.length; i++) { - let stop = arrs[i].stop - let name = `res.arrivals[${i}].stop` + let stop = arrs[i].stop; + let name = `res.arrivals[${i}].stop`; if (stop.station) { - stop = stop.station - name += '.station' + stop = stop.station; + name += '.station'; } t.ok( ids.includes(stop.id) || stop.station && ids.includes(stop.station.id), name + '.id is invalid', - ) + ); } // todo: move into arrivals validator - t.same(arrs, arrs.sort((a, b) => t.when > b.when), 'res.arrivals must be sorted by .when') -} + t.same(arrs, arrs.sort((a, b) => t.when > b.when), 'res.arrivals must be sorted by .when'); +}; export { testArrivals, -} +}; diff --git a/test/e2e/lib/departures-in-direction.js b/test/e2e/lib/departures-in-direction.js index b71cf8a14..7172890df 100644 --- a/test/e2e/lib/departures-in-direction.js +++ b/test/e2e/lib/departures-in-direction.js @@ -7,30 +7,30 @@ const testDeparturesInDirection = async (cfg) => { directionIds, when, validate, - } = cfg + } = cfg; const res = await fetchDepartures(id, { direction: directionIds[0], when, - }) - const {departures: deps} = res + }); + const {departures: deps} = res; - validate(t, res, 'departuresResponse', 'res') + validate(t, res, 'departuresResponse', 'res'); for (let i = 0; i < deps.length; i++) { - const dep = deps[i] - const name = `deps[${i}]` + const dep = deps[i]; + const name = `deps[${i}]`; - const line = dep.line && dep.line.name + const line = dep.line && dep.line.name; const {trip} = await fetchTrip(dep.tripId, line, { when, stopovers: true, - }) + }); t.ok(trip.stopovers.some(st => st.stop.station && directionIds.includes(st.stop.station.id) || directionIds.includes(st.stop.id), - ), `trip ${dep.tripId} of ${name} has no stopover at ${directionIds.join('/')}`) + ), `trip ${dep.tripId} of ${name} has no stopover at ${directionIds.join('/')}`); } -} +}; export { testDeparturesInDirection, -} +}; diff --git a/test/e2e/lib/departures.js b/test/e2e/lib/departures.js index 2d082ac3e..1fd44a2f3 100644 --- a/test/e2e/lib/departures.js +++ b/test/e2e/lib/departures.js @@ -1,31 +1,31 @@ const testDepartures = async (cfg) => { - const {test: t, res, validate} = cfg + const {test: t, res, validate} = cfg; const ids = cfg.ids || (cfg.id ? [cfg.id] - : []) - const {departures: deps} = res + : []); + const {departures: deps} = res; - validate(t, res, 'departuresResponse', 'res') + validate(t, res, 'departuresResponse', 'res'); for (let i = 0; i < deps.length; i++) { - let stop = deps[i].stop - let name = `res.departures[${i}].stop` + let stop = deps[i].stop; + let name = `res.departures[${i}].stop`; if (stop.station) { - stop = stop.station - name += '.station' + stop = stop.station; + name += '.station'; } t.ok( ids.includes(stop.id) || stop.station && ids.includes(stop.station.id), `${name}.id is invalid (${stop.id}), must be one of ${ids.join('/')}`, - ) + ); } // todo: move into deps validator - t.same(deps, deps.sort((a, b) => t.when > b.when), 'res.departures must be sorted by .when') -} + t.same(deps, deps.sort((a, b) => t.when > b.when), 'res.departures must be sorted by .when'); +}; export { testDepartures, -} +}; diff --git a/test/e2e/lib/earlier-later-journeys.js b/test/e2e/lib/earlier-later-journeys.js index aef0428f7..00f4fe909 100644 --- a/test/e2e/lib/earlier-later-journeys.js +++ b/test/e2e/lib/earlier-later-journeys.js @@ -6,50 +6,50 @@ const testEarlierLaterJourneys = async (cfg) => { toId, when, // todo: validate - } = cfg + } = cfg; const model = await fetchJourneys(fromId, toId, { results: 3, departure: when, - }) + }); // todo: move to journeys validator? - t.equal(typeof model.earlierRef, 'string') - t.ok(model.earlierRef) - t.equal(typeof model.laterRef, 'string') - t.ok(model.laterRef) + t.equal(typeof model.earlierRef, 'string'); + t.ok(model.earlierRef); + t.equal(typeof model.laterRef, 'string'); + t.ok(model.laterRef); // departure/arrival and earlierThan/laterThan should be mutually exclusive await t.rejects(async () => { await fetchJourneys(fromId, toId, { departure: when, earlierThan: model.earlierRef, - }) - }) + }); + }); await t.rejects(async () => { await fetchJourneys(fromId, toId, { departure: when, laterThan: model.laterRef, - }) - }) + }); + }); await t.rejects(async () => { await fetchJourneys(fromId, toId, { arrival: when, earlierThan: model.earlierRef, - }) - }) + }); + }); await t.rejects(async () => { await fetchJourneys(fromId, toId, { arrival: when, laterThan: model.laterRef, - }) - }) + }); + }); - let earliestDep = Infinity, latestDep = -Infinity + let earliestDep = Infinity, latestDep = -Infinity; for (let j of model.journeys) { if (j.legs[0].departure === null) { - continue + continue; } - const dep = Date.parse(j.legs[0].departure) + const dep = Date.parse(j.legs[0].departure); if (dep < earliestDep) { - earliestDep = dep + earliestDep = dep; } else if (dep > latestDep) { - latestDep = dep + latestDep = dep; } } @@ -57,25 +57,25 @@ const testEarlierLaterJourneys = async (cfg) => { results: 3, // todo: single journey ref? earlierThan: model.earlierRef, - }) + }); for (let j of earlier.journeys) { - const firstLeg = j.legs[0] - const dep = Date.parse(firstLeg.departure || firstLeg.plannedDeparture) - t.ok(dep < earliestDep) + const firstLeg = j.legs[0]; + const dep = Date.parse(firstLeg.departure || firstLeg.plannedDeparture); + t.ok(dep < earliestDep); } const later = await fetchJourneys(fromId, toId, { results: 3, // todo: single journey ref? laterThan: model.laterRef, - }) + }); for (let j of later.journeys) { - const firstLeg = j.legs[0] - const dep = Date.parse(firstLeg.departure || firstLeg.plannedDeparture) - t.ok(dep > latestDep) + const firstLeg = j.legs[0]; + const dep = Date.parse(firstLeg.departure || firstLeg.plannedDeparture); + t.ok(dep > latestDep); } -} +}; export { testEarlierLaterJourneys, -} +}; diff --git a/test/e2e/lib/journeys-fails-with-no-product.js b/test/e2e/lib/journeys-fails-with-no-product.js index dd1710f4f..4adc80616 100644 --- a/test/e2e/lib/journeys-fails-with-no-product.js +++ b/test/e2e/lib/journeys-fails-with-no-product.js @@ -6,18 +6,18 @@ const journeysFailsWithNoProduct = async (cfg) => { toId, when, products, - } = cfg + } = cfg; - const noProducts = Object.create(null) + const noProducts = Object.create(null); for (let p of products) { - noProducts[p.id] = false + noProducts[p.id] = false; } await t.rejects(async () => { - await fetchJourneys(fromId, toId, {departure: when, products: noProducts}) - }) -} + await fetchJourneys(fromId, toId, {departure: when, products: noProducts}); + }); +}; export { journeysFailsWithNoProduct, -} +}; diff --git a/test/e2e/lib/journeys-station-to-address.js b/test/e2e/lib/journeys-station-to-address.js index 773081abf..b583f6b27 100644 --- a/test/e2e/lib/journeys-station-to-address.js +++ b/test/e2e/lib/journeys-station-to-address.js @@ -1,30 +1,30 @@ -import isRoughlyEqual from 'is-roughly-equal' +import isRoughlyEqual from 'is-roughly-equal'; const testJourneysStationToAddress = async (cfg) => { - const {test: t, res, validate, fromId} = cfg - const {address, latitude, longitude} = cfg.to + const {test: t, res, validate, fromId} = cfg; + const {address, latitude, longitude} = cfg.to; - validate(t, res, 'journeysResult', 'res') - const {journeys} = res + validate(t, res, 'journeysResult', 'res'); + const {journeys} = res; - t.ok(journeys.length >= 3, 'journeys must have >=3 items') + t.ok(journeys.length >= 3, 'journeys must have >=3 items'); for (let i = 0; i < journeys.length; i++) { - const j = journeys[i] + const j = journeys[i]; - const firstLeg = j.legs[0] - const orig = firstLeg.origin.station || firstLeg.origin - t.ok(orig.id, fromId) + const firstLeg = j.legs[0]; + const orig = firstLeg.origin.station || firstLeg.origin; + t.ok(orig.id, fromId); - const d = j.legs[j.legs.length - 1].destination - const n = `res.journeys[0].legs[${i}].destination` + const d = j.legs[j.legs.length - 1].destination; + const n = `res.journeys[0].legs[${i}].destination`; - t.equal(d.type, 'location', n + '.type is invalid') - t.equal(d.address, address, n + '.address is invalid') - t.ok(isRoughlyEqual(0.0001, d.latitude, latitude), n + '.latitude is invalid') - t.ok(isRoughlyEqual(0.0001, d.longitude, longitude), n + '.longitude is invalid') + t.equal(d.type, 'location', n + '.type is invalid'); + t.equal(d.address, address, n + '.address is invalid'); + t.ok(isRoughlyEqual(0.0001, d.latitude, latitude), n + '.latitude is invalid'); + t.ok(isRoughlyEqual(0.0001, d.longitude, longitude), n + '.longitude is invalid'); } -} +}; export { testJourneysStationToAddress, -} +}; diff --git a/test/e2e/lib/journeys-station-to-poi.js b/test/e2e/lib/journeys-station-to-poi.js index fd9fd2b54..5625b492e 100644 --- a/test/e2e/lib/journeys-station-to-poi.js +++ b/test/e2e/lib/journeys-station-to-poi.js @@ -1,42 +1,42 @@ -import isRoughlyEqual from 'is-roughly-equal' +import isRoughlyEqual from 'is-roughly-equal'; const testJourneysStationToPoi = async (cfg) => { - const {test: t, res, validate} = cfg + const {test: t, res, validate} = cfg; const fromIds = cfg.fromIds || (cfg.fromId ? [cfg.fromId] - : []) - const {id, name, latitude, longitude} = cfg.to + : []); + const {id, name, latitude, longitude} = cfg.to; - validate(t, res, 'journeysResult', 'res') - const {journeys} = res + validate(t, res, 'journeysResult', 'res'); + const {journeys} = res; - t.ok(journeys.length >= 3, 'journeys must have >=3 items') + t.ok(journeys.length >= 3, 'journeys must have >=3 items'); for (let i = 0; i < journeys.length; i++) { - const j = journeys[i] + const j = journeys[i]; - let o = j.legs[0].origin - const oN = 'res.journeys[0].legs[0].destination' + let o = j.legs[0].origin; + const oN = 'res.journeys[0].legs[0].destination'; t.ok( fromIds.includes(o.id) || o.station && fromIds.includes(o.station.id), `invalid ${oN}.legs[0].origin`, - ) + ); - let d = j.legs[j.legs.length - 1].destination - let dN = `res.journeys[${i}].legs[${j.legs.length - 1}].destination` + let d = j.legs[j.legs.length - 1].destination; + let dN = `res.journeys[${i}].legs[${j.legs.length - 1}].destination`; if (d.station) { - d = d.station - dN += '.station' + d = d.station; + dN += '.station'; } - t.equal(d.type, 'location', dN + '.type is invalid') - t.equal(d.id, id, dN + '.id is invalid') - t.equal(d.name, name, dN + '.name is invalid') - t.ok(isRoughlyEqual(0.0001, d.latitude, latitude), dN + '.latitude is invalid') - t.ok(isRoughlyEqual(0.0001, d.longitude, longitude), dN + '.longitude is invalid') + t.equal(d.type, 'location', dN + '.type is invalid'); + t.equal(d.id, id, dN + '.id is invalid'); + t.equal(d.name, name, dN + '.name is invalid'); + t.ok(isRoughlyEqual(0.0001, d.latitude, latitude), dN + '.latitude is invalid'); + t.ok(isRoughlyEqual(0.0001, d.longitude, longitude), dN + '.longitude is invalid'); } -} +}; export { testJourneysStationToPoi, -} +}; diff --git a/test/e2e/lib/journeys-station-to-station.js b/test/e2e/lib/journeys-station-to-station.js index 5110cefb1..83fdc0fe8 100644 --- a/test/e2e/lib/journeys-station-to-station.js +++ b/test/e2e/lib/journeys-station-to-station.js @@ -1,35 +1,35 @@ const testJourneysStationToStation = async (cfg) => { - const {test: t, res, validate} = cfg + const {test: t, res, validate} = cfg; const fromIds = cfg.fromIds || (cfg.fromId ? [cfg.fromId] - : []) + : []); const toIds = cfg.toIds || (cfg.toId ? [cfg.toId] - : []) + : []); - validate(t, res, 'journeysResult', 'res') - const {journeys} = res + validate(t, res, 'journeysResult', 'res'); + const {journeys} = res; - t.ok(journeys.length >= 4, 'journeys must have >=4 items') + t.ok(journeys.length >= 4, 'journeys must have >=4 items'); for (let i = 0; i < journeys.length; i++) { - const j = journeys[i] - const n = `res.journeys[${i}]` + const j = journeys[i]; + const n = `res.journeys[${i}]`; - const o = j.legs[0].origin - const d = j.legs[j.legs.length - 1].destination + const o = j.legs[0].origin; + const d = j.legs[j.legs.length - 1].destination; t.ok( fromIds.includes(o.id) || o.station && fromIds.includes(o.station.id), `invalid ${n}.legs[0].origin`, - ) + ); t.ok( toIds.includes(d.id) || d.station && toIds.includes(d.station.id), `invalid ${n}.legs[${j.legs.length - 1}].destination`, - ) + ); } -} +}; export { testJourneysStationToStation, -} +}; diff --git a/test/e2e/lib/journeys-walking-speed.js b/test/e2e/lib/journeys-walking-speed.js index f29fae6e7..05ac32ba7 100644 --- a/test/e2e/lib/journeys-walking-speed.js +++ b/test/e2e/lib/journeys-walking-speed.js @@ -1,31 +1,31 @@ -import isRoughlyEqual from 'is-roughly-equal' +import isRoughlyEqual from 'is-roughly-equal'; const testJourneysWalkingSpeed = async (cfg) => { - const {test: t, journeys, validate, from, to, when, products, minTimeDifference} = cfg + const {test: t, journeys, validate, from, to, when, products, minTimeDifference} = cfg; const {journeys: [journeyWithFastWalking]} = await journeys(from, to, { departure: when, results: 1, products, walkingSpeed: 'fast', - }) - const legWithFastWalking = journeyWithFastWalking.legs.find(l => l.walking) - t.ok(legWithFastWalking, 'no walking leg in journey with fast walking') + }); + const legWithFastWalking = journeyWithFastWalking.legs.find(l => l.walking); + t.ok(legWithFastWalking, 'no walking leg in journey with fast walking'); const {journeys: [journeyWithSlowWalking]} = await journeys(from, to, { departure: when, results: 1, products, walkingSpeed: 'slow', - }) - const legWithSlowWalking = journeyWithSlowWalking.legs.find(l => l.walking) - t.ok(legWithSlowWalking, 'no walking leg in journey with slow walking') + }); + const legWithSlowWalking = journeyWithSlowWalking.legs.find(l => l.walking); + t.ok(legWithSlowWalking, 'no walking leg in journey with slow walking'); - const fastDist = legWithFastWalking.distance - const slowDist = legWithSlowWalking.distance - t.ok(isRoughlyEqual(100, fastDist, slowDist), 'precondition failed') - const fastDur = new Date(legWithFastWalking.arrival) - new Date(legWithFastWalking.departure) - const slowDur = new Date(legWithSlowWalking.arrival) - new Date(legWithSlowWalking.departure) - t.notOk(isRoughlyEqual(minTimeDifference, fastDur, slowDur), 'walkingSpeed not applied') - t.end() -} + const fastDist = legWithFastWalking.distance; + const slowDist = legWithSlowWalking.distance; + t.ok(isRoughlyEqual(100, fastDist, slowDist), 'precondition failed'); + const fastDur = new Date(legWithFastWalking.arrival) - new Date(legWithFastWalking.departure); + const slowDur = new Date(legWithSlowWalking.arrival) - new Date(legWithSlowWalking.departure); + t.notOk(isRoughlyEqual(minTimeDifference, fastDur, slowDur), 'walkingSpeed not applied'); + t.end(); +}; export { testJourneysWalkingSpeed, -} +}; diff --git a/test/e2e/lib/journeys-with-detour.js b/test/e2e/lib/journeys-with-detour.js index 6166da07a..1843d7402 100644 --- a/test/e2e/lib/journeys-with-detour.js +++ b/test/e2e/lib/journeys-with-detour.js @@ -1,20 +1,20 @@ const testJourneysWithDetour = async (cfg) => { - const {test: t, res, validate, detourIds} = cfg + const {test: t, res, validate, detourIds} = cfg; // We assume that going from A to B via C *without* detour is currently // impossible. We check if the routing engine computes a detour. - validate(t, res, 'journeysResult', 'res') - const {journeys} = res + validate(t, res, 'journeysResult', 'res'); + const {journeys} = res; const leg = journeys[0].legs.some((leg) => { return leg.stopovers && leg.stopovers.some((st) => st.stop.station && detourIds.includes(st.stop.station.id) || detourIds.includes(st.stop.id), - ) - }) - t.ok(leg, detourIds.join('/') + ' is not being passed') -} + ); + }); + t.ok(leg, detourIds.join('/') + ' is not being passed'); +}; export { testJourneysWithDetour, -} +}; diff --git a/test/e2e/lib/leg-cycle-alternatives.js b/test/e2e/lib/leg-cycle-alternatives.js index 60c3067f5..3ab4609a6 100644 --- a/test/e2e/lib/leg-cycle-alternatives.js +++ b/test/e2e/lib/leg-cycle-alternatives.js @@ -1,6 +1,6 @@ -import isRoughlyEqual from 'is-roughly-equal' +import isRoughlyEqual from 'is-roughly-equal'; -import {hour} from './util.js' +import {hour} from './util.js'; const testLegCycleAlternatives = async (cfg) => { const { @@ -8,43 +8,43 @@ const testLegCycleAlternatives = async (cfg) => { fetchJourneys, fromId, toId, - } = cfg + } = cfg; // Apparently HAFAS doesn't return the leg cycle or alternatives more // than ~2 hours in advance. This is why we don't pass `when` here. - const journeys = await fetchJourneys(fromId, toId, {results: 3}) + const journeys = await fetchJourneys(fromId, toId, {results: 3}); for (let i = 0; i < journeys.length; i++) { - const journey = journeys[i] + const journey = journeys[i]; for (let j = 0; j < journey.legs.length; j++) { - const leg = journey.legs[j] - const name = `journeys[${i}].legs[${j}]` + const leg = journey.legs[j]; + const name = `journeys[${i}].legs[${j}]`; if (!leg.line) { - continue + continue; } - t.ok(leg.cycle, name + '.cycle is missing') - t.equal(typeof leg.cycle.min, 'number', name + '.cycle.min is not a number') - t.equal(typeof leg.cycle.max, 'number', name + '.cycle.max is not a number') - t.equal(typeof leg.cycle.nr, 'number', name + '.cycle.nr is not a number') + t.ok(leg.cycle, name + '.cycle is missing'); + t.equal(typeof leg.cycle.min, 'number', name + '.cycle.min is not a number'); + t.equal(typeof leg.cycle.max, 'number', name + '.cycle.max is not a number'); + t.equal(typeof leg.cycle.nr, 'number', name + '.cycle.nr is not a number'); - const lineWhen = Number(new Date(leg.departure)) - t.ok(Array.isArray(leg.alternatives), name + '.alternatives must be an array') + const lineWhen = Number(new Date(leg.departure)); + t.ok(Array.isArray(leg.alternatives), name + '.alternatives must be an array'); for (let k = 0; k < leg.alternatives.length; k++) { - const a = leg.alternatives[k] - const n = name + `.alternatives[${k}]` + const a = leg.alternatives[k]; + const n = name + `.alternatives[${k}]`; - let alternativeWhen = Number(new Date(a.when)) + let alternativeWhen = Number(new Date(a.when)); if ('number' === typeof a.delay) { - alternativeWhen -= a.delay * 1000 + alternativeWhen -= a.delay * 1000; } - t.ok(isRoughlyEqual(2 * hour, alternativeWhen, lineWhen), n + '.when seems invalid') + t.ok(isRoughlyEqual(2 * hour, alternativeWhen, lineWhen), n + '.when seems invalid'); } } } -} +}; export { testLegCycleAlternatives, -} +}; diff --git a/test/e2e/lib/lines.js b/test/e2e/lib/lines.js index 75b7508f8..fbde7e754 100644 --- a/test/e2e/lib/lines.js +++ b/test/e2e/lib/lines.js @@ -4,23 +4,23 @@ const testLines = async (cfg) => { fetchLines, validate, query, - } = cfg + } = cfg; - const res = await fetchLines(query) + const res = await fetchLines(query); const { lines, realtimeDataUpdatedAt, - } = res + } = res; for (let i = 0; i < res.lines.length; i++) { - const l = res.lines[i] - const name = `res.lines[${i}]` - validate(t, l, 'line', name) + const l = res.lines[i]; + const name = `res.lines[${i}]`; + validate(t, l, 'line', name); } - validate(t, realtimeDataUpdatedAt, 'realtimeDataUpdatedAt', 'res.realtimeDataUpdatedAt') -} + validate(t, realtimeDataUpdatedAt, 'realtimeDataUpdatedAt', 'res.realtimeDataUpdatedAt'); +}; export { testLines, -} +}; diff --git a/test/e2e/lib/reachable-from.js b/test/e2e/lib/reachable-from.js index cc37d930f..8f8727f7e 100644 --- a/test/e2e/lib/reachable-from.js +++ b/test/e2e/lib/reachable-from.js @@ -1,4 +1,4 @@ -import isPlainObject from 'lodash/isPlainObject.js' +import isPlainObject from 'lodash/isPlainObject.js'; const testReachableFrom = async (cfg) => { const { @@ -8,43 +8,43 @@ const testReachableFrom = async (cfg) => { when, maxDuration, validate, - } = cfg + } = cfg; const res = await reachableFrom(address, { when, maxDuration, - }) + }); const { reachable: results, realtimeDataUpdatedAt, - } = res + } = res; if (realtimeDataUpdatedAt !== null) { // todo: move this check into validators - validate(t, realtimeDataUpdatedAt, 'realtimeDataUpdatedAt', 'res.realtimeDataUpdatedAt') + validate(t, realtimeDataUpdatedAt, 'realtimeDataUpdatedAt', 'res.realtimeDataUpdatedAt'); } - t.ok(Array.isArray(results), 'results must an array') - t.ok(results.length > 0, 'results must have >0 items') + t.ok(Array.isArray(results), 'results must an array'); + t.ok(results.length > 0, 'results must have >0 items'); for (let i = 0; i < results.length; i++) { - const res = results[i] - const name = `results[${i}]` + const res = results[i]; + const name = `results[${i}]`; - t.ok(isPlainObject(res), name + ' must be an object') - t.equal(typeof res.duration, 'number', name + '.duration must be a number') - t.ok(res.duration > 0, name + '.duration must be >0') + t.ok(isPlainObject(res), name + ' must be an object'); + t.equal(typeof res.duration, 'number', name + '.duration must be a number'); + t.ok(res.duration > 0, name + '.duration must be >0'); - t.ok(Array.isArray(res.stations), name + '.stations must be an array') - t.ok(res.stations.length > 0, name + '.stations must have >0 items') + t.ok(Array.isArray(res.stations), name + '.stations must be an array'); + t.ok(res.stations.length > 0, name + '.stations must have >0 items'); for (let j = 0; j < res.stations.length; j++) { - validate(t, res.stations[j], ['stop', 'station'], `${name}.stations[${j}]`) + validate(t, res.stations[j], ['stop', 'station'], `${name}.stations[${j}]`); } } - const sorted = results.sort((a, b) => a.duration - b.duration) - t.same(results, sorted, 'results must be sorted by res.duration') -} + const sorted = results.sort((a, b) => a.duration - b.duration); + t.same(results, sorted, 'results must be sorted by res.duration'); +}; export { testReachableFrom, -} +}; diff --git a/test/e2e/lib/refresh-journey.js b/test/e2e/lib/refresh-journey.js index b5abaebac..391dec321 100644 --- a/test/e2e/lib/refresh-journey.js +++ b/test/e2e/lib/refresh-journey.js @@ -5,8 +5,8 @@ const simplify = j => j.legs.map(l => { departure: l.plannedDeparture || l.departure, arrival: l.plannedArrival || l.arrival, line: l.line, - } -}) + }; +}); const testRefreshJourney = async (cfg) => { const { @@ -17,28 +17,28 @@ const testRefreshJourney = async (cfg) => { fromId, toId, when, - } = cfg + } = cfg; const modelRes = await fetchJourneys(fromId, toId, { results: 1, departure: when, stopovers: false, - }) - validate(t, modelRes, 'journeysResult', 'modelRes') - const [model] = modelRes.journeys + }); + validate(t, modelRes, 'journeysResult', 'modelRes'); + const [model] = modelRes.journeys; // todo: move to journeys validator? - t.equal(typeof model.refreshToken, 'string') - t.ok(model.refreshToken) + t.equal(typeof model.refreshToken, 'string'); + t.ok(model.refreshToken); const refreshedRes = await refreshJourney(model.refreshToken, { stopovers: false, - }) - validate(t, refreshedRes, 'refreshJourneyResult', 'refreshedRes') - const refreshed = refreshedRes.journey + }); + validate(t, refreshedRes, 'refreshJourneyResult', 'refreshedRes'); + const refreshed = refreshedRes.journey; - t.same(simplify(refreshed), simplify(model)) -} + t.same(simplify(refreshed), simplify(model)); +}; export { testRefreshJourney, -} +}; diff --git a/test/e2e/lib/remarks.js b/test/e2e/lib/remarks.js index 004030cae..634fc7ad6 100644 --- a/test/e2e/lib/remarks.js +++ b/test/e2e/lib/remarks.js @@ -1,4 +1,4 @@ -const WEEK = 7 * 24 * 60 * 60 * 1000 +const WEEK = 7 * 24 * 60 * 60 * 1000; const testRemarks = async (cfg) => { const { @@ -6,30 +6,30 @@ const testRemarks = async (cfg) => { fetchRemarks, validate, when, - } = cfg + } = cfg; const res = await fetchRemarks({ results: 10, from: when, to: new Date(when + WEEK), - }) + }); const { remarks, realtimeDataUpdatedAt, - } = res + } = res; for (let i = 0; i < res.remarks.length; i++) { - const rem = res.remarks[i] - const name = `res.remarks[${i}]` - validate(t, rem, 'remark', name) + const rem = res.remarks[i]; + const name = `res.remarks[${i}]`; + validate(t, rem, 'remark', name); } // most endpoints currently don't provide this info for remarks() if (realtimeDataUpdatedAt !== null) { - validate(t, realtimeDataUpdatedAt, 'realtimeDataUpdatedAt', 'res.realtimeDataUpdatedAt') + validate(t, realtimeDataUpdatedAt, 'realtimeDataUpdatedAt', 'res.realtimeDataUpdatedAt'); } -} +}; export { testRemarks, -} +}; diff --git a/test/e2e/lib/server-info.js b/test/e2e/lib/server-info.js index a6a055e7b..0a638b539 100644 --- a/test/e2e/lib/server-info.js +++ b/test/e2e/lib/server-info.js @@ -2,26 +2,26 @@ const testServerInfo = async (cfg) => { const { test: t, fetchServerInfo, - } = cfg + } = cfg; - const info = await fetchServerInfo() - t.ok(info, 'invalid info') + const info = await fetchServerInfo(); + t.ok(info, 'invalid info'); - t.equal(typeof info.hciVersion, 'string', 'invalid info.hciVersion') - t.ok(info.hciVersion, 'invalid info.hciVersion') + t.equal(typeof info.hciVersion, 'string', 'invalid info.hciVersion'); + t.ok(info.hciVersion, 'invalid info.hciVersion'); - t.equal(typeof info.timetableStart, 'string', 'invalid info.timetableStart') - t.ok(info.timetableStart, 'invalid info.timetableStart') - t.equal(typeof info.timetableEnd, 'string', 'invalid info.timetableEnd') - t.ok(info.timetableEnd, 'invalid info.timetableEnd') + t.equal(typeof info.timetableStart, 'string', 'invalid info.timetableStart'); + t.ok(info.timetableStart, 'invalid info.timetableStart'); + t.equal(typeof info.timetableEnd, 'string', 'invalid info.timetableEnd'); + t.ok(info.timetableEnd, 'invalid info.timetableEnd'); - t.equal(typeof info.serverTime, 'string', 'invalid info.serverTime') - t.notOk(Number.isNaN(Date.parse(info.serverTime)), 'invalid info.serverTime') + t.equal(typeof info.serverTime, 'string', 'invalid info.serverTime'); + t.notOk(Number.isNaN(Date.parse(info.serverTime)), 'invalid info.serverTime'); - t.ok(Number.isInteger(info.realtimeDataUpdatedAt), 'invalid info.realtimeDataUpdatedAt') - t.ok(info.realtimeDataUpdatedAt > 0, 'invalid info.realtimeDataUpdatedAt') -} + t.ok(Number.isInteger(info.realtimeDataUpdatedAt), 'invalid info.realtimeDataUpdatedAt'); + t.ok(info.realtimeDataUpdatedAt > 0, 'invalid info.realtimeDataUpdatedAt'); +}; export { testServerInfo, -} +}; diff --git a/test/e2e/lib/util.js b/test/e2e/lib/util.js index 6dd19dc6b..860a8e6b6 100644 --- a/test/e2e/lib/util.js +++ b/test/e2e/lib/util.js @@ -1,33 +1,33 @@ -import isRoughlyEqual from 'is-roughly-equal' -import {ok, AssertionError} from 'assert' -import {DateTime} from 'luxon' -import * as a from 'assert' -import {createRequire} from 'module' -import {gunzipSync} from 'zlib' +import isRoughlyEqual from 'is-roughly-equal'; +import {ok, AssertionError} from 'assert'; +import {DateTime} from 'luxon'; +import * as a from 'assert'; +import {createRequire} from 'module'; +import {gunzipSync} from 'zlib'; -const hour = 60 * 60 * 1000 -const day = 24 * hour -const week = 7 * day +const hour = 60 * 60 * 1000; +const day = 24 * hour; +const week = 7 * day; // next Monday 10 am const createWhen = (timezone, locale, tMock) => { - ok(Number.isInteger(tMock), 'tMock must be an integer') + ok(Number.isInteger(tMock), 'tMock must be an integer'); const t = process.env.VCR_MODE && !process.env.VCR_OFF ? tMock - : Date.now() + : Date.now(); return DateTime.fromMillis(t, { zone: timezone, locale, }) .startOf('week') .plus({weeks: 1, hours: 10}) - .toJSDate() -} + .toJSDate(); +}; const assertValidWhen = (actual, expected, name, delta = day + 6 * hour) => { - const ts = Number(new Date(actual)) - a.ok(!Number.isNaN(ts), name + ' is not parsable by Date') + const ts = Number(new Date(actual)); + a.ok(!Number.isNaN(ts), name + ' is not parsable by Date'); // the timestamps might be from long-distance trains if (!isRoughlyEqual(delta, Number(expected), ts)) { throw new AssertionError({ @@ -35,46 +35,46 @@ const assertValidWhen = (actual, expected, name, delta = day + 6 * hour) => { actual: ts, expected: `${expected - delta} - ${Number(expected) + delta}`, operator: 'isRoughlyEqual', - }) + }); } -} +}; // HTTP request mocking if (process.env.VCR_MODE && !process.env.VCR_OFF) { - const require = createRequire(import.meta.url) + const require = createRequire(import.meta.url); - const {Polly} = require('@pollyjs/core') - const NodeHttpAdapter = require('@pollyjs/adapter-node-http') - const FSPersister = require('@pollyjs/persister-fs') - const tap = require('tap') + const {Polly} = require('@pollyjs/core'); + const NodeHttpAdapter = require('@pollyjs/adapter-node-http'); + const FSPersister = require('@pollyjs/persister-fs'); + const tap = require('tap'); // monkey-patch NodeHttpAdapter to handle gzipped responses properly // todo: submit a PR // related: https://github.com/Netflix/pollyjs/issues/256 // related: https://github.com/Netflix/pollyjs/issues/463 // related: https://github.com/Netflix/pollyjs/issues/207 - const _getBodyFromChunks = NodeHttpAdapter.prototype.getBodyFromChunks + const _getBodyFromChunks = NodeHttpAdapter.prototype.getBodyFromChunks; NodeHttpAdapter.prototype.getBodyFromChunks = function getBodyFromChunksWithGunzip (chunks, headers) { if (headers['content-encoding'] === 'gzip') { - const concatenated = Buffer.concat(chunks) - chunks = [gunzipSync(concatenated)] + const concatenated = Buffer.concat(chunks); + chunks = [gunzipSync(concatenated)]; // todo: this is ugly, find a better way - delete headers['content-encoding'] - headers['content-length'] = chunks[0].length + delete headers['content-encoding']; + headers['content-length'] = chunks[0].length; } - return _getBodyFromChunks.call(this, chunks, headers) - } + return _getBodyFromChunks.call(this, chunks, headers); + }; - Polly.register(NodeHttpAdapter) - Polly.register(FSPersister) + Polly.register(NodeHttpAdapter); + Polly.register(FSPersister); - let mode + let mode; if (process.env.VCR_MODE === 'record') { - mode = 'record' + mode = 'record'; } else if (process.env.VCR_MODE === 'playback') { - mode = 'replay' + mode = 'replay'; } else { - throw new Error('invalid $VCR_MODE, must be "record" or "replay"') + throw new Error('invalid $VCR_MODE, must be "record" or "replay"'); } const polly = new Polly('requests', { @@ -113,13 +113,13 @@ if (process.env.VCR_MODE && !process.env.VCR_OFF) { ], }, }, - }) + }); tap.teardown(async () => { - await polly.stop() - }) + await polly.stop(); + }); } export { hour, createWhen, assertValidWhen, -} +}; diff --git a/test/e2e/lib/validate-fptf-with.js b/test/e2e/lib/validate-fptf-with.js index e9e3f9ebe..81649dd1d 100644 --- a/test/e2e/lib/validate-fptf-with.js +++ b/test/e2e/lib/validate-fptf-with.js @@ -1,27 +1,27 @@ -import validateFptf from 'validate-fptf' -const {defaultValidators} = validateFptf -import anyOf from 'validate-fptf/lib/any-of.js' +import validateFptf from 'validate-fptf'; +const {defaultValidators} = validateFptf; +import anyOf from 'validate-fptf/lib/any-of.js'; -import validators from './validators.js' +import validators from './validators.js'; const createValidateFptfWith = (cfg, customValidators = {}) => { - const val = Object.assign({}, defaultValidators) + const val = Object.assign({}, defaultValidators); for (let key of Object.keys(validators)) { - val[key] = validators[key](cfg) + val[key] = validators[key](cfg); } - Object.assign(val, customValidators) + Object.assign(val, customValidators); const validateFptfWith = (t, item, allowedTypes, name) => { if ('string' === typeof allowedTypes) { - val[allowedTypes](val, item, name) + val[allowedTypes](val, item, name); } else { - anyOf(allowedTypes, val, item, name) + anyOf(allowedTypes, val, item, name); } - t.pass(name + ' is valid') - } - return validateFptfWith -} + t.pass(name + ' is valid'); + }; + return validateFptfWith; +}; export { createValidateFptfWith, -} +}; diff --git a/test/e2e/lib/validators.js b/test/e2e/lib/validators.js index 1f161a8d8..0cf07b761 100644 --- a/test/e2e/lib/validators.js +++ b/test/e2e/lib/validators.js @@ -1,178 +1,178 @@ -import * as a from 'assert' -import validateFptf from 'validate-fptf' -const {defaultValidators} = validateFptf -import anyOf from 'validate-fptf/lib/any-of.js' +import * as a from 'assert'; +import validateFptf from 'validate-fptf'; +const {defaultValidators} = validateFptf; +import anyOf from 'validate-fptf/lib/any-of.js'; -import {assertValidWhen} from './util.js' +import {assertValidWhen} from './util.js'; -const DAY = 24 * 60 * 60 * 1000 +const DAY = 24 * 60 * 60 * 1000; -const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o) -const is = val => val !== null && val !== undefined +const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o); +const is = val => val !== null && val !== undefined; const createValidateRealtimeDataUpdatedAt = (cfg) => { const validateRealtimeDataUpdatedAt = (val, rtDataUpdatedAt, name = 'realtimeDataUpdatedAt') => { - a.ok(Number.isInteger(rtDataUpdatedAt), name + ' must be an integer') - assertValidWhen(rtDataUpdatedAt * 1000, cfg.when, name, 100 * DAY) - } - return validateRealtimeDataUpdatedAt -} + a.ok(Number.isInteger(rtDataUpdatedAt), name + ' must be an integer'); + assertValidWhen(rtDataUpdatedAt * 1000, cfg.when, name, 100 * DAY); + }; + return validateRealtimeDataUpdatedAt; +}; const createValidateProducts = (cfg) => { const validateProducts = (val, p, name = 'products') => { - a.ok(isObj(p), name + ' must be an object') + a.ok(isObj(p), name + ' must be an object'); for (let product of cfg.products) { - const msg = `${name}[${product.id}] must be a boolean` - a.strictEqual(typeof p[product.id], 'boolean', msg) + const msg = `${name}[${product.id}] must be a boolean`; + a.strictEqual(typeof p[product.id], 'boolean', msg); } - } - return validateProducts -} + }; + return validateProducts; +}; const createValidateStation = (cfg) => { const validateStation = (val, s, name = 'station') => { - defaultValidators.station(val, s, name) + defaultValidators.station(val, s, name); if (!cfg.stationCoordsOptional) { - a.ok(is(s.location), `missing ${name}.location`) + a.ok(is(s.location), `missing ${name}.location`); } - val.products(val, s.products, name + '.products') + val.products(val, s.products, name + '.products'); if ('lines' in s) { - a.ok(Array.isArray(s.lines), name + '.lines must be an array') + a.ok(Array.isArray(s.lines), name + '.lines must be an array'); for (let i = 0; i < s.lines.length; i++) { - val.line(val, s.lines[i], name + `.lines[${i}]`) + val.line(val, s.lines[i], name + `.lines[${i}]`); } } - } - return validateStation -} + }; + return validateStation; +}; const validateStop = (val, s, name = 'stop') => { // HAFAS doesn't always return the station of a stop. We mock it here // to silence `validate-fptf`. - const station = Object.assign({}, s) - station.type = 'station' - s = Object.assign({station}, s) - defaultValidators.stop(val, s, name) + const station = Object.assign({}, s); + station.type = 'station'; + s = Object.assign({station}, s); + defaultValidators.stop(val, s, name); // todo: check if s.id has leading zeros -} -const createValidateStop = () => validateStop +}; +const createValidateStop = () => validateStop; const validatePoi = (val, poi, name = 'location') => { - defaultValidators.location(val, poi, name) - val.ref(val, poi.id, name + '.id') + defaultValidators.location(val, poi, name); + val.ref(val, poi.id, name + '.id'); // todo: check if s.id has leading zeros - a.strictEqual(poi.poi, true, name + '.poi must be true') - a.strictEqual(typeof poi.name, 'string', name + '.name must be a string') - a.ok(poi.name, name + '.name must not be empty') -} -const createValidatePoi = () => validatePoi + a.strictEqual(poi.poi, true, name + '.poi must be true'); + a.strictEqual(typeof poi.name, 'string', name + '.name must be a string'); + a.ok(poi.name, name + '.name must not be empty'); +}; +const createValidatePoi = () => validatePoi; const validateAddress = (val, addr, name = 'location') => { - defaultValidators.location(val, addr, name) - a.strictEqual(typeof addr.address, 'string', name + '.address must be a string') - a.ok(addr.address, name + '.address must not be empty') -} -const createValidateAddress = () => validateAddress + defaultValidators.location(val, addr, name); + a.strictEqual(typeof addr.address, 'string', name + '.address must be a string'); + a.ok(addr.address, name + '.address must not be empty'); +}; +const createValidateAddress = () => validateAddress; const validateLocation = (val, loc, name = 'location') => { - a.ok(isObj(loc), name + ' must be an object') + a.ok(isObj(loc), name + ' must be an object'); if (loc.type === 'stop') { - val.stop(val, loc, name) + val.stop(val, loc, name); } else if (loc.type === 'station') { - val.station(val, loc, name) + val.station(val, loc, name); } else if (loc.poi) { - validatePoi(val, loc, name) + validatePoi(val, loc, name); } else if (!('name' in loc) && 'address' in loc) { - validateAddress(val, loc, name) + validateAddress(val, loc, name); } else { - defaultValidators.location(val, loc, name) + defaultValidators.location(val, loc, name); } -} -const createValidateLocation = () => validateLocation +}; +const createValidateLocation = () => validateLocation; const validateLocations = (val, locs, name = 'locations') => { - a.ok(Array.isArray(locs), name + ' must be an array') - a.ok(locs.length > 0, name + ' must not be empty') + a.ok(Array.isArray(locs), name + ' must be an array'); + a.ok(locs.length > 0, name + ' must not be empty'); for (let i = 0; i < locs.length; i++) { - val.location(val, locs[i], name + `[${i}]`) + val.location(val, locs[i], name + `[${i}]`); } -} -const createValidateLocations = () => validateLocations +}; +const createValidateLocations = () => validateLocations; const createValidateLine = (cfg) => { - const validLineModes = [] + const validLineModes = []; for (let product of cfg.products) { if (!validLineModes.includes(product.mode)) { - validLineModes.push(product.mode) + validLineModes.push(product.mode); } } const validateLine = (val, line, name = 'line') => { - defaultValidators.line(val, line, name) + defaultValidators.line(val, line, name); - const msg = name + '.fahrtNr must be ' + const msg = name + '.fahrtNr must be '; if (line.fahrtNr !== null) { - a.strictEqual(typeof line.fahrtNr, 'string', msg + 'a string') - a.ok(line.fahrtNr, msg + ' be empty') + a.strictEqual(typeof line.fahrtNr, 'string', msg + 'a string'); + a.ok(line.fahrtNr, msg + ' be empty'); } - a.ok(validLineModes.includes(line.mode), name + '.mode is invalid') - } - return validateLine -} + a.ok(validLineModes.includes(line.mode), name + '.mode is invalid'); + }; + return validateLine; +}; const validateRemark = (val, rem, name = 'remark') => { - a.ok(isObj(rem), name + ' must be an object') - a.strictEqual(typeof rem.id, 'string', name + '.id must be a string') - a.ok(rem.id, name + '.id must not be empty') + a.ok(isObj(rem), name + ' must be an object'); + a.strictEqual(typeof rem.id, 'string', name + '.id must be a string'); + a.ok(rem.id, name + '.id must not be empty'); if (rem.summary !== null) { - a.strictEqual(typeof rem.summary, 'string', name + '.summary must be a string') - a.ok(rem.summary, name + '.summary must not be empty') + a.strictEqual(typeof rem.summary, 'string', name + '.summary must be a string'); + a.ok(rem.summary, name + '.summary must not be empty'); } if (rem.text !== null) { - a.strictEqual(typeof rem.text, 'string', name + '.text must be a string') - a.ok(rem.text, name + '.text must not be empty') + a.strictEqual(typeof rem.text, 'string', name + '.text must be a string'); + a.ok(rem.text, name + '.text must not be empty'); } if ('validFrom' in rem) { - a.strictEqual(typeof rem.validFrom, 'string', name + '.validFrom must be a string') - a.ok(Number.isInteger(Date.parse(rem.validFrom)), name + '.validFrom must be ISO 8601') + a.strictEqual(typeof rem.validFrom, 'string', name + '.validFrom must be a string'); + a.ok(Number.isInteger(Date.parse(rem.validFrom)), name + '.validFrom must be ISO 8601'); } if ('validUntil' in rem) { - a.strictEqual(typeof rem.validUntil, 'string', name + '.validUntil must be a string') - a.ok(Number.isInteger(Date.parse(rem.validUntil)), name + '.validUntil must be ISO 8601') + a.strictEqual(typeof rem.validUntil, 'string', name + '.validUntil must be a string'); + a.ok(Number.isInteger(Date.parse(rem.validUntil)), name + '.validUntil must be ISO 8601'); } if ('modified' in rem) { - a.strictEqual(typeof rem.modified, 'string', name + '.modified must be a string') - a.ok(Number.isInteger(Date.parse(rem.modified)), name + '.modified must be ISO 8601') + a.strictEqual(typeof rem.modified, 'string', name + '.modified must be a string'); + a.ok(Number.isInteger(Date.parse(rem.modified)), name + '.modified must be ISO 8601'); } if ('products' in rem) { - val.products(val, rem.products, name + '.products') + val.products(val, rem.products, name + '.products'); } if ('edges' in rem) { - a.ok(Array.isArray(rem.edges), name + '.edges must be an array') + a.ok(Array.isArray(rem.edges), name + '.edges must be an array'); for (let i = 0; i < rem.edges.length; i++) { - const e = rem.edges[i] - const n = `${name}.edges[${i}]` - a.ok(isObj(e), n + ' must be an object') + const e = rem.edges[i]; + const n = `${name}.edges[${i}]`; + a.ok(isObj(e), n + ' must be an object'); if (e.fromLocation !== null) { - val.location(val, e.fromLocation, n + '.fromLocation') + val.location(val, e.fromLocation, n + '.fromLocation'); } if (e.toLocation !== null) { - val.location(val, e.toLocation, n + '.toLocation') + val.location(val, e.toLocation, n + '.toLocation'); } } } if ('affectedLines' in rem) { - a.ok(Array.isArray(rem.affectedLines), name + '.affectedLines must be an array') + a.ok(Array.isArray(rem.affectedLines), name + '.affectedLines must be an array'); for (let i = 0; i < rem.affectedLines.length; i++) { - val.line(val, rem.affectedLines[i], `${name}.affectedLines[${i}]`) + val.line(val, rem.affectedLines[i], `${name}.affectedLines[${i}]`); } } -} -const createValidateRemark = () => validateRemark +}; +const createValidateRemark = () => validateRemark; const createValidateStopover = (cfg) => { const validateStopover = (val, s, name = 'stopover') => { @@ -180,488 +180,488 @@ const createValidateStopover = (cfg) => { !is(s.arrival) && !is(s.departure) && !is(s.plannedArrival) && !is(s.plannedDeparture) ) { - a.fail(name + ' contains neither (planned)arrival nor (planned)departure') + a.fail(name + ' contains neither (planned)arrival nor (planned)departure'); } if (is(s.arrival)) { - val.date(val, s.arrival, name + '.arrival') - assertValidWhen(s.arrival, cfg.when, name + '.arrival') + val.date(val, s.arrival, name + '.arrival'); + assertValidWhen(s.arrival, cfg.when, name + '.arrival'); } if (is(s.departure)) { - val.date(val, s.departure, name + '.departure') - assertValidWhen(s.departure, cfg.when, name + '.departure') + val.date(val, s.departure, name + '.departure'); + assertValidWhen(s.departure, cfg.when, name + '.departure'); } if (is(s.plannedArrival)) { - val.date(val, s.plannedArrival, name + '.plannedArrival') - assertValidWhen(s.plannedArrival, cfg.when, name + '.plannedArrival') + val.date(val, s.plannedArrival, name + '.plannedArrival'); + assertValidWhen(s.plannedArrival, cfg.when, name + '.plannedArrival'); } if (is(s.departurePrognosisType)) { - const msg = name + '.departurePrognosisType must ' - a.strictEqual(typeof s.departurePrognosisType, 'string', msg + 'be a string') - a.ok(s.departurePrognosisType, msg + 'not be empty') + const msg = name + '.departurePrognosisType must '; + a.strictEqual(typeof s.departurePrognosisType, 'string', msg + 'be a string'); + a.ok(s.departurePrognosisType, msg + 'not be empty'); } if (is(s.plannedDeparture)) { - val.date(val, s.plannedDeparture, name + '.plannedDeparture') - assertValidWhen(s.plannedDeparture, cfg.when, name + '.plannedDeparture') + val.date(val, s.plannedDeparture, name + '.plannedDeparture'); + assertValidWhen(s.plannedDeparture, cfg.when, name + '.plannedDeparture'); } if (is(s.plannedArrival) && !is(s.arrival) && !s.cancelled) { - a.fail(name + ' has .plannedArrival but not .arrival') + a.fail(name + ' has .plannedArrival but not .arrival'); } if (is(s.plannedDeparture) && !is(s.departure) && !s.cancelled) { - a.fail(name + ' has .plannedDeparture but not .departure') + a.fail(name + ' has .plannedDeparture but not .departure'); } if (is(s.arrivalDelay)) { - const msg = name + '.arrivalDelay must be a number' - a.strictEqual(typeof s.arrivalDelay, 'number', msg) - const d = new Date(s.arrival) - new Date(s.plannedArrival) - a.strictEqual(Math.round(d / 1000), s.arrivalDelay) + const msg = name + '.arrivalDelay must be a number'; + a.strictEqual(typeof s.arrivalDelay, 'number', msg); + const d = new Date(s.arrival) - new Date(s.plannedArrival); + a.strictEqual(Math.round(d / 1000), s.arrivalDelay); } if (is(s.departureDelay)) { - const msg = name + '.departureDelay must be a number' - a.strictEqual(typeof s.departureDelay, 'number', msg) - const d = new Date(s.departure) - new Date(s.plannedDeparture) - a.strictEqual(Math.round(d / 1000), s.departureDelay) + const msg = name + '.departureDelay must be a number'; + a.strictEqual(typeof s.departureDelay, 'number', msg); + const d = new Date(s.departure) - new Date(s.plannedDeparture); + a.strictEqual(Math.round(d / 1000), s.departureDelay); } if (is(s.arrivalPlatform)) { - const msg = name + '.arrivalPlatform must ' - a.strictEqual(typeof s.arrivalPlatform, 'string', msg + 'be a string') - a.ok(s.arrivalPlatform, msg + 'not be empty') + const msg = name + '.arrivalPlatform must '; + a.strictEqual(typeof s.arrivalPlatform, 'string', msg + 'be a string'); + a.ok(s.arrivalPlatform, msg + 'not be empty'); } if (is(s.plannedArrivalPlatform)) { - const msg = name + '.plannedArrivalPlatform must ' - a.strictEqual(typeof s.plannedArrivalPlatform, 'string', msg + 'be a string') - a.ok(s.plannedArrivalPlatform, msg + 'not be empty') + const msg = name + '.plannedArrivalPlatform must '; + a.strictEqual(typeof s.plannedArrivalPlatform, 'string', msg + 'be a string'); + a.ok(s.plannedArrivalPlatform, msg + 'not be empty'); } if (is(s.arrivalPrognosisType)) { - const msg = name + '.arrivalPrognosisType must ' - a.strictEqual(typeof s.arrivalPrognosisType, 'string', msg + 'be a string') - a.ok(s.arrivalPrognosisType, msg + 'not be empty') + const msg = name + '.arrivalPrognosisType must '; + a.strictEqual(typeof s.arrivalPrognosisType, 'string', msg + 'be a string'); + a.ok(s.arrivalPrognosisType, msg + 'not be empty'); } if (is(s.departurePlatform)) { - const msg = name + '.departurePlatform must ' - a.strictEqual(typeof s.departurePlatform, 'string', msg + 'be a string') - a.ok(s.departurePlatform, msg + 'not be empty') + const msg = name + '.departurePlatform must '; + a.strictEqual(typeof s.departurePlatform, 'string', msg + 'be a string'); + a.ok(s.departurePlatform, msg + 'not be empty'); } if (is(s.plannedDeparturePlatform)) { - const msg = name + '.plannedDeparturePlatform must ' - a.strictEqual(typeof s.plannedDeparturePlatform, 'string', msg + 'be a string') - a.ok(s.plannedDeparturePlatform, msg + 'not be empty') + const msg = name + '.plannedDeparturePlatform must '; + a.strictEqual(typeof s.plannedDeparturePlatform, 'string', msg + 'be a string'); + a.ok(s.plannedDeparturePlatform, msg + 'not be empty'); } if (is(s.plannedArrivalPlatform) && !is(s.arrivalPlatform)) { - a.fail(name + ' has .plannedArrivalPlatform but not .arrivalPlatform') + a.fail(name + ' has .plannedArrivalPlatform but not .arrivalPlatform'); } if (is(s.plannedDeparturePlatform) && !is(s.departurePlatform)) { - a.fail(name + ' has .plannedDeparturePlatform but not .departurePlatform') + a.fail(name + ' has .plannedDeparturePlatform but not .departurePlatform'); } - anyOf(['stop', 'station'], val, s.stop, name + '.stop') - } - return validateStopover -} + anyOf(['stop', 'station'], val, s.stop, name + '.stop'); + }; + return validateStopover; +}; const validateTicket = (val, ti, name = 'ticket') => { - a.strictEqual(typeof ti.name, 'string', name + '.name must be a string') - a.ok(ti.name, name + '.name must not be empty') + a.strictEqual(typeof ti.name, 'string', name + '.name must be a string'); + a.ok(ti.name, name + '.name must not be empty'); if (is(ti.price)) { - a.strictEqual(typeof ti.price, 'number', name + '.price must be a number') - a.ok(ti.price > 0, name + '.price must be >0') + a.strictEqual(typeof ti.price, 'number', name + '.price must be a number'); + a.ok(ti.price > 0, name + '.price must be >0'); } if (is(ti.amount)) { - a.strictEqual(typeof ti.amount, 'number', name + '.amount must be a number') - a.ok(ti.amount > 0, name + '.amount must be >0') + a.strictEqual(typeof ti.amount, 'number', name + '.amount must be a number'); + a.ok(ti.amount > 0, name + '.amount must be >0'); } // todo: move to VBB tests if ('bike' in ti) { - a.strictEqual(typeof ti.bike, 'boolean', name + '.bike must be a boolean') + a.strictEqual(typeof ti.bike, 'boolean', name + '.bike must be a boolean'); } if ('shortTrip' in ti) { - a.strictEqual(typeof ti.shortTrip, 'boolean', name + '.shortTrip must be a boolean') + a.strictEqual(typeof ti.shortTrip, 'boolean', name + '.shortTrip must be a boolean'); } if ('group' in ti) { - a.strictEqual(typeof ti.group, 'boolean', name + '.group must be a boolean') + a.strictEqual(typeof ti.group, 'boolean', name + '.group must be a boolean'); } if ('fullDay' in ti) { - a.strictEqual(typeof ti.fullDay, 'boolean', name + '.fullDay must be a boolean') + a.strictEqual(typeof ti.fullDay, 'boolean', name + '.fullDay must be a boolean'); } if ('tariff' in ti) { - a.strictEqual(typeof ti.tariff, 'string', name + '.tariff must be a string') - a.ok(ti.tariff, name + '.tariff must not be empty') + a.strictEqual(typeof ti.tariff, 'string', name + '.tariff must be a string'); + a.ok(ti.tariff, name + '.tariff must not be empty'); } if ('coverage' in ti) { - a.strictEqual(typeof ti.coverage, 'string', name + '.coverage must be a string') - a.ok(ti.coverage, name + '.coverage must not be empty') + a.strictEqual(typeof ti.coverage, 'string', name + '.coverage must be a string'); + a.ok(ti.coverage, name + '.coverage must not be empty'); } if ('variant' in ti) { - a.strictEqual(typeof ti.variant, 'string', name + '.variant must be a string') - a.ok(ti.variant, name + '.variant must not be empty') + a.strictEqual(typeof ti.variant, 'string', name + '.variant must be a string'); + a.ok(ti.variant, name + '.variant must not be empty'); } -} -const createValidateTicket = () => validateTicket +}; +const createValidateTicket = () => validateTicket; const createValidateJourneyLeg = (cfg) => { const validateJourneyLeg = (val, leg, name = 'journeyLeg') => { const fakeLeg = Object.assign({ schedule: 'foo', // todo: let hafas-client parse a schedule ID operator: 'bar', // todo: let hafas-client parse the operator - }, leg) + }, leg); if (leg.cancelled) { // FPTF doesn't support cancelled journey legs yet. // see https://github.com/public-transport/friendly-public-transport-format/issues/27 // todo: remove once this is resolved upstream - fakeLeg.departure = leg.plannedDeparture - fakeLeg.arrival = leg.plannedArrival + fakeLeg.departure = leg.plannedDeparture; + fakeLeg.arrival = leg.plannedArrival; } - defaultValidators.journeyLeg(val, fakeLeg, name) + defaultValidators.journeyLeg(val, fakeLeg, name); if (leg.arrival !== null) { - assertValidWhen(leg.arrival, cfg.when, name + '.arrival') + assertValidWhen(leg.arrival, cfg.when, name + '.arrival'); } if (leg.departure !== null) { - assertValidWhen(leg.departure, cfg.when, name + '.departure') + assertValidWhen(leg.departure, cfg.when, name + '.departure'); } // todo: leg.arrivalPlatform !== null if (is(leg.arrivalPlatform)) { - const msg = name + '.arrivalPlatform must be a string' - a.strictEqual(typeof leg.arrivalPlatform, 'string', msg) - a.ok(leg.arrivalPlatform, name + '.arrivalPlatform must not be empty') + const msg = name + '.arrivalPlatform must be a string'; + a.strictEqual(typeof leg.arrivalPlatform, 'string', msg); + a.ok(leg.arrivalPlatform, name + '.arrivalPlatform must not be empty'); } // todo: leg.departurePlatform !== null if (is(leg.departurePlatform)) { - const msg = name + '.departurePlatform must be a string' - a.strictEqual(typeof leg.departurePlatform, 'string', msg) - a.ok(leg.departurePlatform, name + '.departurePlatform must not be empty') + const msg = name + '.departurePlatform must be a string'; + a.strictEqual(typeof leg.departurePlatform, 'string', msg); + a.ok(leg.departurePlatform, name + '.departurePlatform must not be empty'); } if ('stopovers' in leg) { - a.ok(Array.isArray(leg.stopovers), name + '.stopovers must be an array') - a.ok(leg.stopovers.length > 0, name + '.stopovers must not be empty') + a.ok(Array.isArray(leg.stopovers), name + '.stopovers must be an array'); + a.ok(leg.stopovers.length > 0, name + '.stopovers must not be empty'); for (let i = 0; i < leg.stopovers.length; i++) { - val.stopover(val, leg.stopovers[i], name + `.stopovers[${i}]`) + val.stopover(val, leg.stopovers[i], name + `.stopovers[${i}]`); } } // todo: leg.public if ('walking' in leg) { - a.strictEqual(typeof leg.walking, 'boolean', name + '.walking must be a boolean') + a.strictEqual(typeof leg.walking, 'boolean', name + '.walking must be a boolean'); } if (leg.walking) { if (leg.distance !== null) { - const msg = name + '.distance must be ' - a.strictEqual(typeof leg.distance, 'number', msg + 'a number') - a.ok(leg.distance > 0, msg + '> 0') + const msg = name + '.distance must be '; + a.strictEqual(typeof leg.distance, 'number', msg + 'a number'); + a.ok(leg.distance > 0, msg + '> 0'); } } else { - a.strictEqual(typeof leg.tripId, 'string', name + '.tripId must be a string') - a.ok(leg.tripId, name + '.tripId must not be empty') + a.strictEqual(typeof leg.tripId, 'string', name + '.tripId must be a string'); + a.ok(leg.tripId, name + '.tripId must not be empty'); if (!leg.cancelled) { - const msg = name + '.direction must be a string' - a.strictEqual(typeof leg.direction, 'string', msg) - a.ok(leg.direction, name + '.direction must not be empty') + const msg = name + '.direction must be a string'; + a.strictEqual(typeof leg.direction, 'string', msg); + a.ok(leg.direction, name + '.direction must not be empty'); } } if ('cycle' in leg) { - a.ok(isObj(leg.cycle), name + '.cycle must be an object') + a.ok(isObj(leg.cycle), name + '.cycle must be an object'); if ('min' in leg.cycle && leg.cycle.min !== null) { - a.strictEqual(typeof leg.cycle.min, 'number', name + '.cycle.min must be a number') - a.ok(leg.cycle.min > 0, name + '.cycle.min must be >0') + a.strictEqual(typeof leg.cycle.min, 'number', name + '.cycle.min must be a number'); + a.ok(leg.cycle.min > 0, name + '.cycle.min must be >0'); } if ('max' in leg.cycle && leg.cycle.max !== null) { - a.strictEqual(typeof leg.cycle.max, 'number', name + '.cycle.max must be a number') - a.ok(leg.cycle.max > 0, name + '.cycle.max must be >0') + a.strictEqual(typeof leg.cycle.max, 'number', name + '.cycle.max must be a number'); + a.ok(leg.cycle.max > 0, name + '.cycle.max must be >0'); } if ('nr' in leg.cycle && leg.cycle.nr !== null) { - a.strictEqual(typeof leg.cycle.nr, 'number', name + '.cycle.nr must be a number') - a.ok(leg.cycle.nr > 0, name + '.cycle.nr must be >0') + a.strictEqual(typeof leg.cycle.nr, 'number', name + '.cycle.nr must be a number'); + a.ok(leg.cycle.nr > 0, name + '.cycle.nr must be >0'); } } if ('alternatives' in leg) { - const as = leg.alternatives - a.ok(Array.isArray(as), name + '.alternatives must be an array') + const as = leg.alternatives; + a.ok(Array.isArray(as), name + '.alternatives must be an array'); for (let i = 0; i < as.length; i++) { - const alt = leg.alternatives[i] - const n = name + `.alternatives[${i}]` + const alt = leg.alternatives[i]; + const n = name + `.alternatives[${i}]`; - a.ok(isObj(alt), n + ' must be an object') + a.ok(isObj(alt), n + ' must be an object'); // todo: when, delay - val.line(val, alt.line, n + '.line') + val.line(val, alt.line, n + '.line'); if (alt.direction !== null) { - a.strictEqual(typeof alt.direction, 'string', n + '.direction must be a string') - a.ok(alt.direction, n + '.direction must not be empty') + a.strictEqual(typeof alt.direction, 'string', n + '.direction must be a string'); + a.ok(alt.direction, n + '.direction must not be empty'); } if (alt.when !== null) { - assertValidWhen(alt.when, cfg.when, n + '.when') + assertValidWhen(alt.when, cfg.when, n + '.when'); } if (alt.delay !== null) { - a.strictEqual(typeof alt.delay, 'number', n + '.delay must be a number') + a.strictEqual(typeof alt.delay, 'number', n + '.delay must be a number'); } } } // todo: validate polyline - } - return validateJourneyLeg -} + }; + return validateJourneyLeg; +}; const validateJourney = (val, j, name = 'journey') => { const withFakeId = Object.assign({ id: 'foo', // todo: let hafas-client parse a journey ID - }, j) - defaultValidators.journey(val, withFakeId, name) + }, j); + defaultValidators.journey(val, withFakeId, name); // todo: j.refreshToken if ('tickets' in j) { - a.ok(Array.isArray(j.tickets), name + '.tickets must be an array') - a.ok(j.tickets.length > 0, name + '.tickets must not be empty') + a.ok(Array.isArray(j.tickets), name + '.tickets must be an array'); + a.ok(j.tickets.length > 0, name + '.tickets must not be empty'); for (let i = 0; i < j.tickets.length; i++) { - val.ticket(val, j.tickets[i], name + `.tickets[${i}]`) + val.ticket(val, j.tickets[i], name + `.tickets[${i}]`); } } -} -const createValidateJourney = () => validateJourney +}; +const createValidateJourney = () => validateJourney; const validateJourneys = (val, js, name = 'journeys') => { - a.ok(Array.isArray(js), name + ' must be an array') - a.ok(js.length > 0, name + ' must not be empty') + a.ok(Array.isArray(js), name + ' must be an array'); + a.ok(js.length > 0, name + ' must not be empty'); for (let i = 0; i < js.length; i++) { - val.journey(val, js[i], name + `[${i}]`) + val.journey(val, js[i], name + `[${i}]`); } -} -const createValidateJourneys = () => validateJourneys +}; +const createValidateJourneys = () => validateJourneys; const validateJourneysResult = (val, res, name = 'journeysResult') => { - a.ok(isObj(res), name + ' must be an object') + a.ok(isObj(res), name + ' must be an object'); // todo: `earlierRef`, `laterRef` - val.journeys(val, res.journeys, name + '.journeys') + val.journeys(val, res.journeys, name + '.journeys'); - val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt') -} -const createValidateJourneysResult = () => validateJourneysResult + val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt'); +}; +const createValidateJourneysResult = () => validateJourneysResult; const validateRefreshJourneyResult = (val, res, name = 'refreshJourneyResult') => { - a.ok(isObj(res), name + ' must be an object') + a.ok(isObj(res), name + ' must be an object'); - val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt') + val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt'); - val.journey(val, res.journey, name + '.journey') -} -const createValidateRefreshJourneyResult = () => validateRefreshJourneyResult + val.journey(val, res.journey, name + '.journey'); +}; +const createValidateRefreshJourneyResult = () => validateRefreshJourneyResult; const validateTrip = (val, trip, name = 'trip') => { const withFakeTripId = Object.assign({ tripId: trip.id, - }, trip) - delete withFakeTripId.id - val.journeyLeg(val, withFakeTripId, name) -} -const createValidateTrip = () => validateTrip + }, trip); + delete withFakeTripId.id; + val.journeyLeg(val, withFakeTripId, name); +}; +const createValidateTrip = () => validateTrip; const validateTripResult = (val, res, name = 'tripResult') => { - a.ok(isObj(res), name + ' must be an object') + a.ok(isObj(res), name + ' must be an object'); - val.trip(val, res.trip, name + '.trip') + val.trip(val, res.trip, name + '.trip'); - val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt') -} -const createValidateTripResult = () => validateTripResult + val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt'); +}; +const createValidateTripResult = () => validateTripResult; const validateTripsByNameResult = (val, res, name = 'tripsByNameResult') => { - a.ok(isObj(res), name + ' must be an object') + a.ok(isObj(res), name + ' must be an object'); - a.ok(Array.isArray(res.trips), name + '.trips must be an array') - a.ok(res.trips.length > 0, name + '.trips must not be empty') + a.ok(Array.isArray(res.trips), name + '.trips must be an array'); + a.ok(res.trips.length > 0, name + '.trips must not be empty'); for (let i = 0; i < res.trips.length; i++) { - val.trip(val, res.trips[i], `${name}.trips[${i}]`) + val.trip(val, res.trips[i], `${name}.trips[${i}]`); } - val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt') -} -const createValidateTripsByNameResult = () => validateTripsByNameResult + val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt'); +}; +const createValidateTripsByNameResult = () => validateTripsByNameResult; const createValidateArrivalOrDeparture = (type, cfg) => { if (type !== 'arrival' && type !== 'departure') { - throw new Error('invalid type') + throw new Error('invalid type'); } const validateArrivalOrDeparture = (val, dep, name = 'arrOrDep') => { - a.ok(isObj(dep), name + ' must be an object') + a.ok(isObj(dep), name + ' must be an object'); // todo: let hafas-client add a .type field - a.strictEqual(typeof dep.tripId, 'string', name + '.tripId must be a string') - a.ok(dep.tripId, name + '.tripId must not be empty') + a.strictEqual(typeof dep.tripId, 'string', name + '.tripId must be a string'); + a.ok(dep.tripId, name + '.tripId must not be empty'); - anyOf(['stop', 'station'], val, dep.stop, name + '.stop') + anyOf(['stop', 'station'], val, dep.stop, name + '.stop'); - assertValidWhen(dep.when, cfg.when, name + '.when') + assertValidWhen(dep.when, cfg.when, name + '.when'); if (dep.delay !== null) { - const msg = name + '.delay must be a number' - a.strictEqual(typeof dep.delay, 'number', msg) + const msg = name + '.delay must be a number'; + a.strictEqual(typeof dep.delay, 'number', msg); } if (dep.platform !== null) { - const msg = name + '.platform must ' - a.strictEqual(typeof dep.platform, 'string', msg + 'be a string') - a.ok(dep.platform, name + 'not be empty') + const msg = name + '.platform must '; + a.strictEqual(typeof dep.platform, 'string', msg + 'be a string'); + a.ok(dep.platform, name + 'not be empty'); } - val.line(val, dep.line, name + '.line') + val.line(val, dep.line, name + '.line'); if (type === 'departure') { - const n = name + '.direction' - a.strictEqual(typeof dep.direction, 'string', n + ' must be a string') - a.ok(dep.direction, n + ' must not be empty') + const n = name + '.direction'; + a.strictEqual(typeof dep.direction, 'string', n + ' must be a string'); + a.ok(dep.direction, n + ' must not be empty'); } if (dep.destination !== null) { - const lName = name + '.destination' - val.location(val, dep.destination, lName) + const lName = name + '.destination'; + val.location(val, dep.destination, lName); } if (dep.origin !== null) { - const lName = name + '.origin' - val.location(val, dep.origin, lName) + const lName = name + '.origin'; + val.location(val, dep.origin, lName); } - } - return validateArrivalOrDeparture -} + }; + return validateArrivalOrDeparture; +}; const createValidateArrival = (cfg) => { - const validate = createValidateArrivalOrDeparture('arrival', cfg) + const validate = createValidateArrivalOrDeparture('arrival', cfg); return (val, arr, name = 'arrival') => { - validate(val, arr, name) + validate(val, arr, name); if ('previousStopovers' in arr) { - const n = name + '.previousStopovers' - a.ok(Array.isArray(arr.previousStopovers), n + ' must be an array') + const n = name + '.previousStopovers'; + a.ok(Array.isArray(arr.previousStopovers), n + ' must be an array'); for (let i = 0; i < arr.previousStopovers.length; i++) { - val.stopover(val, arr.previousStopovers[i], n + `[${i}]`) + val.stopover(val, arr.previousStopovers[i], n + `[${i}]`); } } - } -} + }; +}; const createValidateDeparture = (cfg) => { - const validate = createValidateArrivalOrDeparture('departure', cfg) + const validate = createValidateArrivalOrDeparture('departure', cfg); return (val, dep, name = 'departure') => { - validate(val, dep, name) + validate(val, dep, name); if ('nextStopovers' in dep) { - const n = name + '.nextStopovers' - a.ok(Array.isArray(dep.nextStopovers), n + ' must be an array') + const n = name + '.nextStopovers'; + a.ok(Array.isArray(dep.nextStopovers), n + ' must be an array'); for (let i = 0; i < dep.nextStopovers.length; i++) { - val.stopover(val, dep.nextStopovers[i], n + `[${i}]`) + val.stopover(val, dep.nextStopovers[i], n + `[${i}]`); } } - } -} + }; +}; const _createValidateStationBoardResults = (cfg, validatorsKey) => { const validateStationBoardResults = (val, arrsOrDeps, name) => { - a.ok(Array.isArray(arrsOrDeps), name + ' must be an array') - a.ok(arrsOrDeps.length > 0, name + ' must not be empty') + a.ok(Array.isArray(arrsOrDeps), name + ' must be an array'); + a.ok(arrsOrDeps.length > 0, name + ' must not be empty'); for (let i = 0; i < arrsOrDeps.length; i++) { - val[validatorsKey](val, arrsOrDeps[i], name + `[${i}]`) + val[validatorsKey](val, arrsOrDeps[i], name + `[${i}]`); } - } - return validateStationBoardResults -} + }; + return validateStationBoardResults; +}; const createValidateArrivals = (cfg) => { - return _createValidateStationBoardResults(cfg, 'arrival') -} + return _createValidateStationBoardResults(cfg, 'arrival'); +}; const createValidateDepartures = (cfg) => { - return _createValidateStationBoardResults(cfg, 'departure') -} + return _createValidateStationBoardResults(cfg, 'departure'); +}; const _createValidateStationBoardResponse = (cfg, validatorsKey, arrsOrDepsKey) => { const _validateStationBoardResponse = (val, res, name) => { - a.ok(isObj(res), name + ' must be an object') + a.ok(isObj(res), name + ' must be an object'); - val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt') + val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt'); - const arrsOrDeps = res[arrsOrDepsKey] - val[validatorsKey](val, arrsOrDeps, `${name}.${arrsOrDepsKey}`) - } - return _validateStationBoardResponse -} + const arrsOrDeps = res[arrsOrDepsKey]; + val[validatorsKey](val, arrsOrDeps, `${name}.${arrsOrDepsKey}`); + }; + return _validateStationBoardResponse; +}; const createValidateArrivalsResponse = (cfg) => { - return _createValidateStationBoardResponse(cfg, 'arrivals', 'arrivals') -} + return _createValidateStationBoardResponse(cfg, 'arrivals', 'arrivals'); +}; const createValidateDeparturesResponse = (cfg) => { - return _createValidateStationBoardResponse(cfg, 'departures', 'departures') -} + return _createValidateStationBoardResponse(cfg, 'departures', 'departures'); +}; const createValidateMovement = (cfg) => { - const {maxLatitude, minLatitude, maxLongitude, minLongitude} = cfg + const {maxLatitude, minLatitude, maxLongitude, minLongitude} = cfg; const validateMovement = (val, m, name = 'movement') => { - a.ok(isObj(m), name + ' must be an object') + a.ok(isObj(m), name + ' must be an object'); // todo: let hafas-client add a .type field - val.line(val, m.line, name + '.line') - a.strictEqual(typeof m.direction, 'string', name + '.direction must be a string') - a.ok(m.direction, name + '.direction must not be empty') + val.line(val, m.line, name + '.line'); + a.strictEqual(typeof m.direction, 'string', name + '.direction must be a string'); + a.ok(m.direction, name + '.direction must not be empty'); - const lName = name + '.location' - val.location(val, m.location, lName) - const s = `${m.location.latitude}|${m.location.longitude} ${m.line && m.line.name}` + const lName = name + '.location'; + val.location(val, m.location, lName); + const s = `${m.location.latitude}|${m.location.longitude} ${m.line && m.line.name}`; if ('number' === typeof maxLatitude) { - a.ok(m.location.latitude <= maxLatitude, lName + '.latitude is too large: ' + s) + a.ok(m.location.latitude <= maxLatitude, lName + '.latitude is too large: ' + s); } if ('number' === typeof minLatitude) { - a.ok(m.location.latitude >= minLatitude, lName + '.latitude is too small: ' + s) + a.ok(m.location.latitude >= minLatitude, lName + '.latitude is too small: ' + s); } if ('number' === typeof maxLongitude) { - a.ok(m.location.longitude <= maxLongitude, lName + '.longitude is too large: ' + s) + a.ok(m.location.longitude <= maxLongitude, lName + '.longitude is too large: ' + s); } if ('number' === typeof minLongitude) { - a.ok(m.location.longitude >= minLongitude, lName + '.longitude is too small: ' + s) + a.ok(m.location.longitude >= minLongitude, lName + '.longitude is too small: ' + s); } - a.ok(Array.isArray(m.nextStopovers), name + '.nextStopovers must be an array') + a.ok(Array.isArray(m.nextStopovers), name + '.nextStopovers must be an array'); for (let i = 0; i < m.nextStopovers.length; i++) { - const st = m.nextStopovers[i] - val.stopover(val, st, name + `.nextStopovers[${i}]`) + const st = m.nextStopovers[i]; + val.stopover(val, st, name + `.nextStopovers[${i}]`); } - a.ok(Array.isArray(m.frames), name + '.frames must be an array') - a.ok(m.frames.length > 0, name + '.frames must not be empty') + a.ok(Array.isArray(m.frames), name + '.frames must be an array'); + a.ok(m.frames.length > 0, name + '.frames must not be empty'); for (let i = 0; i < m.frames.length; i++) { - const f = m.frames[i] - const fName = name + `.frames[${i}]` + const f = m.frames[i]; + const fName = name + `.frames[${i}]`; - a.ok(isObj(f), fName + ' must be an object') - anyOf(['location', 'stop', 'station'], val, f.origin, fName + '.origin') - anyOf(['location', 'stop', 'station'], val, f.destination, fName + '.destination') - a.strictEqual(typeof f.t, 'number', fName + '.frames must be a number') + a.ok(isObj(f), fName + ' must be an object'); + anyOf(['location', 'stop', 'station'], val, f.origin, fName + '.origin'); + anyOf(['location', 'stop', 'station'], val, f.destination, fName + '.destination'); + a.strictEqual(typeof f.t, 'number', fName + '.frames must be a number'); } // todo: validate polyline - } - return validateMovement -} + }; + return validateMovement; +}; const validateMovements = (val, ms, name = 'movements') => { - a.ok(Array.isArray(ms), name + ' must be an array') - a.ok(ms.length > 0, name + ' must not be empty') + a.ok(Array.isArray(ms), name + ' must be an array'); + a.ok(ms.length > 0, name + ' must not be empty'); for (let i = 0; i < ms.length; i++) { - val.movement(val, ms[i], name + `[${i}]`) + val.movement(val, ms[i], name + `[${i}]`); } -} -const createValidateMovements = () => validateMovements +}; +const createValidateMovements = () => validateMovements; const validateRadarResult = (val, res, name = 'movementsResult') => { - a.ok(isObj(res), name + ' must be an object') + a.ok(isObj(res), name + ' must be an object'); - val.movements(val, res.movements, name + '.movements') + val.movements(val, res.movements, name + '.movements'); - val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt') -} -const createValidateRadarResult = () => validateRadarResult + val.realtimeDataUpdatedAt(val, res.realtimeDataUpdatedAt, name + '.realtimeDataUpdatedAt'); +}; +const createValidateRadarResult = () => validateRadarResult; export { createValidateRealtimeDataUpdatedAt, @@ -693,7 +693,7 @@ export { createValidateMovement, createValidateMovements, createValidateRadarResult, -} +}; export default { realtimeDataUpdatedAt: createValidateRealtimeDataUpdatedAt, @@ -725,4 +725,4 @@ export default { movement: createValidateMovement, movements: createValidateMovements, radarResult: createValidateRadarResult, -} +}; diff --git a/test/e2e/lib/vbb-bvg-validators.js b/test/e2e/lib/vbb-bvg-validators.js index 0e723cc7e..2d9226b02 100644 --- a/test/e2e/lib/vbb-bvg-validators.js +++ b/test/e2e/lib/vbb-bvg-validators.js @@ -1,27 +1,27 @@ -import {products} from '../../../p/bvg/products.js' +import {products} from '../../../p/bvg/products.js'; import { createValidateStation, createValidateJourneyLeg, createValidateDeparture, createValidateMovement, -} from './validators.js' +} from './validators.js'; const createVbbBvgValidators = ({when}) => { const cfg = { when, stationCoordsOptional: false, products, - } + }; // todo: coordsOptional = false - const validateStation = createValidateStation(cfg) + const validateStation = createValidateStation(cfg); - const validateJourneyLeg = createValidateJourneyLeg(cfg) + const validateJourneyLeg = createValidateJourneyLeg(cfg); - const validateDeparture = createValidateDeparture(cfg) + const validateDeparture = createValidateDeparture(cfg); - const validateMovement = createValidateMovement(cfg) + const validateMovement = createValidateMovement(cfg); return { cfg, @@ -29,9 +29,9 @@ const createVbbBvgValidators = ({when}) => { validateJourneyLeg, validateDeparture, validateMovement, - } -} + }; +}; export { createVbbBvgValidators, -} +}; diff --git a/test/e2e/mobil-nrw.js b/test/e2e/mobil-nrw.js index 25f8d09ff..041398070 100644 --- a/test/e2e/mobil-nrw.js +++ b/test/e2e/mobil-nrw.js @@ -1,20 +1,20 @@ -import tap from 'tap' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as mobilNrwProfile} from '../../p/mobil-nrw/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {testDepartures} from './lib/departures.js' -import {testArrivals} from './lib/arrivals.js' -import {testReachableFrom} from './lib/reachable-from.js' - -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(mobilNrwProfile.timezone, mobilNrwProfile.locale, T_MOCK) +import tap from 'tap'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as mobilNrwProfile} from '../../p/mobil-nrw/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {testDepartures} from './lib/departures.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testReachableFrom} from './lib/reachable-from.js'; + +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(mobilNrwProfile.timezone, mobilNrwProfile.locale, T_MOCK); const cfg = { when, @@ -24,22 +24,22 @@ const cfg = { minLongitude: 1.659, maxLatitude: 53.531, maxLongitude: 14.689, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(mobilNrwProfile, 'public-transport/hafas-client:test') +const client = createClient(mobilNrwProfile, 'public-transport/hafas-client:test'); -const soest = '8000076' -const aachenHbf = '8000001' -const dortmundStadtgarten = '655672' +const soest = '8000076'; +const aachenHbf = '8000001'; +const dortmundStadtgarten = '655672'; tap.test('journeys – Soest to Aachen Hbf', async (t) => { const res = await client.journeys(soest, aachenHbf, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -47,9 +47,9 @@ tap.test('journeys – Soest to Aachen Hbf', async (t) => { validate, fromId: soest, toId: aachenHbf, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -60,12 +60,12 @@ tap.test('Aachen Hbf to Schillingstr. 3, Dortmund', async (t) => { address: 'Dortmund - Mitte, Schillingstraße 3', latitude: 51.504891, longitude: 7.457802, - } + }; const res = await client.journeys(aachenHbf, schillingstr3, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -73,9 +73,9 @@ tap.test('Aachen Hbf to Schillingstr. 3, Dortmund', async (t) => { validate, fromId: aachenHbf, to: schillingstr3, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Aachen Hbf to Sportanlage Schulzentrum, Dortmund', async (t) => { const sportanlage = { @@ -85,11 +85,11 @@ tap.test('Aachen Hbf to Sportanlage Schulzentrum, Dortmund', async (t) => { name: 'Dortmund, Sportanlage Schulzentrum (Grünanlagen)', latitude: 51.491201, longitude: 7.562859, - } + }; const res = await client.journeys(aachenHbf, sportanlage, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -97,9 +97,9 @@ tap.test('Aachen Hbf to Sportanlage Schulzentrum, Dortmund', async (t) => { validate, fromId: aachenHbf, to: sportanlage, - }) - t.end() -}) + }); + t.end(); +}); // todo: walkingSpeed "2107 MELRIDGE PL" -> 000002148 // todo: via works – with detour @@ -113,10 +113,10 @@ tap.test('earlier/later journeys', async (t) => { fromId: soest, toId: aachenHbf, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('refreshJourney', async (t) => { await testRefreshJourney({ @@ -127,24 +127,24 @@ tap.test('refreshJourney', async (t) => { fromId: soest, toId: aachenHbf, when, - }) - t.end() -}) + }); + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(soest, aachenHbf, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Soest', async (t) => { const ids = [ @@ -152,20 +152,20 @@ tap.test('departures at Soest', async (t) => { '906135', // Bahnhof, Soest '904812', // Bahnhof/Brüdertor, Soest '902737', // Bahnhof E, Soest - ] + ]; const res = await client.departures(soest, { duration: 10, when, - }) + }); await testDepartures({ test: t, res, validate, ids, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -177,11 +177,11 @@ tap.test('departures with station object', async (t) => { latitude: 1.23, longitude: 2.34, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('arrivals at Soest', async (t) => { const ids = [ @@ -189,48 +189,48 @@ tap.test('arrivals at Soest', async (t) => { '906135', // Bahnhof, Soest '904812', // Bahnhof/Brüdertor, Soest '902737', // Bahnhof E, Soest - ] + ]; const res = await client.arrivals(soest, { duration: 10, when, - }) + }); await testArrivals({ test: t, res, validate, ids, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby tap.test('locations named "stadtgarten dortmund"', async (t) => { const locations = await client.locations('stadtgarten dortmund', { results: 10, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 10) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 10); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs t.ok(locations.some((l) => { - return l.station && l.station.id === dortmundStadtgarten || l.id === dortmundStadtgarten - })) + return l.station && l.station.id === dortmundStadtgarten || l.id === dortmundStadtgarten; + })); - t.end() -}) + t.end(); +}); tap.test('station Aachen Hbf', async (t) => { - const s = await client.stop(aachenHbf) + const s = await client.stop(aachenHbf); - validate(t, s, ['stop', 'station'], 'station') - t.equal(s.id, aachenHbf) + validate(t, s, ['stop', 'station'], 'station'); + t.equal(s.id, aachenHbf); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -240,11 +240,11 @@ tap.test('radar', async (t) => { east: 6.7900, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.test('reachableFrom', async (t) => { await testReachableFrom({ @@ -260,6 +260,6 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/mobiliteit-lu.js b/test/e2e/mobiliteit-lu.js index 3bb6475bb..0a30d82ce 100644 --- a/test/e2e/mobiliteit-lu.js +++ b/test/e2e/mobiliteit-lu.js @@ -1,26 +1,26 @@ -import tap from 'tap' -import assert from 'assert' -import isRoughlyEqual from 'is-roughly-equal' +import tap from 'tap'; +import assert from 'assert'; +import isRoughlyEqual from 'is-roughly-equal'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as mobiliteitLuProfile} from '../../p/mobiliteit-lu/index.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as mobiliteitLuProfile} from '../../p/mobiliteit-lu/index.js'; import { createValidateLine, createValidateJourneyLeg, createValidateMovement, -} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testArrivals} from './lib/arrivals.js' - -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(mobiliteitLuProfile.timezone, mobiliteitLuProfile.locale, T_MOCK) +} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testArrivals} from './lib/arrivals.js'; + +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(mobiliteitLuProfile.timezone, mobiliteitLuProfile.locale, T_MOCK); const cfg = { when, @@ -29,58 +29,58 @@ const cfg = { maxLatitude: 52.9, minLongitude: -0.63, maxLongitude: 14.07, -} +}; -const _validateLine = createValidateLine(cfg) +const _validateLine = createValidateLine(cfg); const validateLine = (validate, l, name) => { if (!l.direction) { - l = Object.assign({}, l, {direction: 'foo'}) + l = Object.assign({}, l, {direction: 'foo'}); } - _validateLine(validate, l, name) -} + _validateLine(validate, l, name); +}; -const _validateJourneyLeg = createValidateJourneyLeg(cfg) +const _validateJourneyLeg = createValidateJourneyLeg(cfg); const validateJourneyLeg = (validate, l, name) => { if (!l.direction) { - l = Object.assign({}, l, {direction: 'foo'}) + l = Object.assign({}, l, {direction: 'foo'}); } - _validateJourneyLeg(validate, l, name) -} + _validateJourneyLeg(validate, l, name); +}; -const _validateMovement = createValidateMovement(cfg) +const _validateMovement = createValidateMovement(cfg); const validateMovement = (val, m, name = 'movement') => { // todo: fix this upstream - const withFakeLocation = Object.assign({}, m) + const withFakeLocation = Object.assign({}, m); withFakeLocation.location = Object.assign({}, m.location, { latitude: 50, longitude: 12, - }) - _validateMovement(val, withFakeLocation, name) + }); + _validateMovement(val, withFakeLocation, name); - assert.ok(m.location.latitude <= 55, name + '.location.latitude is too small') - assert.ok(m.location.latitude >= 45, name + '.location.latitude is too large') - assert.ok(m.location.longitude >= 1, name + '.location.longitude is too small') - assert.ok(m.location.longitude <= 11, name + '.location.longitude is too small') -} + assert.ok(m.location.latitude <= 55, name + '.location.latitude is too small'); + assert.ok(m.location.latitude >= 45, name + '.location.latitude is too large'); + assert.ok(m.location.longitude >= 1, name + '.location.longitude is too small'); + assert.ok(m.location.longitude <= 11, name + '.location.longitude is too small'); +}; const validate = createValidate(cfg, { line: validateLine, journeyLeg: validateJourneyLeg, movement: validateMovement, -}) +}); -const client = createClient(mobiliteitLuProfile, 'public-transport/hafas-client:test') +const client = createClient(mobiliteitLuProfile, 'public-transport/hafas-client:test'); -const ettelbruck = '140701016' -const mersch = '160904011' -const luxembourgGareCentrale = '200405060' +const ettelbruck = '140701016'; +const mersch = '160904011'; +const luxembourgGareCentrale = '200405060'; tap.test('journeys – Ettelbruck to Luxembourg', async (t) => { const res = await client.journeys(ettelbruck, luxembourgGareCentrale, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -92,9 +92,9 @@ tap.test('journeys – Ettelbruck to Luxembourg', async (t) => { '300030001', // Luxembourg, Gare Centrale (Tram) '300032002', // Luxembourg, Gare Rocade ], - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -106,9 +106,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: luxembourgGareCentrale, when, products: mobiliteitLuProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Luxembourg to Ettelbruck, Rue des Romains 4', async (t) => { const rueDeRomain = { @@ -116,12 +116,12 @@ tap.test('Luxembourg to Ettelbruck, Rue des Romains 4', async (t) => { address: 'Ettelbruck, Rue des Romains 4', latitude: 49.847469, longitude: 6.097608, - } + }; const res = await client.journeys(luxembourgGareCentrale, rueDeRomain, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -129,9 +129,9 @@ tap.test('Luxembourg to Ettelbruck, Rue des Romains 4', async (t) => { validate, fromId: luxembourgGareCentrale, to: rueDeRomain, - }) - t.end() -}) + }); + t.end(); +}); // Some journeys don't start or stop at the stop/POI that we queried journeys for. tap.test('Luxembourg to Centre Hospitalier du Nord', async (t) => { @@ -142,11 +142,11 @@ tap.test('Luxembourg to Centre Hospitalier du Nord', async (t) => { name: 'Ettelbruck, Centre Hospitalier du Nord (CHDN)', latitude: 49.853519, longitude: 6.094587, - } + }; const res = await client.journeys(luxembourgGareCentrale, centreHospitalier, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -154,9 +154,9 @@ tap.test('Luxembourg to Centre Hospitalier du Nord', async (t) => { validate, fromId: luxembourgGareCentrale, to: centreHospitalier, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys: via works – with detour // todo: without detour @@ -169,53 +169,53 @@ tap.test('earlier/later journeys', async (t) => { fromId: luxembourgGareCentrale, toId: ettelbruck, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('trip', async (t) => { const {journeys} = await client.journeys(luxembourgGareCentrale, ettelbruck, { results: 1, departure: when, - }) + }); - const p = journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Ettelbruck.', async (t) => { const res = await client.departures(ettelbruck, { duration: 20, when, - }) + }); await testDepartures({ test: t, res, validate, id: ettelbruck, - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Ettelbruck.', async (t) => { const res = await client.arrivals(ettelbruck, { duration: 20, when, - }) + }); await testArrivals({ test: t, res, validate, id: ettelbruck, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -227,41 +227,41 @@ tap.test('departures with station object', async (t) => { latitude: 49.847298, longitude: 6.106157, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); // todo: nearby tap.test('locations named Mersch', async (t) => { const locations = await client.locations('Mersch', { results: 20, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); t.ok(locations.some((loc) => { if (loc.station && loc.station.id === mersch) { - return true + return true; } - return loc.id === mersch - })) + return loc.id === mersch; + })); - t.end() -}) + t.end(); +}); tap.test('stop Mersch', async (t) => { - const s = await client.stop(mersch) + const s = await client.stop(mersch); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, mersch) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, mersch); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -271,8 +271,8 @@ tap.test('radar', async (t) => { east: 6.15, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); diff --git a/test/e2e/nahsh.js b/test/e2e/nahsh.js index 34f5e53b4..09e42ed06 100644 --- a/test/e2e/nahsh.js +++ b/test/e2e/nahsh.js @@ -1,28 +1,28 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as nahshProfile} from '../../p/nahsh/index.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as nahshProfile} from '../../p/nahsh/index.js'; import { createValidateLine, createValidateStation, -} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' -import {testArrivals} from './lib/arrivals.js' -import {testReachableFrom} from './lib/reachable-from.js' - -const T_MOCK = 1670310000 * 1000 // 2022-12-06T08:00:00+01:00 +} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testReachableFrom} from './lib/reachable-from.js'; + +const T_MOCK = 1670310000 * 1000; // 2022-12-06T08:00:00+01:00 // const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(nahshProfile.timezone, nahshProfile.locale, T_MOCK) +const when = createWhen(nahshProfile.timezone, nahshProfile.locale, T_MOCK); const cfg = { when, @@ -32,73 +32,73 @@ const cfg = { minLongitude: 7.5, minLatitude: 53.15, maxLongitude: 11.6, -} +}; -const _validateLine = createValidateLine(cfg) +const _validateLine = createValidateLine(cfg); const validateLine = (validate, l, name) => { if (l && l.product === 'onCall') { // skip line validation // https://github.com/derhuerst/hafas-client/issues/8#issuecomment-355839965 - l = Object.assign({}, l) - l.mode = 'taxi' + l = Object.assign({}, l); + l.mode = 'taxi'; } - _validateLine(validate, l, name) -} + _validateLine(validate, l, name); +}; const validate = createValidate(cfg, { line: validateLine, -}) +}); const assertValidPrice = (t, p) => { - t.ok(p) + t.ok(p); if (p.amount !== null) { - t.equal(typeof p.amount, 'number') - t.ok(p.amount > 0) + t.equal(typeof p.amount, 'number'); + t.ok(p.amount > 0); } if (p.hint !== null) { - t.equal(typeof p.hint, 'string') - t.ok(p.hint) + t.equal(typeof p.hint, 'string'); + t.ok(p.hint); } -} +}; -const client = createClient(nahshProfile, 'public-transport/hafas-client:test') +const client = createClient(nahshProfile, 'public-transport/hafas-client:test'); -const kielHbf = '9049079' -const kielHbf2 = '9049076' -const flensburg = '9027253' -const luebeckHbf = '9057819' -const husum = '9044660' -const schleswig = '9081683' -const ellerbekerMarkt = '9049027' -const seefischmarkt = '9049245' -const kielRaeucherei = '9049217' +const kielHbf = '9049079'; +const kielHbf2 = '9049076'; +const flensburg = '9027253'; +const luebeckHbf = '9057819'; +const husum = '9044660'; +const schleswig = '9081683'; +const ellerbekerMarkt = '9049027'; +const seefischmarkt = '9049245'; +const kielRaeucherei = '9049217'; tap.test('journeys – Kiel Hbf to Flensburg', async (t) => { const res = await client.journeys(kielHbf, flensburg, { results: 4, departure: when, stopovers: true, - }) + }); - const kaistr = '9049113' + const kaistr = '9049113'; await testJourneysStationToStation({ test: t, res, validate, fromIds: [kielHbf, kaistr], toId: flensburg, - }) + }); for (let i = 0; i < res.journeys.length; i++) { - const j = res.journeys[i] + const j = res.journeys[i]; // todo: find a journey where there pricing info is always available if (j.price) { - assertValidPrice(t, j.price, `res.journeys[${i}].price`) + assertValidPrice(t, j.price, `res.journeys[${i}].price`); } } - t.end() -}) + t.end(); +}); // todo: journeys, only one product @@ -110,9 +110,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: flensburg, when, products: nahshProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Kiel Hbf to Berliner Str. 80, Husum', async (t) => { const berlinerStr = { @@ -120,11 +120,11 @@ tap.test('Kiel Hbf to Berliner Str. 80, Husum', async (t) => { address: 'Husum, Berliner Straße 80', latitude: 54.488995, longitude: 9.056263, - } + }; const res = await client.journeys(kielHbf, berlinerStr, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -132,9 +132,9 @@ tap.test('Kiel Hbf to Berliner Str. 80, Husum', async (t) => { validate, fromIds: [kielHbf, kielHbf2], to: berlinerStr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Kiel Hbf to Holstentor', async (t) => { const holstentor = { @@ -144,11 +144,11 @@ tap.test('Kiel Hbf to Holstentor', async (t) => { name: 'Hansestadt Lübeck, Holstentor (Denkmal)', latitude: 53.866321, longitude: 10.679976, - } + }; const res = await client.journeys(kielHbf, holstentor, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -156,9 +156,9 @@ tap.test('Kiel Hbf to Holstentor', async (t) => { validate, fromIds: [kielHbf, kielHbf2], to: holstentor, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Husum to Lübeck Hbf with stopover at Kiel Hbf', async (t) => { const res = await client.journeys(husum, luebeckHbf, { @@ -166,20 +166,20 @@ tap.test('Husum to Lübeck Hbf with stopover at Kiel Hbf', async (t) => { results: 1, departure: when, stopovers: true, - }) + }); - validate(t, res, 'journeysResult', 'res') + validate(t, res, 'journeysResult', 'res'); const leg = res.journeys[0].legs.some((leg) => { return leg.stopovers && leg.stopovers.some((stopover) => { - const s = stopover.stop - return s.station && s.station.id === kielHbf || s.id === kielHbf - }) - }) - t.ok(leg, 'Kiel Hbf is not being passed') + const s = stopover.stop; + return s.station && s.station.id === kielHbf || s.id === kielHbf; + }); + }); + t.ok(leg, 'Kiel Hbf is not being passed'); - t.end() -}) + t.end(); +}); tap.test('earlier/later journeys, Kiel Hbf -> Flensburg', async (t) => { await testEarlierLaterJourneys({ @@ -189,10 +189,10 @@ tap.test('earlier/later journeys, Kiel Hbf -> Flensburg', async (t) => { fromId: kielHbf, toId: flensburg, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('refreshJourney', async (t) => { await testRefreshJourney({ @@ -203,9 +203,9 @@ tap.test('refreshJourney', async (t) => { fromId: kielHbf, toId: flensburg, when, - }) - t.end() -}) + }); + t.end(); +}); // todo: with detour test // todo: without detour test @@ -213,31 +213,31 @@ tap.test('refreshJourney', async (t) => { tap.test('trip details', async (t) => { const res = await client.journeys(flensburg, husum, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Kiel Räucherei', async (t) => { const res = await client.departures(kielRaeucherei, { duration: 30, when, - }) + }); await testDepartures({ test: t, res, validate, id: kielRaeucherei, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -249,11 +249,11 @@ tap.test('departures with station object', async (t) => { latitude: 1.23, longitude: 2.34, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('departures at Berlin Hbf in direction of Berlin Ostbahnhof', async (t) => { await testDeparturesInDirection({ @@ -264,72 +264,72 @@ tap.test('departures at Berlin Hbf in direction of Berlin Ostbahnhof', async (t) directionIds: [seefischmarkt, '710102'], when, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Kiel Räucherei', async (t) => { const res = await client.arrivals(kielRaeucherei, { duration: 30, when, - }) + }); await testArrivals({ test: t, res, validate, id: kielRaeucherei, - }) - t.end() -}) + }); + t.end(); +}); tap.test('nearby Kiel Hbf', async (t) => { const kielHbfPosition = { type: 'location', latitude: 54.314982, longitude: 10.131976, - } + }; const nearby = await client.nearby(kielHbfPosition, { results: 2, distance: 400, - }) + }); - validate(t, nearby, 'locations', 'nearby') + validate(t, nearby, 'locations', 'nearby'); - t.ok(Array.isArray(nearby)) - t.equal(nearby.length, 2) + t.ok(Array.isArray(nearby)); + t.equal(nearby.length, 2); - const match = nearby.find(n => n.id === kielHbf || n.station?.id === kielHbf) - t.ok(match) - t.equal(match.name, 'Kiel Hbf') - t.ok(match.distance >= 0) - t.ok(match.distance <= 100) + const match = nearby.find(n => n.id === kielHbf || n.station?.id === kielHbf); + t.ok(match); + t.equal(match.name, 'Kiel Hbf'); + t.ok(match.distance >= 0); + t.ok(match.distance <= 100); - t.end() -}) + t.end(); +}); tap.test('locations named "Kiel Rathaus"', async (t) => { - const kielRathaus = '9049200' + const kielRathaus = '9049200'; const locations = await client.locations('Kiel Rathaus', { results: 15, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 15) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 15); - t.ok(locations.find(l => l.type === 'stop' || l.type === 'station')) - t.ok(locations.find(l => l.poi)) // POIs - t.ok(locations.some(l => l.station && l.station.id === kielRathaus || l.id === kielRathaus)) + t.ok(locations.find(l => l.type === 'stop' || l.type === 'station')); + t.ok(locations.find(l => l.poi)); // POIs + t.ok(locations.some(l => l.station && l.station.id === kielRathaus || l.id === kielRathaus)); - t.end() -}) + t.end(); +}); tap.test('stop', async (t) => { - const s = await client.stop(kielHbf) + const s = await client.stop(kielHbf); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, kielHbf) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, kielHbf); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -339,27 +339,27 @@ tap.test('radar', async (t) => { east: 10.2, }, { duration: 5 * 60, when, - }) + }); // todo: cfg.stationProductsOptional option - const {products} = nahshProfile - const allProducts = products.reduce((acc, p) => (acc[p.id] = true, acc), {}) - const validateStation = createValidateStation(cfg) + const {products} = nahshProfile; + const allProducts = products.reduce((acc, p) => (acc[p.id] = true, acc), {}); + const validateStation = createValidateStation(cfg); const validate = createValidate(cfg, { station: (validate, s, name) => { s = Object.assign({ products: allProducts, // todo: fix station.products - }, s) + }, s); if (!s.name) { - s.name = 'foo' + s.name = 'foo'; } // todo, see #34 - validateStation(validate, s, name) + validateStation(validate, s, name); }, - }) - validate(t, res, 'radarResult', 'res') + }); + validate(t, res, 'radarResult', 'res'); - t.end() -}) + t.end(); +}); tap.test('reachableFrom', async (t) => { const berlinerStr = { @@ -367,7 +367,7 @@ tap.test('reachableFrom', async (t) => { address: 'Husum, Berliner Straße 80', latitude: 54.488995, longitude: 9.056263, - } + }; await testReachableFrom({ test: t, @@ -376,6 +376,6 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 60, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/nvv.js b/test/e2e/nvv.js index 4f843c80f..a96a84afb 100644 --- a/test/e2e/nvv.js +++ b/test/e2e/nvv.js @@ -1,24 +1,24 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as nvvProfile} from '../../p/nvv/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' -import {testArrivals} from './lib/arrivals.js' -import {testJourneysWithDetour} from './lib/journeys-with-detour.js' - -const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o) - -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(nvvProfile.timezone, nvvProfile.locale, T_MOCK) +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as nvvProfile} from '../../p/nvv/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testJourneysWithDetour} from './lib/journeys-with-detour.js'; + +const isObj = o => o !== null && 'object' === typeof o && !Array.isArray(o); + +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(nvvProfile.timezone, nvvProfile.locale, T_MOCK); const cfg = { when, @@ -28,22 +28,22 @@ const cfg = { minLongitude: 8, maxLatitude: 53, maxLongitude: 14, -} -const validate = createValidate(cfg, {}) +}; +const validate = createValidate(cfg, {}); -const client = createClient(nvvProfile, 'public-transport/hafas-client:test') +const client = createClient(nvvProfile, 'public-transport/hafas-client:test'); -const scheidemannplatz = '2200073' -const auestadion = '2200042' -const weigelstr = '2200056' -const friedrichsplatz = '2200006' +const scheidemannplatz = '2200073'; +const auestadion = '2200042'; +const weigelstr = '2200056'; +const friedrichsplatz = '2200006'; tap.test('journeys – Kassel Scheidemannplatz to Kassel Auestadion', async (t) => { const res = await client.journeys(scheidemannplatz, auestadion, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -51,9 +51,9 @@ tap.test('journeys – Kassel Scheidemannplatz to Kassel Auestadion', async (t) validate, fromId: scheidemannplatz, toId: auestadion, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -65,9 +65,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: auestadion, when, products: nvvProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Kassel Scheidemannplatz to Heckerstraße 2', async (t) => { const heckerstr2 = { @@ -76,12 +76,12 @@ tap.test('Kassel Scheidemannplatz to Heckerstraße 2', async (t) => { address: 'Kassel, Heckerstraße 2', latitude: 51.308108, longitude: 9.475152, - } + }; const res = await client.journeys(scheidemannplatz, heckerstr2, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -89,9 +89,9 @@ tap.test('Kassel Scheidemannplatz to Heckerstraße 2', async (t) => { validate, fromId: scheidemannplatz, to: heckerstr2, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Kassel Scheidemannplatz to Grimmwelt', async (t) => { const grimmwelt = { @@ -101,11 +101,11 @@ tap.test('Kassel Scheidemannplatz to Grimmwelt', async (t) => { name: 'Grimmwelt Kassel', latitude: 51.309313, longitude: 9.489283, - } + }; const res = await client.journeys(scheidemannplatz, grimmwelt, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -113,30 +113,30 @@ tap.test('Kassel Scheidemannplatz to Grimmwelt', async (t) => { validate, fromId: scheidemannplatz, to: grimmwelt, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys: via works – with detour', async (t) => { // Going from Scheidemannplatz to Rathaus/Fünffensterstr. via Kassel Wilhelmshöhe // implies a detour. We check if the routing engine computes a detour. - const rathausFünffensterstr = '2200436' - const wilhelmshöhe = '2200007' + const rathausFünffensterstr = '2200436'; + const wilhelmshöhe = '2200007'; const res = await client.journeys(scheidemannplatz, rathausFünffensterstr, { via: wilhelmshöhe, results: 1, departure: when, stopovers: true, - }) + }); await testJourneysWithDetour({ test: t, res, validate, detourIds: [wilhelmshöhe], - }) - t.end() -}) + }); + t.end(); +}); // todo: without detour @@ -148,39 +148,39 @@ tap.test('earlier/later journeys', async (t) => { fromId: scheidemannplatz, toId: auestadion, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(scheidemannplatz, auestadion, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Kassel Auestadion.', async (t) => { const res = await client.departures(auestadion, { duration: 11, when, - }) + }); await testDepartures({ test: t, res, validate, id: auestadion, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -192,11 +192,11 @@ tap.test('departures with station object', async (t) => { latitude: 1.23, longitude: 2.34, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('departures at Auestadion in direction of Friedrichsplatz', async (t) => { await testDeparturesInDirection({ @@ -207,47 +207,47 @@ tap.test('departures at Auestadion in direction of Friedrichsplatz', async (t) = directionIds: [friedrichsplatz], when, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Kassel Weigelstr.', async (t) => { const res = await client.arrivals(weigelstr, { duration: 5, when, - }) + }); await testArrivals({ test: t, res, validate, id: weigelstr, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby tap.test('locations named Auestadion', async (t) => { - const locations = await client.locations('auestadion', {results: 10}) + const locations = await client.locations('auestadion', {results: 10}); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 10) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 10); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs - t.ok(locations.some(l => l.station && l.station.id === auestadion || l.id === auestadion)) + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs + t.ok(locations.some(l => l.station && l.station.id === auestadion || l.id === auestadion)); - t.end() -}) + t.end(); +}); tap.test('station Auestadion', async (t) => { - const s = await client.stop(auestadion) + const s = await client.stop(auestadion); - validate(t, s, ['stop', 'station'], 'station') - t.equal(s.id, auestadion) + validate(t, s, ['stop', 'station'], 'station'); + t.equal(s.id, auestadion); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -257,9 +257,9 @@ tap.test('radar', async (t) => { east: 9.493672, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') + validate(t, res, 'radarResult', 'res'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/oebb.js b/test/e2e/oebb.js index 7d6ecd57d..e15bfe7fb 100644 --- a/test/e2e/oebb.js +++ b/test/e2e/oebb.js @@ -1,27 +1,27 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' -import validateLine from 'validate-fptf/line.js' +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; +import validateLine from 'validate-fptf/line.js'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as oebbProfile} from '../../p/oebb/index.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as oebbProfile} from '../../p/oebb/index.js'; import { createValidateStation, createValidateStop, -} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testJourneysWithDetour} from './lib/journeys-with-detour.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' - -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(oebbProfile.timezone, oebbProfile.locale, T_MOCK) +} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testJourneysWithDetour} from './lib/journeys-with-detour.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; + +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(oebbProfile.timezone, oebbProfile.locale, T_MOCK); const cfg = { when, @@ -31,44 +31,44 @@ const cfg = { maxLatitude: 49.453517, minLongitude: 8.787557, maxLongitude: 17.491275, -} +}; // todo validateDirection: search list of stations for direction -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const _validateStop = createValidateStop(cfg) +const _validateStop = createValidateStop(cfg); const assertValidPrice = (t, p) => { - t.ok(p) + t.ok(p); if (p.amount !== null) { - t.equal(typeof p.amount, 'number') - t.ok(p.amount > 0) + t.equal(typeof p.amount, 'number'); + t.ok(p.amount > 0); } if (p.hint !== null) { - t.equal(typeof p.hint, 'string') - t.ok(p.hint) + t.equal(typeof p.hint, 'string'); + t.ok(p.hint); } -} +}; -const client = createClient(oebbProfile, 'public-transport/hafas-client:test') +const client = createClient(oebbProfile, 'public-transport/hafas-client:test'); -const salzburgHbf = '8100002' -const wienFickeystr = '911014' -const wien = '1190100' -const wienWestbahnhof = '1291501' -const klagenfurtHbf = '8100085' -const muenchenHbf = '8000261' -const wienRenngasse = '1390186' -const wienKarlsplatz = '1390461' -const wienPilgramgasse = '1390562' +const salzburgHbf = '8100002'; +const wienFickeystr = '911014'; +const wien = '1190100'; +const wienWestbahnhof = '1291501'; +const klagenfurtHbf = '8100085'; +const muenchenHbf = '8000261'; +const wienRenngasse = '1390186'; +const wienKarlsplatz = '1390461'; +const wienPilgramgasse = '1390562'; tap.test('journeys – Salzburg Hbf to Wien Westbahnhof', async (t) => { const res = await client.journeys(salzburgHbf, wienFickeystr, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -76,17 +76,17 @@ tap.test('journeys – Salzburg Hbf to Wien Westbahnhof', async (t) => { validate, fromId: salzburgHbf, toId: wienFickeystr, - }) + }); for (let i = 0; i < res.journeys.length; i++) { - const j = res.journeys[i] + const j = res.journeys[i]; if (j.price) { - assertValidPrice(t, j.price, `res.journeys[${i}].price`) + assertValidPrice(t, j.price, `res.journeys[${i}].price`); } } - t.end() -}) + t.end(); +}); // todo: journeys, only one product @@ -98,9 +98,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: wienFickeystr, when, products: oebbProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Salzburg Hbf to 1220 Wien, Fischerstrand 7', async (t) => { const wagramerStr = { @@ -108,11 +108,11 @@ tap.test('Salzburg Hbf to 1220 Wien, Fischerstrand 7', async (t) => { address: '1220 Wien, Fischerstrand 7', latitude: 48.236216, longitude: 16.425863, - } + }; const res = await client.journeys(salzburgHbf, wagramerStr, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -120,9 +120,9 @@ tap.test('Salzburg Hbf to 1220 Wien, Fischerstrand 7', async (t) => { validate, fromId: salzburgHbf, to: wagramerStr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Salzburg Hbf to Uni Wien', async (t) => { const uniWien = { @@ -131,10 +131,10 @@ tap.test('Salzburg Hbf to Uni Wien', async (t) => { poi: true, name: 'Wien, Donaupark (Parkplatz)', latitude: 48.240674, longitude: 16.4097, - } + }; const res = await client.journeys(salzburgHbf, uniWien, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -142,67 +142,67 @@ tap.test('Salzburg Hbf to Uni Wien', async (t) => { validate, fromId: salzburgHbf, to: uniWien, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys: via works – with detour', async (t) => { // Going from Stephansplatz to Schottenring via Donauinsel without detour // is currently impossible. We check if the routing engine computes a detour. - const stephansplatz = '1390167' - const schottenring = '1390163' - const donauinsel = '1392277' - const donauinselPassed = '922001' + const stephansplatz = '1390167'; + const schottenring = '1390163'; + const donauinsel = '1392277'; + const donauinselPassed = '922001'; const res = await client.journeys(stephansplatz, schottenring, { via: donauinsel, results: 1, departure: when, stopovers: true, - }) + }); await testJourneysWithDetour({ test: t, res, validate, detourIds: [donauinsel, donauinselPassed], - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys: via works – without detour', async (t) => { // When going from Karlsplatz to Praterstern via Museumsquartier, there is // *no need* to change trains / no need for a "detour". - const karlsplatz = '1390461' - const praterstern = '1290201' - const stephansplatz = '1390167' - const stephansplatzPassed = '901006' + const karlsplatz = '1390461'; + const praterstern = '1290201'; + const stephansplatz = '1390167'; + const stephansplatzPassed = '901006'; const res = await client.journeys(karlsplatz, praterstern, { via: stephansplatz, results: 1, departure: when, stopovers: true, - }) + }); - validate(t, res, 'journeysResult', 'res') + validate(t, res, 'journeysResult', 'res'); const l1 = res.journeys[0].legs.some((leg) => { return ( leg.destination.id === stephansplatz || leg.destination.id === stephansplatzPassed - ) - }) - t.notOk(l1, 'transfer at Museumsquartier') + ); + }); + t.notOk(l1, 'transfer at Museumsquartier'); const l2 = res.journeys[0].legs.some((leg) => { return leg.stopovers && leg.stopovers.some((stopover) => { - return stopover.stop.id === stephansplatzPassed - }) - }) - t.ok(l2, 'Museumsquartier is not being passed') + return stopover.stop.id === stephansplatzPassed; + }); + }); + t.ok(l2, 'Museumsquartier is not being passed'); - t.end() -}) + t.end(); +}); tap.test('earlier/later journeys, Salzburg Hbf -> Wien Westbahnhof', async (t) => { await testEarlierLaterJourneys({ @@ -212,10 +212,10 @@ tap.test('earlier/later journeys, Salzburg Hbf -> Wien Westbahnhof', async (t) = fromId: salzburgHbf, toId: wienWestbahnhof, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('refreshJourney', async (t) => { await testRefreshJourney({ @@ -226,45 +226,45 @@ tap.test('refreshJourney', async (t) => { fromId: salzburgHbf, toId: wienWestbahnhof, when, - }) - t.end() -}) + }); + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(wienWestbahnhof, muenchenHbf, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Wien Leibenfrostgasse', async (t) => { - const wienLeibenfrostgasse = '1390469' + const wienLeibenfrostgasse = '1390469'; const ids = [ wienLeibenfrostgasse, // station '904029', // stop "Wien Leibenfrostgasse (Phorusgasse)s" '904030', // stop "Wien Leibenfrostgasse (Ziegelofengasse)" - ] + ]; const res = await client.departures(wienLeibenfrostgasse, { duration: 15, when, - }) + }); await testDepartures({ test: t, res, validate, ids, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -276,16 +276,16 @@ tap.test('departures with station object', async (t) => { latitude: 1.23, longitude: 2.34, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('departures at Karlsplatz in direction of Pilgramgasse', async (t) => { const subStops = (await client.stop(wienPilgramgasse, { subStops: true, entrances: false, - })).stops || [] + })).stops || []; await testDeparturesInDirection({ test: t, @@ -295,9 +295,9 @@ tap.test('departures at Karlsplatz in direction of Pilgramgasse', async (t) => { directionIds: [wienPilgramgasse, ...subStops.map(s => s.id)], when, validate, - }) - t.end() -}) + }); + t.end(); +}); // todo: arrivals @@ -308,64 +308,64 @@ tap.test('nearby Salzburg Hbf', async (t) => { latitude: 47.812852, }, { results: 5, distance: 400, - }) + }); - validate(t, nearby, 'locations', 'nearby') - t.equal(nearby.length, 5) + validate(t, nearby, 'locations', 'nearby'); + t.equal(nearby.length, 5); - const s = nearby[0] - t.equal(s.id, salzburgHbf, 'id should be ' + salzburgHbf) - t.equal(s.name, 'Salzburg Hbf') - t.ok(isRoughlyEqual(0.0005, s.location.latitude, 47.812851)) - t.ok(isRoughlyEqual(0.0005, s.location.longitude, 13.045604)) - t.ok(s.distance >= 0) - t.ok(s.distance <= 100) + const s = nearby[0]; + t.equal(s.id, salzburgHbf, 'id should be ' + salzburgHbf); + t.equal(s.name, 'Salzburg Hbf'); + t.ok(isRoughlyEqual(0.0005, s.location.latitude, 47.812851)); + t.ok(isRoughlyEqual(0.0005, s.location.longitude, 13.045604)); + t.ok(s.distance >= 0); + t.ok(s.distance <= 100); - t.end() -}) + t.end(); +}); tap.test('locations named Salzburg', async (t) => { - const salzburgVolksgarten = '591161' + const salzburgVolksgarten = '591161'; const locations = await client.locations('Salzburg volksgarten', { results: 20, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs t.ok(locations.some((s) => { - return s.station && s.station.id === salzburgVolksgarten || s.id === salzburgVolksgarten - })) + return s.station && s.station.id === salzburgVolksgarten || s.id === salzburgVolksgarten; + })); - t.end() -}) + t.end(); +}); tap.test('stop', async (t) => { - const loc = await client.stop(wienRenngasse) + const loc = await client.stop(wienRenngasse); // todo: find a way to always get products from the API // todo: cfg.stationProductsOptional option - const {products} = oebbProfile - const allProducts = products.reduce((acc, p) => (acc[p.id] = true, acc), {}) - const validateStation = createValidateStation(cfg) + const {products} = oebbProfile; + const allProducts = products.reduce((acc, p) => (acc[p.id] = true, acc), {}); + const validateStation = createValidateStation(cfg); const validate = createValidate(cfg, { stop: (validate, s, name) => { - const withFakeProducts = Object.assign({products: allProducts}, s) - _validateStop(validate, withFakeProducts, name) + const withFakeProducts = Object.assign({products: allProducts}, s); + _validateStop(validate, withFakeProducts, name); }, station: (validate, s, name) => { - const withFakeProducts = Object.assign({products: allProducts}, s) - validateStation(validate, withFakeProducts, name) + const withFakeProducts = Object.assign({products: allProducts}, s); + validateStation(validate, withFakeProducts, name); }, - }) - validate(t, loc, ['stop', 'station'], 'stop') + }); + validate(t, loc, ['stop', 'station'], 'stop'); - t.equal(loc.id, wienRenngasse) + t.equal(loc.id, wienRenngasse); - t.end() -}) + t.end(); +}); tap.test('radar Salzburg', async (t) => { let res = await client.radar({ @@ -375,20 +375,20 @@ tap.test('radar Salzburg', async (t) => { east: 13.07562, }, { duration: 5 * 60, when, - }) + }); // todo: find a way to always get frames from the API - res.movements = res.movements.filter(m => m.frames && m.frames.length > 0) + res.movements = res.movements.filter(m => m.frames && m.frames.length > 0); // todo: find a way to always get products from the API // todo: cfg.stationProductsOptional option - const {products} = oebbProfile - const allProducts = products.reduce((acc, p) => (acc[p.id] = true, acc), {}) - const validateStation = createValidateStation(cfg) + const {products} = oebbProfile; + const allProducts = products.reduce((acc, p) => (acc[p.id] = true, acc), {}); + const validateStation = createValidateStation(cfg); const validate = createValidate(cfg, { station: (validate, s, name) => { - const withFakeProducts = Object.assign({products: allProducts}, s) - validateStation(validate, withFakeProducts, name) + const withFakeProducts = Object.assign({products: allProducts}, s); + validateStation(validate, withFakeProducts, name); }, line: (val, line, name = 'line') => { validateLine(val, { @@ -397,10 +397,10 @@ tap.test('radar Salzburg', async (t) => { mode: line.mode === null ? 'bus' : line.mode, - }, name) + }, name); }, - }) - validate(t, res, 'radarResult', 'res') + }); + validate(t, res, 'radarResult', 'res'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/ooevv.js b/test/e2e/ooevv.js index 56f451125..cef3dbefe 100644 --- a/test/e2e/ooevv.js +++ b/test/e2e/ooevv.js @@ -1,12 +1,12 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as oövvProfile} from '../../p/ooevv/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as oövvProfile} from '../../p/ooevv/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(oövvProfile.timezone, oövvProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(oövvProfile.timezone, oövvProfile.locale, T_MOCK); const cfg = { when, @@ -16,20 +16,20 @@ const cfg = { maxLongitude: 17.0892, minLatitude: 45.7206, minLongitude: 7.8635, -} -const validate = createValidate(cfg) +}; +const validate = createValidate(cfg); -const client = createClient(oövvProfile, 'public-transport/hafas-client:test') +const client = createClient(oövvProfile, 'public-transport/hafas-client:test'); -const linzTheatergasse = '444670100' +const linzTheatergasse = '444670100'; tap.test('locations named "theatergasse"', async (t) => { - const locations = await client.locations('theatergasse') + const locations = await client.locations('theatergasse'); - validate(t, locations, 'locations', 'locations') + validate(t, locations, 'locations', 'locations'); t.ok(locations.some((l) => { - return l.station && l.station.id === linzTheatergasse || l.id === linzTheatergasse - }), 'Linz Theatergasse not found') + return l.station && l.station.id === linzTheatergasse || l.id === linzTheatergasse; + }), 'Linz Theatergasse not found'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/pkp.js b/test/e2e/pkp.js index 173f0c4b5..1d703acf0 100644 --- a/test/e2e/pkp.js +++ b/test/e2e/pkp.js @@ -1,20 +1,20 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as pkpProfile} from '../../p/pkp/index.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as pkpProfile} from '../../p/pkp/index.js'; import { createValidateLine, createValidateJourneyLeg, createValidateMovement, -} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testArrivals} from './lib/arrivals.js' -import {testReachableFrom} from './lib/reachable-from.js' +} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testReachableFrom} from './lib/reachable-from.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(pkpProfile.timezone, pkpProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(pkpProfile.timezone, pkpProfile.locale, T_MOCK); const cfg = { when, @@ -24,48 +24,48 @@ const cfg = { maxLatitude: 65, minLongitude: 10, maxLongitude: 30, -} +}; -const _validateLine = createValidateLine(cfg) +const _validateLine = createValidateLine(cfg); const validateLine = (validate, l, name) => { if (!l.direction) { - l = Object.assign({}, l, {direction: 'foo'}) + l = Object.assign({}, l, {direction: 'foo'}); } - _validateLine(validate, l, name) -} + _validateLine(validate, l, name); +}; -const _validateJourneyLeg = createValidateJourneyLeg(cfg) +const _validateJourneyLeg = createValidateJourneyLeg(cfg); const validateJourneyLeg = (validate, l, name) => { if (!l.direction) { - l = Object.assign({}, l, {direction: 'foo'}) + l = Object.assign({}, l, {direction: 'foo'}); } - _validateJourneyLeg(validate, l, name) -} + _validateJourneyLeg(validate, l, name); +}; -const _validateMovement = createValidateMovement(cfg) +const _validateMovement = createValidateMovement(cfg); const validateMovement = (val, m, name) => { if (!m.direction) { - m = Object.assign({}, m, {direction: 'foo'}) + m = Object.assign({}, m, {direction: 'foo'}); } - _validateMovement(val, m, name) -} + _validateMovement(val, m, name); +}; const validate = createValidate(cfg, { line: validateLine, journeyLeg: validateJourneyLeg, movement: validateMovement, -}) +}); -const client = createClient(pkpProfile, 'public-transport/hafas-client:test') +const client = createClient(pkpProfile, 'public-transport/hafas-client:test'); -const wrocławGł = '5100069' -const krakówGł = '5100028' +const wrocławGł = '5100069'; +const krakówGł = '5100028'; const dworcowa100 = { type: 'location', address: 'Bydgoszcz, Dworcowa 100', latitude: 53.1336648, longitude: 17.9908571, -} +}; const filharmonia = { type: 'location', id: '980013218', @@ -73,14 +73,14 @@ const filharmonia = { longitude: 18.659548, name: 'Gdańsk, Filharmonia', poi: true, -} +}; tap.skip('journeys – Wrocław Główny to Kraków Główny', async (t) => { const res = await client.journeys(wrocławGł, krakówGł, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -88,9 +88,9 @@ tap.skip('journeys – Wrocław Główny to Kraków Główny', async (t) => { validate, fromId: wrocławGł, toId: krakówGł, - }) - t.end() -}) + }); + t.end(); +}); // todo: via works – with detour // todo: without detour @@ -98,41 +98,41 @@ tap.skip('journeys – Wrocław Główny to Kraków Główny', async (t) => { tap.skip('trip details', async (t) => { const res = await client.journeys(wrocławGł, krakówGł, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.skip('arrivals at Kraków Główny', async (t) => { const arrivals = await client.arrivals(krakówGł, { duration: 10, when, - }) + }); await testArrivals({ test: t, arrivals, id: krakówGł, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.skip('nearby', async (t) => { - const nearby = await client.nearby(dworcowa100, {distance: 500}) + const nearby = await client.nearby(dworcowa100, {distance: 500}); - validate(t, nearby, 'locations', 'nearby') + validate(t, nearby, 'locations', 'nearby'); - const bydgoszczGł = '5100005' - t.ok(nearby.find(l => l.id === bydgoszczGł)) + const bydgoszczGł = '5100005'; + t.ok(nearby.find(l => l.id === bydgoszczGł)); - t.end() -}) + t.end(); +}); tap.skip('radar', async (t) => { const res = await client.radar({ @@ -142,11 +142,11 @@ tap.skip('radar', async (t) => { east: 11.43733, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.skip('reachableFrom', async (t) => { await testReachableFrom({ @@ -156,6 +156,6 @@ tap.skip('reachableFrom', async (t) => { when, maxDuration: 20, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/rejseplanen.js b/test/e2e/rejseplanen.js index 82549e00e..bbd7ff196 100644 --- a/test/e2e/rejseplanen.js +++ b/test/e2e/rejseplanen.js @@ -1,19 +1,19 @@ -import tap from 'tap' -import assert from 'assert' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as rejseplanenProfile} from '../../p/rejseplanen/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testDepartures} from './lib/departures.js' -import {testArrivals} from './lib/arrivals.js' - -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(rejseplanenProfile.timezone, rejseplanenProfile.locale, T_MOCK) +import tap from 'tap'; +import assert from 'assert'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as rejseplanenProfile} from '../../p/rejseplanen/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testDepartures} from './lib/departures.js'; +import {testArrivals} from './lib/arrivals.js'; + +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(rejseplanenProfile.timezone, rejseplanenProfile.locale, T_MOCK); const validate = createValidate({ when, @@ -22,20 +22,20 @@ const validate = createValidate({ maxLatitude: 58.85, minLongitude: 5.8, maxLongitude: 15.7, -}, {}) +}, {}); -const client = createClient(rejseplanenProfile, 'public-transport/hafas-client:test') +const client = createClient(rejseplanenProfile, 'public-transport/hafas-client:test'); -const næstved = '8600810' -const randers = '8600040' -const aalborg = '8600020' +const næstved = '8600810'; +const randers = '8600040'; +const aalborg = '8600020'; tap.test('journeys – Næstved to Aalborg', async (t) => { const res = await client.journeys(næstved, aalborg, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -43,9 +43,9 @@ tap.test('journeys – Næstved to Aalborg', async (t) => { validate, fromId: næstved, toId: aalborg, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -57,9 +57,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: aalborg, when, products: rejseplanenProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Randers to Møllegade 3, København', async (t) => { const møllegade3 = { @@ -67,12 +67,12 @@ tap.test('Randers to Møllegade 3, København', async (t) => { id: '901011579', address: 'Møllegade 3, 2200 København N, Københavns Kommune', latitude: 55.69052, longitude: 12.555494, - } + }; const res = await client.journeys(randers, møllegade3, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -80,9 +80,9 @@ tap.test('Randers to Møllegade 3, København', async (t) => { validate, fromId: randers, to: møllegade3, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys: via works – with detour // todo: without detour @@ -95,30 +95,30 @@ tap.test('earlier/later journeys', async (t) => { fromId: randers, toId: næstved, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('trip', async (t) => { const {journeys} = await client.journeys(aalborg, næstved, { results: 1, departure: when, - }) + }); - const p = journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Næstved.', async (t) => { const res = await client.departures(næstved, { duration: 20, when, - }) + }); await testDepartures({ test: t, @@ -129,14 +129,14 @@ tap.test('departures at Næstved.', async (t) => { '8650810', // Næstved St. (togbus) '8651810', // Næstved St. (togbus) ], - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Næstved.', async (t) => { const res = await client.arrivals(næstved, { duration: 20, when, - }) + }); await testArrivals({ test: t, @@ -147,40 +147,40 @@ tap.test('arrivals at Næstved.', async (t) => { '8650810', // Næstved St. (togbus) '8651810', // Næstved St. (togbus) ], - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby tap.test('locations named "næstved"', async (t) => { const locations = await client.locations('næstved', { results: 20, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); t.ok(locations.some((loc) => { if (loc.station && loc.station.id === næstved) { - return true + return true; } - return loc.id === næstved - })) + return loc.id === næstved; + })); - t.end() -}) + t.end(); +}); tap.test('stop Næstved', async (t) => { - const s = await client.stop(næstved) + const s = await client.stop(næstved); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, næstved) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, næstved); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -190,8 +190,8 @@ tap.test('radar', async (t) => { east: 12.621, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); diff --git a/test/e2e/rmv.js b/test/e2e/rmv.js index 4ea3e9abe..109f85e8a 100644 --- a/test/e2e/rmv.js +++ b/test/e2e/rmv.js @@ -1,15 +1,15 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as rmvProfile} from '../../p/rmv/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testArrivals} from './lib/arrivals.js' -import {testReachableFrom} from './lib/reachable-from.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as rmvProfile} from '../../p/rmv/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testReachableFrom} from './lib/reachable-from.js'; -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(rmvProfile.timezone, rmvProfile.locale, T_MOCK) +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(rmvProfile.timezone, rmvProfile.locale, T_MOCK); const cfg = { when, @@ -19,21 +19,21 @@ const cfg = { maxLatitude: 54, minLongitude: 6, maxLongitude: 11, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(rmvProfile, 'public-transport/hafas-client:test') +const client = createClient(rmvProfile, 'public-transport/hafas-client:test'); -const frankfurtOstendstr = '3000525' -const wiesbadenHbf = '3006907' +const frankfurtOstendstr = '3000525'; +const wiesbadenHbf = '3006907'; tap.test('journeys – Frankfurt Ostendstr. to Wiesbaden Hbf', async (t) => { const res = await client.journeys(frankfurtOstendstr, wiesbadenHbf, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -41,9 +41,9 @@ tap.test('journeys – Frankfurt Ostendstr. to Wiesbaden Hbf', async (t) => { validate, fromId: frankfurtOstendstr, toId: wiesbadenHbf, - }) - t.end() -}) + }); + t.end(); +}); // todo: via works – with detour // todo: without detour @@ -51,31 +51,31 @@ tap.test('journeys – Frankfurt Ostendstr. to Wiesbaden Hbf', async (t) => { tap.test('trip details', async (t) => { const res = await client.journeys(frankfurtOstendstr, wiesbadenHbf, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('arrivals at Wiesbaden Hbf', async (t) => { const res = await client.arrivals(wiesbadenHbf, { duration: 10, when, - }) + }); await testArrivals({ test: t, res, validate, id: wiesbadenHbf, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby @@ -87,11 +87,11 @@ tap.test('radar', async (t) => { east: 8.847423, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.test('reachableFrom', async (t) => { await testReachableFrom({ @@ -107,6 +107,6 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/rsag.js b/test/e2e/rsag.js index 479091bdb..a21b4e195 100644 --- a/test/e2e/rsag.js +++ b/test/e2e/rsag.js @@ -1,17 +1,17 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as rsagProfile} from '../../p/rsag/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {testArrivals} from './lib/arrivals.js' -import {testReachableFrom} from './lib/reachable-from.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as rsagProfile} from '../../p/rsag/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testReachableFrom} from './lib/reachable-from.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(rsagProfile.timezone, rsagProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(rsagProfile.timezone, rsagProfile.locale, T_MOCK); const cfg = { when, @@ -21,22 +21,22 @@ const cfg = { maxLatitude: 54.862, minLongitude: 9.121, maxLongitude: 14.824, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(rsagProfile, 'public-transport/hafas-client:test') +const client = createClient(rsagProfile, 'public-transport/hafas-client:test'); -const sternwarte = '704956' -const sternwarte2 = '708539' -const weißesKreuz = '708573' +const sternwarte = '704956'; +const sternwarte2 = '708539'; +const weißesKreuz = '708573'; tap.test('journeys – Platz der Jugend to Weißes Kreuz', async (t) => { const res = await client.journeys(sternwarte, weißesKreuz, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -44,9 +44,9 @@ tap.test('journeys – Platz der Jugend to Weißes Kreuz', async (t) => { validate, fromIds: [sternwarte, sternwarte2], toId: weißesKreuz, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, walkingSpeed // todo: via works – with detour @@ -59,10 +59,10 @@ tap.test('earlier/later journeys', async (t) => { fromId: sternwarte, toId: weißesKreuz, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('refreshJourney', async (t) => { await testRefreshJourney({ @@ -73,14 +73,14 @@ tap.test('refreshJourney', async (t) => { fromId: sternwarte, toId: weißesKreuz, when, - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Platz der Jugend', async (t) => { const res = await client.arrivals(sternwarte, { duration: 30, when, - }) + }); await testArrivals({ test: t, @@ -90,9 +90,9 @@ tap.test('arrivals at Platz der Jugend', async (t) => { sternwarte, '708539', // Rostock Sternwarte ], - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby @@ -104,11 +104,11 @@ tap.test('radar', async (t) => { east: 12.203261, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.test('reachableFrom', async (t) => { await testReachableFrom({ @@ -123,6 +123,6 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/saarfahrplan.js b/test/e2e/saarfahrplan.js index 995ea7aca..bfac419c0 100644 --- a/test/e2e/saarfahrplan.js +++ b/test/e2e/saarfahrplan.js @@ -1,25 +1,25 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as saarfahrplanProfile} from '../../p/saarfahrplan/index.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as saarfahrplanProfile} from '../../p/saarfahrplan/index.js'; import { createValidateStation, createValidateStop, -} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testJourneysWithDetour} from './lib/journeys-with-detour.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' - -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(saarfahrplanProfile.timezone, saarfahrplanProfile.locale, T_MOCK) +} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testJourneysWithDetour} from './lib/journeys-with-detour.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; + +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(saarfahrplanProfile.timezone, saarfahrplanProfile.locale, T_MOCK); const cfg = { when, @@ -29,39 +29,39 @@ const cfg = { maxLatitude: 49.6, minLongitude: 6.1, maxLongitude: 7.5, -} +}; // @todo validateDirection: search list of stations for direction -const validate = createValidate(cfg) +const validate = createValidate(cfg); const assertValidPrice = (t, p) => { - t.ok(p) + t.ok(p); if (p.amount !== null) { - t.equal(typeof p.amount, 'number') - t.ok(p.amount > 0) + t.equal(typeof p.amount, 'number'); + t.ok(p.amount > 0); } if (p.hint !== null) { - t.equal(typeof p.hint, 'string') - t.ok(p.hint) + t.equal(typeof p.hint, 'string'); + t.ok(p.hint); } -} +}; -const client = createClient(saarfahrplanProfile, 'public-transport/hafas-client:test') +const client = createClient(saarfahrplanProfile, 'public-transport/hafas-client:test'); -const saarbrueckenHbf = '8000323' +const saarbrueckenHbf = '8000323'; // This seems to be the bus/tram stop. 🙄 -const hauptbahnhofSaarbruecken = '10600' -const saarlouisHbf = '8005247' -const metzVille = '8700019' -const saarbrueckenUhlandstr = '10609' +const hauptbahnhofSaarbruecken = '10600'; +const saarlouisHbf = '8005247'; +const metzVille = '8700019'; +const saarbrueckenUhlandstr = '10609'; const thomasMannStr = { type: 'location', address: 'Neunkirchen, Thomas-Mann-Straße 1', latitude: 49.348307, longitude: 7.183613, -} +}; // @todo prices/tickets // @todo journeys, only one product @@ -74,15 +74,15 @@ tap.test('journeys – fails with no product', async (t) => { toId: saarlouisHbf, when, products: saarfahrplanProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Saarbrücken Hbf to Neunkirchen, Thomas-Mann-Straße 1', async (t) => { const res = await client.journeys(saarbrueckenHbf, thomasMannStr, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -90,9 +90,9 @@ tap.test('Saarbrücken Hbf to Neunkirchen, Thomas-Mann-Straße 1', async (t) => validate, fromId: saarbrueckenHbf, to: thomasMannStr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Saarbrücken Hbf to Schlossberghöhlen', async (t) => { const schlossberghoehlen = { @@ -102,10 +102,10 @@ tap.test('Saarbrücken Hbf to Schlossberghöhlen', async (t) => { name: 'Homburg, Schlossberghöhlen', latitude: 49.32071, longitude: 7.343764, - } + }; const res = await client.journeys(saarbrueckenHbf, schlossberghoehlen, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -113,31 +113,31 @@ tap.test('Saarbrücken Hbf to Schlossberghöhlen', async (t) => { validate, fromId: saarbrueckenHbf, to: schlossberghoehlen, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys: via works – with detour', async (t) => { // Going from Lessingstr. to An der Trift via Steubenstr. without detour // is currently impossible. We check if the routing engine computes a detour. - const lessingstr = '10615' - const anDerTrift = '10801' - const steubenstr = '10051' + const lessingstr = '10615'; + const anDerTrift = '10801'; + const steubenstr = '10051'; const res = await client.journeys(lessingstr, anDerTrift, { via: steubenstr, results: 1, departure: when, stopovers: true, - }) + }); await testJourneysWithDetour({ test: t, res, validate, detourIds: [steubenstr], - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys: via works – without detour @@ -149,39 +149,39 @@ tap.test('earlier/later journeys, Saarbrücken Hbf -> Saarlouis Hbf', async (t) fromId: saarbrueckenHbf, toId: saarlouisHbf, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(saarlouisHbf, metzVille, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures', async (t) => { const res = await client.departures(saarbrueckenUhlandstr, { duration: 5, when, - }) + }); await testDepartures({ test: t, res, validate, id: saarbrueckenUhlandstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with stop object', async (t) => { const res = await client.departures({ @@ -193,14 +193,14 @@ tap.test('departures with stop object', async (t) => { latitude: 49.241066, longitude: 6.991019, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('departures at Uhlandstr., Saarbrücken in direction of Landwehrplatz', async (t) => { - const saarbrueckenLandwehrplatz = '10606' + const saarbrueckenLandwehrplatz = '10606'; await testDeparturesInDirection({ test: t, fetchDepartures: client.departures, @@ -209,9 +209,9 @@ tap.test('departures at Uhlandstr., Saarbrücken in direction of Landwehrplatz', directionIds: [saarbrueckenLandwehrplatz], when, validate, - }) - t.end() -}) + }); + t.end(); +}); // todo: arrivals @@ -222,48 +222,48 @@ tap.test('nearby Saarbrücken Hbf', async (t) => { longitude: 6.991019, }, { results: 5, distance: 400, - }) + }); - validate(t, nearby, 'locations', 'nearby') - t.equal(nearby.length, 5) + validate(t, nearby, 'locations', 'nearby'); + t.equal(nearby.length, 5); - const s = nearby[0] - t.equal(s.id, saarbrueckenHbf, 'id should be ' + saarbrueckenHbf) - t.equal(s.name, 'Saarbrücken Hbf') - t.ok(isRoughlyEqual(0.0005, s.location.latitude, 49.241066)) - t.ok(isRoughlyEqual(0.0005, s.location.longitude, 6.991019)) - t.ok(s.distance >= 0) - t.ok(s.distance <= 100) + const s = nearby[0]; + t.equal(s.id, saarbrueckenHbf, 'id should be ' + saarbrueckenHbf); + t.equal(s.name, 'Saarbrücken Hbf'); + t.ok(isRoughlyEqual(0.0005, s.location.latitude, 49.241066)); + t.ok(isRoughlyEqual(0.0005, s.location.longitude, 6.991019)); + t.ok(s.distance >= 0); + t.ok(s.distance <= 100); - t.end() -}) + t.end(); +}); tap.test('locations named Saarbrücken', async (t) => { - const aufDerWerthBürgerpark = '10204' + const aufDerWerthBürgerpark = '10204'; const locations = await client.locations('bürgerpark', { results: 20, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs t.ok(locations.some((s) => { - return s.station && s.station.id === aufDerWerthBürgerpark || s.id === aufDerWerthBürgerpark - })) + return s.station && s.station.id === aufDerWerthBürgerpark || s.id === aufDerWerthBürgerpark; + })); - t.end() -}) + t.end(); +}); tap.test('stop', async (t) => { - const s = await client.stop(saarbrueckenUhlandstr) + const s = await client.stop(saarbrueckenUhlandstr); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, saarbrueckenUhlandstr) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, saarbrueckenUhlandstr); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -273,8 +273,8 @@ tap.test('radar', async (t) => { east: 7.02, }, { duration: 5 * 60, when, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); diff --git a/test/e2e/salzburg.js b/test/e2e/salzburg.js index 0aadef9d7..7ebbe5853 100644 --- a/test/e2e/salzburg.js +++ b/test/e2e/salzburg.js @@ -1,12 +1,12 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as salzburgProfile} from '../../p/salzburg/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as salzburgProfile} from '../../p/salzburg/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(salzburgProfile.timezone, salzburgProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(salzburgProfile.timezone, salzburgProfile.locale, T_MOCK); const cfg = { when, @@ -16,20 +16,20 @@ const cfg = { maxLongitude: 17.0892, minLatitude: 45.7206, minLongitude: 7.8635, -} -const validate = createValidate(cfg) +}; +const validate = createValidate(cfg); -const client = createClient(salzburgProfile, 'public-transport/hafas-client:test') +const client = createClient(salzburgProfile, 'public-transport/hafas-client:test'); -const salzburgGaswerkgasse = '455001300' +const salzburgGaswerkgasse = '455001300'; tap.test('locations named "gaswerkgasse"', async (t) => { - const locations = await client.locations('gaswerkgasse') + const locations = await client.locations('gaswerkgasse'); - validate(t, locations, 'locations', 'locations') + validate(t, locations, 'locations', 'locations'); t.ok(locations.some((l) => { - return l.station && l.station.id === salzburgGaswerkgasse || l.id === salzburgGaswerkgasse - }), 'Salzburg Gaswerkgasse not found') + return l.station && l.station.id === salzburgGaswerkgasse || l.id === salzburgGaswerkgasse; + }), 'Salzburg Gaswerkgasse not found'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/sbahn-muenchen.js b/test/e2e/sbahn-muenchen.js index b431bb416..624cc4a42 100644 --- a/test/e2e/sbahn-muenchen.js +++ b/test/e2e/sbahn-muenchen.js @@ -1,23 +1,23 @@ -import tap from 'tap' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as sMunichProfile} from '../../p/sbahn-muenchen/index.js' -import {createValidateMovement as _createValidateMovement} from './lib/validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testArrivals} from './lib/arrivals.js' -import {testJourneysWithDetour} from './lib/journeys-with-detour.js' -import {testReachableFrom} from './lib/reachable-from.js' - -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(sMunichProfile.timezone, sMunichProfile.locale, T_MOCK) +import tap from 'tap'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as sMunichProfile} from '../../p/sbahn-muenchen/index.js'; +import {createValidateMovement as _createValidateMovement} from './lib/validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testJourneysWithDetour} from './lib/journeys-with-detour.js'; +import {testReachableFrom} from './lib/reachable-from.js'; + +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(sMunichProfile.timezone, sMunichProfile.locale, T_MOCK); const cfg = { when, @@ -27,44 +27,44 @@ const cfg = { maxLatitude: 48.3, minLongitude: 11.3, maxLongitude: 11.8, -} +}; -const _validateMovement = _createValidateMovement(cfg) +const _validateMovement = _createValidateMovement(cfg); const validateMovement = (val, m, name = 'movement') => { - const dummyStopA = {type: 'stop', id: '123'} - const dummyStopB = {type: 'stop', id: '321'} + const dummyStopA = {type: 'stop', id: '123'}; + const dummyStopB = {type: 'stop', id: '321'}; - const withFakeFrame = Object.assign({}, m) + const withFakeFrame = Object.assign({}, m); if (!m.frames.length) { withFakeFrame.frames = [ {t: 5, origin: dummyStopA, destination: dummyStopB}, - ] + ]; } - _validateMovement(val, withFakeFrame, name) -} + _validateMovement(val, withFakeFrame, name); +}; const validate = createValidate(cfg, { movement: validateMovement, -}) +}); -const client = createClient(sMunichProfile, 'public-transport/hafas-client:test') +const client = createClient(sMunichProfile, 'public-transport/hafas-client:test'); -const mittersendling = '8004154' -const karlTheodorStr = '638842' // Karl-Theodor-Straße -const lehel = '624826' +const mittersendling = '8004154'; +const karlTheodorStr = '638842'; // Karl-Theodor-Straße +const lehel = '624826'; const poetschnerstr = { type: 'location', address: 'Pötschnerstraße 3, Neuhausen', latitude: 48.152499, longitude: 11.531695, -} +}; tap.test('journeys – Mittersendling to Karl-Theodor-Straße', async (t) => { const res = await client.journeys(mittersendling, karlTheodorStr, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -72,9 +72,9 @@ tap.test('journeys – Mittersendling to Karl-Theodor-Straße', async (t) => { validate, fromId: mittersendling, toId: karlTheodorStr, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -86,15 +86,15 @@ tap.test('journeys – fails with no product', async (t) => { toId: karlTheodorStr, when, products: sMunichProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Karl-Theodor-Straße to Pötschnerstraße 3, Neuhausen', async (t) => { const res = await client.journeys(karlTheodorStr, poetschnerstr, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -102,9 +102,9 @@ tap.test('Karl-Theodor-Straße to Pötschnerstraße 3, Neuhausen', async (t) => validate, fromId: karlTheodorStr, to: poetschnerstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Karl-Theodor-Straße to Hofbräuhaus', async (t) => { const hofbraeuhaus = { @@ -114,11 +114,11 @@ tap.test('Karl-Theodor-Straße to Hofbräuhaus', async (t) => { name: 'München, Hofbräuhaus München', latitude: 48.137739, longitude: 11.579823, - } + }; const res = await client.journeys(karlTheodorStr, hofbraeuhaus, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -126,9 +126,9 @@ tap.test('Karl-Theodor-Straße to Hofbräuhaus', async (t) => { validate, fromId: karlTheodorStr, to: hofbraeuhaus, - }) - t.end() -}) + }); + t.end(); +}); // todo: walkingSpeed "München - Freimann, Gyßlingstraße 78" -> lehel // todo: via works – with detour @@ -142,10 +142,10 @@ tap.test('earlier/later journeys', async (t) => { fromId: mittersendling, toId: karlTheodorStr, when, - }) + }); - t.end() -}) + t.end(); +}); // todo: for some reason, a leg is missing in the journey returned by refreshJourney() tap.skip('refreshJourney', async (t) => { @@ -157,39 +157,39 @@ tap.skip('refreshJourney', async (t) => { fromId: mittersendling, toId: karlTheodorStr, when, - }) - t.end() -}) + }); + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(mittersendling, karlTheodorStr, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Dietlindenstraße', async (t) => { - const dietlindenstr = '624391' + const dietlindenstr = '624391'; const res = await client.departures(dietlindenstr, { duration: 10, when, - }) + }); await testDepartures({ test: t, res, validate, id: dietlindenstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -201,54 +201,54 @@ tap.test('departures with station object', async (t) => { latitude: 48.107418, longitude: 11.536306, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('arrivals at Karl-Theodor-Straße', async (t) => { const res = await client.arrivals(karlTheodorStr, { duration: 10, when, - }) + }); await testArrivals({ test: t, res, validate, id: karlTheodorStr, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby tap.test('locations named "Nationaltheater"', async (t) => { - const nationaltheater = '624639' + const nationaltheater = '624639'; const locations = await client.locations('Nationaltheater', { results: 10, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 10) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 10); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs t.ok(locations.some((l) => { - return l.station && l.station.id === nationaltheater || l.id === nationaltheater - })) + return l.station && l.station.id === nationaltheater || l.id === nationaltheater; + })); - t.end() -}) + t.end(); +}); tap.test('station Karl-Theodor-Straße', async (t) => { - const s = await client.stop(karlTheodorStr) + const s = await client.stop(karlTheodorStr); - validate(t, s, ['stop', 'station'], 'station') - t.equal(s.id, karlTheodorStr) + validate(t, s, ['stop', 'station'], 'station'); + t.equal(s.id, karlTheodorStr); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -258,11 +258,11 @@ tap.test('radar', async (t) => { east: 11.553776, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.test('reachableFrom', async (t) => { await testReachableFrom({ @@ -272,6 +272,6 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/sncb.js b/test/e2e/sncb.js index 1fd589684..6a2c82128 100644 --- a/test/e2e/sncb.js +++ b/test/e2e/sncb.js @@ -1,15 +1,15 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as sncbProfile} from '../../p/sncb/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testArrivals} from './lib/arrivals.js' -import {testReachableFrom} from './lib/reachable-from.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as sncbProfile} from '../../p/sncb/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testReachableFrom} from './lib/reachable-from.js'; -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(sncbProfile.timezone, sncbProfile.locale, T_MOCK) +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(sncbProfile.timezone, sncbProfile.locale, T_MOCK); const cfg = { when, @@ -19,26 +19,26 @@ const cfg = { maxLatitude: 54.521, minLongitude: -1.423, maxLongitude: 15.26, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(sncbProfile, 'public-transport/hafas-client:test') +const client = createClient(sncbProfile, 'public-transport/hafas-client:test'); -const gentStPieters = '8892007' -const bruxellesMidi = '8814001' +const gentStPieters = '8892007'; +const bruxellesMidi = '8814001'; const gentPaddenhoek = { type: 'location', address: 'Gent, Paddenhoek', latitude: 51.051691, longitude: 3.724914, -} +}; tap.skip('journeys – Gent Sant Pieters to Bruxelles Midi', async (t) => { const res = await client.journeys(gentStPieters, bruxellesMidi, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -46,9 +46,9 @@ tap.skip('journeys – Gent Sant Pieters to Bruxelles Midi', async (t) => { validate, fromId: gentStPieters, toId: bruxellesMidi, - }) - t.end() -}) + }); + t.end(); +}); // todo: via works – with detour // todo: without detour @@ -56,31 +56,31 @@ tap.skip('journeys – Gent Sant Pieters to Bruxelles Midi', async (t) => { tap.skip('trip details', async (t) => { const res = await client.journeys(gentStPieters, bruxellesMidi, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.skip('arrivals at Bruxelles Midi', async (t) => { const res = await client.arrivals(bruxellesMidi, { duration: 10, when, - }) + }); await testArrivals({ test: t, res, validate, id: bruxellesMidi, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby @@ -92,11 +92,11 @@ tap.skip('radar', async (t) => { east: 3.748, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.skip('reachableFrom', async (t) => { await testReachableFrom({ @@ -106,6 +106,6 @@ tap.skip('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/stv.js b/test/e2e/stv.js index 953f78ebf..5c176fe8c 100644 --- a/test/e2e/stv.js +++ b/test/e2e/stv.js @@ -1,12 +1,12 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as stvProfile} from '../../p/stv/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as stvProfile} from '../../p/stv/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(stvProfile.timezone, stvProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(stvProfile.timezone, stvProfile.locale, T_MOCK); const cfg = { when, @@ -16,20 +16,20 @@ const cfg = { maxLongitude: 18.347, minLatitude: 46.127, minLongitude: 7.8635, -} -const validate = createValidate(cfg) +}; +const validate = createValidate(cfg); -const client = createClient(stvProfile, 'public-transport/hafas-client:test') +const client = createClient(stvProfile, 'public-transport/hafas-client:test'); -const grazSonnenhang = '460413500' +const grazSonnenhang = '460413500'; tap.test('locations named "sonnenhang"', async (t) => { - const locations = await client.locations('sonnenhang') + const locations = await client.locations('sonnenhang'); - validate(t, locations, 'locations', 'locations') + validate(t, locations, 'locations', 'locations'); t.ok(locations.some((l) => { - return l.station && l.station.id === grazSonnenhang || l.id === grazSonnenhang - }), 'Graz Sonnenhang not found') + return l.station && l.station.id === grazSonnenhang || l.id === grazSonnenhang; + }), 'Graz Sonnenhang not found'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/svv.js b/test/e2e/svv.js index 921aaf4cd..40d6213ec 100644 --- a/test/e2e/svv.js +++ b/test/e2e/svv.js @@ -1,16 +1,16 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as svvProfile} from '../../p/svv/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testArrivals} from './lib/arrivals.js' -import {testReachableFrom} from './lib/reachable-from.js' -import {testServerInfo} from './lib/server-info.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as svvProfile} from '../../p/svv/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testReachableFrom} from './lib/reachable-from.js'; +import {testServerInfo} from './lib/server-info.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(svvProfile.timezone, svvProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(svvProfile.timezone, svvProfile.locale, T_MOCK); const cfg = { when, @@ -20,27 +20,27 @@ const cfg = { maxLatitude: 49.41, minLongitude: 8.177, maxLongitude: 18.448, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(svvProfile, 'public-transport/hafas-client:test') +const client = createClient(svvProfile, 'public-transport/hafas-client:test'); -const sam = '455086100' -const volksgarten = '455082100' +const sam = '455086100'; +const volksgarten = '455082100'; const zillnerstr2 = { type: 'location', id: '980133209', address: 'Zillnerstraße 2, 5020 Salzburg', latitude: 47.801434, longitude: 13.031006, -} +}; tap.test('journeys – Sam to Volksgarten', async (t) => { const res = await client.journeys(sam, volksgarten, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -48,9 +48,9 @@ tap.test('journeys – Sam to Volksgarten', async (t) => { validate, fromId: sam, toId: volksgarten, - }) - t.end() -}) + }); + t.end(); +}); // todo: via works – with detour // todo: without detour @@ -58,31 +58,31 @@ tap.test('journeys – Sam to Volksgarten', async (t) => { tap.test('trip details', async (t) => { const res = await client.journeys(sam, volksgarten, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('arrivals at Volksgarten', async (t) => { const res = await client.arrivals(volksgarten, { duration: 10, when, - }) + }); await testArrivals({ test: t, res, validate, id: volksgarten, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby @@ -94,13 +94,13 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('serverInfo works', async (t) => { await testServerInfo({ test: t, fetchServerInfo: client.serverInfo, - }) -}) + }); +}); diff --git a/test/e2e/tpg.js b/test/e2e/tpg.js index 8adaedb7e..64126f953 100644 --- a/test/e2e/tpg.js +++ b/test/e2e/tpg.js @@ -1,13 +1,13 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as tpgProfile} from '../../p/tpg/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as tpgProfile} from '../../p/tpg/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(tpgProfile.timezone, tpgProfile.locale, T_MOCK) +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(tpgProfile.timezone, tpgProfile.locale, T_MOCK); const cfg = { when, @@ -17,13 +17,13 @@ const cfg = { minLongitude: 4.4604, maxLatitude: 47.2969, maxLongitude: 7.8607, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(tpgProfile, 'public-transport/hafas-client:test') +const client = createClient(tpgProfile, 'public-transport/hafas-client:test'); -const moillebeau = '100451' +const moillebeau = '100451'; tap.test('Moillebeau to Cours des Bastions 10', async (t) => { const coursDesBastions10 = { @@ -32,12 +32,12 @@ tap.test('Moillebeau to Cours des Bastions 10', async (t) => { address: 'Cours des Bastions 10, 1205 Genève', latitude: 46.197768, longitude: 6.148046, - } + }; const res = await client.journeys(moillebeau, coursDesBastions10, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -45,6 +45,6 @@ tap.test('Moillebeau to Cours des Bastions 10', async (t) => { validate, fromId: moillebeau, to: coursDesBastions10, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/vbb.js b/test/e2e/vbb.js index c64ebbd1e..15d751dab 100644 --- a/test/e2e/vbb.js +++ b/test/e2e/vbb.js @@ -1,25 +1,25 @@ -import tap from 'tap' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as vbbProfile} from '../../p/vbb/index.js' -import {createVbbBvgValidators} from './lib/vbb-bvg-validators.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testJourneysWalkingSpeed} from './lib/journeys-walking-speed.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testRefreshJourney} from './lib/refresh-journey.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' -import {testArrivals} from './lib/arrivals.js' -import {testJourneysWithDetour} from './lib/journeys-with-detour.js' -import {testReachableFrom} from './lib/reachable-from.js' - -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(vbbProfile.timezone, vbbProfile.locale, T_MOCK) +import tap from 'tap'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as vbbProfile} from '../../p/vbb/index.js'; +import {createVbbBvgValidators} from './lib/vbb-bvg-validators.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testJourneysWalkingSpeed} from './lib/journeys-walking-speed.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testRefreshJourney} from './lib/refresh-journey.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testJourneysWithDetour} from './lib/journeys-with-detour.js'; +import {testReachableFrom} from './lib/reachable-from.js'; + +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(vbbProfile.timezone, vbbProfile.locale, T_MOCK); const { cfg, @@ -29,23 +29,23 @@ const { validateMovement, } = createVbbBvgValidators({ when, -}) +}); const validate = createValidate(cfg, { station: validateStation, journeyLeg: validateJourneyLeg, departure: validateDeparture, movement: validateMovement, -}) +}); -const client = createClient(vbbProfile, 'public-transport/hafas-client:test') +const client = createClient(vbbProfile, 'public-transport/hafas-client:test'); -const amrumerStr = '900009101' -const spichernstr = '900042101' -const bismarckstr = '900024201' -const westhafen = '900001201' -const wedding = '900009104' -const württembergallee = '900026153' +const amrumerStr = '900009101'; +const spichernstr = '900042101'; +const bismarckstr = '900024201'; +const westhafen = '900001201'; +const wedding = '900009104'; +const württembergallee = '900026153'; tap.test('journeys – Spichernstr. to Bismarckstr.', async (t) => { const res = await client.journeys({ @@ -56,7 +56,7 @@ tap.test('journeys – Spichernstr. to Bismarckstr.', async (t) => { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -64,11 +64,11 @@ tap.test('journeys – Spichernstr. to Bismarckstr.', async (t) => { validate, fromId: spichernstr, toId: bismarckstr, - }) + }); // todo: find a journey where there ticket info is always available - t.end() -}) + t.end(); +}); tap.test('journeys – only subway', async (t) => { const res = await client.journeys(spichernstr, bismarckstr, { @@ -83,27 +83,27 @@ tap.test('journeys – only subway', async (t) => { express: false, regional: false, }, - }) + }); - validate(t, res, 'journeysResult', 'res') + validate(t, res, 'journeysResult', 'res'); - t.ok(res.journeys.length > 1) + t.ok(res.journeys.length > 1); for (let i = 0; i < res.journeys.length; i++) { - const journey = res.journeys[i] + const journey = res.journeys[i]; for (let j = 0; j < journey.legs.length; j++) { - const leg = journey.legs[j] + const leg = journey.legs[j]; - const name = `res.journeys[${i}].legs[${i}].line` + const name = `res.journeys[${i}].legs[${i}].line`; if (leg.line) { - t.equal(leg.line.mode, 'train', name + '.mode is invalid') - t.equal(leg.line.product, 'subway', name + '.product is invalid') + t.equal(leg.line.mode, 'train', name + '.mode is invalid'); + t.equal(leg.line.product, 'subway', name + '.product is invalid'); } - t.ok(journey.legs.some(l => l.line), name + '.legs has no subway leg') + t.ok(journey.legs.some(l => l.line), name + '.legs has no subway leg'); } } - t.end() -}) + t.end(); +}); // todo: journeys – with arrival time @@ -115,9 +115,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: bismarckstr, when, products: vbbProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys: walkingSpeed', async (t) => { const havelchaussee = { @@ -125,8 +125,8 @@ tap.test('journeys: walkingSpeed', async (t) => { address: 'Havelchaussee', latitude: 52.443576, longitude: 13.198973, - } - const wannsee = '900053301' + }; + const wannsee = '900053301'; await testJourneysWalkingSpeed({ test: t, @@ -137,8 +137,8 @@ tap.test('journeys: walkingSpeed', async (t) => { when, products: {bus: false}, minTimeDifference: 5 * 60 * 1000, - }) -}) + }); +}); tap.test('earlier/later journeys', async (t) => { await testEarlierLaterJourneys({ @@ -148,10 +148,10 @@ tap.test('earlier/later journeys', async (t) => { fromId: spichernstr, toId: bismarckstr, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('refreshJourney', async (t) => { await testRefreshJourney({ @@ -162,58 +162,58 @@ tap.test('refreshJourney', async (t) => { fromId: spichernstr, toId: bismarckstr, when, - }) - t.end() -}) + }); + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(spichernstr, amrumerStr, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); // This currently fails because some trips' departure/arrival is out of the range // around `when`, as expected by `assertValidWhen`, as called by `validate`. // todo: allow turning this off? tap.skip('trips', async (t) => { - const {trips: r1} = await client.tripsByName('S1') - t.ok(Array.isArray(r1)) - t.ok(r1.length > 0) - t.ok(r1.every(t => t.line.name.trim() === 'S1')) + const {trips: r1} = await client.tripsByName('S1'); + t.ok(Array.isArray(r1)); + t.ok(r1.length > 0); + t.ok(r1.every(t => t.line.name.trim() === 'S1')); for (let i = 0; i < r1.length; i++) { - validate(t, r1[i], 'trip', `r1[${i}]`) + validate(t, r1[i], 'trip', `r1[${i}]`); } const {trips: r2} = await client.tripsByName('S1', { onlyCurrentlyRunning: false, - }) - t.ok(Array.isArray(r2)) - t.ok(r2.length > r1.length) - t.ok(r2.every(t => t.line.name.trim() === 'S1')) + }); + t.ok(Array.isArray(r2)); + t.ok(r2.length > r1.length); + t.ok(r2.every(t => t.line.name.trim() === 'S1')); for (let i = 0; i < r2.length; i++) { - validate(t, r2[i], 'trip', `r2[${i}]`) + validate(t, r2[i], 'trip', `r2[${i}]`); } const {trips: r3} = await client.tripsByName('*', { onlyCurrentlyRunning: false, - }) - t.ok(Array.isArray(r3)) - t.ok(r3.length > r2.length) + }); + t.ok(Array.isArray(r3)); + t.ok(r3.length > r2.length); for (let i = 0; i < r3.length; i++) { - validate(t, r3[i], 'trip', `r3[${i}]`) + validate(t, r3[i], 'trip', `r3[${i}]`); } - t.end() -}) + t.end(); +}); tap.test('journeys – station to address', async (t) => { const torfstr = { @@ -221,11 +221,11 @@ tap.test('journeys – station to address', async (t) => { address: '13353 Berlin-Wedding, Torfstr. 17', latitude: 52.541797, longitude: 13.350042, - } + }; const res = await client.journeys(spichernstr, torfstr, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -233,9 +233,9 @@ tap.test('journeys – station to address', async (t) => { validate, fromId: spichernstr, to: torfstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys – station to POI', async (t) => { const atze = { @@ -245,11 +245,11 @@ tap.test('journeys – station to POI', async (t) => { name: 'Berlin, Atze Musiktheater für Kinder', latitude: 52.543333, longitude: 13.351686, - } + }; const res = await client.journeys(spichernstr, atze, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -257,9 +257,9 @@ tap.test('journeys – station to POI', async (t) => { validate, fromId: spichernstr, to: atze, - }) - t.end() -}) + }); + t.end(); +}); tap.test('journeys: via works – with detour', async (t) => { // Going from Westhafen to Wedding via Württembergalle without detour @@ -269,32 +269,32 @@ tap.test('journeys: via works – with detour', async (t) => { results: 1, departure: when, stopovers: true, - }) + }); await testJourneysWithDetour({ test: t, res, validate, detourIds: [württembergallee], - }) - t.end() -}) + }); + t.end(); +}); // todo: without detour test tap.test('departures', async (t) => { const res = await client.departures(spichernstr, { duration: 5, when, - }) + }); await testDepartures({ test: t, res, validate, id: spichernstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -306,11 +306,11 @@ tap.test('departures with station object', async (t) => { latitude: 1.23, longitude: 2.34, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('departures at Spichernstr. in direction of Westhafen', async (t) => { await testDeparturesInDirection({ @@ -321,34 +321,34 @@ tap.test('departures at Spichernstr. in direction of Westhafen', async (t) => { directionIds: [westhafen], when, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures at 7-digit station', async (t) => { - const eisenach = '8010097' // see derhuerst/vbb-hafas#22 - await client.departures(eisenach, {when}) - t.pass('did not fail') - t.end() -}) + const eisenach = '8010097'; // see derhuerst/vbb-hafas#22 + await client.departures(eisenach, {when}); + t.pass('did not fail'); + t.end(); +}); tap.test('arrivals', async (t) => { const res = await client.arrivals(spichernstr, { duration: 5, when, - }) + }); await testArrivals({ test: t, res, validate, id: spichernstr, - }) - t.end() -}) + }); + t.end(); +}); tap.test('nearby', async (t) => { - const berlinerStr = '900044201' - const landhausstr = '900043252' + const berlinerStr = '900044201'; + const landhausstr = '900043252'; // Berliner Str./Bundesallee const nearby = await client.nearby({ @@ -358,45 +358,45 @@ tap.test('nearby', async (t) => { }, { // Even though HAFAS reports Landhausstr. to be 179m, we have to pass way more here. 🙄 distance: 600, - }) + }); - validate(t, nearby, 'locations', 'nearby') + validate(t, nearby, 'locations', 'nearby'); - t.equal(nearby[0].id, berlinerStr) - t.equal(nearby[0].name, 'U Berliner Str. (Berlin)') - t.ok(nearby[0].distance > 0) - t.ok(nearby[0].distance < 100) + t.equal(nearby[0].id, berlinerStr); + t.equal(nearby[0].name, 'U Berliner Str. (Berlin)'); + t.ok(nearby[0].distance > 0); + t.ok(nearby[0].distance < 100); - const res = nearby.find(s => s.id === landhausstr) - t.ok(res, `Landhausstr. ${landhausstr} is not among the nearby stops`) - t.equal(nearby[1].name, 'Landhausstr. (Berlin)') - t.ok(nearby[1].distance > 100) - t.ok(nearby[1].distance < 200) + const res = nearby.find(s => s.id === landhausstr); + t.ok(res, `Landhausstr. ${landhausstr} is not among the nearby stops`); + t.equal(nearby[1].name, 'Landhausstr. (Berlin)'); + t.ok(nearby[1].distance > 100); + t.ok(nearby[1].distance < 200); - t.end() -}) + t.end(); +}); tap.test('locations', async (t) => { - const locations = await client.locations('Alexanderplatz', {results: 20}) + const locations = await client.locations('Alexanderplatz', {results: 20}); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs - t.ok(locations.find(s => !s.name && s.address)) // addresses + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs + t.ok(locations.find(s => !s.name && s.address)); // addresses - t.end() -}) + t.end(); +}); tap.test('stop', async (t) => { - const s = await client.stop(spichernstr) + const s = await client.stop(spichernstr); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, spichernstr) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, spichernstr); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -406,11 +406,11 @@ tap.test('radar', async (t) => { east: 13.41709, }, { duration: 5 * 60, when, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); tap.test('reachableFrom', async (t) => { const torfstr17 = { @@ -418,7 +418,7 @@ tap.test('reachableFrom', async (t) => { address: '13353 Berlin-Wedding, Torfstr. 17', latitude: 52.541797, longitude: 13.350042, - } + }; await testReachableFrom({ test: t, @@ -427,6 +427,6 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/vbn.js b/test/e2e/vbn.js index 2296c5d61..4d05a928d 100644 --- a/test/e2e/vbn.js +++ b/test/e2e/vbn.js @@ -1,15 +1,15 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as vbnProfile} from '../../p/vbn/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testArrivals} from './lib/arrivals.js' -import {testReachableFrom} from './lib/reachable-from.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as vbnProfile} from '../../p/vbn/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testArrivals} from './lib/arrivals.js'; +import {testReachableFrom} from './lib/reachable-from.js'; -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(vbnProfile.timezone, vbnProfile.locale, T_MOCK) +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(vbnProfile.timezone, vbnProfile.locale, T_MOCK); const cfg = { when, @@ -19,21 +19,21 @@ const cfg = { maxLatitude: 53.657, minLongitude: 5.248, maxLongitude: 11.719, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(vbnProfile, 'public-transport/hafas-client:test') +const client = createClient(vbnProfile, 'public-transport/hafas-client:test'); -const oldenburg = '8000291' -const bremenHumboldtstr = '9013973' +const oldenburg = '8000291'; +const bremenHumboldtstr = '9013973'; tap.test('journeys – Oldenburg to Bremen Humboldtstr.', async (t) => { const res = await client.journeys(oldenburg, bremenHumboldtstr, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -41,9 +41,9 @@ tap.test('journeys – Oldenburg to Bremen Humboldtstr.', async (t) => { validate, fromId: oldenburg, toId: bremenHumboldtstr, - }) - t.end() -}) + }); + t.end(); +}); // todo: via works – with detour // todo: without detour @@ -51,31 +51,31 @@ tap.test('journeys – Oldenburg to Bremen Humboldtstr.', async (t) => { tap.test('trip details', async (t) => { const res = await client.journeys(oldenburg, bremenHumboldtstr, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('arrivals at Bremen Humboldtstr.', async (t) => { const res = await client.arrivals(bremenHumboldtstr, { duration: 10, when, - }) + }); await testArrivals({ test: t, res, validate, id: bremenHumboldtstr, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby @@ -87,11 +87,11 @@ tap.test('radar', async (t) => { east: 8.847423, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); // todo: fails with "HCI Service: location missing or invalid" tap.test('reachableFrom', async (t) => { @@ -108,6 +108,6 @@ tap.test('reachableFrom', async (t) => { when, maxDuration: 15, validate, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/e2e/vor.js b/test/e2e/vor.js index d6a90a9b7..a29451f28 100644 --- a/test/e2e/vor.js +++ b/test/e2e/vor.js @@ -1,12 +1,12 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as vorProfile} from '../../p/vor/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as vorProfile} from '../../p/vor/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(vorProfile.timezone, vorProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(vorProfile.timezone, vorProfile.locale, T_MOCK); const cfg = { when, @@ -16,20 +16,20 @@ const cfg = { maxLongitude: 17.0892, minLatitude: 45.7206, minLongitude: 7.8635, -} -const validate = createValidate(cfg) +}; +const validate = createValidate(cfg); -const client = createClient(vorProfile, 'public-transport/hafas-client:test') +const client = createClient(vorProfile, 'public-transport/hafas-client:test'); -const stPöltenLinzerTor = '431277900' +const stPöltenLinzerTor = '431277900'; tap.test('locations named "linzer tor"', async (t) => { - const locations = await client.locations('linzer tor') + const locations = await client.locations('linzer tor'); - validate(t, locations, 'locations', 'locations') + validate(t, locations, 'locations', 'locations'); t.ok(locations.some((l) => { - return l.station && l.station.id === stPöltenLinzerTor || l.id === stPöltenLinzerTor - }), 'St. Pölten Linzer Tor not found') + return l.station && l.station.id === stPöltenLinzerTor || l.id === stPöltenLinzerTor; + }), 'St. Pölten Linzer Tor not found'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/vrn.js b/test/e2e/vrn.js index 6ddc49f29..ba9f2d57f 100644 --- a/test/e2e/vrn.js +++ b/test/e2e/vrn.js @@ -1,21 +1,21 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as vrnProfile} from '../../p/vrn/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' -import {testArrivals} from './lib/arrivals.js' - -const T_MOCK = 1668495600 * 1000 // 2022-11-15T08:00:00+01:00 -const when = createWhen(vrnProfile.timezone, vrnProfile.locale, T_MOCK) +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as vrnProfile} from '../../p/vrn/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {journeysFailsWithNoProduct} from './lib/journeys-fails-with-no-product.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; +import {testArrivals} from './lib/arrivals.js'; + +const T_MOCK = 1668495600 * 1000; // 2022-11-15T08:00:00+01:00 +const when = createWhen(vrnProfile.timezone, vrnProfile.locale, T_MOCK); const cfg = { when, @@ -25,21 +25,21 @@ const cfg = { minLongitude: 6.163, maxLatitude: 50.440, maxLongitude: 10.701, -} +}; -const validate = createValidate(cfg, {}) +const validate = createValidate(cfg, {}); -const client = createClient(vrnProfile, 'public-transport/hafas-client:test') +const client = createClient(vrnProfile, 'public-transport/hafas-client:test'); -const ludwigshafen = '8000236' -const meckesheim = '8003932' +const ludwigshafen = '8000236'; +const meckesheim = '8003932'; tap.test('journeys – Ludwigshafen to Meckesheim', async (t) => { const res = await client.journeys(ludwigshafen, meckesheim, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -47,9 +47,9 @@ tap.test('journeys – Ludwigshafen to Meckesheim', async (t) => { validate, fromId: ludwigshafen, toId: meckesheim, - }) - t.end() -}) + }); + t.end(); +}); // todo: journeys, only one product @@ -61,9 +61,9 @@ tap.test('journeys – fails with no product', async (t) => { toId: meckesheim, when, products: vrnProfile.products, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Ludwigshafen to Pestalozzistr. 2, Ludwigshafen', async (t) => { const pestalozzistr2 = { @@ -71,12 +71,12 @@ tap.test('Ludwigshafen to Pestalozzistr. 2, Ludwigshafen', async (t) => { id: '980787337', address: 'Ludwigshafen am Rhein - Mitte, Pestalozzistraße 2', latitude: 49.474336, longitude: 8.441779, - } + }; const res = await client.journeys(ludwigshafen, pestalozzistr2, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, @@ -84,9 +84,9 @@ tap.test('Ludwigshafen to Pestalozzistr. 2, Ludwigshafen', async (t) => { validate, fromId: ludwigshafen, to: pestalozzistr2, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Ludwigshafen to Südwest-Stadion', async (t) => { const südweststadion = { @@ -95,11 +95,11 @@ tap.test('Ludwigshafen to Südwest-Stadion', async (t) => { poi: true, name: 'Ludwigshafen am Rhein, Südwest-Stadion (Sport)', latitude: 49.469248, longitude: 8.440691, - } + }; const res = await client.journeys(ludwigshafen, südweststadion, { results: 3, departure: when, - }) + }); await testJourneysStationToPoi({ test: t, @@ -107,9 +107,9 @@ tap.test('Ludwigshafen to Südwest-Stadion', async (t) => { validate, fromId: ludwigshafen, to: südweststadion, - }) - t.end() -}) + }); + t.end(); +}); // todo: via works – with detour // todo: via works – without detour @@ -122,42 +122,42 @@ tap.test('earlier/later journeys', async (t) => { fromId: ludwigshafen, toId: meckesheim, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(ludwigshafen, meckesheim, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Meckesheim', async (t) => { const res = await client.departures(meckesheim, { duration: 3 * 60, when, - }) + }); await testDepartures({ test: t, res, validate, id: meckesheim, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures at Meckesheim in direction of Reilsheim', async (t) => { - const reilsheim = '8005015' + const reilsheim = '8005015'; await testDeparturesInDirection({ test: t, fetchDepartures: client.departures, @@ -166,52 +166,52 @@ tap.test('departures at Meckesheim in direction of Reilsheim', async (t) => { directionIds: [reilsheim], when, duration: 30 * 60, validate, - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Meckesheim', async (t) => { const res = await client.arrivals(meckesheim, { duration: 3 * 60, when, - }) + }); await testArrivals({ test: t, res, validate, id: meckesheim, - }) - t.end() -}) + }); + t.end(); +}); // todo: nearby tap.test('locations named Ebertpark', async (t) => { - const ebertpark = '506453' + const ebertpark = '506453'; const locations = await client.locations('Ebertpark', { results: 20, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) // POIs + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); // POIs t.ok(locations.some((l) => { - return l.station && l.station.id === ebertpark || l.id === ebertpark - })) + return l.station && l.station.id === ebertpark || l.id === ebertpark; + })); - t.end() -}) + t.end(); +}); tap.skip('station Meckesheim', async (t) => { - const s = await client.stop(meckesheim) + const s = await client.stop(meckesheim); - validate(t, s, ['stop', 'station'], 'station') - t.equal(s.id, meckesheim) + validate(t, s, ['stop', 'station'], 'station'); + t.equal(s.id, meckesheim); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -221,8 +221,8 @@ tap.test('radar', async (t) => { east: 8.4834, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); diff --git a/test/e2e/vsn.js b/test/e2e/vsn.js index 4509d7d4c..d18e9f6ca 100644 --- a/test/e2e/vsn.js +++ b/test/e2e/vsn.js @@ -1,19 +1,19 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as vsnProfile} from '../../p/vsn/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testDepartures} from './lib/departures.js' -import {testArrivals} from './lib/arrivals.js' - -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(vsnProfile.timezone, vsnProfile.locale, T_MOCK) +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as vsnProfile} from '../../p/vsn/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testDepartures} from './lib/departures.js'; +import {testArrivals} from './lib/arrivals.js'; + +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(vsnProfile.timezone, vsnProfile.locale, T_MOCK); const cfg = { when, @@ -22,22 +22,22 @@ const cfg = { maxLatitude: 54.5, minLongitude: 6.5, maxLongitude: 11.5, -} +}; -const validate = createValidate(cfg) +const validate = createValidate(cfg); -const client = createClient(vsnProfile, 'public-transport/hafas-client:test') +const client = createClient(vsnProfile, 'public-transport/hafas-client:test'); -const kornmarkt = '9033977' -const jugendherberge = '9033961' -const ewaldstrasse = '9033896' +const kornmarkt = '9033977'; +const jugendherberge = '9033961'; +const ewaldstrasse = '9033896'; tap.test('journeys – Kornmarkt to Ewaldstraße', async (t) => { const res = await client.journeys(kornmarkt, ewaldstrasse, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -45,9 +45,9 @@ tap.test('journeys – Kornmarkt to Ewaldstraße', async (t) => { validate, fromId: kornmarkt, toId: ewaldstrasse, - }) - t.end() -}) + }); + t.end(); +}); tap.test('Ewaldstraße to 37083 Göttingen, Schulweg 22', async (t) => { const schulweg = { @@ -55,20 +55,20 @@ tap.test('Ewaldstraße to 37083 Göttingen, Schulweg 22', async (t) => { address: '37083 Göttingen, Schulweg 22', latitude: 51.51579, longitude: 9.945382, - } + }; const res = await client.journeys(ewaldstrasse, schulweg, { results: 3, departure: when, - }) + }); await testJourneysStationToAddress({ test: t, res, validate, fromId: ewaldstrasse, to: schulweg, - }) - t.end() -}) + }); + t.end(); +}); tap.test('earlier/later journeys', async (t) => { await testEarlierLaterJourneys({ @@ -78,53 +78,53 @@ tap.test('earlier/later journeys', async (t) => { fromId: ewaldstrasse, toId: kornmarkt, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('trip', async (t) => { const {journeys} = await client.journeys(jugendherberge, kornmarkt, { results: 1, departure: when, - }) + }); - const p = journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at Kornmarkt.', async (t) => { const res = await client.departures(kornmarkt, { duration: 20, when, - }) + }); await testDepartures({ test: t, res, validate, id: kornmarkt, - }) - t.end() -}) + }); + t.end(); +}); tap.test('arrivals at Kornmarkt.', async (t) => { const res = await client.arrivals(kornmarkt, { duration: 20, when, - }) + }); await testArrivals({ test: t, res, validate, id: kornmarkt, - }) - t.end() -}) + }); + t.end(); +}); tap.test('departures with station object', async (t) => { const res = await client.departures({ @@ -136,34 +136,34 @@ tap.test('departures with station object', async (t) => { latitude: 51.727914, longitude: 10.250606, }, - }, {when}) + }, {when}); - validate(t, res, 'departuresResponse', 'res') - t.end() -}) + validate(t, res, 'departuresResponse', 'res'); + t.end(); +}); tap.test('locations named Botanischer Garten', async (t) => { const locations = await client.locations('Botanischer Garten', { results: 20, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) - t.ok(locations.find(s => s.poi)) + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); + t.ok(locations.find(s => s.poi)); - t.end() -}) + t.end(); +}); tap.test('stop Jugendherberge', async (t) => { - const s = await client.stop(jugendherberge) + const s = await client.stop(jugendherberge); - validate(t, s, ['stop', 'station'], 'stop') - t.equal(s.id, jugendherberge) + validate(t, s, ['stop', 'station'], 'stop'); + t.equal(s.id, jugendherberge); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -173,7 +173,7 @@ tap.test('radar', async (t) => { east: 10, }, { duration: 5 * 60, when, results: 10, - }) - validate(t, res, 'radarResult', 'res') - t.end() -}) + }); + validate(t, res, 'radarResult', 'res'); + t.end(); +}); diff --git a/test/e2e/vvv.js b/test/e2e/vvv.js index e1a84abc2..1e9b9dc0e 100644 --- a/test/e2e/vvv.js +++ b/test/e2e/vvv.js @@ -1,12 +1,12 @@ -import tap from 'tap' +import tap from 'tap'; -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as vvvProfile} from '../../p/vvv/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as vvvProfile} from '../../p/vvv/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(vvvProfile.timezone, vvvProfile.locale, T_MOCK) +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(vvvProfile.timezone, vvvProfile.locale, T_MOCK); const cfg = { when, @@ -16,20 +16,20 @@ const cfg = { maxLongitude: 17.0892, minLatitude: 45.7206, minLongitude: 7.8635, -} -const validate = createValidate(cfg) +}; +const validate = createValidate(cfg); -const client = createClient(vvvProfile, 'public-transport/hafas-client:test') +const client = createClient(vvvProfile, 'public-transport/hafas-client:test'); -const bregenzLandeskrankenhaus = '480195700' +const bregenzLandeskrankenhaus = '480195700'; tap.test('locations named "bregenz krankenhaus"', async (t) => { - const locations = await client.locations('bregenz krankenhaus') + const locations = await client.locations('bregenz krankenhaus'); - validate(t, locations, 'locations', 'locations') + validate(t, locations, 'locations', 'locations'); t.ok(locations.some((l) => { - return l.station && l.station.id === bregenzLandeskrankenhaus || l.id === bregenzLandeskrankenhaus - }), 'Bregenz Landeskrankenhaus not found') + return l.station && l.station.id === bregenzLandeskrankenhaus || l.id === bregenzLandeskrankenhaus; + }), 'Bregenz Landeskrankenhaus not found'); - t.end() -}) + t.end(); +}); diff --git a/test/e2e/zvv.js b/test/e2e/zvv.js index ce9f2d18a..1f1e617b8 100644 --- a/test/e2e/zvv.js +++ b/test/e2e/zvv.js @@ -1,20 +1,20 @@ -import tap from 'tap' -import isRoughlyEqual from 'is-roughly-equal' - -import {createWhen} from './lib/util.js' -import {createClient} from '../../index.js' -import {profile as zvvProfile} from '../../p/zvv/index.js' -import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js' -import {testJourneysStationToStation} from './lib/journeys-station-to-station.js' -import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js' -import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js' -import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js' -import {testDepartures} from './lib/departures.js' -import {testDeparturesInDirection} from './lib/departures-in-direction.js' -import {testArrivals} from './lib/arrivals.js' - -const T_MOCK = 1671260400 * 1000 // 2022-12-17T08:00:00+01:00 -const when = createWhen(zvvProfile.timezone, zvvProfile.locale, T_MOCK) +import tap from 'tap'; +import isRoughlyEqual from 'is-roughly-equal'; + +import {createWhen} from './lib/util.js'; +import {createClient} from '../../index.js'; +import {profile as zvvProfile} from '../../p/zvv/index.js'; +import {createValidateFptfWith as createValidate} from './lib/validate-fptf-with.js'; +import {testJourneysStationToStation} from './lib/journeys-station-to-station.js'; +import {testJourneysStationToAddress} from './lib/journeys-station-to-address.js'; +import {testJourneysStationToPoi} from './lib/journeys-station-to-poi.js'; +import {testEarlierLaterJourneys} from './lib/earlier-later-journeys.js'; +import {testDepartures} from './lib/departures.js'; +import {testDeparturesInDirection} from './lib/departures-in-direction.js'; +import {testArrivals} from './lib/arrivals.js'; + +const T_MOCK = 1671260400 * 1000; // 2022-12-17T08:00:00+01:00 +const when = createWhen(zvvProfile.timezone, zvvProfile.locale, T_MOCK); const validate = createValidate({ when, @@ -23,19 +23,19 @@ const validate = createValidate({ minLongitude: 7.38, minLatitude: 46.99, maxLongitude: 9.71, -}, {}) +}, {}); -const client = createClient(zvvProfile, 'public-transport/hafas-client:test') +const client = createClient(zvvProfile, 'public-transport/hafas-client:test'); -const bürkliplatz = '8591105' -const ethUniversitätsspital = '8591123' +const bürkliplatz = '8591105'; +const ethUniversitätsspital = '8591123'; tap.test('journeys – Bürkliplatz to ETH/Universitätsspital', async (t) => { const res = await client.journeys(bürkliplatz, ethUniversitätsspital, { results: 4, departure: when, stopovers: true, - }) + }); await testJourneysStationToStation({ test: t, @@ -43,9 +43,9 @@ tap.test('journeys – Bürkliplatz to ETH/Universitätsspital', async (t) => { validate, fromId: bürkliplatz, toId: ethUniversitätsspital, - }) - t.end() -}) + }); + t.end(); +}); tap.test('earlier/later journeys', async (t) => { await testEarlierLaterJourneys({ @@ -55,60 +55,60 @@ tap.test('earlier/later journeys', async (t) => { fromId: bürkliplatz, toId: ethUniversitätsspital, when, - }) + }); - t.end() -}) + t.end(); +}); tap.test('trip details', async (t) => { const res = await client.journeys(bürkliplatz, ethUniversitätsspital, { results: 1, departure: when, - }) + }); - const p = res.journeys[0].legs.find(l => !l.walking) - t.ok(p.tripId, 'precondition failed') - t.ok(p.line.name, 'precondition failed') + const p = res.journeys[0].legs.find(l => !l.walking); + t.ok(p.tripId, 'precondition failed'); + t.ok(p.line.name, 'precondition failed'); - const tripRes = await client.trip(p.tripId, {when}) + const tripRes = await client.trip(p.tripId, {when}); - validate(t, tripRes, 'tripResult', 'res') - t.end() -}) + validate(t, tripRes, 'tripResult', 'res'); + t.end(); +}); tap.test('departures at ETH/Universitätsspital', async (t) => { // todo - const polyterrasseETH = '8503500' + const polyterrasseETH = '8503500'; const res = await client.departures(ethUniversitätsspital, { duration: 5, when, - }) + }); await testDepartures({ test: t, res, validate, ids: [ethUniversitätsspital, polyterrasseETH], - }) - t.end() -}) + }); + t.end(); +}); // todo: departures in direction // todo: nearby tap.test('locations named Rennweg', async (t) => { - const rennweg = '8591316' + const rennweg = '8591316'; const locations = await client.locations('Rennweg', { results: 20, - }) + }); - validate(t, locations, 'locations', 'locations') - t.ok(locations.length <= 20) + validate(t, locations, 'locations', 'locations'); + t.ok(locations.length <= 20); - t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')) + t.ok(locations.find(s => s.type === 'stop' || s.type === 'station')); t.ok(locations.some((l) => { - return l.station && l.station.id === rennweg || l.id === rennweg - })) + return l.station && l.station.id === rennweg || l.id === rennweg; + })); - t.end() -}) + t.end(); +}); tap.test('radar', async (t) => { const res = await client.radar({ @@ -118,8 +118,8 @@ tap.test('radar', async (t) => { east: 8.568, }, { duration: 5 * 60, when, results: 10, - }) + }); - validate(t, res, 'radarResult', 'res') - t.end() -}) + validate(t, res, 'radarResult', 'res'); + t.end(); +}); diff --git a/test/fixtures/bvg-arrivals.js b/test/fixtures/bvg-arrivals.js index ba1cf233c..2d36c3065 100644 --- a/test/fixtures/bvg-arrivals.js +++ b/test/fixtures/bvg-arrivals.js @@ -145,7 +145,7 @@ const sLandsbergerAllee = { mode: 'bus', product: 'bus', }], -} +}; const achtungFalscheFahrplanauskünfte = { id: '140812', @@ -169,7 +169,7 @@ const achtungFalscheFahrplanauskünfte = { validFrom: '2021-10-27T18:10:00+02:00', validUntil: '2021-10-29T02:00:00+02:00', modified: '2021-10-28T08:50:03+02:00', -} +}; const gemeinsamSicherUnterwegs = { id: '118634', @@ -193,7 +193,7 @@ const gemeinsamSicherUnterwegs = { validFrom: '2021-04-24T00:00:00+02:00', validUntil: '2022-12-31T00:00:00+01:00', modified: '2021-06-12T07:43:36+02:00', -} +}; const ausfallS8 = { id: '140655', @@ -217,7 +217,7 @@ const ausfallS8 = { validFrom: '2021-10-28T02:00:00+02:00', validUntil: '2021-10-29T02:00:00+02:00', modified: '2021-10-27T09:58:25+02:00', -} +}; const ersatzlinieWegenBauarbeiten = { id: '140433', @@ -240,7 +240,7 @@ const ersatzlinieWegenBauarbeiten = { validFrom: '2021-10-25T02:00:00+02:00', validUntil: '2021-11-22T03:00:00+01:00', modified: '2021-10-22T23:39:21+02:00', -} +}; const fehlerImITSysem = { id: '140805', @@ -263,7 +263,7 @@ const fehlerImITSysem = { validFrom: '2021-10-27T17:10:00+02:00', validUntil: '2021-10-29T02:00:00+02:00', modified: '2021-10-27T17:39:54+02:00', -} +}; const bauzeitverlängerung = { id: '140558', @@ -287,7 +287,7 @@ const bauzeitverlängerung = { validFrom: '2021-10-28T02:00:00+02:00', validUntil: '2021-10-29T01:30:00+02:00', modified: '2021-10-27T17:00:45+02:00', -} +}; const bvgArrivals = [ { @@ -1245,8 +1245,8 @@ const bvgArrivals = [ ], currentTripPosition: {type: 'location', latitude: 52.473811, longitude: 13.456142}, }, -] +]; export { bvgArrivals, -} +}; diff --git a/test/fixtures/bvg-journey.js b/test/fixtures/bvg-journey.js index 981cc2450..25fb87893 100644 --- a/test/fixtures/bvg-journey.js +++ b/test/fixtures/bvg-journey.js @@ -1100,8 +1100,8 @@ const bvgJourney = { '2019-12-15': false, '2019-12-16': false, }), -} +}; export { bvgJourney, -} +}; diff --git a/test/fixtures/bvg-radar.js b/test/fixtures/bvg-radar.js index 2789ec575..127bf146f 100644 --- a/test/fixtures/bvg-radar.js +++ b/test/fixtures/bvg-radar.js @@ -3031,8 +3031,8 @@ const bvgRadar = [ ], }, }, -] +]; export { bvgRadar, -} +}; diff --git a/test/fixtures/bvg-trip-with-occupancy.js b/test/fixtures/bvg-trip-with-occupancy.js index 1a6634596..faeb72a06 100644 --- a/test/fixtures/bvg-trip-with-occupancy.js +++ b/test/fixtures/bvg-trip-with-occupancy.js @@ -2040,8 +2040,8 @@ const bvgTripWithOccupancy = { departurePrognosisType: null, }, ], -} +}; export { bvgTripWithOccupancy, -} +}; diff --git a/test/fixtures/db-arrivals.js b/test/fixtures/db-arrivals.js index 984939229..0b775214b 100644 --- a/test/fixtures/db-arrivals.js +++ b/test/fixtures/db-arrivals.js @@ -264,8 +264,8 @@ const dbArrivals = [ }, remarks: [], }, -] +]; export { dbArrivals, -} +}; diff --git a/test/fixtures/db-journey-2.js b/test/fixtures/db-journey-2.js index 994112cf0..fcd66db9a 100644 --- a/test/fixtures/db-journey-2.js +++ b/test/fixtures/db-journey-2.js @@ -1157,8 +1157,8 @@ const dbJourney = { refreshToken: '¶HKI¶T$A=1@O=München-Mittersendling@L=8004154@a=128@$A=1@O=München Siemenswerke@L=8004137@a=128@$202011161004$202011161005$S 7$$1$$$§W$A=1@O=München Siemenswerke@L=8004137@a=128@$A=1@O=Obersendling, München@L=625016@a=128@$202011161005$202011161015$$$1$$$§T$A=1@O=Obersendling, München@L=625016@a=128@$A=1@O=Bonner Platz, München@L=624333@a=128@$202011161015$202011161033$U 3$$1$$$§G@F$A=1@O=Bonner Platz, München@L=624333@a=128@$A=1@O=Karl-Theodor-Straße, München@L=621790@a=128@$202011161033$202011161038$$$1$$$¶GP¶ft@0@2000@120@1@100@1@1000@0@@@@@false@0@-1@$f@$f@$f@$f@$f@$§bt@0@2000@120@1@100@1@1000@0@@@@@false@0@-1@$f@$f@$f@$f@$f@$§tt@0@5000@120@1@100@1@2500@0@@@@@false@0@-1@$t@0@25000@120@1@100@1@3000@0@@@@@false@0@-1@$f@$f@$f@$f@$§', cycle: {min: 1200}, price: null, -} +}; export { dbJourney, -} +}; diff --git a/test/fixtures/db-journey-overnight-1.expected.js b/test/fixtures/db-journey-overnight-1.expected.js index ce4165b69..7402ed5d8 100644 --- a/test/fixtures/db-journey-overnight-1.expected.js +++ b/test/fixtures/db-journey-overnight-1.expected.js @@ -20,7 +20,7 @@ const büchen = { tram: false, taxi: true, }, -} +}; const berlinHbfTief = { type: 'stop', @@ -67,7 +67,7 @@ const berlinHbfTief = { taxi: false, }, }, -} +}; const overnightJourney = { type: 'journey', @@ -306,8 +306,8 @@ const overnightJourney = { remarks: [], price: {amount: 108.9, currency: 'EUR', hint: null}, -} +}; export { overnightJourney, -} +}; diff --git a/test/fixtures/db-journey-polyline.js b/test/fixtures/db-journey-polyline.js index 82440f11a..236ac6c29 100644 --- a/test/fixtures/db-journey-polyline.js +++ b/test/fixtures/db-journey-polyline.js @@ -3975,8 +3975,8 @@ const dbJourneyPolyline = { currency: 'EUR', hint: null, }, -} +}; export { dbJourneyPolyline, -} +}; diff --git a/test/fixtures/db-journey.js b/test/fixtures/db-journey.js index 4a1c42507..a72e2dd59 100644 --- a/test/fixtures/db-journey.js +++ b/test/fixtures/db-journey.js @@ -195,8 +195,8 @@ const dbJourney = { ], refreshToken: '¶HKI¶D$A=1@O=Köln Hbf@L=8000207@a=128@$A=1@O=Köln Messe/Deutz Gl.11-12@L=8073368@a=128@$202004110517$202004110520$$$1$§T$A=1@O=Köln Messe/Deutz Gl.11-12@L=8073368@a=128@$A=1@O=Nürnberg Hbf@L=8000284@a=128@$202004110520$202004110901$ICE 523$$1$', price: {amount: 49.9, currency: 'EUR', hint: null}, -} +}; export { dbJourney, -} +}; diff --git a/test/fixtures/db-stop.js b/test/fixtures/db-stop.js index d3315b40c..86ed940b1 100644 --- a/test/fixtures/db-stop.js +++ b/test/fixtures/db-stop.js @@ -9,7 +9,7 @@ const facilities = { 'stepFreeAccess': true, 'boardingAid': 'ja, um voranmeldung unter 01806 512 512* wird gebeten', 'taxis': true, -} +}; const reisezentrumOpeningHours = { Mo: '08:00-20:00', @@ -28,7 +28,7 @@ const reisezentrumOpeningHours = { ['Sa', '10:00-18:00'], ['So', '10:00-18:00'], ], -} +}; const station = { type: 'station', @@ -59,7 +59,7 @@ const station = { }, facilities, reisezentrumOpeningHours, -} +}; const dbStop = { ...station, @@ -630,8 +630,8 @@ const dbStop = { type: 'location', id: '610728659', latitude: 52.522317, longitude: 13.412895, }], -} +}; export { dbStop, -} +}; diff --git a/test/fixtures/insa-stop.js b/test/fixtures/insa-stop.js index d6e9331e1..61fea900d 100644 --- a/test/fixtures/insa-stop.js +++ b/test/fixtures/insa-stop.js @@ -20,8 +20,8 @@ const insaStop = { bus: true, tourismTrain: false, }, -} +}; export { insaStop, -} +}; diff --git a/test/fixtures/oebb-trip.js b/test/fixtures/oebb-trip.js index 449bfe5d6..70e0ee77a 100644 --- a/test/fixtures/oebb-trip.js +++ b/test/fixtures/oebb-trip.js @@ -1,13 +1,13 @@ const point = (lon, lat) => ({ type: 'Point', coordinates: [lon, lat], -}) +}); const feature = (geometry, props = {}) => ({ type: 'Feature', properties: props, geometry: geometry, -}) +}); const wienFlughafen = { type: 'stop', @@ -31,7 +31,7 @@ const wienFlughafen = { tram: false, onCall: false, }, -} +}; const salzburgHbf = { type: 'stop', @@ -55,13 +55,13 @@ const salzburgHbf = { tram: false, onCall: false, }, -} +}; const öbbWestbahnTickets = { type: 'hint', code: 'O5', text: 'Hinweis: Gegenseitige Anerkennung von ÖBB- und WESTbahn-Tickets (Wien Hbf - Salzburg Hbf)', -} +}; const corona = { id: '483655', @@ -92,7 +92,7 @@ const corona = { validFrom: '2020-05-15T00:00:00+02:00', validUntil: '2020-06-30T23:59:00+02:00', modified: '2020-05-28T13:48:14+02:00', -} +}; const oebbTrip = { id: '2|#VN#0#ST#1591790769#PI#0#ZI#398470#TA#0#DA#110620#1S#8100353#1T#1633#LS#8100002#LT#1948#PU#81#RT#1#CA#RJ#ZE#742#ZB#RJ 742 #', @@ -2021,8 +2021,8 @@ const oebbTrip = { feature(point(13.0456, 47.81285), salzburgHbf), ], }, -} +}; export { oebbTrip, -} +}; diff --git a/test/fixtures/rejseplanen-trip.js b/test/fixtures/rejseplanen-trip.js index 991dcbfe8..e4636c4ef 100644 --- a/test/fixtures/rejseplanen-trip.js +++ b/test/fixtures/rejseplanen-trip.js @@ -435,8 +435,8 @@ const rejseplanenTrip = { departurePrognosisType: null, }, ], -} +}; export { rejseplanenTrip, -} +}; diff --git a/test/fixtures/rsag-journey.js b/test/fixtures/rsag-journey.js index 4ee029f9c..e91445fdb 100644 --- a/test/fixtures/rsag-journey.js +++ b/test/fixtures/rsag-journey.js @@ -92,8 +92,8 @@ const rsagJourneys = { ], refreshToken: '¶HKI¶T$A=1@O=Rostock Hbf@L=8010304@a=128@$A=1@O=Güstrow@L=8010153@a=128@$202101191414$202101191444$ S2$$1$$$$', cycle: {min: 3600}, -} +}; export { rsagJourneys, -} +}; diff --git a/test/fixtures/vbb-departures.js b/test/fixtures/vbb-departures.js index 168662663..29da24f6e 100644 --- a/test/fixtures/vbb-departures.js +++ b/test/fixtures/vbb-departures.js @@ -2577,8 +2577,8 @@ const vbbDepartures = [ longitude: 13.467252, }, }, -] +]; export { vbbDepartures, -} +}; diff --git a/test/fixtures/vbb-journeys.js b/test/fixtures/vbb-journeys.js index 460601bed..9537c7abf 100644 --- a/test/fixtures/vbb-journeys.js +++ b/test/fixtures/vbb-journeys.js @@ -902,8 +902,8 @@ const vbbJourneys = [{ code: 'text.realtime.connection.cancelled', text: 'A section of this itinerary is cancelled or unusable.', }], -}] +}]; export { vbbJourneys, -} +}; diff --git a/test/fixtures/vbb-on-demand-trip.js b/test/fixtures/vbb-on-demand-trip.js index f714bb180..2032a894e 100644 --- a/test/fixtures/vbb-on-demand-trip.js +++ b/test/fixtures/vbb-on-demand-trip.js @@ -93,8 +93,8 @@ const vbbOnDemandTrip = { modified: '2021-06-12T07:43:36+02:00', }, ], -} +}; export { vbbOnDemandTrip, -} +}; diff --git a/test/fixtures/vsn-departures.js b/test/fixtures/vsn-departures.js index d2fcaa91b..cb807cbed 100644 --- a/test/fixtures/vsn-departures.js +++ b/test/fixtures/vsn-departures.js @@ -96,8 +96,8 @@ const vsnDepartures = { }, }, remarks: [], -} +}; export { vsnDepartures, -} +}; diff --git a/test/fixtures/vsn-remarks.js b/test/fixtures/vsn-remarks.js index 1d7cfe75a..64d725155 100644 --- a/test/fixtures/vsn-remarks.js +++ b/test/fixtures/vsn-remarks.js @@ -327,8 +327,8 @@ const vsnRemarks = [ validUntil: '2020-06-30T23:59:00+02:00', modified: '2020-02-21T13:31:05+01:00', }, -] +]; export { vsnRemarks, -} +}; diff --git a/test/format/db-journeys-query.js b/test/format/db-journeys-query.js index 0cd1d1237..df353bd2e 100644 --- a/test/format/db-journeys-query.js +++ b/test/format/db-journeys-query.js @@ -1,11 +1,11 @@ -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../../index.js' -import {profile as rawProfile} from '../../p/db/index.js' -import {data as loyaltyCards} from '../../p/db/loyalty-cards.js' +import {createClient} from '../../index.js'; +import {profile as rawProfile} from '../../p/db/index.js'; +import {data as loyaltyCards} from '../../p/db/loyalty-cards.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: null, @@ -32,7 +32,7 @@ const opt = { type: loyaltyCards.BAHNCARD, discount: 25, }, -} +}; const berlinWienQuery0 = Object.freeze({ getPasslist: false, @@ -60,14 +60,14 @@ const berlinWienQuery0 = Object.freeze({ outDate: '20230912', outTime: '080910', outFrwd: true, -}) +}); tap.test('formats a journeys() request correctly (DB)', (t) => { - const ctx = {profile, opt} + const ctx = {profile, opt}; // transformJourneysQuery() mutates its 2nd argument! - const query = {...berlinWienQuery0} - const req = profile.transformJourneysQuery(ctx, query) + const query = {...berlinWienQuery0}; + const req = profile.transformJourneysQuery(ctx, query); t.same(req, { ...berlinWienQuery0, @@ -80,6 +80,6 @@ tap.test('formats a journeys() request correctly (DB)', (t) => { }], cType: 'PK', }, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/format/products-filter.js b/test/format/products-filter.js index c80739a27..6de98da41 100644 --- a/test/format/products-filter.js +++ b/test/format/products-filter.js @@ -1,5 +1,5 @@ -import tap from 'tap' -import {formatProductsFilter as format} from '../../format/products-filter.js' +import tap from 'tap'; +import {formatProductsFilter as format} from '../../format/products-filter.js'; const products = [ { @@ -17,34 +17,34 @@ const products = [ bitmasks: [8, 32], default: false, }, -] +]; const ctx = { common: {}, opt: {}, profile: {products}, -} +}; tap.test('formatProductsFilter works without customisations', (t) => { - const expected = 1 | 2 | 4 - const filter = {} + const expected = 1 | 2 | 4; + const filter = {}; t.same(format(ctx, filter), { type: 'PROD', mode: 'INC', value: String(expected), - }) - t.end() -}) + }); + t.end(); +}); tap.test('formatProductsFilter works with customisations', (t) => { t.equal(Number(format(ctx, { bus: true, - }).value), 1 | 2 | 4) + }).value), 1 | 2 | 4); t.equal(Number(format(ctx, { bus: false, - }).value), 1 | 2) + }).value), 1 | 2); t.equal(Number(format(ctx, { tram: true, - }).value), 1 | 2 | 4 | 8 | 32) - t.end() -}) + }).value), 1 | 2 | 4 | 8 | 32); + t.end(); +}); diff --git a/test/insa-stop.js b/test/insa-stop.js index 4866865cf..a2ac407d8 100644 --- a/test/insa-stop.js +++ b/test/insa-stop.js @@ -1,28 +1,28 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/insa/index.js' -const res = require('./fixtures/insa-stop.json') -import {insaStop as expected} from './fixtures/insa-stop.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/insa/index.js'; +const res = require('./fixtures/insa-stop.json'); +import {insaStop as expected} from './fixtures/insa-stop.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { linesOfStops: false, // parse & expose lines at the stop/station? remarks: true, -} +}; tap.test('parses a stop() response correctly (INSA)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const stop = profile.parseLocation(ctx, res.locL[0]) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const stop = profile.parseLocation(ctx, res.locL[0]); - t.same(stop, expected) - t.end() -}) + t.same(stop, expected); + t.end(); +}); diff --git a/test/lib/request.js b/test/lib/request.js index 80a1c8335..6e4635709 100644 --- a/test/lib/request.js +++ b/test/lib/request.js @@ -1,143 +1,143 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' -import forEach from 'lodash/forEach.js' +import tap from 'tap'; +import forEach from 'lodash/forEach.js'; import { checkIfResponseIsOk as checkIfResIsOk, request, -} from '../../lib/request.js' +} from '../../lib/request.js'; import { INVALID_REQUEST, NOT_FOUND, HafasError, HafasInvalidRequestError, HafasNotFoundError, -} from '../../lib/errors.js' -import {formatTripReq} from '../../format/trip-req.js' +} from '../../lib/errors.js'; +import {formatTripReq} from '../../format/trip-req.js'; -const resParameter = require('../fixtures/error-parameter.json') -const resNoMatch = require('../fixtures/error-no-match.json') -const resH9360 = require('../fixtures/error-h9360.json') -const resLocation = require('../fixtures/error-location.json') +const resParameter = require('../fixtures/error-parameter.json'); +const resNoMatch = require('../fixtures/error-no-match.json'); +const resH9360 = require('../fixtures/error-h9360.json'); +const resLocation = require('../fixtures/error-location.json'); -const USER_AGENT = 'public-transport/hafas-client:test' +const USER_AGENT = 'public-transport/hafas-client:test'; -const secret = Symbol('secret') +const secret = Symbol('secret'); tap.test('checkIfResponseIsOk properly throws HAFAS "H9360" errors', (t) => { try { checkIfResIsOk({ body: resH9360, errProps: {secret}, - }) + }); } catch (err) { - t.ok(err) + t.ok(err); - t.ok(err instanceof HafasError) - t.equal(err.isHafasError, true) - t.equal(err.message.slice(0, 7), 'H9360: ') - t.ok(err.message.length > 7) + t.ok(err instanceof HafasError); + t.equal(err.isHafasError, true); + t.equal(err.message.slice(0, 7), 'H9360: '); + t.ok(err.message.length > 7); - t.ok(err instanceof HafasInvalidRequestError) - t.equal(err.isCausedByServer, false) - t.equal(err.code, INVALID_REQUEST) - t.equal(err.hafasCode, 'H9360') + t.ok(err instanceof HafasInvalidRequestError); + t.equal(err.isCausedByServer, false); + t.equal(err.code, INVALID_REQUEST); + t.equal(err.hafasCode, 'H9360'); - t.equal(err.hafasResponseId, resH9360.id) - t.equal(err.hafasMessage, 'HAFAS Kernel: Date outside of the timetable period.') - t.equal(err.hafasDescription, 'Fehler bei der Datumseingabe oder Datum außerhalb der Fahrplanperiode (01.05.2022 - 10.12.2022)') - t.equal(err.secret, secret) + t.equal(err.hafasResponseId, resH9360.id); + t.equal(err.hafasMessage, 'HAFAS Kernel: Date outside of the timetable period.'); + t.equal(err.hafasDescription, 'Fehler bei der Datumseingabe oder Datum außerhalb der Fahrplanperiode (01.05.2022 - 10.12.2022)'); + t.equal(err.secret, secret); - t.end() + t.end(); } -}) +}); tap.test('checkIfResponseIsOk properly throws HAFAS "LOCATION" errors', (t) => { try { checkIfResIsOk({ body: resLocation, errProps: {secret}, - }) + }); } catch (err) { - t.ok(err) + t.ok(err); - t.ok(err instanceof HafasError) - t.equal(err.isHafasError, true) - t.equal(err.message.slice(0, 10), 'LOCATION: ') - t.ok(err.message.length > 10) + t.ok(err instanceof HafasError); + t.equal(err.isHafasError, true); + t.equal(err.message.slice(0, 10), 'LOCATION: '); + t.ok(err.message.length > 10); - t.ok(err instanceof HafasNotFoundError) - t.equal(err.isCausedByServer, false) - t.equal(err.code, NOT_FOUND) - t.equal(err.hafasCode, 'LOCATION') + t.ok(err instanceof HafasNotFoundError); + t.equal(err.isCausedByServer, false); + t.equal(err.code, NOT_FOUND); + t.equal(err.hafasCode, 'LOCATION'); - t.equal(err.hafasResponseId, resLocation.id) - t.equal(err.hafasMessage, 'HCI Service: location missing or invalid') - t.equal(err.hafasDescription, 'Während der Suche ist ein interner Fehler aufgetreten') - t.equal(err.secret, secret) + t.equal(err.hafasResponseId, resLocation.id); + t.equal(err.hafasMessage, 'HCI Service: location missing or invalid'); + t.equal(err.hafasDescription, 'Während der Suche ist ein interner Fehler aufgetreten'); + t.equal(err.secret, secret); - t.end() + t.end(); } -}) +}); tap.test('checkIfResponseIsOk properly throws HAFAS "NO_MATCH" errors', (t) => { try { checkIfResIsOk({ body: resNoMatch, errProps: {secret}, - }) + }); } catch (err) { - t.ok(err) + t.ok(err); - t.ok(err instanceof HafasError) - t.equal(err.isHafasError, true) - t.equal(err.message.slice(0, 10), 'NO_MATCH: ') - t.ok(err.message.length > 10) + t.ok(err instanceof HafasError); + t.equal(err.isHafasError, true); + t.equal(err.message.slice(0, 10), 'NO_MATCH: '); + t.ok(err.message.length > 10); - t.ok(err instanceof HafasNotFoundError) - t.equal(err.isCausedByServer, false) - t.equal(err.code, NOT_FOUND) - t.equal(err.hafasCode, 'NO_MATCH') + t.ok(err instanceof HafasNotFoundError); + t.equal(err.isCausedByServer, false); + t.equal(err.code, NOT_FOUND); + t.equal(err.hafasCode, 'NO_MATCH'); - t.equal(err.hafasResponseId, resNoMatch.id) - t.equal(err.hafasMessage, 'Nothing found.') - t.equal(err.hafasDescription, 'Während der Suche ist leider ein interner Fehler aufgetreten. Bitte wenden Sie sich an unsere Serviceauskunft unter Tel. 0421 596059.') - t.equal(err.secret, secret) + t.equal(err.hafasResponseId, resNoMatch.id); + t.equal(err.hafasMessage, 'Nothing found.'); + t.equal(err.hafasDescription, 'Während der Suche ist leider ein interner Fehler aufgetreten. Bitte wenden Sie sich an unsere Serviceauskunft unter Tel. 0421 596059.'); + t.equal(err.secret, secret); - t.end() + t.end(); } -}) +}); tap.test('checkIfResponseIsOk properly throws HAFAS "PARAMETER" errors', (t) => { try { checkIfResIsOk({ body: resParameter, errProps: {secret}, - }) + }); } catch (err) { - t.ok(err) + t.ok(err); - t.ok(err instanceof HafasError) - t.equal(err.isHafasError, true) - t.equal(err.message.slice(0, 11), 'PARAMETER: ') - t.ok(err.message.length > 11) + t.ok(err instanceof HafasError); + t.equal(err.isHafasError, true); + t.equal(err.message.slice(0, 11), 'PARAMETER: '); + t.ok(err.message.length > 11); - t.ok(err instanceof HafasInvalidRequestError) - t.equal(err.isCausedByServer, false) - t.equal(err.code, INVALID_REQUEST) - t.equal(err.hafasCode, 'PARAMETER') + t.ok(err instanceof HafasInvalidRequestError); + t.equal(err.isCausedByServer, false); + t.equal(err.code, INVALID_REQUEST); + t.equal(err.hafasCode, 'PARAMETER'); - t.equal(err.hafasResponseId, resParameter.id) - t.equal(err.hafasMessage, 'HCI Service: parameter invalid') - t.equal(err.hafasDescription, 'Während der Suche ist ein interner Fehler aufgetreten') - t.equal(err.secret, secret) + t.equal(err.hafasResponseId, resParameter.id); + t.equal(err.hafasMessage, 'HCI Service: parameter invalid'); + t.equal(err.hafasDescription, 'Während der Suche ist ein interner Fehler aufgetreten'); + t.equal(err.secret, secret); - t.end() + t.end(); } -}) +}); tap.test('checkIfResponseIsOk properly parses an unknown HAFAS errors', (t) => { const body = { @@ -147,32 +147,32 @@ tap.test('checkIfResponseIsOk properly parses an unknown HAFAS errors', (t) => { errTxt: 'random errTxt', errTxtOut: 'even more random errTxtOut', svcResL: [], - } + }; try { checkIfResIsOk({ body, errProps: {secret}, - }) + }); } catch (err) { - t.ok(err) + t.ok(err); - t.ok(err instanceof HafasError) - t.equal(err.isHafasError, true) - t.equal(err.message, `${body.err}: ${body.errTxt}`) + t.ok(err instanceof HafasError); + t.equal(err.isHafasError, true); + t.equal(err.message, `${body.err}: ${body.errTxt}`); - t.equal(err.isCausedByServer, false) - t.equal(err.code, null) - t.equal(err.hafasCode, body.err) + t.equal(err.isCausedByServer, false); + t.equal(err.code, null); + t.equal(err.hafasCode, body.err); - t.equal(err.hafasResponseId, body.id) - t.equal(err.hafasMessage, body.errTxt) - t.equal(err.hafasDescription, body.errTxtOut) - t.equal(err.secret, secret) + t.equal(err.hafasResponseId, body.id); + t.equal(err.hafasMessage, body.errTxt); + t.equal(err.hafasDescription, body.errTxtOut); + t.equal(err.secret, secret); - t.end() + t.end(); } -}) +}); const freeze = (val) => { if ( @@ -180,9 +180,9 @@ const freeze = (val) => { && val !== null && !Array.isArray(val) ) { - Object.freeze(val) + Object.freeze(val); } -} +}; const ctx = { // random but unique opt: { @@ -207,33 +207,33 @@ const ctx = { transformReq: (_, req) => req, }, -} -forEach(ctx, freeze) +}; +forEach(ctx, freeze); tap.test('lib/request calls profile.transformReqBody & profile.transformReq properly', async (t) => { const customTransformReqBody = (ctx, reqBody) => { - const p = 'transformReqBody call: ' - t.same(ctx, customCtx, 'ctx should be the passed-in ctx') + const p = 'transformReqBody call: '; + t.same(ctx, customCtx, 'ctx should be the passed-in ctx'); - t.ok(reqBody, 'reqBody') - t.equal(reqBody.client, ctx.profile.client, p + 'reqBody.client') - t.equal(reqBody.ext, ctx.profile.ext, p + 'reqBody.ext') - t.equal(reqBody.var, ctx.profile.var, p + 'reqBody.var') - t.equal(reqBody.auth, ctx.profile.auth, p + 'reqBody.auth') - t.equal(reqBody.lang, ctx.opt.language, p + 'reqBody.lang') + t.ok(reqBody, 'reqBody'); + t.equal(reqBody.client, ctx.profile.client, p + 'reqBody.client'); + t.equal(reqBody.ext, ctx.profile.ext, p + 'reqBody.ext'); + t.equal(reqBody.var, ctx.profile.var, p + 'reqBody.var'); + t.equal(reqBody.auth, ctx.profile.auth, p + 'reqBody.auth'); + t.equal(reqBody.lang, ctx.opt.language, p + 'reqBody.lang'); // We test if lib/request.js handles returning a new object. return { ...reqBody, - } - } + }; + }; const customTransformReq = (ctx, req) => { - const p = 'transformReq call: ' - t.same(ctx, customCtx, p + 'ctx should be the passed-in ctx') + const p = 'transformReq call: '; + t.same(ctx, customCtx, p + 'ctx should be the passed-in ctx'); - t.equal(typeof req.body, 'string', p + 'req.body') - t.ok(req.body, p + 'req.body') + t.equal(typeof req.body, 'string', p + 'req.body'); + t.ok(req.body, p + 'req.body'); // We test if lib/request.js handles returning a new object. return { @@ -241,8 +241,8 @@ tap.test('lib/request calls profile.transformReqBody & profile.transformReq prop // From node-fetch, used by isomorphic-fetch: // > req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies). Signal is recommended instead. timeout: 100, - } - } + }; + }; const customCtx = { ...ctx, @@ -251,12 +251,12 @@ tap.test('lib/request calls profile.transformReqBody & profile.transformReq prop transformReqBody: customTransformReqBody, transformReq: customTransformReq, }, - } - const tripReq = formatTripReq(customCtx, 'unknown-trip-id') + }; + const tripReq = formatTripReq(customCtx, 'unknown-trip-id'); // todo: set 1s timeout await t.rejects(async () => { - await request(customCtx, USER_AGENT, tripReq) - }) - t.end() -}) + await request(customCtx, USER_AGENT, tripReq); + }); + t.end(); +}); diff --git a/test/mobiliteit-lu-line.js b/test/mobiliteit-lu-line.js index 8b7b3199f..cd6de6d00 100644 --- a/test/mobiliteit-lu-line.js +++ b/test/mobiliteit-lu-line.js @@ -1,15 +1,15 @@ -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/mobiliteit-lu/index.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/mobiliteit-lu/index.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { linesOfStops: false, // parse & expose lines at the stop/station? remarks: true, -} +}; tap.test('parses a line correctly (mobiliteit.lu)', (t) => { const rawLine = { @@ -30,10 +30,10 @@ tap.test('parses a line correctly (mobiliteit.lu)', (t) => { catCode: '1', admin: 'C88---', }, - } + }; - const ctx = {profile, opt} - const stop = profile.parseLine(ctx, rawLine) + const ctx = {profile, opt}; + const stop = profile.parseLine(ctx, rawLine); t.same(stop, { type: 'line', @@ -45,6 +45,6 @@ tap.test('parses a line correctly (mobiliteit.lu)', (t) => { productName: 'IC', mode: 'train', product: 'national-train', - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/oebb-trip.js b/test/oebb-trip.js index 214e8bce1..c35310deb 100644 --- a/test/oebb-trip.js +++ b/test/oebb-trip.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/oebb/index.js' -const res = require('./fixtures/oebb-trip.json') -import {oebbTrip as expected} from './fixtures/oebb-trip.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/oebb/index.js'; +const res = require('./fixtures/oebb-trip.json'); +import {oebbTrip as expected} from './fixtures/oebb-trip.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { stopovers: true, @@ -20,13 +20,13 @@ const opt = { entrances: true, remarks: true, when: '2020-06-11T15:25:00+02:00', -} +}; tap.test('parses a trip correctly (ÖBB)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const trip = profile.parseTrip(ctx, res.journey) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const trip = profile.parseTrip(ctx, res.journey); - t.same(trip, expected) - t.end() -}) + t.same(trip, expected); + t.end(); +}); diff --git a/test/parse/date-time.js b/test/parse/date-time.js index 82cd96100..f94b34d33 100644 --- a/test/parse/date-time.js +++ b/test/parse/date-time.js @@ -1,5 +1,5 @@ -import tap from 'tap' -import {parseDateTime as parse} from '../../parse/date-time.js' +import tap from 'tap'; +import {parseDateTime as parse} from '../../parse/date-time.js'; const ctx = { common: {}, @@ -8,46 +8,46 @@ const ctx = { timezone: 'Europe/Berlin', locale: 'de-DE', }, -} +}; tap.test('date & time parsing returns a timestamp', (t) => { - const iso = parse(ctx, '20190819', '203000', undefined, false) - const ts = parse(ctx, '20190819', '203000', undefined, true) - t.equal(ts, Number(new Date(iso))) - t.equal(ts, 1566239400 * 1000) - t.end() -}) + const iso = parse(ctx, '20190819', '203000', undefined, false); + const ts = parse(ctx, '20190819', '203000', undefined, true); + t.equal(ts, Number(new Date(iso))); + t.equal(ts, 1566239400 * 1000); + t.end(); +}); tap.test('date & time parsing uses tzOffset', (t) => { - const iso = parse(ctx, '20190819', '203000', -120, false) - t.equal(iso, '2019-08-19T20:30:00-02:00') - t.end() -}) + const iso = parse(ctx, '20190819', '203000', -120, false); + t.equal(iso, '2019-08-19T20:30:00-02:00'); + t.end(); +}); tap.test('date & time parsing works with day "overflow"', (t) => { - const iso = parse(ctx, '20190819', '02203000', undefined, false) - t.equal(iso, '2019-08-21T20:30:00+02:00') - t.end() -}) + const iso = parse(ctx, '20190819', '02203000', undefined, false); + t.equal(iso, '2019-08-21T20:30:00+02:00'); + t.end(); +}); // #106 tap.test('date & time parsing works with day "overflow" & tzOffset', (t) => { - const iso = parse(ctx, '20190819', '02203000', -120, false) - t.equal(iso, '2019-08-21T20:30:00-02:00') - t.end() -}) + const iso = parse(ctx, '20190819', '02203000', -120, false); + t.equal(iso, '2019-08-21T20:30:00-02:00'); + t.end(); +}); tap.test('date & time parsing works with summer & winter time', (t) => { - const iso = parse(ctx, '20190219', '203000', undefined, false) - t.equal(iso, '2019-02-19T20:30:00+01:00') - t.end() -}) + const iso = parse(ctx, '20190219', '203000', undefined, false); + t.equal(iso, '2019-02-19T20:30:00+01:00'); + t.end(); +}); tap.test('date & time parsing uses profile.timezone', (t) => { const iso = parse({ ...ctx, profile: {...ctx.profile, timezone: 'Europe/Moscow'}, - }, '20190819', '203000', undefined, false) - t.equal(iso, '2019-08-19T20:30:00+03:00') - t.end() -}) + }, '20190819', '203000', undefined, false); + t.equal(iso, '2019-08-19T20:30:00+03:00'); + t.end(); +}); diff --git a/test/parse/hint.js b/test/parse/hint.js index 1917177c1..3cbce0034 100644 --- a/test/parse/hint.js +++ b/test/parse/hint.js @@ -1,11 +1,11 @@ -import tap from 'tap' -import {parseHint as parse} from '../../parse/hint.js' +import tap from 'tap'; +import {parseHint as parse} from '../../parse/hint.js'; const ctx = { data: {}, opt: {}, profile: {}, -} +}; tap.test('parses hints correctly', (t) => { const input = { @@ -13,46 +13,46 @@ tap.test('parses hints correctly', (t) => { code: 'bf', prio: 123, txtN: 'some text', - } + }; const expected = { type: 'hint', code: 'bf', text: 'some text', - } + }; - t.same(parse(ctx, input), expected) + t.same(parse(ctx, input), expected); t.same(parse(ctx, { ...input, type: 'I', - }), expected) + }), expected); // alternative trip t.same(parse(ctx, { ...input, type: 'L', jid: 'trip id', }), { ...expected, type: 'status', code: 'alternative-trip', tripId: 'trip id', - }) + }); // type: M t.same(parse(ctx, { ...input, type: 'M', txtS: 'some summary', }), { ...expected, type: 'status', summary: 'some summary', - }) + }); // type: D for (const type of ['D', 'U', 'R', 'N', 'Y']) { t.same(parse(ctx, {...input, type}), { ...expected, type: 'status', - }) + }); } // .code via .icon t.same(parse(ctx, { ...input, code: null, icon: {type: 'cancel'}, - }), {...expected, code: 'cancelled'}) + }), {...expected, code: 'cancelled'}); // invalid - t.equal(parse(ctx, {...input, type: 'X'}), null) + t.equal(parse(ctx, {...input, type: 'X'}), null); - t.end() -}) + t.end(); +}); diff --git a/test/parse/icon.js b/test/parse/icon.js index 5fff74f4a..0919a0266 100644 --- a/test/parse/icon.js +++ b/test/parse/icon.js @@ -1,47 +1,47 @@ -import tap from 'tap' -import {parseIcon as parse} from '../../parse/icon.js' +import tap from 'tap'; +import {parseIcon as parse} from '../../parse/icon.js'; const ctx = { data: {}, opt: {}, profile: {}, -} +}; tap.test('parses icons correctly', (t) => { const text = { res: 'BVG', text: 'Berliner Verkehrsbetriebe', - } + }; t.same(parse(ctx, text), { type: 'BVG', title: 'Berliner Verkehrsbetriebe', - }) + }); const txtS = { res: 'PROD_BUS', txtS: '18', - } + }; t.same(parse(ctx, txtS), { type: 'PROD_BUS', title: '18', - }) + }); const txt = { res: 'RBB', txt: 'Regionalbus Braunschweig GmbH', - } + }; t.same(parse(ctx, txt), { type: 'RBB', title: 'Regionalbus Braunschweig GmbH', - }) + }); const noText = { res: 'attr_bike_r', - } + }; t.same(parse(ctx, noText), { type: 'attr_bike_r', title: null, - }) + }); const withColor = { res: 'prod_sub_t', @@ -57,18 +57,18 @@ tap.test('parses icons correctly', (t) => { b: 153, a: 255, }, - } + }; t.same(parse(ctx, withColor), { type: 'prod_sub_t', title: null, fgColor: {r: 255, g: 255, b: 255, a: 255}, bgColor: {r: 0, g: 51, b: 153, a: 255}, - }) + }); const empty = { res: 'Empty', - } - t.equal(parse(ctx, empty), null) + }; + t.equal(parse(ctx, empty), null); - t.end() -}) + t.end(); +}); diff --git a/test/parse/line.js b/test/parse/line.js index 25d72ea09..518f9cb42 100644 --- a/test/parse/line.js +++ b/test/parse/line.js @@ -1,6 +1,6 @@ -import tap from 'tap' -import omit from 'lodash/omit.js' -import {parseLine as parse} from '../../parse/line.js' +import tap from 'tap'; +import omit from 'lodash/omit.js'; +import {parseLine as parse} from '../../parse/line.js'; const profile = { products: [ @@ -8,12 +8,12 @@ const profile = { {id: 'ferry', bitmasks: [2]}, {id: 'bus', bitmasks: [4, 8]}, ], -} +}; const ctx = { data: {}, opt: {}, profile, -} +}; tap.test('parses lines correctly', (t) => { const input = { @@ -24,7 +24,7 @@ tap.test('parses lines correctly', (t) => { // HAFAS endpoints commonly have these padded admin codes. admin: 'foo---', }, - } + }; const expected = { type: 'line', id: 'foo', @@ -32,23 +32,23 @@ tap.test('parses lines correctly', (t) => { name: 'foo line', public: true, adminCode: 'foo---', - } + }; - t.same(parse(ctx, input), expected) + t.same(parse(ctx, input), expected); t.same(parse(ctx, { ...input, line: null, addName: input.line, - }), expected) + }), expected); t.same(parse(ctx, { ...input, line: null, name: input.line, - }), expected) + }), expected); // no prodCtx.lineId t.same(parse(ctx, { ...input, prodCtx: {...input.prodCtx, lineId: null}, }), { ...expected, id: 'foo-line', - }) + }); // no prodCtx t.same(parse(ctx, { ...input, prodCtx: undefined, @@ -58,6 +58,6 @@ tap.test('parses lines correctly', (t) => { ]), id: 'foo-line', fahrtNr: null, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/parse/location.js b/test/parse/location.js index a8f6636b4..3870bccf1 100644 --- a/test/parse/location.js +++ b/test/parse/location.js @@ -1,12 +1,12 @@ -import tap from 'tap' -import omit from 'lodash/omit.js' -import {parseLocation as parse} from '../../parse/location.js' +import tap from 'tap'; +import omit from 'lodash/omit.js'; +import {parseLocation as parse} from '../../parse/location.js'; const profile = { parseLocation: parse, parseStationName: (_, name) => name.toLowerCase(), parseProductsBitmask: (_, bitmask) => [bitmask], -} +}; const ctx = { data: {}, @@ -16,7 +16,7 @@ const ctx = { entrances: true, }, profile, -} +}; tap.test('parses an address correctly', (t) => { const input = { @@ -24,19 +24,19 @@ tap.test('parses an address correctly', (t) => { name: 'Foo street 3', lid: 'a=b@L=some%20id', crd: {x: 13418027, y: 52515503}, - } + }; - const address = parse(ctx, input) + const address = parse(ctx, input); t.same(address, { type: 'location', id: 'some id', address: 'Foo street 3', latitude: 52.515503, longitude: 13.418027, - }) + }); - t.end() -}) + t.end(); +}); tap.test('parses a POI correctly', (t) => { const input = { @@ -44,9 +44,9 @@ tap.test('parses a POI correctly', (t) => { name: 'some POI', lid: 'a=b@L=some%20id', crd: {x: 13418027, y: 52515503}, - } + }; - const poi = parse(ctx, input) + const poi = parse(ctx, input); t.same(poi, { type: 'location', poi: true, @@ -54,16 +54,16 @@ tap.test('parses a POI correctly', (t) => { name: 'some POI', latitude: 52.515503, longitude: 13.418027, - }) + }); - const withExtId = parse(ctx, {...input, extId: 'some ext id'}) - t.equal(withExtId.id, 'some ext id') + const withExtId = parse(ctx, {...input, extId: 'some ext id'}); + t.equal(withExtId.id, 'some ext id'); - const withLeadingZero = parse(ctx, {...input, extId: '00some ext id'}) - t.equal(withLeadingZero.id, 'some ext id') + const withLeadingZero = parse(ctx, {...input, extId: '00some ext id'}); + t.equal(withLeadingZero.id, 'some ext id'); - t.end() -}) + t.end(); +}); const fooBusStop = { type: 'S', @@ -71,10 +71,10 @@ const fooBusStop = { lid: 'a=b@L=foo%20stop', crd: {x: 13418027, y: 52515503}, pCls: 123, -} +}; tap.test('parses a stop correctly', (t) => { - const stop = parse(ctx, fooBusStop) + const stop = parse(ctx, fooBusStop); t.same(stop, { type: 'stop', id: 'foo stop', @@ -86,40 +86,40 @@ tap.test('parses a stop correctly', (t) => { longitude: 13.418027, }, products: [123], - }) + }); - const withoutLoc = parse(ctx, omit(fooBusStop, ['crd'])) - t.equal(withoutLoc.location, null) + const withoutLoc = parse(ctx, omit(fooBusStop, ['crd'])); + t.equal(withoutLoc.location, null); - const mainMast = parse(ctx, {...fooBusStop, isMainMast: true}) - t.equal(mainMast.type, 'station') + const mainMast = parse(ctx, {...fooBusStop, isMainMast: true}); + t.equal(mainMast.type, 'station'); - const meta = parse(ctx, {...fooBusStop, meta: 1}) - t.equal(meta.isMeta, true) + const meta = parse(ctx, {...fooBusStop, meta: 1}); + t.equal(meta.isMeta, true); - const lineA = {id: 'a'} + const lineA = {id: 'a'}; const withLines = parse({ ...ctx, opt: {...ctx.opt, linesOfStops: true}, }, { ...fooBusStop, lines: [lineA], - }) - t.same(withLines.lines, [lineA]) + }); + t.same(withLines.lines, [lineA]); - t.end() -}) + t.end(); +}); tap.test('falls back to coordinates from `lid`', (t) => { const {location} = parse(ctx, { type: 'S', name: 'foo', lid: 'a=b@L=foo@X=12345678@Y=23456789', - }) - t.ok(location) - t.equal(location.latitude, 23.456789) - t.equal(location.longitude, 12.345678) - t.end() -}) + }); + t.ok(location); + t.equal(location.latitude, 23.456789); + t.equal(location.longitude, 12.345678); + t.end(); +}); tap.test('handles recursive references properly', (t) => { const southernInput = { @@ -130,7 +130,7 @@ tap.test('handles recursive references properly', (t) => { // This doesn't make sense semantically, but we test if // `parseLocation` falls into an endless recursive loop. stopLocL: [1], - } + }; const northernInput = { type: 'S', name: 'Northern Platform', @@ -139,9 +139,9 @@ tap.test('handles recursive references properly', (t) => { // This doesn't make sense semantically, but we test if // `parseLocation` falls into an endless recursive loop. entryLocL: [0], - } - const common = {locL: [southernInput, northernInput]} - const _ctx = {...ctx, res: {common}} + }; + const common = {locL: [southernInput, northernInput]}; + const _ctx = {...ctx, res: {common}}; const northernExpected = { type: 'stop', @@ -152,7 +152,7 @@ tap.test('handles recursive references properly', (t) => { id: 'northern-platform', latitude: 33.333333, longitude: 44.444444, }, - } + }; const southernExpected = { type: 'station', id: 'southern-platform', @@ -163,20 +163,20 @@ tap.test('handles recursive references properly', (t) => { latitude: 11.111111, longitude: 22.222222, }, stops: [northernExpected], - } + }; const {entrances} = parse(_ctx, { ...fooBusStop, entryLocL: [0], - }) - t.same(entrances, [southernExpected.location]) + }); + t.same(entrances, [southernExpected.location]); const {type, stops} = parse(_ctx, { ...fooBusStop, stopLocL: [0], - }) - t.equal(type, 'station') - t.same(stops, [southernExpected]) + }); + t.equal(type, 'station'); + t.same(stops, [southernExpected]); - t.end() -}) + t.end(); +}); diff --git a/test/parse/operator.js b/test/parse/operator.js index 2de78b3af..6b4a8273b 100644 --- a/test/parse/operator.js +++ b/test/parse/operator.js @@ -1,22 +1,22 @@ -import tap from 'tap' -import {parseOperator as parse} from '../../parse/operator.js' +import tap from 'tap'; +import {parseOperator as parse} from '../../parse/operator.js'; const ctx = { data: {}, opt: {}, profile: {}, -} +}; tap.test('parses an operator correctly', (t) => { const op = { name: 'Berliner Verkehrsbetriebe', icoX: 1, id: 'Berliner Verkehrsbetriebe', - } + }; t.same(parse(ctx, op), { type: 'operator', id: 'berliner-verkehrsbetriebe', name: 'Berliner Verkehrsbetriebe', - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/parse/warning.js b/test/parse/warning.js index a5c264ba3..ecd374f5b 100644 --- a/test/parse/warning.js +++ b/test/parse/warning.js @@ -1,16 +1,16 @@ -import tap from 'tap' -import {parseWarning as parse} from '../../parse/warning.js' -import merge from 'lodash/merge.js' +import tap from 'tap'; +import {parseWarning as parse} from '../../parse/warning.js'; +import merge from 'lodash/merge.js'; const profile = { parseProductsBitmask: (_, bitmask) => [bitmask], parseDateTime: (_, date, time) => date + ':' + time, -} +}; const ctx = { data: {}, opt: {}, profile, -} +}; tap.test('parses warnings correctly', (t) => { const input = { @@ -20,7 +20,7 @@ tap.test('parses warnings correctly', (t) => { icon: {type: 'HimWarn'}, // todo: null prio: 123, cat: 1, - } + }; const expected = { id: 'some warning ID', type: 'status', @@ -29,25 +29,25 @@ tap.test('parses warnings correctly', (t) => { icon: {type: 'HimWarn'}, priority: 123, category: 1, - } + }; - t.same(parse(ctx, input), expected) + t.same(parse(ctx, input), expected); // without basic fields - t.same(parse(ctx, {...input, hid: null}), {...expected, id: null}) - t.same(parse(ctx, {...input, head: null}), {...expected, summary: null}) - t.same(parse(ctx, {...input, text: null}), {...expected, text: null}) - t.same(parse(ctx, {...input, cat: null}), {...expected, category: null}) + t.same(parse(ctx, {...input, hid: null}), {...expected, id: null}); + t.same(parse(ctx, {...input, head: null}), {...expected, summary: null}); + t.same(parse(ctx, {...input, text: null}), {...expected, text: null}); + t.same(parse(ctx, {...input, cat: null}), {...expected, category: null}); // without icon t.same(parse(ctx, {...input, icon: null}), { ...expected, type: 'warning', icon: null, - }) + }); // with products t.same(parse(ctx, {...input, prod: 123}), { ...expected, products: [123], - }) + }); // validFrom, validUntil, modified t.same(parse(ctx, { @@ -60,7 +60,7 @@ tap.test('parses warnings correctly', (t) => { validFrom: '20190101:094020', validUntil: '20190101:114020', modified: '20190101:084020', - }) + }); // events const ctxWithHimMsgEventL = { @@ -73,11 +73,11 @@ tap.test('parses warnings correctly', (t) => { }], }, }, - } + }; const inputWithEventRefL = { ...input, eventRefL: [0], - } + }; const expectedWithEvents = { ...expected, events: [{ @@ -87,11 +87,11 @@ tap.test('parses warnings correctly', (t) => { end: '20211221:012345', sections: [], }], - } + }; t.same(parse( ctxWithHimMsgEventL, inputWithEventRefL, - ), expectedWithEvents) + ), expectedWithEvents); // without res.common.himMsgEventL[].{f,t}Time t.same(parse( merge(ctxWithHimMsgEventL, { @@ -110,9 +110,9 @@ tap.test('parses warnings correctly', (t) => { start: '20211111:000000', end: '20211221:000000', }], - })) + })); // todo: .edges - t.end() -}) + t.end(); +}); diff --git a/test/parse/when.js b/test/parse/when.js index 27e9ac1a8..7134724d1 100644 --- a/test/parse/when.js +++ b/test/parse/when.js @@ -1,43 +1,43 @@ -import tap from 'tap' -import {parseWhen as parse} from '../../parse/when.js' +import tap from 'tap'; +import {parseWhen as parse} from '../../parse/when.js'; const profile = { parseDateTime: ({profile}, date, time, tzOffset, timestamp = false) => { if (timestamp) { - return (String(date) + time - tzOffset * 60) * 1000 + return (String(date) + time - tzOffset * 60) * 1000; } - return date + ':' + time + return date + ':' + time; }, -} +}; const ctx = { data: {}, opt: {}, profile, -} +}; tap.test('parseWhen works correctly', (t) => { - const date = '20190606' - const timeS = '163000' - const timeR = '163130' - const tzOffset = 120 + const date = '20190606'; + const timeS = '163000'; + const timeR = '163130'; + const tzOffset = 120; const expected = { when: '20190606:163130', plannedWhen: '20190606:163000', delay: 130, // seconds - } + }; - t.same(parse(ctx, date, timeS, timeR, tzOffset), expected) + t.same(parse(ctx, date, timeS, timeR, tzOffset), expected); // no realtime data t.same(parse(ctx, date, timeS, null, tzOffset), { ...expected, when: expected.plannedWhen, delay: null, - }) + }); // cancelled t.same(parse(ctx, date, timeS, timeR, tzOffset, true), { ...expected, when: null, prognosedWhen: expected.when, - }) - t.end() -}) + }); + t.end(); +}); diff --git a/test/rejseplanen-trip.js b/test/rejseplanen-trip.js index 00087ee84..8888f48f9 100644 --- a/test/rejseplanen-trip.js +++ b/test/rejseplanen-trip.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/rejseplanen/index.js' -const res = require('./fixtures/rejseplanen-trip.json') -import {rejseplanenTrip as expected} from './fixtures/rejseplanen-trip.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/rejseplanen/index.js'; +const res = require('./fixtures/rejseplanen-trip.json'); +import {rejseplanenTrip as expected} from './fixtures/rejseplanen-trip.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { stopovers: true, @@ -20,13 +20,13 @@ const opt = { entrances: true, remarks: true, when: '2021-11-12T17:30:00+02:00', -} +}; tap.test('parses a trip correctly (Rejseplanen)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const trip = profile.parseTrip(ctx, res.journey) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const trip = profile.parseTrip(ctx, res.journey); - t.same(trip, expected) - t.end() -}) + t.same(trip, expected); + t.end(); +}); diff --git a/test/retry.js b/test/retry.js index 80c329d3f..d7eba7cec 100644 --- a/test/retry.js +++ b/test/retry.js @@ -1,35 +1,35 @@ -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {withRetrying} from '../retry.js' -import {profile as vbbProfile} from '../p/vbb/index.js' +import {createClient} from '../index.js'; +import {withRetrying} from '../retry.js'; +import {profile as vbbProfile} from '../p/vbb/index.js'; -const userAgent = 'public-transport/hafas-client:test' -const spichernstr = '900000042101' +const userAgent = 'public-transport/hafas-client:test'; +const spichernstr = '900000042101'; tap.test('withRetrying works', (t) => { // for the first 3 calls, return different kinds of errors - let calls = 0 + let calls = 0; const failingRequest = async (ctx, userAgent, reqData) => { - calls++ + calls++; if (calls === 1) { - const err = new Error('HAFAS error') - err.isHafasError = true - return Promise.reject(err) + const err = new Error('HAFAS error'); + err.isHafasError = true; + return Promise.reject(err); } if (calls === 2) { - const err = new Error('fetch error') - err.code = 'EFOO' - return Promise.reject(err) + const err = new Error('fetch error'); + err.code = 'EFOO'; + return Promise.reject(err); } if (calls < 4) { - return Promise.reject(new Error('generic error')) + return Promise.reject(new Error('generic error')); } return { res: [], common: {}, - } - } + }; + }; const profile = withRetrying({ ...vbbProfile, @@ -39,23 +39,23 @@ tap.test('withRetrying works', (t) => { minTimeout: 100, factor: 2, randomize: false, - }) - const client = createClient(profile, userAgent) + }); + const client = createClient(profile, userAgent); - t.plan(2 + 4) + t.plan(2 + 4); client.departures(spichernstr, {duration: 1}) .then((res) => { const { departures: deps, realtimeDataUpdatedAt, - } = res - t.same(deps, [], 'resolved with invalid value') - t.equal(realtimeDataUpdatedAt, null, 'resolved with invalid value') + } = res; + t.same(deps, [], 'resolved with invalid value'); + t.equal(realtimeDataUpdatedAt, null, 'resolved with invalid value'); }) - .catch(t.ifError) + .catch(t.ifError); - setTimeout(() => t.equal(calls, 1), 50) // buffer - setTimeout(() => t.equal(calls, 2), 200) // 100 + buffer - setTimeout(() => t.equal(calls, 3), 450) // 100 + 200 + buffer - setTimeout(() => t.equal(calls, 4), 900) // 100 + 200 + 400 + buffer -}) + setTimeout(() => t.equal(calls, 1), 50); // buffer + setTimeout(() => t.equal(calls, 2), 200); // 100 + buffer + setTimeout(() => t.equal(calls, 3), 450); // 100 + 200 + buffer + setTimeout(() => t.equal(calls, 4), 900); // 100 + 200 + 400 + buffer +}); diff --git a/test/rsag-journey.js b/test/rsag-journey.js index 698fa27ae..c8173a65a 100644 --- a/test/rsag-journey.js +++ b/test/rsag-journey.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/rsag/index.js' -const res = require('./fixtures/rsag-journey.json') -import {rsagJourneys as expected} from './fixtures/rsag-journey.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/rsag/index.js'; +const res = require('./fixtures/rsag-journey.json'); +import {rsagJourneys as expected} from './fixtures/rsag-journey.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { stopovers: false, @@ -21,13 +21,13 @@ const opt = { entrances: true, remarks: false, products: {}, -} +}; tap.test('parses a journey correctly (RSAG)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const journey = profile.parseJourney(ctx, res.outConL[0]) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const journey = profile.parseJourney(ctx, res.outConL[0]); - t.same(journey, expected) - t.end() -}) + t.same(journey, expected); + t.end(); +}); diff --git a/test/sncb-journey-with-chki.js b/test/sncb-journey-with-chki.js index 54a1851b2..8aee3c95b 100644 --- a/test/sncb-journey-with-chki.js +++ b/test/sncb-journey-with-chki.js @@ -1,16 +1,16 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/sncb/index.js' -const resWithChkiLeg = require('./fixtures/sncb-journey-with-chki.json') +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/sncb/index.js'; +const resWithChkiLeg = require('./fixtures/sncb-journey-with-chki.json'); -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { stopovers: false, @@ -19,14 +19,14 @@ const opt = { subStops: false, entrances: false, remarks: true, -} +}; tap.test('parses a journey with a CHKI leg (#267)', (t) => { - const common = profile.parseCommon({profile, opt, res: resWithChkiLeg}) - const ctx = {profile, opt, common, res: resWithChkiLeg} - const journey = profile.parseJourney(ctx, resWithChkiLeg.outConL[0]) + const common = profile.parseCommon({profile, opt, res: resWithChkiLeg}); + const ctx = {profile, opt, common, res: resWithChkiLeg}; + const journey = profile.parseJourney(ctx, resWithChkiLeg.outConL[0]); - const checkinLeg = journey.legs[0] - t.equal(checkinLeg.checkin, true, 'checkinLeg.checkin') - t.end() -}) + const checkinLeg = journey.legs[0]; + t.equal(checkinLeg.checkin, true, 'checkinLeg.checkin'); + t.end(); +}); diff --git a/test/throttle.js b/test/throttle.js index 509e81d13..7438ff402 100644 --- a/test/throttle.js +++ b/test/throttle.js @@ -1,41 +1,41 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {withThrottling} from '../throttle.js' -import {profile as vbbProfile} from '../p/vbb/index.js' -const depsRes = require('./fixtures/vbb-departures.json') +import {createClient} from '../index.js'; +import {withThrottling} from '../throttle.js'; +import {profile as vbbProfile} from '../p/vbb/index.js'; +const depsRes = require('./fixtures/vbb-departures.json'); -const ua = 'public-transport/hafas-client:test' -const spichernstr = '900000042101' +const ua = 'public-transport/hafas-client:test'; +const spichernstr = '900000042101'; tap.test('withThrottling works', {timeout: 3000}, (t) => { - let calls = 0 + let calls = 0; const mockedRequest = async (ctx, userAgent, reqData) => { - calls++ + calls++; return { res: depsRes, common: ctx.profile.parseCommon({...ctx, res: depsRes}), - } - } + }; + }; const profile = withThrottling({ ...vbbProfile, request: mockedRequest, - }, 2, 1000) - const client = createClient(profile, ua) + }, 2, 1000); + const client = createClient(profile, ua); - t.plan(3) + t.plan(3); for (let i = 0; i < 10; i++) { - const p = client.departures(spichernstr, {duration: 1}) - p.catch(() => {}) + const p = client.departures(spichernstr, {duration: 1}); + p.catch(() => {}); } - setTimeout(() => t.equal(calls, 2), 500) - setTimeout(() => t.equal(calls, 4), 1500) - setTimeout(() => t.equal(calls, 6), 2500) -}) + setTimeout(() => t.equal(calls, 2), 500); + setTimeout(() => t.equal(calls, 4), 1500); + setTimeout(() => t.equal(calls, 6), 2500); +}); diff --git a/test/vbb-departures.js b/test/vbb-departures.js index 1050fc448..08c58d22a 100644 --- a/test/vbb-departures.js +++ b/test/vbb-departures.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/vbb/index.js' -const res = require('./fixtures/vbb-departures.json') -import {vbbDepartures as expected} from './fixtures/vbb-departures.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/vbb/index.js'; +const res = require('./fixtures/vbb-departures.json'); +import {vbbDepartures as expected} from './fixtures/vbb-departures.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { direction: null, @@ -22,13 +22,13 @@ const opt = { includeRelatedStations: true, when: '2021-10-12T17:42:00+02:00', products: {}, -} +}; tap.test('parses a departure correctly (VBB)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const departures = res.jnyL.map(d => profile.parseDeparture(ctx, d)) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const departures = res.jnyL.map(d => profile.parseDeparture(ctx, d)); - t.same(departures, expected) - t.end() -}) + t.same(departures, expected); + t.end(); +}); diff --git a/test/vbb-journeys.js b/test/vbb-journeys.js index d2e02d528..82521dd74 100644 --- a/test/vbb-journeys.js +++ b/test/vbb-journeys.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/vbb/index.js' -const res = require('./fixtures/vbb-journeys.json') -import {vbbJourneys as expected} from './fixtures/vbb-journeys.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/vbb/index.js'; +const res = require('./fixtures/vbb-journeys.json'); +import {vbbJourneys as expected} from './fixtures/vbb-journeys.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: null, @@ -31,13 +31,13 @@ const opt = { scheduledDays: false, departure: '2020-12-07T13:29+01:00', products: {}, -} +}; tap.test('parses a journeys() response correctly (VBB)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const journeys = res.outConL.map(j => profile.parseJourney(ctx, j)) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const journeys = res.outConL.map(j => profile.parseJourney(ctx, j)); - t.same(journeys, expected) - t.end() -}) + t.same(journeys, expected); + t.end(); +}); diff --git a/test/vbb-on-demand-trip.js b/test/vbb-on-demand-trip.js index e8734908a..bcf9b6832 100644 --- a/test/vbb-on-demand-trip.js +++ b/test/vbb-on-demand-trip.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/vbb/index.js' -const res = require('./fixtures/vbb-on-demand-trip.json') -import {vbbOnDemandTrip as expected} from './fixtures/vbb-on-demand-trip.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/vbb/index.js'; +const res = require('./fixtures/vbb-on-demand-trip.json'); +import {vbbOnDemandTrip as expected} from './fixtures/vbb-on-demand-trip.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { stopovers: true, @@ -20,13 +20,13 @@ const opt = { entrances: true, remarks: true, when: '2021-10-24T16:07:00+02:00', -} +}; tap.test('parses an on-demand trip correctly (VBB)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const trip = profile.parseTrip(ctx, res.journey) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const trip = profile.parseTrip(ctx, res.journey); - t.same(trip, expected) - t.end() -}) + t.same(trip, expected); + t.end(); +}); diff --git a/test/vsn-departures.js b/test/vsn-departures.js index bc2ca9cf7..0b84b1a68 100644 --- a/test/vsn-departures.js +++ b/test/vsn-departures.js @@ -1,17 +1,17 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/vsn/index.js' -const res = require('./fixtures/vsn-departures.json') -import {vsnDepartures as expected} from './fixtures/vsn-departures.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/vsn/index.js'; +const res = require('./fixtures/vsn-departures.json'); +import {vsnDepartures as expected} from './fixtures/vsn-departures.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { // results: null, @@ -29,13 +29,13 @@ const opt = { // scheduledDays: false, // departure: '2020-04-10T20:33+02:00', // products: {} -} +}; tap.test('parses departures correctly (VSN)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; - const dep = profile.parseDeparture(ctx, res.jnyL[0]) - t.same(dep, expected) - t.end() -}) + const dep = profile.parseDeparture(ctx, res.jnyL[0]); + t.same(dep, expected); + t.end(); +}); diff --git a/test/vsn-remarks.js b/test/vsn-remarks.js index fedcf519a..5e76ec4ef 100644 --- a/test/vsn-remarks.js +++ b/test/vsn-remarks.js @@ -1,30 +1,30 @@ // todo: use import assertions once they're supported by Node.js & ESLint // https://github.com/tc39/proposal-import-assertions -import {createRequire} from 'module' -const require = createRequire(import.meta.url) +import {createRequire} from 'module'; +const require = createRequire(import.meta.url); -import tap from 'tap' +import tap from 'tap'; -import {createClient} from '../index.js' -import {profile as rawProfile} from '../p/vsn/index.js' -const res = require('./fixtures/vsn-remarks.json') -import {vsnRemarks as expected} from './fixtures/vsn-remarks.js' +import {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/vsn/index.js'; +const res = require('./fixtures/vsn-remarks.json'); +import {vsnRemarks as expected} from './fixtures/vsn-remarks.js'; -const client = createClient(rawProfile, 'public-transport/hafas-client:test') -const {profile} = client +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; const opt = { results: 100, // maximum number of remarks // filter by time from: Date.now(), to: null, products: null, // filter by affected products -} +}; tap.test('parses a remarks() response correctly (VSN)', (t) => { - const common = profile.parseCommon({profile, opt, res}) - const ctx = {profile, opt, common, res} - const warnings = res.msgL.map(w => profile.parseWarning(ctx, w)) + const common = profile.parseCommon({profile, opt, res}); + const ctx = {profile, opt, common, res}; + const warnings = res.msgL.map(w => profile.parseWarning(ctx, w)); - t.same(warnings, expected) - t.end() -}) + t.same(warnings, expected); + t.end(); +}); diff --git a/throttle.js b/throttle.js index 1789452a2..320ee565a 100644 --- a/throttle.js +++ b/throttle.js @@ -1,16 +1,16 @@ -import throttle from 'p-throttle' -import {defaultProfile} from './lib/default-profile.js' +import throttle from 'p-throttle'; +import {defaultProfile} from './lib/default-profile.js'; const withThrottling = (profile, limit = 5, interval = 1000) => { // https://github.com/public-transport/hafas-client/issues/76#issuecomment-574408717 - const {request} = {...defaultProfile, ...profile} + const {request} = {...defaultProfile, ...profile}; return { ...profile, request: throttle({limit, interval})(request), - } -} + }; +}; export { withThrottling, -} +}; diff --git a/tools/debug-cli/cli.js b/tools/debug-cli/cli.js index 245bcc453..e625858ed 100755 --- a/tools/debug-cli/cli.js +++ b/tools/debug-cli/cli.js @@ -1,20 +1,20 @@ #!/usr/bin/env node -import {parseArgs} from 'node:util' -import {createClient} from '../../index.js' +import {parseArgs} from 'node:util'; +import {createClient} from '../../index.js'; const showError = (err) => { - console.error(err) - process.exit(1) -} + console.error(err); + process.exit(1); +}; -const toString = val => String(val) +const toString = val => String(val); const parseJsObject = val => { - const res = eval(`(${val})`) + const res = eval(`(${val})`); return res && 'object' === typeof res ? res - : {} -} + : {}; +}; const methodsAndTheirArgs = [ ['departures', 0, toString], @@ -48,33 +48,33 @@ const methodsAndTheirArgs = [ ['lines', 0, toString], ['lines', 1, parseJsObject], ['serverInfo', 0, parseJsObject], -] +]; const { positionals: args, } = parseArgs({ strict: true, allowPositionals: true, -}) +}); -const profileName = args[0] -const fnName = args[1] +const profileName = args[0]; +const fnName = args[1]; const parsedArgs = args.slice(2) .map((arg, i) => { - const parser = methodsAndTheirArgs.find(([_fnName, _i]) => _fnName === fnName && _i === i) + const parser = methodsAndTheirArgs.find(([_fnName, _i]) => _fnName === fnName && _i === i); return parser ? parser[2](arg) - : arg + : arg; }); (async () => { - const {profile} = await import(`../../p/${profileName}/index.js`) + const {profile} = await import(`../../p/${profileName}/index.js`); - const client = createClient(profile, 'hafas-client debug CLI') + const client = createClient(profile, 'hafas-client debug CLI'); - const fn = client[fnName] + const fn = client[fnName]; - const res = await fn(...parsedArgs) - process.stdout.write(JSON.stringify(res) + '\n') + const res = await fn(...parsedArgs); + process.stdout.write(JSON.stringify(res) + '\n'); })() - .catch(showError) + .catch(showError); diff --git a/tools/endpoint-hci-version/cli.js b/tools/endpoint-hci-version/cli.js index 1310d672c..4930376c0 100755 --- a/tools/endpoint-hci-version/cli.js +++ b/tools/endpoint-hci-version/cli.js @@ -1,7 +1,7 @@ #!/usr/bin/env node -import {parseArgs} from 'node:util' -import {createClient} from '../../index.js' +import {parseArgs} from 'node:util'; +import {createClient} from '../../index.js'; const { values: flags, @@ -19,7 +19,7 @@ const { }, strict: true, allowPositionals: true, -}) +}); if (flags.help) { process.stdout.write(` @@ -30,32 +30,32 @@ Options: represenation. Examples: endpoint-hci-version oebb -\n`) - process.exit(0) +\n`); + process.exit(0); } -const profileName = args[0] +const profileName = args[0]; const silent = flags.silent; (async () => { - const {profile} = await import(`../../p/${profileName}/index.js`) + const {profile} = await import(`../../p/${profileName}/index.js`); const client = createClient( profile, 'hafas-client-endpoint-hci-version', - ) + ); - const {hciVersion: v} = await client.serverInfo() + const {hciVersion: v} = await client.serverInfo(); if ('string' !== typeof v || !v) { - throw new Error('invalid/unexpected server response') + throw new Error('invalid/unexpected server response'); } if (silent) { - console.log(v) + console.log(v); } else { - console.log(v + ' reported as the endpoint version ✔︎') + console.log(v + ' reported as the endpoint version ✔︎'); } })() .catch((err) => { - console.error(err) - process.exit(1) - }) + console.error(err); + process.exit(1); + });