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'); }); });