11#include " complex_numbers.h"
22
33#include < cmath>
4+ #include < sstream>
45
56#ifdef EXERCISM_TEST_SUITE
67#include < catch2/catch.hpp>
@@ -24,11 +25,33 @@ using complex_numbers::Complex;
2425// epsilon for float values near 0.
2526static const double eps = 0.005 ;
2627
27- // Helper function for comparing Complex numbers with approximate float values.
28- [[maybe_unused]] static void require_approx_equal (const Complex& lhs,
29- const Complex& rhs) {
30- REQUIRE_THAT (lhs.real (), Catch::Matchers::WithinAbs (rhs.real (), eps));
31- REQUIRE_THAT (lhs.imag (), Catch::Matchers::WithinAbs (rhs.imag (), eps));
28+ // Custom Catch2 matcher for approximate equality of Complex numbers
29+ class ComplexApproxMatcher : public Catch ::MatcherBase<Complex> {
30+ public:
31+ ComplexApproxMatcher (const Complex& expected, double epsilon = eps)
32+ : expected(expected), epsilon(epsilon) {}
33+
34+ bool match (const Complex& actual) const override {
35+ return std::abs (actual.real () - expected.real ()) <= epsilon &&
36+ std::abs (actual.imag () - expected.imag ()) <= epsilon;
37+ }
38+
39+ std::string describe () const override {
40+ std::ostringstream ss;
41+ ss << " is approximately equal to (" << expected.real () << " , "
42+ << expected.imag () << " i) with epsilon " << epsilon;
43+ return ss.str ();
44+ }
45+
46+ private:
47+ Complex expected;
48+ double epsilon;
49+ };
50+
51+ // Helper function to create the matcher
52+ inline ComplexApproxMatcher ApproxEquals (const Complex& expected,
53+ double epsilon = eps) {
54+ return ComplexApproxMatcher (expected, epsilon);
3255}
3356
3457TEST_CASE (" Real part -> Real part of a purely real number" ,
@@ -79,47 +102,47 @@ TEST_CASE("Imaginary unit", "[a39b7fd6-6527-492f-8c34-609d2c913879]") {
79102 const Complex c1{0.0 , 1.0 };
80103 const Complex c2{0.0 , 1.0 };
81104
82- require_approx_equal ( Complex (-1.0 , 0.0 ), c1 * c2 );
105+ REQUIRE_THAT (c1 * c2, ApproxEquals ( Complex (-1.0 , 0.0 )) );
83106}
84107
85108TEST_CASE (" Arithmetic -> Addition -> Add purely real numbers" ,
86109 " [9a2c8de9-f068-4f6f-b41c-82232cc6c33e]" ) {
87110 const Complex c1{1.0 , 0.0 };
88111 const Complex c2{2.0 , 0.0 };
89112
90- require_approx_equal ( Complex (3.0 , 0.0 ), c1 + c2 );
113+ REQUIRE_THAT (c1 + c2, ApproxEquals ( Complex (3.0 , 0.0 )) );
91114}
92115
93116TEST_CASE (" Arithmetic -> Addition -> Add purely imaginary numbers" ,
94117 " [657c55e1-b14b-4ba7-bd5c-19db22b7d659]" ) {
95118 const Complex c1{0.0 , 1.0 };
96119 const Complex c2{0.0 , 2.0 };
97120
98- require_approx_equal ( Complex (0.0 , 3.0 ), c1 + c2 );
121+ REQUIRE_THAT (c1 + c2, ApproxEquals ( Complex (0.0 , 3.0 )) );
99122}
100123
101124TEST_CASE (" Arithmetic -> Addition -> Add numbers with real and imaginary part" ,
102125 " [4e1395f5-572b-4ce8-bfa9-9a63056888da]" ) {
103126 const Complex c1{1.0 , 2.0 };
104127 const Complex c2{3.0 , 4.0 };
105128
106- require_approx_equal ( Complex (4.0 , 6.0 ), c1 + c2 );
129+ REQUIRE_THAT (c1 + c2, ApproxEquals ( Complex (4.0 , 6.0 )) );
107130}
108131
109132TEST_CASE (" Arithmetic -> Subtraction -> Subtract purely real numbers" ,
110133 " [1155dc45-e4f7-44b8-af34-a91aa431475d]" ) {
111134 const Complex c1{1.0 , 0.0 };
112135 const Complex c2{2.0 , 0.0 };
113136
114- require_approx_equal ( Complex (-1.0 , 0.0 ), c1 - c2 );
137+ REQUIRE_THAT (c1 - c2, ApproxEquals ( Complex (-1.0 , 0.0 )) );
115138}
116139
117140TEST_CASE (" Arithmetic -> Subtraction -> Subtract purely imaginary numbers" ,
118141 " [f95e9da8-acd5-4da4-ac7c-c861b02f774b]" ) {
119142 const Complex c1{0.0 , 1.0 };
120143 const Complex c2{0.0 , 2.0 };
121144
122- require_approx_equal ( Complex (0.0 , -1.0 ), c1 - c2 );
145+ REQUIRE_THAT (c1 - c2, ApproxEquals ( Complex (0.0 , -1.0 )) );
123146}
124147
125148TEST_CASE (
@@ -130,23 +153,23 @@ TEST_CASE(
130153 const Complex c1{1.0 , 2.0 };
131154 const Complex c2{3.0 , 4.0 };
132155
133- require_approx_equal ( Complex (-2.0 , -2.0 ), c1 - c2 );
156+ REQUIRE_THAT (c1 - c2, ApproxEquals ( Complex (-2.0 , -2.0 )) );
134157}
135158
136159TEST_CASE (" Arithmetic -> Multiplication -> Multiply purely real numbers" ,
137160 " [8a0366c0-9e16-431f-9fd7-40ac46ff4ec4]" ) {
138161 const Complex c1{1.0 , 0.0 };
139162 const Complex c2{2.0 , 0.0 };
140163
141- require_approx_equal ( Complex (2.0 , 0.0 ), c1 * c2 );
164+ REQUIRE_THAT (c1 * c2, ApproxEquals ( Complex (2.0 , 0.0 )) );
142165}
143166
144167TEST_CASE (" Arithmetic -> Multiplication -> Multiply purely imaginary numbers" ,
145168 " [e560ed2b-0b80-4b4f-90f2-63cefc911aaf]" ) {
146169 const Complex c1{0.0 , 1.0 };
147170 const Complex c2{0.0 , 2.0 };
148171
149- require_approx_equal ( Complex (-2.0 , 0.0 ), c1 * c2 );
172+ REQUIRE_THAT (c1 * c2, ApproxEquals ( Complex (-2.0 , 0.0 )) );
150173}
151174
152175TEST_CASE (
@@ -157,23 +180,23 @@ TEST_CASE(
157180 const Complex c1{1.0 , 2.0 };
158181 const Complex c2{3.0 , 4.0 };
159182
160- require_approx_equal ( Complex (-5.0 , 10.0 ), c1 * c2 );
183+ REQUIRE_THAT (c1 * c2, ApproxEquals ( Complex (-5.0 , 10.0 )) );
161184}
162185
163186TEST_CASE (" Arithmetic -> Division -> Divide purely real numbers" ,
164187 " [b0571ddb-9045-412b-9c15-cd1d816d36c1]" ) {
165188 const Complex c1{1.0 , 0.0 };
166189 const Complex c2{2.0 , 0.0 };
167190
168- require_approx_equal ( Complex (0.5 , 0.0 ), c1 / c2 );
191+ REQUIRE_THAT (c1 / c2, ApproxEquals ( Complex (0.5 , 0.0 )) );
169192}
170193
171194TEST_CASE (" Arithmetic -> Division -> Divide purely imaginary numbers" ,
172195 " [5bb4c7e4-9934-4237-93cc-5780764fdbdd]" ) {
173196 const Complex c1{0.0 , 1.0 };
174197 const Complex c2{0.0 , 2.0 };
175198
176- require_approx_equal ( Complex (0.5 , 0.0 ), c1 / c2 );
199+ REQUIRE_THAT (c1 / c2, ApproxEquals ( Complex (0.5 , 0.0 )) );
177200}
178201
179202TEST_CASE (
@@ -182,7 +205,7 @@ TEST_CASE(
182205 const Complex c1{1.0 , 2.0 };
183206 const Complex c2{3.0 , 4.0 };
184207
185- require_approx_equal ( Complex (0.44 , 0.08 ), c1 / c2 );
208+ REQUIRE_THAT (c1 / c2, ApproxEquals ( Complex (0.44 , 0.08 )) );
186209}
187210
188211TEST_CASE (" Absolute value -> Absolute value of a positive purely real number" ,
@@ -231,43 +254,43 @@ TEST_CASE("Complex conjugate -> Conjugate a purely real number",
231254 " [fb2d0792-e55a-4484-9443-df1eddfc84a2]" ) {
232255 const Complex c{5.0 , 0.0 };
233256
234- require_approx_equal ( Complex (5.0 , 0.0 ), c. conj ( ));
257+ REQUIRE_THAT (c. conj (), ApproxEquals ( Complex (5.0 , 0.0 )));
235258}
236259
237260TEST_CASE (" Complex conjugate -> Conjugate a purely imaginary number" ,
238261 " [e37fe7ac-a968-4694-a460-66cb605f8691]" ) {
239262 const Complex c{0.0 , 5.0 };
240263
241- require_approx_equal ( Complex (0.0 , -5.0 ), c. conj ( ));
264+ REQUIRE_THAT (c. conj (), ApproxEquals ( Complex (0.0 , -5.0 )));
242265}
243266
244267TEST_CASE (
245268 " Complex conjugate -> Conjugate a number with real and imaginary part" ,
246269 " [f7704498-d0be-4192-aaf5-a1f3a7f43e68]" ) {
247270 const Complex c{1.0 , 1.0 };
248271
249- require_approx_equal ( Complex (1.0 , -1.0 ), c. conj ( ));
272+ REQUIRE_THAT (c. conj (), ApproxEquals ( Complex (1.0 , -1.0 )));
250273}
251274
252275TEST_CASE (" Complex exponential function -> Euler's identity/formula" ,
253276 " [6d96d4c6-2edb-445b-94a2-7de6d4caaf60]" ) {
254277 const Complex c{0.0 , M_PI};
255278
256- require_approx_equal ( Complex (-1.0 , 0.0 ), c. exp ( ));
279+ REQUIRE_THAT (c. exp (), ApproxEquals ( Complex (-1.0 , 0.0 )));
257280}
258281
259282TEST_CASE (" Complex exponential function -> Exponential of 0" ,
260283 " [2d2c05a0-4038-4427-a24d-72f6624aa45f]" ) {
261284 const Complex c{0.0 , 0.0 };
262285
263- require_approx_equal ( Complex (1.0 , 0.0 ), c. exp ( ));
286+ REQUIRE_THAT (c. exp (), ApproxEquals ( Complex (1.0 , 0.0 )));
264287}
265288
266289TEST_CASE (" Complex exponential function -> Exponential of a purely real number" ,
267290 " [ed87f1bd-b187-45d6-8ece-7e331232c809]" ) {
268291 const Complex c{1.0 , 0.0 };
269292
270- require_approx_equal ( Complex (M_E, 0.0 ), c. exp ( ));
293+ REQUIRE_THAT (c. exp (), ApproxEquals ( Complex (M_E, 0.0 )));
271294}
272295
273296// Extra Credit
@@ -278,7 +301,7 @@ TEST_CASE(
278301 " [08eedacc-5a95-44fc-8789-1547b27a8702]" ) {
279302 const Complex c{std::log (2.0 ), M_PI};
280303
281- require_approx_equal ( Complex (-2.0 , 0.0 ), c. exp ( ));
304+ REQUIRE_THAT (c. exp (), ApproxEquals ( Complex (-2.0 , 0.0 )));
282305}
283306
284307TEST_CASE (
@@ -288,7 +311,7 @@ TEST_CASE(
288311 " [d2de4375-7537-479a-aa0e-d474f4f09859]" ) {
289312 const Complex c{std::log (2.0 ) / 2.0 , M_PI / 4.0 };
290313
291- require_approx_equal ( Complex (1.0 , 1.0 ), c. exp ( ));
314+ REQUIRE_THAT (c. exp (), ApproxEquals ( Complex (1.0 , 1.0 )));
292315}
293316
294317TEST_CASE (
@@ -298,7 +321,7 @@ TEST_CASE(
298321 " [06d793bf-73bd-4b02-b015-3030b2c952ec]" ) {
299322 const Complex c{1.0 , 2.0 };
300323
301- require_approx_equal ( Complex (6.0 , 2.0 ), c + 5.0 );
324+ REQUIRE_THAT (c + 5.0 , ApproxEquals ( Complex (6.0 , 2.0 )) );
302325}
303326
304327TEST_CASE (
@@ -308,7 +331,7 @@ TEST_CASE(
308331 " [d77dbbdf-b8df-43f6-a58d-3acb96765328]" ) {
309332 const Complex c{1.0 , 2.0 };
310333
311- require_approx_equal ( Complex (6.0 , 2.0 ), 5.0 + c );
334+ REQUIRE_THAT ( 5.0 + c, ApproxEquals ( Complex (6.0 , 2.0 )) );
312335}
313336
314337TEST_CASE (
@@ -318,7 +341,7 @@ TEST_CASE(
318341 " [20432c8e-8960-4c40-ba83-c9d910ff0a0f]" ) {
319342 const Complex c{5.0 , 7.0 };
320343
321- require_approx_equal ( Complex (1.0 , 7.0 ), c - 4.0 );
344+ REQUIRE_THAT (c - 4.0 , ApproxEquals ( Complex (1.0 , 7.0 )) );
322345}
323346
324347TEST_CASE (
@@ -328,7 +351,7 @@ TEST_CASE(
328351 " [b4b38c85-e1bf-437d-b04d-49bba6e55000]" ) {
329352 const Complex c{5.0 , 7.0 };
330353
331- require_approx_equal ( Complex (-1.0 , -7.0 ), 4.0 - c );
354+ REQUIRE_THAT ( 4.0 - c, ApproxEquals ( Complex (-1.0 , -7.0 )) );
332355}
333356
334357TEST_CASE (
@@ -338,7 +361,7 @@ TEST_CASE(
338361 " [dabe1c8c-b8f4-44dd-879d-37d77c4d06bd]" ) {
339362 const Complex c{2.0 , 5.0 };
340363
341- require_approx_equal ( Complex (10.0 , 25.0 ), c * 5.0 );
364+ REQUIRE_THAT (c * 5.0 , ApproxEquals ( Complex (10.0 , 25.0 )) );
342365}
343366
344367TEST_CASE (
@@ -348,7 +371,7 @@ TEST_CASE(
348371 " [6c81b8c8-9851-46f0-9de5-d96d314c3a28]" ) {
349372 const Complex c{2.0 , 5.0 };
350373
351- require_approx_equal ( Complex (10.0 , 25.0 ), 5.0 * c );
374+ REQUIRE_THAT ( 5.0 * c, ApproxEquals ( Complex (10.0 , 25.0 )) );
352375}
353376
354377TEST_CASE (
@@ -358,7 +381,7 @@ TEST_CASE(
358381 " [8a400f75-710e-4d0c-bcb4-5e5a00c78aa0]" ) {
359382 const Complex c{10.0 , 100.0 };
360383
361- require_approx_equal ( Complex ( 1 .0 , 10.0 ), c / 10.0 );
384+ REQUIRE_THAT (c / 10 .0 , ApproxEquals ( Complex ( 1.0 , 10.0 )) );
362385}
363386
364387TEST_CASE (
@@ -368,7 +391,7 @@ TEST_CASE(
368391 " [9a867d1b-d736-4c41-a41e-90bd148e9d5e]" ) {
369392 const Complex c{1.0 , 1.0 };
370393
371- require_approx_equal ( Complex (2.5 , -2.5 ), 5.0 / c );
394+ REQUIRE_THAT ( 5.0 / c, ApproxEquals ( Complex (2.5 , -2.5 )) );
372395}
373396
374397#endif
0 commit comments