From 7788c1a04ea6500f97aae257f80ff8bcb5230b1f Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Wed, 6 Oct 2021 15:46:48 +0100 Subject: [PATCH] Add a unit test for json schemas. --- test/CMakeLists.txt | 13 ++ .../glTF2/SchemaFailures/CesiumLogoFlat.png | Bin 0 -> 2433 bytes .../glTF2/SchemaFailures/sceneWrongType.gltf | 181 ++++++++++++++++++ test/unit/utglTF2ImportExport.cpp | 58 ++++++ 4 files changed, 252 insertions(+) create mode 100644 test/models/glTF2/SchemaFailures/CesiumLogoFlat.png create mode 100644 test/models/glTF2/SchemaFailures/sceneWrongType.gltf diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6f28d4183..9c2cf3000 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -223,6 +223,19 @@ else() target_sources(unit PUBLIC ${Assimp_SOURCE_DIR}/contrib/gtest/src/gtest-all.cc) endif() +# RapidJSON +IF(ASSIMP_HUNTER_ENABLED) + hunter_add_package(RapidJSON) + find_package(RapidJSON CONFIG REQUIRED) +ELSE() + INCLUDE_DIRECTORIES("../contrib/rapidjson/include") + ADD_DEFINITIONS( -DRAPIDJSON_HAS_STDSTRING=1) + option( ASSIMP_RAPIDJSON_NO_MEMBER_ITERATOR "Suppress rapidjson warning on MSVC (NOTE: breaks android build)" ON ) + if(ASSIMP_RAPIDJSON_NO_MEMBER_ITERATOR) + ADD_DEFINITIONS( -DRAPIDJSON_NOMEMBERITERATORCLASS ) + endif() +ENDIF() + IF (ASSIMP_BUILD_DRACO) ADD_DEFINITIONS( -DASSIMP_ENABLE_DRACO ) ENDIF() diff --git a/test/models/glTF2/SchemaFailures/CesiumLogoFlat.png b/test/models/glTF2/SchemaFailures/CesiumLogoFlat.png new file mode 100644 index 0000000000000000000000000000000000000000..45d502ed2610974189307ad542b05b70df14abd4 GIT binary patch literal 2433 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 #include +#include #include @@ -772,3 +773,60 @@ TEST_F(utglTF2ImportExport, wrongTypes) { } } +namespace { + /// This class provides a fake schema to the GLTF importer. + /// It just checks that the file has a top-level "scene" property which is an integer. + class FakeSchemaProvider : public rapidjson::IRemoteSchemaDocumentProvider + { + public: + FakeSchemaProvider(const char* schemaName) : + m_schemaName(schemaName) + { + rapidjson::Document schemaDoc; + schemaDoc.Parse(R"==({"properties":{"scene" : { "type" : "integer" }}, "required": [ "scene" ]})=="); + EXPECT_FALSE(schemaDoc.HasParseError()); + m_schema = std::make_unique(schemaDoc, m_schemaName.c_str(), static_cast(m_schemaName.size()), this); + } + + const rapidjson::SchemaDocument* GetRemoteDocument(const char* uri, rapidjson::SizeType) override { + if (m_schemaName == uri) { + return m_schema.get(); + } + return nullptr; + } + + private: + std::string m_schemaName; + std::unique_ptr m_schema; + }; +} + +TEST_F(utglTF2ImportExport, schemaCheckPass) { + FakeSchemaProvider schemaProvider("glTF.schema.json"); + Assimp::Importer importer; + importer.SetPropertyPointer(AI_CONFIG_IMPORT_SCHEMA_DOCUMENT_PROVIDER, &schemaProvider); + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/gltf2/BoxTextured-glTF/BoxTextured.gltf", aiProcess_ValidateDataStructure); + EXPECT_NE(scene, nullptr); + EXPECT_STREQ(importer.GetErrorString(), ""); +} + +TEST_F(utglTF2ImportExport, schemaCheckFail) { + FakeSchemaProvider schemaProvider("glTF.schema.json"); + Assimp::Importer importer; + importer.SetPropertyPointer(AI_CONFIG_IMPORT_SCHEMA_DOCUMENT_PROVIDER, &schemaProvider); + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/gltf2/SchemaFailures/sceneWrongType.gltf", aiProcess_ValidateDataStructure); + EXPECT_EQ(scene, nullptr); + const std::string errorString = importer.GetErrorString(); + EXPECT_NE(errorString.find("The JSON document did not satisfy the glTF2 schema"), std::string::npos); +} + +TEST_F(utglTF2ImportExport, noSchemaFound) { + // More than one importer might make use the provider, but not all schemas might be present. + // Check that the glTF importer handles the case when an non-null provider returns null when asked for schemas. + FakeSchemaProvider schemaProvider("missingSchema.json"); + Assimp::Importer importer; + importer.SetPropertyPointer(AI_CONFIG_IMPORT_SCHEMA_DOCUMENT_PROVIDER, &schemaProvider); + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/gltf2/BoxTextured-glTF/BoxTextured.gltf", aiProcess_ValidateDataStructure); + EXPECT_NE(scene, nullptr); + EXPECT_STREQ(importer.GetErrorString(), ""); +}