summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/slang-unit-test/unit-test-file-system.cpp197
1 files changed, 197 insertions, 0 deletions
diff --git a/tools/slang-unit-test/unit-test-file-system.cpp b/tools/slang-unit-test/unit-test-file-system.cpp
new file mode 100644
index 000000000..f1fd2c6bc
--- /dev/null
+++ b/tools/slang-unit-test/unit-test-file-system.cpp
@@ -0,0 +1,197 @@
+// unit-test-file-system.cpp
+
+#include "../../source/core/slang-file-system.h"
+#include "../../source/core/slang-riff-file-system.h"
+#include "../../source/core/slang-zip-file-system.h"
+
+#include "../../source/core/slang-deflate-compression-system.h"
+#include "../../source/core/slang-lz4-compression-system.h"
+
+#include "tools/unit-test/slang-unit-test.h"
+
+using namespace Slang;
+
+namespace {
+
+enum class FileSystemType
+{
+ Zip,
+ RiffUncompressed,
+ RiffDeflate,
+ RiffLZ4,
+ Relative,
+ CountOf,
+};
+
+struct Entry
+{
+ typedef Entry ThisType;
+
+ bool operator<(const ThisType& rhs) const { return name < rhs.name; }
+ bool operator==(const ThisType& rhs) const { return name == rhs.name && type == rhs.type; }
+ bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
+
+ SlangPathType type;
+ String name;
+};
+
+} //
+
+static SlangResult _createAndCheckFile(ISlangMutableFileSystem* fileSystem, const char* path, const char* contents)
+{
+ UnownedStringSlice contentsSlice(contents);
+
+ SLANG_RETURN_ON_FAIL(fileSystem->saveFile(path, contentsSlice.begin(), contentsSlice.getLength()));
+
+ SlangPathType pathType;
+ SLANG_RETURN_ON_FAIL(fileSystem->getPathType(path, &pathType));
+
+ if (pathType != SLANG_PATH_TYPE_FILE)
+ {
+ return SLANG_FAIL;
+ }
+
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(fileSystem->loadFile(path, blob.writeRef()));
+
+ if (blob->getBufferSize() != contentsSlice.getLength())
+ {
+ return SLANG_FAIL;
+ }
+ if (contentsSlice != UnownedStringSlice((const char*)blob->getBufferPointer(), blob->getBufferSize()))
+ {
+ return SLANG_FAIL;
+ }
+
+ return SLANG_OK;
+}
+
+static SlangResult _createAndCheckDirectory(ISlangMutableFileSystem* fileSystem, const char* path)
+{
+ SLANG_RETURN_ON_FAIL(fileSystem->createDirectory(path));
+
+ SlangPathType pathType;
+ SLANG_RETURN_ON_FAIL(fileSystem->getPathType(path, &pathType));
+
+ if (pathType != SLANG_PATH_TYPE_DIRECTORY)
+ {
+ return SLANG_FAIL;
+ }
+
+ return SLANG_OK;
+}
+
+static void _entryCallback(SlangPathType pathType, const char* name, void* userData)
+{
+ List<Entry>& out = *(List<Entry>*)userData;
+ out.add(Entry{pathType, name});
+}
+
+static SlangResult _enumeratePath(ISlangMutableFileSystem* fileSystem, const char* path, const ConstArrayView<Entry>& entries)
+{
+ List<Entry> contents;
+
+ SLANG_RETURN_ON_FAIL(fileSystem->enumeratePathContents(path, _entryCallback, (void*)&contents));
+
+ contents.sort();
+
+ if (contents.getArrayView() != entries)
+ {
+ return SLANG_FAIL;
+ }
+
+ return SLANG_OK;
+}
+
+static SlangResult _test(FileSystemType type)
+{
+ ComPtr<ISlangMutableFileSystem> fileSystem;
+
+ switch (type)
+ {
+ case FileSystemType::Zip:
+ {
+ SLANG_RETURN_ON_FAIL(ZipFileSystem::create(fileSystem));
+ break;
+ }
+ case FileSystemType::RiffUncompressed:
+ {
+ fileSystem = new RiffFileSystem(nullptr);
+ break;
+ }
+ case FileSystemType::RiffDeflate:
+ {
+ fileSystem = new RiffFileSystem(DeflateCompressionSystem::getSingleton());
+ break;
+ }
+ case FileSystemType::RiffLZ4:
+ {
+ fileSystem = new RiffFileSystem(LZ4CompressionSystem::getSingleton());
+ break;
+ }
+ case FileSystemType::Relative:
+ {
+ ComPtr<ISlangMutableFileSystem> memoryFileSystem(new RiffFileSystem(nullptr));
+ memoryFileSystem->createDirectory("base");
+
+ fileSystem = new RelativeFileSystem(memoryFileSystem, "base");
+ break;
+ }
+ }
+
+
+ SLANG_RETURN_ON_FAIL(_createAndCheckFile(fileSystem, "a", "someText"));
+ SLANG_RETURN_ON_FAIL(_createAndCheckFile(fileSystem, "b", "A longer bit of text...."));
+
+ SLANG_RETURN_ON_FAIL(_createAndCheckDirectory(fileSystem, "d"));
+ SLANG_RETURN_ON_FAIL(_createAndCheckFile(fileSystem, "d/a", "Some more silly stuff"));
+ SLANG_RETURN_ON_FAIL(_createAndCheckFile(fileSystem, "d\\b", "Lets go empty"));
+
+ // Lets find all the files in the directory
+
+ {
+ const Entry entries[] = { {SLANG_PATH_TYPE_FILE, "a" }, {SLANG_PATH_TYPE_FILE, "b" } };
+ SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, "d", makeConstArrayView(entries)));
+ }
+
+ {
+ const Entry entries[] = { {SLANG_PATH_TYPE_FILE, "a" }, {SLANG_PATH_TYPE_FILE, "b" }, {SLANG_PATH_TYPE_DIRECTORY, "d" } };
+ SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, ".", makeConstArrayView(entries)));
+ }
+
+ SLANG_RETURN_ON_FAIL(fileSystem->remove("d/a"));
+ {
+ const Entry entries[] = { {SLANG_PATH_TYPE_FILE, "b" } };
+ SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, "d", makeConstArrayView(entries)));
+ }
+ SLANG_RETURN_ON_FAIL(fileSystem->remove("d\\b"));
+ {
+ SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, "d", makeConstArrayView((const Entry*)nullptr, 0)));
+ }
+
+ // If it's removed it can't be removed again
+ SLANG_CHECK(SLANG_FAILED(fileSystem->remove("d\\b")));
+
+ // Remove the directory
+ SLANG_RETURN_ON_FAIL(fileSystem->remove("d"));
+
+ {
+ const Entry entries[] = { {SLANG_PATH_TYPE_FILE, "a" }, {SLANG_PATH_TYPE_FILE, "b" } };
+ SLANG_RETURN_ON_FAIL(_enumeratePath(fileSystem, ".", makeConstArrayView(entries)));
+ }
+
+ return SLANG_OK;
+}
+
+SLANG_UNIT_TEST(fileSystem)
+{
+ for (Index i = 0; i < Count(FileSystemType::CountOf); ++i)
+ {
+ const auto type = FileSystemType(i);
+
+ auto const res = _test(type);
+
+ SLANG_CHECK(SLANG_SUCCEEDED(res));
+ }
+}
+