QueryBlock.utils.test.ts 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { describe, expect, it } from 'vitest'
  2. import { computeYAxisWidth, formatYAxisTick } from './QueryBlock.utils'
  3. describe('formatYAxisTick', () => {
  4. it('returns integers as-is when below 1000', () => {
  5. expect(formatYAxisTick(0)).toBe('0')
  6. expect(formatYAxisTick(1)).toBe('1')
  7. expect(formatYAxisTick(999)).toBe('999')
  8. })
  9. it('abbreviates thousands with K', () => {
  10. expect(formatYAxisTick(1_000)).toBe('1K')
  11. expect(formatYAxisTick(5_000)).toBe('5K')
  12. expect(formatYAxisTick(999_000)).toBe('999K')
  13. })
  14. it('rounds thousands to one decimal place', () => {
  15. expect(formatYAxisTick(1_500)).toBe('1.5K')
  16. expect(formatYAxisTick(55_300)).toBe('55.3K')
  17. expect(formatYAxisTick(1_234)).toBe('1.2K')
  18. })
  19. it('abbreviates millions with M', () => {
  20. expect(formatYAxisTick(1_000_000)).toBe('1M')
  21. expect(formatYAxisTick(2_000_000)).toBe('2M')
  22. })
  23. it('rounds millions to one decimal place', () => {
  24. expect(formatYAxisTick(1_500_000)).toBe('1.5M')
  25. expect(formatYAxisTick(3_208_914)).toBe('3.2M')
  26. })
  27. it('handles values just below the million threshold', () => {
  28. expect(formatYAxisTick(999_900)).toBe('999.9K')
  29. })
  30. it('handles negative values', () => {
  31. expect(formatYAxisTick(-1_000)).toBe('-1K')
  32. expect(formatYAxisTick(-1_500)).toBe('-1.5K')
  33. expect(formatYAxisTick(-1_000_000)).toBe('-1M')
  34. expect(formatYAxisTick(-999)).toBe('-999')
  35. })
  36. it('rounds small decimals to 2 places', () => {
  37. expect(formatYAxisTick(0.456)).toBe('0.46')
  38. expect(formatYAxisTick(0.1)).toBe('0.1')
  39. expect(formatYAxisTick(-0.123)).toBe('-0.12')
  40. })
  41. it('rounds non-integer values between 1 and 1000 to 1 decimal place', () => {
  42. expect(formatYAxisTick(1.25)).toBe('1.3')
  43. expect(formatYAxisTick(99.9)).toBe('99.9')
  44. expect(formatYAxisTick(5.0)).toBe('5')
  45. })
  46. })
  47. describe('computeYAxisWidth', () => {
  48. const row = (v: number) => ({ val: v })
  49. it('returns 52 for log scale regardless of data', () => {
  50. expect(computeYAxisWidth([row(1_000_000)], 'val', { isLogScale: true })).toBe(52)
  51. })
  52. it('returns a fixed width for percentage data', () => {
  53. const width = computeYAxisWidth([row(99)], 'val', { isPercentage: true })
  54. // "100" is the longest tick → (3+1)*8 = 32, floor at 36
  55. expect(width).toBe(36)
  56. })
  57. it('returns minimum 36 for small values', () => {
  58. expect(computeYAxisWidth([row(5)], 'val')).toBe(36)
  59. expect(computeYAxisWidth([], 'val')).toBe(36)
  60. })
  61. it('widens for large values', () => {
  62. // formatYAxisTick(55_300) = "55.3K" (5 chars) → (5+1)*8 = 48
  63. expect(computeYAxisWidth([row(55_300)], 'val')).toBe(48)
  64. })
  65. it('uses absolute magnitude so negative data is handled correctly', () => {
  66. const negWidth = computeYAxisWidth([row(-55_300)], 'val')
  67. const posWidth = computeYAxisWidth([row(55_300)], 'val')
  68. expect(negWidth).toBe(posWidth)
  69. })
  70. it('picks the largest magnitude across all rows', () => {
  71. const data = [row(100), row(5_000), row(200)]
  72. // max is 5000 → "5K" (2 chars) → (2+1)*8 = 24, floor at 36
  73. expect(computeYAxisWidth(data, 'val')).toBe(36)
  74. })
  75. })