import { test } from 'node:test'; import assert from 'node:assert/strict'; import { CREDIT_RATING_SCALE, ScoringRules } from '../server/config/ScoringConfig'; test('CREDIT_RATING_SCALE covers full spectrum', () => { assert.equal(CREDIT_RATING_SCALE.AAA, 10); assert.equal(CREDIT_RATING_SCALE.BBB, 7); assert.equal(CREDIT_RATING_SCALE.BB, 6); assert.equal(CREDIT_RATING_SCALE.D, 1); }); test('STOCK base gates are fundamental (Graham-style)', () => { const { gates } = ScoringRules.STOCK; assert.equal(gates.maxPERatio, 15); // Graham's actual rule: 15x trailing earnings assert.equal(gates.maxPegGate, 1.0); // Lynch standard: PEG > 1.0 is paying full price assert.equal(gates.minQuickRatio, 0.8); // below 0.8 signals liquidity stress }); test('REIT sector override zeroes out irrelevant weights', () => { const reit = ScoringRules.STOCK.SECTOR_OVERRIDE.REIT!; assert.equal(reit.weights!.margin, 0); assert.equal(reit.weights!.peg, 0); assert.equal(reit.weights!.revenue, 0); assert.equal(reit.weights!.yield, 5); }); test('REIT gates disable P/E and PEG', () => { const reit = ScoringRules.STOCK.SECTOR_OVERRIDE.REIT!; assert.equal(reit.gates!.maxPERatio, 9999); assert.equal(reit.gates!.maxPegGate, 9999); }); test('TECHNOLOGY gates are realistic for mega-cap', () => { const tech = ScoringRules.STOCK.SECTOR_OVERRIDE.TECHNOLOGY!; assert.equal(tech.gates!.maxDebtToEquity, 2.0); assert.equal(tech.gates!.minQuickRatio, 0.8); }); test('BOND requires investment-grade floor (BBB = 7)', () => { assert.equal(ScoringRules.BOND.gates.minCreditRating, 7); });