mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-16 18:25:11 -06:00
Merge branch 'maint'
Resolved conflicts: src/import-export/csv-imp/gnc-csv-model.h src/libqof/qof/gnc-date.h src/optional/gtkmm/test/Makefile.am
This commit is contained in:
commit
ce748cceb8
@ -15,6 +15,7 @@ dist_doc_DATA = \
|
||||
AUTHORS \
|
||||
COPYING \
|
||||
ChangeLog \
|
||||
ChangeLog.2015 \
|
||||
ChangeLog.2014 \
|
||||
ChangeLog.2013 \
|
||||
ChangeLog.2012 \
|
||||
|
11
configure.ac
11
configure.ac
@ -93,11 +93,11 @@ AC_DEFINE_UNQUOTED(GNUCASH_LATEST_STABLE_SERIES, "$GNUCASH_LATEST_STABLE_SERIES"
|
||||
[Most recent stable GnuCash series])
|
||||
|
||||
dnl Set of available languages.
|
||||
TP_LINGUAS="az ca cs da eu fa ja nl pt rw sk sr sv tr uk zh_CN"
|
||||
TP_LINGUAS="az ca cs da eu fa ja nl rw sk sr sv tr uk zh_CN"
|
||||
dnl already marked as external at TP:
|
||||
GC_LINGUAS="ar bg de el en_GB es fi fr gu he hi hu it kn ko lt lv mr nb ne pl pt_BR ro ru ta te ur vi zh_TW "
|
||||
GC_LINGUAS="ar bg de el en_GB es fi fr gu he hi hu it kn ko lt lv mr nb ne pl pt pt_BR ro ru ta te ur vi zh_TW "
|
||||
dnl not marked or no TP team:
|
||||
NEW_LINGUAS="as brx doi es_NI kok kok@latin ks mai mni mni@bengali pt_PT"
|
||||
NEW_LINGUAS="as brx doi es_NI kok kok@latin ks mai mni mni@bengali"
|
||||
|
||||
ALL_LINGUAS="$TP_LINGUAS $GC_LINGUAS $NEW_LINGUAS"
|
||||
|
||||
@ -568,7 +568,7 @@ AC_SUBST(GUILE, [`pwd`/gnc-guile])
|
||||
AC_CHECK_HEADERS(ltdl.h,
|
||||
[],
|
||||
[AC_MSG_ERROR([ltdl.h not found. Perhaps you need to install
|
||||
the intltool-ltdl development packages ?])])
|
||||
the libtool(-ltdl) development package?])])
|
||||
|
||||
### --------------------------------------------------------------------------
|
||||
### SWIG version checks (only when building from SCM)
|
||||
@ -1743,6 +1743,7 @@ AC_CONFIG_FILES(
|
||||
src/import-export/ofx/test/Makefile
|
||||
src/import-export/csv-imp/Makefile
|
||||
src/import-export/csv-imp/gschemas/Makefile
|
||||
src/import-export/csv-imp/test/Makefile
|
||||
src/import-export/csv-exp/Makefile
|
||||
src/import-export/csv-exp/gschemas/Makefile
|
||||
src/import-export/log-replay/Makefile
|
||||
@ -1876,6 +1877,8 @@ AC_CONFIG_FILES([src/tax/us/test/test-load-module],
|
||||
|
||||
# A few files need extra actions at creation time
|
||||
AC_CONFIG_FILES([src/bin/overrides/gnucash-make-guids], [chmod u+x src/bin/overrides/gnucash-make-guids])
|
||||
#Link (copy on Windows) test data files:
|
||||
AC_CONFIG_LINKS([src/import-export/csv-imp/test/sample1.csv:src/import-export/csv-imp/test/sample1.csv])
|
||||
LDFLAGS="${LDFLAGS} ${NOUNDEF}"
|
||||
AC_OUTPUT
|
||||
|
||||
|
25695
po/pt_PT.po
25695
po/pt_PT.po
File diff suppressed because it is too large
Load Diff
@ -603,6 +603,8 @@ gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page)
|
||||
{
|
||||
case GNC_OWNER_NONE :
|
||||
case GNC_OWNER_UNDEFINED :
|
||||
PWARN("missing owner_type");
|
||||
label = _("Unknown");
|
||||
break;
|
||||
case GNC_OWNER_CUSTOMER :
|
||||
label = _("Customers");
|
||||
|
@ -208,6 +208,21 @@ gnc_utf8_strip_invalid_strdup(const gchar* str)
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_utf8_strip_invalid_and_controls (gchar *str)
|
||||
{
|
||||
gchar *c = NULL;
|
||||
const gchar *controls = "\b\f\n\r\t\v";
|
||||
g_return_if_fail (str != NULL && strlen (str) > 0);
|
||||
gnc_utf8_strip_invalid (str); /* First fix the UTF-8 */
|
||||
for(c = str + strlen (str) - 1; c != str; --c)
|
||||
{
|
||||
gboolean line_control = ((unsigned char)(*c) < 0x20);
|
||||
if (line_control || strchr(controls, *c) != NULL)
|
||||
*c = ' '; /*replace controls with a single space. */
|
||||
}
|
||||
}
|
||||
|
||||
gchar *
|
||||
gnc_locale_from_utf8(const gchar* str)
|
||||
{
|
||||
|
@ -108,6 +108,14 @@ void gnc_utf8_strip_invalid (gchar *str);
|
||||
* caller. */
|
||||
gchar *gnc_utf8_strip_invalid_strdup (const gchar* str);
|
||||
|
||||
/** Strip any non-utf8 characters and any control characters (everything < 0x20,
|
||||
* \b, \f, \n, \r, \t, and \v) from a string. Rewrites the string in-place.
|
||||
*
|
||||
* @param str Pointer to the string to clean up.
|
||||
*/
|
||||
|
||||
void gnc_utf8_strip_invalid_and_controls (gchar* str);
|
||||
|
||||
/**
|
||||
* @brief Converts a string from UTF-8 to the encoding used for
|
||||
* strings in the current locale.
|
||||
|
@ -1,3 +1,5 @@
|
||||
include $(top_srcdir)/test-templates/Makefile.decl
|
||||
MODULEPATH = src/core-utils
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I${top_srcdir} \
|
||||
@ -17,9 +19,11 @@ LDADD = \
|
||||
# these tests are ordered kind more or less in the order
|
||||
# that they should be executed, with more basic tests coming first.
|
||||
#
|
||||
|
||||
TESTS = \
|
||||
test-gnc-uri-utils \
|
||||
test-resolve-file-path
|
||||
test-resolve-file-path \
|
||||
test-gnc-glib-utils
|
||||
|
||||
GNC_TEST_DEPS = \
|
||||
--library-dir ${top_builddir}/src/libqof/qof \
|
||||
@ -29,10 +33,21 @@ TESTS_ENVIRONMENT = \
|
||||
SRCDIR=${srcdir} \
|
||||
$(shell ${abs_top_srcdir}/src/gnc-test-env.pl --noexports ${GNC_TEST_DEPS})
|
||||
|
||||
check_PROGRAMS = \
|
||||
test-gnc-uri-utils \
|
||||
test-resolve-file-path
|
||||
check_PROGRAMS = ${TESTS}
|
||||
|
||||
test_gnc_glib_utils_SOURCES = \
|
||||
$(top_srcdir)/$(MODULEPATH)/gnc-glib-utils.c \
|
||||
test-gnc-glib-utils.c
|
||||
|
||||
test_gnc_glib_utils_LDADD = \
|
||||
${top_builddir}/src/libqof/qof/libgnc-qof.la \
|
||||
${top_builddir}/src/test-core/libtest-core.la \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
test_gnc_glib_utils_CFLAGS = \
|
||||
${DEFAULT_INCLUDES} \
|
||||
-I${top_srcdir}/${MODULEPATH} \
|
||||
${GLIB_CFLAGS}
|
||||
|
||||
EXTRA_DIST =
|
||||
|
||||
|
67
src/core-utils/test/test-gnc-glib-utils.c
Normal file
67
src/core-utils/test/test-gnc-glib-utils.c
Normal file
@ -0,0 +1,67 @@
|
||||
/********************************************************************
|
||||
* testmain.c: GLib g_test test execution file. *
|
||||
* Copyright 2011 John Ralls <jralls@ceridwen.us> *
|
||||
* *
|
||||
* 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 *
|
||||
\********************************************************************/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <gnc-glib-utils.h>
|
||||
#include <unittest-support.h>
|
||||
|
||||
static void
|
||||
test_gnc_utf8_strip_invalid_and_controls (gconstpointer data)
|
||||
{
|
||||
gchar *str = g_strdup (data);
|
||||
const gchar *controls = "\b\f\n\r\t\v\x01\x02\x03\x04\x05\x06\x07"
|
||||
"\x08\x09\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16"
|
||||
"\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
|
||||
char *msg1 = g_strdup_printf ("Invalid utf8 string: %s",
|
||||
(const gchar*)data);
|
||||
const GLogLevelFlags level = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
|
||||
TestErrorStruct check = {level, NULL, msg1, 0};
|
||||
|
||||
guint handler = g_log_set_handler (NULL, level,
|
||||
(GLogFunc)test_null_handler, &check);
|
||||
g_test_log_set_fatal_handler((GTestLogFatalFunc)test_checked_handler,
|
||||
&check);
|
||||
|
||||
gnc_utf8_strip_invalid_and_controls (str);
|
||||
g_assert (g_utf8_validate(str, -1, NULL) == TRUE);
|
||||
g_assert (strpbrk(str, controls) == NULL);
|
||||
g_assert (g_utf8_strlen(str, -1) > 0);
|
||||
g_log_remove_handler (NULL, handler);
|
||||
g_free (str);
|
||||
g_free (msg1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
const gchar *invalid_utf8 = "Η γρήγορη καφέ αλεπού πήδηξε πάνω από την \xb2\xf3ργή σκύλο.";
|
||||
const gchar *controls = "Η γρήγορη καφέ αλεπού\bπήδηξε\nπάνω από\tτην αργή σκύλο.";
|
||||
g_test_init (&argc, &argv, NULL); // initialize test program
|
||||
g_test_add_data_func ("/core-utils/gnc_utf8_strip_invalid_and_controls invalid utf8", (gconstpointer)invalid_utf8, test_gnc_utf8_strip_invalid_and_controls);
|
||||
g_test_add_data_func ("/core-utils/gnc_utf8_strip_invalid_and_controls control chars", (gconstpointer)controls, test_gnc_utf8_strip_invalid_and_controls);
|
||||
|
||||
return g_test_run();
|
||||
}
|
@ -565,6 +565,19 @@
|
||||
smallest-fraction="100"
|
||||
local-symbol="Br"
|
||||
/>
|
||||
<!-- "BYN" - "Belarussian Ruble"
|
||||
-->
|
||||
<currency
|
||||
isocode="BYN"
|
||||
fullname="Belarussian Ruble"
|
||||
unitname="ruble"
|
||||
partname="kapeyka"
|
||||
namespace="ISO4217"
|
||||
exchange-code="933"
|
||||
parts-per-unit="100"
|
||||
smallest-fraction="1"
|
||||
local-symbol="Br"
|
||||
/>
|
||||
<!-- "BZD" - "Belize Dollar"
|
||||
-->
|
||||
<currency
|
||||
|
@ -837,7 +837,7 @@ xaccAccountCommitEdit checks the flag and finding it true:
|
||||
Again checking that the book isn't shutting down:
|
||||
run destroy_pending_splits_for_account
|
||||
destroy all of the lots in the lots list (again, destroy, not unref or even dispose)
|
||||
free the lot list (regardless of whether the book is shuttin down) and NULL the pointer
|
||||
free the lot list (regardless of whether the book is shutting down) and NULL the pointer
|
||||
set the instance dirty
|
||||
unconditionally calls qof_commit_edit_part2 with acc_free
|
||||
qof_commit_edit_part2:
|
||||
|
@ -73,6 +73,7 @@ gnc_show_splash_screen (void)
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (splash), "GnuCash");
|
||||
gtk_window_set_position (GTK_WINDOW (splash), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_type_hint (GTK_WINDOW (splash), GDK_WINDOW_TYPE_HINT_DIALOG);
|
||||
|
||||
pixmap = gnc_gnome_get_pixmap ("gnucash_splash.png");
|
||||
|
||||
|
@ -363,9 +363,36 @@ gnc_tree_view_owner_new (GncOwnerType owner_type)
|
||||
GncTreeView *view;
|
||||
GtkTreeModel *model, *f_model, *s_model;
|
||||
const gchar *sample_type, *sample_currency;
|
||||
const gchar *owner_name = NULL, * owner_id = NULL;
|
||||
GncTreeViewOwnerPrivate *priv;
|
||||
|
||||
ENTER(" ");
|
||||
|
||||
switch (owner_type)
|
||||
{
|
||||
case GNC_OWNER_NONE :
|
||||
case GNC_OWNER_UNDEFINED :
|
||||
PWARN("missing owner_type");
|
||||
owner_name = _("Name");
|
||||
owner_id = _("ID #");
|
||||
break;
|
||||
case GNC_OWNER_CUSTOMER :
|
||||
owner_name = _("Company Name");
|
||||
owner_id = _("Customer Number");
|
||||
break;
|
||||
case GNC_OWNER_JOB :
|
||||
owner_name = _("Job Name");
|
||||
owner_id = _("Job Number");
|
||||
break;
|
||||
case GNC_OWNER_VENDOR :
|
||||
owner_name = _("Company Name");
|
||||
owner_id = _("Vendor Number");
|
||||
break;
|
||||
case GNC_OWNER_EMPLOYEE :
|
||||
owner_name = _("Employee Name");
|
||||
owner_id = _("Employee Number");
|
||||
break;
|
||||
}
|
||||
/* Create our view */
|
||||
view = g_object_new (GNC_TYPE_TREE_VIEW_OWNER,
|
||||
"name", "owner_tree", NULL);
|
||||
@ -394,7 +421,7 @@ gnc_tree_view_owner_new (GncOwnerType owner_type)
|
||||
sample_currency = gnc_commodity_get_fullname(gnc_default_currency());
|
||||
|
||||
priv->name_column
|
||||
= gnc_tree_view_add_text_column(view, _("Owner Name"), GNC_OWNER_TREE_NAME_COL,
|
||||
= gnc_tree_view_add_text_column(view, owner_name, GNC_OWNER_TREE_NAME_COL,
|
||||
NULL, "GnuCash Inc.",
|
||||
GNC_TREE_MODEL_OWNER_COL_NAME,
|
||||
GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
|
||||
@ -405,7 +432,7 @@ gnc_tree_view_owner_new (GncOwnerType owner_type)
|
||||
GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
|
||||
sort_by_string);
|
||||
priv->id_column
|
||||
= gnc_tree_view_add_text_column(view, _("Owner ID"), GNC_OWNER_TREE_ID_COL,
|
||||
= gnc_tree_view_add_text_column(view, owner_id, GNC_OWNER_TREE_ID_COL,
|
||||
NULL, "1-123-1234",
|
||||
GNC_TREE_MODEL_OWNER_COL_ID,
|
||||
GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
|
||||
|
@ -1,4 +1,4 @@
|
||||
SUBDIRS = . gschemas
|
||||
SUBDIRS = . gschemas test
|
||||
|
||||
pkglib_LTLIBRARIES=libgncmod-csv-import.la
|
||||
|
||||
|
@ -717,7 +717,7 @@ csv_import_trans_file_chooser_confirm_cb (GtkWidget *button, CsvImportTrans *inf
|
||||
{
|
||||
/* If we couldn't load the file ... */
|
||||
gnc_error_dialog (NULL, "%s", error->message);
|
||||
if (error->code == GNC_CSV_FILE_OPEN_ERR)
|
||||
if (error->code == GNC_CSV_IMP_ERROR_OPEN)
|
||||
{
|
||||
g_free (file_name);
|
||||
gnc_csv_parse_data_free (parse_data);
|
||||
|
@ -50,6 +50,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
GQuark
|
||||
gnc_csv_imp_error_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("g-csv-imp-error-quark");
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_IMPORT;
|
||||
|
||||
const int num_date_formats = 5;
|
||||
@ -158,10 +164,14 @@ static time64 parse_date_with_year (const char* date_str, int format)
|
||||
}
|
||||
}
|
||||
|
||||
/* Put some sane values in retvalue by using the current time for
|
||||
/* Put some sane values in retvalue by using a fixed time for
|
||||
* the non-year-month-day parts of the date. */
|
||||
gnc_time (&rawtime);
|
||||
gnc_localtime_r (&rawtime, &retvalue);
|
||||
retvalue.tm_hour = 11;
|
||||
retvalue.tm_min = 0;
|
||||
retvalue.tm_sec = 0;
|
||||
retvalue.tm_isdst = -1;
|
||||
|
||||
/* j traverses pmatch (index 0 contains the entire string, so we
|
||||
* start at index 1 for the first meaningful match). */
|
||||
@ -181,7 +191,7 @@ static time64 parse_date_with_year (const char* date_str, int format)
|
||||
date_segment[mem_length] = '\0';
|
||||
|
||||
/* Set the appropriate member of retvalue. Save the original
|
||||
* values so that we can check if the change when we use gnc_mktime
|
||||
* values so that we can check if they change when we use gnc_mktime
|
||||
* below. */
|
||||
switch (segment_type)
|
||||
{
|
||||
@ -268,10 +278,14 @@ static time64 parse_date_without_year (const char* date_str, int format)
|
||||
if (pmatch[0].rm_eo == 0)
|
||||
return -1;
|
||||
|
||||
/* Put some sane values in retvalue by using the current time for
|
||||
/* Put some sane values in retvalue by using a fixed time for
|
||||
* the non-year-month-day parts of the date. */
|
||||
gnc_time (&rawtime);
|
||||
gnc_localtime_r (&rawtime, &retvalue);
|
||||
retvalue.tm_hour = 11;
|
||||
retvalue.tm_min = 0;
|
||||
retvalue.tm_sec = 0;
|
||||
retvalue.tm_isdst = -1;
|
||||
orig_year = retvalue.tm_year;
|
||||
|
||||
/* j traverses pmatch (index 0 contains the entire string, so we
|
||||
@ -293,7 +307,7 @@ static time64 parse_date_without_year (const char* date_str, int format)
|
||||
date_segment[mem_length] = '\0';
|
||||
|
||||
/* Set the appropriate member of retvalue. Save the original
|
||||
* values so that we can check if the change when we use gnc_mktime
|
||||
* values so that we can check if they change when we use gnc_mktime
|
||||
* below. */
|
||||
switch (segment_type)
|
||||
{
|
||||
@ -357,6 +371,7 @@ GncCsvParseData* gnc_csv_new_parse_data (void)
|
||||
/* All of the data pointers are initially NULL. This is so that, if
|
||||
* gnc_csv_parse_data_free is called before all of the data is
|
||||
* initialized, only the data that needs to be freed is freed. */
|
||||
parse_data->raw_mapping = NULL;
|
||||
parse_data->raw_str.begin = parse_data->raw_str.end
|
||||
= parse_data->file_str.begin = parse_data->file_str.end = NULL;
|
||||
parse_data->orig_lines = NULL;
|
||||
@ -417,7 +432,7 @@ void gnc_csv_parse_data_free (GncCsvParseData* parse_data)
|
||||
g_list_free (parse_data->transactions);
|
||||
}
|
||||
|
||||
g_free (parse_data->chunk);
|
||||
g_string_chunk_free (parse_data->chunk);
|
||||
g_free (parse_data);
|
||||
}
|
||||
|
||||
@ -475,14 +490,13 @@ int gnc_csv_load_file (GncCsvParseData* parse_data, const char* filename,
|
||||
const char* guess_enc = NULL;
|
||||
|
||||
/* Get the raw data first and handle an error if one occurs. */
|
||||
parse_data->raw_mapping = g_mapped_file_new (filename, FALSE, error);
|
||||
parse_data->raw_mapping = g_mapped_file_new (filename, FALSE, NULL);
|
||||
if (parse_data->raw_mapping == NULL)
|
||||
{
|
||||
/* TODO Handle file opening errors more specifically,
|
||||
* e.g. inexistent file versus no read permission. */
|
||||
parse_data->raw_str.begin = NULL;
|
||||
g_clear_error (error);
|
||||
g_set_error (error, 0, GNC_CSV_FILE_OPEN_ERR, "%s", _("File opening failed."));
|
||||
g_set_error (error, GNC_CSV_IMP_ERROR, GNC_CSV_IMP_ERROR_OPEN, "%s", _("File opening failed."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -497,7 +511,7 @@ int gnc_csv_load_file (GncCsvParseData* parse_data, const char* filename,
|
||||
"UTF-8", NULL);
|
||||
if (guess_enc == NULL)
|
||||
{
|
||||
g_set_error (error, 0, GNC_CSV_ENCODING_ERR, "%s", _("Unknown encoding."));
|
||||
g_set_error (error, GNC_CSV_IMP_ERROR, GNC_CSV_IMP_ERROR_ENCODING, "%s", _("Unknown encoding."));
|
||||
return 1;
|
||||
}
|
||||
/* Convert using the guessed encoding into parse_data->file_str and
|
||||
@ -505,7 +519,7 @@ int gnc_csv_load_file (GncCsvParseData* parse_data, const char* filename,
|
||||
gnc_csv_convert_encoding (parse_data, guess_enc, error);
|
||||
if (parse_data->file_str.begin == NULL)
|
||||
{
|
||||
g_set_error (error, 0, GNC_CSV_ENCODING_ERR, "%s", _("Unknown encoding."));
|
||||
g_set_error (error, GNC_CSV_IMP_ERROR, GNC_CSV_IMP_ERROR_ENCODING, "%s", _("Unknown encoding."));
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -568,7 +582,7 @@ int gnc_csv_parse (GncCsvParseData* parse_data, gboolean guessColTypes, GError**
|
||||
/* If it failed, generate an error. */
|
||||
if (parse_data->orig_lines == NULL)
|
||||
{
|
||||
g_set_error (error, 0, 0, "Parsing failed.");
|
||||
g_set_error (error, GNC_CSV_IMP_ERROR, GNC_CSV_IMP_ERROR_PARSE, "Parsing failed.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -38,27 +38,34 @@
|
||||
* columns that can exist in a CSV/Fixed-Width file. There should be
|
||||
* no two columns with the same type except for the GNC_CSV_NONE
|
||||
* type. */
|
||||
enum GncCsvColumnType {GNC_CSV_NONE,
|
||||
GNC_CSV_DATE,
|
||||
GNC_CSV_NUM,
|
||||
GNC_CSV_DESCRIPTION,
|
||||
GNC_CSV_NOTES,
|
||||
GNC_CSV_ACCOUNT,
|
||||
GNC_CSV_DEPOSIT,
|
||||
GNC_CSV_WITHDRAWAL,
|
||||
GNC_CSV_BALANCE,
|
||||
GNC_CSV_MEMO,
|
||||
GNC_CSV_OACCOUNT,
|
||||
GNC_CSV_OMEMO,
|
||||
GNC_CSV_NUM_COL_TYPES
|
||||
};
|
||||
enum GncCsvColumnType {
|
||||
GNC_CSV_NONE,
|
||||
GNC_CSV_DATE,
|
||||
GNC_CSV_NUM,
|
||||
GNC_CSV_DESCRIPTION,
|
||||
GNC_CSV_NOTES,
|
||||
GNC_CSV_ACCOUNT,
|
||||
GNC_CSV_DEPOSIT,
|
||||
GNC_CSV_WITHDRAWAL,
|
||||
GNC_CSV_BALANCE,
|
||||
GNC_CSV_MEMO,
|
||||
GNC_CSV_OACCOUNT,
|
||||
GNC_CSV_OMEMO,
|
||||
GNC_CSV_NUM_COL_TYPES
|
||||
};
|
||||
|
||||
/** Error domain for the csv importer. */
|
||||
#define GNC_CSV_IMP_ERROR gnc_csv_imp_error_quark ()
|
||||
GQuark gnc_csv_imp_error_quark (void);
|
||||
|
||||
/** Enumeration for error types. These are the different types of
|
||||
* errors that various functions used for the CSV/Fixed-Width importer
|
||||
* can have. */
|
||||
enum GncCsvErrorType {GNC_CSV_FILE_OPEN_ERR,
|
||||
GNC_CSV_ENCODING_ERR
|
||||
};
|
||||
enum GncCsvErrorType {
|
||||
GNC_CSV_IMP_ERROR_OPEN,
|
||||
GNC_CSV_IMP_ERROR_ENCODING,
|
||||
GNC_CSV_IMP_ERROR_PARSE
|
||||
};
|
||||
|
||||
/** Struct for containing a string. This struct simply contains
|
||||
* pointers to the beginning and end of a string. We need this because
|
||||
|
98
src/import-export/csv-imp/test/Makefile.am
Normal file
98
src/import-export/csv-imp/test/Makefile.am
Normal file
@ -0,0 +1,98 @@
|
||||
# A template Makefile.am for GLib g_test-based test directories.
|
||||
# Copyright 2011 John Ralls <jralls@ceridwen.us>
|
||||
|
||||
include $(top_srcdir)/test-templates/Makefile.decl
|
||||
|
||||
|
||||
#You will only need one of these: It points to the module directory
|
||||
#after $(top_srcdir) or ${top_builddir}:
|
||||
MODULEPATH = src/import-export/csv-imp
|
||||
|
||||
#The test program. You'll need to add to this if you have more than one module above.
|
||||
|
||||
check_PROGRAMS = test-csv-imp
|
||||
|
||||
TESTS = ${check_PROGRAMS}
|
||||
|
||||
test_csv_impdir = ${top_srcdir}/${MODULEPATH}/test
|
||||
|
||||
#Program files for tests go here. It's probably best to have one for
|
||||
#each file in the parent directory. Include
|
||||
#test_foo_support.c if you have one and aren't building the
|
||||
#support library.
|
||||
test_csv_imp_SOURCES = \
|
||||
test-csv-imp.c \
|
||||
utest-gnc-csv-model.c
|
||||
|
||||
test_csv_imp_HEADERS =
|
||||
|
||||
#The tests might require more libraries, but try to keep them
|
||||
#as independent as possible.
|
||||
test_csv_imp_LDADD = \
|
||||
${top_builddir}/${MODULEPATH}/libgncmod-csv-import.la \
|
||||
${top_builddir}/src/import-export/libgncmod-generic-import.la \
|
||||
${top_builddir}/src/gnome/libgnc-gnome.la \
|
||||
${top_builddir}/src/gnome-utils/libgncmod-gnome-utils.la \
|
||||
${top_builddir}/src/register/ledger-core/libgncmod-ledger-core.la \
|
||||
${top_builddir}/src/report/report-gnome/libgncmod-report-gnome.la \
|
||||
${top_builddir}/src/app-utils/libgncmod-app-utils.la \
|
||||
${top_builddir}/src/backend/xml/libgnc-backend-xml-utils.la \
|
||||
${top_builddir}/src/engine/libgncmod-engine.la \
|
||||
${top_builddir}/src/core-utils/libgnc-core-utils.la \
|
||||
${top_builddir}/src/gnc-module/libgnc-module.la \
|
||||
${top_builddir}/src/libqof/qof/libgnc-qof.la \
|
||||
${top_builddir}/lib/stf/libgnc-stf.la \
|
||||
${GLIB_LIBS}
|
||||
|
||||
test_csv_imp_CFLAGS = \
|
||||
-DTESTPROG=test_csv-imp \
|
||||
${DEFAULT_INCLUDES} \
|
||||
-I$(top_srcdir)/${MODULEPATH}/ \
|
||||
-I${top_srcdir}/src/test-core \
|
||||
-I${top_srcdir}/src \
|
||||
-I${top_srcdir}/src/import-export \
|
||||
-I${top_srcdir}/src/gnome \
|
||||
-I${top_srcdir}/src/register/ledger-core \
|
||||
-I${top_srcdir}/src/register/register-gnome \
|
||||
-I${top_srcdir}/src/register/register-core \
|
||||
-I${top_srcdir}/src/gnome-utils \
|
||||
-I${top_srcdir}/src/app-utils \
|
||||
-I${top_srcdir}/src/engine \
|
||||
-I${top_srcdir}/src/core-utils \
|
||||
-I${top_srcdir}/src/gnc-module \
|
||||
-I${top_srcdir}/src/libqof/qof \
|
||||
-I${top_srcdir}/lib/libc \
|
||||
-I${top_srcdir}/lib \
|
||||
${GTK_CFLAGS} \
|
||||
${GLIB_CFLAGS}
|
||||
|
||||
GNC_TEST_DEPS = \
|
||||
--library-dir ${top_builddir}/${MODULEPATH} \
|
||||
--library-dir ${top_builddir}/src/import-export \
|
||||
--library-dir ${top_builddir}/src/gnome \
|
||||
--library-dir ${top_builddir}/src/gnome-utils \
|
||||
--library-dir ${top_builddir}/src/gnome-search \
|
||||
--library-dir ${top_builddir}/src/register/ledger-core \
|
||||
--library-dir ${top_builddir}/src/register/register-core \
|
||||
--library-dir ${top_builddir}/src/register/register-gnome \
|
||||
--library-dir ${top_builddir}/src/report/report-system \
|
||||
--library-dir ${top_builddir}/src/report/report-gnome \
|
||||
--library-dir ${top_builddir}/src/html \
|
||||
--library-dir ${top_builddir}/src/app-utils \
|
||||
--library-dir ${top_builddir}/src/backend/xml \
|
||||
--library-dir ${top_builddir}/src/engine \
|
||||
--library-dir ${top_builddir}/src/core-utils \
|
||||
--library-dir ${top_builddir}/src/gnc-module \
|
||||
--library-dir ${top_builddir}/src/libqof/qof \
|
||||
--library-dir ${top_builddir}/lib/stf
|
||||
|
||||
TESTS_ENVIRONMENT = \
|
||||
SRCDIR=${srcdir} \
|
||||
G_DEBUG= \
|
||||
$(shell ${abs_top_srcdir}/src/gnc-test-env.pl --noexports ${GNC_TEST_DEPS})
|
||||
|
||||
EXTRA_DIST= \
|
||||
sample1.csv
|
||||
|
||||
|
||||
AM_CPPFLAGS = -DG_LOG_DOMAIN=\"gnc.import.csv\"
|
2
src/import-export/csv-imp/test/sample1.csv
Normal file
2
src/import-export/csv-imp/test/sample1.csv
Normal file
@ -0,0 +1,2 @@
|
||||
Date,Num,Description,Notes,Account,Deposit,Withdrawal,Balance
|
||||
05/01/15,45,Acme Inc.,,Miscellaneous,,"1,100.00",
|
|
60
src/import-export/csv-imp/test/test-csv-imp.c
Normal file
60
src/import-export/csv-imp/test/test-csv-imp.c
Normal file
@ -0,0 +1,60 @@
|
||||
/********************************************************************
|
||||
* testmain.c: GLib g_test test execution file. *
|
||||
* Copyright 2011 John Ralls <jralls@ceridwen.us> *
|
||||
* *
|
||||
* 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 *
|
||||
\********************************************************************/
|
||||
|
||||
#include <glib.h>
|
||||
#include "config.h"
|
||||
#include <qof.h>
|
||||
#include "backend/xml/gnc-backend-xml.h"
|
||||
#include "gnc-module/gnc-module.h"
|
||||
#include "engine/gnc-engine.h"
|
||||
#include <engine/TransLog.h>
|
||||
|
||||
/* Declare the test suite assembly functions (see test-suite.c) for
|
||||
* each sub-suite; avoids having header files. */
|
||||
|
||||
extern GTestSuite *test_suite_gnc_csv_model();
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
qof_init(); /* Initialize the GObject system */
|
||||
qof_log_init_filename_special("stderr"); /* Init the log system */
|
||||
g_test_init ( &argc, &argv, NULL ); /* initialize test program */
|
||||
qof_log_set_level("gnc", (QofLogLevel)G_LOG_LEVEL_DEBUG);
|
||||
g_test_bug_base("https://bugzilla.gnome.org/show_bug.cgi?id="); /* init the bugzilla URL */
|
||||
/* Disable the transaction log */
|
||||
xaccLogDisable();
|
||||
|
||||
gnc_module_system_init();
|
||||
gnc_engine_init_static(argc, argv);
|
||||
qof_load_backend_library ("../../../backend/xml/.libs/",
|
||||
"gncmod-backend-xml");
|
||||
|
||||
/* Add test functions and suites. See
|
||||
* http://library.gnome.org/devel/glib/stable/glib-Testing.html for
|
||||
* details. Unfortunately, GLib-Testing doesn't provide the automatic
|
||||
* registration features of more sophisticated frameworks. */
|
||||
test_suite_gnc_csv_model();
|
||||
|
||||
return g_test_run();
|
||||
}
|
462
src/import-export/csv-imp/test/utest-gnc-csv-model.c
Normal file
462
src/import-export/csv-imp/test/utest-gnc-csv-model.c
Normal file
@ -0,0 +1,462 @@
|
||||
/********************************************************************
|
||||
* utest-gnc-csv-model.c: GLib g_test test suite for gnc-csv-model.c. *
|
||||
* Copyright 2015 Geert Janssens <geert.gnucash@kobaltwit.be> *
|
||||
* *
|
||||
* 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 *
|
||||
* http://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 <string.h>
|
||||
#include <glib.h>
|
||||
#include <unittest-support.h>
|
||||
/* Add specific headers for this class */
|
||||
#include "import-export/csv-imp/gnc-csv-model.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GncCsvParseData* parse_data;
|
||||
} Fixture;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int date_fmt;
|
||||
const gchar *date_str;
|
||||
int exp_year;
|
||||
int exp_month;
|
||||
int exp_day;
|
||||
} parse_date_data;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const gchar *csv_line;
|
||||
int num_fields;
|
||||
const gchar *fields [8];
|
||||
} parse_test_data;
|
||||
|
||||
static const gchar* samplefile1 = "sample1.csv";
|
||||
|
||||
static parse_test_data comma_separated [] = {
|
||||
{ "Date,Num,Description,Notes,Account,Deposit,Withdrawal,Balance", 8, { "Date","Num","Description","Notes","Account","Deposit","Withdrawal","Balance" } },
|
||||
{ "05/01/15,45,Acme Inc.,,Miscellaneous,,\"1,100.00\",", 8, { "05/01/15","45","Acme Inc.","","Miscellaneous","","1,100.00","" } },
|
||||
{ "05/01/15,45,Acme Inc.,,Miscellaneous,", 4, { "05/01/15","45","Acme Inc.","",NULL,NULL,NULL,NULL } },
|
||||
{ NULL, 0, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
|
||||
};
|
||||
|
||||
static parse_test_data semicolon_separated [] = {
|
||||
{ "Date;Num;Description;Notes;Account;Deposit;Withdrawal;Balance", 8, { "Date","Num","Description","Notes","Account","Deposit","Withdrawal","Balance" } },
|
||||
{ "05/01/15;45;Acme Inc.;;Miscellaneous;;\"1,100.00\";", 8, { "05/01/15","45","Acme Inc.","","Miscellaneous","","1,100.00","" } },
|
||||
{ "05/01/15;45;Acme Inc.;;Miscellaneous;", 4, { "05/01/15","45","Acme Inc.","",NULL,NULL,NULL,NULL } },
|
||||
{ NULL, 0, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
|
||||
};
|
||||
|
||||
static char* get_filepath(const char* filename, gboolean test_existence)
|
||||
{
|
||||
char *result;
|
||||
|
||||
const char *srcdir = g_getenv("SRCDIR");
|
||||
if (!srcdir)
|
||||
{
|
||||
g_test_message("No env variable SRCDIR exists, assuming \".\"\n");
|
||||
srcdir = ".";
|
||||
}
|
||||
|
||||
result = g_strdup_printf("%s/%s", srcdir, filename);
|
||||
|
||||
g_test_message("Using file path %s\n", result);
|
||||
|
||||
// Test whether the file really exists
|
||||
if (test_existence)
|
||||
g_assert(g_file_test(result, G_FILE_TEST_EXISTS));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
setup( Fixture *fixture, gconstpointer pData )
|
||||
{
|
||||
fixture->parse_data = gnc_csv_new_parse_data ();
|
||||
}
|
||||
|
||||
static void
|
||||
setup_one_file( Fixture *fixture, gconstpointer pData )
|
||||
{
|
||||
const gchar *filename = (const gchar*) pData;
|
||||
char *filepath = get_filepath (filename, TRUE);
|
||||
GError *the_error = NULL;
|
||||
int resultcode = 0;
|
||||
|
||||
fixture->parse_data = gnc_csv_new_parse_data ();
|
||||
resultcode = gnc_csv_load_file (fixture->parse_data, filepath,
|
||||
&the_error);
|
||||
g_assert (resultcode == 0);
|
||||
g_free(filepath);
|
||||
}
|
||||
|
||||
static void
|
||||
teardown( Fixture *fixture, gconstpointer pData )
|
||||
{
|
||||
gnc_csv_parse_data_free (fixture->parse_data);
|
||||
}
|
||||
|
||||
static const gchar *suitename = "/import-export/csv-imp/gnc-csv-model";
|
||||
void test_suite_gnc_csv_model ( void );
|
||||
|
||||
/* parse_date_with_year
|
||||
time64 parse_date_with_year (const char* date_str, int format)// Local: 1:0:0
|
||||
*/
|
||||
// Internal helper only - no tests.
|
||||
/* parse_date_without_year
|
||||
static time64 parse_date_without_year (const char* date_str, int format)// Local: 1:0:0
|
||||
*/
|
||||
// Internal helper only - no tests.
|
||||
|
||||
/* parse_date
|
||||
time64 parse_date (const char* date_str, int format)// C: 14 in 7 SCM: 9 in 2 Local: 1:0:0
|
||||
*/
|
||||
static void
|
||||
test_parse_date (void)
|
||||
{
|
||||
time64 rawtime = gnc_time_utc (NULL);
|
||||
struct tm *tm = gnc_gmtime (&rawtime);
|
||||
int curr_year = tm->tm_year;
|
||||
|
||||
|
||||
/* Note: tm_year = year - 1900 and tm_mon = 0-11
|
||||
* I'm writing the expected values as subtractions for easier
|
||||
* comparison with the date string under test
|
||||
*/
|
||||
parse_date_data test_dates[] =
|
||||
{
|
||||
// supported combinations -/.'
|
||||
{ 0, "2013-08-01", 2013 - 1900, 8 - 1, 1},
|
||||
{ 0, "2013-8-01", 2013 - 1900, 8 - 1, 1},
|
||||
{ 0, "2013-08-1", 2013 - 1900, 8 - 1, 1},
|
||||
{ 0, "2013-8-1", 2013 - 1900, 8 - 1, 1},
|
||||
{ 0, "13-08-01", 2013 - 1900, 8 - 1, 1},
|
||||
{ 0, "13-8-01", 2013 - 1900, 8 - 1, 1},
|
||||
{ 0, "13-08-1", 2013 - 1900, 8 - 1, 1},
|
||||
{ 0, "13-8-1", 2013 - 1900, 8 - 1, 1},
|
||||
{ 0, "2009/11/04", 2009 - 1900, 11 - 1, 4},
|
||||
{ 0, "1985.3.12", 1985 - 1900, 3 - 1, 12},
|
||||
{ 0, "3'6'8", 2003 - 1900, 6 - 1, 8},
|
||||
{ 0, "20130801", 2013 - 1900, 8 - 1, 1},
|
||||
{ 1, "01-08-2013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 1, "01-8-2013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 1, "1-08-2013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 1, "1-8-2013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 1, "01-08-13", 2013 - 1900, 8 - 1, 1},
|
||||
{ 1, "01-8-13", 2013 - 1900, 8 - 1, 1},
|
||||
{ 1, "1-08-13", 2013 - 1900, 8 - 1, 1},
|
||||
{ 1, "1-8-13", 2013 - 1900, 8 - 1, 1},
|
||||
{ 1, "04/11/2009", 2009 - 1900, 11 - 1, 4},
|
||||
{ 1, "12.3.1985", 1985 - 1900, 3 - 1, 12},
|
||||
{ 1, "8'6'3", 2003 - 1900, 6 - 1, 8},
|
||||
{ 1, "01082013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 2, "08-01-2013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 2, "8-01-2013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 2, "08-1-2013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 2, "8-1-2013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 2, "08-01-13", 2013 - 1900, 8 - 1, 1},
|
||||
{ 2, "8-01-13", 2013 - 1900, 8 - 1, 1},
|
||||
{ 2, "08-1-13", 2013 - 1900, 8 - 1, 1},
|
||||
{ 2, "8-1-13", 2013 - 1900, 8 - 1, 1},
|
||||
{ 2, "11/04/2009", 2009 - 1900, 11 - 1, 4},
|
||||
{ 2, "3.12.1985", 1985 - 1900, 3 - 1, 12},
|
||||
{ 2, "6'8'3", 2003 - 1900, 6 - 1, 8},
|
||||
{ 2, "08012013", 2013 - 1900, 8 - 1, 1},
|
||||
{ 3, "01-08", curr_year, 8 - 1, 1},
|
||||
{ 3, "01-8", curr_year, 8 - 1, 1},
|
||||
{ 3, "1-08", curr_year, 8 - 1, 1},
|
||||
{ 3, "1-8", curr_year, 8 - 1, 1},
|
||||
{ 3, "04/11", curr_year, 11 - 1, 4},
|
||||
{ 3, "12.3", curr_year, 3 - 1, 12},
|
||||
{ 3, "8'6", curr_year, 6 - 1, 8},
|
||||
{ 4, "08-01", curr_year, 8 - 1, 1},
|
||||
{ 4, "8-01", curr_year, 8 - 1, 1},
|
||||
{ 4, "08-1", curr_year, 8 - 1, 1},
|
||||
{ 4, "8-1", curr_year, 8 - 1, 1},
|
||||
{ 4, "11/04", curr_year, 11 - 1, 4},
|
||||
{ 4, "3.12", curr_year, 3 - 1, 12},
|
||||
{ 4, "6'8", curr_year, 6 - 1, 8},
|
||||
|
||||
// ambiguous date formats
|
||||
// current parser doesn't know how to disambiguate
|
||||
// and hence refuses to parse
|
||||
// can possibly improved with a smarter parser
|
||||
{ 0, "130801", -1, -1, -1},
|
||||
{ 1, "010813", -1, -1, -1},
|
||||
{ 2, "080113", -1, -1, -1},
|
||||
{ 3, "0108", -1, -1, -1},
|
||||
{ 4, "0801", -1, -1, -1},
|
||||
|
||||
// Combinations that don't make sense
|
||||
// but can still be entered by a user
|
||||
// Should ideally all result in refusal to parse...
|
||||
{ 0, "08-01", -1, -1, -1},
|
||||
{ 0, "0801", -1, -1, -1},
|
||||
{ 1, "01-08", -1, -1, -1},
|
||||
{ 1, "0108", -1, -1, -1},
|
||||
{ 2, "08-01", -1, -1, -1},
|
||||
{ 2, "0801", -1, -1, -1},
|
||||
{ 3, "01-08-2013", curr_year, 8 - 1, 1}, // BAD behavior !
|
||||
{ 3, "01-08-13", curr_year, 8 - 1, 1}, // BAD behavior !
|
||||
{ 3, "08-08-08", curr_year, 8 - 1, 8}, // BAD behavior !
|
||||
{ 3, "01082013", -1, -1, -1},
|
||||
{ 3, "010813", -1, -1, -1},
|
||||
{ 3, "20130108", -1, -1, -1},
|
||||
{ 4, "08-01-2013", curr_year, 8 - 1, 1}, // BAD behavior !
|
||||
{ 4, "08-01-13", curr_year, 8 - 1, 1}, // BAD behavior !
|
||||
{ 4, "2013-08-01", -1, -1, -1},
|
||||
{ 4, "09-08-01", curr_year, 9 - 1, 8}, // BAD behavior !
|
||||
{ 4, "08012013", -1, -1, -1},
|
||||
{ 4, "080113", -1, -1, -1},
|
||||
{ 4, "20130801", -1, -1, -1},
|
||||
|
||||
// Sentinel to mark the end of available tests
|
||||
{ 0, NULL, 0, 0, 0},
|
||||
|
||||
};
|
||||
int i = 0;
|
||||
|
||||
gnc_tm_free(tm);
|
||||
while (test_dates[i].date_str)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
int got_year = 0, got_month = 0, got_day = 0;
|
||||
|
||||
rawtime = parse_date (test_dates[i].date_str, test_dates[i].date_fmt);
|
||||
if (rawtime == -1)
|
||||
got_year = got_month = got_day = -1;
|
||||
else
|
||||
{
|
||||
tm = gnc_gmtime (&rawtime);
|
||||
got_year = tm->tm_year;
|
||||
got_month = tm->tm_mon;
|
||||
got_day = tm->tm_mday;
|
||||
gnc_tm_free(tm);
|
||||
}
|
||||
|
||||
if ((got_year != test_dates[i].exp_year) ||
|
||||
(got_month != test_dates[i].exp_month) ||
|
||||
(got_day != test_dates[i].exp_day))
|
||||
{
|
||||
g_error ("Parse_date failed for date '%s' and format '%d'.\n"
|
||||
"Expected result: year %d, month %d, day %d\n"
|
||||
"Obtained result: year %d, month %d, day %d",
|
||||
test_dates[i].date_str,
|
||||
test_dates[i].date_fmt,
|
||||
test_dates[i].exp_year,
|
||||
test_dates[i].exp_month,
|
||||
test_dates[i].exp_day,
|
||||
got_year, got_month, got_day);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/* gnc_csv_new_parse_data
|
||||
GncCsvParseData* gnc_csv_new_parse_data (void)// C: 1 in 1 Local: 0:0:0
|
||||
*/
|
||||
static void
|
||||
test_gnc_csv_new_parse_data (void)
|
||||
{
|
||||
GncCsvParseData* parse_data = gnc_csv_new_parse_data ();
|
||||
g_assert (parse_data != NULL);
|
||||
g_assert (parse_data->chunk != NULL);
|
||||
gnc_csv_parse_data_free (parse_data);
|
||||
}
|
||||
|
||||
/* gnc_csv_parse_data_free
|
||||
void gnc_csv_parse_data_free (GncCsvParseData* parse_data)// C: 3 in 1 Local: 0:0:0
|
||||
*/
|
||||
// Basic freeing of memory - no test
|
||||
|
||||
/* gnc_csv_convert_encoding
|
||||
int gnc_csv_convert_encoding (GncCsvParseData* parse_data, const char* encoding,// C: 1 Local: 1:0:0
|
||||
*/
|
||||
/* static void
|
||||
test_gnc_csv_convert_encoding (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
}*/
|
||||
/* gnc_csv_load_file
|
||||
int gnc_csv_load_file (GncCsvParseData* parse_data, const char* filename,// C: 1 Local: 0:0:0
|
||||
*/
|
||||
static void
|
||||
test_gnc_csv_load_file (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
|
||||
char *file1 = get_filepath ("notexist.csv", FALSE);
|
||||
char *file2 = get_filepath ("sample1.csv", TRUE);
|
||||
GError *the_error = NULL;
|
||||
int resultcode = 0;
|
||||
|
||||
/* Test loading of a non-existing file */
|
||||
resultcode = gnc_csv_load_file (fixture->parse_data, file1,
|
||||
&the_error);
|
||||
g_assert ((the_error->domain == GNC_CSV_IMP_ERROR) &&
|
||||
(the_error->code == GNC_CSV_IMP_ERROR_OPEN));
|
||||
|
||||
/* Test loading of a valid csv file */
|
||||
resultcode = gnc_csv_load_file (fixture->parse_data, file2,
|
||||
&the_error);
|
||||
g_assert (resultcode == 0);
|
||||
}
|
||||
/* gnc_csv_parse
|
||||
int gnc_csv_parse (GncCsvParseData* parse_data, gboolean guessColTypes, GError** error)// C: 13 in 1 Local: 0:0:0
|
||||
*/
|
||||
static void
|
||||
test_gnc_csv_parse_from_file (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
GError *the_error = NULL;
|
||||
int resultcode = 0;
|
||||
|
||||
/* Test basic parsing of the loaded file
|
||||
* A few fields are sampled in the parsed data. */
|
||||
resultcode = gnc_csv_parse (fixture->parse_data, TRUE, &the_error);
|
||||
g_assert (g_strcmp0 ((char*)((GPtrArray*)(fixture->parse_data->orig_lines->pdata[0]))->pdata[0],
|
||||
"Date") == 0);
|
||||
g_assert (g_strcmp0 ((char*)((GPtrArray*)(fixture->parse_data->orig_lines->pdata[1]))->pdata[6],
|
||||
"1,100.00") == 0);
|
||||
}
|
||||
|
||||
/* Test parsing for several different prepared strings
|
||||
* These tests bypass file loading, rather taking a
|
||||
* prepared set of strings as input. This makes it
|
||||
* easier to add test cases without having to create new test files
|
||||
* each time to load from.
|
||||
* Note this bypasses encoding configuration, which should be tested
|
||||
* independently.
|
||||
*/
|
||||
|
||||
/* This helper function will run the parse step on the given data
|
||||
* with the parser as configured by the calling test function.
|
||||
* This allows the same code to be used with different csv test strings
|
||||
* and parser option combinations.
|
||||
*/
|
||||
static void
|
||||
test_gnc_csv_parse_helper (GncCsvParseData *parse_data, gconstpointer pData)
|
||||
{
|
||||
parse_test_data *test_data = (parse_test_data *) pData;
|
||||
GError *the_error = NULL;
|
||||
int resultcode = 0;
|
||||
int i = 0;
|
||||
|
||||
while (test_data[i].csv_line)
|
||||
{
|
||||
int j;
|
||||
parse_test_data cur_line = test_data[i];
|
||||
|
||||
g_test_message("Using string %s\n", cur_line.csv_line);
|
||||
g_free (parse_data->file_str.begin);
|
||||
parse_data->file_str.begin = g_strdup (cur_line.csv_line);
|
||||
parse_data->file_str.end = parse_data->file_str.begin + strlen (parse_data->file_str.begin);
|
||||
resultcode = gnc_csv_parse (parse_data, TRUE, &the_error);
|
||||
g_assert (resultcode == 0);
|
||||
for (j=0; j < cur_line.num_fields; j++)
|
||||
{
|
||||
g_assert (g_strcmp0 ((char*)((GPtrArray*)(parse_data->orig_lines->pdata[0]))->pdata[j],
|
||||
(cur_line.fields[j])) == 0);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_gnc_csv_parse_comma_sep (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
GSList* sep_list = NULL;
|
||||
|
||||
sep_list = g_slist_append (sep_list, ",");
|
||||
stf_parse_options_csv_set_separators (fixture->parse_data->options, NULL, sep_list);
|
||||
g_slist_free (sep_list);
|
||||
|
||||
test_gnc_csv_parse_helper (fixture->parse_data, pData);
|
||||
}
|
||||
|
||||
static void
|
||||
test_gnc_csv_parse_semicolon_sep (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
GSList* sep_list = NULL;
|
||||
|
||||
sep_list = g_slist_append (sep_list, ";");
|
||||
stf_parse_options_csv_set_separators (fixture->parse_data->options, NULL, sep_list);
|
||||
g_slist_free (sep_list);
|
||||
|
||||
test_gnc_csv_parse_helper (fixture->parse_data, pData);
|
||||
}
|
||||
|
||||
/* trans_property_free
|
||||
static void trans_property_free (TransProperty* prop)// Local: 2:0:0
|
||||
*/
|
||||
// Internal helper function - no test
|
||||
/* trans_property_set
|
||||
static gboolean trans_property_set (TransProperty* prop, char* str)// Local: 1:0:0
|
||||
*/
|
||||
// Internal helper function - no test
|
||||
/* trans_property_list_free
|
||||
static void trans_property_list_free (TransPropertyList* list)// Local: 1:0:0
|
||||
*/
|
||||
// Internal helper function - no test
|
||||
/* trans_property_list_add
|
||||
static void trans_property_list_add (TransProperty* property)// Local: 1:0:0
|
||||
*/
|
||||
// Internal helper function - no test
|
||||
/* trans_add_split
|
||||
static void trans_add_split (Transaction* trans, Account* account, QofBook* book,// Local: 2:0:0
|
||||
*/
|
||||
// Internal helper function - no test
|
||||
/* trans_property_list_verify_essentials
|
||||
static gboolean trans_property_list_verify_essentials (TransPropertyList* list, gchar** error)// Local: 1:0:0
|
||||
*/
|
||||
// Internal helper function - no test
|
||||
/* gnc_csv_parse_to_trans
|
||||
int gnc_csv_parse_to_trans (GncCsvParseData* parse_data, Account* account,// C: 2 in 1 Local: 0:0:0
|
||||
*/
|
||||
/* static void
|
||||
test_gnc_csv_parse_to_trans (Fixture *fixture, gconstpointer pData)
|
||||
{
|
||||
}*/
|
||||
|
||||
|
||||
void
|
||||
test_suite_gnc_csv_model (void)
|
||||
{
|
||||
|
||||
// GNC_TEST_ADD (suitename, "parse date with year", Fixture, NULL, setup, test_parse_date_with_year, teardown);
|
||||
// GNC_TEST_ADD (suitename, "parse date without year", Fixture, NULL, setup, test_parse_date_without_year, teardown);
|
||||
GNC_TEST_ADD_FUNC (suitename, "parse date", test_parse_date);
|
||||
GNC_TEST_ADD_FUNC (suitename, "gnc csv new parse data", test_gnc_csv_new_parse_data);
|
||||
// GNC_TEST_ADD (suitename, "gnc csv parse data free", Fixture, NULL, setup, test_gnc_csv_parse_data_free, teardown);
|
||||
// GNC_TEST_ADD (suitename, "gnc csv convert encoding", Fixture, NULL, setup, test_gnc_csv_convert_encoding, teardown);
|
||||
GNC_TEST_ADD (suitename, "gnc csv load file", Fixture, NULL, setup, test_gnc_csv_load_file, teardown);
|
||||
GNC_TEST_ADD (suitename, "gnc csv parse from file", Fixture, samplefile1, setup_one_file, test_gnc_csv_parse_from_file, teardown);
|
||||
GNC_TEST_ADD (suitename, "parse comma", Fixture, comma_separated, setup, test_gnc_csv_parse_comma_sep, teardown);
|
||||
GNC_TEST_ADD (suitename, "parse semicolon", Fixture, semicolon_separated, setup, test_gnc_csv_parse_semicolon_sep, teardown);
|
||||
// GNC_TEST_ADD (suitename, "trans property free", Fixture, NULL, setup, test_trans_property_free, teardown);
|
||||
// GNC_TEST_ADD (suitename, "trans property set", Fixture, NULL, setup, test_trans_property_set, teardown);
|
||||
// GNC_TEST_ADD (suitename, "trans property list free", Fixture, NULL, setup, test_trans_property_list_free, teardown);
|
||||
// GNC_TEST_ADD (suitename, "trans property list add", Fixture, NULL, setup, test_trans_property_list_add, teardown);
|
||||
// GNC_TEST_ADD (suitename, "trans add split", Fixture, NULL, setup, test_trans_add_split, teardown);
|
||||
// GNC_TEST_ADD (suitename, "trans property list verify essentials", Fixture, NULL, setup, test_trans_property_list_verify_essentials, teardown);
|
||||
// GNC_TEST_ADD (suitename, "gnc csv parse to trans", Fixture, NULL, setup, test_gnc_csv_parse_to_trans, teardown);
|
||||
|
||||
}
|
@ -38,7 +38,7 @@
|
||||
stores and use UNIVERSAL TIME internally. Universal time is the
|
||||
'one true time' that is independent of one's location on planet
|
||||
Earth. It is measured in seconds from midnight January 1, 1970
|
||||
in localtime-Grenwich (GMT). If one wants to display the local
|
||||
in localtime-Greenwich (GMT). If one wants to display the local
|
||||
time, then the display-print routine should make all final
|
||||
tweaks to print the local time. The local time *must not* be
|
||||
kept as a numeric value anywhere in the program. If one wants
|
||||
@ -108,10 +108,10 @@ extern const char *gnc_default_strftime_date_format;
|
||||
/** Constants *******************************************************/
|
||||
/** \brief UTC date format string.
|
||||
|
||||
Timezone independent, date and time inclusive, as used in the QSF backend.
|
||||
Time zone independent, date and time inclusive, as used in the QSF backend.
|
||||
The T and Z characters are from xsd:dateTime format in coordinated universal time, UTC.
|
||||
You can reproduce the string from the GNU/Linux command line using the date utility:
|
||||
date -u +%Y-%m-%dT%H:M:SZ = 2004-12-12T23:39:11Z The datestring must be timezone independent
|
||||
date -u +%Y-%m-%dT%H:M:SZ = 2004-12-12T23:39:11Z The datestring must be time zone independent
|
||||
and include all specified fields. Remember to use gmtime() NOT localtime()!
|
||||
*/
|
||||
|
||||
@ -305,12 +305,12 @@ gboolean timespec_equal(const Timespec *ta, const Timespec *tb);
|
||||
/** comparison: if (ta < tb) -1; else if (ta > tb) 1; else 0; */
|
||||
gint timespec_cmp(const Timespec *ta, const Timespec *tb);
|
||||
|
||||
/** difference between ta and tb, results are normalised
|
||||
/** difference between ta and tb, results are normalized
|
||||
* ie tv_sec and tv_nsec of the result have the same size
|
||||
* abs(result.tv_nsec) <= 1000000000 */
|
||||
Timespec timespec_diff(const Timespec *ta, const Timespec *tb);
|
||||
|
||||
/** absolute value, also normalised */
|
||||
/** absolute value, also normalized */
|
||||
Timespec timespec_abs(const Timespec *t);
|
||||
|
||||
/** convert a timepair on a certain day (localtime) to
|
||||
@ -344,15 +344,15 @@ Timespec gnc_dmy2timespec_end (gint day, gint month, gint year);
|
||||
/** The gnc_iso8601_to_timespec_gmt() routine converts an ISO-8601 style
|
||||
* date/time string to Timespec. Please note that ISO-8601 strings
|
||||
* are a representation of Universal Time (UTC), and as such, they
|
||||
* 'store' UTC. To make them human readable, they show timezone
|
||||
* 'store' UTC. To make them human readable, they show time zone
|
||||
* information along with a local-time string. But fundamentally,
|
||||
* they *are* UTC. Thus, thir routine takes a UTC input, and
|
||||
* they *are* UTC. Thus, this routine takes a UTC input, and
|
||||
* returns a UTC output.
|
||||
*
|
||||
* For example: 1998-07-17 11:00:00.68-0500
|
||||
* is 680 milliseconds after 11 o'clock, central daylight time
|
||||
* It is also 680 millisecs after 16:00:00 hours UTC.
|
||||
* \return The universl time.
|
||||
* It is also 680 milliseconds after 16:00:00 hours UTC.
|
||||
* \return The universal time.
|
||||
*
|
||||
* XXX Caution: this routine does not handle strings that specify
|
||||
* times before January 1 1970.
|
||||
@ -368,12 +368,12 @@ Timespec gnc_iso8601_to_timespec_gmt(const gchar *);
|
||||
*
|
||||
* Please note that ISO-8601 strings are a representation of
|
||||
* Universal Time (UTC), and as such, they 'store' UTC. To make them
|
||||
* human readable, they show timezone information along with a
|
||||
* human readable, they show time zone information along with a
|
||||
* local-time string. But fundamentally, they *are* UTC. Thus,
|
||||
* this routine takes a UTC input, and returns a UTC output.
|
||||
*
|
||||
* The string generated by this routine uses the local timezone
|
||||
* on the machine on which it is executing to create the timestring.
|
||||
* The string generated by this routine uses the local time zone
|
||||
* on the machine on which it is executing to create the time string.
|
||||
*/
|
||||
gchar * gnc_timespec_to_iso8601_buff (Timespec ts, gchar * buff);
|
||||
|
||||
@ -391,7 +391,7 @@ void gnc_timespec2dmy (Timespec ts, gint *day, gint *month, gint *year);
|
||||
/** \name QofDateFormat functions */
|
||||
// @{
|
||||
/** The qof_date_format_get routine returns the date format that
|
||||
* the date printing will use when printing a date, and the scaning
|
||||
* the date printing will use when printing a date, and the scanning
|
||||
* routines will assume when parsing a date.
|
||||
* @returns: the one of the enumerated date formats.
|
||||
*/
|
||||
|
@ -8,17 +8,25 @@ include $(top_srcdir)/test-templates/Makefile.decl
|
||||
#after $(top_srcdir) or $(top_builddir):
|
||||
MODULEPATH = src/optional/gtkmm
|
||||
|
||||
test_gtkmm_SOURCES = \
|
||||
test-gtkmm.cpp \
|
||||
test-book.cpp
|
||||
|
||||
test_gtkmm_HEADERSS = \
|
||||
$(top_srcdir)/${MODULEPATH}/gncmm/Book.hpp
|
||||
#The test program. You'll need to add to this if you have more than one module above.
|
||||
|
||||
check_PROGRAMS = test-gtkmm
|
||||
|
||||
TESTS = ${check_PROGRAMS}
|
||||
|
||||
test_gtkmmdir = ${top_srcdir}/${MODULEPATH}/test
|
||||
|
||||
#Program files for tests go here. It's probably best to have one for
|
||||
#each file in the parent directory. Include
|
||||
#test_foo_support.c if you have one and aren't building the
|
||||
#support library.
|
||||
test_gtkmm_SOURCES = \
|
||||
test-gtkmm.cpp \
|
||||
test-book.cpp
|
||||
|
||||
test_gtkmm_HEADERS = \
|
||||
$(top_srcdir)/${MODULEPATH}/gncmm/Book.hpp
|
||||
|
||||
#The tests might require more libraries, but try to keep them
|
||||
#as independent as possible.
|
||||
test_gtkmm_LDADD = ${top_builddir}/${MODULEPATH}/libgncmod-gtkmm.la \
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <gnc-glib-utils.h>
|
||||
#include "gfec.h"
|
||||
#include "dialog-custom-report.h"
|
||||
#include "gnc-component-manager.h"
|
||||
@ -604,11 +605,11 @@ gnc_plugin_page_report_option_change_cb(gpointer data)
|
||||
"Report name", NULL);
|
||||
if (strcmp(old_name, new_name) != 0)
|
||||
{
|
||||
/* Bug 727130 - escape the non-printable characters from the name */
|
||||
new_name_escaped = g_strescape(new_name,NULL);
|
||||
ENTER("Escaped new report name: %s", new_name_escaped);
|
||||
main_window_update_page_name(GNC_PLUGIN_PAGE(report), new_name_escaped);
|
||||
g_free(new_name_escaped);
|
||||
/* Bug 727130, 760711 - remove only the non-printable
|
||||
* characters from the new name */
|
||||
gnc_utf8_strip_invalid_and_controls(new_name);
|
||||
ENTER("Cleaned-up new report name: %s", new_name);
|
||||
main_window_update_page_name(GNC_PLUGIN_PAGE(report), new_name);
|
||||
}
|
||||
g_free(new_name);
|
||||
|
||||
|
@ -278,7 +278,7 @@ make_testfile "Author Name <author@email.addr>" path/to/input [path/to/output]
|
||||
Creates template unit test files from C source files. The default
|
||||
output file is utest-filename in a subdirectory named "test". For
|
||||
example, if the input file is src/engine/Account.c, the default output
|
||||
file will be src/engine/test/test-Account.c.
|
||||
file will be src/engine/test/utest-Account.c.
|
||||
|
||||
The program scans the input file to find function signatures. Each
|
||||
function signature will generate a comment with the function's
|
||||
|
54
util/check-po.pl
Executable file
54
util/check-po.pl
Executable file
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/perl -w
|
||||
use strict;
|
||||
|
||||
my $filename = $ARGV[0];
|
||||
my ($last_merge, $last_rev, $msgtot, $msgtrans, $msgfuzz);
|
||||
my $date_re = '(\d{4}-\d{2}-\d{2})';
|
||||
my $merge_re = qr/^"POT-Creation-Date: $date_re/;
|
||||
my $rev_re = qr/^"PO-Revision-Date: $date_re/;
|
||||
my $msgid_re = qr(^msgid ".+");
|
||||
my $str_re = qr/^msgstr ".+"/;
|
||||
|
||||
while (<>) {
|
||||
$last_merge = $1 if ($_ =~ $merge_re);
|
||||
$last_rev = $1 if ($_ =~ $rev_re);
|
||||
}
|
||||
my ($strings, $fuzzy, $missing);
|
||||
open STATS, "msgfmt --stat $filename 2>&1 |" or die;
|
||||
while (<STATS>) {
|
||||
#print;
|
||||
$_ =~ /^(\d+) translated messages(?:, (\d+) fuzzy translations)?(?:, (\d+) untranslated messages)?./;
|
||||
$strings = $1 || 0;
|
||||
$fuzzy = $2 || 0;
|
||||
$missing = $3 ||0;
|
||||
}
|
||||
close STATS;
|
||||
my $total = ($strings + $fuzzy + $missing) || 1;
|
||||
my $percent = $strings/$total * 100.0;
|
||||
my $fuzpct = ($strings + $fuzzy) / $total * 100.0;
|
||||
printf "%14s: %s %s\t%4d\t%4d\t%4d\t%3.2f%%\t %3.2f%%\n", $filename, $last_rev,
|
||||
$last_merge, $strings, $fuzzy, $total, $percent, $fuzpct;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
check-po.pl
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
check-po.pl po-filename
|
||||
|
||||
=head1 SUMMARY
|
||||
|
||||
Prints the filename, last revision date, date of the potfile with which it was
|
||||
last merged, the number of translated strings not marked fuzzy, the number of
|
||||
translated strings marked fuzzy, the total number of translatable strings, the
|
||||
percentage of strings with not-fuzzy translations and the percentage of strings
|
||||
with both fuzzy and non-fuzzy translations.
|
||||
|
||||
Most effectively used in a shell for loop, e.g.:
|
||||
|
||||
C<for i in *.po; do check-po.pl $i; done>
|
||||
|
||||
The results of which can be piped to sort(1) for simple analysis.
|
||||
|
||||
=cut
|
Loading…
Reference in New Issue
Block a user