json_schema_test_suite.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. inline std::filesystem::path const & JSONSchemaTestSuiteDir() {
  8. static auto const g_root =
  9. std::filesystem::path(__FILE__).parent_path().parent_path().parent_path();
  10. static auto const g_path = g_root / "thirdparty" / "JSON-Schema-Test-Suite";
  11. return g_path;
  12. }
  13. inline std::string to_string(jvalidate::schema::Version version) {
  14. std::stringstream ss;
  15. ss << version;
  16. return ss.str();
  17. }
  18. inline auto SchemaTests(jvalidate::schema::Version version) {
  19. struct fs_iterator : std::filesystem::recursive_directory_iterator {
  20. using super = std::filesystem::recursive_directory_iterator;
  21. using value_type = SchemaParams;
  22. using reference = SchemaParams;
  23. fs_iterator() = default;
  24. explicit fs_iterator(jvalidate::schema::Version version)
  25. : super(JSONSchemaTestSuiteDir() / "tests" / to_string(version)), version(version) {}
  26. SchemaParams operator*() const { return std::make_tuple(version, super::operator*().path()); }
  27. fs_iterator operator++() {
  28. do {
  29. super::operator++();
  30. } while (*this != fs_iterator() && super::operator*().is_directory());
  31. return *this;
  32. }
  33. jvalidate::schema::Version version;
  34. };
  35. return testing::ValuesIn(fs_iterator(version), fs_iterator());
  36. }
  37. static auto SchemaTestName = [](auto const & info) {
  38. auto [version, file] = info.param;
  39. auto base = JSONSchemaTestSuiteDir() / "tests" / to_string(version);
  40. std::string name = std::filesystem::relative(file, base);
  41. name = name.substr(0, name.rfind('.'));
  42. std::transform(name.begin(), name.end(), name.begin(),
  43. [](char c) { return std::isalnum(c) ? c : '_'; });
  44. return name;
  45. };
  46. MATCHER_P2(ValidatesAgainst, schema, format, "") {
  47. jvalidate::ValidationResult result;
  48. bool valid = jvalidate::Validator(schema, {.validate_format = format}).validate(arg, &result);
  49. *result_listener << result;
  50. return valid;
  51. }
  52. template <typename T>
  53. testing::Matcher<T> ValidatesAgainst(jvalidate::Schema const & schema, T const & test,
  54. bool format) {
  55. if (not jvalidate::adapter::AdapterFor<T const>(test)["valid"].as_boolean()) {
  56. return testing::Not(ValidatesAgainst(std::cref(schema), format));
  57. }
  58. return ValidatesAgainst(std::cref(schema), format);
  59. }