#ifndef CAST_TESTER_H #define CAST_TESTER_H #include "simdjson.h" #include "test_macros.h" namespace { using simdjson::error_code; using simdjson::simdjson_error; using simdjson::simdjson_result; using simdjson::dom::array; using simdjson::dom::element; using simdjson::dom::object; } // cast_tester tester; // tester.test_implicit(value, [](T value) { return true; }) // tester.test_implicit_error(value, error) // Used to test casts to a type. In the case of const char * in particular, we don't test // implicit casts at all, so that method always returns true. template class cast_tester { public: bool test_get(element element, T expected = {}); bool test_get(simdjson_result element, T expected = {}); bool test_get_error(element element, error_code expected_error); bool test_get_error(simdjson_result element, error_code expected_error); bool test_get_t(element element, T expected = {}); bool test_get_t(simdjson_result element, T expected = {}); bool test_get_t_error(element element, error_code expected_error); bool test_get_t_error(simdjson_result element, error_code expected_error); #if SIMDJSON_EXCEPTIONS bool test_implicit_cast(element element, T expected = {}); bool test_implicit_cast(simdjson_result element, T expected = {}); bool test_implicit_cast_error(element element, error_code expected_error); bool test_implicit_cast_error(simdjson_result element, error_code expected_error); #endif // SIMDJSON_EXCEPTIONS bool test_is(element element, bool expected); bool test_is(simdjson_result element, bool expected); bool test_named_get(element element, T expected = {}); bool test_named_get(simdjson_result element, T expected = {}); bool test_named_get_error(element element, error_code expected_error); bool test_named_get_error(simdjson_result element, error_code expected_error); bool test_named_is(element element, bool expected); bool test_named_is(simdjson_result element, bool expected); private: simdjson_result named_get(element element); simdjson_result named_get(simdjson_result element); bool named_is(element element); bool named_is(simdjson_result element); bool assert_equal(const T& expected, const T& actual); }; template bool cast_tester::test_get(element element, T expected) { T actual; ASSERT_SUCCESS(element.get(actual)); return assert_equal(actual, expected); } template bool cast_tester::test_get(simdjson_result element, T expected) { T actual; ASSERT_SUCCESS(element.get(actual)); return assert_equal(actual, expected); } template bool cast_tester::test_get_error(element element, error_code expected_error) { T actual; ASSERT_EQUAL(element.get(actual), expected_error); return true; } template bool cast_tester::test_get_error(simdjson_result element, error_code expected_error) { T actual; ASSERT_EQUAL(element.get(actual), expected_error); return true; } template bool cast_tester::test_get_t(element element, T expected) { auto actual = element.get(); ASSERT_SUCCESS(actual.error()); return assert_equal(actual.first, expected); } template bool cast_tester::test_get_t(simdjson_result element, T expected) { auto actual = element.get(); ASSERT_SUCCESS(actual.error()); return assert_equal(actual.first, expected); } template bool cast_tester::test_get_t_error(element element, error_code expected_error) { ASSERT_EQUAL(element.get().error(), expected_error); return true; } template bool cast_tester::test_get_t_error(simdjson_result element, error_code expected_error) { ASSERT_EQUAL(element.get().error(), expected_error); return true; } template bool cast_tester::test_named_get(element element, T expected) { T actual; ASSERT_SUCCESS(named_get(element).get(actual)); return assert_equal(actual, expected); } template bool cast_tester::test_named_get(simdjson_result element, T expected) { T actual; ASSERT_SUCCESS(named_get(element).get(actual)); return assert_equal(actual, expected); } template bool cast_tester::test_named_get_error(element element, error_code expected_error) { T actual; ASSERT_EQUAL(named_get(element).get(actual), expected_error); return true; } template bool cast_tester::test_named_get_error(simdjson_result element, error_code expected_error) { T actual; ASSERT_EQUAL(named_get(element).get(actual), expected_error); return true; } #if SIMDJSON_EXCEPTIONS template bool cast_tester::test_implicit_cast(element element, T expected) { T actual; try { actual = element; } catch(simdjson_error &e) { std::cerr << e.error() << std::endl; return false; } return assert_equal(actual, expected); } template bool cast_tester::test_implicit_cast(simdjson_result element, T expected) { T actual; try { actual = element; } catch(simdjson_error &e) { std::cerr << e.error() << std::endl; return false; } return assert_equal(actual, expected); } template bool cast_tester::test_implicit_cast_error(element element, error_code expected_error) { try { simdjson_unused T actual; actual = element; return false; } catch(simdjson_error &e) { ASSERT_EQUAL(e.error(), expected_error); return true; } } template bool cast_tester::test_implicit_cast_error(simdjson_result element, error_code expected_error) { try { simdjson_unused T actual; actual = element; return false; } catch(simdjson_error &e) { ASSERT_EQUAL(e.error(), expected_error); return true; } } template<> bool cast_tester::test_implicit_cast(element, const char *) { return true; } template<> bool cast_tester::test_implicit_cast(simdjson_result, const char *) { return true; } template<> bool cast_tester::test_implicit_cast_error(element, error_code) { return true; } template<> bool cast_tester::test_implicit_cast_error(simdjson_result, error_code) { return true; } #endif // SIMDJSON_EXCEPTIONS template bool cast_tester::test_is(element element, bool expected) { ASSERT_EQUAL(element.is(), expected); return true; } template bool cast_tester::test_is(simdjson_result element, bool expected) { ASSERT_EQUAL(element.is(), expected); return true; } template bool cast_tester::test_named_is(element element, bool expected) { ASSERT_EQUAL(named_is(element), expected); return true; } template bool cast_tester::test_named_is(simdjson_result element, bool expected) { ASSERT_EQUAL(named_is(element), expected); return true; } template<> simdjson_result cast_tester::named_get(element element) { return element.get_array(); } template<> simdjson_result cast_tester::named_get(element element) { return element.get_object(); } template<> simdjson_result cast_tester::named_get(element element) { return element.get_c_str(); } template<> simdjson_result cast_tester::named_get(element element) { return element.get_string(); } template<> simdjson_result cast_tester::named_get(element element) { return element.get_uint64(); } template<> simdjson_result cast_tester::named_get(element element) { return element.get_int64(); } template<> simdjson_result cast_tester::named_get(element element) { return element.get_double(); } template<> simdjson_result cast_tester::named_get(element element) { return element.get_bool(); } template<> simdjson_result cast_tester::named_get(simdjson_result element) { return element.get_array(); } template<> simdjson_result cast_tester::named_get(simdjson_result element) { return element.get_object(); } template<> simdjson_result cast_tester::named_get(simdjson_result element) { return element.get_c_str(); } template<> simdjson_result cast_tester::named_get(simdjson_result element) { return element.get_string(); } template<> simdjson_result cast_tester::named_get(simdjson_result element) { return element.get_uint64(); } template<> simdjson_result cast_tester::named_get(simdjson_result element) { return element.get_int64(); } template<> simdjson_result cast_tester::named_get(simdjson_result element) { return element.get_double(); } template<> simdjson_result cast_tester::named_get(simdjson_result element) { return element.get_bool(); } template<> bool cast_tester::named_is(element element) { return element.is_array(); } template<> bool cast_tester::named_is(element element) { return element.is_object(); } template<> bool cast_tester::named_is(element element) { return element.is_string(); } template<> bool cast_tester::named_is(element element) { return element.is_string(); } template<> bool cast_tester::named_is(element element) { return element.is_uint64(); } template<> bool cast_tester::named_is(element element) { return element.is_int64(); } template<> bool cast_tester::named_is(element element) { return element.is_double(); } template<> bool cast_tester::named_is(element element) { return element.is_bool(); } template<> bool cast_tester::named_is(simdjson_result element) { return element.is_array(); } template<> bool cast_tester::named_is(simdjson_result element) { return element.is_object(); } template<> bool cast_tester::named_is(simdjson_result element) { return element.is_string(); } template<> bool cast_tester::named_is(simdjson_result element) { return element.is_string(); } template<> bool cast_tester::named_is(simdjson_result element) { return element.is_uint64(); } template<> bool cast_tester::named_is(simdjson_result element) { return element.is_int64(); } template<> bool cast_tester::named_is(simdjson_result element) { return element.is_double(); } template<> bool cast_tester::named_is(simdjson_result element) { return element.is_bool(); } template bool cast_tester::assert_equal(const T& expected, const T& actual) { ASSERT_EQUAL(expected, actual); return true; } // We don't actually check equality for objects and arrays, just check that they actually cast template<> bool cast_tester::assert_equal(const array&, const array&) { return true; } template<> bool cast_tester::assert_equal(const object&, const object&) { return true; } #endif