summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2025-01-02 15:11:51 -0600
committerDominick Allen <djallen@librehumanitas.org>2025-01-02 15:11:51 -0600
commit87071200872c2450c947047350132aee493033c1 (patch)
tree49109532d9bbd148b4e59043120037684093be33 /test
parent16379362c02a2472f00fac49cad62788547c9519 (diff)
Get basic CSV parser operating.
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/test_common.cpp19
-rw-r--r--test/test_common.hpp4
-rw-r--r--test/test_csv.cpp74
-rw-r--r--test/test_directory.cpp4
-rw-r--r--test/test_file.cpp41
-rw-r--r--test/test_format.cpp9
-rw-r--r--test/test_string.cpp14
8 files changed, 135 insertions, 31 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 1ceca71..0a1a1e7 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -63,6 +63,7 @@ endfunction()
fud_add_test(test_fud SOURCES test_fud.cpp)
fud_add_test(test_allocator SOURCES test_allocator.cpp)
fud_add_test(test_assert SOURCES test_assert.cpp)
+fud_add_test(test_csv SOURCES test_csv.cpp)
# fud_add_test(test_c_file SOURCES test_c_file.cpp)
fud_add_test(test_directory SOURCES test_directory.cpp)
fud_add_test(test_file SOURCES test_file.cpp)
diff --git a/test/test_common.cpp b/test/test_common.cpp
index 07a0088..f272dad 100644
--- a/test/test_common.cpp
+++ b/test/test_common.cpp
@@ -74,7 +74,7 @@ int unlink_cb(const char* fpath, const struct stat* sb_unused, int typeflag, str
return retValue;
}
-FudStatus removeRecursive(const String& path)
+FudStatus removeRecursive(StringView path)
{
if (!path.utf8Valid()) {
return FudStatus::Utf8Invalid;
@@ -82,6 +82,9 @@ FudStatus removeRecursive(const String& path)
if (path.length() < 5) {
return FudStatus::ArgumentInvalid;
}
+ if (not path.nullTerminated()) {
+ return FudStatus::StringInvalid;
+ }
auto prefix{String::makeFromCString("/tmp/").takeOkay()};
auto diffResult = compareMem(path.data(), path.length(), prefix.data(), prefix.length());
if (diffResult.isError()) {
@@ -92,7 +95,8 @@ FudStatus removeRecursive(const String& path)
return FudStatus::ArgumentInvalid;
}
constexpr int maxOpenFd = 64;
- auto status = nftw(path.c_str(), unlink_cb, maxOpenFd, FTW_DEPTH | FTW_PHYS);
+
+ auto status = nftw(reinterpret_cast<const char*>(path.data()), unlink_cb, maxOpenFd, FTW_DEPTH | FTW_PHYS);
if (status == 0) {
return FudStatus::Success;
}
@@ -104,4 +108,15 @@ FudStatus removeRecursive(const String& path)
return FudStatus::Failure;
}
+auto rmFile(StringView filename) -> int
+{
+ auto result = unlink(filename.c_str());
+ if (result == -1) {
+ if (errno == ENOENT) {
+ return 0;
+ }
+ }
+ return result;
+}
+
} // namespace fud
diff --git a/test/test_common.hpp b/test/test_common.hpp
index 8912e42..5f6828f 100644
--- a/test/test_common.hpp
+++ b/test/test_common.hpp
@@ -81,7 +81,9 @@ struct MockFudAllocator {
extern MockFudAllocator globalMockFudAlloc;
class String;
-FudStatus removeRecursive(const String& path);
+class StringView;
+auto rmFile(StringView filename) -> int;
+FudStatus removeRecursive(StringView path);
} // namespace fud
diff --git a/test/test_csv.cpp b/test/test_csv.cpp
new file mode 100644
index 0000000..6923f6f
--- /dev/null
+++ b/test/test_csv.cpp
@@ -0,0 +1,74 @@
+/*
+ * libfud
+ * Copyright 2024 Dominick Allen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "fud_csv.hpp"
+#include "fud_print.hpp"
+
+#include "gtest/gtest.h"
+
+namespace fud {
+
+const StringView happyCsvFilename{u8"fud-happy-test.csv"};
+
+const StringView happyData{
+ u8"foo,bar,baz\n"
+ u8"1,Unquoted Text,\"Quoted Text with embedded \"\" quote and embedded newline \n"
+ u8"see\"\n,,\"Prior two fields are empty\"\n"};
+
+auto writeHappyCsv() -> FudStatus
+{
+ auto fileResult{RegularFile::create(
+ happyCsvFilename,
+ FileAccessMode::Write,
+ OpenFlags{OpenFlagEnum::Truncate},
+ PermUserRwGroupRead,
+ false,
+ NullOpt)};
+ if (fileResult.isError()) {
+ debugPrint(u8"Error opening file: {}\n", FudStatusToString(fileResult.getError()));
+ return fileResult.takeError();
+ }
+ auto file{fileResult.takeOkay()};
+
+ auto writeResult = file.write(reinterpret_cast<const std::byte*>(happyData.data()), happyData.length());
+ if (writeResult.status != FudStatus::Success) {
+ return writeResult.status;
+ }
+
+ if (writeResult.bytesDrained != happyData.length()) {
+ return FudStatus::Failure;
+ }
+
+ return FudStatus::Success;
+}
+
+TEST(FudCsv, ParseCsvFromFilename)
+{
+ Csv csv{Csv::makeDefault()};
+
+ ASSERT_EQ(writeHappyCsv(), FudStatus::Success);
+
+ debugPrint(u8"Wrote happy data:\n-----\n{}\n-----\n", happyData);
+
+ auto parseStatus = Csv::parseFromFilename(csv, NullOpt, happyCsvFilename);
+ if (parseStatus != FudStatus::Success) {
+ debugPrint(u8"Error parsing file: {}\n", FudStatusToString(parseStatus));
+ }
+ ASSERT_EQ(parseStatus, FudStatus::Success);
+}
+
+} // namespace fud
diff --git a/test/test_directory.cpp b/test/test_directory.cpp
index 96b9c2d..0f7dc8d 100644
--- a/test/test_directory.cpp
+++ b/test/test_directory.cpp
@@ -41,12 +41,12 @@ TEST(FudDirectory, Basic)
ASSERT_TRUE(files[0].utf8Valid());
ASSERT_TRUE(files[1].utf8Valid());
- ASSERT_EQ(removeRecursive(testDirName), FudStatus::Success);
+ ASSERT_EQ(removeRecursive(testDirName.asView()), FudStatus::Success);
auto mkdirResult = mkdir(testDirName.c_str(), pathMode);
EXPECT_EQ(mkdirResult, 0);
if (mkdirResult != 0) {
- ASSERT_EQ(removeRecursive(testDirName), FudStatus::Success);
+ ASSERT_EQ(removeRecursive(testDirName.asView()), FudStatus::Success);
return;
}
diff --git a/test/test_file.cpp b/test/test_file.cpp
index 9727e94..12cfb98 100644
--- a/test/test_file.cpp
+++ b/test/test_file.cpp
@@ -29,38 +29,27 @@
namespace fud {
-auto rmFile(const auto& filename) -> int
-{
- auto result = unlink(filename.c_str());
- if (result == -1) {
- if (errno == ENOENT) {
- return 0;
- }
- }
- return result;
-}
-
TEST(FudFile, Basic)
{
- constexpr const char* testDirCName = "/tmp/fud_directory_test";
- const auto testDirName{String::makeFromCString(testDirCName).takeOkay()};
+ StringView testDirCName{StringView::makeFromCString("/tmp/fud_directory_test")};
+ const auto testDirName{String::from(testDirCName).takeOkay()};
ASSERT_TRUE(testDirName.utf8Valid());
constexpr mode_t pathMode = 0777;
- ASSERT_EQ(removeRecursive(testDirName), FudStatus::Success);
+ ASSERT_EQ(removeRecursive(testDirName.asView()), FudStatus::Success);
- auto mkdirResult = mkdir(testDirName.c_str(), pathMode);
+ auto mkdirResult = mkdir(testDirCName.c_str(), pathMode);
EXPECT_EQ(mkdirResult, 0);
if (mkdirResult != 0) {
- ASSERT_EQ(removeRecursive(testDirName), FudStatus::Success);
+ ASSERT_EQ(removeRecursive(testDirCName), FudStatus::Success);
return;
}
- String testName1{String::makeFromCStrings(testDirCName, "/", "test1").takeOkay()};
- String testName2{String::makeFromCStrings(testDirCName, "/", "test2").takeOkay()};
+ String testName1{String::makeFromCStrings(testDirCName.c_str(), "/", "test1").takeOkay()};
+ String testName2{String::makeFromCStrings(testDirCName.c_str(), "/", "test2").takeOkay()};
- ASSERT_EQ(rmFile(testName1), 0);
- ASSERT_EQ(rmFile(testName2), 0);
+ ASSERT_EQ(rmFile(testName1.asView()), 0);
+ ASSERT_EQ(rmFile(testName2.asView()), 0);
auto fileResult{RegularFile::open(testName1.asView(), FileAccessMode::Read, OpenFlags{}, NullOpt)};
EXPECT_EQ(fileResult.takeErrorOr(FudStatus::Success), FudStatus::NotFound);
@@ -83,8 +72,8 @@ TEST(FudFile, Basic)
auto file{fileResult.takeOkay()};
ASSERT_EQ(file.close(), FudStatus::Success);
- ASSERT_EQ(rmFile(testName1), 0);
- ASSERT_GE(createFile(testName2), 0);
+ ASSERT_EQ(rmFile(testName1.asView()), 0);
+ ASSERT_GE(createFile(testName2.asView()), 0);
ASSERT_EQ(symlink(testName2.c_str(), testName1.c_str()), 0);
fileResult = RegularFile::open(testName2.asView(), FileAccessMode::Read, OpenFlags{}, NullOpt);
@@ -99,9 +88,9 @@ TEST(FudFile, Basic)
TEST(FudBufferedFile, OpenReadWrite)
{
- constexpr const char* testDirCName = "/tmp/fud_directory_test";
- const auto testDirName{String::makeFromCString(testDirCName).takeOkay()};
+ StringView testDirName{StringView::makeFromCString("/tmp/fud_directory_test")};
ASSERT_TRUE(testDirName.utf8Valid());
+ ASSERT_TRUE(testDirName.nullTerminated());
constexpr mode_t pathMode = 0777;
ASSERT_EQ(removeRecursive(testDirName), FudStatus::Success);
@@ -113,7 +102,7 @@ TEST(FudBufferedFile, OpenReadWrite)
return;
}
- String testName{String::makeFromCStrings(testDirCName, "/", "test1").takeOkay()};
+ String testName{String::makeFromCStrings(testDirName.c_str(), "/", "test1").takeOkay()};
auto fileResult{RegularFile::create(
testName.asView(),
FileAccessMode::ReadWrite,
@@ -171,7 +160,7 @@ TEST(FudBufferedFile, OpenReadWrite)
EXPECT_EQ(output[testName.size() - 1], testName.data()[testName.size() - 1]);
EXPECT_EQ(bufferedFile.close(true), FudStatus::Success);
- ASSERT_EQ(rmFile(testName), 0);
+ ASSERT_EQ(rmFile(testName.asView()), 0);
}
} // namespace fud
diff --git a/test/test_format.cpp b/test/test_format.cpp
index b9d373c..738b551 100644
--- a/test/test_format.cpp
+++ b/test/test_format.cpp
@@ -709,4 +709,13 @@ TEST(FormatTest, TwoArgFormatTest)
EXPECT_STREQ(sink.c_str(), expected.c_str());
}
+TEST(FormatTest, StringView)
+{
+ String sink{};
+ auto expected = std::format("Test {}", std::string_view{"Hello, World!"});
+ auto formatResult = format(sink, FormatCharMode::Unchecked, u8"Test {}", StringView{u8"Hello, World!"});
+ EXPECT_TRUE(formatResult.isOkay());
+ EXPECT_STREQ(sink.c_str(), expected.c_str());
+}
+
} // namespace fud
diff --git a/test/test_string.cpp b/test/test_string.cpp
index 6bcbd37..ba2df6c 100644
--- a/test/test_string.cpp
+++ b/test/test_string.cpp
@@ -56,11 +56,25 @@ TEST(FudString, BasicStringOps)
StringView view1{};
ASSERT_FALSE(view1.utf8Valid());
+
StringView view2{fudString};
ASSERT_TRUE(view2.utf8Valid());
ASSERT_TRUE(view2.nullTerminated());
}
+TEST(FudString, ViewFromCString)
+{
+ StringView viewFromU8{u8"Test"};
+ EXPECT_EQ(viewFromU8.length(), 4);
+ EXPECT_TRUE(viewFromU8.utf8Valid());
+ EXPECT_TRUE(viewFromU8.nullTerminated());
+
+ StringView viewFromCString{StringView::makeFromCString("Test")};
+ EXPECT_EQ(viewFromCString.length(), 4);
+ EXPECT_TRUE(viewFromCString.utf8Valid());
+ EXPECT_TRUE(viewFromCString.nullTerminated());
+}
+
TEST(FudString, HeapAlloc)
{
constexpr const char filenameLiteral[] = "Amazing Saga Volume 01/000.jpg";