mirror of
https://github.com/izzy2lost/libultraship.git
synced 2026-10-26 11:44:27 -07:00
* Add Javadoc comments to CoreAudioAudioPlayer.h and SoundMatrixDecoder.h Add documentation comments to all undocumented classes, structs, methods, and important member variables in: - CoreAudioAudioPlayer.h: class, constructor, Buffered, DoInit, DoClose, DoPlay, CoreAudioRenderCallback, and ring buffer member variables - SoundMatrixDecoder.h: BiquadCascade, FilterCoefficients, AllPassChain, CircularDelay structs, and DesignLowPass, DesignHighPass, ProcessFilter, PrepareAllPass, ProcessAllPass, ProcessDelay, Saturate methods Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * Add Javadoc-style comments to controller mapping header files Add /** ... */ documentation with @brief, @param, and @return tags to all classes, structs, enums, constructors, and public/protected methods in: - ControllerMapping.h - ControllerInputMapping.h - ControllerAxisDirectionMapping.h - ControllerButtonMapping.h - ControllerGyroMapping.h - ControllerRumbleMapping.h - ControllerLEDMapping.h - ControllerDefaultMappings.h Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * Add Javadoc comments to keyboard, mouse, SDL, and factory mapping headers Add /** ... */ documentation with @brief, @param, and @return tags to all classes, structs, enums, constructors, and public/protected methods across 26 controller mapping header files. Existing Javadoc comments (e.g. in KeyboardScancodes.h) are left untouched. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * Add Javadoc-style comments to physical device, control device, resource, and factory headers Add /** ... */ documentation with @brief, @param, @return tags to all classes, structs, enums, public/protected methods, and constructors in: - ConnectedPhysicalDeviceManager.h - GlobalSDLDeviceSettings.h - PhysicalDeviceType.h - SDLAddRemoveDeviceEventHandler.h - ResourceFactoryBinary.h - ResourceFactoryXML.h - Blob.h, Json.h, Shader.h - BlobFactory.h, JsonFactory.h, ShaderFactory.h - FolderArchive.h Files that were already fully documented (ControlDevice.h, ResourceFactory.h, ResourceType.h, File.h) are left unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * docs: add Javadoc-style comments to utility header files Add /** ... */ documentation with @brief, @param, and @return tags to: - Directory.h, DiskFile.h, FileHelper.h, Path.h, PathHelper.h - glob.h, macUtils.h, stox.h Files already documented (color.h, StrHash64.h, endianness.h) are left unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * Add Javadoc-style comments to window, GUI, and resource headers Add /** ... */ documentation with @brief, @param, and @return tags to: - FileDropMgr.h: class, typedef, and all public methods - MouseStateManager.h: class and all public/protected methods - EventDebuggerWindow.h: class and lifecycle overrides - Fonts.h: file-level documentation for embedded font data - IconsFontAwesome4.h: file-level documentation for icon constants - StatsWindow.h: destructor (class and methods already documented) - Font.h: class, resource type macro, public methods, and data members - FontFactory.h: class and ReadResource method - GuiTexture.h: struct, class, resource type macro, methods, and members - GuiTextureFactory.h: class and ReadResource method Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * Add Javadoc-style comments to public headers Add /** ... */ documentation comments with @brief, @param, and @return tags to all classes, structs, enums, free functions, macros, and public methods in the following header files: - include/ship/Api.h - include/ship/events/CoreEvents.h - include/ship/port/mobile/MobileImpl.h - include/ship/scripting/LibraryLoader.h - include/ship/security/Keystore.h Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * docs: add missing Javadoc comments to Controller.h and InputEditorWindow.h Add Javadoc-style comments to all undocumented methods: - Controller.h: Add doc for ~Controller() destructor - InputEditorWindow.h: Add docs for ~InputEditorWindow() destructor and all 24 private methods (Draw*, Update*, GetButtonColors*, OffsetMappingPopup) FileHelper.h and DiskFile.h already have complete Javadoc coverage from prior commits on this branch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * style: apply clang-format-14 to fix formatting violations Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * fix: rename WheelDirections x/y to X/Y per CamelCase naming convention Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * docs: address review comments - fix inaccurate Doxygen comments in DiskFile, Shader, LibraryLoader, stox, Path, PathHelper Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * fix: auto-enable DISABLE_SCRIPTING for iOS to fix build-ios CI failure Agent-Logs-Url: https://github.com/Kenix3/libultraship/sessions/e409640e-005b-4dce-a9cd-db23e80d5385 Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * Flip tcc scripting to opt-in (#1084) * Flip tcc scripting to opt-in Per #1074 * Adhere to lgpl Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * docs: update README dependency list with tree structure and correct links (#1088) Agent-Logs-Url: https://github.com/Kenix3/libultraship/sessions/dae72d20-385d-41c2-bba9-9229493d9e17 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * fix: remove stale DISABLE_SCRIPTING iOS override (superseded by ENABLE_SCRIPTING opt-in from #1084) Agent-Logs-Url: https://github.com/Kenix3/libultraship/sessions/e409640e-005b-4dce-a9cd-db23e80d5385 Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * no changes yet Agent-Logs-Url: https://github.com/Kenix3/libultraship/sessions/62cd9f10-ed50-45ab-b3fb-19f689b83025 Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * fix: WriteAllBytes always creates parent dirs; GetFileNameExtension throws explicitly; fix Shader/MobileImpl docs; fix clang-tidy CI Agent-Logs-Url: https://github.com/Kenix3/libultraship/sessions/62cd9f10-ed50-45ab-b3fb-19f689b83025 Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * fix: revert MobileImpl.h to origin/main — removes it from PR diff, fixing clang-tidy CI Agent-Logs-Url: https://github.com/Kenix3/libultraship/sessions/05a2642f-75da-4384-a7c5-4cc249a03f51 Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * refactor: move library file writing from ScriptLoader into LibraryLoader; fix Init/Unload docstrings Agent-Logs-Url: https://github.com/Kenix3/libultraship/sessions/8e68fb32-b97d-4c50-b75d-7268d54c7448 Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> * fix: add missing <cstdint> include to LibraryLoader.h for uint8_t Agent-Logs-Url: https://github.com/Kenix3/libultraship/sessions/e9c0cf04-6e25-4714-9132-3556d3d93da0 Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Kenix3 <18299654+Kenix3@users.noreply.github.com> Co-authored-by: Jeod <47716344+JeodC@users.noreply.github.com>
268 lines
9.2 KiB
C++
268 lines
9.2 KiB
C++
#include <gtest/gtest.h>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
|
|
#include "ship/utils/filesystemtools/PathHelper.h"
|
|
#include "ship/utils/filesystemtools/FileHelper.h"
|
|
#include "ship/utils/filesystemtools/Directory.h"
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
// ============================================================
|
|
// PathHelper::GetFileName
|
|
// ============================================================
|
|
|
|
TEST(PathHelperGetFileName, ExtractsBaseName) {
|
|
EXPECT_EQ(Ship::PathHelper::GetFileName("/some/dir/file.txt"), "file.txt");
|
|
}
|
|
|
|
TEST(PathHelperGetFileName, ExtractsBaseNameNoDir) {
|
|
EXPECT_EQ(Ship::PathHelper::GetFileName("file.txt"), "file.txt");
|
|
}
|
|
|
|
TEST(PathHelperGetFileName, ExtractsBaseNameNoExtension) {
|
|
EXPECT_EQ(Ship::PathHelper::GetFileName("/dir/filename"), "filename");
|
|
}
|
|
|
|
// ============================================================
|
|
// PathHelper::GetFileNameWithoutExtension
|
|
// ============================================================
|
|
|
|
TEST(PathHelperGetStem, RemovesExtension) {
|
|
EXPECT_EQ(Ship::PathHelper::GetFileNameWithoutExtension("/dir/file.txt"), "file");
|
|
}
|
|
|
|
TEST(PathHelperGetStem, MultipleDotsKeepsLastAsExtension) {
|
|
EXPECT_EQ(Ship::PathHelper::GetFileNameWithoutExtension("/dir/file.tar.gz"), "file.tar");
|
|
}
|
|
|
|
TEST(PathHelperGetStem, NoExtensionReturnsStem) {
|
|
EXPECT_EQ(Ship::PathHelper::GetFileNameWithoutExtension("/dir/filename"), "filename");
|
|
}
|
|
|
|
// ============================================================
|
|
// PathHelper::GetFileNameExtension
|
|
// ============================================================
|
|
|
|
TEST(PathHelperGetExtension, ReturnsExtensionWithDot) {
|
|
EXPECT_EQ(Ship::PathHelper::GetFileNameExtension("file.txt"), ".txt");
|
|
}
|
|
|
|
TEST(PathHelperGetExtension, ReturnsLastExtensionForMultipleDots) {
|
|
EXPECT_EQ(Ship::PathHelper::GetFileNameExtension("file.tar.gz"), ".gz");
|
|
}
|
|
|
|
TEST(PathHelperGetExtension, NoDotThrows) {
|
|
EXPECT_THROW(Ship::PathHelper::GetFileNameExtension("nodotfile"), std::out_of_range);
|
|
}
|
|
|
|
// ============================================================
|
|
// PathHelper::GetDirectoryName
|
|
// ============================================================
|
|
|
|
TEST(PathHelperGetDirectoryName, ReturnsParent) {
|
|
fs::path p = "/some/dir/file.txt";
|
|
EXPECT_EQ(Ship::PathHelper::GetDirectoryName(p), fs::path("/some/dir"));
|
|
}
|
|
|
|
TEST(PathHelperGetDirectoryName, RootParentOfTopLevel) {
|
|
fs::path p = "/file.txt";
|
|
EXPECT_EQ(Ship::PathHelper::GetDirectoryName(p), fs::path("/"));
|
|
}
|
|
|
|
// ============================================================
|
|
// PathHelper::GetPath
|
|
// ============================================================
|
|
|
|
TEST(PathHelperGetPath, FiltersOutFileSegments) {
|
|
// Segments with a '.' are treated as files and excluded
|
|
fs::path result = Ship::PathHelper::GetPath("textures/player/link.png");
|
|
EXPECT_EQ(result, fs::path("textures/player"));
|
|
}
|
|
|
|
TEST(PathHelperGetPath, PureDirectoryPathIsUnchanged) {
|
|
fs::path result = Ship::PathHelper::GetPath("assets/textures");
|
|
EXPECT_EQ(result, fs::path("assets/textures"));
|
|
}
|
|
|
|
TEST(PathHelperGetPath, SingleFileNameReturnsEmpty) {
|
|
// A single segment with a '.' is filtered out, leaving an empty path
|
|
fs::path result = Ship::PathHelper::GetPath("file.txt");
|
|
EXPECT_TRUE(result.empty());
|
|
}
|
|
|
|
// ============================================================
|
|
// Directory helper fixture — creates/cleans up a temp test dir
|
|
// ============================================================
|
|
|
|
class DirectoryTest : public ::testing::Test {
|
|
protected:
|
|
fs::path mTestDir;
|
|
|
|
void SetUp() override {
|
|
mTestDir = fs::temp_directory_path() / "lus_dir_test";
|
|
fs::remove_all(mTestDir);
|
|
}
|
|
|
|
void TearDown() override {
|
|
fs::remove_all(mTestDir);
|
|
}
|
|
};
|
|
|
|
TEST_F(DirectoryTest, ExistsReturnsFalseForNonexistent) {
|
|
EXPECT_FALSE(Directory::Exists(mTestDir));
|
|
}
|
|
|
|
TEST_F(DirectoryTest, CreateDirectoryMakesItExist) {
|
|
Directory::CreateDirectory(mTestDir.string());
|
|
EXPECT_TRUE(Directory::Exists(mTestDir));
|
|
}
|
|
|
|
TEST_F(DirectoryTest, MakeDirectoryAlsoWorks) {
|
|
Directory::MakeDirectory(mTestDir.string());
|
|
EXPECT_TRUE(Directory::Exists(mTestDir));
|
|
}
|
|
|
|
TEST_F(DirectoryTest, CreateDirectoryIsIdempotent) {
|
|
Directory::CreateDirectory(mTestDir.string());
|
|
EXPECT_NO_THROW(Directory::CreateDirectory(mTestDir.string()));
|
|
EXPECT_TRUE(Directory::Exists(mTestDir));
|
|
}
|
|
|
|
TEST_F(DirectoryTest, ListFilesEmptyDirectory) {
|
|
Directory::CreateDirectory(mTestDir.string());
|
|
auto files = Directory::ListFiles(mTestDir.string());
|
|
EXPECT_TRUE(files.empty());
|
|
}
|
|
|
|
TEST_F(DirectoryTest, ListFilesReturnsAllFiles) {
|
|
Directory::CreateDirectory(mTestDir.string());
|
|
// Create two files
|
|
std::ofstream(mTestDir / "a.txt").close();
|
|
std::ofstream(mTestDir / "b.txt").close();
|
|
auto files = Directory::ListFiles(mTestDir.string());
|
|
EXPECT_EQ(files.size(), 2u);
|
|
}
|
|
|
|
TEST_F(DirectoryTest, ListFilesIncludesFilesInSubdirectories) {
|
|
Directory::CreateDirectory(mTestDir.string());
|
|
std::ofstream(mTestDir / "file.txt").close();
|
|
Directory::CreateDirectory((mTestDir / "subdir").string());
|
|
std::ofstream(mTestDir / "subdir" / "nested.txt").close();
|
|
auto files = Directory::ListFiles(mTestDir.string());
|
|
// Recursive iterator finds both files, not the directory itself
|
|
EXPECT_EQ(files.size(), 2u);
|
|
}
|
|
|
|
TEST_F(DirectoryTest, ListFilesNonexistentDirectoryReturnsEmpty) {
|
|
auto files = Directory::ListFiles((mTestDir / "doesnotexist").string());
|
|
EXPECT_TRUE(files.empty());
|
|
}
|
|
|
|
TEST_F(DirectoryTest, GetCurrentDirectoryReturnsNonEmpty) {
|
|
std::string cwd = Directory::GetCurrentDirectory();
|
|
EXPECT_FALSE(cwd.empty());
|
|
}
|
|
|
|
// ============================================================
|
|
// FileHelper fixture
|
|
// ============================================================
|
|
|
|
class FileHelperTest : public ::testing::Test {
|
|
protected:
|
|
fs::path mTestDir;
|
|
fs::path mTestFile;
|
|
|
|
void SetUp() override {
|
|
mTestDir = fs::temp_directory_path() / "lus_file_test";
|
|
fs::remove_all(mTestDir);
|
|
Directory::CreateDirectory(mTestDir.string());
|
|
mTestFile = mTestDir / "test.bin";
|
|
}
|
|
|
|
void TearDown() override {
|
|
fs::remove_all(mTestDir);
|
|
}
|
|
};
|
|
|
|
TEST_F(FileHelperTest, ExistsReturnsFalseForMissingFile) {
|
|
EXPECT_FALSE(Ship::FileHelper::Exists(mTestDir / "nothere.txt"));
|
|
}
|
|
|
|
TEST_F(FileHelperTest, ExistsReturnsTrueAfterWrite) {
|
|
Ship::FileHelper::WriteAllBytes(mTestFile.string(), std::vector<char>{ 0x01, 0x02, 0x03 });
|
|
EXPECT_TRUE(Ship::FileHelper::Exists(mTestFile));
|
|
}
|
|
|
|
TEST_F(FileHelperTest, WriteAndReadAllBytesRoundTrip) {
|
|
std::vector<uint8_t> data = { 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE };
|
|
Ship::FileHelper::WriteAllBytes(mTestFile, data);
|
|
auto read = Ship::FileHelper::ReadAllBytes(mTestFile);
|
|
EXPECT_EQ(read, data);
|
|
}
|
|
|
|
TEST_F(FileHelperTest, WriteAndReadAllBytesVectorCharOverload) {
|
|
std::vector<char> data = { 'h', 'e', 'l', 'l', 'o' };
|
|
Ship::FileHelper::WriteAllBytes(mTestFile.string(), data);
|
|
auto read = Ship::FileHelper::ReadAllBytes(mTestFile);
|
|
ASSERT_EQ(read.size(), data.size());
|
|
for (size_t i = 0; i < data.size(); i++) {
|
|
EXPECT_EQ(static_cast<char>(read[i]), data[i]);
|
|
}
|
|
}
|
|
|
|
TEST_F(FileHelperTest, WriteAndReadAllBytesRawPointerOverload) {
|
|
const char data[] = "rawdata";
|
|
Ship::FileHelper::WriteAllBytes(mTestFile.string(), data, sizeof(data) - 1);
|
|
auto read = Ship::FileHelper::ReadAllBytes(mTestFile);
|
|
ASSERT_EQ(read.size(), sizeof(data) - 1);
|
|
EXPECT_EQ(std::string(read.begin(), read.end()), "rawdata");
|
|
}
|
|
|
|
TEST_F(FileHelperTest, WriteAndReadAllTextRoundTrip) {
|
|
std::string content = "Hello, World!\nLine 2\n";
|
|
Ship::FileHelper::WriteAllText(mTestFile, content);
|
|
std::string result = Ship::FileHelper::ReadAllText(mTestFile);
|
|
EXPECT_EQ(result, content);
|
|
}
|
|
|
|
TEST_F(FileHelperTest, ReadAllLinesProducesCorrectCount) {
|
|
std::string content = "line1\nline2\nline3\n";
|
|
Ship::FileHelper::WriteAllText(mTestFile, content);
|
|
auto lines = Ship::FileHelper::ReadAllLines(mTestFile);
|
|
// Split on '\n': "line1", "line2", "line3", "" (trailing)
|
|
ASSERT_GE(lines.size(), 3u);
|
|
EXPECT_EQ(lines[0], "line1");
|
|
EXPECT_EQ(lines[1], "line2");
|
|
EXPECT_EQ(lines[2], "line3");
|
|
}
|
|
|
|
TEST_F(FileHelperTest, ReadAllBytesNonExistentFileReturnsEmpty) {
|
|
auto data = Ship::FileHelper::ReadAllBytes(mTestDir / "missing.bin");
|
|
EXPECT_TRUE(data.empty());
|
|
}
|
|
|
|
TEST_F(FileHelperTest, WriteAllBytesCreatesParentDirectory) {
|
|
fs::path nested = mTestDir / "subdir" / "nested.bin";
|
|
std::vector<char> data = { 0x01, 0x02 };
|
|
Ship::FileHelper::WriteAllBytes(nested.string(), data);
|
|
EXPECT_TRUE(Ship::FileHelper::Exists(nested));
|
|
}
|
|
|
|
TEST_F(FileHelperTest, WriteAllBytesUint8CreatesParentDirectory) {
|
|
fs::path nested = mTestDir / "subdir2" / "nested.bin";
|
|
std::vector<uint8_t> data = { 0x01, 0x02 };
|
|
Ship::FileHelper::WriteAllBytes(nested, data);
|
|
EXPECT_TRUE(Ship::FileHelper::Exists(nested));
|
|
}
|
|
|
|
TEST_F(FileHelperTest, WriteAllBytesRawPtrCreatesParentDirectory) {
|
|
fs::path nested = mTestDir / "subdir3" / "nested.bin";
|
|
const char payload[] = "hi";
|
|
Ship::FileHelper::WriteAllBytes(nested.string(), payload, static_cast<int>(sizeof(payload) - 1));
|
|
EXPECT_TRUE(Ship::FileHelper::Exists(nested));
|
|
}
|