Giter Site home page Giter Site logo

Comments (3)

eranpeer avatar eranpeer commented on June 14, 2024

Thanks, did you try to build the tests project? It doesn't compile. I'll be happy to include your improvement after the test project pass compilation & all tests pass.

1>c:\users\eran\projects\fakeit\include\mockutils\formatter.hpp(20): error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const A' (or there is no acceptable conversion)
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(498): could be 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(std::basic_streambuf<char,std::char_traits> *)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(478): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(const void *)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(458): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(long double)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(438): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(double)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(418): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(float)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(397): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(unsigned __int64)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(377): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(__int64)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(356): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(unsigned long)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(336): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(long)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(316): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(unsigned int)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(291): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(int)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(271): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(unsigned short)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(237): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(short)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(217): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(std::_Bool)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(210): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(std::ios_base &(__cdecl *)(std::ios_base &))'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(203): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(std::basic_ios<char,std::char_traits> &(__cdecl *)(std::basic_ios<char,std::char_traits> &))'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(197): or 'std::basic_ostream<char,std::char_traits> &std::basic_ostream<char,std::char_traits>::operator <<(std::basic_ostream<char,std::char_traits> &(__cdecl *)(std::basic_ostream<char,std::char_traits> &))'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(699): or 'std::basic_ostream<char,std::char_traits> &std::operator <<<char,std::char_traits>(std::basic_ostream<char,std::char_traits> &,const char *)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(746): or 'std::basic_ostream<char,std::char_traits> &std::operator <<<char,std::char_traits>(std::basic_ostream<char,std::char_traits> &,char)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(784): or 'std::basic_ostream<char,std::char_traits> &std::operator <<std::char_traits(std::basic_ostream<char,std::char_traits> &,const char *)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(831): or 'std::basic_ostream<char,std::char_traits> &std::operator <<std::char_traits(std::basic_ostream<char,std::char_traits> &,char)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(957): or 'std::basic_ostream<char,std::char_traits> &std::operator <<std::char_traits(std::basic_ostream<char,std::char_traits> &,const signed char *)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(964): or 'std::basic_ostream<char,std::char_traits> &std::operator <<std::char_traits(std::basic_ostream<char,std::char_traits> &,signed char)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(971): or 'std::basic_ostream<char,std::char_traits> &std::operator <<std::char_traits(std::basic_ostream<char,std::char_traits> &,const unsigned char *)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(978): or 'std::basic_ostream<char,std::char_traits> &std::operator <<std::char_traits(std::basic_ostream<char,std::char_traits> &,unsigned char)'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(988): or 'std::basic_ostream<char,std::char_traits> &std::operator <<<char,std::char_traits,A>(std::basic_ostream<char,std::char_traits> &&,const _Ty &)'
1> with
1> [
1> _Ty=A
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\ostream(1026): or 'std::basic_ostream<char,std::char_traits> &std::operator <<<char,std::char_traits>(std::basic_ostream<char,std::char_traits> &,const std::error_code &)'
1> while trying to match the argument list '(std::ostream, const A)'
1> c:\users\eran\projects\fakeit\include\mockutils\tupleprinter.hpp(30) : see reference to class template instantiation 'fakeit::Formatter<const A &>' being compiled
1> c:\users\eran\projects\fakeit\include\mockutils\tupleprinter.hpp(29) : while compiling class template member function 'void fakeit::TuplePrinter<const std::tuple<const A &> &,1>::print(std::ostream &,Tuple)'
1> with
1> [
1> Tuple=const std::tuple<const A &> &
1> ]
1> c:\users\eran\projects\fakeit\include\mockutils\tupleprinter.hpp(43) : see reference to function template instantiation 'void fakeit::TuplePrinter<const std::tuple<const A &> &,1>::print(std::ostream &,Tuple)' being compiled
1> with
1> [
1> Tuple=const std::tuple<const A &> &
1> ]
1> c:\users\eran\projects\fakeit\include\mockutils\tupleprinter.hpp(43) : see reference to class template instantiation 'fakeit::TuplePrinter<const std::tuple<const A &> &,1>' being compiled
1> c:\users\eran\projects\fakeit\include\fakeit\actualinvocation.hpp(77) : see reference to function template instantiation 'void fakeit::print<const A&>(std::ostream &,const std::tuple<const A &> &)' being compiled
1> c:\users\eran\projects\fakeit\include\fakeit\actualinvocation.hpp(74) : while compiling class template member function 'std::string fakeit::ActualInvocation<const A &>::format(void) const'
1> c:\users\eran\projects\fakeit\include\fakeit\methodmockingcontext.hpp(78) : see reference to class template instantiation 'fakeit::ActualInvocation<const A &>' being compiled
1> c:\users\eran\projects\fakeit\include\fakeit\methodmockingcontext.hpp(185) : see reference to class template instantiation 'fakeit::MethodMockingContext<void,const A &>::Implementation' being compiled
1> c:\users\eran\projects\fakeit\include\fakeit\methodmockingcontext.hpp(184) : while compiling class template member function 'std::string fakeit::MethodMockingContext<void,const A &>::format(void) const'
1> c:\users\eran\projects\fakeit\include\fakeit\methodmockingcontext.hpp(337) : see reference to class template instantiation 'fakeit::MethodMockingContext<void,const A &>' being compiled
1> c:\users\eran\projects\fakeit\tests\verification_tests.cpp(325) : see reference to class template instantiation 'fakeit::MockingContext<void,const A &>' being compiled

from fakeit.

coombez avatar coombez commented on June 14, 2024

I'm not sure of the best way to submit a patch. I'm used to git, but not github, so I'm just pasting it right here... hopefully that will work ok. This passes all tests on GCC. My first implementation did a poor job of trying to use sfinae.

I changed the two specializations of Formatter, but really just defining an operator<< for class 'A' would probably be more convenient now. I don't know if you considered the Formatter part of your interface with the expectation that users would specialize. If so, I've broken this interface with this patch, but that could probably be massaged if necessary.

diff --git a/include/mockutils/Formatter.hpp b/include/mockutils/Formatter.hpp
index 7946712..a048413 100644
--- a/include/mockutils/Formatter.hpp
+++ b/include/mockutils/Formatter.hpp
@@ -10,92 +10,58 @@
 #include <ostream>
 #include <type_traits>
 #include <string>
-#include "mockutils/to_string.hpp"

 namespace fakeit {

-    template<class T>
-    struct Formatter {
-        static std::string format(const T &val) {
-            if (std::is_const<T>::value)
-                return Formatter<typename std::remove_const<T>::type>::format(val);
-            if (std::is_reference<T>::value)
-                return Formatter<typename std::remove_reference<T>::type>::format(val);
-            if (std::is_volatile<T>::value)
-                return Formatter<typename std::remove_volatile<T>::type>::format(val);
+template <typename T>
+class is_ostreamable
+{
+  struct no {};
+  template <typename T1>
+  static auto test(std::ostream &s, const T1 &t) -> decltype(s << t);
+  static no test(...);
+public:
+  static const bool value = std::is_same<decltype(test(*(std::ostream *)nullptr,
+      std::declval<T>())),std::ostream &>::value;
+};

-            return {"?"};
-        }
-    };

-    template<>
-    struct Formatter<bool> {
-        static std::string format(const bool &val) {
-            return val ? "true" : "false";
-        }
-    };
+template <typename T, bool streamable>
+struct FormatterImpl
+{
+  static std::string format(T const &)
+  {
+    return "?";
+  }
+};

-    template<>
-    struct Formatter<int> {
-        static std::string format(const int &val) {
-            return fakeit::to_string(val);
-        }
-    };
+template <typename T>
+struct FormatterImpl<T, true>
+{
+  static std::string format(T const &val)
+  {
+    std::ostringstream os;
+    os << val;
+    return os.str();
+  }
+};

-    template<>
-    struct Formatter<unsigned int> {
-        static std::string format(const unsigned int &val) {
-            return fakeit::to_string(val);
-        }
-    };
+template <>
+struct FormatterImpl<bool, true>
+{
+  static std::string format(bool const &val)
+  {
+    return val ? "true" : "false";
+  }
+};

-    template<>
-    struct Formatter<long> {
-        static std::string format(const long &val) {
-            return fakeit::to_string(val);
-        }
-    };
-
-    template<>
-    struct Formatter<unsigned long> {
-        static std::string format(const unsigned long &val) {
-            return fakeit::to_string(val);
-        }
-    };
-
-    template<>
-    struct Formatter<long long> {
-        static std::string format(const long long &val) {
-            return fakeit::to_string(val);
-        }
-    };
-
-    template<>
-    struct Formatter<unsigned long long> {
-        static std::string format(const unsigned long long &val) {
-            return fakeit::to_string(val);
-        }
-    };
-
-    template<>
-    struct Formatter<double> {
-        static std::string format(const double &val) {
-            return fakeit::to_string(val);
-        }
-    };
-
-    template<>
-    struct Formatter<long double> {
-        static std::string format(const long double &val) {
-            return fakeit::to_string(val);
-        }
-    };
-
-    template<>
-    struct Formatter<float> {
-        static std::string format(const float &val) {
-            return fakeit::to_string(val);
-        }
-    };
+template <typename T>
+using Formatter = FormatterImpl<
+  typename std::remove_volatile<
+    typename std::remove_const<
+      typename std::remove_reference<T>::type
+      >::type
+    >::type, is_ostreamable<T>::value
+  >;

 }
diff --git a/tests/default_event_formatting_tests.cpp b/tests/default_event_formatting_tests.cpp
index 3ad2728..be55865 100644
--- a/tests/default_event_formatting_tests.cpp
+++ b/tests/default_event_formatting_tests.cpp
@@ -217,7 +217,7 @@ struct DefaultEventFormatting: tpunit::TestFixture {
            expectedMsg += "Actual matches  : 1\n";
            expectedMsg += "Actual sequence : total of 1 actual invocations:\n";
            //expectedMsg += "  mock.all_types(?, true, 1, 1, 1, 1, 1, 1, 1.000000, 1.000000)";
-           expectedMsg += "  mock.all_types(?, true, 1, 1, 1, 1, 0, 0)";
+           expectedMsg += "  mock.all_types(a, true, 1, 1, 1, 1, 0, 0)";

            std::string actualMsg {to_string(e)};
            std::cout << actualMsg;
@@ -240,7 +240,7 @@ struct DefaultEventFormatting: tpunit::TestFixture {
             std::string expectedMsg{ formatLineNumner("test file", 1) };
             expectedMsg += ": Verification error\n";
            //expectedMsg += "Expected pattern: mock.all_types('a', true, 1, 1, 1, 1, 1.000000)\n";
-           expectedMsg += "Expected pattern: mock.all_types(?, true, 1, 1, 1, 1, 0, 0)\n";
+           expectedMsg += "Expected pattern: mock.all_types(a, true, 1, 1, 1, 1, 0, 0)\n";
            expectedMsg += "Expected matches: exactly 2\n";
            expectedMsg += "Actual matches  : 0\n";
            expectedMsg += "Actual sequence : total of 0 actual invocations.";
diff --git a/tests/verification_errors_tests.cpp b/tests/verification_errors_tests.cpp
index 099898a..df328c5 100644
--- a/tests/verification_errors_tests.cpp
+++ b/tests/verification_errors_tests.cpp
@@ -26,7 +26,7 @@ struct A {
 };

 namespace fakeit {
-template<> struct Formatter<A> {
+template<> struct FormatterImpl<A, false> {
    static std::string format(const A&) {
        return {"a"};
    }
diff --git a/tests/verification_tests.cpp b/tests/verification_tests.cpp
index a20d5fa..9773400 100644
--- a/tests/verification_tests.cpp
+++ b/tests/verification_tests.cpp
@@ -28,7 +28,7 @@ struct A {
 };

 namespace fakeit {
-template<> struct Formatter<A> {
+template<> struct FormatterImpl<A, false> {
    static std::string format(const A&) {
        return {"a"};
    }

from fakeit.

eranpeer avatar eranpeer commented on June 14, 2024

Thanks you for the suggestion and the solution. I used most of your code but changed it a little in order to keep the backwards compatibility. You can pull the latest version.
Enjoy!

from fakeit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.