From f4415d13ed79526f9902fe5035da3d7e29185155 Mon Sep 17 00:00:00 2001 From: kosuke55 Date: Mon, 10 Aug 2026 21:59:18 +0900 Subject: [PATCH] fix(sdk): createPedestrian emitted a shape type no consumer recognises `createPedestrian` returned `type: 'pedestrian'`, but nothing in the SDK or the editor handles that type: - the editor has only ever stored placed participants as `vehicle` (pedestrians are a `templateId`, not a shape type) - `exporter/openscenario.ts` iterates `shape.type !== 'vehicle' && continue` and picks `` vs `` from PEDESTRIAN_PATTERNS So scenes built with `createPedestrian` silently lost every pedestrian: `exportToOpenScenario` emitted 0 ScenarioObjects for them, with no warning. `createVehicle` and `createPedestrian` differ only in the default templateId ('filled'), which already matches the exporter's pedestrian patterns. Return `type: 'vehicle'` so the factory agrees with its own consumers, and document why, since the naming otherwise invites the same mistake again. Verified with plain Node: a lane + createVehicle + createPedestrian scene now emits 2 entities named Vehicle_0 / Pedestrian_1, with ``. Adds __tests__/helpersFactoryContract.test.ts. It runs factory output through the exporter rather than asserting the shape type, because the type alone would not have caught the consequence. No existing test referenced createPedestrian, which is why this went unnoticed. Confirmed both cases fail when the old type is restored. --- .../__tests__/helpersFactoryContract.test.ts | 43 +++++++++++++++++++ packages/drawtonomy-sdk/src/helpers.ts | 16 ++++++- 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 packages/drawtonomy-sdk/__tests__/helpersFactoryContract.test.ts diff --git a/packages/drawtonomy-sdk/__tests__/helpersFactoryContract.test.ts b/packages/drawtonomy-sdk/__tests__/helpersFactoryContract.test.ts new file mode 100644 index 0000000..6d841d1 --- /dev/null +++ b/packages/drawtonomy-sdk/__tests__/helpersFactoryContract.test.ts @@ -0,0 +1,43 @@ +import { describe, it, expect } from 'vitest' +import { createLaneWithBoundaries, createPedestrian, createSnapshot, createVehicle } from '../src/helpers.js' +import { exportToOpenScenario } from '../src/exporter/openscenario.js' + +/** + * The factories must produce shapes that the rest of the SDK actually consumes. + * + * `createPedestrian` used to emit `type: 'pedestrian'`, a shape type no consumer + * recognises: the editor has only ever stored placed participants as `vehicle`, + * and the OpenSCENARIO exporter selects `` vs `` from + * `templateId`. Scenes built with it silently lost every pedestrian — the + * exporter emitted zero ScenarioObjects for them. + * + * Asserting the shape type alone is not enough (it would not have caught the + * consequence), so these tests run the factory output through the exporter. + */ +describe('factory output is consumable by the exporters', () => { + const lane = createLaneWithBoundaries( + [{ x: 0, y: 0 }, { x: 500, y: 0 }], + [{ x: 0, y: 50 }, { x: 500, y: 50 }], + ) + + it('createPedestrian produces a shape the OpenSCENARIO exporter emits', () => { + const pedestrian = createPedestrian(300, 25) + const xosc = exportToOpenScenario(createSnapshot([...lane, pedestrian]), {}) + + expect(xosc).toContain(' { + const xosc = exportToOpenScenario( + createSnapshot([...lane, createVehicle(100, 25), createPedestrian(300, 25)]), + {}, + ) + const names = [...xosc.matchAll(/ m[1]) + + expect(names).toEqual(['Vehicle_0', 'Pedestrian_1']) + expect(xosc).toContain('` vs `` from `templateId` + * (see PEDESTRIAN_PATTERNS in exporter/openscenario.ts). + * + * Emitting `type: 'pedestrian'` here produced shapes that no consumer + * recognised — they were skipped by the exporter (0 ScenarioObjects) and + * unknown to the editor. + */ export function createPedestrian( x: number, y: number, options?: Partial & { id?: string } -): BaseShape<'pedestrian', PedestrianProps> { +): BaseShape<'vehicle', PedestrianProps> { return { id: options?.id ?? nextId('ped'), - type: 'pedestrian', + type: 'vehicle', x, y, rotation: 0,