UNPKG

sec-edgar-toolkit

Version:

Open source toolkit to facilitate working with the SEC EDGAR database

258 lines 10.7 kB
"use strict"; /** * Tests for XBRL functionality */ Object.defineProperty(exports, "__esModule", { value: true }); const xbrl_1 = require("../core/xbrl"); const xbrl_2 = require("../endpoints/xbrl"); const edgar_1 = require("../edgar"); // Mock data const mockXBRLFacts = { facts: { 'us-gaap': { Assets: { units: { USD: [ { val: 365725000000, accn: '0000320193-24-000001', fy: 2023, fp: 'FY', form: '10-K', filed: '2024-01-29', end: '2023-09-30' } ] } }, Revenues: { units: { USD: [ { val: 383285000000, accn: '0000320193-24-000001', fy: 2023, fp: 'FY', form: '10-K', filed: '2024-01-29', start: '2022-10-01', end: '2023-09-30' } ] } }, NetIncomeLoss: { units: { USD: [ { val: 96995000000, accn: '0000320193-24-000001', fy: 2023, fp: 'FY', form: '10-K', filed: '2024-01-29', start: '2022-10-01', end: '2023-09-30' } ] } }, Liabilities: { units: { USD: [ { val: 290437000000, accn: '0000320193-24-000001', fy: 2023, fp: 'FY', form: '10-K', filed: '2024-01-29', end: '2023-09-30' } ] } }, StockholdersEquity: { units: { USD: [ { val: 62146000000, accn: '0000320193-24-000001', fy: 2023, fp: 'FY', form: '10-K', filed: '2024-01-29', end: '2023-09-30' } ] } } } }, entityName: 'Apple Inc.', cik: '0000320193' }; // Mock HTTP client const mockHttpClient = { get: jest.fn().mockResolvedValue(mockXBRLFacts) }; describe('XBRLInstance', () => { let xbrlEndpoints; let xbrlInstance; let mockFiling; beforeEach(() => { xbrlEndpoints = new xbrl_2.XbrlEndpoints(mockHttpClient); mockFiling = { cik: '0000320193', accessionNumber: '0000320193-24-000001', formType: '10-K', filingDate: '2024-01-29', api: { xbrl: xbrlEndpoints } }; xbrlInstance = new xbrl_1.XBRLInstance(mockFiling); }); afterEach(() => { jest.clearAllMocks(); }); describe('getFacts', () => { it('should fetch and cache XBRL facts', async () => { const facts = await xbrlInstance.getFacts(); expect(facts).toEqual(mockXBRLFacts); expect(mockHttpClient.get).toHaveBeenCalledTimes(1); // Second call should use cache const cachedFacts = await xbrlInstance.getFacts(); expect(cachedFacts).toEqual(mockXBRLFacts); expect(mockHttpClient.get).toHaveBeenCalledTimes(1); // Still only called once }); }); describe('getConceptValue', () => { it('should extract concept value', async () => { const assets = await xbrlInstance.getConceptValue('Assets', 'us-gaap', 'USD'); expect(assets).toBe(365725000000); const revenue = await xbrlInstance.getConceptValue('Revenues', 'us-gaap', 'USD'); expect(revenue).toBe(383285000000); }); it('should return null for non-existent concept', async () => { const value = await xbrlInstance.getConceptValue('NonExistentConcept', 'us-gaap', 'USD'); expect(value).toBeNull(); }); it('should handle specific period', async () => { const value = await xbrlInstance.getConceptValue('Assets', 'us-gaap', 'USD', '2023-09-30'); expect(value).toBe(365725000000); const noValue = await xbrlInstance.getConceptValue('Assets', 'us-gaap', 'USD', '2022-09-30'); expect(noValue).toBeNull(); }); }); describe('getFactsByConcept', () => { it('should return all facts for a concept', async () => { const assetFacts = await xbrlInstance.getFactsByConcept('Assets'); expect(assetFacts).toHaveLength(1); expect(assetFacts[0]).toEqual({ concept: 'Assets', taxonomy: 'us-gaap', value: 365725000000, unit: 'USD', period: '2023-09-30', fiscal_year: 2023, fiscal_period: 'FY', start_date: undefined, end_date: '2023-09-30', filed: '2024-01-29', accession_number: '0000320193-24-000001', form: '10-K' }); }); it('should handle taxonomy parameter', async () => { const facts = await xbrlInstance.getFactsByConcept('Assets', 'us-gaap'); expect(facts).toHaveLength(1); const noFacts = await xbrlInstance.getFactsByConcept('Assets', 'ifrs'); expect(noFacts).toHaveLength(0); }); }); describe('getBalanceSheet', () => { it('should extract balance sheet data', async () => { const balanceSheet = await xbrlInstance.getBalanceSheet(); // Check that balance sheet has the expected structure expect(balanceSheet).toHaveProperty('assets'); expect(balanceSheet).toHaveProperty('liabilities'); expect(balanceSheet).toHaveProperty('equity'); // Check specific values if available if (balanceSheet.assets.total_assets) { expect(balanceSheet.assets.total_assets.value).toBe(365725000000); } if (balanceSheet.liabilities.total_liabilities) { expect(balanceSheet.liabilities.total_liabilities.value).toBe(290437000000); } if (balanceSheet.equity.total_equity) { expect(balanceSheet.equity.total_equity.value).toBe(62146000000); } }); }); describe('getIncomeStatement', () => { it('should extract income statement data', async () => { const incomeStatement = await xbrlInstance.getIncomeStatement(); // Check that income statement has the expected structure expect(incomeStatement).toHaveProperty('revenue'); expect(incomeStatement).toHaveProperty('net_income'); // Check specific values if (incomeStatement.revenue && typeof incomeStatement.revenue === 'object') { expect(incomeStatement.revenue.value).toBe(383285000000); } if (incomeStatement.net_income && typeof incomeStatement.net_income === 'object') { expect(incomeStatement.net_income.value).toBe(96995000000); } }); }); describe('getCashFlowStatement', () => { it('should extract cash flow data', async () => { const cashFlow = await xbrlInstance.getCashFlowStatement(); // Check that cash flow statement has the expected structure expect(cashFlow).toHaveProperty('operating_activities'); expect(cashFlow).toHaveProperty('investing_activities'); expect(cashFlow).toHaveProperty('financing_activities'); // The actual structure is arrays of activities expect(Array.isArray(cashFlow.operating_activities)).toBe(true); expect(Array.isArray(cashFlow.investing_activities)).toBe(true); expect(Array.isArray(cashFlow.financing_activities)).toBe(true); }); }); describe('Integration with Filing', () => { it('should work with filing.xbrl() method', async () => { // Client creation test - validates createClient signature (0, edgar_1.createClient)({ userAgent: 'Test/1.0 (test@example.com)' }); // Mock the filing's xbrl method const mockFiling = { cik: '0000320193', accessionNumber: '0000320193-24-000001', xbrl: jest.fn().mockResolvedValue(xbrlInstance) }; const xbrl = await mockFiling.xbrl(); const revenue = await xbrl.getConceptValue('Revenues', 'us-gaap', 'USD'); expect(revenue).toBe(383285000000); }); }); describe('Error handling', () => { it('should handle API errors gracefully', async () => { const errorClient = { get: jest.fn().mockRejectedValue(new Error('API Error')) }; const errorEndpoints = new xbrl_2.XbrlEndpoints(errorClient); const errorFiling = { ...mockFiling, api: { xbrl: errorEndpoints } }; const errorInstance = new xbrl_1.XBRLInstance(errorFiling); await expect(errorInstance.getFacts()).rejects.toThrow('API Error'); }); it('should handle malformed data', async () => { const malformedClient = { get: jest.fn().mockResolvedValue({ invalid: 'data' }) }; const malformedEndpoints = new xbrl_2.XbrlEndpoints(malformedClient); const malformedFiling = { ...mockFiling, api: { xbrl: malformedEndpoints } }; const malformedInstance = new xbrl_1.XBRLInstance(malformedFiling); const value = await malformedInstance.getConceptValue('Assets'); expect(value).toBeNull(); }); }); }); //# sourceMappingURL=xbrl.test.js.map