import { test } from 'node:test'; import assert from 'node:assert/strict'; import { mapToStandardFormat } from '../src/screener/DataMapper.js'; const base = { price: { quoteType: 'EQUITY', regularMarketPrice: 150 }, assetProfile: { sector: 'Technology', industry: 'Software', category: '' }, financialData: { quickRatio: 1.2, debtToEquity: 150, freeCashflow: 5e9, revenueGrowth: 0.15, profitMargins: 0.25, operatingMargins: 0.3, returnOnEquity: 0.2, earningsGrowth: 0.12, operatingCashflow: 8e9, }, defaultKeyStatistics: { pegRatio: null, forwardPE: 28, sharesOutstanding: 1e9, priceToBook: 12 }, summaryDetail: { trailingAnnualDividendYield: 0.005, trailingPE: 30, beta: 1.2, fiftyTwoWeekHigh: 200, fiftyTwoWeekLow: 120, }, }; test('maps EQUITY quote type to STOCK', () => { const result = mapToStandardFormat('AAPL', base); assert.equal(result.type, 'STOCK'); assert.equal(result.ticker, 'AAPL'); }); test('computes PEG from trailingPE / earningsGrowth when Yahoo returns null', () => { const result = mapToStandardFormat('AAPL', base); const expected = +(30 / (0.12 * 100)).toFixed(2); // trailingPE=30, earningsGrowth=12% assert.equal(result.pegRatio, expected); }); test('uses Yahoo pegRatio when available', () => { const summary = { ...base, defaultKeyStatistics: { ...base.defaultKeyStatistics, pegRatio: 1.5 }, }; const result = mapToStandardFormat('AAPL', summary); assert.equal(result.pegRatio, 1.5); }); test('debtToEquity is divided by 100', () => { const result = mapToStandardFormat('AAPL', base); assert.equal(result.debtToEquity, 1.5); // 150 / 100 }); test('maps ETF quoteType to ETF', () => { const etfSummary = { ...base, price: { ...base.price, quoteType: 'ETF' }, assetProfile: { category: 'Large Blend' }, }; const result = mapToStandardFormat('VOO', etfSummary); assert.equal(result.type, 'ETF'); }); test('classifies bond ETF from category keyword', () => { const bondSummary = { ...base, price: { ...base.price, quoteType: 'ETF' }, assetProfile: { category: 'Intermediate-Term Bond' }, }; const result = mapToStandardFormat('BND', bondSummary); assert.equal(result.type, 'BOND'); }); test('FCF yield is computed when data available', () => { const result = mapToStandardFormat('AAPL', base); assert.notEqual(result.fcfYield, null); assert(result.fcfYield > 0); }); test('metrics are null (not 0) when data missing', () => { const sparse = { price: { quoteType: 'EQUITY', regularMarketPrice: 100 }, financialData: {}, defaultKeyStatistics: {}, summaryDetail: {}, assetProfile: {}, }; const result = mapToStandardFormat('X', sparse); assert.equal(result.pegRatio, null); assert.equal(result.quickRatio, null); });