json_schema_test_suite.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include <filesystem>
  2. #include <gmock/gmock.h>
  3. #include <jvalidate/enum.h>
  4. #include <jvalidate/validation_result.h>
  5. #include <jvalidate/validator.h>
  6. using SchemaParams = std::tuple<jvalidate::schema::Version, std::filesystem::path>;
  7. #if !defined(JVALIDATE_JSON_SCHEMA_TEST_SUITE_DIR)
  8. inline std::filesystem::path const & JSONSchemaTestSuiteDir() {
  9. static auto const g_root =
  10. std::filesystem::path(__FILE__).parent_path().parent_path().parent_path();
  11. static auto const g_path = g_root / "thirdparty" / "JSON-Schema-Test-Suite";
  12. return g_path;
  13. }
  14. #else
  15. inline std::filesystem::path const & JSONSchemaTestSuiteDir() {
  16. static std::filesystem::path const g_path = JVALIDATE_JSON_SCHEMA_TEST_SUITE_DIR;
  17. return g_path;
  18. }
  19. #endif
  20. inline std::string to_string(jvalidate::schema::Version version) {
  21. std::stringstream ss;
  22. ss << version;
  23. return ss.str();
  24. }
  25. inline auto SchemaTests(jvalidate::schema::Version version) {
  26. struct FsIterator : std::filesystem::recursive_directory_iterator {
  27. using super = std::filesystem::recursive_directory_iterator;
  28. using value_type = SchemaParams;
  29. using reference = SchemaParams;
  30. FsIterator() = default;
  31. explicit FsIterator(jvalidate::schema::Version version)
  32. : super(JSONSchemaTestSuiteDir() / "tests" / to_string(version)), version(version) {}
  33. SchemaParams operator*() const { return std::make_tuple(version, super::operator*().path()); }
  34. FsIterator operator++() {
  35. super::operator++();
  36. while (*this != FsIterator() && super::operator*().is_directory()) {
  37. super::operator++();
  38. }
  39. return *this;
  40. }
  41. jvalidate::schema::Version version;
  42. };
  43. return testing::ValuesIn(FsIterator(version), FsIterator());
  44. }
  45. static auto const SchemaTestName = [](auto const & info) {
  46. auto [version, file] = info.param;
  47. auto base = JSONSchemaTestSuiteDir() / "tests" / to_string(version);
  48. std::string name = std::filesystem::relative(file, base);
  49. name = name.substr(0, name.rfind('.'));
  50. std::transform(name.begin(), name.end(), name.begin(),
  51. [](char chr) { return std::isalnum(chr) ? chr : '_'; });
  52. return name;
  53. };
  54. MATCHER_P(ValidatesAgainst, schema, "") {
  55. jvalidate::ValidationResult result;
  56. bool valid = jvalidate::Validator(schema).validate(arg, &result);
  57. *result_listener << result;
  58. return valid;
  59. }
  60. template <typename T>
  61. testing::Matcher<T> ValidatesAgainst(jvalidate::Schema const & schema, T const & test) {
  62. if (not jvalidate::adapter::AdapterFor<T const>(test)["valid"].as_boolean()) {
  63. return testing::Not(ValidatesAgainst(std::cref(schema)));
  64. }
  65. return ValidatesAgainst(std::cref(schema));
  66. }