Files
Neil 36f17a04a7 plugins: Box layout container for components panels (catalog 4) (#37420)
- Box (ui.catalog 4, since 1.4.248): direction, gap/padding/paddingX/
  paddingY/margin on the gap scale, align, justify, wrap, grow, shrink,
  width/height/min/max (px up to 4096 or whole percents), columns,
  scroll, border (true or a tone), radius, background (theme surfaces or
  tone tints). Strict props: hex colours, CSS lengths and unknown props
  are dropped with a warning like other components.
- Renderer maps props to theme tokens through data attributes; sizes
  reach inline style only as validated px or percents.
- Typings, docs, skill references, gallery Layout tab; orca/testing
  finds Boxes and summarizes danger or warning Boxes.
2026-11-02 01:05:57 -08:00

8.7 KiB

Test kit (orca/testing)

ORCA plugin test runs *.test.ts(x) files in Node with orca and orca/testing resolved to what this Orca ships, and plugin sources (panels and the worker main) loaded as Orca loads them. Every act resolves once the panel or worker has settled: await it and never add sleeps.

Functions

  • function mockHost(options?: MockHostOptions): MockHost: A stand-in Orca host that refuses what Orca refuses, with the same codes: a missing capability, bad params, a method panels cannot call, and a user-gesture method (shell.openExternal, files.saveAs) without a press first.
  • function hostError(code: string, message?: string, retryAfterMs?: number): HostError
  • function mockEditorHost(file: MockEditorFile, options?: MockEditorHostOptions): MockEditorHost: A stand-in for Orca's custom editor host, backed by an in-memory file: installs globalThis.orca with the real frame shell's document API and session(), so sync logic tests in Node. Answers only document calls. One at a time: a new one disposes the last.
  • function stored(value: unknown, version: number): unknown: A persisted value an older version wrote, to test an atom's migrate.
  • function mount(target: PanelModule | (() => OrcaNode), options?: MountOptions): Promise<TestPanel>: Mounts a panel module (import * as panel from './panel') or its component, with the real runtime and Orca's own checks, and resolves once it has drawn. Mounting again starts over: every atom goes back to its initial value.
  • function mountWorker(module: WorkerModule, options?: MountWorkerOptions): Promise<TestWorker>: Calls the worker's default-exported activate(orca) with the orca object Orca passes, backed by mockHost (worker methods, the manifest's capabilities). .ts mains load as Orca loads them.
  • function defineCheck<S extends Record<string, CheckScenario>>(scenarios: S): S: Named scenarios for orca plugin check, as the default export of <entry>.check.ts beside the panel (src/panel.check.ts for src/panel.tsx). Check renders the panel once per scenario, with the plugin's worker on the same host; without the file it renders once with defaults.
  • function test(name: string, fn: () => unknown): Promise<void>: Node's node:test, re-exported so a test type-checks without the Node typings.
  • function describe(name: string, fn: () => unknown): Promise<void>
  • function beforeEach(fn: () => unknown): void
  • function afterEach(fn: () => unknown): void

TestPanel (from mount)

  • host: MockHost
  • errors: readonly PanelIssue[]
  • warnings: readonly string[]: Props and components Orca would drop, as Orca would warn.
  • refusals: readonly MockHostRefusal[]: Host calls Orca would refuse (a missing capability, no press), even ones the panel caught.
  • persisted: { plugin: Record<string, unknown>; workspace: Record<string, unknown>; storage: Record<string, unknown> }: What persisted atoms hold now, by scope and key; storage is the plugin's storage.
  • find(query: TestQuery): The innermost match, or null.
  • findAll(query: TestQuery)
  • tree(): The drawn tree as plain data, for snapshots; handlers show as [handler].
  • summary(): One line per thing a person notices first: headings, callouts, empty states, table and tree sizes, the selected tab, loading placeholders, danger or warning text and boxes.
  • press(target: Target): Each act grants one gesture (a press) and resolves once the panel has settled.
  • type(target: Target, text: string, options?: { replace?: boolean; submit?: boolean }): Types after what the field holds (replace clears it first); submit presses Enter.
  • submit(target: Target)
  • toggle(target: Target): A Switch, Checkbox or Collapsible.
  • select(target: Target, value: string): A Select or RadioGroup option, or a Tabs tab, by value.
  • slide(target: Target, value: number)
  • sort(target: Target, column: string): Table: a header click (ascending first, then flipping).
  • selectRows(target: Target, keys: readonly string[]): Table: replaces the selection with exactly these rows.
  • activateRow(target: Target, key: string): Table: Enter or a double click on a row.
  • loadMore(target: Target): Table: scrolls to the end of the loaded rows (needs hasMore and onLoadMore).
  • expand(target: Target, key: string): Tree: expand or collapse an item, calling onToggle.
  • collapse(target: Target, key: string)
  • selectItem(target: Target, key: string)
  • activateItem(target: Target, key: string)
  • expandedOf(target: Target): Tree: the items Orca shows expanded.
  • columnsOf(target: Target, view?: { width?: number }): Table: the column keys Orca shows at width px (wide when omitted), after hideBelow.
  • rowsOf(target: Target): Table: row keys in the order Orca draws them.
  • valueOf(target: Target): What Orca shows in a value control: text, a flag, a number, a tab, or selected keys.
  • emit(event: E, payload: OrcaEvents[E]): An Orca event: theme, or a workspace or agent event the panel subscribed to.
  • post(event: K, payload: PluginPanelEvents[K]): What the plugin's worker posts with orca.panels.post; plugin.on handlers hear it.
  • post(event: Undeclared<N, PluginPanelEvents>, payload?: JsonValue)
  • setVisible(visible: boolean)
  • rerender()
  • settled()
  • unmount(): Ends the run: setup cleanup, ctx.signal and subscriptions, as when the panel closes.

TestWorker (from mountWorker)

  • host: MockHost
  • logs: readonly string[]: What the worker passed to orca.log.
  • refusals: readonly MockHostRefusal[]
  • posts: readonly { event: string; payload?: unknown; panel?: string }[]: What the worker sent with orca.panels.post, in order.
  • emit(event: E, payload: PluginEvents[E]): Delivers an event as Orca would (checked against Orca's payload schema) and waits for every handler.
  • hooks: { fire<H extends PluginHookName>(hook: H, event: PluginHooks[H]['event']): Promise<HookDecision<H>> }
  • command(commandId: string, args?: unknown): Runs a registered command and resolves with its result.
  • request(name: K, input?: PluginRequestInput<K>, caller?: { panel?: string }): A panel's plugin.request, answered by the worker's orca.panels.handle; panel names the calling panel's contribution id. An unhandled name rejects with unknown_method.
  • request(name: Undeclared<N, PluginRequests>, input?: JsonValue, caller?: { panel?: string })
  • deactivate(): Runs the module's deactivate and drops its handlers.

MockHost (from mockHost)

  • calls: readonly { method: string; params: unknown }[]: Every call that reached the host, in order, refused ones included.
  • refusals: readonly MockHostRefusal[]: capability_denied, not_permitted, invalid_params or unknown_method calls.
  • callsOf(method: string)
  • respond(method: string, result: unknown)
  • data(): The plugin's storage, settings and secrets as they are now.

MockEditorHost (from mockEditorHost)

  • orca: OrcaFrameApi: The frame API, also installed as globalThis.orca.
  • text: string | undefined: The file as Orca holds it now; undefined for a bytes file.
  • bytes: Uint8Array | undefined
  • version: number: Rises with each document sent to the editor.
  • edits: readonly MockEditorEdit[]: Every applyEdit, in order, refused ones included.
  • replace(next: string | ArrayBuffer | Uint8Array): An outside change, such as an agent writing the file.
  • conflictNext(outside?: string | ArrayBuffer | Uint8Array): Refuses the next edit with conflict, after landing outside first when given.
  • flush(): As a save does: asks the editor for pending edits and waits for its answer (1 s); rejects, as Orca refuses to save, after an edit too large to apply.
  • setTheme(colorScheme: 'light' | 'dark')
  • dispose(): Removes globalThis.orca.

Options

  • MountOptions = { host?: MockHost; theme?: 'light' | 'dark'; locale?: string; visible?: boolean; panelId?: string; persisted?: { plugin?: Record<string, unknown>; workspace?: Record<string, unknown> } }
  • MountWorkerOptions = { host?: MockHost; events?: readonly string[]; commands?: readonly string[]; hooks?: readonly (string | { event: string; onError?: 'pass' | 'deny' })[] }
  • MockHostOptions = { capabilities?: readonly string[]; results?: Record<string, unknown>; requests?: MockRequests; storage?: Record<string, JsonValue>; settings?: Record<string, JsonValue>; secrets?: Record<string, string> }
  • MockEditorHostOptions = { readOnly?: boolean; colorScheme?: 'light' | 'dark'; locale?: string; fileType?: string }
  • CheckScenario = MockHostOptions & { persisted?: MountOptions['persisted']; theme?: 'light' | 'dark'; events?: readonly { [E in keyof OrcaEvents]: { event: E; payload: OrcaEvents[E] } }[keyof OrcaEvents][] }