Ctrl K
ComunidadGuías…

tests/chart-breakdown.unit.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import type { NumericSeriesByApp } from '../src/services/usageSeries'
import { describe, expect, it } from 'vitest'
import { limitChartBreakdown, MAX_CHART_BREAKDOWN_SERIES } from '../src/utils/chartBreakdown'

describe('chart breakdown rendering budget', () => {
  it.concurrent('keeps a small active breakdown in its existing order without copying its arrays', () => {
    const source = { 'com.example.first': [1, 2], 'com.example.second': [4, 5] }
    const result = limitChartBreakdown(source)

    expect(result.map(series => series.id)).toEqual(Object.keys(source))
    expect(result[0].data).toBe(source['com.example.first'])
    expect(result[1].data).toBe(source['com.example.second'])
  })

  it.concurrent('does not spend the rendering budget on inactive or missing-only series', () => {
    expect(limitChartBreakdown({
      'com.example.empty': [],
      'com.example.zero': [0, 0],
      'com.example.missing': [undefined, undefined],
      'com.example.active': [undefined, 1],
    })).toEqual([{ id: 'com.example.active', data: [undefined, 1] }])
  })

  it.concurrent('groups the remainder without mutating inputs or fabricating an app identity', () => {
    const source = Object.fromEntries(Array.from({ length: 1000 }, (_, index) => [
      `com.example.app${index}`,
      [index + 1, (index + 1) * 2, undefined],
    ]))
    const snapshot = structuredClone(source)
    const result = limitChartBreakdown(source)

    expect(result).toHaveLength(MAX_CHART_BREAKDOWN_SERIES)
    expect(result[0].id).toBe('com.example.app999')
    expect(result.at(-1)?.id).toBeUndefined()
    expect(result.at(-1)?.data[2]).toBeUndefined()
    expect(source).toEqual(snapshot)
    for (let dayIndex = 0; dayIndex < 2; dayIndex++) {
      const sum = result.reduce((total, series) => total + (series.data[dayIndex] ?? 0), 0)
      expect(sum).toBe(500_500 * (dayIndex + 1))
    }
  })

  it.concurrent('preserves signed totals, differing lengths, and zero days when grouping', () => {
    const source: NumericSeriesByApp = Object.fromEntries(Array.from({ length: 9 }, (_, index) => [
      `com.example.top${index}`,
      [100, 100],
    ]))
    source['com.example.corrections'] = [-5, 5, undefined, 0]
    source['com.example.later'] = [undefined, -1, 2]

    const result = limitChartBreakdown(source)
    expect(result.at(-1)).toEqual({ data: [-5, 4, 2, 0] })
    expect(result.reduce((total, series) => total + (series.data[0] ?? 0), 0)).toBe(895)
  })

  it.concurrent('keeps tied series deterministic at the rendering boundary', () => {
    const source = Object.fromEntries(Array.from({ length: 11 }, (_, index) => [`com.example.app${index}`, [1]]))
    const result = limitChartBreakdown(source)

    expect(result.slice(0, -1).map(series => series.id)).toEqual(Object.keys(source).slice(0, 9))
    expect(result.at(-1)).toEqual({ data: [2] })
  })
})