Files
Neon-Desk/lib/server/financial-taxonomy.test.ts

2066 lines
74 KiB
TypeScript

import { describe, expect, it } from 'bun:test';
import {
__financialTaxonomyInternals,
getCompanyFinancialTaxonomy
} from './financial-taxonomy';
import type { FilingTaxonomySnapshotRecord } from './repos/filing-taxonomy';
import type {
FinancialStatementKind,
FinancialStatementPeriod,
StructuredKpiRow,
TaxonomyFactRow,
TaxonomyStatementRow
} from '@/lib/types';
function createRow(input: {
key?: string;
label?: string;
conceptKey?: string;
qname?: string;
localName?: string;
statement?: FinancialStatementKind;
roleUri?: string | null;
order?: number;
depth?: number;
hasDimensions?: boolean;
values: Record<string, number | null>;
sourceFactIds?: number[];
unit?: string | null;
}): TaxonomyStatementRow {
const localName = input.localName ?? 'RevenueFromContractWithCustomerExcludingAssessedTax';
const conceptKey = input.conceptKey ?? `http://fasb.org/us-gaap/2024#${localName}`;
const qname = input.qname ?? `us-gaap:${localName}`;
return {
key: input.key ?? conceptKey,
label: input.label ?? localName,
conceptKey,
qname,
namespaceUri: 'http://fasb.org/us-gaap/2024',
localName,
isExtension: false,
statement: input.statement ?? 'income',
roleUri: input.roleUri ?? input.statement ?? 'income',
order: input.order ?? 1,
depth: input.depth ?? 0,
parentKey: null,
values: input.values,
units: Object.fromEntries(Object.keys(input.values).map((periodId) => [periodId, input.unit ?? 'iso4217:USD'])),
hasDimensions: input.hasDimensions ?? false,
sourceFactIds: input.sourceFactIds ?? [1]
};
}
function createSnapshot(input: {
filingId: number;
filingType: '10-K' | '10-Q';
filingDate: string;
periods: Array<{
id: string;
periodStart: string | null;
periodEnd: string;
periodLabel: string;
}>;
statement: FinancialStatementKind;
rows?: TaxonomyStatementRow[];
}) {
const defaultRow = createRow({
statement: input.statement,
values: Object.fromEntries(input.periods.map((period, index) => [period.id, 100 + index]))
});
const faithfulRows = {
income: input.statement === 'income' ? (input.rows ?? [defaultRow]) : [],
balance: input.statement === 'balance' ? (input.rows ?? [{ ...defaultRow, statement: 'balance' }]) : [],
cash_flow: input.statement === 'cash_flow' ? (input.rows ?? [{ ...defaultRow, statement: 'cash_flow' }]) : [],
equity: [],
comprehensive_income: []
} satisfies FilingTaxonomySnapshotRecord['faithful_rows'];
return {
id: input.filingId,
filing_id: input.filingId,
ticker: 'MSFT',
filing_date: input.filingDate,
filing_type: input.filingType,
parse_status: 'ready',
parse_error: null,
source: 'xbrl_instance',
parser_engine: 'fiscal-xbrl',
parser_version: '0.1.0',
taxonomy_regime: 'us-gaap',
fiscal_pack: 'core',
periods: input.periods.map((period) => ({
id: period.id,
filingId: input.filingId,
accessionNumber: `0000-${input.filingId}`,
filingDate: input.filingDate,
periodStart: period.periodStart,
periodEnd: period.periodEnd,
filingType: input.filingType,
periodLabel: period.periodLabel
})),
faithful_rows: faithfulRows,
statement_rows: faithfulRows,
surface_rows: {
income: [],
balance: [],
cash_flow: [],
equity: [],
comprehensive_income: []
},
detail_rows: {
income: {},
balance: {},
cash_flow: {},
equity: {},
comprehensive_income: {}
},
kpi_rows: [],
derived_metrics: null,
validation_result: null,
normalization_summary: null,
facts_count: 0,
concepts_count: 0,
dimensions_count: 0,
created_at: input.filingDate,
updated_at: input.filingDate
} satisfies FilingTaxonomySnapshotRecord;
}
function createPeriod(input: {
id: string;
filingId: number;
filingDate: string;
periodEnd: string;
periodStart?: string | null;
filingType?: '10-K' | '10-Q';
}): FinancialStatementPeriod {
return {
id: input.id,
filingId: input.filingId,
accessionNumber: `0000-${input.filingId}`,
filingDate: input.filingDate,
periodStart: input.periodStart ?? null,
periodEnd: input.periodEnd,
filingType: input.filingType ?? '10-Q',
periodLabel: 'Test period'
};
}
function createDimensionFact(input: {
filingId: number;
filingDate: string;
conceptKey: string;
qname: string;
localName: string;
periodEnd: string;
value: number;
axis?: string;
member?: string;
}): TaxonomyFactRow {
return {
id: input.filingId,
snapshotId: input.filingId,
filingId: input.filingId,
filingDate: input.filingDate,
statement: 'income',
roleUri: 'income',
conceptKey: input.conceptKey,
qname: input.qname,
namespaceUri: 'http://fasb.org/us-gaap/2024',
localName: input.localName,
value: input.value,
contextId: `ctx-${input.filingId}`,
unit: 'iso4217:USD',
decimals: null,
periodStart: '2025-01-01',
periodEnd: input.periodEnd,
periodInstant: null,
dimensions: [{
axis: input.axis ?? 'srt:ProductOrServiceAxis',
member: input.member ?? 'msft:CloudMember'
}],
isDimensionless: false,
sourceFile: null
};
}
function createFact(input: {
id?: number;
filingId: number;
filingDate: string;
statement?: FinancialStatementKind;
conceptKey?: string;
qname?: string;
localName: string;
periodEnd: string;
periodStart?: string | null;
periodInstant?: string | null;
value: number;
unit?: string | null;
}): TaxonomyFactRow {
const conceptKey = input.conceptKey ?? `http://fasb.org/us-gaap/2024#${input.localName}`;
const qname = input.qname ?? `us-gaap:${input.localName}`;
return {
id: input.id ?? input.filingId,
snapshotId: input.filingId,
filingId: input.filingId,
filingDate: input.filingDate,
statement: input.statement ?? 'income',
roleUri: input.statement ?? 'income',
conceptKey,
qname,
namespaceUri: 'http://fasb.org/us-gaap/2024',
localName: input.localName,
value: input.value,
contextId: `ctx-${input.filingId}-${input.localName}`,
unit: input.unit ?? 'iso4217:USD',
decimals: null,
periodStart: input.periodStart ?? null,
periodEnd: input.periodEnd,
periodInstant: input.periodInstant ?? null,
dimensions: [],
isDimensionless: true,
sourceFile: null
};
}
function createKpiRow(input: {
key: string;
values: Record<string, number | null>;
provenanceType?: StructuredKpiRow['provenanceType'];
sourceConcepts?: string[];
sourceFactIds?: number[];
}): StructuredKpiRow {
return {
key: input.key,
label: input.key,
category: 'operating_kpi',
unit: 'percent',
order: 10,
segment: null,
axis: null,
member: null,
values: input.values,
sourceConcepts: input.sourceConcepts ?? [],
sourceFactIds: input.sourceFactIds ?? [],
provenanceType: input.provenanceType ?? 'taxonomy',
hasDimensions: false
};
}
function findRow(rows: ReturnType<typeof __financialTaxonomyInternals.buildStandardizedRows>, key: string) {
const row = rows.find((entry) => entry.key === key);
expect(row).toBeDefined();
return row!;
}
function findPeriodId(periods: FinancialStatementPeriod[], periodEnd: string) {
const period = periods.find((entry) => entry.periodEnd === periodEnd);
expect(period).toBeDefined();
return period!.id;
}
function findStandardizedResponseRow(
response: Awaited<ReturnType<typeof getCompanyFinancialTaxonomy>>,
key: string
) {
const row = response.statementRows?.standardized.find((entry) => entry.key === key);
expect(row).toBeDefined();
return row!;
}
describe('financial taxonomy internals', () => {
it('selects the primary quarter duration for 10-Q income statements', () => {
const snapshot = createSnapshot({
filingId: 1,
filingType: '10-Q',
filingDate: '2026-01-28',
statement: 'income',
periods: [
{ id: 'instant', periodStart: null, periodEnd: '2025-12-31', periodLabel: 'Instant' },
{ id: 'quarter', periodStart: '2025-10-01', periodEnd: '2025-12-31', periodLabel: '2025-10-01 to 2025-12-31' },
{ id: 'ytd', periodStart: '2025-07-01', periodEnd: '2025-12-31', periodLabel: '2025-07-01 to 2025-12-31' }
]
});
const selection = __financialTaxonomyInternals.selectPrimaryPeriodsByCadence([snapshot], 'income', 'quarterly');
expect(selection.periods).toHaveLength(1);
expect(selection.periods[0]?.id).toBe('quarter');
});
it('selects the latest instant for balance sheets', () => {
const snapshot = createSnapshot({
filingId: 2,
filingType: '10-K',
filingDate: '2025-07-30',
statement: 'balance',
periods: [
{ id: 'prior', periodStart: null, periodEnd: '2024-06-30', periodLabel: 'Instant' },
{ id: 'current', periodStart: null, periodEnd: '2025-06-30', periodLabel: 'Instant' }
]
});
const selection = __financialTaxonomyInternals.selectPrimaryPeriodsByCadence([snapshot], 'balance', 'annual');
expect(selection.periods).toHaveLength(1);
expect(selection.periods[0]?.id).toBe('current');
});
it('builds one reporting period per filing for the selected statement', () => {
const annual = createSnapshot({
filingId: 10,
filingType: '10-K',
filingDate: '2025-07-30',
statement: 'income',
periods: [
{ id: 'annual', periodStart: '2024-07-01', periodEnd: '2025-06-30', periodLabel: '2024-07-01 to 2025-06-30' },
{ id: 'quarter', periodStart: '2025-04-01', periodEnd: '2025-06-30', periodLabel: '2025-04-01 to 2025-06-30' }
]
});
const quarterly = createSnapshot({
filingId: 11,
filingType: '10-Q',
filingDate: '2025-10-29',
statement: 'income',
periods: [
{ id: 'instant', periodStart: null, periodEnd: '2025-09-30', periodLabel: 'Instant' },
{ id: 'quarter', periodStart: '2025-07-01', periodEnd: '2025-09-30', periodLabel: '2025-07-01 to 2025-09-30' },
{ id: 'ytd', periodStart: '2025-01-01', periodEnd: '2025-09-30', periodLabel: '2025-01-01 to 2025-09-30' }
]
});
const annualPeriods = __financialTaxonomyInternals.selectPrimaryPeriodsByCadence([annual, quarterly], 'income', 'annual').periods;
const quarterlyPeriods = __financialTaxonomyInternals.selectPrimaryPeriodsByCadence([annual, quarterly], 'income', 'quarterly').periods;
expect(annualPeriods.map((period) => period.id)).toEqual(['annual']);
expect(quarterlyPeriods.map((period) => period.id)).toEqual(['quarter']);
});
it('ignores future-dated fallback note periods for annual income selection', () => {
const snapshot = createSnapshot({
filingId: 12,
filingType: '10-K',
filingDate: '2025-11-05',
statement: 'income',
periods: [
{ id: 'annual', periodStart: '2024-09-30', periodEnd: '2025-09-28', periodLabel: '2024-09-30 to 2025-09-28' },
{ id: 'future-note', periodStart: '2026-09-28', periodEnd: '2027-09-26', periodLabel: '2026-09-28 to 2027-09-26' }
],
rows: [
createRow({
localName: 'Revenues',
label: 'Revenues',
values: { annual: 44_284_000_000 }
}),
createRow({
localName: 'CostOfSales',
label: 'Cost of Sales',
values: { annual: 19_738_000_000 },
order: 2
}),
createRow({
localName: 'EffectiveIncomeTaxRateContinuingOperations',
label: 'Effective Income Tax Rate Continuing Operations',
roleUri: null,
order: Number.MAX_SAFE_INTEGER,
values: { 'future-note': 0.16 },
unit: 'pure'
})
]
});
const selection = __financialTaxonomyInternals.selectPrimaryPeriodsByCadence([snapshot], 'income', 'annual');
expect(selection.periods).toHaveLength(1);
expect(selection.periods[0]?.id).toBe('annual');
});
it('prefers broader presented-row coverage over sparser later annual periods', () => {
const snapshot = createSnapshot({
filingId: 13,
filingType: '10-K',
filingDate: '2025-07-30',
statement: 'income',
periods: [
{ id: 'primary', periodStart: '2024-07-01', periodEnd: '2025-06-30', periodLabel: '2024-07-01 to 2025-06-30' },
{ id: 'sparse-later', periodStart: '2024-07-16', periodEnd: '2025-07-15', periodLabel: '2024-07-16 to 2025-07-15' }
],
rows: [
createRow({
localName: 'Revenues',
label: 'Revenues',
values: { primary: 245_122_000_000, 'sparse-later': 246_000_000_000 }
}),
createRow({
localName: 'OperatingIncomeLoss',
label: 'Operating Income',
values: { primary: 109_433_000_000 },
order: 2
}),
createRow({
localName: 'NetIncomeLoss',
label: 'Net Income',
values: { primary: 88_136_000_000 },
order: 3
})
]
});
const selection = __financialTaxonomyInternals.selectPrimaryPeriodsByCadence([snapshot], 'income', 'annual');
expect(selection.periods).toHaveLength(1);
expect(selection.periods[0]?.id).toBe('primary');
});
it('falls back to plausible non-presented periods when no presented rows exist', () => {
const snapshot = createSnapshot({
filingId: 14,
filingType: '10-K',
filingDate: '2025-11-05',
statement: 'income',
periods: [
{ id: 'annual', periodStart: '2024-09-30', periodEnd: '2025-09-28', periodLabel: '2024-09-30 to 2025-09-28' },
{ id: 'future-note', periodStart: '2026-09-28', periodEnd: '2027-09-26', periodLabel: '2026-09-28 to 2027-09-26' }
],
rows: [
createRow({
localName: 'Revenues',
label: 'Revenues',
roleUri: null,
order: Number.MAX_SAFE_INTEGER,
values: { annual: 44_284_000_000 }
}),
createRow({
localName: 'EffectiveIncomeTaxRateContinuingOperations',
label: 'Effective Income Tax Rate Continuing Operations',
roleUri: null,
order: Number.MAX_SAFE_INTEGER,
values: { 'future-note': 0.16 },
unit: 'pure'
})
]
});
const selection = __financialTaxonomyInternals.selectPrimaryPeriodsByCadence([snapshot], 'income', 'annual');
expect(selection.periods).toHaveLength(1);
expect(selection.periods[0]?.id).toBe('annual');
});
it('maps overlapping GAAP aliases into one standardized COGS row while preserving faithful rows', () => {
const period2024 = createPeriod({
id: '2024-q4',
filingId: 30,
filingDate: '2025-01-29',
periodEnd: '2024-12-31'
});
const period2025 = createPeriod({
id: '2025-q4',
filingId: 31,
filingDate: '2026-01-28',
periodEnd: '2025-12-31'
});
const faithfulRows = __financialTaxonomyInternals.buildRows([
createSnapshot({
filingId: 30,
filingType: '10-Q',
filingDate: '2025-01-29',
statement: 'income',
periods: [{
id: '2024-q4',
periodStart: '2024-10-01',
periodEnd: '2024-12-31',
periodLabel: '2024-10-01 to 2024-12-31'
}],
rows: [
createRow({
localName: 'CostOfRevenue',
label: 'Cost of Revenue',
values: { '2024-q4': 45_000 },
sourceFactIds: [101]
})
]
}),
createSnapshot({
filingId: 31,
filingType: '10-Q',
filingDate: '2026-01-28',
statement: 'income',
periods: [{
id: '2025-q4',
periodStart: '2025-10-01',
periodEnd: '2025-12-31',
periodLabel: '2025-10-01 to 2025-12-31'
}],
rows: [
createRow({
localName: 'CostOfGoodsSold',
label: 'Cost of Goods Sold',
values: { '2025-q4': 48_000 },
sourceFactIds: [202]
})
]
})
], 'income', new Set(['2024-q4', '2025-q4']));
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows(
{
rows: faithfulRows,
statement: 'income',
periods: [period2024, period2025],
facts: []
}
);
expect(faithfulRows).toHaveLength(2);
const cogs = standardizedRows.find((row) => row.key === 'cost_of_revenue');
expect(cogs).toBeDefined();
expect(cogs?.values['2024-q4']).toBe(45_000);
expect(cogs?.values['2025-q4']).toBe(48_000);
expect(cogs?.sourceConcepts).toEqual([
'us-gaap:CostOfGoodsSold',
'us-gaap:CostOfRevenue'
]);
expect(cogs?.sourceRowKeys).toHaveLength(2);
});
it('aggregates standardized dimension drill-down across mapped source concepts', () => {
const period2024 = createPeriod({
id: '2024-q4',
filingId: 40,
filingDate: '2025-01-29',
periodEnd: '2024-12-31'
});
const period2025 = createPeriod({
id: '2025-q4',
filingId: 41,
filingDate: '2026-01-28',
periodEnd: '2025-12-31'
});
const faithfulRows = [
createRow({
localName: 'CostOfRevenue',
label: 'Cost of Revenue',
values: { '2024-q4': 45_000 }
}),
createRow({
localName: 'CostOfGoodsSold',
label: 'Cost of Goods Sold',
values: { '2025-q4': 48_000 }
})
];
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows(
{
rows: faithfulRows,
statement: 'income',
periods: [period2024, period2025],
facts: []
}
);
const breakdown = __financialTaxonomyInternals.buildDimensionBreakdown([
createDimensionFact({
filingId: 40,
filingDate: '2025-01-29',
conceptKey: faithfulRows[0].key,
qname: faithfulRows[0].qname,
localName: faithfulRows[0].localName,
periodEnd: '2024-12-31',
value: 20_000,
member: 'msft:ProductivityMember'
}),
createDimensionFact({
filingId: 41,
filingDate: '2026-01-28',
conceptKey: faithfulRows[1].key,
qname: faithfulRows[1].qname,
localName: faithfulRows[1].localName,
periodEnd: '2025-12-31',
value: 28_000,
member: 'msft:IntelligentCloudMember'
})
], [period2024, period2025], faithfulRows, standardizedRows);
const cogs = breakdown?.['cost_of_revenue'] ?? [];
expect(cogs).toHaveLength(2);
expect(cogs.map((row) => row.sourceLabel)).toEqual([
'Cost of Revenue',
'Cost of Goods Sold'
]);
});
it('prefers exact Microsoft income aliases over pro forma and reconciliation rows', () => {
const period = createPeriod({
id: '2024-fy',
filingId: 80,
filingDate: '2024-07-30',
periodStart: '2023-07-01',
periodEnd: '2024-06-30',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'income',
periods: [period],
facts: [],
rows: [
createRow({
localName: 'BusinessAcquisitionsProFormaRevenue',
label: 'Business Acquisitions Pro Forma Revenue',
values: { '2024-fy': 247_442_000_000 }
}),
createRow({
localName: 'RevenueFromContractWithCustomerExcludingAssessedTax',
label: 'Revenue From Contract With Customer Excluding Assessed Tax',
values: { '2024-fy': 245_122_000_000 }
}),
createRow({
localName: 'NonoperatingIncomeExpense',
label: 'Nonoperating Income Expense',
values: { '2024-fy': -1_646_000_000 }
}),
createRow({
localName: 'SellingAndMarketingExpense',
label: 'Selling And Marketing Expense',
values: { '2024-fy': 24_456_000_000 }
}),
createRow({
localName: 'GeneralAndAdministrativeExpense',
label: 'General And Administrative Expense',
values: { '2024-fy': 7_609_000_000 }
}),
createRow({
localName: 'OperatingIncomeLoss',
label: 'Operating Income Loss',
values: { '2024-fy': 109_433_000_000 }
}),
createRow({
localName: 'BusinessAcquisitionsProFormaNetIncomeLoss',
label: 'Business Acquisitions Pro Forma Net Income Loss',
values: { '2024-fy': 88_308_000_000 },
hasDimensions: true
}),
createRow({
localName: 'NetIncomeLoss',
label: 'Net Income Loss',
values: { '2024-fy': 88_136_000_000 }
}),
createRow({
localName: 'CurrentIncomeTaxExpenseBenefit',
label: 'Current Income Tax Expense Benefit',
values: { '2024-fy': 24_389_000_000 }
}),
createRow({
localName: 'IncomeTaxExpenseBenefit',
label: 'Income Tax Expense Benefit',
values: { '2024-fy': 19_651_000_000 }
}),
createRow({
localName: 'IncomeLossFromContinuingOperationsBeforeIncomeTaxesExtraordinaryItemsNoncontrollingInterest',
label: 'Income Loss From Continuing Operations Before Income Taxes Extraordinary Items Noncontrolling Interest',
values: { '2024-fy': 107_787_000_000 }
}),
createRow({
localName: 'EffectiveIncomeTaxRateReconciliationInterestIncomeExpense',
label: 'Effective Income Tax Rate Reconciliation Interest Income Expense',
values: { '2024-fy': 0.011 },
unit: 'pure'
}),
createRow({
localName: 'InvestmentIncomeNet',
label: 'Investment Income Net',
values: { '2024-fy': 3_157_000_000 }
}),
createRow({
localName: 'CostOfGoodsAndServicesSold',
label: 'Cost Of Goods And Services Sold',
values: { '2024-fy': 74_114_000_000 }
})
]
});
const revenue = findRow(standardizedRows, 'revenue');
expect(revenue.values['2024-fy']).toBe(245_122_000_000);
expect(revenue.resolvedSourceRowKeys['2024-fy']).toContain('RevenueFromContractWithCustomerExcludingAssessedTax');
const operatingIncome = findRow(standardizedRows, 'operating_income');
expect(operatingIncome.values['2024-fy']).toBe(109_433_000_000);
expect(operatingIncome.resolvedSourceRowKeys['2024-fy']).toContain('OperatingIncomeLoss');
const sga = findRow(standardizedRows, 'selling_general_and_administrative');
expect(sga.values['2024-fy']).toBe(32_065_000_000);
expect(sga.formulaKey).toBe('selling_general_and_administrative');
const netIncome = findRow(standardizedRows, 'net_income');
expect(netIncome.values['2024-fy']).toBe(88_136_000_000);
expect(netIncome.resolvedSourceRowKeys['2024-fy']).toContain('NetIncomeLoss');
const taxExpense = findRow(standardizedRows, 'income_tax_expense');
expect(taxExpense.values['2024-fy']).toBe(19_651_000_000);
expect(taxExpense.resolvedSourceRowKeys['2024-fy']).toContain('IncomeTaxExpenseBenefit');
const pretaxIncome = findRow(standardizedRows, 'pretax_income');
expect(pretaxIncome.values['2024-fy']).toBe(107_787_000_000);
const interestIncome = findRow(standardizedRows, 'interest_income');
expect(interestIncome.values['2024-fy']).toBe(3_157_000_000);
expect(interestIncome.resolvedSourceRowKeys['2024-fy']).toContain('InvestmentIncomeNet');
const cogs = findRow(standardizedRows, 'cost_of_revenue');
expect(cogs.label).toBe('Cost of Sales');
expect(cogs.values['2024-fy']).toBe(74_114_000_000);
expect(standardizedRows.some((row) => row.key.includes('BusinessAcquisitionsProFormaRevenue'))).toBe(true);
expect(standardizedRows.some((row) => row.key.includes('BusinessAcquisitionsProFormaNetIncomeLoss'))).toBe(true);
});
it('merges detail rows across taxonomy-version concept drift for Microsoft residuals', () => {
const aggregated = __financialTaxonomyInternals.aggregateDetailRows({
statement: 'income',
selectedPeriodIds: new Set(['2024-fy', '2025-fy']),
snapshots: [
{
...createSnapshot({
filingId: 90,
filingType: '10-K',
filingDate: '2024-07-30',
statement: 'income',
periods: [{
id: '2024-fy',
periodStart: '2023-07-01',
periodEnd: '2024-06-30',
periodLabel: 'FY24'
}]
}),
detail_rows: {
income: {
unmapped: [
{
key: 'http://fasb.org/us-gaap/2024#AdvertisingExpense',
parentSurfaceKey: 'unmapped',
label: 'Advertising Expense',
conceptKey: 'http://fasb.org/us-gaap/2024#AdvertisingExpense',
qname: 'us-gaap:AdvertisingExpense',
namespaceUri: 'http://fasb.org/us-gaap/2024',
localName: 'AdvertisingExpense',
unit: 'iso4217:USD',
values: { '2024-fy': 1_500_000_000 },
sourceFactIds: [101],
isExtension: false,
dimensionsSummary: [],
residualFlag: true
},
{
key: 'https://xbrl.microsoft.com/2024#BusinessAcquisitionsProFormaRevenue',
parentSurfaceKey: 'unmapped',
label: 'Business Acquisitions Pro Forma Revenue',
conceptKey: 'https://xbrl.microsoft.com/2024#BusinessAcquisitionsProFormaRevenue',
qname: 'msft:BusinessAcquisitionsProFormaRevenue',
namespaceUri: 'https://xbrl.microsoft.com/2024',
localName: 'BusinessAcquisitionsProFormaRevenue',
unit: 'iso4217:USD',
values: { '2024-fy': 247_442_000_000 },
sourceFactIds: [102],
isExtension: true,
dimensionsSummary: [],
residualFlag: true
}
]
},
balance: {},
cash_flow: {},
equity: {},
comprehensive_income: {}
}
} satisfies FilingTaxonomySnapshotRecord,
{
...createSnapshot({
filingId: 91,
filingType: '10-K',
filingDate: '2025-07-30',
statement: 'income',
periods: [{
id: '2025-fy',
periodStart: '2024-07-01',
periodEnd: '2025-06-30',
periodLabel: 'FY25'
}]
}),
detail_rows: {
income: {
unmapped: [
{
key: 'http://fasb.org/us-gaap/2025#AdvertisingExpense',
parentSurfaceKey: 'unmapped',
label: 'Advertising Expense',
conceptKey: 'http://fasb.org/us-gaap/2025#AdvertisingExpense',
qname: 'us-gaap:AdvertisingExpense',
namespaceUri: 'http://fasb.org/us-gaap/2025',
localName: 'AdvertisingExpense',
unit: 'iso4217:USD',
values: { '2025-fy': 1_700_000_000 },
sourceFactIds: [201],
isExtension: false,
dimensionsSummary: [],
residualFlag: true
},
{
key: 'https://xbrl.microsoft.com/2025#BusinessAcquisitionsProFormaRevenue',
parentSurfaceKey: 'unmapped',
label: 'Business Acquisitions Pro Forma Revenue',
conceptKey: 'https://xbrl.microsoft.com/2025#BusinessAcquisitionsProFormaRevenue',
qname: 'msft:BusinessAcquisitionsProFormaRevenue',
namespaceUri: 'https://xbrl.microsoft.com/2025',
localName: 'BusinessAcquisitionsProFormaRevenue',
unit: 'iso4217:USD',
values: { '2025-fy': 219_790_000_000 },
sourceFactIds: [202],
isExtension: true,
dimensionsSummary: [],
residualFlag: true
}
]
},
balance: {},
cash_flow: {},
equity: {},
comprehensive_income: {}
}
} satisfies FilingTaxonomySnapshotRecord
]
});
const unmapped = aggregated.unmapped ?? [];
expect(unmapped).toHaveLength(2);
const advertising = unmapped.find((row) => row.label === 'Advertising Expense');
expect(advertising?.values).toEqual({
'2024-fy': 1_500_000_000,
'2025-fy': 1_700_000_000
});
const proFormaRevenue = unmapped.find((row) => row.label === 'Business Acquisitions Pro Forma Revenue');
expect(proFormaRevenue?.values).toEqual({
'2024-fy': 247_442_000_000,
'2025-fy': 219_790_000_000
});
});
it('resolves CASY-style income gaps with ordered fallbacks and tighter interest income exclusions', () => {
const period = createPeriod({
id: '2025-fy',
filingId: 81,
filingDate: '2025-06-23',
periodStart: '2024-05-01',
periodEnd: '2025-04-30',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'income',
periods: [period],
facts: [],
rows: [
createRow({
localName: 'Revenues',
label: 'Revenues',
values: { '2025-fy': 15_940_899_000 }
}),
createRow({
localName: 'CostOfGoodsAndServiceExcludingDepreciationDepletionAndAmortization',
label: 'Cost Of Goods And Service Excluding Depreciation Depletion And Amortization',
values: { '2025-fy': 12_188_496_000 }
}),
createRow({
localName: 'OperatingExpenses',
label: 'Operating Expenses',
values: { '2025-fy': 2_552_356_000 }
}),
createRow({
localName: 'CostOfGoodsAndServicesSoldDepreciationAndAmortization',
label: 'Cost Of Goods And Services Sold Depreciation And Amortization',
values: { '2025-fy': 403_647_000 }
}),
createRow({
localName: 'NetIncomeLoss',
label: 'Net Income Loss',
values: { '2025-fy': 546_520_000 }
}),
createRow({
localName: 'IncomeTaxExpenseBenefit',
label: 'Income Tax Expense Benefit',
values: { '2025-fy': 165_929_000 }
}),
createRow({
localName: 'InterestExpense',
label: 'Interest Expense',
values: { '2025-fy': 83_951_000 }
}),
createRow({
localName: 'InterestIncomeExpenseNet',
label: 'Interest Income Expense Net',
values: { '2025-fy': 13_102_000 }
}),
createRow({
localName: 'EffectiveIncomeTaxRateContinuingOperations',
label: 'Effective Income Tax Rate Continuing Operations',
values: { '2025-fy': 0.233 },
unit: 'pure'
})
]
});
expect(findRow(standardizedRows, 'cost_of_revenue').values['2025-fy']).toBe(12_188_496_000);
expect(findRow(standardizedRows, 'gross_profit').values['2025-fy']).toBe(3_752_403_000);
expect(findRow(standardizedRows, 'selling_general_and_administrative').values['2025-fy']).toBe(2_552_356_000);
expect(findRow(standardizedRows, 'pretax_income').values['2025-fy']).toBe(712_449_000);
expect(findRow(standardizedRows, 'operating_income').values['2025-fy']).toBe(796_400_000);
expect(findRow(standardizedRows, 'depreciation_and_amortization').values['2025-fy']).toBe(403_647_000);
expect(findRow(standardizedRows, 'depreciation_and_amortization_expenses').values['2025-fy']).toBe(403_647_000);
expect(findRow(standardizedRows, 'ebitda').values['2025-fy']).toBe(1_200_047_000);
expect(findRow(standardizedRows, 'effective_tax_rate').values['2025-fy']).toBe(0.233);
expect(standardizedRows.some((row) => row.key === 'interest_income')).toBe(false);
});
it('keeps EBITDA formula-only instead of mapping it directly from operating income', () => {
const period = createPeriod({
id: '2024-fy',
filingId: 90,
filingDate: '2024-07-30',
periodStart: '2023-07-01',
periodEnd: '2024-06-30',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'income',
periods: [period],
facts: [],
rows: [
createRow({
localName: 'OperatingIncomeLoss',
label: 'Operating Income Loss',
values: { '2024-fy': 109_433_000_000 }
}),
createRow({
localName: 'DepreciationDepletionAndAmortization',
label: 'Depreciation Depletion And Amortization',
values: { '2024-fy': 22_287_000_000 }
})
]
});
const ebitda = findRow(standardizedRows, 'ebitda');
expect(ebitda.values['2024-fy']).toBe(131_720_000_000);
expect(ebitda.formulaKey).toBe('ebitda');
expect(ebitda.resolvedSourceRowKeys['2024-fy']).toBeNull();
expect(ebitda.sourceRowKeys).toHaveLength(0);
});
it('uses balance template ordering and sections, with equity falling back to assets minus liabilities', () => {
const period = createPeriod({
id: '2025-balance',
filingId: 95,
filingDate: '2025-07-30',
periodEnd: '2025-06-30',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'balance',
periods: [period],
facts: [],
rows: [
createRow({
statement: 'balance',
localName: 'Assets',
label: 'Assets',
values: { '2025-balance': 619_003_000_000 }
}),
createRow({
statement: 'balance',
localName: 'Liabilities',
label: 'Liabilities',
values: { '2025-balance': 275_524_000_000 }
}),
createRow({
statement: 'balance',
localName: 'AssetsCurrent',
label: 'Assets Current',
values: { '2025-balance': 191_131_000_000 }
})
]
});
const currentAssets = findRow(standardizedRows, 'current_assets');
const totalAssets = findRow(standardizedRows, 'total_assets');
const totalLiabilities = findRow(standardizedRows, 'total_liabilities');
const totalEquity = findRow(standardizedRows, 'total_equity');
expect(currentAssets.category).toBe('assets');
expect(totalLiabilities.category).toBe('liabilities');
expect(totalEquity.category).toBe('equity');
expect(totalEquity.values['2025-balance']).toBe(343_479_000_000);
expect(totalEquity.formulaKey).toBe('total_equity');
expect(currentAssets.order).toBeLessThan(totalAssets.order);
expect(totalAssets.order).toBeLessThan(totalLiabilities.order);
expect(totalLiabilities.order).toBeLessThan(totalEquity.order);
});
it('maps cash flow capex and computes free cash flow from the template formula', () => {
const period = createPeriod({
id: '2024-cf',
filingId: 100,
filingDate: '2024-07-30',
periodStart: '2023-07-01',
periodEnd: '2024-06-30',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'cash_flow',
periods: [period],
facts: [],
rows: [
createRow({
statement: 'cash_flow',
localName: 'NetCashProvidedByUsedInOperatingActivities',
label: 'Net Cash Provided By Used In Operating Activities',
values: { '2024-cf': 118_548_000_000 }
}),
createRow({
statement: 'cash_flow',
localName: 'PaymentsToAcquirePropertyPlantAndEquipment',
label: 'Payments To Acquire Property Plant And Equipment',
values: { '2024-cf': 46_937_000_000 }
})
]
});
const capex = findRow(standardizedRows, 'capital_expenditures');
expect(capex.values['2024-cf']).toBe(-46_937_000_000);
const freeCashFlow = findRow(standardizedRows, 'free_cash_flow');
expect(freeCashFlow.values['2024-cf']).toBe(71_611_000_000);
expect(freeCashFlow.formulaKey).toBe('free_cash_flow');
});
it('prefers dimensionless facts over dimensioned or label-only rows for canonical balance rows', () => {
const period = createPeriod({
id: '2025-balance',
filingId: 110,
filingDate: '2025-02-05',
periodEnd: '2024-12-31',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'balance',
periods: [period],
rows: [
createRow({
statement: 'balance',
localName: 'Assets',
label: 'Assets',
values: { '2025-balance': 8_700_000_000 },
hasDimensions: true
}),
createRow({
statement: 'balance',
localName: 'IntangibleAssetsGrossExcludingGoodwill',
label: 'Intangible Assets Gross Excluding Goodwill',
values: { '2025-balance': 2_793_000_000 }
})
],
facts: [
createFact({
filingId: 110,
filingDate: '2025-02-05',
statement: 'balance',
localName: 'Assets',
periodEnd: '2024-12-31',
periodInstant: '2024-12-31',
value: 450_256_000_000
}),
createFact({
id: 111,
filingId: 110,
filingDate: '2025-02-05',
statement: 'balance',
localName: 'Goodwill',
periodEnd: '2024-12-31',
periodInstant: '2024-12-31',
value: 31_885_000_000
})
]
});
const totalAssets = findRow(standardizedRows, 'total_assets');
expect(totalAssets.values['2025-balance']).toBe(450_256_000_000);
expect(totalAssets.resolvedSourceRowKeys['2025-balance']).toContain('Assets');
expect(standardizedRows.some((row) => row.key === 'other:http://fasb.org/us-gaap/2024#Assets')).toBe(false);
const goodwill = findRow(standardizedRows, 'goodwill');
expect(goodwill.values['2025-balance']).toBe(31_885_000_000);
expect(goodwill.resolvedSourceRowKeys['2025-balance']).toContain('Goodwill');
});
it('uses alias priority for Apple-style long-term investments and unearned revenue rows', () => {
const period = createPeriod({
id: '2025-balance',
filingId: 120,
filingDate: '2025-10-31',
periodEnd: '2025-09-27',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'balance',
periods: [period],
rows: [
createRow({
statement: 'balance',
localName: 'AvailableForSaleSecuritiesDebtSecurities',
label: 'Available For Sale Securities Debt Securities',
values: { '2025-balance': 98_027_000_000 }
}),
createRow({
statement: 'balance',
localName: 'AvailableForSaleSecuritiesDebtMaturitiesSingleMaturityDate',
label: 'Available For Sale Securities Debt Maturities Single Maturity Date',
values: { '2025-balance': 77_723_000_000 }
}),
createRow({
statement: 'balance',
localName: 'ContractWithCustomerLiability',
label: 'Contract With Customer Liability',
values: { '2025-balance': 13_700_000_000 }
}),
createRow({
statement: 'balance',
localName: 'ContractWithCustomerLiabilityCurrent',
label: 'Contract With Customer Liability Current',
values: { '2025-balance': 9_055_000_000 }
})
],
facts: []
});
const longTermInvestments = findRow(standardizedRows, 'long_term_investments');
expect(longTermInvestments.values['2025-balance']).toBe(77_723_000_000);
expect(longTermInvestments.resolvedSourceRowKeys['2025-balance']).toContain('AvailableForSaleSecuritiesDebtMaturitiesSingleMaturityDate');
const unearnedRevenue = findRow(standardizedRows, 'unearned_revenue');
expect(unearnedRevenue.values['2025-balance']).toBe(9_055_000_000);
expect(unearnedRevenue.resolvedSourceRowKeys['2025-balance']).toContain('ContractWithCustomerLiabilityCurrent');
});
it('maps WMS extension aliases and direct effective tax rate values', () => {
const period = createPeriod({
id: '2025-fy',
filingId: 130,
filingDate: '2025-05-15',
periodStart: '2024-04-01',
periodEnd: '2025-03-31',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'income',
periods: [period],
rows: [
createRow({
localName: 'CostOfGoodsAndServicesSold',
label: 'Cost Of Goods And Services Sold',
values: { '2025-fy': 340_800_000 }
}),
createRow({
localName: 'SellingGeneralAndAdministrativeExpenseEmployeeStockOptionPlanSpecialDividendCompensation',
label: 'Selling General And Administrative Expense Employee Stock Option Plan Special Dividend Compensation',
values: { '2025-fy': 0 }
})
],
facts: [
createFact({
filingId: 130,
filingDate: '2025-05-15',
localName: 'CostOfGoodsSoldExcludingEmployeeStockOptionPlanSpecialDividendCompensation',
periodStart: '2024-04-01',
periodEnd: '2025-03-31',
value: 1_810_004_000
}),
createFact({
id: 131,
filingId: 130,
filingDate: '2025-05-15',
localName: 'SellingGeneralAndAdministrativeExpenseExcludingEmployeeStockOptionPlanSpecialDividendCompensation',
periodStart: '2024-04-01',
periodEnd: '2025-03-31',
value: 380_378_000
}),
createFact({
id: 132,
filingId: 130,
filingDate: '2025-05-15',
localName: 'EffectiveIncomeTaxRateContinuingOperations',
periodStart: '2024-04-01',
periodEnd: '2025-03-31',
value: 0.239,
unit: 'pure'
}),
createFact({
id: 133,
filingId: 130,
filingDate: '2025-05-15',
localName: 'InterestIncomeExpenseNonoperatingNet',
periodStart: '2024-04-01',
periodEnd: '2025-03-31',
value: -91_803_000
})
]
});
expect(findRow(standardizedRows, 'cost_of_revenue').values['2025-fy']).toBe(1_810_004_000);
expect(findRow(standardizedRows, 'selling_general_and_administrative').values['2025-fy']).toBe(380_378_000);
expect(findRow(standardizedRows, 'effective_tax_rate').values['2025-fy']).toBe(0.239);
expect(findRow(standardizedRows, 'interest_expense').values['2025-fy']).toBe(91_803_000);
});
it('inverts Fiscal.ai cash flow outflows and working-capital changes', () => {
const period = createPeriod({
id: '2025-cf',
filingId: 140,
filingDate: '2025-05-15',
periodStart: '2024-04-01',
periodEnd: '2025-03-31',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'cash_flow',
periods: [period],
facts: [],
rows: [
createRow({
statement: 'cash_flow',
localName: 'NetCashProvidedByUsedInOperatingActivities',
label: 'Net Cash Provided By Used In Operating Activities',
values: { '2025-cf': 1_000_000_000 }
}),
createRow({
statement: 'cash_flow',
localName: 'PaymentsToAcquirePropertyPlantAndEquipment',
label: 'Payments To Acquire Property Plant And Equipment',
values: { '2025-cf': 250_000_000 }
}),
createRow({
statement: 'cash_flow',
localName: 'IncreaseDecreaseInReceivables',
label: 'Increase Decrease In Receivables',
values: { '2025-cf': -37_487_000 }
}),
createRow({
statement: 'cash_flow',
localName: 'IncreaseDecreaseInInventories',
label: 'Increase Decrease In Inventories',
values: { '2025-cf': 15_749_000 }
}),
createRow({
statement: 'cash_flow',
localName: 'PaymentsForRepurchaseOfCommonStock',
label: 'Payments For Repurchase Of Common Stock',
values: { '2025-cf': 100_000_000 }
}),
createRow({
statement: 'cash_flow',
localName: 'PaymentsOfDividends',
label: 'Payments Of Dividends',
values: { '2025-cf': 40_000_000 }
}),
createRow({
statement: 'cash_flow',
localName: 'OtherInvestingActivitiesNet',
label: 'Other Investing Activities Net',
values: { '2025-cf': 12_000_000 }
})
]
});
expect(findRow(standardizedRows, 'changes_trade_receivables').values['2025-cf']).toBe(37_487_000);
expect(findRow(standardizedRows, 'changes_inventories').values['2025-cf']).toBe(-15_749_000);
expect(findRow(standardizedRows, 'capital_expenditures').values['2025-cf']).toBe(-250_000_000);
expect(findRow(standardizedRows, 'share_repurchases').values['2025-cf']).toBe(-100_000_000);
expect(findRow(standardizedRows, 'dividends_paid').values['2025-cf']).toBe(-40_000_000);
expect(findRow(standardizedRows, 'other_investing_activities').values['2025-cf']).toBe(-12_000_000);
expect(findRow(standardizedRows, 'free_cash_flow').values['2025-cf']).toBe(750_000_000);
});
it('aggregates multiple matching component rows for template rows that require it', () => {
const period = createPeriod({
id: '2025-cf',
filingId: 150,
filingDate: '2025-05-15',
periodStart: '2024-04-01',
periodEnd: '2025-03-31',
filingType: '10-K'
});
const standardizedRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'cash_flow',
periods: [period],
facts: [],
rows: [
createRow({
statement: 'cash_flow',
localName: 'IncreaseDecreaseInOtherOperatingAssets',
label: 'Increase Decrease In Other Operating Assets',
values: { '2025-cf': 25_000_000 }
}),
createRow({
statement: 'cash_flow',
localName: 'IncreaseDecreaseInOtherOperatingLiabilities',
label: 'Increase Decrease In Other Operating Liabilities',
values: { '2025-cf': -40_000_000 }
})
]
});
const otherOperating = findRow(standardizedRows, 'changes_other_operating_activities');
expect(otherOperating.values['2025-cf']).toBe(15_000_000);
expect(otherOperating.resolvedSourceRowKeys['2025-cf']).toBeNull();
expect(otherOperating.sourceRowKeys).toHaveLength(2);
});
it('aggregates CASY balance and cash-flow component rows from dimensionless facts', () => {
const balancePeriod = createPeriod({
id: '2025-balance',
filingId: 151,
filingDate: '2025-06-23',
periodEnd: '2025-04-30',
filingType: '10-K'
});
const cashFlowPeriod = createPeriod({
id: '2025-cf',
filingId: 152,
filingDate: '2025-06-23',
periodStart: '2024-05-01',
periodEnd: '2025-04-30',
filingType: '10-K'
});
const balanceRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'balance',
periods: [balancePeriod],
facts: [],
rows: [
createRow({
statement: 'balance',
localName: 'PropertyPlantAndEquipmentAndFinanceLeaseRightOfUseAssetAfterAccumulatedDepreciationAndAmortization',
label: 'Property Plant And Equipment And Finance Lease Right Of Use Asset After Accumulated Depreciation And Amortization',
values: { '2025-balance': 5_413_244_000 }
}),
createRow({
statement: 'balance',
localName: 'EmployeeRelatedLiabilitiesCurrent',
label: 'Employee Related Liabilities Current',
values: { '2025-balance': 80_633_000 }
}),
createRow({
statement: 'balance',
localName: 'OtherLiabilitiesCurrent',
label: 'Other Liabilities Current',
values: { '2025-balance': 189_870_000 }
}),
createRow({
statement: 'balance',
localName: 'AccruedPropertyTaxes',
qname: 'caseys:AccruedPropertyTaxes',
conceptKey: 'http://www.caseys.com/20250430#AccruedPropertyTaxes',
label: 'Accrued Property Taxes',
values: { '2025-balance': 59_843_000 }
}),
createRow({
statement: 'balance',
localName: 'DeferredIncomeTaxLiabilitiesNet',
label: 'Deferred Income Tax Liabilities Net',
values: { '2025-balance': 646_905_000 }
}),
createRow({
statement: 'balance',
localName: 'OtherLiabilitiesNoncurrent',
label: 'Other Liabilities Noncurrent',
values: { '2025-balance': 69_380_000 }
}),
createRow({
statement: 'balance',
localName: 'LiabilitiesCurrent',
label: 'Liabilities Current',
values: { '2025-balance': 1_101_693_000 }
}),
createRow({
statement: 'balance',
localName: 'OperatingLeaseLiability',
label: 'Operating Lease Liability',
values: { '2025-balance': 449_354_000 }
}),
createRow({
statement: 'balance',
localName: 'FinanceLeaseLiability',
label: 'Finance Lease Liability',
values: { '2025-balance': 108_920_000 }
})
]
});
expect(findRow(balanceRows, 'property_plant_equipment').values['2025-balance']).toBe(5_413_244_000);
expect(findRow(balanceRows, 'accrued_liabilities').values['2025-balance']).toBe(330_346_000);
expect(findRow(balanceRows, 'other_long_term_liabilities').values['2025-balance']).toBe(69_380_000);
expect(findRow(balanceRows, 'total_current_liabilities').values['2025-balance']).toBe(1_101_693_000);
expect(findRow(balanceRows, 'leases').values['2025-balance']).toBe(558_274_000);
const cashFlowRows = __financialTaxonomyInternals.buildStandardizedRows({
statement: 'cash_flow',
periods: [cashFlowPeriod],
facts: [
createFact({
id: 2001,
filingId: 152,
filingDate: '2025-06-23',
statement: 'income',
localName: 'IncreaseDecreaseInDeferredIncomeTaxes',
periodStart: '2024-05-01',
periodEnd: '2025-04-30',
value: -59_958_000
}),
createFact({
id: 2002,
filingId: 152,
filingDate: '2025-06-23',
statement: 'cash_flow',
localName: 'OtherNoncashIncomeExpense',
periodStart: '2024-05-01',
periodEnd: '2025-04-30',
value: 4_054_000
}),
createFact({
id: 2003,
filingId: 152,
filingDate: '2025-06-23',
statement: 'income',
localName: 'IncreaseDecreaseInIncomeTaxes',
periodStart: '2024-05-01',
periodEnd: '2025-04-30',
value: -84_000
}),
createFact({
id: 2004,
filingId: 152,
filingDate: '2025-06-23',
statement: 'income',
localName: 'IncreaseDecreaseInIncomeTaxesReceivable',
periodStart: '2024-05-01',
periodEnd: '2025-04-30',
value: -15_460_000
}),
createFact({
id: 2005,
filingId: 152,
filingDate: '2025-06-23',
statement: 'balance',
localName: 'IncreaseDecreaseInAccruedLiabilities',
periodStart: '2024-05-01',
periodEnd: '2025-04-30',
value: 21_525_000
}),
createFact({
id: 2006,
filingId: 152,
filingDate: '2025-06-23',
statement: 'income',
localName: 'IncreaseDecreaseInPrepaidExpense',
periodStart: '2024-05-01',
periodEnd: '2025-04-30',
value: -3_658_000
}),
createFact({
id: 2007,
filingId: 152,
filingDate: '2025-06-23',
statement: 'cash_flow',
localName: 'ProceedsFromSaleOfPropertyPlantAndEquipment',
periodStart: '2024-05-01',
periodEnd: '2025-04-30',
value: 18_805_000
})
],
rows: []
});
expect(findRow(cashFlowRows, 'changes_income_taxes_payable').values['2025-cf']).toBe(-84_000);
expect(findRow(cashFlowRows, 'changes_accrued_expenses').values['2025-cf']).toBe(21_525_000);
expect(findRow(cashFlowRows, 'other_adjustments').values['2025-cf']).toBe(55_904_000);
expect(findRow(cashFlowRows, 'changes_other_operating_activities').values['2025-cf']).toBe(63_616_000);
expect(findRow(cashFlowRows, 'proceeds_from_sale_of_property_plant_and_equipment').values['2025-cf']).toBe(18_805_000);
});
it('matches local MSFT annual income regression on exact period-end dates', async () => {
const response = await getCompanyFinancialTaxonomy({
ticker: 'MSFT',
surfaceKind: 'income_statement',
cadence: 'annual',
includeDimensions: false,
includeFacts: false,
queuedSync: false,
v3Enabled: true
});
const period2024 = findPeriodId(response.periods, '2024-06-30');
expect(response.periods.map((period) => period.periodEnd)).toEqual([
'2022-06-30',
'2023-06-30',
'2024-06-30',
'2025-06-30'
]);
expect(findStandardizedResponseRow(response, 'revenue').values[period2024]).toBe(245_122_000_000);
expect(findStandardizedResponseRow(response, 'operating_income').values[period2024]).toBe(109_433_000_000);
expect(findStandardizedResponseRow(response, 'net_income').values[period2024]).toBe(88_136_000_000);
expect(findStandardizedResponseRow(response, 'pretax_income').values[period2024]).toBe(107_787_000_000);
expect(findStandardizedResponseRow(response, 'income_tax_expense').values[period2024]).toBe(19_651_000_000);
expect(findStandardizedResponseRow(response, 'effective_tax_rate').values[period2024]).toBe(0.182);
expect(findStandardizedResponseRow(response, 'revenue').templateSection).toBe('statement');
});
it('matches local QCOM annual income regression on exact period-end dates', async () => {
const response = await getCompanyFinancialTaxonomy({
ticker: 'QCOM',
surfaceKind: 'income_statement',
cadence: 'annual',
includeDimensions: false,
includeFacts: false,
queuedSync: false,
v3Enabled: true
});
const period2024 = findPeriodId(response.periods, '2024-09-29');
const period2025 = findPeriodId(response.periods, '2025-09-28');
expect(response.periods.map((period) => period.periodEnd)).toEqual([
'2022-09-25',
'2023-09-24',
'2024-09-29',
'2025-09-28'
]);
expect(response.periods.some((period) => period.periodEnd === '2026-09-28')).toBe(false);
expect(response.periods.some((period) => period.periodEnd === '2027-09-26')).toBe(false);
expect(findStandardizedResponseRow(response, 'revenue').values[period2024]).toBe(38_962_000_000);
expect(findStandardizedResponseRow(response, 'cost_of_revenue').values[period2024]).toBe(17_060_000_000);
expect(findStandardizedResponseRow(response, 'gross_profit').values[period2024]).toBe(21_902_000_000);
expect(findStandardizedResponseRow(response, 'selling_general_and_administrative').values[period2024]).toBe(2_759_000_000);
expect(findStandardizedResponseRow(response, 'research_and_development').values[period2024]).toBe(8_893_000_000);
expect(findStandardizedResponseRow(response, 'pretax_income').values[period2024]).toBe(10_336_000_000);
expect(findStandardizedResponseRow(response, 'ebitda').values[period2024]).toBe(11_777_000_000);
expect(findStandardizedResponseRow(response, 'effective_tax_rate').values[period2024]).toBe(0.02);
expect(findStandardizedResponseRow(response, 'revenue').values[period2025]).toBe(44_284_000_000);
expect(findStandardizedResponseRow(response, 'income_tax_expense').values[period2025]).toBe(7_122_000_000);
expect(findStandardizedResponseRow(response, 'net_income').values[period2025]).toBe(5_541_000_000);
});
it('matches local MSFT annual balance regression on the June 30, 2025 balance sheet', async () => {
const response = await getCompanyFinancialTaxonomy({
ticker: 'MSFT',
surfaceKind: 'balance_sheet',
cadence: 'annual',
includeDimensions: false,
includeFacts: false,
queuedSync: false,
v3Enabled: true
});
const period2025 = findPeriodId(response.periods, '2025-06-30');
expect(findStandardizedResponseRow(response, 'total_assets').values[period2025]).toBe(619_003_000_000);
expect(findStandardizedResponseRow(response, 'total_liabilities').values[period2025]).toBe(275_524_000_000);
expect(findStandardizedResponseRow(response, 'total_equity').values[period2025]).toBe(343_479_000_000);
expect(findStandardizedResponseRow(response, 'total_assets').templateSection).toBe('assets');
expect(findStandardizedResponseRow(response, 'total_liabilities').templateSection).toBe('liabilities');
expect(findStandardizedResponseRow(response, 'total_equity').templateSection).toBe('equity');
});
it('matches local MSFT annual cash flow regression on the June 30, 2025 filing period', async () => {
const response = await getCompanyFinancialTaxonomy({
ticker: 'MSFT',
surfaceKind: 'cash_flow_statement',
cadence: 'annual',
includeDimensions: false,
includeFacts: false,
queuedSync: false,
v3Enabled: true
});
const period2025 = findPeriodId(response.periods, '2025-06-30');
expect(findStandardizedResponseRow(response, 'depreciation_and_amortization').values[period2025]).toBe(34_153_000_000);
expect(findStandardizedResponseRow(response, 'stock_based_compensation').values[period2025]).toBe(11_974_000_000);
expect(findStandardizedResponseRow(response, 'free_cash_flow').values[period2025]).toBe(71_611_000_000);
expect(findStandardizedResponseRow(response, 'operating_cash_flow').templateSection).toBe('operating');
expect(findStandardizedResponseRow(response, 'free_cash_flow').templateSection).toBe('free_cash_flow');
});
it('matches local CASY annual income regression on the April 30, 2025 period', async () => {
const response = await getCompanyFinancialTaxonomy({
ticker: 'CASY',
surfaceKind: 'income_statement',
cadence: 'annual',
includeDimensions: false,
includeFacts: false,
queuedSync: false,
v3Enabled: true
});
const period2025 = findPeriodId(response.periods, '2025-04-30');
expect(findStandardizedResponseRow(response, 'revenue').values[period2025]).toBe(15_940_899_000);
expect(findStandardizedResponseRow(response, 'cost_of_revenue').values[period2025]).toBe(12_188_496_000);
expect(findStandardizedResponseRow(response, 'gross_profit').values[period2025]).toBe(3_752_403_000);
expect(findStandardizedResponseRow(response, 'selling_general_and_administrative').values[period2025]).toBe(2_552_356_000);
expect(findStandardizedResponseRow(response, 'operating_income').values[period2025]).toBe(796_400_000);
expect(findStandardizedResponseRow(response, 'pretax_income').values[period2025]).toBe(712_449_000);
expect(findStandardizedResponseRow(response, 'income_tax_expense').values[period2025]).toBe(165_929_000);
expect(findStandardizedResponseRow(response, 'net_income').values[period2025]).toBe(546_520_000);
expect(findStandardizedResponseRow(response, 'ebitda').values[period2025]).toBe(1_200_047_000);
expect(findStandardizedResponseRow(response, 'effective_tax_rate').values[period2025]).toBe(0.233);
});
it('matches local CASY annual balance and cash-flow regression on the April 30, 2025 period', async () => {
const balance = await getCompanyFinancialTaxonomy({
ticker: 'CASY',
surfaceKind: 'balance_sheet',
cadence: 'annual',
includeDimensions: false,
includeFacts: false,
queuedSync: false,
v3Enabled: true
});
const cash = await getCompanyFinancialTaxonomy({
ticker: 'CASY',
surfaceKind: 'cash_flow_statement',
cadence: 'annual',
includeDimensions: false,
includeFacts: false,
queuedSync: false,
v3Enabled: true
});
const balancePeriod2025 = findPeriodId(balance.periods, '2025-04-30');
const cashPeriod2025 = findPeriodId(cash.periods, '2025-04-30');
expect(findStandardizedResponseRow(balance, 'total_assets').values[balancePeriod2025]).toBe(8_208_118_000);
expect(findStandardizedResponseRow(balance, 'total_liabilities').values[balancePeriod2025]).toBe(4_699_448_000);
expect(findStandardizedResponseRow(balance, 'total_equity').values[balancePeriod2025]).toBe(3_508_670_000);
expect(findStandardizedResponseRow(balance, 'cash_and_equivalents').values[balancePeriod2025]).toBe(326_662_000);
expect(findStandardizedResponseRow(balance, 'accrued_liabilities').values[balancePeriod2025]).toBe(330_731_000);
expect(findStandardizedResponseRow(balance, 'other_long_term_liabilities').values[balancePeriod2025]).toBe(121_485_000);
expect(findStandardizedResponseRow(cash, 'operating_cash_flow').values[cashPeriod2025]).toBe(1_090_854_000);
expect(findStandardizedResponseRow(cash, 'capital_expenditures').values[cashPeriod2025]).toBe(-506_224_000);
expect(findStandardizedResponseRow(cash, 'free_cash_flow').values[cashPeriod2025]).toBe(584_630_000);
expect(findStandardizedResponseRow(cash, 'acquisitions').values[cashPeriod2025]).toBe(-1_239_249_000);
expect(findStandardizedResponseRow(cash, 'long_term_debt_issued').values[cashPeriod2025]).toBe(1_100_000_000);
expect(findStandardizedResponseRow(cash, 'debt_repaid').values[cashPeriod2025]).toBe(-239_492_000);
expect(findStandardizedResponseRow(cash, 'dividends_paid').values[cashPeriod2025]).toBe(-72_309_000);
expect(findStandardizedResponseRow(cash, 'financing_cash_flow').values[cashPeriod2025]).toBe(755_994_000);
expect(findStandardizedResponseRow(cash, 'changes_income_taxes_payable').values[cashPeriod2025]).toBe(-84_000);
expect(findStandardizedResponseRow(cash, 'changes_accrued_expenses').values[cashPeriod2025]).toBe(21_525_000);
expect(findStandardizedResponseRow(cash, 'other_adjustments').values[cashPeriod2025]).toBe(55_904_000);
});
it('merges KPI rows by priority without overwriting higher-priority periods', () => {
const merged = __financialTaxonomyInternals.mergeStructuredKpiRowsByPriority([
[
createKpiRow({
key: 'loan_growth',
values: { p1: 0.12 },
sourceConcepts: ['us-gaap:LoansReceivableNetReportedAmount'],
sourceFactIds: [1]
})
],
[
createKpiRow({
key: 'loan_growth',
values: { p1: 0.11, p2: 0.09 },
sourceConcepts: ['us-gaap:FinancingReceivableRecordedInvestment'],
sourceFactIds: [2]
})
],
[
createKpiRow({
key: 'loan_growth',
values: { p2: 0.08, p3: 0.07 },
provenanceType: 'structured_note',
sourceFactIds: [3]
})
]
]);
expect(merged).toHaveLength(1);
expect(merged[0]?.values).toEqual({ p1: 0.12, p2: 0.09, p3: 0.07 });
expect(merged[0]?.sourceConcepts).toEqual([
'us-gaap:FinancingReceivableRecordedInvestment',
'us-gaap:LoansReceivableNetReportedAmount'
]);
expect(merged[0]?.sourceFactIds).toEqual([1, 2, 3]);
expect(merged[0]?.provenanceType).toBe('taxonomy');
});
it('builds faithful rows when persisted statement rows are missing sourceFactIds', () => {
const malformedSnapshot = {
...createSnapshot({
filingId: 19,
filingType: '10-K',
filingDate: '2026-02-20',
statement: 'income',
periods: [
{ id: '2025-fy', periodStart: '2025-01-01', periodEnd: '2025-12-31', periodLabel: '2025 FY' }
]
}),
statement_rows: {
income: [{
...createRow({
key: 'revenue',
label: 'Revenue',
statement: 'income',
values: { '2025-fy': 123_000_000 }
}),
sourceFactIds: undefined
} as unknown as TaxonomyStatementRow],
balance: [],
cash_flow: [],
equity: [],
comprehensive_income: []
}
} satisfies FilingTaxonomySnapshotRecord;
const rows = __financialTaxonomyInternals.buildRows(
[malformedSnapshot],
'income',
new Set(['2025-fy'])
);
expect(rows).toHaveLength(1);
expect(rows[0]?.key).toBe('revenue');
expect(rows[0]?.sourceFactIds).toEqual([]);
});
it('aggregates persisted surface rows when legacy snapshots are missing source arrays', () => {
const snapshot = {
...createSnapshot({
filingId: 20,
filingType: '10-K',
filingDate: '2026-02-21',
statement: 'income',
periods: [
{ id: '2025-fy', periodStart: '2025-01-01', periodEnd: '2025-12-31', periodLabel: '2025 FY' }
]
}),
surface_rows: {
income: [{
key: 'revenue',
label: 'Revenue',
category: 'revenue',
templateSection: 'statement',
order: 10,
unit: 'currency',
values: { '2025-fy': 123_000_000 },
sourceConcepts: undefined,
sourceRowKeys: undefined,
sourceFactIds: undefined,
formulaKey: null,
hasDimensions: false,
resolvedSourceRowKeys: {},
statement: 'income',
detailCount: 0,
resolutionMethod: 'direct',
confidence: 'high',
warningCodes: []
} as unknown as FilingTaxonomySnapshotRecord['surface_rows']['income'][number]],
balance: [],
cash_flow: [],
equity: [],
comprehensive_income: []
}
} satisfies FilingTaxonomySnapshotRecord;
const rows = __financialTaxonomyInternals.aggregateSurfaceRows({
snapshots: [snapshot],
statement: 'income',
selectedPeriodIds: new Set(['2025-fy'])
});
expect(rows).toHaveLength(1);
expect(rows[0]).toMatchObject({
key: 'revenue',
sourceConcepts: [],
sourceRowKeys: [],
sourceFactIds: []
});
});
it('aggregates persisted detail rows when legacy snapshots are missing dimension arrays', () => {
const snapshot = {
...createSnapshot({
filingId: 21,
filingType: '10-K',
filingDate: '2026-02-22',
statement: 'income',
periods: [
{ id: '2025-fy', periodStart: '2025-01-01', periodEnd: '2025-12-31', periodLabel: '2025 FY' }
]
}),
detail_rows: {
income: {
revenue: [{
key: 'revenue_detail',
parentSurfaceKey: 'revenue',
label: 'Revenue Detail',
conceptKey: 'us-gaap:RevenueDetail',
qname: 'us-gaap:RevenueDetail',
namespaceUri: 'http://fasb.org/us-gaap/2024',
localName: 'RevenueDetail',
unit: 'iso4217:USD',
values: { '2025-fy': 123_000_000 },
sourceFactIds: undefined,
isExtension: false,
dimensionsSummary: undefined,
residualFlag: false
} as unknown as FilingTaxonomySnapshotRecord['detail_rows']['income'][string][number]]
},
balance: {},
cash_flow: {},
equity: {},
comprehensive_income: {}
}
} satisfies FilingTaxonomySnapshotRecord;
const rows = __financialTaxonomyInternals.aggregateDetailRows({
snapshots: [snapshot],
statement: 'income',
selectedPeriodIds: new Set(['2025-fy'])
});
expect(rows.revenue).toHaveLength(1);
expect(rows.revenue?.[0]).toMatchObject({
key: 'revenue_detail',
sourceFactIds: [],
dimensionsSummary: []
});
});
it('builds normalization metadata from snapshot fiscal pack and counts', () => {
const snapshot = {
...createSnapshot({
filingId: 15,
filingType: '10-Q',
filingDate: '2026-01-28',
statement: 'income',
periods: [
{ id: 'quarter', periodStart: '2025-10-01', periodEnd: '2025-12-31', periodLabel: '2025-10-01 to 2025-12-31' }
]
}),
parser_version: '0.1.0',
fiscal_pack: 'bank_lender',
normalization_summary: {
surfaceRowCount: 5,
detailRowCount: 3,
kpiRowCount: 2,
unmappedRowCount: 4,
materialUnmappedRowCount: 1,
warnings: []
}
} satisfies FilingTaxonomySnapshotRecord;
expect(__financialTaxonomyInternals.buildNormalizationMetadata([snapshot])).toEqual({
parserEngine: 'fiscal-xbrl',
regime: 'us-gaap',
fiscalPack: 'bank_lender',
parserVersion: '0.1.0',
surfaceRowCount: 5,
detailRowCount: 3,
kpiRowCount: 2,
unmappedRowCount: 4,
materialUnmappedRowCount: 1,
warnings: []
});
});
it('aggregates normalization counts and warning codes across snapshots while using the latest parser identity', () => {
const olderSnapshot = {
...createSnapshot({
filingId: 17,
filingType: '10-K',
filingDate: '2025-02-13',
statement: 'income',
periods: [
{ id: '2024-fy', periodStart: '2024-01-01', periodEnd: '2024-12-31', periodLabel: '2024 FY' }
]
}),
parser_engine: 'fiscal-xbrl',
parser_version: '0.9.0',
fiscal_pack: 'core',
normalization_summary: {
surfaceRowCount: 4,
detailRowCount: 2,
kpiRowCount: 1,
unmappedRowCount: 3,
materialUnmappedRowCount: 1,
warnings: ['balance_residual_detected', 'income_sparse_mapping']
}
} satisfies FilingTaxonomySnapshotRecord;
const latestSnapshot = {
...createSnapshot({
filingId: 18,
filingType: '10-Q',
filingDate: '2026-02-13',
statement: 'income',
periods: [
{ id: '2025-q4', periodStart: '2025-10-01', periodEnd: '2025-12-31', periodLabel: '2025 Q4' }
]
}),
parser_engine: 'fiscal-xbrl',
parser_version: '1.1.0',
fiscal_pack: 'bank_lender',
normalization_summary: {
surfaceRowCount: 6,
detailRowCount: 5,
kpiRowCount: 4,
unmappedRowCount: 2,
materialUnmappedRowCount: 0,
warnings: ['income_sparse_mapping', 'unmapped_cash_flow_bridge']
}
} satisfies FilingTaxonomySnapshotRecord;
expect(__financialTaxonomyInternals.buildNormalizationMetadata([olderSnapshot, latestSnapshot])).toEqual({
parserEngine: 'fiscal-xbrl',
regime: 'us-gaap',
fiscalPack: 'bank_lender',
parserVersion: '1.1.0',
surfaceRowCount: 10,
detailRowCount: 7,
kpiRowCount: 5,
unmappedRowCount: 5,
materialUnmappedRowCount: 1,
warnings: [
'balance_residual_detected',
'income_sparse_mapping',
'unmapped_cash_flow_bridge'
]
});
});
it('retains pinned income surface rows even when they are intentionally null', () => {
const snapshot = {
...createSnapshot({
filingId: 16,
filingType: '10-K',
filingDate: '2026-02-13',
statement: 'income',
periods: [
{ id: '2025-fy', periodStart: '2025-01-01', periodEnd: '2025-12-31', periodLabel: '2025 FY' }
]
}),
fiscal_pack: 'bank_lender',
surface_rows: {
income: [
{
key: 'revenue',
label: 'Revenue',
category: 'surface',
templateSection: 'surface',
order: 10,
unit: 'currency',
values: { '2025-fy': 100_000_000 },
sourceConcepts: ['us-gaap:TotalNetRevenues'],
sourceRowKeys: ['revenue'],
sourceFactIds: [1],
formulaKey: null,
hasDimensions: false,
resolvedSourceRowKeys: { '2025-fy': 'revenue' },
statement: 'income',
detailCount: 0,
resolutionMethod: 'direct',
confidence: 'high',
warningCodes: []
},
{
key: 'gross_profit',
label: 'Gross Profit',
category: 'surface',
templateSection: 'surface',
order: 20,
unit: 'currency',
values: { '2025-fy': null },
sourceConcepts: [],
sourceRowKeys: [],
sourceFactIds: [],
formulaKey: null,
hasDimensions: false,
resolvedSourceRowKeys: { '2025-fy': null },
statement: 'income',
detailCount: 0,
resolutionMethod: 'not_meaningful',
confidence: 'low',
warningCodes: ['gross_profit_not_meaningful_bank_pack']
},
{
key: 'selling_general_and_administrative',
label: 'SG&A',
category: 'surface',
templateSection: 'surface',
order: 31,
unit: 'currency',
values: { '2025-fy': null },
sourceConcepts: [],
sourceRowKeys: [],
sourceFactIds: [],
formulaKey: null,
hasDimensions: false,
resolvedSourceRowKeys: { '2025-fy': null },
statement: 'income',
detailCount: 0,
resolutionMethod: 'not_meaningful',
confidence: 'low',
warningCodes: ['selling_general_and_administrative_not_meaningful_bank_pack']
}
],
balance: [],
cash_flow: [],
equity: [],
comprehensive_income: []
}
} satisfies FilingTaxonomySnapshotRecord;
const rows = __financialTaxonomyInternals.aggregateSurfaceRows({
snapshots: [snapshot],
statement: 'income',
selectedPeriodIds: new Set(['2025-fy'])
});
const grossProfit = rows.find((row) => row.key === 'gross_profit');
const sga = rows.find((row) => row.key === 'selling_general_and_administrative');
expect(grossProfit).toBeDefined();
expect(grossProfit?.values['2025-fy']).toBeNull();
expect(grossProfit?.resolutionMethod).toBe('not_meaningful');
expect(grossProfit?.warningCodes).toEqual(['gross_profit_not_meaningful_bank_pack']);
expect(sga).toBeDefined();
expect(sga?.values['2025-fy']).toBeNull();
expect(sga?.resolutionMethod).toBe('not_meaningful');
expect(sga?.warningCodes).toEqual(['selling_general_and_administrative_not_meaningful_bank_pack']);
});
});