diff --git a/tests/dbf_test.cc b/tests/dbf_test.cc index dff0189..e2d7307 100644 --- a/tests/dbf_test.cc +++ b/tests/dbf_test.cc @@ -1,6 +1,10 @@ +#include +#include +#include #include #include #include +#include #include #include @@ -14,9 +18,9 @@ namespace static const auto kTestData = fs::path{"shape_eg_data"}; -static bool SetContents(const fs::path &file_name, std::string_view content) +static bool SetContents(const fs::path &filename, std::string_view content) { - std::ofstream file(file_name); + std::ofstream file(filename); if (!file.is_open()) return false; file << content; @@ -27,27 +31,27 @@ static bool SetContents(const fs::path &file_name, std::string_view content) TEST(DBFOpenTest, OpenDoesNotExist_rb) { const auto handle = DBFOpen("/does/not/exist.dbf", "rb"); - EXPECT_EQ(nullptr, handle); + ASSERT_EQ(nullptr, handle); } TEST(DBFOpenTest, OpenDoesNotExist_rb_plus) { const auto handle = DBFOpen("/does/not/exist2.dbf", "rb+"); - EXPECT_EQ(nullptr, handle); + ASSERT_EQ(nullptr, handle); } TEST(DBFOpenTest, OpenUnexpectedFormat) { const auto filename = kTestData / "README.md"; const auto handle = DBFOpen(filename.string().c_str(), "rb"); - EXPECT_EQ(nullptr, handle); + ASSERT_EQ(nullptr, handle); } TEST(DBFOpenTest, OpenExisting) { const auto filename = kTestData / "anno.dbf"; const auto handle = DBFOpen(filename.string().c_str(), "rb"); - EXPECT_NE(nullptr, handle); + ASSERT_NE(nullptr, handle); DBFClose(handle); } @@ -64,7 +68,7 @@ TEST(DBFCreateTest, CreateAlreadyExisting) EXPECT_TRUE(SetContents(filename, "some content")); const auto handle = DBFCreate(filename.string().c_str()); // TODO(schwehr): Seems like a bug to overwrite an existing. - EXPECT_NE(nullptr, handle); + ASSERT_NE(nullptr, handle); DBFClose(handle); const auto size = fs::file_size(filename); EXPECT_EQ(34, size); @@ -81,6 +85,90 @@ TEST(DBFCreateTest, CreateAndClose) fs::remove(filename); } +static auto WriteDate(const fs::path &filename, + const std::unique_ptr &date) +{ + const auto handle = DBFCreate(filename.string().c_str()); + ASSERT_NE(nullptr, handle); + const auto fid = DBFAddField(handle, "date", FTDate, 8, 0); + EXPECT_GE(fid, 0); + const auto success = DBFWriteDateAttribute(handle, 0, fid, date.get()); + EXPECT_TRUE(success); + const auto recordcount = DBFGetRecordCount(handle); + EXPECT_EQ(1, recordcount); + DBFClose(handle); +} + +static auto ReadDate(const fs::path &filename) -> auto +{ + const auto handle = DBFOpen(filename.string().c_str(), "rb"); + EXPECT_NE(nullptr, handle); + const auto fieldcount = DBFGetFieldCount(handle); + EXPECT_EQ(1, fieldcount); + const auto fieldname = + std::make_unique>(); + int width, decimals; + const auto fieldtype = + DBFGetFieldInfo(handle, 0, fieldname->data(), &width, &decimals); + EXPECT_EQ(FTDate, fieldtype); + EXPECT_EQ(0, std::strcmp("date", fieldname->data())); + EXPECT_EQ(8, width); + EXPECT_EQ(0, decimals); + const auto recordcount = DBFGetRecordCount(handle); + EXPECT_EQ(1, recordcount); + const auto date = DBFReadDateAttribute(handle, 0, 0); + DBFClose(handle); + return std::make_unique(date); +} + +static auto GenerateUniqueFilename(std::string_view ext) -> auto +{ + const auto now = std::chrono::system_clock::now(); + const auto timestamp = + std::chrono::duration_cast( + now.time_since_epoch()) + .count(); + std::ostringstream oss; + oss << "test_" << timestamp << ext; + return oss.str(); +} + +TEST(DBFFieldTest, SetAndGetDateToday) +{ + const auto filename = + fs::temp_directory_path() / GenerateUniqueFilename(".dbf"); + const auto today = [] + { + const auto calendarTime = std::chrono::system_clock::to_time_t( + std::chrono::system_clock::now()); + const auto tlocal = std::localtime(&calendarTime); + return std::make_unique(SHPDate{ + 1900 + tlocal->tm_year, tlocal->tm_mon + 1, tlocal->tm_mday}); + }(); + WriteDate(filename, today); + const auto size = fs::file_size(filename); + EXPECT_EQ(75, size); + const auto date = ReadDate(filename); + EXPECT_EQ(today->year, date->year); + EXPECT_EQ(today->month, date->month); + EXPECT_EQ(today->day, date->day); + fs::remove(filename); +} + +TEST(DBFFieldTest, SetAndGetDateInvalid) +{ + const auto filename = + fs::temp_directory_path() / GenerateUniqueFilename(".dbf"); + WriteDate(filename, std::make_unique()); + const auto size = fs::file_size(filename); + EXPECT_EQ(75, size); + const auto date = ReadDate(filename); + EXPECT_EQ(0, date->year); + EXPECT_EQ(0, date->month); + EXPECT_EQ(0, date->day); + fs::remove(filename); +} + } // namespace int main(int argc, char **argv)