| 
									
										
										
										
											2011-04-28 08:28:03 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  Created by Phil on 28/04/2011. | 
					
						
							|  |  |  |  *  Copyright 2011 Two Blue Cubes Ltd. All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Distributed under the Boost Software License, Version 1.0. (See accompanying | 
					
						
							|  |  |  |  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "catch.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 07:30:11 +01:00
										 |  |  | #include <cmath>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | namespace { namespace ApproxTests { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef APPROX_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
 | 
					
						
							|  |  |  | #define APPROX_TEST_HELPERS_INCLUDED
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     inline double divide( double a, double b ) { | 
					
						
							|  |  |  |         return a/b; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class StrongDoubleTypedef { | 
					
						
							|  |  |  |         double d_ = 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         explicit StrongDoubleTypedef(double d) : d_(d) {} | 
					
						
							|  |  |  |         explicit operator double() const { return d_; } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     inline std::ostream& operator<<( std::ostream& os, StrongDoubleTypedef td ) { | 
					
						
							|  |  |  |         return os << "StrongDoubleTypedef(" << static_cast<double>(td) << ")"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 15:42:40 +02:00
										 |  |  | using namespace Catch::literals; | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-28 08:28:03 +01:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2018-05-21 15:42:40 +02:00
										 |  |  | TEST_CASE( "A comparison that uses literals instead of the normal constructor", "[Approx]" ) { | 
					
						
							|  |  |  |     double d = 1.23; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE( d == 1.23_a ); | 
					
						
							|  |  |  |     REQUIRE( d != 1.22_a ); | 
					
						
							|  |  |  |     REQUIRE( -d == -1.23_a ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE( d == 1.2_a .epsilon(.1) ); | 
					
						
							|  |  |  |     REQUIRE( d != 1.2_a .epsilon(.001) ); | 
					
						
							|  |  |  |     REQUIRE( d == 1_a .epsilon(.3) ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | TEST_CASE( "Some simple comparisons between doubles", "[Approx]" ) { | 
					
						
							| 
									
										
										
										
											2011-04-28 08:28:03 +01:00
										 |  |  |     double d = 1.23; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-28 08:28:03 +01:00
										 |  |  |     REQUIRE( d == Approx( 1.23 ) ); | 
					
						
							|  |  |  |     REQUIRE( d != Approx( 1.22 ) ); | 
					
						
							|  |  |  |     REQUIRE( d != Approx( 1.24 ) ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 15:42:40 +02:00
										 |  |  |     REQUIRE( d == 1.23_a ); | 
					
						
							|  |  |  |     REQUIRE( d != 1.22_a ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-28 08:28:03 +01:00
										 |  |  |     REQUIRE( Approx( d ) == 1.23 ); | 
					
						
							|  |  |  |     REQUIRE( Approx( d ) != 1.22 ); | 
					
						
							|  |  |  |     REQUIRE( Approx( d ) != 1.24 ); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-05-24 08:23:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | TEST_CASE( "Approximate comparisons with different epsilons", "[Approx]" ) { | 
					
						
							| 
									
										
										
										
											2011-05-24 08:23:02 +01:00
										 |  |  |     double d = 1.23; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 08:23:02 +01:00
										 |  |  |     REQUIRE( d != Approx( 1.231 ) ); | 
					
						
							|  |  |  |     REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) ); | 
					
						
							| 
									
										
										
										
											2011-06-03 18:56:47 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-24 17:59:23 +01:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | TEST_CASE( "Less-than inequalities with different epsilons", "[Approx]" ) { | 
					
						
							| 
									
										
										
										
											2016-09-24 17:59:23 +01:00
										 |  |  |   double d = 1.23; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE( d <= Approx( 1.24 ) ); | 
					
						
							|  |  |  |   REQUIRE( d <= Approx( 1.23 ) ); | 
					
						
							|  |  |  |   REQUIRE_FALSE( d <= Approx( 1.22 ) ); | 
					
						
							|  |  |  |   REQUIRE( d <= Approx( 1.22 ).epsilon(0.1) ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | TEST_CASE( "Greater-than inequalities with different epsilons", "[Approx]" ) { | 
					
						
							| 
									
										
										
										
											2016-09-24 17:59:23 +01:00
										 |  |  |   double d = 1.23; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE( d >= Approx( 1.22 ) ); | 
					
						
							|  |  |  |   REQUIRE( d >= Approx( 1.23 ) ); | 
					
						
							|  |  |  |   REQUIRE_FALSE( d >= Approx( 1.24 ) ); | 
					
						
							|  |  |  |   REQUIRE( d >= Approx( 1.24 ).epsilon(0.1) ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-03 18:56:47 +01:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | TEST_CASE( "Approximate comparisons with floats", "[Approx]" ) { | 
					
						
							| 
									
										
										
										
											2011-06-03 18:56:47 +01:00
										 |  |  |     REQUIRE( 1.23f == Approx( 1.23f ) ); | 
					
						
							|  |  |  |     REQUIRE( 0.0f == Approx( 0.0f ) ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | TEST_CASE( "Approximate comparisons with ints", "[Approx]" ) { | 
					
						
							| 
									
										
										
										
											2011-06-03 18:56:47 +01:00
										 |  |  |     REQUIRE( 1 == Approx( 1 ) ); | 
					
						
							|  |  |  |     REQUIRE( 0 == Approx( 0 ) ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | TEST_CASE( "Approximate comparisons with mixed numeric types", "[Approx]" ) { | 
					
						
							| 
									
										
										
										
											2011-06-03 18:56:47 +01:00
										 |  |  |     const double dZero = 0; | 
					
						
							|  |  |  |     const double dSmall = 0.00001; | 
					
						
							|  |  |  |     const double dMedium = 1.234; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-03 18:56:47 +01:00
										 |  |  |     REQUIRE( 1.0f == Approx( 1 ) ); | 
					
						
							|  |  |  |     REQUIRE( 0 == Approx( dZero) ); | 
					
						
							| 
									
										
										
										
											2017-11-01 07:30:11 +01:00
										 |  |  |     REQUIRE( 0 == Approx( dSmall ).margin( 0.001 ) ); | 
					
						
							| 
									
										
										
										
											2011-06-03 18:56:47 +01:00
										 |  |  |     REQUIRE( 1.234f == Approx( dMedium ) ); | 
					
						
							|  |  |  |     REQUIRE( dMedium == Approx( 1.234f ) ); | 
					
						
							| 
									
										
										
										
											2011-05-24 08:23:02 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-06-06 08:21:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | TEST_CASE( "Use a custom approx", "[Approx][custom]" ) { | 
					
						
							| 
									
										
										
										
											2011-06-06 08:21:21 +01:00
										 |  |  |     double d = 1.23; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 07:30:11 +01:00
										 |  |  |     Approx approx = Approx::custom().epsilon( 0.01 ); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-06 08:21:21 +01:00
										 |  |  |     REQUIRE( d == approx( 1.23 ) ); | 
					
						
							|  |  |  |     REQUIRE( d == approx( 1.22 ) ); | 
					
						
							|  |  |  |     REQUIRE( d == approx( 1.24 ) ); | 
					
						
							|  |  |  |     REQUIRE( d != approx( 1.25 ) ); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-06 08:21:21 +01:00
										 |  |  |     REQUIRE( approx( d ) == 1.23 ); | 
					
						
							|  |  |  |     REQUIRE( approx( d ) == 1.22 ); | 
					
						
							|  |  |  |     REQUIRE( approx( d ) == 1.24 ); | 
					
						
							|  |  |  |     REQUIRE( approx( d ) != 1.25 ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | TEST_CASE( "Approximate PI", "[Approx][PI]" ) { | 
					
						
							| 
									
										
										
										
											2013-03-04 12:19:15 +01:00
										 |  |  |     REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) ); | 
					
						
							|  |  |  |     REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) ); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-05-12 19:18:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-27 14:15:03 +01:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE( "Absolute margin", "[Approx]" ) { | 
					
						
							|  |  |  |     REQUIRE( 104.0 != Approx(100.0) ); | 
					
						
							|  |  |  |     REQUIRE( 104.0 == Approx(100.0).margin(5) ); | 
					
						
							| 
									
										
										
										
											2017-10-30 15:25:48 +01:00
										 |  |  |     REQUIRE( 104.0 == Approx(100.0).margin(4) ); | 
					
						
							| 
									
										
										
										
											2017-02-27 14:15:03 +01:00
										 |  |  |     REQUIRE( 104.0 != Approx(100.0).margin(3) ); | 
					
						
							|  |  |  |     REQUIRE( 100.3 != Approx(100.0) ); | 
					
						
							|  |  |  |     REQUIRE( 100.3 == Approx(100.0).margin(0.5) ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 15:25:48 +01:00
										 |  |  | TEST_CASE("Approx with exactly-representable margin", "[Approx]") { | 
					
						
							|  |  |  |     CHECK( 0.25f == Approx(0.0f).margin(0.25f) ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CHECK( 0.0f == Approx(0.25f).margin(0.25f) ); | 
					
						
							|  |  |  |     CHECK( 0.5f == Approx(0.25f).margin(0.25f) ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CHECK( 245.0f == Approx(245.25f).margin(0.25f) ); | 
					
						
							|  |  |  |     CHECK( 245.5f == Approx(245.25f).margin(0.25f) ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Approx setters validate their arguments", "[Approx]") { | 
					
						
							|  |  |  |     REQUIRE_NOTHROW(Approx(0).margin(0)); | 
					
						
							|  |  |  |     REQUIRE_NOTHROW(Approx(0).margin(1234656)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE_THROWS_AS(Approx(0).margin(-2), std::domain_error); | 
					
						
							| 
									
										
										
										
											2017-11-01 07:30:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE_NOTHROW(Approx(0).epsilon(0)); | 
					
						
							|  |  |  |     REQUIRE_NOTHROW(Approx(0).epsilon(1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE_THROWS_AS(Approx(0).epsilon(-0.001), std::domain_error); | 
					
						
							|  |  |  |     REQUIRE_THROWS_AS(Approx(0).epsilon(1.0001), std::domain_error); | 
					
						
							| 
									
										
										
										
											2017-10-30 15:25:48 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-01 07:30:11 +01:00
										 |  |  | TEST_CASE("Default scale is invisible to comparison", "[Approx]") { | 
					
						
							|  |  |  |     REQUIRE(101.000001 != Approx(100).epsilon(0.01)); | 
					
						
							|  |  |  |     REQUIRE(std::pow(10, -5) != Approx(std::pow(10, -7))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("Epsilon only applies to Approx's value", "[Approx]") { | 
					
						
							|  |  |  |     REQUIRE(101.01 != Approx(100).epsilon(0.01)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-04 13:23:14 +02:00
										 |  |  | TEST_CASE("Assorted miscellaneous tests", "[Approx][approvals]") { | 
					
						
							| 
									
										
										
										
											2017-11-01 07:30:11 +01:00
										 |  |  |     REQUIRE(INFINITY == Approx(INFINITY)); | 
					
						
							| 
									
										
										
										
											2019-10-04 13:23:14 +02:00
										 |  |  |     REQUIRE(-INFINITY != Approx(INFINITY)); | 
					
						
							|  |  |  |     REQUIRE(1 != Approx(INFINITY)); | 
					
						
							| 
									
										
										
										
											2019-10-04 14:00:34 +02:00
										 |  |  |     REQUIRE(INFINITY != Approx(1)); | 
					
						
							| 
									
										
										
										
											2017-11-10 18:48:45 +01:00
										 |  |  |     REQUIRE(NAN != Approx(NAN)); | 
					
						
							|  |  |  |     REQUIRE_FALSE(NAN == Approx(NAN)); | 
					
						
							| 
									
										
										
										
											2017-11-01 07:30:11 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-05-12 19:18:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-13 08:52:51 +01:00
										 |  |  | TEST_CASE( "Comparison with explicitly convertible types", "[Approx]" ) | 
					
						
							| 
									
										
										
										
											2016-05-12 19:18:44 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   StrongDoubleTypedef td(10.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(td == Approx(10.0)); | 
					
						
							|  |  |  |   REQUIRE(Approx(10.0) == td); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(td != Approx(11.0)); | 
					
						
							|  |  |  |   REQUIRE(Approx(11.0) != td); | 
					
						
							| 
									
										
										
										
											2017-01-26 23:13:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 19:18:44 +01:00
										 |  |  |   REQUIRE(td <= Approx(10.0)); | 
					
						
							|  |  |  |   REQUIRE(td <= Approx(11.0)); | 
					
						
							|  |  |  |   REQUIRE(Approx(10.0) <= td); | 
					
						
							|  |  |  |   REQUIRE(Approx(9.0) <= td); | 
					
						
							| 
									
										
										
										
											2017-01-26 23:13:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 19:18:44 +01:00
										 |  |  |   REQUIRE(td >= Approx(9.0)); | 
					
						
							| 
									
										
										
										
											2017-11-28 21:29:34 +01:00
										 |  |  |   REQUIRE(td >= Approx(td)); | 
					
						
							|  |  |  |   REQUIRE(Approx(td) >= td); | 
					
						
							| 
									
										
										
										
											2016-05-12 19:18:44 +01:00
										 |  |  |   REQUIRE(Approx(11.0) >= td); | 
					
						
							| 
									
										
										
										
											2017-01-26 23:13:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-12 19:18:44 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-11-15 07:48:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | }} // namespace ApproxTests
 |