Files
osmWorkflow/scripts/test-preview-assets.js

105 lines
4.5 KiB
JavaScript

#!/usr/bin/env node
"use strict";
const assert = require("assert");
const fs = require("fs");
const os = require("os");
const path = require("path");
const { cesiumPreviewHtml } = require("./lib/area-preview");
const { makeVehicleGltf } = require("./lib/vehicle-model");
const { allowedTurns, buildVehicleRoute, classifyConnection } = require("./lib/vehicle-route");
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "preview-assets-"));
const osmPath = path.join(tempDir, "fixture.osm");
fs.writeFileSync(osmPath, `<?xml version="1.0"?>
<osm version="0.6">
<bounds minlon="120" minlat="30" maxlon="120.01" maxlat="30.01"/>
<node id="1" lon="120.001" lat="30.001"/>
<node id="2" lon="120.003" lat="30.001"/>
<node id="3" lon="120.005" lat="30.002"/>
<node id="4" lon="120.007" lat="30.002"/>
<node id="5" lon="120.009" lat="30.002"/>
<way id="west-road">
<nd ref="1"/><nd ref="2"/>
<tag k="highway" v="primary"/><tag k="turn:lanes:forward" v="left|through"/>
</way>
<way id="turn-road">
<nd ref="2"/><nd ref="3"/>
<tag k="highway" v="residential"/><tag k="turn:lanes:forward" v="through|left"/>
</way>
<way id="east-road">
<nd ref="3"/><nd ref="4"/><tag k="highway" v="residential"/>
</way>
<way id="oneway-spur">
<nd ref="4"/><nd ref="5"/><tag k="highway" v="residential"/><tag k="oneway" v="yes"/>
</way>
<way id="footpath">
<nd ref="1"/><nd ref="5"/><tag k="highway" v="footway"/>
</way>
</osm>
`);
const route = buildVehicleRoute(osmPath);
assert.equal(route.source, osmPath);
assert.deepEqual(route.bounds, {
minLon: 120,
minLat: 30,
maxLon: 120.01,
maxLat: 30.01,
});
assert.equal(route.speedMetersPerSecond, 8);
assert.equal(route.loop, true);
assert.equal(route.segments, route.routes, "legacy segments remains an alias for the new route list");
assert.ok(route.routes.length >= 1 && route.routes.length <= 5);
assert.ok(route.routes.every((segment) => segment.edgeIds.length >= 6));
assert.ok(route.routes.every((segment) => segment.maneuvers.includes("u_turn")));
assert.ok(route.routes.every((segment) => segment.maneuvers.some((value) => ["left", "right", "through"].includes(value))));
assert.ok(route.routes.every((segment) => JSON.stringify(segment.coordinates[0]) === JSON.stringify(segment.coordinates.at(-1))));
assert.ok(route.routes.every((segment) => !segment.edgeIds.includes("oneway-spur:backward")));
assert.notDeepEqual(route.routes[0].coordinates, route.routes[0].centerlineCoordinates);
assert.deepEqual(
[...allowedTurns({ "turn:lanes:forward": "left|through;right" }, "forward")].sort(),
["left", "right", "through"],
);
const incoming = { wayId: "in", coordinates: [[120, 30], [120.001, 30]] };
assert.equal(classifyConnection(incoming, { wayId: "left", coordinates: [[120.001, 30], [120.001, 30.001]] }), "left");
assert.equal(classifyConnection(incoming, { wayId: "right", coordinates: [[120.001, 30], [120.001, 29.999]] }), "right");
assert.equal(classifyConnection(incoming, { wayId: "through", coordinates: [[120.001, 30], [120.002, 30]] }), "through");
const vehicle = makeVehicleGltf();
assert.equal(vehicle.asset.version, "2.0");
assert.equal(vehicle.asset.generator, "osm-asset-pipeline vehicle preview");
assert.equal(vehicle.scene, 0);
assert.equal(vehicle.meshes.length, vehicle.nodes.length);
assert.equal(vehicle.scenes[0].nodes.length, vehicle.nodes.length);
assert.deepEqual(
vehicle.materials.map((material) => material.name),
["paint red", "dark roof", "glass", "tire", "wheel hub", "headlight", "tail light"],
);
assert.ok(vehicle.meshes.some((mesh) => mesh.name === "body"));
assert.ok(vehicle.meshes.some((mesh) => mesh.name === "wheel_-1.55_-1.02"));
assert.match(vehicle.buffers[0].uri, /^data:application\/octet-stream;base64,/);
assert.equal(
Buffer.from(vehicle.buffers[0].uri.split(",")[1], "base64").length,
vehicle.buffers[0].byteLength,
);
const html = cesiumPreviewHtml(
"scene<&>.glb",
"scene.json",
"route.json",
"vehicle.gltf",
"north<&>\u2028valley",
);
assert.match(html, /<title>north&lt;&amp;&gt;\u2028valley Cesium Preview<\/title>/);
assert.match(html, /Loading scene&lt;&amp;&gt;\.glb/);
assert.match(html, /"areaId":"north\\u003c\\u0026\\u003e\\u2028valley"/);
assert.match(html, /"glbName":"scene\\u003c\\u0026\\u003e\.glb"/);
assert.match(html, /id="viewMode"/);
assert.match(html, /data-view-mode="inspect"/);
assert.match(html, /id="semanticToggles" class="control-subgroup hidden"/);
fs.rmSync(tempDir, { recursive: true, force: true });
console.log("Preview asset tests passed.");