@bytebrand/export-cars 1.26.21 → 1.26.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/interfaces/export-item.interface.d.ts +2 -2
- package/dist/transformers/google-feed-envkv.d.ts +5 -0
- package/dist/transformers/google-feed-envkv.js +56 -0
- package/dist/transformers/google-feed-envkv.js.map +1 -0
- package/dist/transformers/google.transformer.d.ts +0 -2
- package/dist/transformers/google.transformer.js +7 -28
- package/dist/transformers/google.transformer.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +3 -2
- package/src/interfaces/export-item.interface.ts +2 -2
- package/src/transformers/google-feed-envkv.ts +92 -0
- package/src/transformers/google.transformer.ts +16 -49
- package/test/google-feed-envkv.test.ts +114 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bytebrand/export-cars",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.23",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "bytebrand",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"prepublishOnly": "npm run build",
|
|
11
11
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
12
12
|
"lint": "eslint -c .eslintrc.js --ext .ts src/",
|
|
13
|
-
"start:dev": "nest start --watch"
|
|
13
|
+
"start:dev": "nest start --watch",
|
|
14
|
+
"test": "ts-node --transpile-only test/google-feed-envkv.test.ts"
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {
|
|
16
17
|
"@bytebrand/autode-request": "^1.19.2",
|
|
@@ -199,11 +199,11 @@ export interface GoogleXmlItem {
|
|
|
199
199
|
doors?: number;
|
|
200
200
|
capacity?: number;
|
|
201
201
|
date_first_registered: string,
|
|
202
|
-
fuel_consumption
|
|
202
|
+
fuel_consumption?: string,
|
|
203
203
|
energy_consumption?: string,
|
|
204
204
|
electric_range?: string,
|
|
205
205
|
fuel_consumption_discharged_battery?: string,
|
|
206
|
-
co2_emissions
|
|
206
|
+
co2_emissions?: string,
|
|
207
207
|
identifier_exists: string,
|
|
208
208
|
ads_redirect?: string;
|
|
209
209
|
"certified_pre-owned"?: boolean;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { get } from 'lodash';
|
|
2
|
+
import { DataSchemes } from '@bytebrand/car-schema';
|
|
3
|
+
|
|
4
|
+
// Google vehicle ads `engine`: gasoline, diesel, electric, hybrid, lpg, methane, natural_gas,
|
|
5
|
+
// plug-in_hybrid, other (https://support.google.com/merchants/answer/14156068). Any other value
|
|
6
|
+
// is rejected as "Missing attribute [engine]" — CarGas / NaturalGas did that for ~290 items.
|
|
7
|
+
const GOOGLE_ENGINE: Record<string, string> = {
|
|
8
|
+
selector_fuel_petrol: 'Gasoline',
|
|
9
|
+
selector_fuel_diesel: 'Diesel',
|
|
10
|
+
selector_fuel_electrical: 'Electric',
|
|
11
|
+
selector_fuel_hybridElectricalPetrol: 'Hybrid',
|
|
12
|
+
selector_fuel_hybridElectricalDiesel: 'Hybrid',
|
|
13
|
+
selector_fuel_carGas: 'lpg',
|
|
14
|
+
selector_fuel_naturalGas: 'natural_gas',
|
|
15
|
+
selector_fuel_ethanol: 'other',
|
|
16
|
+
selector_fuel_hydrogen: 'other',
|
|
17
|
+
selector_unknown: 'other',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const HYBRID_FUELS = ['selector_fuel_hybridElectricalPetrol', 'selector_fuel_hybridElectricalDiesel'];
|
|
21
|
+
|
|
22
|
+
const positive = (value: unknown): number | undefined => {
|
|
23
|
+
const n = Number(value);
|
|
24
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const isBev = (car: DataSchemes.Car): boolean => get(car, 'consumption.fuel') === 'selector_fuel_electrical';
|
|
28
|
+
const isPlugIn = (car: DataSchemes.Car): boolean =>
|
|
29
|
+
HYBRID_FUELS.includes(get(car, 'consumption.fuel')) && !!get(car, 'engineData.hybridPlugin');
|
|
30
|
+
|
|
31
|
+
export function googleEngine(car: DataSchemes.Car): string {
|
|
32
|
+
const engine = GOOGLE_ENGINE[get(car, 'consumption.fuel', 'selector_unknown')] || 'other';
|
|
33
|
+
return engine === 'Hybrid' && get(car, 'engineData.hybridPlugin') ? 'plug-in_hybrid' : engine;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// BEV: combined WLTP range (CoC 49.2). Plug-in: the EAER (`wltpTotalRange`, CoC 49.5) when present,
|
|
37
|
+
// else the range the dealer delivered. City ranges are never used; 0 counts as missing.
|
|
38
|
+
export function googleElectricRange(car: DataSchemes.Car): string | undefined {
|
|
39
|
+
let range: number | undefined;
|
|
40
|
+
if (isBev(car)) {
|
|
41
|
+
range = positive(get(car, 'battery.wltpRange')) ?? positive(get(car, 'battery.batteryRangeElectric'));
|
|
42
|
+
} else if (isPlugIn(car)) {
|
|
43
|
+
range = positive(get(car, 'battery.wltpTotalRange'))
|
|
44
|
+
?? positive(get(car, 'battery.wltpRange'))
|
|
45
|
+
?? positive(get(car, 'battery.batteryRangeElectric'));
|
|
46
|
+
}
|
|
47
|
+
return range ? `${range}km` : undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Plug-in hybrids: Google and Pkw-EnVKV (CoC 49.4) want the WEIGHTED combined values for fuel,
|
|
51
|
+
// electricity and CO2, and the fuel consumption with a DISCHARGED battery separately. In CBD those
|
|
52
|
+
// are wltpWeightedCombined, wltpWeightedPowerCombined, wltpCo2 (weighted for a plug-in) and
|
|
53
|
+
// wltpCombined (discharged for a plug-in); the legacy consumptionCombined / co2 are only a fallback.
|
|
54
|
+
|
|
55
|
+
// Missing or 0 is omitted instead of sending "0l/100km". BEVs carry no fuel consumption
|
|
56
|
+
// (CBD mirrors kWh into consumptionCombined for them).
|
|
57
|
+
export function googleFuelConsumption(car: DataSchemes.Car): string | undefined {
|
|
58
|
+
if (isBev(car)) return undefined;
|
|
59
|
+
const value = isPlugIn(car)
|
|
60
|
+
? positive(get(car, 'consumption.wltpWeightedCombined')) ?? positive(get(car, 'consumption.consumptionCombined'))
|
|
61
|
+
: positive(get(car, 'consumption.consumptionCombined'));
|
|
62
|
+
return value ? `${value}l/100km` : undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Plug-in only. No fallback: the legacy combined value is (close to) the weighted one, sending it
|
|
66
|
+
// here would repeat the weighted figure as the discharged one.
|
|
67
|
+
export function googleFuelConsumptionDischarged(car: DataSchemes.Car): string | undefined {
|
|
68
|
+
if (!isPlugIn(car)) return undefined;
|
|
69
|
+
const value = positive(get(car, 'consumption.wltpCombined'));
|
|
70
|
+
return value ? `${value}l/100km` : undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// BEV: combined consumption. Plug-in: weighted combined. Nothing for other cars.
|
|
74
|
+
export function googleEnergyConsumption(car: DataSchemes.Car): string | undefined {
|
|
75
|
+
let value: number | undefined;
|
|
76
|
+
if (isBev(car)) {
|
|
77
|
+
value = positive(get(car, 'consumption.wltpPowerCombined')) ?? positive(get(car, 'consumption.consumptionPowerCombined'));
|
|
78
|
+
} else if (isPlugIn(car)) {
|
|
79
|
+
value = positive(get(car, 'consumption.wltpWeightedPowerCombined'));
|
|
80
|
+
}
|
|
81
|
+
return value ? `${value}kWh/100km` : undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// A BEV emits 0 g/km by definition; a plug-in sends the weighted WLTP CO2; for every other car the
|
|
85
|
+
// stored value. A missing or 0 value is omitted.
|
|
86
|
+
export function googleCo2(car: DataSchemes.Car): string | undefined {
|
|
87
|
+
if (isBev(car)) return '0g/km';
|
|
88
|
+
const value = isPlugIn(car)
|
|
89
|
+
? positive(get(car, 'environmentEmissions.wltpCo2')) ?? positive(get(car, 'environmentEmissions.co2'))
|
|
90
|
+
: positive(get(car, 'environmentEmissions.co2'));
|
|
91
|
+
return value ? `${value}g/km` : undefined;
|
|
92
|
+
}
|
|
@@ -8,6 +8,14 @@ import { Injectable } from '@nestjs/common';
|
|
|
8
8
|
import { ConfigService, ImagesService, MappingService, TransformerService, UserService } from '../services';
|
|
9
9
|
import { GoogleXmlItem } from '../interfaces';
|
|
10
10
|
import { isValidVin } from '../utils';
|
|
11
|
+
import {
|
|
12
|
+
googleCo2,
|
|
13
|
+
googleElectricRange,
|
|
14
|
+
googleEnergyConsumption,
|
|
15
|
+
googleEngine,
|
|
16
|
+
googleFuelConsumption,
|
|
17
|
+
googleFuelConsumptionDischarged,
|
|
18
|
+
} from './google-feed-envkv';
|
|
11
19
|
import {
|
|
12
20
|
META_PUSH_PRIORITY_ALLOWED_VALUES,
|
|
13
21
|
META_PUSH_PRIORITY_STANDARD,
|
|
@@ -85,17 +93,17 @@ export class GoogleTransformer {
|
|
|
85
93
|
color: this.getColor(car),
|
|
86
94
|
vehicle_option: this.getExtrasField(car),
|
|
87
95
|
body_style: this.mapBodyStyle(car),
|
|
88
|
-
engine:
|
|
96
|
+
engine: googleEngine(car),
|
|
89
97
|
transmission: this.mapTransmission(car),
|
|
90
98
|
drive: this.mapDrive(car),
|
|
91
99
|
doors: this.getDoors(car),
|
|
92
100
|
capacity: this.getCapacity(car),
|
|
93
101
|
date_first_registered: this.getDateFirstRegistered(car),
|
|
94
|
-
fuel_consumption:
|
|
95
|
-
energy_consumption:
|
|
96
|
-
electric_range:
|
|
97
|
-
fuel_consumption_discharged_battery:
|
|
98
|
-
co2_emissions:
|
|
102
|
+
fuel_consumption: googleFuelConsumption(car),
|
|
103
|
+
energy_consumption: googleEnergyConsumption(car),
|
|
104
|
+
electric_range: googleElectricRange(car),
|
|
105
|
+
fuel_consumption_discharged_battery: googleFuelConsumptionDischarged(car),
|
|
106
|
+
co2_emissions: googleCo2(car),
|
|
99
107
|
description: this.processText((await this.getDescription(car))),
|
|
100
108
|
identifier_exists: 'yes',
|
|
101
109
|
availability: 'in_stock',
|
|
@@ -121,6 +129,8 @@ export class GoogleTransformer {
|
|
|
121
129
|
'certification',
|
|
122
130
|
'energy_consumption',
|
|
123
131
|
'electric_range',
|
|
132
|
+
'fuel_consumption',
|
|
133
|
+
'co2_emissions',
|
|
124
134
|
'fuel_consumption_discharged_battery',
|
|
125
135
|
'installment',
|
|
126
136
|
'body_style',
|
|
@@ -329,30 +339,8 @@ export class GoogleTransformer {
|
|
|
329
339
|
return certifications.length ? certifications : undefined;
|
|
330
340
|
}
|
|
331
341
|
|
|
332
|
-
private getEnergyConsumption(car: DataSchemes.Car): string | undefined {
|
|
333
|
-
const fuel = get(car, 'consumption.fuel');
|
|
334
|
-
const isElectricOrHybrid =
|
|
335
|
-
['selector_fuel_electrical', 'selector_fuel_hybridElectricalPetrol', 'selector_fuel_hybridElectricalDiesel'].includes(fuel) ||
|
|
336
|
-
!!get(car, 'engineData.hybridPlugin');
|
|
337
|
-
if (!isElectricOrHybrid) {
|
|
338
|
-
return undefined;
|
|
339
|
-
}
|
|
340
|
-
const power = get(car, 'consumption.wltpPowerCombined') || get(car, 'consumption.consumptionPowerCombined');
|
|
341
|
-
return power ? `${power}kWh/100km` : undefined;
|
|
342
|
-
}
|
|
343
342
|
|
|
344
|
-
private getElectricRange(car: DataSchemes.Car): string | undefined {
|
|
345
|
-
const range = get(car, 'battery.batteryRangeElectric') || get(car, 'battery.wltpRange');
|
|
346
|
-
return range ? `${range}km` : undefined;
|
|
347
|
-
}
|
|
348
343
|
|
|
349
|
-
private getFuelConsumptionDischargedBattery(car: DataSchemes.Car): string | undefined {
|
|
350
|
-
if (!get(car, 'engineData.hybridPlugin')) {
|
|
351
|
-
return undefined;
|
|
352
|
-
}
|
|
353
|
-
const consumption = get(car, 'consumption.consumptionCombined') || get(car, 'consumption.wltpCombined');
|
|
354
|
-
return consumption ? `${consumption}l/100km` : undefined;
|
|
355
|
-
}
|
|
356
344
|
|
|
357
345
|
private getInstallment(car: DataSchemes.Car) {
|
|
358
346
|
const monthlyInstallment = round(get(car, 'rate.monthlyInstallment', null));
|
|
@@ -386,27 +374,6 @@ export class GoogleTransformer {
|
|
|
386
374
|
}
|
|
387
375
|
}
|
|
388
376
|
|
|
389
|
-
private mapFuel(car: DataSchemes.Car): string {
|
|
390
|
-
const available = {
|
|
391
|
-
selector_fuel_petrol: 'Gasoline',
|
|
392
|
-
selector_fuel_diesel: 'Diesel',
|
|
393
|
-
selector_fuel_electrical: 'Electric',
|
|
394
|
-
selector_fuel_hybridElectricalPetrol: 'Hybrid',
|
|
395
|
-
selector_fuel_hybridElectricalDiesel: 'Hybrid',
|
|
396
|
-
selector_fuel_carGas: 'CarGas',
|
|
397
|
-
selector_fuel_naturalGas: 'NaturalGas',
|
|
398
|
-
selector_fuel_ethanol: 'Ethanol',
|
|
399
|
-
selector_fuel_hydrogen: 'Hydrogen',
|
|
400
|
-
selector_unknown: 'Other',
|
|
401
|
-
};
|
|
402
|
-
const fuel = get(car, 'consumption.fuel', 'selector_unknown');
|
|
403
|
-
let engine = get(available, fuel, 'Other')
|
|
404
|
-
const hybridPlugin = car?.engineData?.hybridPlugin;
|
|
405
|
-
if (engine === 'Hybrid' && hybridPlugin)
|
|
406
|
-
engine = 'plug-in_hybrid';
|
|
407
|
-
|
|
408
|
-
return engine;
|
|
409
|
-
}
|
|
410
377
|
|
|
411
378
|
private mapBodyStyle(car: DataSchemes.Car): string {
|
|
412
379
|
const available = {
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Run: npm test (ts-node, no test framework needed)
|
|
2
|
+
import * as assert from 'node:assert/strict';
|
|
3
|
+
import {
|
|
4
|
+
googleCo2,
|
|
5
|
+
googleElectricRange,
|
|
6
|
+
googleEnergyConsumption,
|
|
7
|
+
googleEngine,
|
|
8
|
+
googleFuelConsumption,
|
|
9
|
+
googleFuelConsumptionDischarged,
|
|
10
|
+
} from '../src/transformers/google-feed-envkv';
|
|
11
|
+
|
|
12
|
+
const car = (fuel: string, extra: Record<string, unknown> = {}): any => ({
|
|
13
|
+
consumption: { fuel, ...(extra.consumption as object) },
|
|
14
|
+
engineData: { hybridPlugin: extra.hybridPlugin },
|
|
15
|
+
battery: extra.battery || {},
|
|
16
|
+
environmentEmissions: extra.environmentEmissions || {},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const cases: Array<[string, () => void]> = [
|
|
20
|
+
['LPG and CNG get the values Google accepts', () => {
|
|
21
|
+
assert.equal(googleEngine(car('selector_fuel_carGas')), 'lpg');
|
|
22
|
+
assert.equal(googleEngine(car('selector_fuel_naturalGas')), 'natural_gas');
|
|
23
|
+
}],
|
|
24
|
+
['ethanol, hydrogen and unknown fuels become other', () => {
|
|
25
|
+
assert.equal(googleEngine(car('selector_fuel_ethanol')), 'other');
|
|
26
|
+
assert.equal(googleEngine(car('selector_fuel_hydrogen')), 'other');
|
|
27
|
+
assert.equal(googleEngine(car('selector_fuel_somethingNew')), 'other');
|
|
28
|
+
}],
|
|
29
|
+
['existing engine values are unchanged', () => {
|
|
30
|
+
assert.equal(googleEngine(car('selector_fuel_petrol')), 'Gasoline');
|
|
31
|
+
assert.equal(googleEngine(car('selector_fuel_diesel')), 'Diesel');
|
|
32
|
+
assert.equal(googleEngine(car('selector_fuel_electrical')), 'Electric');
|
|
33
|
+
assert.equal(googleEngine(car('selector_fuel_hybridElectricalPetrol')), 'Hybrid');
|
|
34
|
+
assert.equal(googleEngine(car('selector_fuel_hybridElectricalPetrol', { hybridPlugin: true })), 'plug-in_hybrid');
|
|
35
|
+
}],
|
|
36
|
+
['BEV range is the combined WLTP range, never the city range', () => {
|
|
37
|
+
assert.equal(googleElectricRange(car('selector_fuel_electrical', { battery: { wltpRange: 451, wltpRangeCity: 590 } })), '451km');
|
|
38
|
+
assert.equal(googleElectricRange(car('selector_fuel_electrical', { battery: { wltpRangeCity: 590 } })), undefined);
|
|
39
|
+
}],
|
|
40
|
+
['plug-in range prefers the EAER, then the delivered range', () => {
|
|
41
|
+
const phev = (battery: object) => car('selector_fuel_hybridElectricalPetrol', { hybridPlugin: true, battery });
|
|
42
|
+
assert.equal(googleElectricRange(phev({ wltpTotalRange: 62, wltpRange: 59 })), '62km');
|
|
43
|
+
assert.equal(googleElectricRange(phev({ wltpTotalRange: 0, wltpRange: 59 })), '59km');
|
|
44
|
+
assert.equal(googleElectricRange(phev({ wltpTotalRangeCity: 70 })), undefined);
|
|
45
|
+
}],
|
|
46
|
+
['a range of 0 counts as missing', () => {
|
|
47
|
+
assert.equal(googleElectricRange(car('selector_fuel_electrical', { battery: { wltpRange: 0 } })), undefined);
|
|
48
|
+
}],
|
|
49
|
+
['no range for combustion cars or non-plug-in hybrids', () => {
|
|
50
|
+
assert.equal(googleElectricRange(car('selector_fuel_petrol', { battery: { wltpRange: 50 } })), undefined);
|
|
51
|
+
assert.equal(googleElectricRange(car('selector_fuel_hybridElectricalPetrol', { battery: { wltpRange: 50 } })), undefined);
|
|
52
|
+
}],
|
|
53
|
+
['missing or 0 fuel consumption is omitted, never "0l/100km"', () => {
|
|
54
|
+
assert.equal(googleFuelConsumption(car('selector_fuel_petrol', { consumption: { consumptionCombined: 0 } })), undefined);
|
|
55
|
+
assert.equal(googleFuelConsumption(car('selector_fuel_petrol')), undefined);
|
|
56
|
+
assert.equal(googleFuelConsumption(car('selector_fuel_petrol', { consumption: { consumptionCombined: 6.3 } })), '6.3l/100km');
|
|
57
|
+
}],
|
|
58
|
+
['BEVs send no fuel consumption (CBD mirrors kWh into it)', () => {
|
|
59
|
+
assert.equal(googleFuelConsumption(car('selector_fuel_electrical', { consumption: { consumptionCombined: 18 } })), undefined);
|
|
60
|
+
}],
|
|
61
|
+
['CO2: BEV is 0 g/km, other cars omit a missing or 0 value', () => {
|
|
62
|
+
assert.equal(googleCo2(car('selector_fuel_electrical')), '0g/km');
|
|
63
|
+
assert.equal(googleCo2(car('selector_fuel_petrol', { environmentEmissions: { co2: 0 } })), undefined);
|
|
64
|
+
assert.equal(googleCo2(car('selector_fuel_petrol', { environmentEmissions: { co2: 144 } })), '144g/km');
|
|
65
|
+
}],
|
|
66
|
+
['plug-in: weighted fuel, discharged fuel, weighted electricity and weighted CO2', () => {
|
|
67
|
+
const phev = car('selector_fuel_hybridElectricalPetrol', {
|
|
68
|
+
hybridPlugin: true,
|
|
69
|
+
consumption: { consumptionCombined: 1.4, wltpCombined: 6.3, wltpWeightedCombined: 1.2, wltpPowerCombined: 19.3, wltpWeightedPowerCombined: 17.3 },
|
|
70
|
+
environmentEmissions: { co2: 121, wltpCo2: 28 },
|
|
71
|
+
});
|
|
72
|
+
assert.equal(googleFuelConsumption(phev), '1.2l/100km');
|
|
73
|
+
assert.equal(googleFuelConsumptionDischarged(phev), '6.3l/100km');
|
|
74
|
+
assert.equal(googleEnergyConsumption(phev), '17.3kWh/100km');
|
|
75
|
+
assert.equal(googleCo2(phev), '28g/km');
|
|
76
|
+
}],
|
|
77
|
+
['plug-in without weighted values falls back to the legacy combined ones, never the pure-electric value', () => {
|
|
78
|
+
const phev = car('selector_fuel_hybridElectricalPetrol', {
|
|
79
|
+
hybridPlugin: true,
|
|
80
|
+
consumption: { consumptionCombined: 1.4, wltpPowerCombined: 19.3 },
|
|
81
|
+
environmentEmissions: { co2: 32 },
|
|
82
|
+
});
|
|
83
|
+
assert.equal(googleFuelConsumption(phev), '1.4l/100km');
|
|
84
|
+
assert.equal(googleFuelConsumptionDischarged(phev), undefined);
|
|
85
|
+
assert.equal(googleEnergyConsumption(phev), undefined);
|
|
86
|
+
assert.equal(googleCo2(phev), '32g/km');
|
|
87
|
+
}],
|
|
88
|
+
['non-plug-in hybrids and combustion cars keep the stored values and send no electricity', () => {
|
|
89
|
+
const hev = car('selector_fuel_hybridElectricalPetrol', {
|
|
90
|
+
consumption: { consumptionCombined: 5.1, wltpCombined: 5.3, wltpWeightedCombined: 2.3, wltpWeightedPowerCombined: 21.5 },
|
|
91
|
+
environmentEmissions: { co2: 116, wltpCo2: 119 },
|
|
92
|
+
});
|
|
93
|
+
assert.equal(googleFuelConsumption(hev), '5.1l/100km');
|
|
94
|
+
assert.equal(googleFuelConsumptionDischarged(hev), undefined);
|
|
95
|
+
assert.equal(googleEnergyConsumption(hev), undefined);
|
|
96
|
+
assert.equal(googleCo2(hev), '116g/km');
|
|
97
|
+
}],
|
|
98
|
+
['BEV energy consumption is the combined value', () => {
|
|
99
|
+
assert.equal(googleEnergyConsumption(car('selector_fuel_electrical', { consumption: { wltpPowerCombined: 16.5 } })), '16.5kWh/100km');
|
|
100
|
+
assert.equal(googleEnergyConsumption(car('selector_fuel_electrical', { consumption: { consumptionPowerCombined: 18 } })), '18kWh/100km');
|
|
101
|
+
}],
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
let failed = 0;
|
|
105
|
+
for (const [name, fn] of cases) {
|
|
106
|
+
try {
|
|
107
|
+
fn();
|
|
108
|
+
console.log(`ok ${name}`);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
failed++;
|
|
111
|
+
console.log(`FAIL ${name}\n ${(e as Error).message}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (failed) process.exit(1);
|