// http://turtle.sourceforge.net // // Copyright Mathieu Champlon 2008 // // 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 #include #include #include #include #ifdef BOOST_MSVC # pragma warning(push, 0) #endif #include #include #ifdef BOOST_MSVC # pragma warning(pop) #endif #ifndef BOOST_MSVC // this produces an ICE with all versions of MSVC # include # include #endif #include #include #include #include #include #include #include #include // Convention: // "Serializable: Implements operator<<(std::ostream&, ...) // "Streamable": Implements operator<<(mock::stream&, ...) // "Mock Streamable": Implements operator<<(stream&, ...) in namespace mock namespace { template std::string to_string(const T& t) { std::ostringstream s; s << mock::format(t); return s.str(); } template std::string to_string(T* t) { std::ostringstream s; s << mock::format(t); return s.str(); } } // namespace BOOST_AUTO_TEST_CASE(pointer_yields_its_value_when_serialized) { { int i = 0; std::ostringstream s; s << &i; const std::string pointerValue = s.str(); BOOST_CHECK_EQUAL(pointerValue, to_string(&i)); } { const int i = 0; std::ostringstream s; s << &i; const std::string pointerValue = s.str(); BOOST_CHECK_EQUAL(pointerValue, to_string(&i)); } } BOOST_AUTO_TEST_CASE(base_type_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("42", to_string(42)); } BOOST_AUTO_TEST_CASE(booleans_are_serialized_as_bool_alpha) { BOOST_CHECK_EQUAL("true", to_string(true)); BOOST_CHECK_EQUAL("false", to_string(false)); } BOOST_AUTO_TEST_CASE(strings_are_serialized_with_double_quotes) { BOOST_CHECK_EQUAL("\"string\"", to_string("string")); BOOST_CHECK_EQUAL("\"string\"", to_string(std::string("string"))); } BOOST_AUTO_TEST_CASE(null_c_strings_are_serialized_to_nullptr) { const char* const null_str = nullptr; BOOST_CHECK_EQUAL("nullptr", to_string(null_str)); // Note the lack of double quotes in the output, as opposed to when the // string "nullptr" is serialized. } namespace { struct non_serializable {}; } // namespace BOOST_AUTO_TEST_CASE(non_serializable_type_yields_a_question_mark_when_serialized) { BOOST_CHECK_EQUAL("?", to_string(non_serializable())); } namespace { struct serializable {}; std::ostream& operator<<(std::ostream& s, const serializable&) { return s << "serializable"; } } // namespace BOOST_AUTO_TEST_CASE(serializable_type_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("serializable", to_string(serializable())); } namespace { struct streamable {}; BOOST_ATTRIBUTE_UNUSED std::ostream& operator<<(std::ostream& s, const streamable&) { BOOST_FAIL("should not have been called"); return s; } mock::stream& operator<<(mock::stream& s, const streamable&) { return s << "streamable"; } } // namespace BOOST_AUTO_TEST_CASE(streamable_type_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("streamable", to_string(streamable())); } namespace { struct mock_streamable {}; BOOST_ATTRIBUTE_UNUSED std::ostream& operator<<(std::ostream& s, const mock_streamable&) { BOOST_FAIL("should not have been called"); return s; } } // namespace namespace mock { stream& operator<<(stream& s, const mock_streamable&) { return s << "mock_streamable"; } } // namespace mock BOOST_AUTO_TEST_CASE(mock_streamable_type_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("mock_streamable", to_string(mock_streamable())); } namespace { struct derived_from_serializable : serializable {}; } // namespace BOOST_AUTO_TEST_CASE(type_derived_from_serializable_yields_a_question_mark_when_serialized) { #ifdef MOCK_USE_CONVERSIONS BOOST_CHECK_EQUAL("serializable", to_string(derived_from_serializable())); #else BOOST_CHECK_EQUAL("?", to_string(derived_from_serializable())); #endif } namespace { struct derived_from_streamable : streamable {}; } // namespace BOOST_AUTO_TEST_CASE(type_derived_from_streamable_yields_a_question_mark_when_serialized) { #ifdef MOCK_USE_CONVERSIONS BOOST_CHECK_EQUAL("streamable", to_string(derived_from_streamable())); #else BOOST_CHECK_EQUAL("?", to_string(derived_from_streamable())); #endif } namespace { // Class which can be converted to many other types making implicit conversions ambiguous struct ambiguous_convertible { operator float() const; operator int() const; operator serializable() const; operator streamable() const; template operator T() const; }; } // namespace #ifndef MOCK_USE_CONVERSIONS // all this does not compile with conversions activated, which is precisely the purpose of // having this compilation flag namespace { struct convertible_to_base { operator int() const; }; } // namespace BOOST_AUTO_TEST_CASE(type_convertible_to_base_yields_a_question_mark_when_serialized) { BOOST_CHECK_EQUAL("?", to_string(convertible_to_base())); } namespace { struct convertible_to_serializable { operator serializable() const; }; } // namespace BOOST_AUTO_TEST_CASE(type_convertible_to_serializable_yields_a_question_mark_when_serialized) { BOOST_CHECK_EQUAL("?", to_string(convertible_to_serializable())); } namespace { struct convertible_to_streamable { operator streamable() const; }; } // namespace BOOST_AUTO_TEST_CASE(type_convertible_to_streamable_yields_a_question_mark_when_serialized) { BOOST_CHECK_EQUAL("?", to_string(convertible_to_streamable())); } BOOST_AUTO_TEST_CASE(type_ambiguous_convertible_yields_a_question_mark_when_serialized) { BOOST_CHECK_EQUAL("?", to_string(ambiguous_convertible())); } namespace { struct ambiguous_convertible_serializable : public ambiguous_convertible {}; std::ostream& operator<<(std::ostream& s, const ambiguous_convertible_serializable&) { return s << "ambiguous_convertible_serializable"; } } // namespace BOOST_AUTO_TEST_CASE(type_convertible_serializable_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("ambiguous_convertible_serializable", to_string(ambiguous_convertible_serializable())); } #endif // MOCK_USE_CONVERSIONS namespace { struct ambiguous_convertible_streamable : public ambiguous_convertible {}; BOOST_ATTRIBUTE_UNUSED std::ostream& operator<<(std::ostream& s, const ambiguous_convertible_streamable&) { BOOST_FAIL("should not have been called"); return s; } mock::stream& operator<<(mock::stream& s, const ambiguous_convertible_streamable&) { return s << "ambiguous_convertible_streamable"; } } // namespace BOOST_AUTO_TEST_CASE(type_ambiguous_convertible_streamable_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("ambiguous_convertible_streamable", to_string(ambiguous_convertible_streamable())); } namespace { struct ambiguous_convertible_mock_streamable { operator float() const; operator int() const; operator serializable() const; operator streamable() const; template operator T() const; }; BOOST_ATTRIBUTE_UNUSED std::ostream& operator<<(std::ostream& s, const ambiguous_convertible_mock_streamable&) { BOOST_FAIL("should not have been called"); return s; } } // namespace namespace mock { stream& operator<<(stream& s, const ambiguous_convertible_mock_streamable&) { return s << "ambiguous_convertible_mock_streamable"; } } // namespace mock BOOST_AUTO_TEST_CASE(type_ambiguous_convertible_mock_streamable_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("ambiguous_convertible_mock_streamable", to_string(ambiguous_convertible_mock_streamable())); } namespace { template struct template_serializable {}; template std::ostream& operator<<(std::ostream& s, const template_serializable&) { return s << "template_serializable"; } } // namespace BOOST_AUTO_TEST_CASE(template_type_serializable_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("template_serializable", to_string(template_serializable())); } namespace { template struct template_streamable {}; template std::ostream& operator<<(std::ostream& s, const template_streamable&) { BOOST_FAIL("should not have been called"); return s; } template mock::stream& operator<<(mock::stream& s, const template_streamable&) { return s << "template_streamable"; } } // namespace BOOST_AUTO_TEST_CASE(template_template_streamable_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("template_streamable", to_string(template_streamable())); } namespace { template struct template_mock_streamable {}; template std::ostream& operator<<(std::ostream& s, const template_mock_streamable&) { BOOST_FAIL("should not have been called"); return s; } } // namespace namespace mock { template stream& operator<<(stream& s, const template_mock_streamable&) { return s << "template_mock_streamable"; } } // namespace mock BOOST_AUTO_TEST_CASE(template_mock_streamable_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("template_mock_streamable", to_string(template_mock_streamable())); } BOOST_AUTO_TEST_CASE(std_pairs_are_serialized) { BOOST_CHECK_EQUAL("(3,42)", to_string(std::make_pair(3, 42.f))); } BOOST_AUTO_TEST_CASE(boost_shared_ptr_are_serialized) { BOOST_CHECK_NE("?", to_string(boost::shared_ptr())); BOOST_CHECK_NE("?", to_string(boost::shared_ptr(new int(42)))); } BOOST_AUTO_TEST_CASE(boost_weak_ptr_are_serialized) { BOOST_CHECK_NE("?", to_string(boost::weak_ptr(boost::shared_ptr()))); BOOST_CHECK_NE("?", to_string(boost::weak_ptr(boost::shared_ptr(new int(42))))); } BOOST_AUTO_TEST_CASE(std_shared_ptr_are_serialized) { BOOST_CHECK_NE("?", to_string(std::shared_ptr())); BOOST_CHECK_NE("?", to_string(std::shared_ptr(new int(42)))); } BOOST_AUTO_TEST_CASE(std_weak_ptr_are_serialized) { BOOST_CHECK_NE("?", to_string(std::weak_ptr(std::shared_ptr()))); BOOST_CHECK_NE("?", to_string(std::weak_ptr(std::shared_ptr(new int(42))))); } BOOST_AUTO_TEST_CASE(std_unique_ptr_are_serialized) { BOOST_CHECK_NE("?", to_string(std::unique_ptr())); BOOST_CHECK_NE("?", to_string(std::unique_ptr(new int(42)))); } BOOST_AUTO_TEST_CASE(std_deques_are_serialized) { std::deque d; d.push_back(12); d.push_back(42); BOOST_CHECK_EQUAL("(12,42)", to_string(d)); } BOOST_AUTO_TEST_CASE(std_lists_are_serialized) { std::list l; l.push_back(12); l.push_back(42); BOOST_CHECK_EQUAL("(12,42)", to_string(l)); } BOOST_AUTO_TEST_CASE(std_vectors_are_serialized) { std::vector v; v.push_back(12); v.push_back(42); BOOST_CHECK_EQUAL("(12,42)", to_string(v)); } BOOST_AUTO_TEST_CASE(std_maps_are_serialized) { std::map m; m[12] = "15"; m[42] = "46"; BOOST_CHECK_EQUAL("((12,\"15\"),(42,\"46\"))", to_string(m)); } BOOST_AUTO_TEST_CASE(std_multimaps_are_serialized) { std::multimap m; m.insert(std::make_pair(12, "15")); m.insert(std::make_pair(42, "46")); BOOST_CHECK_EQUAL("((12,\"15\"),(42,\"46\"))", to_string(m)); } BOOST_AUTO_TEST_CASE(std_sets_are_serialized) { std::set s; s.insert(12); s.insert(42); BOOST_CHECK_EQUAL("(12,42)", to_string(s)); } BOOST_AUTO_TEST_CASE(std_multisets_are_serialized) { std::multiset s; s.insert(12); s.insert(42); BOOST_CHECK_EQUAL("(12,42)", to_string(s)); } BOOST_AUTO_TEST_CASE(std_deques_of_vectors_are_serialized) { std::deque> v; std::vector v1, v2; v1.push_back(12); v2.push_back(42); v2.push_back(77); v.push_back(v1); v.push_back(v2); BOOST_CHECK_EQUAL("((12),(42,77))", to_string(v)); } BOOST_AUTO_TEST_CASE(std_vectors_of_deques_are_serialized) { std::vector> v; std::deque v1, v2; v1.push_back(12); v2.push_back(42); v2.push_back(77); v.push_back(v1); v.push_back(v2); BOOST_CHECK_EQUAL("((12),(42,77))", to_string(v)); } BOOST_AUTO_TEST_CASE(boost_assign_list_of_are_serialized) { BOOST_CHECK_EQUAL("(12,42)", to_string(boost::assign::list_of(12)(42))); } BOOST_AUTO_TEST_CASE(boost_assign_map_list_of_are_serialized) { BOOST_CHECK_EQUAL("((12,\"16\"),(42,\"43\"))", to_string(boost::assign::map_list_of(12, "16")(42, "43"))); } BOOST_AUTO_TEST_CASE(std_reference_wrappers_are_serialized) { const int i = 3; BOOST_CHECK_EQUAL("3", to_string(std::cref(i))); BOOST_CHECK_EQUAL("\"string\"", to_string(std::cref("string"))); } namespace { void callable_builtin() {} } // namespace BOOST_AUTO_TEST_CASE(callable_builtin_yields_a_question_mark_when_serialized) { BOOST_CHECK_EQUAL("?", to_string(callable_builtin)); BOOST_CHECK_EQUAL("?", to_string(&callable_builtin)); } namespace { struct serialized_using_format {}; std::ostream& operator<<(std::ostream& s, const serialized_using_format&) { return s << mock::format("string"); } } // namespace BOOST_AUTO_TEST_CASE(type_can_use_format_when_serialized) { BOOST_CHECK_EQUAL("\"string\"", to_string(serialized_using_format())); } namespace { struct streamed_using_format {}; mock::stream& operator<<(mock::stream& s, const streamed_using_format&) { return s << mock::format("string"); } } // namespace BOOST_AUTO_TEST_CASE(type_can_use_format_when_streamed) { BOOST_CHECK_EQUAL("\"string\"", to_string(streamed_using_format())); } namespace { struct std_string_streamed {}; mock::stream& operator<<(mock::stream& s, const std_string_streamed&) { return s << std::string("string"); } } // namespace BOOST_AUTO_TEST_CASE(std_string_streamed_is_not_a_container) { BOOST_CHECK_EQUAL("string", to_string(std_string_streamed())); } namespace mock { namespace detail { template struct template_serializable {}; template std::ostream& operator<<(std::ostream& s, const template_serializable&) { return s << "mock::detail::template_serializable"; } }} // namespace mock::detail BOOST_AUTO_TEST_CASE(mock_detail_template_type_serializable_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("mock::detail::template_serializable", to_string(mock::detail::template_serializable())); } namespace mock { namespace detail { template struct template_streamable {}; template std::ostream& operator<<(std::ostream& s, const template_streamable&) { BOOST_FAIL("should not have been called"); return s; } template mock::stream& operator<<(mock::stream& s, const template_streamable&) { return s << "mock::detail::template_streamable"; } }} // namespace mock::detail BOOST_AUTO_TEST_CASE(mock_detail_template_template_streamable_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("mock::detail::template_streamable", to_string(mock::detail::template_streamable())); } BOOST_AUTO_TEST_CASE(unsigned_char_is_serialized_as_int) { BOOST_CHECK_EQUAL(std::to_string(static_cast('a')), to_string('a')); } namespace { bool some_function() { return false; } } // namespace BOOST_AUTO_TEST_CASE(boost_phoenix_functor_yields_question_mark_when_serialized) { BOOST_CHECK_EQUAL("?", to_string(boost::phoenix::bind(&some_function))); BOOST_CHECK_EQUAL("?", to_string(boost::phoenix::arg_names::_1 < 42)); } BOOST_AUTO_TEST_CASE(bind_functor_yields_question_mark_when_serialized) { BOOST_CHECK_EQUAL("?", to_string(boost::bind(&some_function))); BOOST_CHECK_EQUAL("?", to_string(std::bind(&some_function))); } #ifndef BOOST_MSVC // this produces an ICE with all versions of MSVC BOOST_AUTO_TEST_CASE(boost_lambda_functor_yields_question_mark_when_serialized) { BOOST_CHECK_EQUAL("?", to_string(boost::lambda::bind(&some_function))); BOOST_CHECK_EQUAL("?", to_string(boost::lambda::_1 < 42)); } #endif BOOST_AUTO_TEST_CASE(nullptr_is_serialized) { BOOST_CHECK_EQUAL("nullptr", to_string(nullptr)); } BOOST_AUTO_TEST_CASE(mock_boost_optional_yields_its_value_when_serialized) { BOOST_CHECK_EQUAL("7", to_string(boost::optional(7))); BOOST_CHECK_EQUAL("?", to_string(boost::optional(non_serializable()))); BOOST_CHECK_EQUAL("none", to_string(boost::optional())); BOOST_CHECK_EQUAL("none", to_string(boost::optional())); BOOST_CHECK_EQUAL("none", to_string(boost::none)); }