[csv-export-helpers.cpp] helper function and full test suite

This commit is contained in:
Christopher Lam 2023-04-01 13:51:14 +08:00
parent 5236f33709
commit e6352f5497
6 changed files with 246 additions and 0 deletions

View File

@ -1,5 +1,9 @@
add_subdirectory(test)
set(csv_export_SOURCES
gnc-plugin-csv-export.c
csv-export-helpers.cpp
assistant-csv-export.c
csv-tree-export.c
csv-transactions-export.c
@ -11,6 +15,7 @@ set_source_files_properties (${csv_export_SOURCES} PROPERTIES OBJECT_DEPENDS ${C
set(csv_export_noinst_HEADERS
gnc-plugin-csv-export.h
assistant-csv-export.h
csv-export-helpers.hpp
csv-tree-export.h
csv-transactions-export.h
)

View File

@ -0,0 +1,84 @@
/*******************************************************************\
* csv-export-helpers.c -- Functions to assist csv export *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License*
* along with this program; if not, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
* Boston, MA 02110-1301, USA gnu@gnu.org *
\********************************************************************/
/** @file csv-export-helprs.cpp
@brief CSV Export helper functions
@author Christopher Lam
*/
#include <config.h>
#include <cstring>
#include <cstdio>
#include <fstream>
#include <vector>
#include "gnc-ui-util.h"
#include "csv-export-helpers.hpp"
/* This static indicates the debugging module that this .o belongs to. */
[[maybe_unused]] static QofLogModule log_module = GNC_MOD_ASSISTANT;
/* CSV spec requires CRLF line endings. Tweak the end-of-line string so this
* true for each platform */
#ifdef G_OS_WIN32
# define EOLSTR "\n"
#else
# define EOLSTR "\r\n"
#endif
#define QUOTE '"'
bool
gnc_csv_add_line (std::ostream& ss, const StringVec& str_vec,
bool use_quotes, const char* sep)
{
auto first{true};
auto sep_view{std::string_view (sep ? sep : "")};
for (const auto& str : str_vec)
{
auto need_quote = use_quotes
|| (!sep_view.empty() && str.find (sep_view) != std::string::npos)
|| str.find_first_of ("\"\n\r") != std::string::npos;
if (first)
first = false;
else
ss << sep_view;
if (need_quote)
ss << QUOTE;
for (const char& p : str)
{
ss << p;
if (p == QUOTE)
ss << QUOTE;
}
if (need_quote)
ss << QUOTE;
if (ss.fail())
return false;
}
ss << EOLSTR;
return !ss.fail();
}

View File

@ -0,0 +1,39 @@
/*******************************************************************\
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License*
* along with this program; if not, contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
* Boston, MA 02110-1301, USA gnu@gnu.org *
\********************************************************************/
#ifndef CSV_EXPORT_HELPERS
#define CSV_EXPORT_HELPERS
#include <string>
#include <cstdio>
#include <fstream>
#include <vector>
using StringVec = std::vector<std::string>;
// add a csv-formatted line onto output stream. charsvec is the vector
// of std::strings, sep is the separator string. use_quotes to always
// "quote"; some strings may be quoted anyway if contains separator
// string, quote, \r or \n. This function returns a bool indicating
// success.
bool gnc_csv_add_line (std::ostream& ss, const StringVec& charsvec,
bool use_quotes, const char* sep);
#endif

View File

@ -0,0 +1,25 @@
set (test-csv-export-helpers_SOURCES
test-csv-export-helpers.cpp
)
set (test-csv-export-helpers_INCLUDE_DIRS
${CMAKE_BINARY_DIR}/common
${CMAKE_SOURCE_DIR}/libgnucash/engine
)
set (test-csv-export-helpers_LIBS
gnc-csv-export
gtest
)
gnc_add_test (test-csv-export-helpers
"${test-csv-export-helpers_SOURCES}"
test-csv-export-helpers_INCLUDE_DIRS
test-csv-export-helpers_LIBS
)
set_dist_list (test-csv-export_DIST
CMakeLists.txt
${test-csv-export-helpers_SOURCES}
)

View File

@ -0,0 +1,92 @@
/********************************************************************
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License*
* along with this program; if not, you can retrieve it from *
* https://www.gnu.org/licenses/old-licenses/gpl-2.0.html *
* or contact: *
* *
* Free Software Foundation Voice: +1-617-542-5942 *
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
* Boston, MA 02110-1301, USA gnu@gnu.org *
********************************************************************/
// #include "config.h"
#include "csv-export-helpers.hpp"
#include <gtest/gtest.h>
#include <sstream>
#ifdef G_OS_WIN32
# define EOLSTR "\n"
#else
# define EOLSTR "\r\n"
#endif
TEST (CsvHelperTest, EmptyTests)
{
std::ostringstream ss;
gnc_csv_add_line (ss, {}, false, nullptr);
ASSERT_EQ (ss.str(), EOLSTR);
std::ostringstream().swap(ss);
gnc_csv_add_line (ss, {}, true, ",");
ASSERT_EQ (ss.str(), EOLSTR);
std::ostringstream().swap(ss);
gnc_csv_add_line (ss, {}, false, ",");
ASSERT_EQ (ss.str(), EOLSTR);
std::ostringstream().swap(ss);
gnc_csv_add_line (ss, {}, true, nullptr);
ASSERT_EQ (ss.str(), EOLSTR);
}
TEST (CsvHelperTest, BasicTests)
{
std::ostringstream ss;
gnc_csv_add_line (ss, { "A","B","C","","D" }, false, ",");
ASSERT_EQ (ss.str(), "A,B,C,,D" EOLSTR);
std::ostringstream().swap(ss);
gnc_csv_add_line (ss, { "A","B","C","","D" }, false, "");
ASSERT_EQ (ss.str(), "ABCD" EOLSTR);
std::ostringstream().swap(ss);
gnc_csv_add_line (ss, { "A","B","C","","D" }, false, nullptr);
ASSERT_EQ (ss.str(), "ABCD" EOLSTR);
std::ostringstream().swap(ss);
gnc_csv_add_line (ss, { "A","B","C","","D" }, false, ";");
ASSERT_EQ (ss.str(), "A;B;C;;D" EOLSTR);
std::ostringstream().swap(ss);
gnc_csv_add_line (ss, { "A","B","C","","D" }, true, ",");
ASSERT_EQ (ss.str(), "\"A\",\"B\",\"C\",\"\",\"D\"" EOLSTR);
}
TEST (CsvHelperTest, ForcedQuote)
{
std::ostringstream ss;
gnc_csv_add_line (ss, { "A","B","C","\"","D" }, false, ",");
ASSERT_EQ (ss.str(), "A,B,C,\"\"\"\",D" EOLSTR);
std::ostringstream().swap(ss);
gnc_csv_add_line (ss, { "A","B","C","",",D" }, false, ",");
ASSERT_EQ (ss.str(), "A,B,C,,\",D\"" EOLSTR);
std::ostringstream().swap(ss);
gnc_csv_add_line (ss, { "A","B","C","\n","D\r" }, false, ";");
ASSERT_EQ (ss.str(), "A;B;C;\"\n\";\"D\r\"" EOLSTR);
}

View File

@ -326,6 +326,7 @@ gnucash/import-export/bi-import/dialog-bi-import-gui.c
gnucash/import-export/bi-import/dialog-bi-import-helper.c
gnucash/import-export/bi-import/gnc-plugin-bi-import.c
gnucash/import-export/csv-exp/assistant-csv-export.c
gnucash/import-export/csv-exp/csv-export-helpers.cpp
gnucash/import-export/csv-exp/csv-transactions-export.c
gnucash/import-export/csv-exp/csv-tree-export.c
gnucash/import-export/csv-exp/gnc-plugin-csv-export.c