1 2 // 3 // This source file is part of appleseed. 4 // Visit https://appleseedhq.net/ for additional information and resources. 5 // 6 // This software is released under the MIT license. 7 // 8 // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited 9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization 10 // 11 // Permission is hereby granted, free of charge, to any person obtaining a copy 12 // of this software and associated documentation files (the "Software"), to deal 13 // in the Software without restriction, including without limitation the rights 14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 // copies of the Software, and to permit persons to whom the Software is 16 // furnished to do so, subject to the following conditions: 17 // 18 // The above copyright notice and this permission notice shall be included in 19 // all copies or substantial portions of the Software. 20 // 21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 // THE SOFTWARE. 28 // 29 30 #pragma once 31 32 // appleseed.foundation headers. 33 #include "foundation/math/scalar.h" 34 #include "foundation/utility/countof.h" 35 #include "foundation/utility/string.h" 36 #include "foundation/utility/test/exceptionassertionfailure.h" 37 #include "foundation/utility/test/testlistenerhelper.h" 38 #include "foundation/utility/test/testmessage.h" 39 #include "foundation/utility/test/testresult.h" 40 41 // Standard headers. 42 #include <string> 43 44 namespace foundation 45 { 46 47 // 48 // Emit an error message signaling that an assertion failed. 49 // 50 51 #define FOUNDATION_ASSERTION_FAILURE(op, expected, expr, stop) \ 52 do { \ 53 case_result.signal_assertion_failure(); \ 54 \ 55 foundation::TestListenerHelper::write( \ 56 test_listener, \ 57 current_test_suite__(), \ 58 get_name(), \ 59 __FILE__, \ 60 __LINE__, \ 61 foundation::TestMessage::AssertionFailure, \ 62 "expected: %s %s %s\n" \ 63 "received: %s == %s", \ 64 #expr, op, foundation::to_string(expected).c_str(), \ 65 #expr, foundation::to_string(expr).c_str()); \ 66 \ 67 if (stop) \ 68 throw foundation::ExceptionAssertionFailure(); \ 69 } while (0) 70 71 72 // 73 // Expect a true boolean expression. 74 // 75 76 #define FOUNDATION_EXPECT_TRUE_IMPL(expr, stop) \ 77 do { \ 78 case_result.signal_assertion_execution(); \ 79 if (!(expr)) \ 80 FOUNDATION_ASSERTION_FAILURE("==", true, expr, stop); \ 81 } while (0) 82 83 #define EXPECT_TRUE(expr) \ 84 FOUNDATION_EXPECT_TRUE_IMPL(expr, false) 85 86 #define ASSERT_TRUE(expr) \ 87 FOUNDATION_EXPECT_TRUE_IMPL(expr, true) 88 89 90 // 91 // Expect a false boolean expression. 92 // 93 94 #define FOUNDATION_EXPECT_FALSE_IMPL(expr, stop) \ 95 do { \ 96 case_result.signal_assertion_execution(); \ 97 if (expr) \ 98 FOUNDATION_ASSERTION_FAILURE("==", false, expr, stop); \ 99 } while (0) 100 101 #define EXPECT_FALSE(expr) \ 102 FOUNDATION_EXPECT_FALSE_IMPL(expr, false) 103 104 #define ASSERT_FALSE(expr) \ 105 FOUNDATION_EXPECT_FALSE_IMPL(expr, true) 106 107 108 // 109 // Expect exact equality of single objects. 110 // 111 112 #define FOUNDATION_EXPECT_EQ_IMPL(expected, expr, stop) \ 113 do { \ 114 case_result.signal_assertion_execution(); \ 115 if (!((expr) == (expected))) \ 116 FOUNDATION_ASSERTION_FAILURE("==", expected, expr, stop); \ 117 } while (0) 118 119 #define EXPECT_EQ(expected, expr) \ 120 FOUNDATION_EXPECT_EQ_IMPL(expected, expr, false) 121 122 #define ASSERT_EQ(expected, expr) \ 123 FOUNDATION_EXPECT_EQ_IMPL(expected, expr, true) 124 125 126 // 127 // Expect exact equality of C arrays of objects. 128 // 129 130 #define FOUNDATION_EXPECT_ARRAY_EQ_IMPL(expected, expr, stop) \ 131 do { \ 132 case_result.signal_assertion_execution(); \ 133 \ 134 const size_t expected_count__ = countof(expected); \ 135 const size_t expr_count__ = countof(expr); \ 136 \ 137 bool are_equal__ = expected_count__ == expr_count__; \ 138 if (are_equal__) \ 139 { \ 140 for (size_t i__ = 0; i__ < expected_count__; ++i__) \ 141 { \ 142 if (!((expr)[i__] == (expected)[i__])) \ 143 { \ 144 are_equal__ = false; \ 145 break; \ 146 } \ 147 } \ 148 } \ 149 \ 150 if (!are_equal__) \ 151 { \ 152 case_result.signal_assertion_failure(); \ 153 \ 154 foundation::TestListenerHelper::write( \ 155 test_listener, \ 156 current_test_suite__(), \ 157 get_name(), \ 158 __FILE__, \ 159 __LINE__, \ 160 foundation::TestMessage::AssertionFailure, \ 161 "expected: %s == %s\n" \ 162 "received: %s == %s", \ 163 #expr, foundation::to_string((expected), countof(expected)).c_str(), \ 164 #expr, foundation::to_string((expr), countof(expr)).c_str()); \ 165 \ 166 if (stop) \ 167 throw foundation::ExceptionAssertionFailure(); \ 168 } \ 169 } while (0) 170 171 #define EXPECT_ARRAY_EQ(expected, expr) \ 172 FOUNDATION_EXPECT_ARRAY_EQ_IMPL(expected, expr, false) 173 174 #define ASSERT_ARRAY_EQ(expected, expr) \ 175 FOUNDATION_EXPECT_ARRAY_EQ_IMPL(expected, expr, true) 176 177 178 // 179 // Expect exact equality of sequences of objects. 180 // 181 182 #define FOUNDATION_EXPECT_SEQUENCE_EQ_IMPL(count, expected, expr, stop) \ 183 do { \ 184 case_result.signal_assertion_execution(); \ 185 \ 186 bool are_equal__ = true; \ 187 for (size_t i__ = 0; i__ < count; ++i__) \ 188 { \ 189 if (!((expr)[i__] == (expected)[i__])) \ 190 { \ 191 are_equal__ = false; \ 192 break; \ 193 } \ 194 } \ 195 \ 196 if (!are_equal__) \ 197 { \ 198 case_result.signal_assertion_failure(); \ 199 \ 200 foundation::TestListenerHelper::write( \ 201 test_listener, \ 202 current_test_suite__(), \ 203 get_name(), \ 204 __FILE__, \ 205 __LINE__, \ 206 foundation::TestMessage::AssertionFailure, \ 207 "expected: %s == %s\n" \ 208 "received: %s == %s", \ 209 #expr, foundation::to_string((expected), count).c_str(), \ 210 #expr, foundation::to_string((expr), count).c_str()); \ 211 \ 212 if (stop) \ 213 throw foundation::ExceptionAssertionFailure(); \ 214 } \ 215 } while (0) 216 217 #define EXPECT_SEQUENCE_EQ(count, expected, expr) \ 218 FOUNDATION_EXPECT_SEQUENCE_EQ_IMPL(count, expected, expr, false) 219 220 #define ASSERT_SEQUENCE_EQ(count, expected, expr) \ 221 FOUNDATION_EXPECT_SEQUENCE_EQ_IMPL(count, expected, expr, true) 222 223 224 // 225 // Expect exact inequality. 226 // 227 228 #define FOUNDATION_EXPECT_NEQ_IMPL(expected, expr, stop) \ 229 do { \ 230 case_result.signal_assertion_execution(); \ 231 if (!((expr) != (expected))) \ 232 FOUNDATION_ASSERTION_FAILURE("!=", expected, expr, stop); \ 233 } while (0) 234 235 #define EXPECT_NEQ(expected, expr) \ 236 FOUNDATION_EXPECT_NEQ_IMPL(expected, expr, false) 237 238 #define ASSERT_NEQ(expected, expr) \ 239 FOUNDATION_EXPECT_NEQ_IMPL(expected, expr, true) 240 241 242 // 243 // Expect less-than inequality. 244 // 245 246 #define FOUNDATION_EXPECT_LT_IMPL(expected, expr, stop) \ 247 do { \ 248 case_result.signal_assertion_execution(); \ 249 if (!((expr) < (expected))) \ 250 FOUNDATION_ASSERTION_FAILURE("<", expected, expr, stop); \ 251 } while (0) 252 253 #define EXPECT_LT(expected, expr) \ 254 FOUNDATION_EXPECT_LT_IMPL(expected, expr, false) 255 256 #define ASSERT_LT(expected, expr) \ 257 FOUNDATION_EXPECT_LT_IMPL(expected, expr, true) 258 259 260 // 261 // Expect greater-than inequality. 262 // 263 264 #define FOUNDATION_EXPECT_GT_IMPL(expected, expr, stop) \ 265 do { \ 266 case_result.signal_assertion_execution(); \ 267 if (!((expr) > (expected))) \ 268 FOUNDATION_ASSERTION_FAILURE(">", expected, expr, stop); \ 269 } while (0) 270 271 #define EXPECT_GT(expected, expr) \ 272 FOUNDATION_EXPECT_GT_IMPL(expected, expr, false) 273 274 #define ASSERT_GT(expected, expr) \ 275 FOUNDATION_EXPECT_GT_IMPL(expected, expr, true) 276 277 278 // 279 // Expect approximate floating-point equality. 280 // 281 282 #define FOUNDATION_EXPECT_FEQ_IMPL(expected, expr, stop) \ 283 do { \ 284 using namespace foundation; \ 285 case_result.signal_assertion_execution(); \ 286 if (!feq((expr), (expected))) \ 287 FOUNDATION_ASSERTION_FAILURE("==", expected, expr, stop); \ 288 } while (0) 289 290 #define EXPECT_FEQ(expected, expr) \ 291 FOUNDATION_EXPECT_FEQ_IMPL(expected, expr, false) 292 293 #define ASSERT_FEQ(expected, expr) \ 294 FOUNDATION_EXPECT_FEQ_IMPL(expected, expr, true) 295 296 297 // 298 // Expect approximate floating-point equality of C arrays of objects. 299 // 300 301 #define FOUNDATION_EXPECT_ARRAY_FEQ_IMPL(expected, expr, stop) \ 302 do { \ 303 case_result.signal_assertion_execution(); \ 304 \ 305 const size_t expected_count__ = countof(expected); \ 306 const size_t expr_count__ = countof(expr); \ 307 \ 308 bool are_equal__ = expected_count__ == expr_count__; \ 309 if (are_equal__) \ 310 { \ 311 for (size_t i__ = 0; i__ < expected_count__; ++i__) \ 312 { \ 313 if (!feq((expr)[i__], (expected)[i__])) \ 314 { \ 315 are_equal__ = false; \ 316 break; \ 317 } \ 318 } \ 319 } \ 320 \ 321 if (!are_equal__) \ 322 { \ 323 case_result.signal_assertion_failure(); \ 324 \ 325 foundation::TestListenerHelper::write( \ 326 test_listener, \ 327 current_test_suite__(), \ 328 get_name(), \ 329 __FILE__, \ 330 __LINE__, \ 331 foundation::TestMessage::AssertionFailure, \ 332 "expected: %s == %s\n" \ 333 "received: %s == %s", \ 334 #expr, foundation::to_string((expected), countof(expected)).c_str(), \ 335 #expr, foundation::to_string((expr), countof(expr)).c_str()); \ 336 \ 337 if (stop) \ 338 throw foundation::ExceptionAssertionFailure(); \ 339 } \ 340 } while (0) 341 342 #define EXPECT_ARRAY_FEQ(expected, expr) \ 343 FOUNDATION_EXPECT_ARRAY_FEQ_IMPL(expected, expr, false) 344 345 #define ASSERT_ARRAY_FEQ(expected, expr) \ 346 FOUNDATION_EXPECT_ARRAY_FEQ_IMPL(expected, expr, true) 347 348 349 // 350 // Expect approximate floating-point equality of sequences of objects. 351 // 352 353 #define FOUNDATION_EXPECT_SEQUENCE_FEQ_IMPL(count, expected, expr, stop) \ 354 do { \ 355 case_result.signal_assertion_execution(); \ 356 \ 357 bool are_equal__ = true; \ 358 for (size_t i__ = 0; i__ < count; ++i__) \ 359 { \ 360 if (!feq((expr)[i__], (expected)[i__])) \ 361 { \ 362 are_equal__ = false; \ 363 break; \ 364 } \ 365 } \ 366 \ 367 if (!are_equal__) \ 368 { \ 369 case_result.signal_assertion_failure(); \ 370 \ 371 foundation::TestListenerHelper::write( \ 372 test_listener, \ 373 current_test_suite__(), \ 374 get_name(), \ 375 __FILE__, \ 376 __LINE__, \ 377 foundation::TestMessage::AssertionFailure, \ 378 "expected: %s == %s\n" \ 379 "received: %s == %s", \ 380 #expr, foundation::to_string((expected), count).c_str(), \ 381 #expr, foundation::to_string((expr), count).c_str()); \ 382 \ 383 if (stop) \ 384 throw foundation::ExceptionAssertionFailure(); \ 385 } \ 386 } while (0) 387 388 #define EXPECT_SEQUENCE_FEQ(count, expected, expr) \ 389 FOUNDATION_EXPECT_SEQUENCE_FEQ_IMPL(count, expected, expr, false) 390 391 #define ASSERT_SEQUENCE_FEQ(count, expected, expr) \ 392 FOUNDATION_EXPECT_SEQUENCE_FEQ_IMPL(count, expected, expr, true) 393 394 395 // 396 // Expect approximate floating-point equality with custom epsilon value. 397 // 398 399 #define FOUNDATION_EXPECT_FEQ_EPS_IMPL(expected, expr, eps, stop) \ 400 do { \ 401 using namespace foundation; \ 402 case_result.signal_assertion_execution(); \ 403 if (!feq((expr), (expected), (eps))) \ 404 FOUNDATION_ASSERTION_FAILURE("==", expected, expr, stop); \ 405 } while (0) 406 407 #define EXPECT_FEQ_EPS(expected, expr, eps) \ 408 FOUNDATION_EXPECT_FEQ_EPS_IMPL(expected, expr, eps, false) 409 410 #define ASSERT_FEQ_EPS(expected, expr, eps) \ 411 FOUNDATION_EXPECT_FEQ_EPS_IMPL(expected, expr, eps, true) 412 413 414 // 415 // Expect approximate floating-point equality of C arrays of objects with custom epsilon value. 416 // 417 418 #define FOUNDATION_EXPECT_ARRAY_FEQ_EPS_IMPL(expected, expr, eps, stop) \ 419 do { \ 420 case_result.signal_assertion_execution(); \ 421 \ 422 const size_t expected_count__ = countof(expected); \ 423 const size_t expr_count__ = countof(expr); \ 424 \ 425 bool are_equal__ = expected_count__ == expr_count__; \ 426 if (are_equal__) \ 427 { \ 428 for (size_t i__ = 0; i__ < expected_count__; ++i__) \ 429 { \ 430 if (!feq((expr)[i__], (expected)[i__], (eps))) \ 431 { \ 432 are_equal__ = false; \ 433 break; \ 434 } \ 435 } \ 436 } \ 437 \ 438 if (!are_equal__) \ 439 { \ 440 case_result.signal_assertion_failure(); \ 441 \ 442 foundation::TestListenerHelper::write( \ 443 test_listener, \ 444 current_test_suite__(), \ 445 get_name(), \ 446 __FILE__, \ 447 __LINE__, \ 448 foundation::TestMessage::AssertionFailure, \ 449 "expected: %s == %s\n" \ 450 "received: %s == %s", \ 451 #expr, foundation::to_string((expected), countof(expected)).c_str(), \ 452 #expr, foundation::to_string((expr), countof(expr)).c_str()); \ 453 \ 454 if (stop) \ 455 throw foundation::ExceptionAssertionFailure(); \ 456 } \ 457 } while (0) 458 459 #define EXPECT_ARRAY_FEQ_EPS(expected, expr, eps) \ 460 FOUNDATION_EXPECT_ARRAY_FEQ_EPS_IMPL(expected, expr, eps, false) 461 462 #define ASSERT_ARRAY_FEQ_EPS(expected, expr, eps) \ 463 FOUNDATION_EXPECT_ARRAY_FEQ_EPS_IMPL(expected, expr, eps, true) 464 465 466 // 467 // Expect approximate floating-point equality of sequences of objects with custom epsilon value. 468 // 469 470 #define FOUNDATION_EXPECT_SEQUENCE_FEQ_EPS_IMPL(count, expected, expr, eps, stop) \ 471 do { \ 472 case_result.signal_assertion_execution(); \ 473 \ 474 bool are_equal__ = true; \ 475 for (size_t i__ = 0; i__ < count; ++i__) \ 476 { \ 477 if (!feq((expr)[i__], (expected)[i__], (eps))) \ 478 { \ 479 are_equal__ = false; \ 480 break; \ 481 } \ 482 } \ 483 \ 484 if (!are_equal__) \ 485 { \ 486 case_result.signal_assertion_failure(); \ 487 \ 488 foundation::TestListenerHelper::write( \ 489 test_listener, \ 490 current_test_suite__(), \ 491 get_name(), \ 492 __FILE__, \ 493 __LINE__, \ 494 foundation::TestMessage::AssertionFailure, \ 495 "expected: %s == %s\n" \ 496 "received: %s == %s", \ 497 #expr, foundation::to_string((expected), count).c_str(), \ 498 #expr, foundation::to_string((expr), count).c_str()); \ 499 \ 500 if (stop) \ 501 throw foundation::ExceptionAssertionFailure(); \ 502 } \ 503 } while (0) 504 505 #define EXPECT_SEQUENCE_FEQ_EPS(count, expected, expr, eps) \ 506 FOUNDATION_EXPECT_SEQUENCE_FEQ_EPS_IMPL(count, expected, expr, eps, false) 507 508 #define ASSERT_SEQUENCE_FEQ_EPS(count, expected, expr, eps) \ 509 FOUNDATION_EXPECT_SEQUENCE_FEQ_EPS_IMPL(count, expected, expr, eps, true) 510 511 512 // 513 // Expect approximate floating-point inequality. 514 // 515 516 #define FOUNDATION_EXPECT_FNEQ_IMPL(expected, expr, stop) \ 517 do { \ 518 using namespace foundation; \ 519 case_result.signal_assertion_execution(); \ 520 if (feq((expr), (expected))) \ 521 FOUNDATION_ASSERTION_FAILURE("!=", expected, expr, stop); \ 522 } while (0) 523 524 #define EXPECT_FNEQ(expected, expr) \ 525 FOUNDATION_EXPECT_FNEQ_IMPL(expected, expr, false) 526 527 #define ASSERT_FNEQ(expected, expr) \ 528 FOUNDATION_EXPECT_FNEQ_IMPL(expected, expr, true) 529 530 531 // 532 // Expect approximate floating-point inequality with custom epsilon value. 533 // 534 535 #define FOUNDATION_EXPECT_FNEQ_EPS_IMPL(expected, expr, eps, stop) \ 536 do { \ 537 using namespace foundation; \ 538 case_result.signal_assertion_execution(); \ 539 if (feq((expr), (expected), (eps))) \ 540 FOUNDATION_ASSERTION_FAILURE("!=", expected, expr, stop); \ 541 } while (0) 542 543 #define EXPECT_FNEQ_EPS(expected, expr, eps) \ 544 FOUNDATION_EXPECT_FNEQ_EPS_IMPL(expected, expr, eps, false) 545 546 #define ASSERT_FNEQ_EPS(expected, expr, eps) \ 547 FOUNDATION_EXPECT_FNEQ_EPS_IMPL(expected, expr, eps, true) 548 549 550 // 551 // Expect a given exception to be thrown. 552 // 553 554 #define FOUNDATION_EXPECT_EXCEPTION_IMPL(exception, expr, stop) \ 555 do { \ 556 case_result.signal_assertion_execution(); \ 557 \ 558 bool caught_exception__ = false; \ 559 try \ 560 { \ 561 expr; \ 562 } \ 563 catch (const exception&) \ 564 { \ 565 caught_exception__ = true; \ 566 } \ 567 \ 568 if (!caught_exception__) \ 569 { \ 570 case_result.signal_assertion_failure(); \ 571 \ 572 foundation::TestListenerHelper::write( \ 573 test_listener, \ 574 current_test_suite__(), \ 575 get_name(), \ 576 __FILE__, \ 577 __LINE__, \ 578 foundation::TestMessage::AssertionFailure, \ 579 "expected: %s throws exception %s\n" \ 580 "received: no exception", \ 581 #expr, #exception); \ 582 \ 583 if (stop) \ 584 throw foundation::ExceptionAssertionFailure(); \ 585 } \ 586 } while (0) 587 588 #define EXPECT_EXCEPTION(exception, expr) \ 589 FOUNDATION_EXPECT_EXCEPTION_IMPL(exception, expr, false) 590 591 #define ASSERT_EXCEPTION(exception, expr) \ 592 FOUNDATION_EXPECT_EXCEPTION_IMPL(exception, expr, true) 593 594 } // namespace foundation 595