first commit
This commit is contained in:
commit
b54624be96
226 files changed
+108840
No files matched your search
@@ -0,0 +1,77 @@
|
||||
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 });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user