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 
9 #include "catch.hpp"
10 
11 ///////////////////////////////////////////////////////////////////////////////
12 TEST_CASE
13 (
14     "Some simple comparisons between doubles",
15     "[Approx]"
16 )
17 {
18     double d = 1.23;
19 
20     REQUIRE( d == Approx( 1.23 ) );
21     REQUIRE( d != Approx( 1.22 ) );
22     REQUIRE( d != Approx( 1.24 ) );
23 
24     REQUIRE( Approx( d ) == 1.23 );
25     REQUIRE( Approx( d ) != 1.22 );
26     REQUIRE( Approx( d ) != 1.24 );
27 }
28 
29 ///////////////////////////////////////////////////////////////////////////////
30 TEST_CASE
31 (
32     "Approximate comparisons with different epsilons",
33     "[Approx]"
34  )
35 {
36     double d = 1.23;
37 
38     REQUIRE( d != Approx( 1.231 ) );
39     REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) );
40 }
41 
42 ///////////////////////////////////////////////////////////////////////////////
43 TEST_CASE
44 (
45  "Less-than inequalities with different epsilons",
46  "[Approx]"
47 )
48 {
49   double d = 1.23;
50 
51   REQUIRE( d <= Approx( 1.24 ) );
52   REQUIRE( d <= Approx( 1.23 ) );
53   REQUIRE_FALSE( d <= Approx( 1.22 ) );
54   REQUIRE( d <= Approx( 1.22 ).epsilon(0.1) );
55 }
56 
57 ///////////////////////////////////////////////////////////////////////////////
58 TEST_CASE
59 (
60  "Greater-than inequalities with different epsilons",
61  "[Approx]"
62 )
63 {
64   double d = 1.23;
65 
66   REQUIRE( d >= Approx( 1.22 ) );
67   REQUIRE( d >= Approx( 1.23 ) );
68   REQUIRE_FALSE( d >= Approx( 1.24 ) );
69   REQUIRE( d >= Approx( 1.24 ).epsilon(0.1) );
70 }
71 
72 ///////////////////////////////////////////////////////////////////////////////
73 TEST_CASE
74 (
75     "Approximate comparisons with floats",
76     "[Approx]"
77 )
78 {
79     REQUIRE( 1.23f == Approx( 1.23f ) );
80     REQUIRE( 0.0f == Approx( 0.0f ) );
81 }
82 
83 ///////////////////////////////////////////////////////////////////////////////
84 TEST_CASE
85 (
86     "Approximate comparisons with ints",
87     "[Approx]"
88 )
89 {
90     REQUIRE( 1 == Approx( 1 ) );
91     REQUIRE( 0 == Approx( 0 ) );
92 }
93 
94 ///////////////////////////////////////////////////////////////////////////////
95 TEST_CASE
96 (
97     "Approximate comparisons with mixed numeric types",
98     "[Approx]"
99 )
100 {
101     const double dZero = 0;
102     const double dSmall = 0.00001;
103     const double dMedium = 1.234;
104 
105     REQUIRE( 1.0f == Approx( 1 ) );
106     REQUIRE( 0 == Approx( dZero) );
107     REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) );
108     REQUIRE( 1.234f == Approx( dMedium ) );
109     REQUIRE( dMedium == Approx( 1.234f ) );
110 }
111 
112 ///////////////////////////////////////////////////////////////////////////////
113 TEST_CASE
114 (
115     "Use a custom approx",
116     "[Approx][custom]"
117 )
118 {
119     double d = 1.23;
120 
121     Approx approx = Approx::custom().epsilon( 0.005 );
122 
123     REQUIRE( d == approx( 1.23 ) );
124     REQUIRE( d == approx( 1.22 ) );
125     REQUIRE( d == approx( 1.24 ) );
126     REQUIRE( d != approx( 1.25 ) );
127 
128     REQUIRE( approx( d ) == 1.23 );
129     REQUIRE( approx( d ) == 1.22 );
130     REQUIRE( approx( d ) == 1.24 );
131     REQUIRE( approx( d ) != 1.25 );
132 }
133 
divide(double a,double b)134 inline double divide( double a, double b ) {
135     return a/b;
136 }
137 
138 TEST_CASE( "Approximate PI", "[Approx][PI]" )
139 {
140     REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) );
141     REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) );
142 }
143 
144 ////////////////////////////////////////////////////////////////////////////////
145 
146 #if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
147 class StrongDoubleTypedef
148 {
149   double d_ = 0.0;
150 
151   public:
StrongDoubleTypedef(double d)152     explicit StrongDoubleTypedef(double d) : d_(d) {}
operator double() const153     explicit operator double() const { return d_; }
154 };
155 
operator <<(std::ostream & os,StrongDoubleTypedef td)156 inline std::ostream& operator<<( std::ostream& os, StrongDoubleTypedef td ) {
157     return os << "StrongDoubleTypedef(" << static_cast<double>(td) << ")";
158 }
159 
160 TEST_CASE
161 (
162  "Comparison with explicitly convertible types",
163  "[Approx]"
164 )
165 {
166   StrongDoubleTypedef td(10.0);
167 
168   REQUIRE(td == Approx(10.0));
169   REQUIRE(Approx(10.0) == td);
170 
171   REQUIRE(td != Approx(11.0));
172   REQUIRE(Approx(11.0) != td);
173 
174   REQUIRE(td <= Approx(10.0));
175   REQUIRE(td <= Approx(11.0));
176   REQUIRE(Approx(10.0) <= td);
177   REQUIRE(Approx(9.0) <= td);
178 
179   REQUIRE(td >= Approx(9.0));
180   REQUIRE(td >= Approx(10.0));
181   REQUIRE(Approx(10.0) >= td);
182   REQUIRE(Approx(11.0) >= td);
183 
184 }
185 #endif
186 
187 ////////////////////////////////////////////////////////////////////////////////
188