merge oebb into master

This commit is contained in:
Jannis R 2018-01-07 17:13:51 +01:00
commit 0e1bc5e399
No known key found for this signature in database
GPG key ID: 0FE83946296A88A5
15 changed files with 696 additions and 33 deletions

View file

@ -2,6 +2,7 @@
const createFormatBitmask = (modes) => {
const formatBitmask = (products) => {
if(Object.keys(products).length === 0) throw new Error('products filter must not be empty')
let bitmask = 0
for (let product in products) {
if (products[product] === true) bitmask += modes[product].bitmask

18
p/oebb/example.js Normal file
View file

@ -0,0 +1,18 @@
'use strict'
const createClient = require('../..')
const oebbProfile = require('.')
const client = createClient(oebbProfile)
// Wien Westbahnhof to Salzburg Hbf
client.journeys('1291501', '8100002', {results: 1})
// client.departures('8100002', {duration: 1})
// client.locations('Salzburg', {results: 2})
// client.nearby(47.812851, 13.045604, {distance: 60})
// client.radar(47.827203, 13.001261, 47.773278, 13.07562, {results: 10})
.then((data) => {
console.log(require('util').inspect(data, {depth: null}))
})
.catch(console.error)

122
p/oebb/index.js Normal file
View file

@ -0,0 +1,122 @@
'use strict'
// 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
const createParseBitmask = require('../../parse/products-bitmask')
const createFormatBitmask = require('../../format/products-bitmask')
const _parseLine = require('../../parse/line')
const _parseLocation = require('../../parse/location')
const _createParseMovement = require('../../parse/movement')
const products = require('./products')
const transformReqBody = (body) => {
// todo: necessary headers?
body.client = {
type: 'IPA',
id: 'OEBB',
v: '6000500',
name: 'oebbIPAD_ADHOC',
os: 'iOS 10.3.3'
}
// todo: https://gist.github.com/anonymous/a5fc856bc80ae7364721943243f934f4#file-haf_config_base-properties-L33 shows 1.16
body.ver = '1.16'
body.auth = {aid: 'OWDL4fE4ixNiPBBm'}
body.lang = 'de'
return body
}
const parseLine = (profile, l) => {
const res = _parseLine(profile, l)
res.mode = res.product = null
if ('class' in res) {
const data = products.bitmasks[parseInt(res.class)]
if (data) {
res.mode = data.mode
res.product = data.product
}
}
return res
}
const parseLocation = (profile, l) => {
// ÖBB has some 'stations' **in austria** with no departures/products,
// like station entrances, that are actually POIs.
const res = _parseLocation(profile, l)
if (
res.type === 'station' &&
!res.products &&
res.name &&
res.id && res.id.length !== 7
) {
return Object.assign({
type: 'location',
id: res.id,
name: res.name
}, res.location)
}
return res
}
const createParseMovement = (profile, locations, lines, remarks) => {
const _parseMovement = _createParseMovement(profile, locations, lines, remarks)
const parseMovement = (m) => {
const res = _parseMovement(m)
// filter out POIs
// todo: make use of them, as some of them specify fare zones
res.nextStops = res.nextStops.filter(s => s.type === 'station')
res.frames = res.frames.filter((f) => {
return f.origin.type !== 'location' && f.destination.type !== 'location'
})
return res
}
return parseMovement
}
const defaultProducts = {
nationalExp: true,
national: true,
interregional: true,
regional: true,
suburban: true,
bus: true,
ferry: true,
subway: true,
tram: true,
onCall: true
}
const formatBitmask = createFormatBitmask(products)
const formatProducts = (products) => {
products = Object.assign(Object.create(null), defaultProducts, products)
return {
type: 'PROD',
mode: 'INC',
value: formatBitmask(products) + ''
}
}
const oebbProfile = {
locale: 'de-AT',
timezone: 'Europe/Vienna',
// todo: there is also https://beta.verkehrsauskunft.at/bin/mgate.exe
endpoint: 'http://fahrplan.oebb.at/bin/mgate.exe',
transformReqBody,
products: products.allProducts,
parseProducts: createParseBitmask(products.bitmasks),
parseLine,
parseLocation,
parseMovement: createParseMovement,
formatProducts,
journeyLeg: true,
radar: true
}
module.exports = oebbProfile

112
p/oebb/products.js Normal file
View file

@ -0,0 +1,112 @@
'use strict'
const p = {
nationalExp: {
bitmask: 1,
name: 'InterCityExpress & RailJet',
short: 'ICE/RJ',
mode: 'train',
product: 'nationalExp'
},
national: {
bitmask: 2 + 4,
name: 'InterCity & EuroCity',
short: 'IC/EC',
mode: 'train',
product: 'national'
},
interregional: {
bitmask: 8 + 4096,
name: 'Durchgangszug & EuroNight',
short: 'D/EN',
mode: 'train',
product: 'interregional'
},
regional: {
bitmask: 16,
name: 'Regional & RegionalExpress',
short: 'R/REX',
mode: 'train',
product: 'regional'
},
suburban: {
bitmask: 32,
name: 'S-Bahn',
short: 'S',
mode: 'train',
product: 'suburban'
},
bus: {
bitmask: 64,
name: 'Bus',
short: 'B',
mode: 'bus',
product: 'bus'
},
ferry: {
bitmask: 128,
name: 'Ferry',
short: 'F',
mode: 'watercraft',
product: 'ferry'
},
subway: {
bitmask: 256,
name: 'U-Bahn',
short: 'U',
mode: 'train',
product: 'subway'
},
tram: {
bitmask: 512,
name: 'Tram',
short: 'T',
mode: 'train',
product: 'tram'
},
onCall: {
bitmask: 2048,
name: 'On-call transit',
short: 'on-call',
mode: null, // todo
product: 'onCall'
},
unknown: {
bitmask: 0,
name: 'unknown',
short: '?',
product: 'unknown'
}
}
p.bitmasks = []
p.bitmasks[1] = p.nationalExp
p.bitmasks[2] = p.national
p.bitmasks[4] = p.national
p.bitmasks[2+4] = p.national
p.bitmasks[8] = p.interregional
p.bitmasks[16] = p.regional
p.bitmasks[32] = p.suburban
p.bitmasks[64] = p.bus
p.bitmasks[128] = p.ferry
p.bitmasks[256] = p.subway
p.bitmasks[512] = p.tram
p.bitmasks[1024] = p.unknown
p.bitmasks[2048] = p.onCall
p.bitmasks[4096] = p.interregional
p.bitmasks[8+4096] = p.interregional
p.allProducts = [
p.nationalExp,
p.national,
p.interregional,
p.regional,
p.suburban,
p.bus,
p.ferry,
p.subway,
p.tram,
p.onCall
]
module.exports = p

19
p/oebb/readme.md Normal file
View file

@ -0,0 +1,19 @@
# ÖBB profile for `hafas-client`
[*Österreichische Bundesbahnen (ÖBB)*](https://en.wikipedia.org/wiki/Austrian_Federal_Railways) is the largest Austrian long-distance public transport company. This profile adds *ÖBB*-specific customizations to `hafas-client`. Consider using [`oebb-hafas`](https://github.com/juliuste/oebb-hafas#oebb-hafas), to always get the customized client right away.
## Usage
```js
const createClient = require('hafas-client')
const oebbProfile = require('hafas-client/p/oebb')
// create a client with ÖBB profile
const client = createClient(oebbProfile)
```
## Customisations
- parses *ÖBB*-specific products (such as *RailJet*)
- parses invalid empty stations from the API as [`location`](https://github.com/public-transport/friendly-public-transport-format/blob/1.0.1/spec/readme.md#location-objects)s

View file

@ -12,6 +12,7 @@
"docs"
],
"author": "Jannis R <mail@jannisr.de>",
"contributors": ["Julius Tens <mail@juliustens.eu>"],
"homepage": "https://github.com/derhuerst/hafas-client",
"repository": "derhuerst/hafas-client",
"bugs": "https://github.com/derhuerst/hafas-client/issues",

View file

@ -43,7 +43,9 @@ const createParseJourneyLeg = (profile, stations, lines, remarks) => {
if (passed && pt.jny.stopL) {
const parse = profile.parseStopover(profile, stations, lines, remarks, j)
res.passed = pt.jny.stopL.map(parse)
const passedStations = pt.jny.stopL.map(parse)
// filter stations the train passes without stopping, as this doesn't comply with fptf (yet)
res.passed = passedStations.filter((x) => !x.passBy)
}
if (Array.isArray(pt.jny.remL)) {
for (let remark of pt.jny.remL) applyRemark(j, remark)

View file

@ -5,7 +5,7 @@ const createParseBitmask = (bitmasks) => {
const products = {}
let i = 1
do {
products[bitmasks[i].product] = !!(bitmask & i)
products[bitmasks[i].product] = products[bitmasks[i].product] || !!(bitmask & i)
i *= 2
} while (bitmasks[i] && bitmasks[i].product)
return products

View file

@ -16,6 +16,9 @@ const createParseStopover = (profile, stations, lines, remarks, connection) => {
res.departure = dep.toISO()
}
// mark stations the train passes without stopping
if(st.dInS === false && st.aOutS === false) res.passBy = true
// todo: follow public-transport/friendly-public-transport-format#27 here
// see also derhuerst/vbb-rest#19
if (st.aCncl) {

View file

@ -6,6 +6,7 @@ HAFAS endpoint | wrapper library? | docs | example code | source code
---------------|------------------|------|---------|------------
[Deutsche Bahn](https://en.wikipedia.org/wiki/Deutsche_Bahn) | [`vbb-hafas`](https://github.com/derhuerst/vbb-hafas), which has additional features | [docs](p/db/readme.md) | [example code](p/db/example.js) | [src](p/db/index.js)
[Berlin & Brandenburg public transport](https://en.wikipedia.org/wiki/Verkehrsverbund_Berlin-Brandenburg) | [`db-hafas`](https://github.com/derhuerst/db-hafas), which has additional features | [docs](p/vbb/readme.md) | [example code](p/vbb/example.js) | [src](p/vbb/index.js)
[Österreichische Bundesbahnen (ÖBB)](https://en.wikipedia.org/wiki/Austrian_Federal_Railways) | | [docs](p/oebb/readme.md) | [example code](p/oebb/example.js) | [src](p/oebb/index.js)
[![npm version](https://img.shields.io/npm/v/hafas-client.svg)](https://www.npmjs.com/package/hafas-client)
[![build status](https://img.shields.io/travis/derhuerst/hafas-client.svg)](https://travis-ci.org/derhuerst/hafas-client)
@ -30,7 +31,7 @@ npm install hafas-client
## API
- [`journeys(from, to, [opt])`](docs/journeys.md) get journeys between locations
- [`journeyLeg(ref, name, [opt])`](docs/journey-leg.md) get details for a leg of a journey
- [`journeyLeg(ref, lineName, [opt])`](docs/journey-leg.md) get details for a leg of a journey
- [`departures(station, [opt])`](docs/departures.md) query the next departures at a station
- [`locations(query, [opt])`](docs/locations.md) find stations, POIs and addresses
- [`nearby(location, [opt])`](docs/nearby.md) show stations & POIs around

View file

@ -16,9 +16,11 @@ const {
assertValidLocation,
assertValidLine,
assertValidStopover,
when, isValidWhen
createWhen, assertValidWhen
} = require('./util.js')
const when = createWhen('Europe/Berlin', 'de-DE')
const assertValidStationProducts = (t, p) => {
t.ok(p)
t.equal(typeof p.nationalExp, 'boolean')
@ -106,7 +108,7 @@ test('Berlin Jungfernheide to München Hbf', co.wrap(function* (t) {
if (journey.origin.products) {
assertValidProducts(t, journey.origin.products)
}
t.ok(isValidWhen(journey.departure))
assertValidWhen(t, journey.departure, when)
assertValidStation(t, journey.destination)
assertValidStationProducts(t, journey.origin.products)
@ -116,7 +118,7 @@ test('Berlin Jungfernheide to München Hbf', co.wrap(function* (t) {
if (journey.destination.products) {
assertValidProducts(t, journey.destination.products)
}
t.ok(isValidWhen(journey.arrival))
assertValidWhen(t, journey.arrival, when)
t.ok(Array.isArray(journey.legs))
t.ok(journey.legs.length > 0, 'no legs')
@ -127,7 +129,7 @@ test('Berlin Jungfernheide to München Hbf', co.wrap(function* (t) {
if (!(yield findStation(leg.origin.id))) {
console.error('unknown station', leg.origin.id, leg.origin.name)
}
t.ok(isValidWhen(leg.departure))
assertValidWhen(t, leg.departure, when)
t.equal(typeof leg.departurePlatform, 'string')
assertValidStation(t, leg.destination)
@ -135,7 +137,7 @@ test('Berlin Jungfernheide to München Hbf', co.wrap(function* (t) {
if (!(yield findStation(leg.destination.id))) {
console.error('unknown station', leg.destination.id, leg.destination.name)
}
t.ok(isValidWhen(leg.arrival))
assertValidWhen(t, leg.arrival, when)
t.equal(typeof leg.arrivalPlatform, 'string')
assertValidLine(t, leg.line)
@ -166,8 +168,8 @@ test('Berlin Jungfernheide to Torfstraße 17', co.wrap(function* (t) {
console.error('unknown station', leg.origin.id, leg.origin.name)
}
if (leg.origin.products) assertValidProducts(t, leg.origin.products)
t.ok(isValidWhen(leg.departure))
t.ok(isValidWhen(leg.arrival))
assertValidWhen(t, leg.departure, when)
assertValidWhen(t, leg.arrival, when)
const d = leg.destination
assertValidAddress(t, d)
@ -195,8 +197,8 @@ test('Berlin Jungfernheide to ATZE Musiktheater', co.wrap(function* (t) {
console.error('unknown station', leg.origin.id, leg.origin.name)
}
if (leg.origin.products) assertValidProducts(t, leg.origin.products)
t.ok(isValidWhen(leg.departure))
t.ok(isValidWhen(leg.arrival))
assertValidWhen(t, leg.departure, when)
assertValidWhen(t, leg.arrival, when)
const d = leg.destination
assertValidPoi(t, d)
@ -220,7 +222,7 @@ test('departures at Berlin Jungfernheide', co.wrap(function* (t) {
console.error('unknown station', dep.station.id, dep.station.name)
}
if (dep.station.products) assertValidProducts(t, dep.station.products)
t.ok(isValidWhen(dep.when))
assertValidWhen(t, dep.when, when)
}
t.end()

View file

@ -2,3 +2,4 @@
require('./db')
require('./vbb')
require('./oebb')

377
test/oebb.js Normal file
View file

@ -0,0 +1,377 @@
'use strict'
// todo
// const getStations = require('db-stations').full
const tapePromise = require('tape-promise').default
const tape = require('tape')
const co = require('co')
const isRoughlyEqual = require('is-roughly-equal')
const createClient = require('..')
const oebbProfile = require('../p/oebb')
const products = require('../p/oebb/products')
const {
assertValidStation,
assertValidPoi,
assertValidAddress,
assertValidLocation,
assertValidLine,
assertValidStopover,
hour, createWhen, assertValidWhen
} = require('./util.js')
const when = createWhen('Europe/Vienna', 'de-AT')
const assertValidStationProducts = (t, p) => {
t.ok(p)
t.equal(typeof p.nationalExp, 'boolean')
t.equal(typeof p.national, 'boolean')
t.equal(typeof p.interregional, 'boolean')
t.equal(typeof p.regional, 'boolean')
t.equal(typeof p.suburban, 'boolean')
t.equal(typeof p.bus, 'boolean')
t.equal(typeof p.ferry, 'boolean')
t.equal(typeof p.subway, 'boolean')
t.equal(typeof p.tram, 'boolean')
t.equal(typeof p.onCall, 'boolean')
}
// todo
// const findStation = (id) => new Promise((yay, nay) => {
// const stations = getStations()
// stations
// .once('error', nay)
// .on('data', (s) => {
// if (
// s.id === id ||
// (s.additionalIds && s.additionalIds.includes(id))
// ) {
// yay(s)
// stations.destroy()
// }
// })
// .once('end', yay)
// })
const isSalzburgHbf = (s) => {
return s.type === 'station' &&
(s.id === '008100002' || s.id === '8100002') &&
s.name === 'Salzburg Hbf' &&
s.location &&
isRoughlyEqual(s.location.latitude, 47.812851, .0005) &&
isRoughlyEqual(s.location.longitude, 13.045604, .0005)
}
const assertIsSalzburgHbf = (t, s) => {
t.equal(s.type, 'station')
t.ok(s.id === '008100002' || s.id === '8100002', 'id should be 8100002')
t.equal(s.name, 'Salzburg Hbf')
t.ok(s.location)
t.ok(isRoughlyEqual(s.location.latitude, 47.812851, .0005))
t.ok(isRoughlyEqual(s.location.longitude, 13.045604, .0005))
}
// todo: this doesnt seem to work
// todo: DRY with assertValidStationProducts
const assertValidProducts = (t, p) => {
for (let k of Object.keys(products)) {
t.ok('boolean', typeof products[k], 'mode ' + k + ' must be a boolean')
}
}
const assertValidPrice = (t, p) => {
t.ok(p)
if (p.amount !== null) {
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)
}
}
const test = tapePromise(tape)
const client = createClient(oebbProfile)
test('Salzburg Hbf to Wien Westbahnhof', co.wrap(function* (t) {
const salzburgHbf = '8100002'
const wienWestbahnhof = '1291501'
const journeys = yield client.journeys(salzburgHbf, wienWestbahnhof, {
when, passedStations: true
})
t.ok(Array.isArray(journeys))
t.ok(journeys.length > 0, 'no journeys')
for (let journey of journeys) {
assertValidStation(t, journey.origin)
assertValidStationProducts(t, journey.origin.products)
// todo
// if (!(yield findStation(journey.origin.id))) {
// console.error('unknown station', journey.origin.id, journey.origin.name)
// }
if (journey.origin.products) {
assertValidProducts(t, journey.origin.products)
}
assertValidWhen(t, journey.departure, when)
assertValidStation(t, journey.destination)
assertValidStationProducts(t, journey.origin.products)
// todo
// if (!(yield findStation(journey.origin.id))) {
// console.error('unknown station', journey.destination.id, journey.destination.name)
// }
if (journey.destination.products) {
assertValidProducts(t, journey.destination.products)
}
assertValidWhen(t, journey.arrival, when)
t.ok(Array.isArray(journey.legs))
t.ok(journey.legs.length > 0, 'no legs')
const leg = journey.legs[0]
assertValidStation(t, leg.origin)
assertValidStationProducts(t, leg.origin.products)
// todo
// if (!(yield findStation(leg.origin.id))) {
// console.error('unknown station', leg.origin.id, leg.origin.name)
// }
assertValidWhen(t, leg.departure, when)
t.equal(typeof leg.departurePlatform, 'string')
assertValidStation(t, leg.destination)
assertValidStationProducts(t, leg.origin.products)
// todo
// if (!(yield findStation(leg.destination.id))) {
// console.error('unknown station', leg.destination.id, leg.destination.name)
// }
assertValidWhen(t, leg.arrival, when)
t.equal(typeof leg.arrivalPlatform, 'string')
assertValidLine(t, leg.line)
t.ok(Array.isArray(leg.passed))
for (let stopover of leg.passed) assertValidStopover(t, stopover)
if (journey.price) assertValidPrice(t, journey.price)
}
t.end()
}))
test('Salzburg Hbf to 1220 Wien, Wagramer Straße 5', co.wrap(function* (t) {
const salzburgHbf = '8100002'
const wagramerStr = {
type: 'location',
latitude: 48.236216,
longitude: 16.425863,
address: '1220 Wien, Wagramer Straße 5'
}
const journeys = yield client.journeys(salzburgHbf, wagramerStr, {when})
t.ok(Array.isArray(journeys))
t.ok(journeys.length >= 1, 'no journeys')
const journey = journeys[0]
const firstLeg = journey.legs[0]
const lastLeg = journey.legs[journey.legs.length - 1]
assertValidStation(t, firstLeg.origin)
assertValidStationProducts(t, firstLeg.origin.products)
// todo
// if (!(yield findStation(leg.origin.id))) {
// console.error('unknown station', leg.origin.id, leg.origin.name)
// }
if (firstLeg.origin.products) assertValidProducts(t, firstLeg.origin.products)
assertValidWhen(t, firstLeg.departure, when)
assertValidWhen(t, firstLeg.arrival, when)
assertValidWhen(t, lastLeg.departure, when)
assertValidWhen(t, lastLeg.arrival, when)
const d = lastLeg.destination
assertValidAddress(t, d)
t.equal(d.address, '1220 Wien, Wagramer Straße 5')
t.ok(isRoughlyEqual(.0001, d.latitude, 48.236216))
t.ok(isRoughlyEqual(.0001, d.longitude, 16.425863))
t.end()
}))
test('Albertina to Salzburg Hbf', co.wrap(function* (t) {
const albertina = {
type: 'location',
latitude: 48.204699,
longitude: 16.368404,
name: 'Albertina',
id: '975900003'
}
const salzburgHbf = '8100002'
const journeys = yield client.journeys(albertina, salzburgHbf, {when})
t.ok(Array.isArray(journeys))
t.ok(journeys.length >= 1, 'no journeys')
const journey = journeys[0]
const firstLeg = journey.legs[0]
const lastLeg = journey.legs[journey.legs.length - 1]
const o = firstLeg.origin
assertValidPoi(t, o)
t.equal(o.name, 'Albertina')
t.ok(isRoughlyEqual(.0001, o.latitude, 48.204699))
t.ok(isRoughlyEqual(.0001, o.longitude, 16.368404))
assertValidWhen(t, firstLeg.departure, when)
assertValidWhen(t, firstLeg.arrival, when)
assertValidWhen(t, lastLeg.departure, when)
assertValidWhen(t, lastLeg.arrival, when)
assertValidStation(t, lastLeg.destination)
assertValidStationProducts(t, lastLeg.destination.products)
if (lastLeg.destination.products) assertValidProducts(t, lastLeg.destination.products)
// todo
// if (!(yield findStation(leg.destination.id))) {
// console.error('unknown station', leg.destination.id, leg.destination.name)
// }
t.end()
}))
test('leg details for Wien Westbahnhof to München Hbf', co.wrap(function* (t) {
const wienWestbahnhof = '1291501'
const muenchenHbf = '8000261'
const journeys = yield client.journeys(wienWestbahnhof, muenchenHbf, {
results: 1, when
})
const p = journeys[0].legs[0]
t.ok(p.id, 'precondition failed')
t.ok(p.line.name, 'precondition failed')
const leg = yield client.journeyLeg(p.id, p.line.name, {when})
t.equal(typeof leg.id, 'string')
t.ok(leg.id)
assertValidLine(t, leg.line)
t.equal(typeof leg.direction, 'string')
t.ok(leg.direction)
t.ok(Array.isArray(leg.passed))
for (let passed of leg.passed) assertValidStopover(t, passed)
t.end()
}))
test('departures at Salzburg Hbf', co.wrap(function* (t) {
const salzburgHbf = '8100002'
const deps = yield client.departures(salzburgHbf, {
duration: 5, when
})
t.ok(Array.isArray(deps))
for (let dep of deps) {
assertValidStation(t, dep.station)
assertValidStationProducts(t, dep.station.products)
// todo
// if (!(yield findStation(dep.station.id))) {
// console.error('unknown station', dep.station.id, dep.station.name)
// }
if (dep.station.products) assertValidProducts(t, dep.station.products)
assertValidWhen(t, dep.when, when)
}
t.end()
}))
test('nearby Salzburg Hbf', co.wrap(function* (t) {
const salzburgHbfPosition = {
longitude: 13.045604,
latitude: 47.812851
}
const nearby = yield client.nearby(salzburgHbfPosition.latitude, salzburgHbfPosition.longitude, {
results: 2, distance: 400
})
t.ok(Array.isArray(nearby))
t.equal(nearby.length, 2)
assertIsSalzburgHbf(t, nearby[0])
t.ok(nearby[0].distance >= 0)
t.ok(nearby[0].distance <= 100)
for (let n of nearby) {
if (n.type === 'station') assertValidStation(t, n)
else assertValidLocation(t, n)
}
t.end()
}))
test('locations named Salzburg', co.wrap(function* (t) {
const locations = yield client.locations('Salzburg', {
results: 10
})
t.ok(Array.isArray(locations))
t.ok(locations.length > 0)
t.ok(locations.length <= 10)
for (let l of locations) {
if (l.type === 'station') assertValidStation(t, l)
else assertValidLocation(t, l)
}
t.ok(locations.some(isSalzburgHbf))
t.end()
}))
test('radar Salzburg', co.wrap(function* (t) {
const vehicles = yield client.radar(47.827203, 13.001261, 47.773278, 13.07562, {
duration: 5 * 60, when
})
t.ok(Array.isArray(vehicles))
t.ok(vehicles.length > 0)
for (let v of vehicles) {
// todo
// t.ok(findStation(v.direction))
assertValidLine(t, v.line)
t.equal(typeof v.location.latitude, 'number')
t.ok(v.location.latitude <= 52, 'vehicle is too far away')
t.ok(v.location.latitude >= 42, 'vehicle is too far away')
t.equal(typeof v.location.longitude, 'number')
t.ok(v.location.longitude >= 10, 'vehicle is too far away')
t.ok(v.location.longitude <= 16, 'vehicle is too far away')
t.ok(Array.isArray(v.nextStops))
for (let st of v.nextStops) {
assertValidStopover(t, st, true)
if (st.arrival) {
t.equal(typeof st.arrival, 'string')
const arr = +new Date(st.arrival)
// note that this can be an ICE train
t.ok(isRoughlyEqual(14 * hour, +when, arr))
}
if (st.departure) {
t.equal(typeof st.departure, 'string')
const dep = +new Date(st.departure)
t.ok(isRoughlyEqual(14 * hour, +when, dep))
}
}
t.ok(Array.isArray(v.frames))
for (let f of v.frames) {
assertValidStation(t, f.origin, true)
// can contain stations in germany which don't have a products property, would break
// assertValidStationProducts(t, f.origin.products)
assertValidStation(t, f.destination, true)
// can contain stations in germany which don't have a products property, would break
// assertValidStationProducts(t, f.destination.products)
t.equal(typeof f.t, 'number')
}
}
t.end()
}))

View file

@ -98,18 +98,20 @@ const hour = 60 * 60 * 1000
const week = 7 * 24 * hour
// next Monday 10 am
const when = DateTime.fromMillis(Date.now(), {
zone: 'Europe/Berlin',
locale: 'de-DE'
const createWhen = (timezone, locale) => {
return DateTime.fromMillis(Date.now(), {
zone: timezone,
locale,
}).startOf('week').plus({weeks: 1, hours: 10}).toJSDate()
const isValidWhen = (w) => {
const ts = +new Date(w)
}
const isValidWhen = (actual, expected) => {
const ts = +new Date(actual)
if (Number.isNaN(ts)) return false
return isRoughlyEqual(12 * hour, +when, ts)
return isRoughlyEqual(12 * hour, +expected, ts)
}
const assertValidWhen = (t, w) => {
t.ok(isValidWhen(w), 'invalid when')
const assertValidWhen = (t, actual, expected) => {
t.ok(isValidWhen(actual, expected), 'invalid when')
}
const assertValidTicket = (t, ti) => {
@ -151,6 +153,6 @@ module.exports = {
assertValidLine,
isValidDateTime,
assertValidStopover,
hour, when, isValidWhen, assertValidWhen,
hour, createWhen, isValidWhen, assertValidWhen,
assertValidTicket
}

View file

@ -17,11 +17,13 @@ const {
assertValidLocation,
assertValidLine: _assertValidLine,
assertValidStopover,
hour, when,
hour, createWhen,
assertValidWhen,
assertValidTicket
} = require('./util')
const when = createWhen('Europe/Berlin', 'de-DE')
const assertValidStation = (t, s, coordsOptional = false) => {
_assertValidStation(t, s, coordsOptional)
t.equal(s.name, shorten(s.name))
@ -70,12 +72,12 @@ test('journeys  station to station', co.wrap(function* (t) {
assertValidStationProducts(t, journey.origin.products)
t.ok(journey.origin.name.indexOf('(Berlin)') === -1)
t.strictEqual(journey.origin.id, spichernstr)
assertValidWhen(t, journey.departure)
assertValidWhen(t, journey.departure, when)
assertValidStation(t, journey.destination)
assertValidStationProducts(t, journey.destination.products)
t.strictEqual(journey.destination.id, amrumerStr)
assertValidWhen(t, journey.arrival)
assertValidWhen(t, journey.arrival, when)
t.ok(Array.isArray(journey.legs))
t.strictEqual(journey.legs.length, 1)
@ -87,12 +89,12 @@ test('journeys  station to station', co.wrap(function* (t) {
assertValidStationProducts(t, leg.origin.products)
t.ok(leg.origin.name.indexOf('(Berlin)') === -1)
t.strictEqual(leg.origin.id, spichernstr)
assertValidWhen(t, leg.departure)
assertValidWhen(t, leg.departure, when)
assertValidStation(t, leg.destination)
assertValidStationProducts(t, leg.destination.products)
t.strictEqual(leg.destination.id, amrumerStr)
assertValidWhen(t, leg.arrival)
assertValidWhen(t, leg.arrival, when)
assertValidLine(t, leg.line)
t.ok(findStation(leg.direction))
@ -198,14 +200,14 @@ test('journeys  station to address', co.wrap(function* (t) {
assertValidStation(t, leg.origin)
assertValidStationProducts(t, leg.origin.products)
assertValidWhen(t, leg.departure)
assertValidWhen(t, leg.departure, when)
const dest = leg.destination
assertValidAddress(t, dest)
t.strictEqual(dest.address, 'Torfstraße 17')
t.ok(isRoughlyEqual(.0001, dest.latitude, 52.5416823))
t.ok(isRoughlyEqual(.0001, dest.longitude, 13.3491223))
assertValidWhen(t, leg.arrival)
assertValidWhen(t, leg.arrival, when)
t.end()
}))
@ -225,14 +227,14 @@ test('journeys  station to POI', co.wrap(function* (t) {
assertValidStation(t, leg.origin)
assertValidStationProducts(t, leg.origin.products)
assertValidWhen(t, leg.departure)
assertValidWhen(t, leg.departure, when)
const dest = leg.destination
assertValidPoi(t, dest)
t.strictEqual(dest.name, 'ATZE Musiktheater')
t.ok(isRoughlyEqual(.0001, dest.latitude, 52.543333))
t.ok(isRoughlyEqual(.0001, dest.longitude, 13.351686))
assertValidWhen(t, leg.arrival)
assertValidWhen(t, leg.arrival, when)
t.end()
}))
@ -253,7 +255,7 @@ test('departures', co.wrap(function* (t) {
assertValidStationProducts(t, dep.station.products)
t.strictEqual(dep.station.id, spichernstr)
assertValidWhen(t, dep.when)
assertValidWhen(t, dep.when, when)
t.ok(findStation(dep.direction))
assertValidLine(t, dep.line)
}