/** Render-layer contract tests that do not require a WebGL context. */ import assert from "node:assert/strict"; import { describe, it } from "node:test"; import * as THREE from "three"; import type { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; import CALIFORNIA_TRANSPORT from "../transport/california.ts"; import { createRoadTrafficLayer } from "../engine/roadTraffic.ts"; import type { World } from "../engine/world.ts"; function fixture() { const world = { project(lat: number, lng: number): [number, number] { return [(lng + 121) * 20, -(lat - 36) * 20]; }, groundAt(): number { return 0; }, } as unknown as World; const camera = new THREE.PerspectiveCamera(42, 16 / 9, 0.1, 2_000); const controls = { target: new THREE.Vector3(), enabled: true, } as unknown as OrbitControls; const layer = createRoadTrafficLayer(world, camera, controls, { pack: CALIFORNIA_TRANSPORT, routeId: "la-sf-us-101", count: 8, seed: 115, }); return { layer, camera, controls }; } describe("road traffic render layer", () => { it("draws one articulated hero and instanced background parts", () => { const { layer } = fixture(); const hero = layer.group.getObjectByName("model-x-hero"); assert.ok(hero); assert.equal(hero.scale.x, 0.18); assert.ok(layer.group.children.some((child) => child instanceof THREE.InstancedMesh)); assert.equal(layer.hero()?.routeId, "la-sf-us-101"); assert.ok(Math.abs(hero.position.y - 0.155) < 1e-9); layer.dispose(); }); it("switches routes and owns the orbit-control handoff while following", () => { const { layer, camera, controls } = fixture(); layer.setRoute("la-sf-i-5"); assert.equal(layer.routeId(), "la-sf-i-5"); assert.equal(layer.hero()?.routeId, "la-sf-i-5"); layer.setFollowing(true); assert.equal(layer.following(), true); assert.equal(controls.enabled, false); layer.tick(0.1); assert.ok(camera.position.toArray().every(Number.isFinite)); assert.ok(controls.target.toArray().every(Number.isFinite)); layer.setCameraMode("driver"); assert.equal(layer.cameraMode(), "driver"); layer.tick(1 / 60); assert.ok(camera.position.y > layer.group.getObjectByName("model-x-hero")!.position.y); layer.setFollowing(false); assert.equal(controls.enabled, true); layer.dispose(); }); it("hands manual input to the deterministic hero and resumes assistance", () => { const { layer } = fixture(); for (let index = 0; index < 20; index += 1) { layer.setVehicleActions({ throttle: 1, steering: 0.8 }); layer.tick(1 / 30); } assert.equal(layer.hero().mode, "manual"); assert.ok(layer.hero().lateralOffsetM > 0); layer.setVehicleActions({ modeRequest: "assisted" }); layer.tick(1 / 30); assert.equal(layer.hero().mode, "assisted"); layer.dispose(); }); });