simdjson/tests/cast_tester.h

276 lines
11 KiB
C++

#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<T> 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<typename T>
class cast_tester {
public:
bool test_get(element element, T expected = {});
bool test_get(simdjson_result<element> element, T expected = {});
bool test_get_error(element element, error_code expected_error);
bool test_get_error(simdjson_result<element> element, error_code expected_error);
#if SIMDJSON_EXCEPTIONS
bool test_implicit_cast(element element, T expected = {});
bool test_implicit_cast(simdjson_result<element> element, T expected = {});
bool test_implicit_cast_error(element element, error_code expected_error);
bool test_implicit_cast_error(simdjson_result<element> element, error_code expected_error);
#endif // SIMDJSON_EXCEPTIONS
bool test_is(element element, bool expected);
bool test_is(simdjson_result<element> element, bool expected);
bool test_is_error(simdjson_result<element> element, error_code expected_error);
bool test_named_get(element element, T expected = {});
bool test_named_get(simdjson_result<element> element, T expected = {});
bool test_named_get_error(element element, error_code expected_error);
bool test_named_get_error(simdjson_result<element> element, error_code expected_error);
bool test_named_is(element element, bool expected);
bool test_named_is(simdjson_result<element> element, bool expected);
bool test_named_is_error(simdjson_result<element> element, error_code expected_error);
private:
simdjson_result<T> named_get(element element);
simdjson_result<T> named_get(simdjson_result<element> element);
bool named_is(element element);
simdjson_result<bool> named_is(simdjson_result<element> element);
bool assert_equal(const T& expected, const T& actual);
};
template<typename T>
bool cast_tester<T>::test_get(element element, T expected) {
T actual;
error_code error;
error = element.get(actual);
ASSERT_SUCCESS(error);
return assert_equal(actual, expected);
}
template<typename T>
bool cast_tester<T>::test_get(simdjson_result<element> element, T expected) {
T actual;
error_code error;
error = element.get(actual);
ASSERT_SUCCESS(error);
return assert_equal(actual, expected);
}
template<typename T>
bool cast_tester<T>::test_get_error(element element, error_code expected_error) {
T actual;
error_code error;
error = element.get(actual);
ASSERT_EQUAL(error, expected_error);
return true;
}
template<typename T>
bool cast_tester<T>::test_get_error(simdjson_result<element> element, error_code expected_error) {
T actual;
error_code error;
error = element.get(actual);
ASSERT_EQUAL(error, expected_error);
return true;
}
template<typename T>
bool cast_tester<T>::test_named_get(element element, T expected) {
T actual;
auto error = named_get(element).get(actual);
ASSERT_SUCCESS(error);
return assert_equal(actual, expected);
}
template<typename T>
bool cast_tester<T>::test_named_get(simdjson_result<element> element, T expected) {
T actual;
auto error = named_get(element).get(actual);
ASSERT_SUCCESS(error);
return assert_equal(actual, expected);
}
template<typename T>
bool cast_tester<T>::test_named_get_error(element element, error_code expected_error) {
T actual;
auto error = named_get(element).get(actual);
ASSERT_EQUAL(error, expected_error);
return true;
}
template<typename T>
bool cast_tester<T>::test_named_get_error(simdjson_result<element> element, error_code expected_error) {
T actual;
auto error = named_get(element).get(actual);
ASSERT_EQUAL(error, expected_error);
return true;
}
#if SIMDJSON_EXCEPTIONS
template<typename T>
bool cast_tester<T>::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<typename T>
bool cast_tester<T>::test_implicit_cast(simdjson_result<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<typename T>
bool cast_tester<T>::test_implicit_cast_error(element element, error_code expected_error) {
try {
UNUSED T actual;
actual = element;
return false;
} catch(simdjson_error &e) {
ASSERT_EQUAL(e.error(), expected_error);
return true;
}
}
template<typename T>
bool cast_tester<T>::test_implicit_cast_error(simdjson_result<element> element, error_code expected_error) {
try {
UNUSED T actual;
actual = element;
return false;
} catch(simdjson_error &e) {
ASSERT_EQUAL(e.error(), expected_error);
return true;
}
}
template<> bool cast_tester<const char *>::test_implicit_cast(element, const char *) { return true; }
template<> bool cast_tester<const char *>::test_implicit_cast(simdjson_result<element>, const char *) { return true; }
template<> bool cast_tester<const char *>::test_implicit_cast_error(element, error_code) { return true; }
template<> bool cast_tester<const char *>::test_implicit_cast_error(simdjson_result<element>, error_code) { return true; }
#endif // SIMDJSON_EXCEPTIONS
template<typename T>
bool cast_tester<T>::test_is(element element, bool expected) {
ASSERT_EQUAL(element.is<T>(), expected);
return true;
}
template<typename T>
bool cast_tester<T>::test_is(simdjson_result<element> element, bool expected) {
bool actual;
auto error = element.is<T>().get(actual);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual, expected);
return true;
}
template<typename T>
bool cast_tester<T>::test_is_error(simdjson_result<element> element, error_code expected_error) {
UNUSED bool actual;
auto error = element.is<T>().get(actual);
ASSERT_EQUAL(error, expected_error);
return true;
}
template<typename T>
bool cast_tester<T>::test_named_is(element element, bool expected) {
ASSERT_EQUAL(named_is(element), expected);
return true;
}
template<typename T>
bool cast_tester<T>::test_named_is(simdjson_result<element> element, bool expected) {
bool actual;
auto error = named_is(element).get(actual);
ASSERT_SUCCESS(error);
ASSERT_EQUAL(actual, expected);
return true;
}
template<typename T>
bool cast_tester<T>::test_named_is_error(simdjson_result<element> element, error_code expected_error) {
bool actual;
auto error = named_is(element).get(actual);
ASSERT_EQUAL(error, expected_error);
return true;
}
template<> simdjson_result<array> cast_tester<array>::named_get(element element) { return element.get_array(); }
template<> simdjson_result<object> cast_tester<object>::named_get(element element) { return element.get_object(); }
template<> simdjson_result<const char *> cast_tester<const char *>::named_get(element element) { return element.get_c_str(); }
template<> simdjson_result<std::string_view> cast_tester<std::string_view>::named_get(element element) { return element.get_string(); }
template<> simdjson_result<uint64_t> cast_tester<uint64_t>::named_get(element element) { return element.get_uint64_t(); }
template<> simdjson_result<int64_t> cast_tester<int64_t>::named_get(element element) { return element.get_int64_t(); }
template<> simdjson_result<double> cast_tester<double>::named_get(element element) { return element.get_double(); }
template<> simdjson_result<bool> cast_tester<bool>::named_get(element element) { return element.get_bool(); }
template<> simdjson_result<array> cast_tester<array>::named_get(simdjson_result<element> element) { return element.get_array(); }
template<> simdjson_result<object> cast_tester<object>::named_get(simdjson_result<element> element) { return element.get_object(); }
template<> simdjson_result<const char *> cast_tester<const char *>::named_get(simdjson_result<element> element) { return element.get_c_str(); }
template<> simdjson_result<std::string_view> cast_tester<std::string_view>::named_get(simdjson_result<element> element) { return element.get_string(); }
template<> simdjson_result<uint64_t> cast_tester<uint64_t>::named_get(simdjson_result<element> element) { return element.get_uint64_t(); }
template<> simdjson_result<int64_t> cast_tester<int64_t>::named_get(simdjson_result<element> element) { return element.get_int64_t(); }
template<> simdjson_result<double> cast_tester<double>::named_get(simdjson_result<element> element) { return element.get_double(); }
template<> simdjson_result<bool> cast_tester<bool>::named_get(simdjson_result<element> element) { return element.get_bool(); }
template<> bool cast_tester<array>::named_is(element element) { return element.is_array(); }
template<> bool cast_tester<object>::named_is(element element) { return element.is_object(); }
template<> bool cast_tester<const char *>::named_is(element element) { return element.is_string(); }
template<> bool cast_tester<std::string_view>::named_is(element element) { return element.is_string(); }
template<> bool cast_tester<uint64_t>::named_is(element element) { return element.is_uint64_t(); }
template<> bool cast_tester<int64_t>::named_is(element element) { return element.is_int64_t(); }
template<> bool cast_tester<double>::named_is(element element) { return element.is_double(); }
template<> bool cast_tester<bool>::named_is(element element) { return element.is_bool(); }
template<> simdjson_result<bool> cast_tester<array>::named_is(simdjson_result<element> element) { return element.is_array(); }
template<> simdjson_result<bool> cast_tester<object>::named_is(simdjson_result<element> element) { return element.is_object(); }
template<> simdjson_result<bool> cast_tester<const char *>::named_is(simdjson_result<element> element) { return element.is_string(); }
template<> simdjson_result<bool> cast_tester<std::string_view>::named_is(simdjson_result<element> element) { return element.is_string(); }
template<> simdjson_result<bool> cast_tester<uint64_t>::named_is(simdjson_result<element> element) { return element.is_uint64_t(); }
template<> simdjson_result<bool> cast_tester<int64_t>::named_is(simdjson_result<element> element) { return element.is_int64_t(); }
template<> simdjson_result<bool> cast_tester<double>::named_is(simdjson_result<element> element) { return element.is_double(); }
template<> simdjson_result<bool> cast_tester<bool>::named_is(simdjson_result<element> element) { return element.is_bool(); }
template<typename T> bool cast_tester<T>::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<array>::assert_equal(const array&, const array&) {
return true;
}
template<> bool cast_tester<object>::assert_equal(const object&, const object&) {
return true;
}
#endif