forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1import { describe, expect, it, vi } from 'vitest'
2
3vi.mock('~/utils/npm/api', () => ({
4 fetchNpmDownloadsRange: vi.fn(),
5}))
6
7import {
8 buildDailyEvolutionFromDaily,
9 buildRollingWeeklyEvolutionFromDaily,
10 buildMonthlyEvolutionFromDaily,
11 buildYearlyEvolutionFromDaily,
12 getNpmPackageCreationDate,
13} from '../../../../app/composables/useCharts'
14
15describe('buildDailyEvolutionFromDaily', () => {
16 it('adds timestamps and preserves values', () => {
17 const result = buildDailyEvolutionFromDaily([
18 { day: '2025-03-01', value: 10 },
19 { day: '2025-03-02', value: 20 },
20 ])
21
22 expect(result).toEqual([
23 { day: '2025-03-01', value: 10, timestamp: Date.UTC(2025, 2, 1) },
24 { day: '2025-03-02', value: 20, timestamp: Date.UTC(2025, 2, 2) },
25 ])
26 })
27
28 it('sorts by day', () => {
29 const result = buildDailyEvolutionFromDaily([
30 { day: '2025-03-03', value: 3 },
31 { day: '2025-03-01', value: 1 },
32 { day: '2025-03-02', value: 2 },
33 ])
34
35 expect(result.map(r => r.day)).toEqual(['2025-03-01', '2025-03-02', '2025-03-03'])
36 })
37
38 it('returns empty array for empty input', () => {
39 expect(buildDailyEvolutionFromDaily([])).toEqual([])
40 })
41})
42
43describe('buildRollingWeeklyEvolutionFromDaily', () => {
44 it('groups daily data into rolling 7-day buckets', () => {
45 const daily = Array.from({ length: 14 }, (_, i) => ({
46 day: `2025-03-${String(i + 1).padStart(2, '0')}`,
47 value: 10,
48 }))
49
50 const result = buildRollingWeeklyEvolutionFromDaily(daily, '2025-03-01', '2025-03-14')
51
52 expect(result).toHaveLength(2)
53 expect(result[0]!.value).toBe(70)
54 expect(result[0]!.weekStart).toBe('2025-03-01')
55 expect(result[0]!.weekEnd).toBe('2025-03-07')
56 expect(result[1]!.value).toBe(70)
57 expect(result[1]!.weekStart).toBe('2025-03-08')
58 expect(result[1]!.weekEnd).toBe('2025-03-14')
59 })
60
61 it('clamps last week to range end date', () => {
62 const daily = [
63 { day: '2025-03-01', value: 5 },
64 { day: '2025-03-02', value: 5 },
65 { day: '2025-03-08', value: 10 },
66 ]
67
68 const result = buildRollingWeeklyEvolutionFromDaily(daily, '2025-03-01', '2025-03-09')
69
70 // Last week bucket should be clamped to end date
71 const lastWeek = result[result.length - 1]!
72 expect(lastWeek.weekEnd).toBe('2025-03-09')
73 })
74
75 it('returns empty array for empty input', () => {
76 expect(buildRollingWeeklyEvolutionFromDaily([], '2025-03-01', '2025-03-14')).toEqual([])
77 })
78})
79
80describe('buildMonthlyEvolutionFromDaily', () => {
81 it('aggregates daily data by month', () => {
82 const result = buildMonthlyEvolutionFromDaily([
83 { day: '2025-01-15', value: 10 },
84 { day: '2025-01-20', value: 5 },
85 { day: '2025-02-10', value: 20 },
86 ])
87
88 expect(result).toEqual([
89 { month: '2025-01', value: 15, timestamp: Date.UTC(2025, 0, 1) },
90 { month: '2025-02', value: 20, timestamp: Date.UTC(2025, 1, 1) },
91 ])
92 })
93
94 it('sorts by month', () => {
95 const result = buildMonthlyEvolutionFromDaily([
96 { day: '2025-03-01', value: 1 },
97 { day: '2025-01-01', value: 1 },
98 { day: '2025-02-01', value: 1 },
99 ])
100
101 expect(result.map(r => r.month)).toEqual(['2025-01', '2025-02', '2025-03'])
102 })
103
104 it('returns empty array for empty input', () => {
105 expect(buildMonthlyEvolutionFromDaily([])).toEqual([])
106 })
107})
108
109describe('buildYearlyEvolutionFromDaily', () => {
110 it('aggregates daily data by year', () => {
111 const result = buildYearlyEvolutionFromDaily([
112 { day: '2024-06-15', value: 100 },
113 { day: '2024-12-01', value: 50 },
114 { day: '2025-03-01', value: 200 },
115 ])
116
117 expect(result).toEqual([
118 { year: '2024', value: 150, timestamp: Date.UTC(2024, 0, 1) },
119 { year: '2025', value: 200, timestamp: Date.UTC(2025, 0, 1) },
120 ])
121 })
122
123 it('returns empty array for empty input', () => {
124 expect(buildYearlyEvolutionFromDaily([])).toEqual([])
125 })
126})
127
128describe('getNpmPackageCreationDate', () => {
129 it('returns created date from packument time', () => {
130 const result = getNpmPackageCreationDate({
131 time: {
132 'created': '2020-01-15T10:00:00.000Z',
133 'modified': '2025-01-01T00:00:00.000Z',
134 '1.0.0': '2020-01-15T10:00:00.000Z',
135 },
136 })
137
138 expect(result).toBe('2020-01-15T10:00:00.000Z')
139 })
140
141 it('returns earliest version date when created is missing', () => {
142 const result = getNpmPackageCreationDate({
143 time: {
144 'modified': '2025-01-01T00:00:00.000Z',
145 '1.0.0': '2020-06-01T00:00:00.000Z',
146 '2.0.0': '2021-01-01T00:00:00.000Z',
147 },
148 })
149
150 expect(result).toBe('2020-06-01T00:00:00.000Z')
151 })
152
153 it('returns null when time is missing', () => {
154 expect(getNpmPackageCreationDate({})).toBeNull()
155 })
156})