Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide some easy way to compare structs containing float/doubles #73

Closed
obfuscated opened this issue Jun 8, 2017 · 5 comments
Closed

Comments

@obfuscated
Copy link

obfuscated commented Jun 8, 2017

I have Vector3, Color3 and similar classes that I need to test.
They look like:

struct A { float x, y, z; };

I want to be able to use something like the Floating point comparisons to do per component comparisons.
So I want to be able to do:

TEST_CASE("bla") {
   A a(...);
   A b(...);
   CHECK(a==doctest::Approx(b).epsilon(1e-6));
}

The added benefit is that the values of a and b will be visible when the test fails. At the moment I can only do this with a function returning a bool value.

@chambm
Copy link

chambm commented Jul 31, 2017

Have you tried writing a function like:

void checkA(const A& lhs, const B& rhs) {
    CHECK(lhs.x==Approx(rhs.x));
    CHECK(lhs.y==Approx(rhs.y));
    CHECK(lhs.z==Approx(rhs.z));
}

@obfuscated
Copy link
Author

@chambm: It doesn't work, because if the macro fails the error won't be on the line calling checkA, but inside checkA, so it will be really hard to debug this problem only looking at the log.

@chambm
Copy link

chambm commented Aug 1, 2017

How about a macro then?

#define checkA(lhs, rhs) do { \
    CHECK((lhs).x==Approx((rhs).x)); \
    CHECK((lhs).y==Approx((rhs).y)); \
    CHECK((lhs).z==Approx((rhs).z)); \
    } while(false)

@onqtam
Copy link
Member

onqtam commented Aug 3, 2017

I don't see a way for doctest to solve this for user types in a generic way out of the box - I'd recommend using a macro like @chambm suggests.

@onqtam onqtam closed this as completed Aug 3, 2017
@madeso
Copy link

madeso commented Apr 25, 2019

Sorry for necroing, but in catch2, that has the same construction, I implemented a custom templated version of Approx, that's basically calling a global approx_equal function: approx_equal(lhs, rhs, settings); This function has overloads for doubles and floats (the meat of the catch2 Approx implementation), and while I have to overload this function for my custom types like

bool approx_equal(const V& lhs, const V& rhs, const ApproxSettings& s) {
    return approx_equal(lhs.x, rhs.x, s)
        && approx_equal(lhs.y, rhs.y, s)
        && approx_equal(lhs.z, rhs.z, s);
}

it is less macros and I can use the standard CHECK macros and Approx api as usual. Also scales well for compound types that are based on other compound types.

Not sure if doctest support less/greater than operators for Approx like catch2 but I don't use them so they are excluded from my version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants