Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 `<Pedestrian>` vs `<Vehicle>` 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('<Pedestrian ')
expect(xosc).toContain('pedestrianCategory="pedestrian"')
expect(xosc.match(/<ScenarioObject /g) ?? []).toHaveLength(1)
})

it('vehicles and pedestrians coexist and are told apart', () => {
const xosc = exportToOpenScenario(
createSnapshot([...lane, createVehicle(100, 25), createPedestrian(300, 25)]),
{},
)
const names = [...xosc.matchAll(/<ScenarioObject name="([^"]+)"/g)].map((m) => m[1])

expect(names).toEqual(['Vehicle_0', 'Pedestrian_1'])
expect(xosc).toContain('<Vehicle ')
expect(xosc).toContain('<Pedestrian ')
})
})
16 changes: 14 additions & 2 deletions packages/drawtonomy-sdk/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,26 @@ export function createVehicle(

// --- Pedestrian ---

/**
* Pedestrians are stored as `type: 'vehicle'` with a pedestrian `templateId`.
*
* This is not a quirk of this helper: the editor has only ever had the
* `vehicle` shape type for placed participants, and the OpenSCENARIO
* exporter decides `<Pedestrian>` vs `<Vehicle>` 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<PedestrianProps> & { id?: string }
): BaseShape<'pedestrian', PedestrianProps> {
): BaseShape<'vehicle', PedestrianProps> {
return {
id: options?.id ?? nextId('ped'),
type: 'pedestrian',
type: 'vehicle',
x,
y,
rotation: 0,
Expand Down
Loading