diff --git a/p/db/index.js b/p/db/index.js index a5973581..f88dc539 100644 --- a/p/db/index.js +++ b/p/db/index.js @@ -140,7 +140,7 @@ const dbProfile = { // todo: parseLocation parseLine: createParseLine, - parseProducts: createParseBitmask(modes.bitmasks), + parseProducts: createParseBitmask(modes.allProducts, defaultProducts), parseJourney: createParseJourney, formatStation, diff --git a/p/insa/index.js b/p/insa/index.js index f0b90c64..b50c02fc 100644 --- a/p/insa/index.js +++ b/p/insa/index.js @@ -71,7 +71,7 @@ const insaProfile = { transformReqBody, defaultProducts, - parseProducts: createParseBitmask(products.bitmasks), + parseProducts: createParseBitmask(products.allProducts, defaultProducts), formatProducts, parseLine: createParseLine diff --git a/p/oebb/index.js b/p/oebb/index.js index 13a61284..5196ab49 100644 --- a/p/oebb/index.js +++ b/p/oebb/index.js @@ -113,7 +113,7 @@ const oebbProfile = { products: products.allProducts, - parseProducts: createParseBitmask(products.bitmasks), + parseProducts: createParseBitmask(products.allProducts, defaultProducts), parseLine: createParseLine, parseLocation, parseMovement: createParseMovement, diff --git a/p/vbb/index.js b/p/vbb/index.js index 307ba0f4..3f9f9ecd 100644 --- a/p/vbb/index.js +++ b/p/vbb/index.js @@ -181,7 +181,7 @@ const vbbProfile = { parseStationName: shorten, parseLocation, parseLine: createParseLine, - parseProducts: createParseBitmask(modes.bitmasks), + parseProducts: createParseBitmask(modes.allProducts, defaultProducts), parseJourney: createParseJourney, parseDeparture: createParseDeparture, parseStopover: createParseStopover, diff --git a/parse/products-bitmask.js b/parse/products-bitmask.js index 04f9b89a..5dc5e8bc 100644 --- a/parse/products-bitmask.js +++ b/parse/products-bitmask.js @@ -1,14 +1,29 @@ 'use strict' -const createParseBitmask = (bitmasks) => { +const createParseBitmask = (allProducts, defaultProducts) => { + allProducts = allProducts.sort((p1, p2) => p2.bitmask - p1.bitmask) // desc + if (allProducts.length === 0) throw new Error('allProducts is empty.') + for (let product of allProducts) { + if ('string' !== typeof product.product) { + throw new Error('allProducts[].product must be a string.') + } + if ('number' !== typeof product.bitmask) { + throw new Error(product.product + '.bitmask must be a number.') + } + } + const parseBitmask = (bitmask) => { - const products = {} - let i = 1 - do { - products[bitmasks[i].product] = products[bitmasks[i].product] || !!(bitmask & i) - i *= 2 - } while (bitmasks[i] && bitmasks[i].product) - return products + const res = Object.assign({}, defaultProducts) + + for (let product of allProducts) { + if (bitmask === 0) break + if ((product.bitmask & bitmask) > 0) { + res[product.product] = true + bitmask -= product.bitmask + } + } + + return res } return parseBitmask } diff --git a/test/db.js b/test/db.js index f38d2ddd..ffaca334 100644 --- a/test/db.js +++ b/test/db.js @@ -8,7 +8,7 @@ const isRoughlyEqual = require('is-roughly-equal') const co = require('./co') const createClient = require('..') const dbProfile = require('../p/db') -const modes = require('../p/db/modes') +const {allProducts} = require('../p/db/modes') const { assertValidStation, assertValidPoi, @@ -69,11 +69,12 @@ const assertIsJungfernheide = (t, s) => { t.ok(isRoughlyEqual(s.location.longitude, 13.299424, .0005)) } -// todo: this doesnt seem to work // todo: DRY with assertValidStationProducts +// todo: DRY with other tests const assertValidProducts = (t, p) => { - for (let k of Object.keys(modes)) { - t.ok('boolean', typeof modes[k], 'mode ' + k + ' must be a boolean') + for (let product of allProducts) { + product = product.product // wat + t.equal(typeof p[product], 'boolean', 'product ' + p + ' must be a boolean') } } diff --git a/test/insa.js b/test/insa.js index 86008982..b23db709 100644 --- a/test/insa.js +++ b/test/insa.js @@ -8,7 +8,7 @@ const validateFptf = require('validate-fptf') const co = require('./co') const createClient = require('..') const insaProfile = require('../p/insa') -const products = require('../p/insa/products') +const {allProducts} = require('../p/insa/products') const { assertValidStation, assertValidPoi, @@ -56,11 +56,12 @@ const assertIsMagdeburgHbf = (t, s) => { t.ok(isRoughlyEqual(s.location.longitude, 11.626891, 0.001)) } -// todo: this doesnt seem to work // todo: DRY with assertValidStationProducts +// todo: DRY with other tests const assertValidProducts = (t, p) => { - for (let k of Object.keys(products)) { - t.ok('boolean', typeof products[k], 'mode ' + k + ' must be a boolean') + for (let product of allProducts) { + product = product.product // wat + t.equal(typeof p[product], 'boolean', 'product ' + p + ' must be a boolean') } } diff --git a/test/oebb.js b/test/oebb.js index 178c58db..73d8c685 100644 --- a/test/oebb.js +++ b/test/oebb.js @@ -12,7 +12,7 @@ const validateLineWithoutMode = require('./validate-line-without-mode') const co = require('./co') const createClient = require('..') const oebbProfile = require('../p/oebb') -const products = require('../p/oebb/products') +const {allProducts} = require('../p/oebb/products') const { assertValidStation, assertValidPoi, @@ -73,11 +73,12 @@ const assertIsSalzburgHbf = (t, s) => { t.ok(isRoughlyEqual(s.location.longitude, 13.045604, .0005)) } -// todo: this doesnt seem to work // todo: DRY with assertValidStationProducts +// todo: DRY with other tests const assertValidProducts = (t, p) => { - for (let k of Object.keys(products)) { - t.ok('boolean', typeof products[k], 'mode ' + k + ' must be a boolean') + for (let product of allProducts) { + product = product.product // wat + t.equal(typeof p[product], 'boolean', 'product ' + p + ' must be a boolean') } }