Files
lingniu-vehicle-ingest/station-navigation/tests/test_app.mjs
T

104 lines
5.8 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs';
import vm from 'node:vm';
const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8');
const styles = fs.readFileSync(new URL('../styles.css', import.meta.url), 'utf8');
const sandbox = {
console,
document: { addEventListener() {}, getElementById() { return null; } },
window: {},
pinyinPro: { pinyin(value) { return value === '广州合作站' ? 'guang zhou he zuo zhan' : value; } },
navigator: {},
};
sandbox.globalThis = sandbox;
vm.runInNewContext(source, sandbox, { filename: 'app.js' });
assert.equal(sandbox.stationSearchScore({ name: '广州合作站' }, 'gz'), 2);
assert.equal(sandbox.stationSearchScore({ address: '广东省广州市黄埔区' }, '黄埔'), 3);
assert.equal(sandbox.stationSearchScore({ name: '广州合作站' }, '北京'), 0);
assert.equal(sandbox.hasCoordinates({ longitude: 113.2, latitude: 23.1 }), true);
assert.equal(sandbox.hasCoordinates({ longitude: 'bad', latitude: 23.1 }), false);
vm.runInNewContext(`
state.stations = [
{ id: 'partner', name: '广州合作站', cooperative: true },
{ id: 'external', name: '广州外部站', cooperative: false }
];
globalThis.allStationIds = filteredStations().map(station => station.id);
state.stationFilter = 'partner';
globalThis.partnerStationIds = filteredStations().map(station => station.id);
`, sandbox);
assert.equal(sandbox.allStationIds.join(','), 'partner,external');
assert.equal(sandbox.partnerStationIds.join(','), 'partner');
vm.runInNewContext(`
state.stations = [
{ id: 'gd-hp', name: '黄埔合作站', province: '广东省', city: '广州市', district: '黄埔区', longitude: 113.3, latitude: 23.1, cooperative: true },
{ id: 'gd-nh', name: '南海合作站', province: '广东省', city: '佛山市', district: '南海区', longitude: 113.1, latitude: 23.0, cooperative: true },
{ id: 'zj-jx', name: '嘉兴合作站', province: '浙江省', city: '嘉兴市', district: '秀洲区', longitude: 120.7, latitude: 30.7, cooperative: true }
];
globalThis.hierarchy = [stationHierarchyLevel(4.8), stationHierarchyLevel(8), stationHierarchyLevel(13)];
globalThis.provinceNodeCount = buildStationNodes(filteredStations(), 'province').length;
globalThis.cityNodeCount = buildStationNodes(filteredStations(), 'city').length;
globalThis.stationNodeCount = buildStationNodes(filteredStations(), 'station').length;
globalThis.locationOptionCount = stationLocationOptions().length;
`, sandbox);
assert.equal(sandbox.hierarchy.join(','), 'province,city,station');
assert.equal(sandbox.provinceNodeCount, 2);
assert.equal(sandbox.cityNodeCount, 3);
assert.equal(sandbox.stationNodeCount, 3);
assert.equal(sandbox.locationOptionCount, 8);
vm.runInNewContext(`
globalThis.inferredDistrict = stationDistrictName({ province: '浙江省', city: '嘉兴市', address: '嘉兴市海盐县海盐经济开发区' });
state.locationFilters = [];
state.query = '广州';
globalThis.queryMatches = stationMatchesQuery({ name: '广州合作站' });
globalThis.queryMisses = stationMatchesQuery({ name: '杭州合作站' });
`, sandbox);
assert.equal(sandbox.inferredDistrict, '海盐县');
assert.equal(sandbox.queryMatches, true);
assert.equal(sandbox.queryMisses, false);
vm.runInNewContext(`
state.query = '';
state.locationFilters = [
{ level: 'city', province: '广东省', city: '广州市', district: '', label: '广州' },
{ level: 'city', province: '浙江省', city: '嘉兴市', district: '', label: '嘉兴' }
];
globalThis.multiLocationMatches = [
stationMatchesLocation({ province: '广东省', city: '广州市', district: '白云区' }),
stationMatchesLocation({ province: '浙江省', city: '嘉兴市', district: '海盐县' }),
stationMatchesLocation({ province: '广东省', city: '深圳市', district: '南山区' })
];
`, sandbox);
assert.equal(sandbox.multiLocationMatches.join(','), 'true,true,false');
assert.ok(Math.abs(sandbox.distanceKm([113, 23], [114, 23]) - 102.4) < 1);
assert.match(source, /zoom < 11\) return 'city'/);
assert.match(source, /state\.userLocation && left\.kind === 'station'/);
assert.doesNotMatch(source, /rankSecondaryTab|setRank\(/);
assert.match(source, /stationSearchSuggestions/);
assert.match(source, /handleStationSearchInput/);
assert.match(source, /locationFilters/);
assert.match(source, /renderLocationFilterChips/);
assert.match(source, /kpiTotal|kpiPartner/);
const index = fs.readFileSync(new URL('../index.html', import.meta.url), 'utf8');
assert.match(index, /station-summary-strip/);
assert.match(index, /station-status-card/);
assert.equal((index.match(/id="statusTotal"/g) || []).length, 1);
assert.equal((index.match(/id="mobileStatusTotal"/g) || []).length, 1);
assert.match(source, /window\.setTimeout\(\(\) => \{ state\.query = value/);
assert.match(source, /focusSearchResults\(\)/);
assert.match(source, /visibleOnly && !normalize\(state\.query\)/);
assert.match(source, /station-list-partner-tag/);
assert.match(source, /station-list-partner-tag\$\{node\.cooperative \? '' : ' is-placeholder'\}/);
assert.match(source, /node\.kind === 'station' \? '' : `\$\{formatNumber\(node\.count\)\} 座`/);
assert.match(source, /node\.cooperative \? 'H₂ · 合作' : ''/);
assert.doesNotMatch(source, /在线 \$\{formatNumber\(node\.online\)\}/);
assert.doesNotMatch(source, /monthlyHydrogenKg|totalHydrogenKg|vehicle/);
assert.match(source, /uri\.amap\.com\/navigation/);
assert.equal((source.match(/function navigateToStation\(/g) || []).length, 1);
assert.match(styles, /station-summary-strip/);
assert.match(styles, /header-kpi-group,\n \.station-navigation-shell \.station-status-card/);
assert.match(styles, /theme-switcher-bw \.bw-btn span \{ display: none; \}/);
assert.match(styles, /height: clamp\(430px, 58dvh, 540px\)/);
assert.match(styles, /map-action-controls \.glass-btn:nth-child\(2\)/);
console.log('station navigation app tests: ok');