1#!/usr/bin/env bats
2
3# Bats Tests for Math Library
4# Tests all functions in math_lib.sh for correctness and error handling
5
6# Setup - run before each test
7setup() {
8 # Source the library to test
9 load '../13_testing/math_lib'
10
11 # Create temp directory for test files if needed
12 TEST_TEMP_DIR="${BATS_TEST_TMPDIR}/math_lib_tests"
13 mkdir -p "$TEST_TEMP_DIR"
14}
15
16# Teardown - run after each test
17teardown() {
18 # Clean up temp directory
19 rm -rf "$TEST_TEMP_DIR"
20}
21
22# ============================================================================
23# Tests for Basic Arithmetic Operations
24# ============================================================================
25
26@test "add: positive numbers" {
27 result=$(add 5 3)
28 [ "$result" -eq 8 ]
29}
30
31@test "add: negative numbers" {
32 result=$(add -5 -3)
33 [ "$result" -eq -8 ]
34}
35
36@test "add: mixed positive and negative" {
37 result=$(add 10 -3)
38 [ "$result" -eq 7 ]
39}
40
41@test "add: zero" {
42 result=$(add 5 0)
43 [ "$result" -eq 5 ]
44}
45
46@test "subtract: positive numbers" {
47 result=$(subtract 10 3)
48 [ "$result" -eq 7 ]
49}
50
51@test "subtract: negative result" {
52 result=$(subtract 3 10)
53 [ "$result" -eq -7 ]
54}
55
56@test "subtract: negative numbers" {
57 result=$(subtract -5 -3)
58 [ "$result" -eq -2 ]
59}
60
61@test "multiply: positive numbers" {
62 result=$(multiply 6 7)
63 [ "$result" -eq 42 ]
64}
65
66@test "multiply: by zero" {
67 result=$(multiply 5 0)
68 [ "$result" -eq 0 ]
69}
70
71@test "multiply: negative numbers" {
72 result=$(multiply -4 -5)
73 [ "$result" -eq 20 ]
74}
75
76@test "multiply: mixed signs" {
77 result=$(multiply -4 5)
78 [ "$result" -eq -20 ]
79}
80
81@test "divide: positive numbers" {
82 result=$(divide 20 4)
83 [ "$result" -eq 5 ]
84}
85
86@test "divide: integer division truncates" {
87 result=$(divide 10 3)
88 [ "$result" -eq 3 ]
89}
90
91@test "divide: negative numbers" {
92 result=$(divide -20 4)
93 [ "$result" -eq -5 ]
94}
95
96@test "divide: division by zero returns error" {
97 run divide 10 0
98 [ "$status" -eq 1 ]
99 [[ "$output" =~ "Division by zero" ]]
100}
101
102# ============================================================================
103# Tests for Factorial Function
104# ============================================================================
105
106@test "factorial: zero" {
107 result=$(factorial 0)
108 [ "$result" -eq 1 ]
109}
110
111@test "factorial: one" {
112 result=$(factorial 1)
113 [ "$result" -eq 1 ]
114}
115
116@test "factorial: small number" {
117 result=$(factorial 5)
118 [ "$result" -eq 120 ]
119}
120
121@test "factorial: larger number" {
122 result=$(factorial 10)
123 [ "$result" -eq 3628800 ]
124}
125
126@test "factorial: negative number returns error" {
127 run factorial -5
128 [ "$status" -eq 1 ]
129 [[ "$output" =~ "negative numbers" ]]
130}
131
132# ============================================================================
133# Tests for Prime Number Check
134# ============================================================================
135
136@test "is_prime: 2 is prime" {
137 is_prime 2
138 [ "$?" -eq 0 ]
139}
140
141@test "is_prime: 3 is prime" {
142 is_prime 3
143 [ "$?" -eq 0 ]
144}
145
146@test "is_prime: 17 is prime" {
147 is_prime 17
148 [ "$?" -eq 0 ]
149}
150
151@test "is_prime: 97 is prime" {
152 is_prime 97
153 [ "$?" -eq 0 ]
154}
155
156@test "is_prime: 1 is not prime" {
157 run is_prime 1
158 [ "$status" -eq 1 ]
159}
160
161@test "is_prime: 4 is not prime" {
162 run is_prime 4
163 [ "$status" -eq 1 ]
164}
165
166@test "is_prime: 20 is not prime" {
167 run is_prime 20
168 [ "$status" -eq 1 ]
169}
170
171@test "is_prime: 100 is not prime" {
172 run is_prime 100
173 [ "$status" -eq 1 ]
174}
175
176@test "is_prime: 0 is not prime" {
177 run is_prime 0
178 [ "$status" -eq 1 ]
179}
180
181# ============================================================================
182# Tests for GCD (Greatest Common Divisor)
183# ============================================================================
184
185@test "gcd: simple case" {
186 result=$(gcd 48 18)
187 [ "$result" -eq 6 ]
188}
189
190@test "gcd: coprime numbers" {
191 result=$(gcd 17 19)
192 [ "$result" -eq 1 ]
193}
194
195@test "gcd: one number is multiple of other" {
196 result=$(gcd 24 12)
197 [ "$result" -eq 12 ]
198}
199
200@test "gcd: same numbers" {
201 result=$(gcd 42 42)
202 [ "$result" -eq 42 ]
203}
204
205@test "gcd: with zero" {
206 result=$(gcd 15 0)
207 [ "$result" -eq 15 ]
208}
209
210@test "gcd: negative numbers" {
211 result=$(gcd -48 18)
212 [ "$result" -eq 6 ]
213}
214
215# ============================================================================
216# Tests for LCM (Least Common Multiple)
217# ============================================================================
218
219@test "lcm: simple case" {
220 result=$(lcm 12 18)
221 [ "$result" -eq 36 ]
222}
223
224@test "lcm: coprime numbers" {
225 result=$(lcm 7 13)
226 [ "$result" -eq 91 ]
227}
228
229@test "lcm: one number is multiple of other" {
230 result=$(lcm 5 15)
231 [ "$result" -eq 15 ]
232}
233
234@test "lcm: same numbers" {
235 result=$(lcm 8 8)
236 [ "$result" -eq 8 ]
237}
238
239@test "lcm: with zero" {
240 result=$(lcm 5 0)
241 [ "$result" -eq 0 ]
242}
243
244@test "lcm: negative numbers" {
245 result=$(lcm -12 18)
246 [ "$result" -eq 36 ]
247}
248
249# ============================================================================
250# Integration Tests
251# ============================================================================
252
253@test "integration: factorial of prime" {
254 # 7 is prime, factorial(7) = 5040
255 is_prime 7
256 [ "$?" -eq 0 ]
257
258 result=$(factorial 7)
259 [ "$result" -eq 5040 ]
260}
261
262@test "integration: gcd and lcm relationship" {
263 # For any two numbers a and b: a * b = gcd(a, b) * lcm(a, b)
264 a=24
265 b=36
266
267 gcd_val=$(gcd $a $b)
268 lcm_val=$(lcm $a $b)
269
270 product=$((a * b))
271 gcd_lcm_product=$((gcd_val * lcm_val))
272
273 [ "$product" -eq "$gcd_lcm_product" ]
274}