Skip to content

createTestWrapper

Create a reusable test harness for a language package. Returns a Wrapper component (wraps content in <Output> + <SourceFile>) and a defkey helper that creates stable namekeys for pre-declaring symbols.

import { createTestWrapper } from "@alloy-js/core/testing";
function createTestWrapper<SymbolT extends OutputSymbol, ScopeT extends {
spaces: any;
}>(opts: {
filePath: string;
useScope: () => ScopeT | undefined;
makeSymbol: (nk: Namekey, scope: ScopeT) => SymbolT;
SourceFile: (props: {
path: string;
children: Children;
}) => any;
namePolicy?: NamePolicy<string>;
nameConflictResolver?: NameConflictResolver;
}): TestWrapper;
opts{ filePath: string; useScope: () => ScopeT | undefined; makeSymbol: (nk: Namekey, scope: ScopeT) => SymbolT; SourceFile: (props: { path: string; children: Children; }) => any; namePolicy?: NamePolicy<string>; nameConflictResolver?: NameConflictResolver; }

TestWrapper

Downstream consumers import and call this from the language package’s testing/ entrypoint. The Wrapper automatically declares symbols created by defkey before rendering children, so tests can reference symbols without explicit <Declaration> boilerplate.

// In your language package's testing/ entrypoint:
import { FileComponent } from "./components/index.js"; // your language package's top-level file component
import { createTestWrapper, type TestWrapper } from "@alloy-js/core/testing";

export function createMyLangTestWrapper(): TestWrapper {
  return createTestWrapper({
    filePath: "test.ext",
    useScope: useMyLangScope,
    makeSymbol: (nk, scope) => new MyOutputSymbol(nk, scope),
    SourceFile: FileComponent,
  });
}
// Extend your language test factory to accept and forward namePolicy:
export function createMyLangTestWrapper(namePolicy?: NamePolicy<string>): TestWrapper {
  return createTestWrapper({ ...langOpts, namePolicy });
}

// In a name-policy test:
const { Wrapper } = createMyLangTestWrapper(myNamePolicy);
const fooKey = namekey("foo"); // namekey(), not defkey — name policy applies
// namekey() schedules no pre-declaration; the test body must declare the symbol.
expect(
  <Wrapper>
    <MyDeclaration refkey={fooKey} name="foo" />
  </Wrapper>
).toRenderTo("FOO");