Add daily report day picker and cumulative insights for mortality data. Updated AiInsightCard and related components to support daily and weekly reporting, ensuring accurate data representation. Introduced new utility functions for water consumption standards and enhanced context management for insights.
CI / lint-and-test (push) Canceled after 0s
CI / lint-and-test (push) Canceled after 0s
This commit is contained in:
1 parent
172ea3a148
commit
427cac54a1
18 files changed
+1055
-205
No files matched your search
@@ -0,0 +1,81 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
calculateCp707Uniformity,
|
||||
getCp707UniformityStatus,
|
||||
CP707_UNIFORMITY_TARGET,
|
||||
} from '../weightUtils.ts';
|
||||
|
||||
/**
|
||||
* Keseragaman dihitung ulang dari `avg` + `Standard_deviasi` menurut CP 707
|
||||
* (persen ayam dalam ±10% dari rata-rata), bukan diambil dari field
|
||||
* `uniformity` milik API `distribusi_bobot` yang memakai band ±5%.
|
||||
*
|
||||
* Nilai acuan di bawah berasal dari respons API sungguhan dan dicocokkan
|
||||
* dengan perhitungan referensi `math.erf` di Python.
|
||||
*/
|
||||
describe('calculateCp707Uniformity', () => {
|
||||
it.each([
|
||||
// tanggal, avg (g), Standard_deviasi (g), harapan (%)
|
||||
['2026-08-10', 1123.53, 161.3, 51.4],
|
||||
['2026-08-05', 806.79, 26.87, 99.7],
|
||||
['2026-08-04', 667.31, 139.71, 36.7],
|
||||
['2026-06-18', 1324.8, 106.5, 78.6],
|
||||
])('cocok dengan perhitungan referensi untuk %s', (_tanggal, avg, sd, harapan) => {
|
||||
expect(calculateCp707Uniformity(avg, sd)).toBeCloseTo(harapan as number, 0);
|
||||
});
|
||||
|
||||
it('tidak terpengaruh lebar bucket 50 g di awal siklus', () => {
|
||||
// Bobot 75 g: band ±10% hanya 15 g, jauh lebih sempit dari bucket 50 g milik
|
||||
// API. Perhitungan berbasis bucket gagal di sini; berbasis SD tidak.
|
||||
expect(calculateCp707Uniformity(75.4, 3.3)).toBeCloseTo(97.8, 0);
|
||||
});
|
||||
|
||||
it('mengembalikan 100 saat tidak ada variasi bobot', () => {
|
||||
expect(calculateCp707Uniformity(1000, 0)).toBe(100);
|
||||
});
|
||||
|
||||
it('hasilnya selalu berada di rentang 0-100', () => {
|
||||
for (const [avg, sd] of [
|
||||
[1000, 1],
|
||||
[1000, 5000],
|
||||
[50, 0.1],
|
||||
]) {
|
||||
const v = calculateCp707Uniformity(avg, sd);
|
||||
expect(v).not.toBeNull();
|
||||
expect(v as number).toBeGreaterThanOrEqual(0);
|
||||
expect(v as number).toBeLessThanOrEqual(100);
|
||||
}
|
||||
});
|
||||
|
||||
it('mengembalikan null, bukan angka karangan, saat data tidak memadai', () => {
|
||||
expect(calculateCp707Uniformity(null, 10)).toBeNull();
|
||||
expect(calculateCp707Uniformity(1000, null)).toBeNull();
|
||||
expect(calculateCp707Uniformity(undefined, undefined)).toBeNull();
|
||||
expect(calculateCp707Uniformity(0, 10)).toBeNull();
|
||||
expect(calculateCp707Uniformity(-100, 10)).toBeNull();
|
||||
expect(calculateCp707Uniformity(1000, -5)).toBeNull();
|
||||
expect(calculateCp707Uniformity(NaN, 10)).toBeNull();
|
||||
expect(calculateCp707Uniformity(1000, Infinity)).toBeNull();
|
||||
});
|
||||
|
||||
it('naik saat sebaran menyempit', () => {
|
||||
const ketat = calculateCp707Uniformity(1000, 30) as number;
|
||||
const longgar = calculateCp707Uniformity(1000, 150) as number;
|
||||
expect(ketat).toBeGreaterThan(longgar);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCp707UniformityStatus', () => {
|
||||
it('memakai ambang CP 707 (>80%), bukan ambang lama 85/75', () => {
|
||||
expect(getCp707UniformityStatus(CP707_UNIFORMITY_TARGET)).toBe('ok');
|
||||
expect(getCp707UniformityStatus(82)).toBe('ok');
|
||||
// 82 dulu berstatus "warning" dengan ambang lama 85.
|
||||
expect(getCp707UniformityStatus(75)).toBe('warning');
|
||||
expect(getCp707UniformityStatus(70)).toBe('warning');
|
||||
expect(getCp707UniformityStatus(69.9)).toBe('critical');
|
||||
});
|
||||
|
||||
it('memperlakukan data tidak tersedia sebagai critical', () => {
|
||||
expect(getCp707UniformityStatus(null)).toBe('critical');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user