1+ import unittest
2+ import math
3+ from datetime import datetime
4+ from api .gen_ai .math import (
5+ add , subtract , divide , factorial , is_prime , fibonacci ,
6+ Calculator , StringManipulator , DataProcessor ,
7+ parse_date , safe_list_access , merge_dicts
8+ )
9+
10+
11+ class BasicMathFunctionsTest (unittest .TestCase ):
12+ def test_add (self ):
13+ self .assertEqual (add (3 , 5 ), 8 )
14+ self .assertEqual (add (- 1 , 1 ), 0 )
15+ self .assertEqual (add (0 , 0 ), 0 )
16+ self .assertEqual (add (3.5 , 2.5 ), 6.0 )
17+
18+ def test_subtract (self ):
19+ self .assertEqual (subtract (10 , 5 ), 5 )
20+ self .assertEqual (subtract (5 , 10 ), - 5 )
21+ self .assertEqual (subtract (0 , 0 ), 0 )
22+ self .assertEqual (subtract (3.5 , 2.5 ), 1.0 )
23+
24+ def test_divide (self ):
25+ self .assertEqual (divide (10 , 2 ), 5 )
26+ self .assertEqual (divide (5 , 2 ), 2.5 )
27+ self .assertEqual (divide (0 , 5 ), 0 )
28+ self .assertAlmostEqual (divide (1 , 3 ), 0.3333333333333333 )
29+
30+ def test_divide_by_zero (self ):
31+ with self .assertRaises (ValueError ) as context :
32+ divide (5 , 0 )
33+ self .assertEqual (str (context .exception ), "Division by zero is not allowed" )
34+
35+
36+ class FactorialTest (unittest .TestCase ):
37+ def test_factorial_zero (self ):
38+ self .assertEqual (factorial (0 ), 1 )
39+
40+ def test_factorial_positive (self ):
41+ self .assertEqual (factorial (1 ), 1 )
42+ self .assertEqual (factorial (2 ), 2 )
43+ self .assertEqual (factorial (3 ), 6 )
44+ self .assertEqual (factorial (5 ), 120 )
45+ self .assertEqual (factorial (10 ), 3628800 )
46+
47+ def test_factorial_negative (self ):
48+ with self .assertRaises (ValueError ) as context :
49+ factorial (- 1 )
50+ self .assertEqual (str (context .exception ), "Negative numbers do not have factorials" )
51+
52+
53+ class PrimeTest (unittest .TestCase ):
54+ def test_is_prime_negative_and_zero (self ):
55+ self .assertFalse (is_prime (- 5 ))
56+ self .assertFalse (is_prime (0 ))
57+ self .assertFalse (is_prime (1 ))
58+
59+ def test_is_prime_small_primes (self ):
60+ self .assertTrue (is_prime (2 ))
61+ self .assertTrue (is_prime (3 ))
62+ self .assertTrue (is_prime (5 ))
63+ self .assertTrue (is_prime (7 ))
64+ self .assertTrue (is_prime (11 ))
65+ self .assertTrue (is_prime (13 ))
66+
67+ def test_is_prime_non_primes (self ):
68+ self .assertFalse (is_prime (4 ))
69+ self .assertFalse (is_prime (6 ))
70+ self .assertFalse (is_prime (8 ))
71+ self .assertFalse (is_prime (9 ))
72+ self .assertFalse (is_prime (10 ))
73+ self .assertFalse (is_prime (12 ))
74+
75+ def test_is_prime_larger_numbers (self ):
76+ self .assertTrue (is_prime (17 ))
77+ self .assertTrue (is_prime (19 ))
78+ self .assertTrue (is_prime (23 ))
79+ self .assertFalse (is_prime (25 ))
80+ self .assertFalse (is_prime (100 ))
81+ self .assertTrue (is_prime (101 ))
82+
83+
84+ class FibonacciTest (unittest .TestCase ):
85+ def test_fibonacci_base_cases (self ):
86+ self .assertEqual (fibonacci (0 ), 0 )
87+ self .assertEqual (fibonacci (1 ), 1 )
88+
89+ def test_fibonacci_sequence (self ):
90+ self .assertEqual (fibonacci (2 ), 1 )
91+ self .assertEqual (fibonacci (3 ), 2 )
92+ self .assertEqual (fibonacci (4 ), 3 )
93+ self .assertEqual (fibonacci (5 ), 5 )
94+ self .assertEqual (fibonacci (6 ), 8 )
95+ self .assertEqual (fibonacci (10 ), 55 )
96+
97+ def test_fibonacci_negative (self ):
98+ with self .assertRaises (ValueError ) as context :
99+ fibonacci (- 1 )
100+ self .assertEqual (str (context .exception ), "n must be a non-negative integer" )
101+
102+
103+ class CalculatorTest (unittest .TestCase ):
104+ def setUp (self ):
105+ self .calc = Calculator ()
106+
107+ def test_calculator_add (self ):
108+ self .assertEqual (self .calc .add (3 , 5 ), 8 )
109+ self .assertEqual (self .calc .add (- 1 , 1 ), 0 )
110+
111+ def test_calculator_subtract (self ):
112+ self .assertEqual (self .calc .subtract (10 , 5 ), 5 )
113+ self .assertEqual (self .calc .subtract (5 , 10 ), - 5 )
114+
115+ def test_calculator_multiply (self ):
116+ self .assertEqual (self .calc .multiply (3 , 5 ), 15 )
117+ self .assertEqual (self .calc .multiply (- 2 , 3 ), - 6 )
118+ self .assertEqual (self .calc .multiply (0 , 5 ), 0 )
119+
120+ def test_calculator_divide (self ):
121+ self .assertEqual (self .calc .divide (10 , 2 ), 5 )
122+ self .assertEqual (self .calc .divide (5 , 2 ), 2.5 )
123+
124+ def test_calculator_divide_by_zero (self ):
125+ with self .assertRaises (ValueError ) as context :
126+ self .calc .divide (5 , 0 )
127+ self .assertEqual (str (context .exception ), "Cannot divide by zero" )
128+
129+ def test_calculator_memory (self ):
130+ self .assertEqual (self .calc .memory , 0 ) # Default value
131+ self .calc .store (10 )
132+ self .assertEqual (self .calc .memory , 10 )
133+ self .assertEqual (self .calc .recall (), 10 )
134+ self .calc .store (- 5 )
135+ self .assertEqual (self .calc .recall (), - 5 )
136+
137+
138+ class StringManipulatorTest (unittest .TestCase ):
139+ def test_reverse_string (self ):
140+ self .assertEqual (StringManipulator .reverse_string ("hello" ), "olleh" )
141+ self .assertEqual (StringManipulator .reverse_string ("" ), "" )
142+ self .assertEqual (StringManipulator .reverse_string ("a" ), "a" )
143+ self .assertEqual (StringManipulator .reverse_string ("12345" ), "54321" )
144+
145+ def test_is_palindrome (self ):
146+ self .assertTrue (StringManipulator .is_palindrome ("racecar" ))
147+ self .assertTrue (StringManipulator .is_palindrome ("A man a plan a canal Panama" ))
148+ self .assertTrue (StringManipulator .is_palindrome ("" ))
149+ self .assertTrue (StringManipulator .is_palindrome ("a" ))
150+ self .assertFalse (StringManipulator .is_palindrome ("hello" ))
151+ self .assertFalse (StringManipulator .is_palindrome ("world" ))
152+
153+
154+ class DataProcessorTest (unittest .TestCase ):
155+ def test_data_processor_initialization (self ):
156+ dp = DataProcessor ([1 , 2 , 3 , 4 , 5 ])
157+ self .assertEqual (dp .data , [1 , 2 , 3 , 4 , 5 ])
158+
159+ def test_data_processor_empty_data (self ):
160+ with self .assertRaises (ValueError ) as context :
161+ DataProcessor ([])
162+ self .assertEqual (str (context .exception ), "Data list cannot be empty" )
163+
164+ def test_get_mean (self ):
165+ dp = DataProcessor ([1 , 2 , 3 , 4 , 5 ])
166+ self .assertEqual (dp .get_mean (), 3 )
167+
168+ dp = DataProcessor ([0 , 10 ])
169+ self .assertEqual (dp .get_mean (), 5 )
170+
171+ def test_get_variance (self ):
172+ dp = DataProcessor ([1 , 2 , 3 , 4 , 5 ])
173+ self .assertEqual (dp .get_variance (), 2.5 )
174+
175+ dp = DataProcessor ([2 , 2 , 2 , 2 ])
176+ self .assertEqual (dp .get_variance (), 0 )
177+
178+ def test_get_variance_single_value (self ):
179+ dp = DataProcessor ([5 ])
180+ with self .assertRaises (ValueError ) as context :
181+ dp .get_variance ()
182+ self .assertEqual (str (context .exception ), "At least two data points are required to compute variance" )
183+
184+ def test_normalize (self ):
185+ dp = DataProcessor ([1 , 2 , 3 , 4 , 5 ])
186+ normalized = dp .normalize ()
187+ self .assertAlmostEqual (normalized [0 ], - 1.2649110640673518 )
188+ self .assertAlmostEqual (normalized [1 ], - 0.6324555320336759 )
189+ self .assertAlmostEqual (normalized [2 ], 0.0 )
190+ self .assertAlmostEqual (normalized [3 ], 0.6324555320336759 )
191+ self .assertAlmostEqual (normalized [4 ], 1.2649110640673518 )
192+
193+ def test_normalize_zero_variance (self ):
194+ dp = DataProcessor ([2 , 2 , 2 , 2 ])
195+ with self .assertRaises (ValueError ) as context :
196+ dp .normalize ()
197+ self .assertEqual (str (context .exception ), "Standard deviation is zero, cannot normalize." )
198+
199+
200+ class UtilityFunctionsTest (unittest .TestCase ):
201+ def test_parse_date_default_format (self ):
202+ date = parse_date ("2023-01-15" )
203+ self .assertEqual (date , datetime (2023 , 1 , 15 ))
204+
205+ def test_parse_date_custom_format (self ):
206+ date = parse_date ("15/01/2023" , fmt = "%d/%m/%Y" )
207+ self .assertEqual (date , datetime (2023 , 1 , 15 ))
208+
209+ def test_parse_date_invalid_format (self ):
210+ with self .assertRaises (ValueError ) as context :
211+ parse_date ("invalid-date" )
212+ self .assertEqual (str (context .exception ), "Incorrect date format, should be YYYY-MM-DD" )
213+
214+ def test_safe_list_access (self ):
215+ test_list = [1 , 2 , 3 ]
216+ self .assertEqual (safe_list_access (test_list , 0 ), 1 )
217+ self .assertEqual (safe_list_access (test_list , 2 ), 3 )
218+ self .assertIsNone (safe_list_access (test_list , 5 ))
219+ self .assertEqual (safe_list_access (test_list , 5 , "default" ), "default" )
220+
221+ def test_merge_dicts (self ):
222+ dict1 = {"a" : 1 , "b" : 2 , "c" : {"x" : 1 , "y" : 2 }}
223+ dict2 = {"b" : 3 , "d" : 4 , "c" : {"y" : 3 , "z" : 4 }}
224+ merged = merge_dicts (dict1 , dict2 )
225+ self .assertEqual (merged , {"a" : 1 , "b" : 3 , "c" : {"x" : 1 , "y" : 3 , "z" : 4 }, "d" : 4 })
0 commit comments