tests: remove legacy test tree

This commit is contained in:
2026-04-22 00:22:32 +08:00
parent 8bfca5e8f2
commit bc47e6e5ac
754 changed files with 0 additions and 3517894 deletions

View File

@@ -1,31 +0,0 @@
# ============================================================
# UI Resource Tests
# ============================================================
set(UI_RESOURCE_TEST_SOURCES
test_ui_document_loader.cpp
test_ui_schema_document.cpp
)
add_executable(ui_resource_tests ${UI_RESOURCE_TEST_SOURCES})
if(MSVC)
set_target_properties(ui_resource_tests PROPERTIES
LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib"
)
endif()
target_link_libraries(ui_resource_tests
PRIVATE
XCEngine
GTest::gtest
GTest::gtest_main
)
target_include_directories(ui_resource_tests PRIVATE
${CMAKE_SOURCE_DIR}/engine/include
${CMAKE_SOURCE_DIR}/tests/Fixtures
)
include(GoogleTest)
gtest_discover_tests(ui_resource_tests)

View File

@@ -1,226 +0,0 @@
#include <gtest/gtest.h>
#include <XCEngine/Core/Asset/ArtifactContainer.h>
#include <XCEngine/Core/Asset/AssetDatabase.h>
#include <XCEngine/Core/Asset/AssetImportService.h>
#include <XCEngine/Core/Asset/ResourceTypes.h>
#include <XCEngine/Resources/UI/UIDocumentLoaders.h>
#include <XCEngine/Resources/UI/UIDocuments.h>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <thread>
using namespace XCEngine::Resources;
namespace {
void WriteTextFile(const std::filesystem::path& path, const std::string& contents) {
std::filesystem::create_directories(path.parent_path());
std::ofstream output(path, std::ios::binary | std::ios::trunc);
ASSERT_TRUE(output.is_open());
output << contents;
ASSERT_TRUE(static_cast<bool>(output));
}
bool ContainsExtension(const XCEngine::Containers::Array<XCEngine::Containers::String>& values,
const char* expectedValue) {
for (const auto& value : values) {
if (value == expectedValue) {
return true;
}
}
return false;
}
bool ContainsDependencyFile(const XCEngine::Containers::Array<XCEngine::Containers::String>& dependencies,
const char* expectedFileName) {
namespace fs = std::filesystem;
for (const auto& dependency : dependencies) {
if (fs::path(dependency.CStr()).filename().string() == expectedFileName) {
return true;
}
}
return false;
}
TEST(UIDocumentLoader, LoadersExposeExpectedTypesAndExtensions) {
UIViewLoader viewLoader;
UIThemeLoader themeLoader;
UISchemaLoader schemaLoader;
EXPECT_EQ(viewLoader.GetResourceType(), ResourceType::UIView);
EXPECT_EQ(themeLoader.GetResourceType(), ResourceType::UITheme);
EXPECT_EQ(schemaLoader.GetResourceType(), ResourceType::UISchema);
const auto viewExtensions = viewLoader.GetSupportedExtensions();
EXPECT_TRUE(ContainsExtension(viewExtensions, "xcui"));
EXPECT_TRUE(ContainsExtension(viewExtensions, "xcuiasset"));
EXPECT_TRUE(viewLoader.CanLoad("panel.xcui"));
EXPECT_TRUE(viewLoader.CanLoad("panel.xcuiasset"));
EXPECT_FALSE(viewLoader.CanLoad("panel.txt"));
const auto themeExtensions = themeLoader.GetSupportedExtensions();
EXPECT_TRUE(ContainsExtension(themeExtensions, "xctheme"));
EXPECT_TRUE(ContainsExtension(themeExtensions, "xcthemeasset"));
EXPECT_TRUE(themeLoader.CanLoad("editor.xctheme"));
EXPECT_TRUE(themeLoader.CanLoad("editor.xcthemeasset"));
const auto schemaExtensions = schemaLoader.GetSupportedExtensions();
EXPECT_TRUE(ContainsExtension(schemaExtensions, "xcschema"));
EXPECT_TRUE(ContainsExtension(schemaExtensions, "xcschemaasset"));
EXPECT_TRUE(schemaLoader.CanLoad("entity.xcschema"));
EXPECT_TRUE(schemaLoader.CanLoad("entity.xcschemaasset"));
}
TEST(UIDocumentLoader, CompileAndLoadViewTracksDependencies) {
namespace fs = std::filesystem;
const fs::path root = fs::temp_directory_path() / "xc_ui_document_compile_test";
fs::remove_all(root);
WriteTextFile(root / "shared" / "toolbar.xcui", "<View name=\"Toolbar\" />\n");
WriteTextFile(root / "themes" / "editor.xctheme", "<Theme name=\"EditorTheme\" />\n");
WriteTextFile(root / "schemas" / "entity.xcschema", "<Schema name=\"EntitySchema\" />\n");
WriteTextFile(
root / "main.xcui",
"<!-- root comment -->\n"
"<View name=\"MainPanel\" theme=\"themes/editor.xctheme\">\n"
" <Column>\n"
" <Use view=\"shared/toolbar.xcui\" />\n"
" <AutoForm schema=\"schemas/entity.xcschema\" />\n"
" </Column>\n"
"</View>\n");
UIViewLoader loader;
UIDocumentCompileResult compileResult = {};
ASSERT_TRUE(loader.CompileDocument((root / "main.xcui").string().c_str(), compileResult));
ASSERT_TRUE(compileResult.succeeded);
ASSERT_TRUE(compileResult.document.valid);
EXPECT_EQ(compileResult.document.rootNode.tagName, "View");
EXPECT_EQ(compileResult.document.rootNode.children.Size(), 1u);
EXPECT_EQ(compileResult.document.rootNode.children[0].tagName, "Column");
EXPECT_EQ(compileResult.document.dependencies.Size(), 3u);
EXPECT_TRUE(ContainsDependencyFile(compileResult.document.dependencies, "toolbar.xcui"));
EXPECT_TRUE(ContainsDependencyFile(compileResult.document.dependencies, "editor.xctheme"));
EXPECT_TRUE(ContainsDependencyFile(compileResult.document.dependencies, "entity.xcschema"));
LoadResult loadResult = loader.Load((root / "main.xcui").string().c_str());
ASSERT_TRUE(loadResult);
ASSERT_NE(loadResult.resource, nullptr);
auto* view = static_cast<UIView*>(loadResult.resource);
ASSERT_NE(view, nullptr);
EXPECT_TRUE(view->IsValid());
EXPECT_EQ(view->GetName(), "MainPanel");
EXPECT_EQ(view->GetRootNode().tagName, "View");
EXPECT_EQ(view->GetDependencies().Size(), 3u);
delete view;
fs::remove_all(root);
}
TEST(UIDocumentLoader, AssetDatabaseImportsViewArtifactAndReimportsWhenDependencyChanges) {
namespace fs = std::filesystem;
using namespace std::chrono_literals;
const fs::path projectRoot = fs::temp_directory_path() / "xc_ui_artifact_reimport_test";
const fs::path assetsRoot = projectRoot / "Assets";
fs::remove_all(projectRoot);
WriteTextFile(assetsRoot / "UI" / "Shared" / "toolbar.xcui", "<View name=\"Toolbar\" />\n");
WriteTextFile(
assetsRoot / "UI" / "Main.xcui",
"<View name=\"Inspector\">\n"
" <Use view=\"Shared/toolbar.xcui\" />\n"
"</View>\n");
AssetDatabase database;
database.Initialize(projectRoot.string().c_str());
AssetDatabase::ResolvedAsset firstResolve;
ASSERT_TRUE(database.EnsureArtifact("Assets/UI/Main.xcui", ResourceType::UIView, firstResolve));
ASSERT_TRUE(firstResolve.artifactReady);
EXPECT_EQ(fs::path(firstResolve.artifactMainPath.CStr()).extension().string(), ".xcuiasset");
EXPECT_TRUE(fs::exists(firstResolve.artifactMainPath.CStr()));
EXPECT_TRUE(IsArtifactContainerFile(firstResolve.artifactMainPath));
EXPECT_FALSE(firstResolve.artifactMainEntryPath.Empty());
EXPECT_NE(firstResolve.artifactMainEntryPath, firstResolve.artifactMainPath);
XCEngine::Containers::Array<XCEngine::Core::uint8> artifactPayload;
ASSERT_TRUE(ReadArtifactContainerMainEntryPayload(
firstResolve.artifactMainPath,
ResourceType::UIView,
artifactPayload));
EXPECT_FALSE(artifactPayload.Empty());
UIViewLoader loader;
LoadResult firstLoad = loader.Load(firstResolve.artifactMainEntryPath.CStr());
ASSERT_TRUE(firstLoad);
auto* firstView = static_cast<UIView*>(firstLoad.resource);
ASSERT_NE(firstView, nullptr);
EXPECT_EQ(firstView->GetRootNode().tagName, "View");
EXPECT_EQ(firstView->GetDependencies().Size(), 1u);
EXPECT_TRUE(ContainsDependencyFile(firstView->GetDependencies(), "toolbar.xcui"));
delete firstView;
const XCEngine::Containers::String firstArtifactPath = firstResolve.artifactMainPath;
database.Shutdown();
std::this_thread::sleep_for(50ms);
WriteTextFile(
assetsRoot / "UI" / "Shared" / "toolbar.xcui",
"<View name=\"Toolbar\">\n"
" <Button id=\"refresh\" />\n"
"</View>\n");
database.Initialize(projectRoot.string().c_str());
AssetDatabase::ResolvedAsset secondResolve;
ASSERT_TRUE(database.EnsureArtifact("Assets/UI/Main.xcui", ResourceType::UIView, secondResolve));
ASSERT_TRUE(secondResolve.artifactReady);
EXPECT_NE(firstArtifactPath, secondResolve.artifactMainPath);
EXPECT_TRUE(fs::exists(secondResolve.artifactMainPath.CStr()));
database.Shutdown();
fs::remove_all(projectRoot);
}
TEST(UIDocumentLoader, AssetImportServiceReportsDetailedDiagnosticsForMissingDependency) {
namespace fs = std::filesystem;
const fs::path projectRoot = fs::temp_directory_path() / "xc_ui_import_error_test";
const fs::path assetsRoot = projectRoot / "Assets";
fs::remove_all(projectRoot);
WriteTextFile(
assetsRoot / "UI" / "Broken.xcui",
"<View>\n"
" <Use view=\"Shared/missing_toolbar.xcui\" />\n"
"</View>\n");
AssetImportService importService;
importService.Initialize();
importService.SetProjectRoot(projectRoot.string().c_str());
AssetImportService::ImportedAsset importedAsset;
EXPECT_FALSE(importService.EnsureArtifact("Assets/UI/Broken.xcui", ResourceType::UIView, importedAsset));
const AssetImportService::ImportStatusSnapshot status = importService.GetLastImportStatus();
EXPECT_TRUE(status.HasValue());
EXPECT_FALSE(status.success);
const std::string message = status.message.CStr();
EXPECT_NE(message.find("Failed to build asset artifact: Assets/UI/Broken.xcui"), std::string::npos);
EXPECT_NE(message.find("Referenced UI document was not found"), std::string::npos);
EXPECT_NE(message.find("missing_toolbar.xcui"), std::string::npos);
importService.Shutdown();
fs::remove_all(projectRoot);
}
} // namespace

View File

@@ -1,230 +0,0 @@
#include <gtest/gtest.h>
#include <XCEngine/Core/Asset/ArtifactContainer.h>
#include <XCEngine/Resources/UI/UIDocumentCompiler.h>
#include <XCEngine/Resources/UI/UIDocumentLoaders.h>
#include <filesystem>
#include <fstream>
using namespace XCEngine::Resources;
namespace {
void WriteTextFile(const std::filesystem::path& path, const std::string& contents) {
std::filesystem::create_directories(path.parent_path());
std::ofstream output(path, std::ios::binary | std::ios::trunc);
ASSERT_TRUE(output.is_open());
output << contents;
ASSERT_TRUE(static_cast<bool>(output));
}
void ExpectSchemaCompileFailure(
const char* testFolderName,
const char* markup,
const char* expectedMessageFragment) {
namespace fs = std::filesystem;
const fs::path root = fs::temp_directory_path() / testFolderName;
const fs::path schemaPath = root / "invalid.xcschema";
fs::remove_all(root);
WriteTextFile(schemaPath, markup);
UISchemaLoader loader;
UIDocumentCompileResult compileResult = {};
EXPECT_FALSE(loader.CompileDocument(schemaPath.string().c_str(), compileResult));
EXPECT_FALSE(compileResult.succeeded);
EXPECT_FALSE(compileResult.errorMessage.Empty());
ASSERT_FALSE(compileResult.document.diagnostics.Empty());
const std::string errorMessage = compileResult.errorMessage.CStr();
EXPECT_NE(errorMessage.find(expectedMessageFragment), std::string::npos);
fs::remove_all(root);
}
TEST(UISchemaDocument, CompileAndArtifactLoadPopulateSchemaDefinition) {
namespace fs = std::filesystem;
const fs::path root = fs::temp_directory_path() / "xc_ui_schema_compile_test";
const fs::path schemaPath = root / "markup.xcschema";
const fs::path artifactPath = root / "markup.xcschemaasset";
fs::remove_all(root);
WriteTextFile(
schemaPath,
"<Schema name=\"EditorMarkup\">\n"
" <Element tag=\"View\" allowUnknownChildren=\"true\">\n"
" <Attribute name=\"theme\" type=\"document\" kind=\"theme\" />\n"
" <Attribute name=\"mode\" type=\"enum\" values=\"compact, cozy\" />\n"
" <Element tag=\"Column\">\n"
" <Attribute name=\"gap\" type=\"number\" />\n"
" </Element>\n"
" </Element>\n"
"</Schema>\n");
UISchemaLoader loader;
UIDocumentCompileResult compileResult = {};
ASSERT_TRUE(loader.CompileDocument(schemaPath.string().c_str(), compileResult));
ASSERT_TRUE(compileResult.succeeded);
ASSERT_TRUE(compileResult.document.valid);
ASSERT_TRUE(compileResult.document.schemaDefinition.valid);
EXPECT_EQ(compileResult.document.schemaDefinition.name, "EditorMarkup");
const UISchemaElementDefinition* viewElement =
compileResult.document.schemaDefinition.FindElement("View");
ASSERT_NE(viewElement, nullptr);
EXPECT_TRUE(viewElement->allowUnknownChildren);
const UISchemaAttributeDefinition* themeAttribute = viewElement->FindAttribute("theme");
ASSERT_NE(themeAttribute, nullptr);
EXPECT_EQ(themeAttribute->valueType, UISchemaValueType::Document);
EXPECT_TRUE(themeAttribute->restrictDocumentKind);
EXPECT_EQ(themeAttribute->documentKind, UIDocumentKind::Theme);
const UISchemaAttributeDefinition* modeAttribute = viewElement->FindAttribute("mode");
ASSERT_NE(modeAttribute, nullptr);
EXPECT_EQ(modeAttribute->valueType, UISchemaValueType::Enum);
ASSERT_EQ(modeAttribute->allowedValues.Size(), 2u);
EXPECT_EQ(modeAttribute->allowedValues[0], "compact");
EXPECT_EQ(modeAttribute->allowedValues[1], "cozy");
LoadResult loadResult = loader.Load(schemaPath.string().c_str());
ASSERT_TRUE(loadResult);
ASSERT_NE(loadResult.resource, nullptr);
auto* schemaResource = static_cast<UISchema*>(loadResult.resource);
ASSERT_NE(schemaResource, nullptr);
ASSERT_TRUE(schemaResource->GetSchemaDefinition().valid);
ASSERT_NE(schemaResource->GetSchemaDefinition().FindElement("View"), nullptr);
delete schemaResource;
XCEngine::Containers::String artifactWriteError;
ASSERT_TRUE(
WriteUIDocumentArtifact(artifactPath.string().c_str(), compileResult, &artifactWriteError))
<< artifactWriteError.CStr();
XCEngine::Containers::Array<XCEngine::Core::uint8> artifactPayload;
ASSERT_TRUE(ReadArtifactContainerMainEntryPayload(
artifactPath.string().c_str(),
ResourceType::UISchema,
artifactPayload));
EXPECT_FALSE(artifactPayload.Empty());
UIDocumentCompileResult artifactResult = {};
ASSERT_TRUE(LoadUIDocumentArtifact(
artifactPath.string().c_str(),
UIDocumentKind::Schema,
artifactResult));
ASSERT_TRUE(artifactResult.succeeded);
ASSERT_TRUE(artifactResult.document.valid);
ASSERT_TRUE(artifactResult.document.schemaDefinition.valid);
const UISchemaElementDefinition* artifactViewElement =
artifactResult.document.schemaDefinition.FindElement("View");
ASSERT_NE(artifactViewElement, nullptr);
ASSERT_NE(artifactViewElement->FindChild("Column"), nullptr);
fs::remove_all(root);
}
TEST(UISchemaDocument, CompileRejectsInvalidSchemaFlags) {
namespace fs = std::filesystem;
const fs::path root = fs::temp_directory_path() / "xc_ui_schema_invalid_flag_test";
const fs::path schemaPath = root / "broken.xcschema";
fs::remove_all(root);
WriteTextFile(
schemaPath,
"<Schema>\n"
" <Element tag=\"View\" allowUnknownChildren=\"sometimes\" />\n"
"</Schema>\n");
UISchemaLoader loader;
UIDocumentCompileResult compileResult = {};
EXPECT_FALSE(loader.CompileDocument(schemaPath.string().c_str(), compileResult));
EXPECT_FALSE(compileResult.succeeded);
EXPECT_FALSE(compileResult.errorMessage.Empty());
ASSERT_FALSE(compileResult.document.diagnostics.Empty());
const std::string errorMessage = compileResult.errorMessage.CStr();
EXPECT_NE(errorMessage.find("allowUnknownChildren"), std::string::npos);
fs::remove_all(root);
}
TEST(UISchemaDocument, CompileRejectsDuplicateAttributeDefinitions) {
namespace fs = std::filesystem;
const fs::path root = fs::temp_directory_path() / "xc_ui_schema_duplicate_attribute_test";
const fs::path schemaPath = root / "duplicate.xcschema";
fs::remove_all(root);
WriteTextFile(
schemaPath,
"<Schema>\n"
" <Element tag=\"View\">\n"
" <Attribute name=\"id\" type=\"string\" />\n"
" <Attribute name=\"id\" type=\"string\" />\n"
" </Element>\n"
"</Schema>\n");
UISchemaLoader loader;
UIDocumentCompileResult compileResult = {};
EXPECT_FALSE(loader.CompileDocument(schemaPath.string().c_str(), compileResult));
EXPECT_FALSE(compileResult.succeeded);
EXPECT_FALSE(compileResult.errorMessage.Empty());
ASSERT_FALSE(compileResult.document.diagnostics.Empty());
const std::string errorMessage = compileResult.errorMessage.CStr();
EXPECT_NE(errorMessage.find("Duplicate schema attribute definition"), std::string::npos);
fs::remove_all(root);
}
TEST(UISchemaDocument, CompileRejectsAllowedValuesOnNonEnumAttribute) {
ExpectSchemaCompileFailure(
"xc_ui_schema_allowed_values_non_enum_test",
"<Schema>\n"
" <Element tag=\"View\">\n"
" <Attribute name=\"gap\" type=\"number\" allowedValues=\"8,12\" />\n"
" </Element>\n"
"</Schema>\n",
"allowedValues");
}
TEST(UISchemaDocument, CompileRejectsDocumentKindOnNonDocumentAttribute) {
ExpectSchemaCompileFailure(
"xc_ui_schema_document_kind_non_document_test",
"<Schema>\n"
" <Element tag=\"View\">\n"
" <Attribute name=\"id\" type=\"string\" documentKind=\"theme\" />\n"
" </Element>\n"
"</Schema>\n",
"documentKind");
}
TEST(UISchemaDocument, CompileRejectsRestrictDocumentKindOnNonDocumentAttribute) {
ExpectSchemaCompileFailure(
"xc_ui_schema_restrict_non_document_test",
"<Schema>\n"
" <Element tag=\"View\">\n"
" <Attribute name=\"id\" type=\"string\" restrictDocumentKind=\"true\" />\n"
" </Element>\n"
"</Schema>\n",
"restrictDocumentKind");
}
TEST(UISchemaDocument, CompileRejectsRestrictDocumentKindWithoutExplicitDocumentKind) {
ExpectSchemaCompileFailure(
"xc_ui_schema_restrict_without_kind_test",
"<Schema>\n"
" <Element tag=\"View\">\n"
" <Attribute name=\"theme\" type=\"document\" restrictDocumentKind=\"true\" />\n"
" </Element>\n"
"</Schema>\n",
"must declare 'documentKind'");
}
} // namespace