Approx.tests.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright Catch2 Authors
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // https://www.boost.org/LICENSE_1_0.txt)
  5. // SPDX-License-Identifier: BSL-1.0
  6. #include <catch2/catch_test_macros.hpp>
  7. #include <catch2/catch_approx.hpp>
  8. #include <cmath>
  9. using Catch::Approx;
  10. namespace {
  11. static double divide(double a, double b) {
  12. return a / b;
  13. }
  14. class StrongDoubleTypedef {
  15. double d_ = 0.0;
  16. public:
  17. explicit StrongDoubleTypedef(double d) : d_(d) {}
  18. explicit operator double() const { return d_; }
  19. };
  20. static std::ostream& operator<<(std::ostream& os, StrongDoubleTypedef td) {
  21. return os << "StrongDoubleTypedef(" << static_cast<double>(td) << ")";
  22. }
  23. } // end unnamed namespace
  24. using namespace Catch::literals;
  25. ///////////////////////////////////////////////////////////////////////////////
  26. TEST_CASE( "A comparison that uses literals instead of the normal constructor", "[Approx]" ) {
  27. double d = 1.23;
  28. REQUIRE( d == 1.23_a );
  29. REQUIRE( d != 1.22_a );
  30. REQUIRE( -d == -1.23_a );
  31. REQUIRE( d == 1.2_a .epsilon(.1) );
  32. REQUIRE( d != 1.2_a .epsilon(.001) );
  33. REQUIRE( d == 1_a .epsilon(.3) );
  34. }
  35. TEST_CASE( "Some simple comparisons between doubles", "[Approx]" ) {
  36. double d = 1.23;
  37. REQUIRE( d == Approx( 1.23 ) );
  38. REQUIRE( d != Approx( 1.22 ) );
  39. REQUIRE( d != Approx( 1.24 ) );
  40. REQUIRE( d == 1.23_a );
  41. REQUIRE( d != 1.22_a );
  42. REQUIRE( Approx( d ) == 1.23 );
  43. REQUIRE( Approx( d ) != 1.22 );
  44. REQUIRE( Approx( d ) != 1.24 );
  45. }
  46. ///////////////////////////////////////////////////////////////////////////////
  47. TEST_CASE( "Approximate comparisons with different epsilons", "[Approx]" ) {
  48. double d = 1.23;
  49. REQUIRE( d != Approx( 1.231 ) );
  50. REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) );
  51. }
  52. ///////////////////////////////////////////////////////////////////////////////
  53. TEST_CASE( "Less-than inequalities with different epsilons", "[Approx]" ) {
  54. double d = 1.23;
  55. REQUIRE( d <= Approx( 1.24 ) );
  56. REQUIRE( d <= Approx( 1.23 ) );
  57. REQUIRE_FALSE( d <= Approx( 1.22 ) );
  58. REQUIRE( d <= Approx( 1.22 ).epsilon(0.1) );
  59. }
  60. ///////////////////////////////////////////////////////////////////////////////
  61. TEST_CASE( "Greater-than inequalities with different epsilons", "[Approx]" ) {
  62. double d = 1.23;
  63. REQUIRE( d >= Approx( 1.22 ) );
  64. REQUIRE( d >= Approx( 1.23 ) );
  65. REQUIRE_FALSE( d >= Approx( 1.24 ) );
  66. REQUIRE( d >= Approx( 1.24 ).epsilon(0.1) );
  67. }
  68. ///////////////////////////////////////////////////////////////////////////////
  69. TEST_CASE( "Approximate comparisons with floats", "[Approx]" ) {
  70. REQUIRE( 1.23f == Approx( 1.23f ) );
  71. REQUIRE( 0.0f == Approx( 0.0f ) );
  72. }
  73. ///////////////////////////////////////////////////////////////////////////////
  74. TEST_CASE( "Approximate comparisons with ints", "[Approx]" ) {
  75. REQUIRE( 1 == Approx( 1 ) );
  76. REQUIRE( 0 == Approx( 0 ) );
  77. }
  78. ///////////////////////////////////////////////////////////////////////////////
  79. TEST_CASE( "Approximate comparisons with mixed numeric types", "[Approx]" ) {
  80. const double dZero = 0;
  81. const double dSmall = 0.00001;
  82. const double dMedium = 1.234;
  83. REQUIRE( 1.0f == Approx( 1 ) );
  84. REQUIRE( 0 == Approx( dZero) );
  85. REQUIRE( 0 == Approx( dSmall ).margin( 0.001 ) );
  86. REQUIRE( 1.234f == Approx( dMedium ) );
  87. REQUIRE( dMedium == Approx( 1.234f ) );
  88. }
  89. ///////////////////////////////////////////////////////////////////////////////
  90. TEST_CASE( "Use a custom approx", "[Approx][custom]" ) {
  91. double d = 1.23;
  92. Approx approx = Approx::custom().epsilon( 0.01 );
  93. REQUIRE( d == approx( 1.23 ) );
  94. REQUIRE( d == approx( 1.22 ) );
  95. REQUIRE( d == approx( 1.24 ) );
  96. REQUIRE( d != approx( 1.25 ) );
  97. REQUIRE( approx( d ) == 1.23 );
  98. REQUIRE( approx( d ) == 1.22 );
  99. REQUIRE( approx( d ) == 1.24 );
  100. REQUIRE( approx( d ) != 1.25 );
  101. }
  102. TEST_CASE( "Approximate PI", "[Approx][PI]" ) {
  103. REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) );
  104. REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) );
  105. }
  106. ///////////////////////////////////////////////////////////////////////////////
  107. TEST_CASE( "Absolute margin", "[Approx]" ) {
  108. REQUIRE( 104.0 != Approx(100.0) );
  109. REQUIRE( 104.0 == Approx(100.0).margin(5) );
  110. REQUIRE( 104.0 == Approx(100.0).margin(4) );
  111. REQUIRE( 104.0 != Approx(100.0).margin(3) );
  112. REQUIRE( 100.3 != Approx(100.0) );
  113. REQUIRE( 100.3 == Approx(100.0).margin(0.5) );
  114. }
  115. TEST_CASE("Approx with exactly-representable margin", "[Approx]") {
  116. CHECK( 0.25f == Approx(0.0f).margin(0.25f) );
  117. CHECK( 0.0f == Approx(0.25f).margin(0.25f) );
  118. CHECK( 0.5f == Approx(0.25f).margin(0.25f) );
  119. CHECK( 245.0f == Approx(245.25f).margin(0.25f) );
  120. CHECK( 245.5f == Approx(245.25f).margin(0.25f) );
  121. }
  122. TEST_CASE("Approx setters validate their arguments", "[Approx]") {
  123. REQUIRE_NOTHROW(Approx(0).margin(0));
  124. REQUIRE_NOTHROW(Approx(0).margin(1234656));
  125. REQUIRE_THROWS_AS(Approx(0).margin(-2), std::domain_error);
  126. REQUIRE_NOTHROW(Approx(0).epsilon(0));
  127. REQUIRE_NOTHROW(Approx(0).epsilon(1));
  128. REQUIRE_THROWS_AS(Approx(0).epsilon(-0.001), std::domain_error);
  129. REQUIRE_THROWS_AS(Approx(0).epsilon(1.0001), std::domain_error);
  130. }
  131. TEST_CASE("Default scale is invisible to comparison", "[Approx]") {
  132. REQUIRE(101.000001 != Approx(100).epsilon(0.01));
  133. REQUIRE(std::pow(10, -5) != Approx(std::pow(10, -7)));
  134. }
  135. TEST_CASE("Epsilon only applies to Approx's value", "[Approx]") {
  136. REQUIRE(101.01 != Approx(100).epsilon(0.01));
  137. }
  138. TEST_CASE("Assorted miscellaneous tests", "[Approx][approvals]") {
  139. REQUIRE(INFINITY == Approx(INFINITY));
  140. REQUIRE(-INFINITY != Approx(INFINITY));
  141. REQUIRE(1 != Approx(INFINITY));
  142. REQUIRE(INFINITY != Approx(1));
  143. REQUIRE(NAN != Approx(NAN));
  144. REQUIRE_FALSE(NAN == Approx(NAN));
  145. }
  146. TEST_CASE( "Comparison with explicitly convertible types", "[Approx]" )
  147. {
  148. StrongDoubleTypedef td(10.0);
  149. REQUIRE(td == Approx(10.0));
  150. REQUIRE(Approx(10.0) == td);
  151. REQUIRE(td != Approx(11.0));
  152. REQUIRE(Approx(11.0) != td);
  153. REQUIRE(td <= Approx(10.0));
  154. REQUIRE(td <= Approx(11.0));
  155. REQUIRE(Approx(10.0) <= td);
  156. REQUIRE(Approx(9.0) <= td);
  157. REQUIRE(td >= Approx(9.0));
  158. REQUIRE(td >= Approx(td));
  159. REQUIRE(Approx(td) >= td);
  160. REQUIRE(Approx(11.0) >= td);
  161. }
  162. TEST_CASE("Approx::operator() is const correct", "[Approx][.approvals]") {
  163. const Approx ap = Approx(0.0).margin(0.01);
  164. // As long as this compiles, the test should be considered passing
  165. REQUIRE(1.0 == ap(1.0));
  166. }