-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_sort_function.py
More file actions
333 lines (264 loc) · 12.1 KB
/
Copy pathtest_sort_function.py
File metadata and controls
333 lines (264 loc) · 12.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
"""
Unit Tests for PackageSorter Core Sorting Function
This test suite provides comprehensive coverage of the sort() function,
including edge cases, boundary conditions, and error handling.
Run tests with:
python -m pytest test_sort_function.py -v
or
python test_sort_function.py
"""
import unittest
from sort_function import sort, sort_detailed
class TestSortFunction(unittest.TestCase):
"""Test suite for the sort() function."""
# ============================================================================
# STANDARD Package Tests
# ============================================================================
def test_standard_small_package(self):
"""Test standard small package - not bulky, not heavy."""
result = sort(10, 10, 10, 5)
self.assertEqual(result, "STANDARD")
def test_standard_medium_package(self):
"""Test standard medium package."""
result = sort(30, 40, 50, 12)
self.assertEqual(result, "STANDARD")
def test_standard_at_boundary(self):
"""Test standard package just below bulky/heavy thresholds."""
# Volume = 149 * 99 * 99 = 1,460,349 (but dimension = 149 < 150)
# Actually volume check: 99 * 99 * 99 = 970,299 < 1,000,000
result = sort(99, 99, 99, 19.9)
self.assertEqual(result, "STANDARD")
# ============================================================================
# SPECIAL Package Tests (Bulky OR Heavy, but not both)
# ============================================================================
def test_special_heavy_only(self):
"""Test package that is heavy but not bulky."""
result = sort(50, 50, 50, 25)
self.assertEqual(result, "SPECIAL")
def test_special_bulky_by_dimension(self):
"""Test package that is bulky by dimension but not heavy."""
result = sort(160, 50, 50, 15)
self.assertEqual(result, "SPECIAL")
def test_special_bulky_by_volume(self):
"""Test package that is bulky by volume but not heavy."""
# Volume = 120 * 110 * 90 = 1,188,000 >= 1,000,000
result = sort(120, 110, 90, 18)
self.assertEqual(result, "SPECIAL")
def test_special_bulky_width(self):
"""Test package bulky due to width >= 150."""
result = sort(150, 50, 50, 15)
self.assertEqual(result, "SPECIAL")
def test_special_bulky_height(self):
"""Test package bulky due to height >= 150."""
result = sort(50, 150, 50, 15)
self.assertEqual(result, "SPECIAL")
def test_special_bulky_length(self):
"""Test package bulky due to length >= 150."""
result = sort(50, 50, 150, 15)
self.assertEqual(result, "SPECIAL")
# ============================================================================
# REJECTED Package Tests (Both Bulky AND Heavy)
# ============================================================================
def test_rejected_bulky_and_heavy(self):
"""Test package that is both bulky and heavy."""
result = sort(200, 100, 100, 30)
self.assertEqual(result, "REJECTED")
def test_rejected_large_volume_and_heavy(self):
"""Test package with large volume and heavy mass."""
# Volume = 150 * 150 * 150 = 3,375,000
result = sort(150, 150, 150, 25)
self.assertEqual(result, "REJECTED")
def test_rejected_one_large_dimension_and_heavy(self):
"""Test package with one large dimension and heavy mass."""
result = sort(200, 50, 50, 20)
self.assertEqual(result, "REJECTED")
# ============================================================================
# Edge Case Tests (Boundary Values)
# ============================================================================
def test_edge_volume_exactly_1_million(self):
"""Test package with volume exactly 1,000,000 cm³."""
# 100 * 100 * 100 = 1,000,000
result = sort(100, 100, 100, 15)
self.assertEqual(result, "SPECIAL")
def test_edge_volume_just_below_1_million(self):
"""Test package with volume just below 1,000,000 cm³."""
# 99 * 100 * 100 = 990,000
result = sort(99, 100, 100, 15)
self.assertEqual(result, "STANDARD")
def test_edge_dimension_exactly_150(self):
"""Test package with one dimension exactly 150 cm."""
result = sort(150, 50, 50, 15)
self.assertEqual(result, "SPECIAL")
def test_edge_dimension_just_below_150(self):
"""Test package with dimensions just below 150 cm."""
result = sort(149, 50, 50, 15)
self.assertEqual(result, "STANDARD")
def test_edge_mass_exactly_20(self):
"""Test package with mass exactly 20 kg."""
result = sort(50, 50, 50, 20)
self.assertEqual(result, "SPECIAL")
def test_edge_mass_just_below_20(self):
"""Test package with mass just below 20 kg."""
result = sort(50, 50, 50, 19.9)
self.assertEqual(result, "STANDARD")
def test_edge_all_thresholds_exactly(self):
"""Test package at exactly all thresholds."""
result = sort(150, 100, 100, 20)
self.assertEqual(result, "REJECTED")
# ============================================================================
# Input Validation Tests
# ============================================================================
def test_negative_width(self):
"""Test that negative width raises ValueError."""
with self.assertRaises(ValueError):
sort(-10, 50, 50, 15)
def test_negative_height(self):
"""Test that negative height raises ValueError."""
with self.assertRaises(ValueError):
sort(50, -10, 50, 15)
def test_negative_length(self):
"""Test that negative length raises ValueError."""
with self.assertRaises(ValueError):
sort(50, 50, -10, 15)
def test_negative_mass(self):
"""Test that negative mass raises ValueError."""
with self.assertRaises(ValueError):
sort(50, 50, 50, -5)
def test_zero_width(self):
"""Test that zero width raises ValueError."""
with self.assertRaises(ValueError):
sort(0, 50, 50, 15)
def test_zero_height(self):
"""Test that zero height raises ValueError."""
with self.assertRaises(ValueError):
sort(50, 0, 50, 15)
def test_zero_length(self):
"""Test that zero length raises ValueError."""
with self.assertRaises(ValueError):
sort(50, 50, 0, 15)
def test_zero_mass(self):
"""Test that zero mass raises ValueError."""
with self.assertRaises(ValueError):
sort(50, 50, 50, 0)
def test_string_input(self):
"""Test that string input raises TypeError."""
with self.assertRaises(TypeError):
sort("50", 50, 50, 15)
def test_none_input(self):
"""Test that None input raises TypeError."""
with self.assertRaises(TypeError):
sort(None, 50, 50, 15)
# ============================================================================
# Float/Decimal Input Tests
# ============================================================================
def test_float_dimensions(self):
"""Test that float dimensions work correctly."""
result = sort(10.5, 10.5, 10.5, 5.5)
self.assertEqual(result, "STANDARD")
def test_decimal_precision(self):
"""Test handling of decimal precision."""
result = sort(149.99, 50.01, 50.01, 19.99)
self.assertEqual(result, "STANDARD")
def test_float_at_boundary(self):
"""Test float values at exact boundaries."""
result = sort(150.0, 50.0, 50.0, 20.0)
self.assertEqual(result, "REJECTED")
# ============================================================================
# Large Value Tests
# ============================================================================
def test_very_large_package(self):
"""Test very large package dimensions."""
result = sort(500, 500, 500, 100)
self.assertEqual(result, "REJECTED")
def test_extremely_heavy(self):
"""Test extremely heavy package."""
result = sort(50, 50, 50, 1000)
self.assertEqual(result, "SPECIAL")
def test_very_small_package(self):
"""Test very small package."""
result = sort(1, 1, 1, 0.1)
self.assertEqual(result, "STANDARD")
class TestSortDetailedFunction(unittest.TestCase):
"""Test suite for the sort_detailed() helper function."""
def test_detailed_standard(self):
"""Test detailed output for standard package."""
result = sort_detailed(10, 10, 10, 5)
self.assertEqual(result["category"], "STANDARD")
self.assertEqual(result["volume"], 1000)
self.assertFalse(result["is_bulky"])
self.assertFalse(result["is_heavy"])
def test_detailed_special_heavy(self):
"""Test detailed output for heavy package."""
result = sort_detailed(50, 50, 50, 25)
self.assertEqual(result["category"], "SPECIAL")
self.assertTrue(result["is_heavy"])
self.assertFalse(result["is_bulky"])
self.assertIn("Mass 25 kg >= 20 kg", result["reasons"])
def test_detailed_special_bulky(self):
"""Test detailed output for bulky package."""
result = sort_detailed(160, 50, 50, 15)
self.assertEqual(result["category"], "SPECIAL")
self.assertTrue(result["is_bulky"])
self.assertFalse(result["is_heavy"])
self.assertIn("Width 160 cm >= 150 cm", result["reasons"])
def test_detailed_rejected(self):
"""Test detailed output for rejected package."""
result = sort_detailed(200, 100, 100, 30)
self.assertEqual(result["category"], "REJECTED")
self.assertTrue(result["is_bulky"])
self.assertTrue(result["is_heavy"])
self.assertTrue(len(result["reasons"]) > 0)
def test_detailed_dimensions_stored(self):
"""Test that dimensions are correctly stored in detailed output."""
result = sort_detailed(10, 20, 30, 5)
self.assertEqual(result["dimensions"]["width"], 10)
self.assertEqual(result["dimensions"]["height"], 20)
self.assertEqual(result["dimensions"]["length"], 30)
self.assertEqual(result["mass"], 5)
class TestRealWorldScenarios(unittest.TestCase):
"""Test real-world package scenarios."""
def test_amazon_small_box(self):
"""Test typical Amazon small box."""
result = sort(30, 20, 15, 2)
self.assertEqual(result, "STANDARD")
def test_furniture_package(self):
"""Test furniture package (long but light)."""
result = sort(200, 50, 50, 15)
self.assertEqual(result, "SPECIAL")
def test_appliance_package(self):
"""Test appliance package (bulky and heavy)."""
result = sort(150, 150, 150, 50)
self.assertEqual(result, "REJECTED")
def test_books_package(self):
"""Test books package (small but heavy)."""
result = sort(40, 30, 30, 25)
self.assertEqual(result, "SPECIAL")
def test_envelope(self):
"""Test envelope (very small and light)."""
result = sort(30, 20, 1, 0.5)
self.assertEqual(result, "STANDARD")
def run_tests():
"""Run all tests with verbose output."""
# Create test suite
loader = unittest.TestLoader()
suite = unittest.TestSuite()
# Add all test classes
suite.addTests(loader.loadTestsFromTestCase(TestSortFunction))
suite.addTests(loader.loadTestsFromTestCase(TestSortDetailedFunction))
suite.addTests(loader.loadTestsFromTestCase(TestRealWorldScenarios))
# Run tests
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
# Print summary
print("\n" + "=" * 70)
print("TEST SUMMARY")
print("=" * 70)
print(f"Tests run: {result.testsRun}")
print(f"Successes: {result.testsRun - len(result.failures) - len(result.errors)}")
print(f"Failures: {len(result.failures)}")
print(f"Errors: {len(result.errors)}")
print("=" * 70)
return result.wasSuccessful()
if __name__ == "__main__":
success = run_tests()
exit(0 if success else 1)