78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import type { KPI } from '../../types/api.ts';
|
|
import {
|
|
isEndDateInWindow,
|
|
latestValidRatios,
|
|
rankingWindowStart,
|
|
} from '../kandangRanking.ts';
|
|
|
|
function kpi(partial: Partial<KPI>): KPI {
|
|
return {
|
|
id: 1,
|
|
cycle: 1,
|
|
kandang: 1,
|
|
flock_id: 1,
|
|
date: '2026-01-01',
|
|
age: 1,
|
|
mortality: 0,
|
|
mortality_total: 0,
|
|
feed: 0,
|
|
feed_total: 0,
|
|
harvest: 0,
|
|
harvest_total: 0,
|
|
harvest_weight: 0,
|
|
harvest_weight_total: 0,
|
|
chicken_life: 1000,
|
|
chicken_life_percentage: 100,
|
|
iot_weight: 0,
|
|
average_harvest_day: 0,
|
|
average_harvest_weight: 0,
|
|
fcr: 0,
|
|
eef: 0,
|
|
cc: 0,
|
|
cw: 0,
|
|
fs: 0,
|
|
manual: 0,
|
|
created_at: '',
|
|
updated_at: '',
|
|
...partial,
|
|
};
|
|
}
|
|
|
|
describe('kandangRanking helpers', () => {
|
|
it('rankingWindowStart subtracts calendar months', () => {
|
|
expect(rankingWindowStart(3, new Date(2026, 8, 8))).toBe('2026-06-08');
|
|
expect(rankingWindowStart(1, new Date(2026, 0, 31))).toBe('2025-12-31');
|
|
});
|
|
|
|
it('isEndDateInWindow is inclusive on the lower bound', () => {
|
|
expect(isEndDateInWindow('2026-06-08', '2026-06-08')).toBe(true);
|
|
expect(isEndDateInWindow('2026-06-07', '2026-06-08')).toBe(false);
|
|
expect(isEndDateInWindow(null, '2026-06-08')).toBe(false);
|
|
});
|
|
|
|
it('latestValidRatios takes last positive EEF by age, not array order', () => {
|
|
// API-style newest-first ordering
|
|
const rows = [
|
|
kpi({ date: '2026-01-03', age: 3, eef: 310, fcr: 1.25 }),
|
|
kpi({ date: '2026-01-02', age: 2, eef: 0, fcr: 1.3 }),
|
|
kpi({ date: '2026-01-01', age: 1, eef: 200, fcr: 1.4 }),
|
|
];
|
|
expect(latestValidRatios(rows)).toEqual({ eef: 310, fcr: 1.25 });
|
|
});
|
|
|
|
it('latestValidRatios finds FCR and EEF independently from latest days', () => {
|
|
const rows = [
|
|
kpi({ date: '2026-01-03', age: 3, eef: 320, fcr: 0 }),
|
|
kpi({ date: '2026-01-02', age: 2, eef: 0, fcr: 1.22 }),
|
|
kpi({ date: '2026-01-01', age: 1, eef: 100, fcr: 1.5 }),
|
|
];
|
|
expect(latestValidRatios(rows)).toEqual({ eef: 320, fcr: 1.22 });
|
|
});
|
|
|
|
it('latestValidRatios returns null EEF when none valid', () => {
|
|
const rows = [kpi({ age: 2, eef: 0, fcr: 1.2 }), kpi({ age: 1, eef: 0, fcr: 0 })];
|
|
expect(latestValidRatios(rows)).toEqual({ eef: null, fcr: 1.2 });
|
|
});
|
|
});
|