selfvalidate_test.cxx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <filesystem>
  4. #include <fstream>
  5. #include <iostream>
  6. #include <curl/curl.h>
  7. #include <jvalidate/adapter.h>
  8. #include <jvalidate/adapters/jsoncpp.h>
  9. #include <jvalidate/enum.h>
  10. #include <jvalidate/schema.h>
  11. #include <jvalidate/status.h>
  12. #include <jvalidate/uri.h>
  13. #include <jvalidate/validator.h>
  14. #include <json/reader.h>
  15. #include <json/value.h>
  16. #include <json/writer.h>
  17. #include "./json_schema_test_suite.h"
  18. using jvalidate::schema::Version;
  19. using testing::Combine;
  20. using testing::TestWithParam;
  21. using testing::Values;
  22. bool load_stream(std::istream & in, Json::Value & out) {
  23. Json::CharReaderBuilder builder;
  24. std::string error;
  25. return Json::parseFromStream(builder, in, &out, &error);
  26. }
  27. bool load_file(std::filesystem::path const & path, Json::Value & out) {
  28. std::ifstream in(path);
  29. return load_stream(in, out);
  30. }
  31. size_t transfer_to_buffer(char * data, size_t size, size_t nmemb, void * userdata) {
  32. std::stringstream & ss = *reinterpret_cast<std::stringstream *>(userdata);
  33. size_t actual_size = size * nmemb;
  34. ss << std::string_view(data, actual_size);
  35. return actual_size;
  36. }
  37. bool load_external_for_test(jvalidate::URI const & uri, Json::Value & out) {
  38. constexpr std::string_view g_fake_url = "localhost:1234/";
  39. if (uri.scheme().starts_with("http") && uri.resource().starts_with(g_fake_url)) {
  40. std::string_view path = uri.resource().substr(g_fake_url.size());
  41. return load_file(JSONSchemaTestSuiteDir() / "remotes" / path, out);
  42. } else if (uri.scheme().starts_with("http")) {
  43. std::stringstream ss;
  44. if (CURL * curl = curl_easy_init(); curl) {
  45. curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
  46. curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  47. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ss);
  48. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &transfer_to_buffer);
  49. CURLcode res = curl_easy_perform(curl);
  50. curl_easy_cleanup(curl);
  51. if (res == CURLE_OK) {
  52. return load_stream(ss, out);
  53. }
  54. }
  55. return false;
  56. } else if (uri.scheme() == "file") {
  57. return load_file(uri.resource(), out);
  58. } else {
  59. return false;
  60. }
  61. }
  62. struct JsonSchema : TestWithParam<std::tuple<Version, std::filesystem::path>> {};
  63. TEST_P(JsonSchema, TestSuite) {
  64. auto const & [version, file] = GetParam();
  65. Json::Value spec;
  66. EXPECT_TRUE(load_file(file, spec));
  67. for (auto const & suite : spec) {
  68. std::cout << "\033[0;32m[ SUITE ] \033[0;0m" << suite["description"].asString() << std::endl;
  69. try {
  70. jvalidate::Schema schema(suite["schema"], version, &load_external_for_test);
  71. for (auto const & test : suite["tests"]) {
  72. try {
  73. std::cout << "\033[0;32m[ CASE ] \033[0;0m " << test["description"].asString()
  74. << std::endl;
  75. EXPECT_THAT(test["data"], ValidatesAgainst(schema, test)) << suite["schema"];
  76. } catch (std::exception const & ex) { ADD_FAILURE() << ex.what() << "\n" << test; }
  77. }
  78. } catch (std::exception const & ex) {
  79. ADD_FAILURE() << "when parsing schema: " << ex.what() << "\n" << suite["schema"];
  80. }
  81. }
  82. }
  83. INSTANTIATE_TEST_SUITE_P(Draft7, JsonSchema,
  84. Combine(Values(Version::Draft07), SchemaTests("draft7")), SchemaTestName);
  85. int main(int argc, char ** argv) {
  86. testing::InitGoogleMock(&argc, argv);
  87. return RUN_ALL_TESTS();
  88. }