Approx.tests.cpp 6.4 KB

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