154 lines
5.8 KiB
C++
154 lines
5.8 KiB
C++
#include <catch2/catch_test_macros.hpp>
|
|
|
|
#include <fastgltf/types.hpp>
|
|
#include <fastgltf/parser.hpp>
|
|
|
|
#include "gltf_path.hpp"
|
|
|
|
TEST_CASE("Test basic URIs", "[uri-tests]") {
|
|
const fastgltf::URI uri1(std::string_view(""));
|
|
REQUIRE(uri1.scheme().empty());
|
|
REQUIRE(uri1.path().empty());
|
|
|
|
std::string_view path = "path/somewhere.xyz";
|
|
SECTION("Basic local path") {
|
|
const fastgltf::URI uri2(path);
|
|
REQUIRE(uri2.scheme().empty());
|
|
REQUIRE(uri2.path() == path);
|
|
REQUIRE(uri2.isLocalPath());
|
|
REQUIRE(uri2.fspath() == path);
|
|
}
|
|
|
|
std::string_view abspath = "/path/somewhere.xyz";
|
|
SECTION("File scheme path") {
|
|
const std::string_view filePath = "file:/path/somewhere.xyz";
|
|
const fastgltf::URI uri3(filePath);
|
|
REQUIRE(uri3.scheme() == "file");
|
|
REQUIRE(uri3.isLocalPath());
|
|
REQUIRE(uri3.path() == abspath);
|
|
}
|
|
|
|
SECTION("File scheme localhost path") {
|
|
const std::string_view localhostPath = "file://localhost/path/somewhere.xyz";
|
|
const fastgltf::URI uri4(localhostPath);
|
|
REQUIRE(uri4.scheme() == "file");
|
|
REQUIRE(uri4.path() == abspath);
|
|
REQUIRE(!uri4.isLocalPath());
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Test generic URIs", "[uri-tests]") {
|
|
// These are a bunch of example URIs from https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Example_URIs
|
|
const fastgltf::URI uri(std::string_view("https://john.doe@www.example.com:123/forum/questions/?tag=networking&order=newest#top"));
|
|
REQUIRE(uri.scheme() == "https");
|
|
REQUIRE(uri.userinfo() == "john.doe");
|
|
REQUIRE(uri.host() == "www.example.com");
|
|
REQUIRE(uri.port() == "123");
|
|
REQUIRE(uri.path() == "/forum/questions/");
|
|
REQUIRE(uri.query() == "tag=networking&order=newest");
|
|
REQUIRE(uri.fragment() == "top");
|
|
|
|
const fastgltf::URI uri1(std::string_view("ldap://[2001:db8::7]/c=GB?objectClass?one"));
|
|
REQUIRE(uri1.scheme() == "ldap");
|
|
REQUIRE(uri1.host() == "2001:db8::7");
|
|
REQUIRE(uri1.path() == "/c=GB");
|
|
REQUIRE(uri1.query() == "objectClass?one");
|
|
|
|
const fastgltf::URI uri2(std::string_view("mailto:John.Doe@example.com"));
|
|
REQUIRE(uri2.scheme() == "mailto");
|
|
REQUIRE(uri2.path() == "John.Doe@example.com");
|
|
|
|
const fastgltf::URI uri3(std::string_view("telnet://192.0.2.16:80/"));
|
|
REQUIRE(uri3.scheme() == "telnet");
|
|
REQUIRE(uri3.host() == "192.0.2.16");
|
|
REQUIRE(uri3.port() == "80");
|
|
REQUIRE(uri3.path() == "/");
|
|
}
|
|
|
|
TEST_CASE("Test percent decoding", "[uri-tests]") {
|
|
std::string test = "%22 %25";
|
|
fastgltf::URI::decodePercents(test);
|
|
REQUIRE(test == "\" %");
|
|
}
|
|
|
|
TEST_CASE("Test data URI parsing", "[uri-tests]") {
|
|
// This example base64 data is from an example on https://en.wikipedia.org/wiki/Data_URI_scheme.
|
|
const std::string_view data = "data:image/png;base64,iVBORw0KGgoAAA"
|
|
"ANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4"
|
|
"//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU"
|
|
"5ErkJggg==";
|
|
const fastgltf::URI uri(data);
|
|
REQUIRE(uri.scheme() == "data");
|
|
REQUIRE(uri.path() == data.substr(5));
|
|
}
|
|
|
|
TEST_CASE("Validate URI copying/moving", "[uri-tests]") {
|
|
const std::string_view data = "test.bin";
|
|
SECTION("Copy semantics") {
|
|
fastgltf::URI uri(data);
|
|
REQUIRE(uri.path() == data);
|
|
fastgltf::URI uri2(uri);
|
|
REQUIRE(uri2.string().data() != uri.string().data());
|
|
REQUIRE(uri2.path() == data);
|
|
}
|
|
|
|
SECTION("Move semantics") {
|
|
fastgltf::URI uri;
|
|
{
|
|
fastgltf::URI uri2(data);
|
|
uri = std::move(uri2);
|
|
REQUIRE(uri2.string().empty());
|
|
}
|
|
// Test that the values were copied over and that the string views are still valid.
|
|
REQUIRE(uri.string() == data);
|
|
REQUIRE(uri.path() == uri.string());
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Validate escaped/percent-encoded URI", "[uri-tests]") {
|
|
const std::string_view gltfString = R"({"images": [{"uri": "grande_sph\u00E8re.png"}]})";
|
|
fastgltf::GltfDataBuffer dataBuffer;
|
|
dataBuffer.copyBytes((uint8_t*) gltfString.data(), gltfString.size());
|
|
|
|
fastgltf::Parser parser;
|
|
auto asset = parser.loadGLTF(&dataBuffer, "", fastgltf::Options::DontRequireValidAssetMember);
|
|
REQUIRE(asset.error() == fastgltf::Error::None);
|
|
|
|
auto escaped = std::get<fastgltf::sources::URI>(asset->images.front().data);
|
|
|
|
// This only tests wether the default ctor of fastgltf::URI can handle percent-encoding correctly.
|
|
const fastgltf::URI original(std::string_view("grande_sphère.png"));
|
|
const fastgltf::URI encoded(std::string_view("grande_sph%C3%A8re.png"));
|
|
REQUIRE(original.string() == escaped.uri.string());
|
|
REQUIRE(original.string() == encoded.string());
|
|
}
|
|
|
|
TEST_CASE("Test percent-encoded URIs in glTF", "[uri-tests]") {
|
|
auto boxWithSpaces = sampleModels / "2.0" / "Box With Spaces" / "glTF";
|
|
fastgltf::GltfDataBuffer jsonData;
|
|
REQUIRE(jsonData.loadFromFile(boxWithSpaces / "Box With Spaces.gltf"));
|
|
|
|
fastgltf::Parser parser;
|
|
auto asset = parser.loadGLTF(&jsonData, boxWithSpaces);
|
|
REQUIRE(asset.error() == fastgltf::Error::None);
|
|
REQUIRE(fastgltf::validate(asset.get()) == fastgltf::Error::None);
|
|
|
|
REQUIRE(asset->images.size() == 3);
|
|
|
|
auto* image0 = std::get_if<fastgltf::sources::URI>(&asset->images[0].data);
|
|
REQUIRE(image0 != nullptr);
|
|
REQUIRE(image0->uri.path() == "Normal Map.png");
|
|
|
|
auto* image1 = std::get_if<fastgltf::sources::URI>(&asset->images[1].data);
|
|
REQUIRE(image1 != nullptr);
|
|
REQUIRE(image1->uri.path() == "glTF Logo With Spaces.png");
|
|
|
|
auto* image2 = std::get_if<fastgltf::sources::URI>(&asset->images[2].data);
|
|
REQUIRE(image2 != nullptr);
|
|
REQUIRE(image2->uri.path() == "Roughness Metallic.png");
|
|
|
|
auto* buffer0 = std::get_if<fastgltf::sources::URI>(&asset->buffers[0].data);
|
|
REQUIRE(buffer0 != nullptr);
|
|
REQUIRE(buffer0->uri.path() == "Box With Spaces.bin");
|
|
}
|