Teach Google-Test how to print Eigen Matrix

后端 未结 3 1410
一向
一向 2020-12-24 13:50

Introduction

I am writing tests on Eigen matrices using Google\'s testing framework Google-Mock, as already discussed in another question.

With the followi

3条回答
  •  庸人自扰
    2020-12-24 14:32

    Considering the OPs answer I want to do some clarifications. Unlike the derived solution from the OP I actually wanted to decorate the class instead of using a function wrapper inside the assertion.

    For the sake of simplicity instead of using a google test match predicate I overloaded operator==.

    The Idea

    Instead of using the Eigen class itself we use a wrapper that is a complete replacement of Eigen. So whenever we would create an instance of Eigen we create an instance of WrapEigen instead.

    Because we do not intent to alter the implementation of Eigen derivation is fine.

    Furthermore we want to add functions to the wrapper. I do this here with multiple inheritance of functor like classes named StreamBase and EqualBase. We use CRTP in these functors to get the signatures right.

    In order to save potential typing I used a variadic template constructor in Wrapper. It calls the corresponding base constructor if one exists.

    Working Example

    #include 
    #include 
    #include 
    
    using namespace testing::internal;
    
    struct EigenBase {
        explicit EigenBase(int i) : priv_(i) {}
        friend std::ostream &operator<<(std::ostream &o, const EigenBase &r) {
            o << r.priv_;
            return o;
        }
        friend bool operator==(const EigenBase& a, const EigenBase& b) {
            return a.priv_ == b.priv_;
        }
        int priv_;
    };
    
    struct Eigen : public EigenBase {
        explicit Eigen(int i) : EigenBase(i)  {}
    };
    
    template 
    struct StreamBase {
        typedef T value_type;
        typedef const value_type &const_reference;
    
        friend void PrintTo(const value_type &t, std::ostream *o) {
            *o << static_cast(t);
        }
    };
    
    template 
    struct EqualBase {
        typedef T value_type;
        typedef const T &const_reference;
    
        friend bool operator==(const_reference a, const_reference b) {
            return static_cast(a) 
                == static_cast(b);
        }
    };
    
    template 
    struct Wrapper 
        : public T,
          public StreamBase, U>,
          public EqualBase, U> {
        template 
        Wrapper(Args&&... args) : T(std::forward(args)...) { }
    };
    
    TEST(EigenPrint, t1) {
        Eigen e(10);
        Eigen f(11);
        ASSERT_EQ(e,f); // calls gtest::PrintTo
    }
    
    TEST(WrapEigenPrint, t1) {
        typedef Wrapper WrapEigen;
        WrapEigen e(10);
        WrapEigen f(11);
        ASSERT_EQ(e,f); // calls our own.
    }
    

提交回复
热议问题