95 lines
3.8 KiB
TypeScript
95 lines
3.8 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { scopeContextToTimeframe, describeTimeframe } from '../insightScope.ts';
|
|
|
|
/**
|
|
* Picking a day in the AI Insight day picker means "the cycle so far, up to
|
|
* that day" — day 0 through day N — not that day in isolation. A single row
|
|
* shows no trend and cannot support a cumulative figure such as
|
|
* mortality-to-date, which is what these cards lead with.
|
|
*/
|
|
const ctx = {
|
|
riwayat: [
|
|
{ hari: 0, nilai: 5 },
|
|
{ hari: 1, nilai: 10 },
|
|
{ hari: 5, nilai: 50 },
|
|
{ hari: 12, nilai: 120 },
|
|
{ hari: 30, nilai: 300 },
|
|
],
|
|
// Snapshot list: no time dimension, must survive slicing intact.
|
|
perangkat: [{ nama: 'B1' }, { nama: 'B2' }],
|
|
bobot: 1234,
|
|
};
|
|
|
|
const daysIn = (scoped: typeof ctx) => scoped.riwayat.map((row) => row.hari);
|
|
|
|
describe('scopeContextToTimeframe — jendela kumulatif hari 0..N', () => {
|
|
it('menyertakan seluruh hari sampai hari yang dipilih', () => {
|
|
expect(daysIn(scopeContextToTimeframe(ctx, 'harian', 5))).toEqual([0, 1, 5]);
|
|
expect(daysIn(scopeContextToTimeframe(ctx, 'harian', 12))).toEqual([0, 1, 5, 12]);
|
|
expect(daysIn(scopeContextToTimeframe(ctx, 'harian', 30))).toEqual([0, 1, 5, 12, 30]);
|
|
});
|
|
|
|
it('tidak menyertakan hari setelah hari yang dipilih', () => {
|
|
expect(daysIn(scopeContextToTimeframe(ctx, 'harian', 5))).not.toContain(12);
|
|
expect(daysIn(scopeContextToTimeframe(ctx, 'harian', 5))).not.toContain(30);
|
|
});
|
|
|
|
it('menyertakan hari 0 sebagai awal siklus', () => {
|
|
expect(daysIn(scopeContextToTimeframe(ctx, 'harian', 1))).toEqual([0, 1]);
|
|
});
|
|
|
|
it('hari tanpa data sendiri tetap memuat hari-hari sebelumnya', () => {
|
|
// Hari 7 tidak ada barisnya, tapi jendela 0..7 tetap berisi hari 0, 1, 5.
|
|
expect(daysIn(scopeContextToTimeframe(ctx, 'harian', 7))).toEqual([0, 1, 5]);
|
|
});
|
|
|
|
it('tetap memakai hari terakhir saja bila tidak ada hari yang diminta', () => {
|
|
// Perilaku lama, dipakai saat pengguna belum menyentuh dropdown.
|
|
expect(daysIn(scopeContextToTimeframe(ctx, 'harian'))).toEqual([30]);
|
|
});
|
|
|
|
it('tidak memotong daftar snapshot dan tidak menyentuh skalar', () => {
|
|
const scoped = scopeContextToTimeframe(ctx, 'harian', 5);
|
|
expect(scoped.perangkat).toHaveLength(2);
|
|
expect(scoped.bobot).toBe(1234);
|
|
});
|
|
|
|
it('tidak mengubah perilaku mingguan', () => {
|
|
// Jendela 7 hari tetap dihitung dari hari terakhir, apa pun hari yang dipilih.
|
|
expect(daysIn(scopeContextToTimeframe(ctx, 'mingguan', 5))).toEqual([30]);
|
|
});
|
|
|
|
it('mengenali penamaan field "day" maupun "hari"', () => {
|
|
const inggris = {
|
|
riwayat: [
|
|
{ day: 3, nilai: 1 },
|
|
{ day: 9, nilai: 2 },
|
|
],
|
|
};
|
|
expect(scopeContextToTimeframe(inggris, 'harian', 3).riwayat.map((r) => r.day)).toEqual([3]);
|
|
});
|
|
});
|
|
|
|
describe('describeTimeframe — label periode', () => {
|
|
it('menyatakan rentang kumulatif, bukan satu hari', () => {
|
|
// Menyebut "hari ke-30" saja membuat model melaporkan angka kumulatif
|
|
// 31 hari seolah-olah itu capaian satu hari.
|
|
expect(describeTimeframe('harian', 48, 30)).toContain('hari ke-0 sampai hari ke-30');
|
|
expect(describeTimeframe('harian', 48, 30)).toContain('kumulatif');
|
|
});
|
|
|
|
it('menandai bahwa periode berakhir bukan di hari ini', () => {
|
|
expect(describeTimeframe('harian', 48, 30)).toContain('BUKAN hari ini');
|
|
});
|
|
|
|
it('menandai bahwa periode berakhir di hari ini bila memang begitu', () => {
|
|
expect(describeTimeframe('harian', 30, 30)).toContain('berakhir hari ini');
|
|
expect(describeTimeframe('harian', 30, 30)).not.toContain('BUKAN hari ini');
|
|
});
|
|
|
|
it('mempertahankan perilaku lama saat tidak ada hari dipilih', () => {
|
|
expect(describeTimeframe('harian', 30)).toBe('Hari ini saja (hari ke-30)');
|
|
expect(describeTimeframe('mingguan', 30)).toContain('7 hari terakhir');
|
|
});
|
|
});
|