uri_tests.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include <catch2/catch_test_macros.hpp>
  2. #include <fastgltf/types.hpp>
  3. #include <fastgltf/parser.hpp>
  4. #include "gltf_path.hpp"
  5. TEST_CASE("Test basic URIs", "[uri-tests]") {
  6. const fastgltf::URI uri1(std::string_view(""));
  7. REQUIRE(uri1.scheme().empty());
  8. REQUIRE(uri1.path().empty());
  9. std::string_view path = "path/somewhere.xyz";
  10. SECTION("Basic local path") {
  11. const fastgltf::URI uri2(path);
  12. REQUIRE(uri2.scheme().empty());
  13. REQUIRE(uri2.path() == path);
  14. REQUIRE(uri2.isLocalPath());
  15. REQUIRE(uri2.fspath() == path);
  16. }
  17. std::string_view abspath = "/path/somewhere.xyz";
  18. SECTION("File scheme path") {
  19. const std::string_view filePath = "file:/path/somewhere.xyz";
  20. const fastgltf::URI uri3(filePath);
  21. REQUIRE(uri3.scheme() == "file");
  22. REQUIRE(uri3.isLocalPath());
  23. REQUIRE(uri3.path() == abspath);
  24. }
  25. SECTION("File scheme localhost path") {
  26. const std::string_view localhostPath = "file://localhost/path/somewhere.xyz";
  27. const fastgltf::URI uri4(localhostPath);
  28. REQUIRE(uri4.scheme() == "file");
  29. REQUIRE(uri4.path() == abspath);
  30. REQUIRE(!uri4.isLocalPath());
  31. }
  32. }
  33. TEST_CASE("Test generic URIs", "[uri-tests]") {
  34. // These are a bunch of example URIs from https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Example_URIs
  35. const fastgltf::URI uri(std::string_view("https://[email protected]:123/forum/questions/?tag=networking&order=newest#top"));
  36. REQUIRE(uri.scheme() == "https");
  37. REQUIRE(uri.userinfo() == "john.doe");
  38. REQUIRE(uri.host() == "www.example.com");
  39. REQUIRE(uri.port() == "123");
  40. REQUIRE(uri.path() == "/forum/questions/");
  41. REQUIRE(uri.query() == "tag=networking&order=newest");
  42. REQUIRE(uri.fragment() == "top");
  43. const fastgltf::URI uri1(std::string_view("ldap://[2001:db8::7]/c=GB?objectClass?one"));
  44. REQUIRE(uri1.scheme() == "ldap");
  45. REQUIRE(uri1.host() == "2001:db8::7");
  46. REQUIRE(uri1.path() == "/c=GB");
  47. REQUIRE(uri1.query() == "objectClass?one");
  48. const fastgltf::URI uri2(std::string_view("mailto:[email protected]"));
  49. REQUIRE(uri2.scheme() == "mailto");
  50. REQUIRE(uri2.path() == "[email protected]");
  51. const fastgltf::URI uri3(std::string_view("telnet://192.0.2.16:80/"));
  52. REQUIRE(uri3.scheme() == "telnet");
  53. REQUIRE(uri3.host() == "192.0.2.16");
  54. REQUIRE(uri3.port() == "80");
  55. REQUIRE(uri3.path() == "/");
  56. }
  57. TEST_CASE("Test percent decoding", "[uri-tests]") {
  58. std::pmr::string test = "%22 %25";
  59. fastgltf::URI::decodePercents(test);
  60. REQUIRE(test == "\" %");
  61. }
  62. TEST_CASE("Test data URI parsing", "[uri-tests]") {
  63. // This example base64 data is from an example on https://en.wikipedia.org/wiki/Data_URI_scheme.
  64. const std::string_view data = "data:image/png;base64,iVBORw0KGgoAAA"
  65. "ANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4"
  66. "//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU"
  67. "5ErkJggg==";
  68. const fastgltf::URI uri(data);
  69. REQUIRE(uri.scheme() == "data");
  70. REQUIRE(uri.path() == data.substr(5));
  71. }
  72. TEST_CASE("Validate URI copying/moving", "[uri-tests]") {
  73. const std::string_view data = "test.bin";
  74. SECTION("Copy semantics") {
  75. fastgltf::URI uri(data);
  76. REQUIRE(uri.path() == data);
  77. fastgltf::URI uri2(uri);
  78. REQUIRE(uri2.string().data() != uri.string().data());
  79. REQUIRE(uri2.path() == data);
  80. }
  81. SECTION("Move semantics") {
  82. fastgltf::URI uri;
  83. {
  84. fastgltf::URI uri2(data);
  85. uri = std::move(uri2);
  86. REQUIRE(uri2.string().empty());
  87. }
  88. // Test that the values were copied over and that the string views are still valid.
  89. REQUIRE(uri.string() == data);
  90. REQUIRE(uri.path() == uri.string());
  91. }
  92. }
  93. TEST_CASE("Validate escaped/percent-encoded URI", "[uri-tests]") {
  94. const std::string_view gltfString = R"({"images": [{"uri": "grande_sph\u00E8re.png"}]})";
  95. fastgltf::GltfDataBuffer dataBuffer;
  96. dataBuffer.copyBytes((uint8_t*) gltfString.data(), gltfString.size());
  97. fastgltf::Parser parser;
  98. auto asset = parser.loadGLTF(&dataBuffer, "", fastgltf::Options::DontRequireValidAssetMember);
  99. REQUIRE(asset.error() == fastgltf::Error::None);
  100. auto escaped = std::get<fastgltf::sources::URI>(asset->images.front().data);
  101. // This only tests wether the default ctor of fastgltf::URI can handle percent-encoding correctly.
  102. const fastgltf::URI original(std::string_view("grande_sphère.png"));
  103. const fastgltf::URI encoded(std::string_view("grande_sph%C3%A8re.png"));
  104. REQUIRE(original.string() == escaped.uri.string());
  105. REQUIRE(original.string() == encoded.string());
  106. }
  107. TEST_CASE("Test percent-encoded URIs in glTF", "[uri-tests]") {
  108. auto boxWithSpaces = sampleModels / "2.0" / "Box With Spaces" / "glTF";
  109. fastgltf::GltfDataBuffer jsonData;
  110. REQUIRE(jsonData.loadFromFile(boxWithSpaces / "Box With Spaces.gltf"));
  111. fastgltf::Parser parser;
  112. auto asset = parser.loadGLTF(&jsonData, boxWithSpaces);
  113. REQUIRE(asset.error() == fastgltf::Error::None);
  114. REQUIRE(fastgltf::validate(asset.get()) == fastgltf::Error::None);
  115. REQUIRE(asset->images.size() == 3);
  116. auto* image0 = std::get_if<fastgltf::sources::URI>(&asset->images[0].data);
  117. REQUIRE(image0 != nullptr);
  118. REQUIRE(image0->uri.path() == "Normal Map.png");
  119. auto* image1 = std::get_if<fastgltf::sources::URI>(&asset->images[1].data);
  120. REQUIRE(image1 != nullptr);
  121. REQUIRE(image1->uri.path() == "glTF Logo With Spaces.png");
  122. auto* image2 = std::get_if<fastgltf::sources::URI>(&asset->images[2].data);
  123. REQUIRE(image2 != nullptr);
  124. REQUIRE(image2->uri.path() == "Roughness Metallic.png");
  125. auto* buffer0 = std::get_if<fastgltf::sources::URI>(&asset->buffers[0].data);
  126. REQUIRE(buffer0 != nullptr);
  127. REQUIRE(buffer0->uri.path() == "Box With Spaces.bin");
  128. }