@@ -16,10 +16,12 @@ function makeWeeklyPoint(weekStart: string, value: number): WeeklyDataPoint {
1616describe ( 'applyHampelCorrection' , ( ) => {
1717 it ( 'flags and corrects a spike in the middle of steady data' , ( ) => {
1818 const data : WeeklyDataPoint [ ] = [
19+ makeWeeklyPoint ( '2022-10-24' , 100 ) ,
20+ makeWeeklyPoint ( '2022-10-31' , 100 ) ,
1921 makeWeeklyPoint ( '2022-11-07' , 100 ) ,
2022 makeWeeklyPoint ( '2022-11-14' , 100 ) ,
21- makeWeeklyPoint ( '2022-11-21' , 100 ) ,
22- makeWeeklyPoint ( '2022-11-28' , 1000 ) , // spike
23+ makeWeeklyPoint ( '2022-11-21' , 1000 ) , // spike (index 4)
24+ makeWeeklyPoint ( '2022-11-28' , 100 ) ,
2325 makeWeeklyPoint ( '2022-12-05' , 100 ) ,
2426 makeWeeklyPoint ( '2022-12-12' , 100 ) ,
2527 makeWeeklyPoint ( '2022-12-19' , 100 ) ,
@@ -28,18 +30,20 @@ describe('applyHampelCorrection', () => {
2830 const result = applyHampelCorrection ( data ) as WeeklyDataPoint [ ]
2931
3032 // The spike should be corrected
31- expect ( result [ 3 ] ! . hasAnomaly ) . toBe ( true )
32- expect ( result [ 3 ] ! . value ) . toBe ( 100 ) // replaced with median
33+ expect ( result [ 4 ] ! . hasAnomaly ) . toBe ( true )
34+ expect ( result [ 4 ] ! . value ) . toBe ( 100 ) // replaced with median
3335
3436 // Non-spike points should be unchanged
3537 expect ( result [ 0 ] ! . value ) . toBe ( 100 )
3638 expect ( result [ 0 ] ! . hasAnomaly ) . toBeUndefined ( )
37- expect ( result [ 1 ] ! . value ) . toBe ( 100 )
38- expect ( result [ 6 ] ! . value ) . toBe ( 100 )
39+ expect ( result [ 3 ] ! . value ) . toBe ( 100 )
40+ expect ( result [ 8 ] ! . value ) . toBe ( 100 )
3941 } )
4042
4143 it ( 'does not flag gradual growth as anomalies' , ( ) => {
4244 const data : WeeklyDataPoint [ ] = [
45+ makeWeeklyPoint ( '2022-10-24' , 80 ) ,
46+ makeWeeklyPoint ( '2022-10-31' , 90 ) ,
4347 makeWeeklyPoint ( '2022-11-07' , 100 ) ,
4448 makeWeeklyPoint ( '2022-11-14' , 110 ) ,
4549 makeWeeklyPoint ( '2022-11-21' , 120 ) ,
@@ -70,6 +74,8 @@ describe('applyHampelCorrection', () => {
7074 it ( 'does not flatten a "great start" (sudden real growth at the end)' , ( ) => {
7175 // A package going from zero to real adoption — this is NOT a spike.
7276 const data : WeeklyDataPoint [ ] = [
77+ makeWeeklyPoint ( '2022-10-24' , 0 ) ,
78+ makeWeeklyPoint ( '2022-10-31' , 0 ) ,
7379 makeWeeklyPoint ( '2022-11-07' , 0 ) ,
7480 makeWeeklyPoint ( '2022-11-14' , 0 ) ,
7581 makeWeeklyPoint ( '2022-11-21' , 0 ) ,
@@ -82,41 +88,45 @@ describe('applyHampelCorrection', () => {
8288 const result = applyHampelCorrection ( data ) as WeeklyDataPoint [ ]
8389
8490 // The 20000 should NOT be erased — it's real growth, not an anomaly.
85- expect ( result [ 6 ] ! . value ) . toBe ( 20000 )
86- expect ( result [ 6 ] ! . hasAnomaly ) . toBeUndefined ( )
91+ expect ( result [ 8 ] ! . value ) . toBe ( 20000 )
92+ expect ( result [ 8 ] ! . hasAnomaly ) . toBeUndefined ( )
8793 } )
8894
8995 it ( 'does not flatten low-volume real activity' , ( ) => {
9096 // Sparse package with occasional real downloads
9197 const data : WeeklyDataPoint [ ] = [
98+ makeWeeklyPoint ( '2022-10-24' , 0 ) ,
99+ makeWeeklyPoint ( '2022-10-31' , 0 ) ,
92100 makeWeeklyPoint ( '2022-11-07' , 0 ) ,
93101 makeWeeklyPoint ( '2022-11-14' , 0 ) ,
94- makeWeeklyPoint ( '2022-11-21' , 0 ) ,
95- makeWeeklyPoint ( '2022-11-28' , 1 ) ,
102+ makeWeeklyPoint ( '2022-11-21' , 1 ) ,
96103 makeWeeklyPoint ( '2022-12-05' , 0 ) ,
97104 makeWeeklyPoint ( '2022-12-12' , 0 ) ,
98105 makeWeeklyPoint ( '2022-12-19' , 0 ) ,
106+ makeWeeklyPoint ( '2022-12-26' , 0 ) ,
99107 ]
100108
101109 const result = applyHampelCorrection ( data ) as WeeklyDataPoint [ ]
102110
103111 // A single download is not an anomaly
104- expect ( result [ 3 ] ! . value ) . toBe ( 1 )
105- expect ( result [ 3 ] ! . hasAnomaly ) . toBeUndefined ( )
112+ expect ( result [ 4 ] ! . value ) . toBe ( 1 )
113+ expect ( result [ 4 ] ! . hasAnomaly ) . toBeUndefined ( )
106114 } )
107115
108116 it ( 'does not mutate the original data' , ( ) => {
109117 const data : WeeklyDataPoint [ ] = [
118+ makeWeeklyPoint ( '2022-10-24' , 100 ) ,
119+ makeWeeklyPoint ( '2022-10-31' , 100 ) ,
110120 makeWeeklyPoint ( '2022-11-07' , 100 ) ,
111121 makeWeeklyPoint ( '2022-11-14' , 100 ) ,
112- makeWeeklyPoint ( '2022-11-21' , 100 ) ,
113- makeWeeklyPoint ( '2022-11-28' , 1000 ) ,
122+ makeWeeklyPoint ( '2022-11-21' , 1000 ) ,
123+ makeWeeklyPoint ( '2022-11-28' , 100 ) ,
114124 makeWeeklyPoint ( '2022-12-05' , 100 ) ,
115125 makeWeeklyPoint ( '2022-12-12' , 100 ) ,
116126 makeWeeklyPoint ( '2022-12-19' , 100 ) ,
117127 ]
118128
119129 applyHampelCorrection ( data )
120- expect ( data [ 3 ] ! . value ) . toBe ( 1000 ) // original unchanged
130+ expect ( data [ 4 ] ! . value ) . toBe ( 1000 ) // original unchanged
121131 } )
122132} )
0 commit comments