Automate issuer overlay creation from ticker searches
This commit is contained in:
@@ -4,6 +4,7 @@ import type {
|
||||
TaxonomyHydrationInput,
|
||||
TaxonomyHydrationResult,
|
||||
} from "@/lib/server/taxonomy/types";
|
||||
import type { IssuerOverlayDefinition } from "@/lib/server/db/schema";
|
||||
import { __parserClientInternals } from "@/lib/server/taxonomy/parser-client";
|
||||
|
||||
function streamFromText(text: string) {
|
||||
@@ -81,6 +82,10 @@ function sampleHydrationResult(): TaxonomyHydrationResult {
|
||||
kpi_row_count: 0,
|
||||
unmapped_row_count: 0,
|
||||
material_unmapped_row_count: 0,
|
||||
residual_primary_count: 0,
|
||||
residual_disclosure_count: 0,
|
||||
unsupported_concept_count: 0,
|
||||
issuer_overlay_match_count: 0,
|
||||
warnings: [],
|
||||
},
|
||||
xbrl_validation: {
|
||||
@@ -103,6 +108,22 @@ function sampleInput(): TaxonomyHydrationInput {
|
||||
};
|
||||
}
|
||||
|
||||
function sampleOverlay(): IssuerOverlayDefinition {
|
||||
return {
|
||||
version: "fiscal-v1",
|
||||
ticker: "AAPL",
|
||||
pack: "core",
|
||||
mappings: [
|
||||
{
|
||||
surface_key: "revenue",
|
||||
statement: "income",
|
||||
allowed_source_concepts: ["aapl:ServicesRevenue"],
|
||||
allowed_authoritative_concepts: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
const passThroughTimeout = ((handler: TimerHandler, timeout?: number) =>
|
||||
globalThis.setTimeout(
|
||||
handler,
|
||||
@@ -156,6 +177,47 @@ describe("parser client", () => {
|
||||
expect(result.parser_engine).toBe("fiscal-xbrl");
|
||||
expect(stdinWrite).toHaveBeenCalledTimes(1);
|
||||
expect(stdinEnd).toHaveBeenCalledTimes(1);
|
||||
const [firstCall] = stdinWrite.mock.calls as unknown[][];
|
||||
const firstWrite = firstCall?.[0];
|
||||
expect(firstWrite).toBeDefined();
|
||||
const payload = JSON.parse(
|
||||
new TextDecoder().decode(firstWrite as unknown as Uint8Array),
|
||||
) as { issuerOverlay?: IssuerOverlayDefinition | null };
|
||||
expect(payload.issuerOverlay).toBeNull();
|
||||
});
|
||||
|
||||
it("includes issuer overlay payload when provided", async () => {
|
||||
const stdinWrite = mock(() => {});
|
||||
|
||||
await __parserClientInternals.hydrateFromSidecarImpl(
|
||||
{
|
||||
...sampleInput(),
|
||||
issuerOverlay: sampleOverlay(),
|
||||
},
|
||||
{
|
||||
existsSync: () => true,
|
||||
spawn: mock(() => ({
|
||||
stdin: {
|
||||
write: stdinWrite,
|
||||
end: () => {},
|
||||
},
|
||||
stdout: streamFromText(JSON.stringify(sampleHydrationResult())),
|
||||
stderr: streamFromText(""),
|
||||
exited: Promise.resolve(0),
|
||||
kill: mock(() => {}),
|
||||
})) as never,
|
||||
setTimeout: passThroughTimeout,
|
||||
clearTimeout,
|
||||
},
|
||||
);
|
||||
|
||||
const [firstCall] = stdinWrite.mock.calls as unknown[][];
|
||||
const firstWrite = firstCall?.[0];
|
||||
expect(firstWrite).toBeDefined();
|
||||
const payload = JSON.parse(
|
||||
new TextDecoder().decode(firstWrite as unknown as Uint8Array),
|
||||
) as { issuerOverlay?: IssuerOverlayDefinition | null };
|
||||
expect(payload.issuerOverlay).toEqual(sampleOverlay());
|
||||
});
|
||||
|
||||
it("throws when the sidecar exits non-zero", async () => {
|
||||
|
||||
Reference in New Issue
Block a user