mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 09:27:29 +00:00
- 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.
8.7 KiB
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): HostErrorfunction mockEditorHost(file: MockEditorFile, options?: MockEditorHostOptions): MockEditorHost: A stand-in for Orca's custom editor host, backed by an in-memory file: installsglobalThis.orcawith the real frame shell's document API andsession(), 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'smigrate.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-exportedactivate(orca)with theorcaobject Orca passes, backed bymockHost(worker methods, the manifest's capabilities)..tsmains load as Orca loads them.function defineCheck<S extends Record<string, CheckScenario>>(scenarios: S): S: Named scenarios fororca plugin check, as the default export of<entry>.check.tsbeside the panel (src/panel.check.tsforsrc/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'snode:test, re-exported so a test type-checks without the Node typings.function describe(name: string, fn: () => unknown): Promise<void>function beforeEach(fn: () => unknown): voidfunction afterEach(fn: () => unknown): void
TestPanel (from mount)
host: MockHosterrors: 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;storageis 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 (replaceclears it first);submitpresses 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 (needshasMoreandonLoadMore).expand(target: Target, key: string): Tree: expand or collapse an item, callingonToggle.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 atwidthpx (wide when omitted), afterhideBelow.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 withorca.panels.post;plugin.onhandlers hear it.post(event: Undeclared<N, PluginPanelEvents>, payload?: JsonValue)setVisible(visible: boolean)rerender()settled()unmount(): Ends the run: setup cleanup,ctx.signaland subscriptions, as when the panel closes.
TestWorker (from mountWorker)
host: MockHostlogs: readonly string[]: What the worker passed toorca.log.refusals: readonly MockHostRefusal[]posts: readonly { event: string; payload?: unknown; panel?: string }[]: What the worker sent withorca.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'splugin.request, answered by the worker'sorca.panels.handle;panelnames the calling panel's contribution id. An unhandled name rejects withunknown_method.request(name: Undeclared<N, PluginRequests>, input?: JsonValue, caller?: { panel?: string })deactivate(): Runs the module'sdeactivateand 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_paramsorunknown_methodcalls.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 asglobalThis.orca.text: string | undefined: The file as Orca holds it now; undefined for a bytes file.bytes: Uint8Array | undefinedversion: number: Rises with each document sent to the editor.edits: readonly MockEditorEdit[]: EveryapplyEdit, 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 withconflict, after landingoutsidefirst 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(): RemovesglobalThis.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][] }