aboutsummaryrefslogtreecommitdiff
path: root/src/zen-test/utility-cmd-tests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zen-test/utility-cmd-tests.cpp')
-rw-r--r--src/zen-test/utility-cmd-tests.cpp179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/zen-test/utility-cmd-tests.cpp b/src/zen-test/utility-cmd-tests.cpp
new file mode 100644
index 000000000..aa49d7299
--- /dev/null
+++ b/src/zen-test/utility-cmd-tests.cpp
@@ -0,0 +1,179 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include <zencore/zencore.h>
+
+#if ZEN_WITH_TESTS
+
+# include "zen-test.h"
+
+# include <zencore/compactbinarybuilder.h>
+# include <zencore/filesystem.h>
+# include <zencore/iobuffer.h>
+# include <zencore/testing.h>
+# include <zencore/testutils.h>
+
+namespace zen::tests {
+
+TEST_SUITE_BEGIN("zen.utility-cmd");
+
+TEST_CASE("print.cbo_to_json")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ // Build a small compact binary object covering a few primitive field types.
+ CbObjectWriter Writer;
+ Writer << "Name"
+ << "ZenPrintTest";
+ Writer << "Count" << int32_t(42);
+ Writer << "Enabled" << true;
+
+ IoBuffer Payload = Writer.Save().GetBuffer().AsIoBuffer();
+ REQUIRE(Payload.GetSize() > 0);
+
+ const std::filesystem::path CboPath = TempDir.Path() / "object.cbo";
+ WriteFile(CboPath, Payload);
+
+ const ZenCommandResult Result = RunZen(fmt::format(R"(print --source "{}")", CboPath.string()));
+
+ REQUIRE_MESSAGE(Result.ExitCode == 0, fmt::format("zen print exited with code {}", Result.ExitCode));
+
+ // CompactBinaryToJson emits a JSON object; field names are quoted and values appear verbatim.
+ CHECK(Result.Output.find("\"Name\"") != std::string::npos);
+ CHECK(Result.Output.find("\"ZenPrintTest\"") != std::string::npos);
+ CHECK(Result.Output.find("\"Count\"") != std::string::npos);
+ CHECK(Result.Output.find("42") != std::string::npos);
+ CHECK(Result.Output.find("\"Enabled\"") != std::string::npos);
+ CHECK(Result.Output.find("true") != std::string::npos);
+}
+
+TEST_CASE("print.show_type_info_annotates_output")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ CbObjectWriter Writer;
+ Writer << "Count" << int32_t(7);
+
+ IoBuffer Payload = Writer.Save().GetBuffer().AsIoBuffer();
+ const std::filesystem::path CboPath = TempDir.Path() / "object.cbo";
+ WriteFile(CboPath, Payload);
+
+ const ZenCommandResult Plain = RunZen(fmt::format(R"(print --source "{}")", CboPath.string()));
+ const ZenCommandResult Typed = RunZen(fmt::format(R"(print --show-type-info --source "{}")", CboPath.string()));
+
+ REQUIRE(Plain.ExitCode == 0);
+ REQUIRE(Typed.ExitCode == 0);
+
+ // --show-type-info prefixes values with type annotations like [IntegerPositive] that the plain variant omits.
+ CHECK(Typed.Output.size() > Plain.Output.size());
+ CHECK(Typed.Output.find("[IntegerPositive]") != std::string::npos);
+ CHECK(Plain.Output.find("[IntegerPositive]") == std::string::npos);
+}
+
+TEST_CASE("print.missing_source_fails")
+{
+ const ZenCommandResult Result = RunZen(R"(print)");
+
+ CHECK(Result.ExitCode != 0);
+}
+
+TEST_CASE("print.non_cbo_file_fails")
+{
+ ScopedTemporaryDirectory TempDir;
+
+ const std::filesystem::path GarbagePath = TempDir.Path() / "garbage.cbo";
+ const std::string_view Garbage = "this is not compact binary data";
+ WriteFile(GarbagePath, IoBuffer(IoBuffer::Wrap, Garbage.data(), Garbage.size()));
+
+ const ZenCommandResult Result = RunZen(fmt::format(R"(print --source "{}")", GarbagePath.string()));
+
+ CHECK(Result.ExitCode != 0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// wipe
+
+namespace {
+
+ // Drop a small fixture tree of files and nested directories inside Root so wipe has
+ // something non-trivial to recurse over.
+ void PopulateWipeFixture(const std::filesystem::path& Root)
+ {
+ std::filesystem::create_directories(Root / "nested" / "deep");
+ const std::string_view Contents = "hello";
+ const IoBuffer Payload(IoBuffer::Wrap, Contents.data(), Contents.size());
+ WriteFile(Root / "top.txt", Payload);
+ WriteFile(Root / "nested" / "mid.txt", Payload);
+ WriteFile(Root / "nested" / "deep" / "leaf.txt", Payload);
+ }
+
+ bool DirectoryIsEmpty(const std::filesystem::path& Path)
+ {
+ std::error_code Ec;
+ return std::filesystem::is_empty(Path, Ec) && !Ec;
+ }
+
+} // namespace
+
+TEST_CASE("wipe.removes_directory_contents")
+{
+ ScopedTemporaryDirectory TempDir;
+ const std::filesystem::path Target = TempDir.Path() / "to-wipe";
+ PopulateWipeFixture(Target);
+
+ REQUIRE(std::filesystem::exists(Target / "top.txt"));
+ REQUIRE(std::filesystem::exists(Target / "nested" / "deep" / "leaf.txt"));
+
+ const ZenCommandResult Result = RunZen(fmt::format(R"(wipe --yes --quiet --directory "{}")", Target.string()));
+
+ REQUIRE_MESSAGE(Result.ExitCode == 0, fmt::format("zen wipe exited with code {}", Result.ExitCode));
+
+ CHECK_FALSE(std::filesystem::exists(Target / "top.txt"));
+ CHECK_FALSE(std::filesystem::exists(Target / "nested"));
+}
+
+TEST_CASE("wipe.dryrun_keeps_files")
+{
+ ScopedTemporaryDirectory TempDir;
+ const std::filesystem::path Target = TempDir.Path() / "to-wipe";
+ PopulateWipeFixture(Target);
+
+ const ZenCommandResult Result = RunZen(fmt::format(R"(wipe --yes --quiet --dryrun --directory "{}")", Target.string()));
+
+ REQUIRE_MESSAGE(Result.ExitCode == 0, fmt::format("zen wipe --dryrun exited with code {}", Result.ExitCode));
+
+ // --dryrun must leave the tree untouched.
+ CHECK(std::filesystem::exists(Target / "top.txt"));
+ CHECK(std::filesystem::exists(Target / "nested" / "mid.txt"));
+ CHECK(std::filesystem::exists(Target / "nested" / "deep" / "leaf.txt"));
+}
+
+TEST_CASE("wipe.nonexistent_directory_is_noop")
+{
+ ScopedTemporaryDirectory TempDir;
+ const std::filesystem::path Missing = TempDir.Path() / "does-not-exist";
+ REQUIRE_FALSE(std::filesystem::exists(Missing));
+
+ const ZenCommandResult Result = RunZen(fmt::format(R"(wipe --yes --quiet --directory "{}")", Missing.string()));
+
+ // A missing directory should be silently skipped without failing.
+ CHECK(Result.ExitCode == 0);
+ CHECK_FALSE(std::filesystem::exists(Missing));
+}
+
+TEST_CASE("wipe.empty_directory")
+{
+ ScopedTemporaryDirectory TempDir;
+ const std::filesystem::path Target = TempDir.Path() / "empty";
+ std::filesystem::create_directories(Target);
+ REQUIRE(DirectoryIsEmpty(Target));
+
+ const ZenCommandResult Result = RunZen(fmt::format(R"(wipe --yes --quiet --directory "{}")", Target.string()));
+
+ CHECK(Result.ExitCode == 0);
+}
+
+TEST_SUITE_END();
+
+} // namespace zen::tests
+
+#endif