@@ -324,6 +324,102 @@ def test_degradation_year_on_year_multi():
324324 assert len (calc_info ['YoY_values' ]) > len (calc_info0 ['YoY_values' ])
325325
326326
327+ def test_classical_decomposition_missing_data ():
328+ """Test that classical decomposition raises error for missing data."""
329+ # Create a regular time series with missing values (NaN)
330+ idx = pd .date_range ("2012-01-01" , "2015-01-01" , freq = "D" )
331+ series = pd .Series (1.0 , index = idx )
332+ series .iloc [100 :105 ] = np .nan # introduce missing data
333+
334+ with pytest .raises (ValueError , match = "regular time series" ):
335+ degradation_classical_decomposition (series )
336+
337+
338+ def test_classical_decomposition_irregular_frequency ():
339+ """Test that classical decomposition raises error for irregular frequency."""
340+ # Create an irregular time series by sampling randomly
341+ idx = pd .date_range ("2012-01-01" , "2015-01-01" , freq = "D" )
342+ series = pd .Series (1.0 , index = idx )
343+ series = series .sample (frac = 0.8 , replace = False ).sort_index ()
344+
345+ with pytest .raises (ValueError , match = "regular time series" ):
346+ degradation_classical_decomposition (series )
347+
348+
349+ def test_yoy_circular_block_no_frequency ():
350+ """Test circular_block raises error when frequency cannot be inferred."""
351+ # Create an irregular time series
352+ idx = pd .date_range ("2012-01-01" , "2015-01-01" , freq = "D" )
353+ series = pd .Series (1.0 , index = idx )
354+ series = series .sample (frac = 0.8 , replace = False ).sort_index ()
355+
356+ with pytest .raises (ValueError , match = "fixed frequency" ):
357+ degradation_year_on_year (series , uncertainty_method = "circular_block" )
358+
359+
360+ def test_yoy_circular_block_too_long ():
361+ """Test circular_block raises error when block_length is too long."""
362+ idx = pd .date_range ("2012-01-01" , "2015-01-01" , freq = "D" )
363+ series = pd .Series (1.0 , index = idx )
364+
365+ # block_length must be less than 1/3 of the series length
366+ too_long = len (series ) // 2
367+
368+ with pytest .raises (ValueError , match = "shorter than a third" ):
369+ degradation_year_on_year (
370+ series , uncertainty_method = "circular_block" , block_length = too_long
371+ )
372+
373+
374+ def test_yoy_no_pairs_found ():
375+ """Test year_on_year raises error when no valid pairs can be formed."""
376+ # Create a series that's just over 1 year but with NaN in positions
377+ # that prevent any valid year-over-year pairs
378+ idx = pd .date_range ("2012-01-01" , "2014-06-01" , freq = "D" )
379+ series = pd .Series (1.0 , index = idx )
380+ # Make all values NaN except first few and last few (too far apart for pairs)
381+ series .iloc [10 :- 10 ] = np .nan
382+
383+ with pytest .raises (ValueError , match = "no year-over-year" ):
384+ degradation_year_on_year (series )
385+
386+
387+ def test_mk_test_no_trend ():
388+ """Test Mann-Kendall test with no trend (z == 0 case)."""
389+ from rdtools .degradation import _mk_test
390+
391+ # Constant series should have no trend
392+ x = np .array ([1.0 , 1.0 , 1.0 , 1.0 , 1.0 ])
393+ trend , h , p , z = _mk_test (x )
394+
395+ assert trend == "no trend"
396+ assert z == 0
397+ assert not h
398+
399+
400+ def test_mk_test_with_ties ():
401+ """Test Mann-Kendall test with tied values."""
402+ from rdtools .degradation import _mk_test
403+
404+ # Series with ties (repeated values)
405+ x = np .array ([1 , 2 , 2 , 3 , 3 , 3 , 4 , 5 ])
406+ trend , h , p , z = _mk_test (x )
407+
408+ # Should still detect increasing trend
409+ assert trend == "increasing"
410+
411+
412+ def test_mk_test_decreasing ():
413+ """Test Mann-Kendall test with clear decreasing trend."""
414+ from rdtools .degradation import _mk_test
415+
416+ x = np .array ([10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ])
417+ trend , h , p , z = _mk_test (x )
418+
419+ assert trend == "decreasing"
420+ assert z < 0
421+
422+
327423if __name__ == '__main__' :
328424 # Initialize logger when run as a module:
329425 # python -m tests.degradation_test
0 commit comments