|
1 | 1 | import unittest |
| 2 | +from unittest.mock import MagicMock, patch |
2 | 3 |
|
3 | | -from tfts.data.get_data import get_air_passengers, get_data, get_sine |
| 4 | +import numpy as np |
| 5 | +import pandas as pd |
| 6 | + |
| 7 | +from tfts.data.get_data import get_air_passengers, get_ar_data, get_data, get_sine, get_stock_data |
4 | 8 |
|
5 | 9 |
|
6 | 10 | class GetDataTest(unittest.TestCase): |
@@ -35,3 +39,166 @@ def test_get_air_passenger_data(self): |
35 | 39 | self.assertEqual(train[1].shape[1:], (predict_sequence_length, 1)) |
36 | 40 | self.assertEqual(valid[0].shape[1:], (train_length, 1)) |
37 | 41 | self.assertEqual(valid[1].shape[1:], (predict_sequence_length, 1)) |
| 42 | + |
| 43 | + def test_get_sine_no_test_split(self): |
| 44 | + """Test get_sine with test_size=0 returns single tuple""" |
| 45 | + train_length = 10 |
| 46 | + predict_sequence_length = 4 |
| 47 | + n_examples = 50 |
| 48 | + x, y = get_sine(train_length, predict_sequence_length, test_size=0, n_examples=n_examples) |
| 49 | + self.assertEqual(x.shape, (n_examples, train_length, 1)) |
| 50 | + self.assertEqual(y.shape, (n_examples, predict_sequence_length, 1)) |
| 51 | + self.assertIsInstance(x, np.ndarray) |
| 52 | + self.assertIsInstance(y, np.ndarray) |
| 53 | + |
| 54 | + def test_get_air_passengers_no_test_split(self): |
| 55 | + """Test get_air_passengers with test_size=0""" |
| 56 | + train_length = 10 |
| 57 | + predict_sequence_length = 4 |
| 58 | + x, y = get_air_passengers(train_length, predict_sequence_length, test_size=0) |
| 59 | + self.assertEqual(x.shape[1:], (train_length, 1)) |
| 60 | + self.assertEqual(y.shape[1:], (predict_sequence_length, 1)) |
| 61 | + |
| 62 | + def test_get_data_invalid_name(self): |
| 63 | + """Test get_data raises ValueError for unsupported dataset""" |
| 64 | + with self.assertRaises(ValueError) as context: |
| 65 | + get_data("invalid_dataset", 10, 4, 0.2) |
| 66 | + self.assertIn("unsupported data", str(context.exception)) |
| 67 | + |
| 68 | + def test_get_data_test_size_validation(self): |
| 69 | + """Test get_data validates test_size parameter""" |
| 70 | + with self.assertRaises(AssertionError): |
| 71 | + get_data("sine", 10, 4, test_size=-0.1) |
| 72 | + |
| 73 | + with self.assertRaises(AssertionError): |
| 74 | + get_data("sine", 10, 4, test_size=1.5) |
| 75 | + |
| 76 | + def test_get_data_airpassengers(self): |
| 77 | + """Test get_data dispatcher for airpassengers dataset""" |
| 78 | + train_length = 12 |
| 79 | + predict_length = 6 |
| 80 | + train, valid = get_data("airpassengers", train_length, predict_length, test_size=0.15) |
| 81 | + self.assertIsNotNone(train) |
| 82 | + self.assertIsNotNone(valid) |
| 83 | + self.assertEqual(len(train), 2) |
| 84 | + self.assertEqual(len(valid), 2) |
| 85 | + |
| 86 | + def test_get_sine_data_values_in_range(self): |
| 87 | + """Test that sine wave values are in expected range""" |
| 88 | + train_length = 20 |
| 89 | + predict_length = 5 |
| 90 | + x, y = get_sine(train_length, predict_length, test_size=0, n_examples=10) |
| 91 | + |
| 92 | + # Sine values should be roughly in [-1, 1] range |
| 93 | + self.assertTrue(np.all(x >= -1.5)) |
| 94 | + self.assertTrue(np.all(x <= 1.5)) |
| 95 | + self.assertTrue(np.all(y >= -1.5)) |
| 96 | + self.assertTrue(np.all(y <= 1.5)) |
| 97 | + |
| 98 | + def test_get_ar_data_basic(self): |
| 99 | + """Test basic AR data generation""" |
| 100 | + df = get_ar_data(n_series=5, timesteps=100) |
| 101 | + |
| 102 | + self.assertIsInstance(df, pd.DataFrame) |
| 103 | + self.assertIn("series", df.columns) |
| 104 | + self.assertIn("time_idx", df.columns) |
| 105 | + self.assertIn("value", df.columns) |
| 106 | + self.assertEqual(len(df), 5 * 100) # n_series * timesteps |
| 107 | + |
| 108 | + def test_get_ar_data_with_covariates(self): |
| 109 | + """Test AR data generation with covariates""" |
| 110 | + df = get_ar_data(n_series=3, timesteps=50, add_covariates=True) |
| 111 | + |
| 112 | + self.assertIn("day_of_week", df.columns) |
| 113 | + self.assertIn("month", df.columns) |
| 114 | + self.assertIn("category", df.columns) |
| 115 | + self.assertIn("special_event", df.columns) |
| 116 | + |
| 117 | + # Check value ranges |
| 118 | + self.assertTrue(df["day_of_week"].between(0, 6).all()) |
| 119 | + self.assertTrue(df["month"].between(1, 13).all()) |
| 120 | + self.assertTrue(df["special_event"].isin([0, 1]).all()) |
| 121 | + |
| 122 | + def test_get_ar_data_with_components(self): |
| 123 | + """Test AR data generation returning components""" |
| 124 | + df, components = get_ar_data(n_series=3, timesteps=50, return_components=True) |
| 125 | + |
| 126 | + self.assertIsInstance(components, dict) |
| 127 | + self.assertIn("linear_trends", components) |
| 128 | + self.assertIn("quadratic_trends", components) |
| 129 | + self.assertIn("seasonalities", components) |
| 130 | + self.assertIn("levels", components) |
| 131 | + self.assertIn("series", components) |
| 132 | + |
| 133 | + def test_get_ar_data_exponential(self): |
| 134 | + """Test AR data with exponential transformation""" |
| 135 | + df = get_ar_data(n_series=2, timesteps=50, exp=True) |
| 136 | + |
| 137 | + # Exponential values should all be positive |
| 138 | + self.assertTrue((df["value"] > 0).all()) |
| 139 | + |
| 140 | + def test_get_ar_data_seeded_reproducibility(self): |
| 141 | + """Test that same seed produces same data""" |
| 142 | + df1 = get_ar_data(n_series=3, timesteps=50, seed=42) |
| 143 | + df2 = get_ar_data(n_series=3, timesteps=50, seed=42) |
| 144 | + |
| 145 | + pd.testing.assert_frame_equal(df1, df2) |
| 146 | + |
| 147 | + def test_get_ar_data_different_seeds(self): |
| 148 | + """Test that different seeds produce different data""" |
| 149 | + df1 = get_ar_data(n_series=3, timesteps=50, seed=42) |
| 150 | + df2 = get_ar_data(n_series=3, timesteps=50, seed=123) |
| 151 | + |
| 152 | + # Values should be different |
| 153 | + self.assertFalse(df1["value"].equals(df2["value"])) |
| 154 | + |
| 155 | + def test_get_ar_data_invalid_params(self): |
| 156 | + """Test AR data validation for invalid parameters""" |
| 157 | + with self.assertRaises(ValueError): |
| 158 | + get_ar_data(n_series=0, timesteps=100) |
| 159 | + |
| 160 | + with self.assertRaises(ValueError): |
| 161 | + get_ar_data(n_series=5, timesteps=-10) |
| 162 | + |
| 163 | + with self.assertRaises(ValueError): |
| 164 | + get_ar_data(n_series=5, timesteps=100, noise=-0.5) |
| 165 | + |
| 166 | + def test_get_ar_data_parameter_effects(self): |
| 167 | + """Test that parameters affect data as expected""" |
| 168 | + # High noise should create more variance |
| 169 | + df_low_noise = get_ar_data(n_series=5, timesteps=100, noise=0.01, seed=42) |
| 170 | + df_high_noise = get_ar_data(n_series=5, timesteps=100, noise=1.0, seed=42) |
| 171 | + |
| 172 | + # Not directly comparing variance due to random effects, |
| 173 | + # but shapes should match |
| 174 | + self.assertEqual(len(df_low_noise), len(df_high_noise)) |
| 175 | + |
| 176 | + def test_get_data_ar_dispatch(self): |
| 177 | + """Test get_data dispatcher for AR data""" |
| 178 | + result = get_data("ar", train_length=10, predict_sequence_length=5, test_size=0, n_series=3, timesteps=50) |
| 179 | + |
| 180 | + self.assertIsInstance(result, pd.DataFrame) |
| 181 | + self.assertEqual(len(result), 3 * 50) |
| 182 | + |
| 183 | + def test_sine_data_sequence_continuity(self): |
| 184 | + """Test that sine data maintains temporal continuity""" |
| 185 | + train_length = 10 |
| 186 | + predict_length = 5 |
| 187 | + x, y = get_sine(train_length, predict_length, test_size=0, n_examples=1) |
| 188 | + |
| 189 | + # x and y should form a continuous sequence |
| 190 | + # This is a shape test since exact continuity depends on implementation |
| 191 | + self.assertEqual(x.shape[1], train_length) |
| 192 | + self.assertEqual(y.shape[1], predict_length) |
| 193 | + |
| 194 | + def test_air_passengers_normalization(self): |
| 195 | + """Test that air passengers data is properly normalized""" |
| 196 | + x, y = get_air_passengers(10, 4, test_size=0) |
| 197 | + |
| 198 | + # Values should be normalized (roughly between -1 and 1 after normalization) |
| 199 | + self.assertTrue(np.all(x >= -1.5)) |
| 200 | + self.assertTrue(np.all(x <= 1.5)) |
| 201 | + |
| 202 | + |
| 203 | +if __name__ == "__main__": |
| 204 | + unittest.main() |
0 commit comments