Initial Commit
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Root-export shape snapshot. Pins the canonical exports of
|
||||
* `@suaveplan/api-plugin-example` so the dual-shape refactor cannot
|
||||
* accidentally drop or rename a public surface.
|
||||
*
|
||||
* Uses TypeScript `typeof` + a structural `Equal<>` helper rather than
|
||||
* a runtime structural diff so the assertion fires at typecheck time —
|
||||
* any drift in the exported type's signature breaks the build before
|
||||
* the test even runs.
|
||||
*/
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import * as RootBarrel from "../../src/index.js";
|
||||
|
||||
type Equal<A, B> =
|
||||
(<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2
|
||||
? true
|
||||
: false;
|
||||
|
||||
// Pin the canonical exports — assigning to a `true` constant means the
|
||||
// build fails if the structural compatibility breaks.
|
||||
type _Pin_EXAMPLE_CODES = Equal<
|
||||
typeof RootBarrel.EXAMPLE_CODES,
|
||||
{
|
||||
readonly SUBSCRIPTION_INACTIVE: "PLUGIN.EXAMPLE.SUBSCRIPTION_INACTIVE";
|
||||
readonly INVOICE_NOT_FOUND: "PLUGIN.EXAMPLE.INVOICE_NOT_FOUND";
|
||||
readonly INVALID_INVOICE_STATE: "PLUGIN.EXAMPLE.INVALID_INVOICE_STATE";
|
||||
readonly RESPONSE_VALIDATION_TRIGGER: "PLUGIN.EXAMPLE.RESPONSE_VALIDATION_TRIGGER";
|
||||
}
|
||||
>;
|
||||
const pinExampleCodes: _Pin_EXAMPLE_CODES = true;
|
||||
|
||||
type _Pin_examplePluginModule_name = Equal<
|
||||
typeof RootBarrel.examplePluginModule.name,
|
||||
"@suaveplan/api-plugin-example"
|
||||
>;
|
||||
const pinPluginName: _Pin_examplePluginModule_name = true;
|
||||
|
||||
type _Pin_buildRoutes = Equal<
|
||||
Parameters<typeof RootBarrel.buildRoutes>[0]["ledger"]["nextId"],
|
||||
() => string
|
||||
>;
|
||||
const pinBuildRoutes: _Pin_buildRoutes = true;
|
||||
|
||||
describe("root exports preserve existing types and names", () => {
|
||||
it("exports the canonical EXAMPLE_CODES constants", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
expect(RootBarrel.EXAMPLE_CODES.INVOICE_NOT_FOUND).toBe(
|
||||
"PLUGIN.EXAMPLE.INVOICE_NOT_FOUND"
|
||||
);
|
||||
expect(RootBarrel.EXAMPLE_CODES.SUBSCRIPTION_INACTIVE).toBe(
|
||||
"PLUGIN.EXAMPLE.SUBSCRIPTION_INACTIVE"
|
||||
);
|
||||
expect(RootBarrel.EXAMPLE_CODES.INVALID_INVOICE_STATE).toBe(
|
||||
"PLUGIN.EXAMPLE.INVALID_INVOICE_STATE"
|
||||
);
|
||||
expect(RootBarrel.EXAMPLE_CODES.RESPONSE_VALIDATION_TRIGGER).toBe(
|
||||
"PLUGIN.EXAMPLE.RESPONSE_VALIDATION_TRIGGER"
|
||||
);
|
||||
});
|
||||
|
||||
it("exports ExamplePluginError as a public-constructor class", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const e = new RootBarrel.ExamplePluginError(
|
||||
RootBarrel.EXAMPLE_CODES.INVOICE_NOT_FOUND,
|
||||
"msg"
|
||||
);
|
||||
expect(e.code).toBe("PLUGIN.EXAMPLE.INVOICE_NOT_FOUND");
|
||||
});
|
||||
|
||||
it("exports examplePluginModule with the canonical name + version", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
expect(RootBarrel.examplePluginModule.name).toBe(
|
||||
"@suaveplan/api-plugin-example"
|
||||
);
|
||||
expect(RootBarrel.examplePluginModule.version).toBe("0.1.0");
|
||||
});
|
||||
|
||||
it("exports buildRoutes + createInMemoryLedger", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const ledger = RootBarrel.createInMemoryLedger();
|
||||
const routes = RootBarrel.buildRoutes({
|
||||
ledger,
|
||||
publisher: { publish() {} },
|
||||
});
|
||||
expect(routes.length).toBeGreaterThan(0);
|
||||
expect(typeof ledger.nextId).toBe("function");
|
||||
});
|
||||
|
||||
it("exports the canonical event topics and payload schemas", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
expect(RootBarrel.EXAMPLE_INVOICE_CREATED_TOPIC).toBe(
|
||||
"example.invoice.created"
|
||||
);
|
||||
expect(RootBarrel.USERS_USER_DELETED_TOPIC).toBe("users.user.deleted");
|
||||
expect(RootBarrel.ExampleInvoiceCreatedPayload).toBeDefined();
|
||||
expect(RootBarrel.UsersUserDeletedPayload).toBeDefined();
|
||||
});
|
||||
|
||||
it("exports the request/response Zod schemas", { timeout: 5000 }, () => {
|
||||
expect(RootBarrel.CreateInvoiceRequest).toBeDefined();
|
||||
expect(RootBarrel.CreateInvoiceResponse).toBeDefined();
|
||||
expect(RootBarrel.InvoiceResponse).toBeDefined();
|
||||
expect(RootBarrel.PingResponse).toBeDefined();
|
||||
expect(RootBarrel.StreamChunk).toBeDefined();
|
||||
});
|
||||
|
||||
it("exports instrument helpers", { timeout: 5000 }, () => {
|
||||
expect(typeof RootBarrel.getExampleInstruments).toBe("function");
|
||||
expect(typeof RootBarrel.resetExampleInstrumentsForTest).toBe(
|
||||
"function"
|
||||
);
|
||||
});
|
||||
|
||||
it("type-level pins satisfy structural equality", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
expect(pinExampleCodes).toBe(true);
|
||||
expect(pinPluginName).toBe(true);
|
||||
expect(pinBuildRoutes).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user