Merge branch 'maint'

Resolved conflicts:
	src/engine/Split.c
	src/engine/test/utest-Split.cpp
This commit is contained in:
Geert Janssens committed 2015-08-04 15:54:27 +02:00
commit aa6b538ecb
29 files changed
+443 -332

No files matched your search

+38 -74
View File
@@ -14,7 +14,7 @@ msgstr ""
"Project-Id-Version: gnucash-2.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-19 21:02+0100\n"
"PO-Revision-Date: 2015-04-11 08:40+0200\n"
"PO-Revision-Date: 2015-07-10 20:51+0200\n"
"Last-Translator: Mechtilde <ooo@mechtilde.de>\n"
"Language-Team: GnuCash-de <gnucash-de@gnucash.org>\n"
"Language: German\n"
@@ -5777,9 +5777,9 @@ msgstr "Kontobuch als Bericht für dieses Konto öffnen"
#: ../src/gnome/gnc-plugin-page-register2.c:392
#: ../src/gnome/gnc-plugin-page-register.c:401
#, fuzzy
msgid "Account Report - Single Transaction"
msgstr "Online-Überweisung eingeben"
msgstr "Kontenbuch - Einzelüberweisung"
#: ../src/gnome/gnc-plugin-page-register2.c:393
#: ../src/gnome/gnc-plugin-page-register.c:402
@@ -8982,7 +8982,6 @@ msgstr ""
"müssen nun geändert werden. Klicken Sie Ok, um sie zu ändern."
#: ../src/gnome/gtkbuilder/dialog-sx.glade.h:4
#, fuzzy
msgid "<b>Since Last Run</b>"
msgstr "<b>Seit-letztem-Aufruf Fenster</b>"
@@ -8995,25 +8994,21 @@ msgid "_Run when data file opened"
msgstr "Seit-Letztem-Aufruf Fenster starten, wenn eine _Datei geöffnet wird"
#: ../src/gnome/gtkbuilder/dialog-sx.glade.h:7
#, fuzzy
msgid "Run the \"since last run\" process when a file is opened."
msgstr ""
"Das Fenster »Seit letztem Aufruf« anzeigen, wenn eine Datei geöffnet wird "
"oder beim Programmstart von GnuCash."
"Lasse den »Seit letztem Aufruf« Pozess laufen, wenn eine Datei geöffnet wird "
#: ../src/gnome/gtkbuilder/dialog-sx.glade.h:8
#, fuzzy
msgid "_Show notification window"
msgstr "Verlaufs_fenster anzeigen"
msgstr "Benachrichtigungs_fenster anzeigen"
#: ../src/gnome/gtkbuilder/dialog-sx.glade.h:9
#, fuzzy
msgid ""
"Show the notification window for the \"since last run\" process when a file "
"is opened."
msgstr ""
"Das Fenster »Seit letztem Aufruf« anzeigen, wenn eine Datei geöffnet wird "
"oder beim Programmstart von GnuCash."
"Das Benachrichtigungsfenster »Seit letztem Aufruf« anzeigen, wenn eine "
"Datei geöffnet wird "
#: ../src/gnome/gtkbuilder/dialog-sx.glade.h:10
msgid "_Auto-create new transactions"
@@ -9194,7 +9189,6 @@ msgid "<b>Income Tax Identity</b>"
msgstr "<b>Art der Steuererklärung</b>"
#: ../src/gnome/gtkbuilder/dialog-tax-info.glade.h:5
#, fuzzy
msgid "Click to change Tax Name and/or Tax Type."
msgstr "Anklicken, um Name oder Typ der Steuern zu ändern"
@@ -9432,9 +9426,8 @@ msgstr "Alle auswählen"
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register2.glade.h:24
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:25
#, fuzzy
msgid "Sa_ve Filter"
msgstr "%s in Datei speichern"
msgstr "Filter speichern"
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register2.glade.h:25
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:51
@@ -9499,7 +9492,6 @@ msgstr "_Betrag"
#. src/report/standard-reports/transaction.scm
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:38
#: ../intl-scm/guile-strings.c:4570 ../intl-scm/guile-strings.c:4626
#, fuzzy
msgid "Sort by amount."
msgstr "Sortieren nach Summe"
@@ -9510,14 +9502,12 @@ msgstr "Buchungstext"
#. src/report/standard-reports/transaction.scm
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:40
#: ../intl-scm/guile-strings.c:4586 ../intl-scm/guile-strings.c:4638
#, fuzzy
msgid "Sort by memo."
msgstr "Sortiere nach Buchungstext"
#. src/report/standard-reports/transaction.scm
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:42
#: ../intl-scm/guile-strings.c:4574 ../intl-scm/guile-strings.c:4630
#, fuzzy
msgid "Sort by description."
msgstr "Sortieren nach Beschreibung"
@@ -9526,23 +9516,20 @@ msgid "_Action"
msgstr "A_ktionen"
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:44
#, fuzzy
msgid "Sort by action field."
msgstr "Sortiere nach Aktion"
msgstr "Sortiere nach Aktionsfeld"
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:45
msgid "_Notes"
msgstr "_Bemerkung"
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:46
#, fuzzy
msgid "Sort by notes field."
msgstr "Sortiere nach Bemerkung"
msgstr "Sortiere nach Bemerkungsfeld"
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:47
#, fuzzy
msgid "Sa_ve Sort Order"
msgstr "Sortierreihenfolge"
msgstr "Sortierreihenfolge speichern"
#: ../src/gnome/gtkbuilder/gnc-plugin-page-register.glade.h:48
#, fuzzy
@@ -9878,9 +9865,8 @@ msgstr "entspricht nicht regulärem Ausdruck"
#. Build and connect the case-sensitive check button; defaults to off
#: ../src/gnome-search/search-string.c:329
#, fuzzy
msgid "Match case"
msgstr "Passt?"
msgstr "Groß-/Kleinschreibung beachten"
#: ../src/gnome/top-level.c:98
#, c-format
@@ -11107,7 +11093,6 @@ msgid "View..."
msgstr "Ansicht..."
#: ../src/gnome-utils/gnc-gnome-utils.c:236
#, fuzzy
msgid ""
"GnuCash could not find the files for the help documentation. This is likely "
"because the 'gnucash-docs' package is not installed"
@@ -11132,14 +11117,12 @@ msgstr "Die Dateien für die Hilfe-Dokumentation konnten nicht gefunden werden."
#: ../src/gnome-utils/gnc-gnome-utils.c:415
#: ../src/gnome-utils/gnc-gnome-utils.c:440
#, fuzzy
msgid "GnuCash could not find the associated file."
msgstr "GnuCash konnte keine exklusive Schreibberechtigung für %s erreichen."
msgstr "GnuCash konnte die dazugehörige Datei nicht finden."
#: ../src/gnome-utils/gnc-gnome-utils.c:466
#, fuzzy
msgid "GnuCash could not open the associated URI:"
msgstr "GnuCash konnte keine exklusive Schreibberechtigung für %s erreichen."
msgstr "GnuCash konnte die dazugehörige URI nicht öffnen."
#: ../src/gnome-utils/gnc-icons.c:19
msgid "_Delete Account"
@@ -11463,9 +11446,8 @@ msgstr ""
"GnuCash: Ihr privater Finanzmanager. Die freie Lösung zur Finanzverwaltung."
#: ../src/gnome-utils/gnc-main-window.c:4379
#, fuzzy
msgid "© 1997-2014 Contributors"
msgstr "© 1997-2013 Mitarbeiter"
msgstr "© 1997-2015 Mitwirkende"
#. Translators: the following string will be shown in Help->About->Credits
#. * Enter your name or that of your team and an email contact for feedback.
@@ -11591,22 +11573,17 @@ msgid "Save Transaction before proceeding?"
msgstr "Buchungsänderungen speichern, bevor es weitergeht?"
#: ../src/gnome-utils/gnc-tree-control-split-reg.c:133
#, fuzzy
msgid ""
"The current transaction has been changed. Would you like to record the "
"changes before proceeding, or cancel?"
msgstr ""
"Der aktuelle Eintrag wurde verändert. Wollen Sie die Änderungen speichern, "
"bevor Sie die Kopie erstellen, oder soll der Kopiervorgang abgebrochen "
"werden?"
"Der aktuelle Buchung wurde verändert. Wollen Sie die Änderungen aufzeichnen, "
"bevor Sie weitermachen oder abbrechen. "
#: ../src/gnome-utils/gnc-tree-control-split-reg.c:185
#, fuzzy
msgid "This transaction is being edited in a different register."
msgstr ""
"Diese Buchung wird bereits von einem anderen Kontofenster aus bearbeitet. "
"Bitte beenden Sie zuerst diese Bearbeitung, indem Sie in dem anderen "
"Kontofenster »Eingabe« oder »Abbrechen« wählen. "
"Diese Buchung wird bereits in einem anderen Kontofenster bearbeitet. "
#: ../src/gnome-utils/gnc-tree-control-split-reg.c:205
#: ../src/register/ledger-core/split-register-control.c:58
@@ -13452,7 +13429,6 @@ msgid "Use _formal accounting labels"
msgstr "Buchungsüberschriften aus _Rechnungswesen"
#: ../src/gnome-utils/gtkbuilder/dialog-preferences.glade.h:20
#, fuzzy
msgid "Use only 'debit' and 'credit' instead of informal synonyms."
msgstr "Nur 'Soll' und 'Haben' anstatt informeller Bezeichnungen benutzen"
@@ -13656,7 +13632,6 @@ msgid "Display ne_gative amounts in red"
msgstr "Negative Beträge in rot anzeigen"
#: ../src/gnome-utils/gtkbuilder/dialog-preferences.glade.h:77
#, fuzzy
msgid "Display negative amounts in red."
msgstr "Negative Beträge in rot anzeigen"
@@ -14804,8 +14779,7 @@ msgstr "Haben"
#: ../src/gnome/window-reconcile2.c:1270 ../src/gnome/window-reconcile.c:1270
msgid "Are you sure you want to delete the selected transaction?"
msgstr ""
"Sind Sie sicher, dass Sie den ausgewählten Buchungssatz löschen wollen?"
msgstr "Sind Sie sicher, dass Sie den ausgewählten Buchungssatz löschen wollen?"
#. statement date title/value
#: ../src/gnome/window-reconcile2.c:1800 ../src/gnome/window-reconcile.c:1800
@@ -14919,14 +14893,12 @@ msgid "Reconcile the selected transactions"
msgstr "Ausgewählte Buchungen abgleichen löschen"
#: ../src/gnome/window-reconcile2.c:2218 ../src/gnome/window-reconcile.c:2218
#, fuzzy
msgid "_Unreconcile Selection"
msgstr "_Nicht abgeglichen"
msgstr "_Nicht abgeglichene Auswahl"
#: ../src/gnome/window-reconcile2.c:2219 ../src/gnome/window-reconcile.c:2219
#, fuzzy
msgid "Unreconcile the selected transactions"
msgstr "Ausgewählten Buchungssatz löschen"
msgstr "Ausgewählten Buchungssatz nicht abgleichen"
#: ../src/gnome/window-reconcile2.c:2227 ../src/gnome/window-reconcile.c:2227
msgid "Open the GnuCash help window"
@@ -15723,14 +15695,13 @@ msgid ""
"Result of Online Banking job: \n"
"Account booked balance is %s"
msgstr ""
"Ergebnis der Saldenabfrage:\n"
"Ergebnis der Saldenabfrage: \n"
"Gebuchter Saldo des Kontos ist %s"
#: ../src/import-export/aqb/gnc-ab-utils.c:969
#, c-format
msgid "For your information: This account also has a noted balance of %s\n"
msgstr ""
"Zu Ihrer Information: Dieses Konto hat außerdem folgenden Saldo an zur "
msgstr "Zu Ihrer Information: Dieses Konto hat außerdem folgenden Saldo an zur "
"Ausführung vorgemerkten Aufträgen: %s\n"
#: ../src/import-export/aqb/gnc-ab-utils.c:976
@@ -16210,7 +16181,6 @@ msgid "To Num."
msgstr "Bis Nr."
#: ../src/import-export/csv-exp/csv-transactions-export.c:425
#, fuzzy
msgid "From Num."
msgstr "Von Nr."
@@ -16253,14 +16223,12 @@ msgid "notes"
msgstr "Bemerkung"
#: ../src/import-export/csv-exp/csv-tree-export.c:157
#, fuzzy
msgid "commoditym"
msgstr "Devise/Wertpapier"
msgstr "Devise/Wertpapier M"
#: ../src/import-export/csv-exp/csv-tree-export.c:157
#, fuzzy
msgid "commodityn"
msgstr "Devise/Wertpapier"
msgstr "Devise/Wertpapier N"
#: ../src/import-export/csv-exp/csv-tree-export.c:158
msgid "hidden"
@@ -18386,13 +18354,12 @@ msgid "T-Num"
msgstr "B.-Nr."
#: ../src/register/ledger-core/split-register-model.c:381
#, fuzzy
msgid "Exch. Rate"
msgstr "Wechselkurs:"
#: ../src/register/ledger-core/split-register-model.c:398
msgid "Oth. Curr."
msgstr ""
msgstr "Andere Währung"
#: ../src/register/ledger-core/split-register-model.c:415
#: ../src/register/ledger-core/split-register-model.c:439
@@ -18507,22 +18474,18 @@ msgid "List"
msgstr "Liste"
#: ../src/report/report-gnome/dialog-custom-report.c:421
#, fuzzy
msgid "You must select a report configuration to load."
msgstr "Sie müssen einen Bericht auswählen, den Sie erstellen wollen."
msgstr "Sie müssen eine Berichtskonfiguration auswählen, die Sie erstellen wollen."
#: ../src/report/report-gnome/dialog-custom-report.c:432
#, fuzzy
msgid "You must select a report configuration to delete."
msgstr "Sie müssen einen Bericht auswählen, den Sie löschen wollen."
msgstr "Sie müssen einen Berichtskonfiguration auswählen, die Sie löschen wollen."
#: ../src/report/report-gnome/dialog-custom-report.c:441
#, fuzzy
msgid "Unable to change report configuration name."
msgstr "Berichtsname konnte nicht geändert werden."
msgstr "Berichtskonfiguration konnte nicht geändert werden."
#: ../src/report/report-gnome/dialog-custom-report.c:453
#, fuzzy
msgid ""
"A saved report configuration with this name already exists, please choose "
"another name."
@@ -18531,14 +18494,12 @@ msgstr ""
"Sie einen anderen Namen ein."
#: ../src/report/report-gnome/dialog-custom-report.c:477
#, fuzzy
msgid "Load report configuration"
msgstr "Name der Konfiguration ändern"
msgstr "Berichtskonfiguration laden"
#: ../src/report/report-gnome/dialog-custom-report.c:479
#, fuzzy
msgid "Edit report configuration name"
msgstr "Name der Konfiguration ändern"
msgstr "Berichtskonfiguration ändern"
#: ../src/report/report-gnome/dialog-custom-report.c:481
msgid "Delete report configuration"
@@ -18570,6 +18531,11 @@ msgid ""
"Configuration\" from\n"
"the Reports menu or tool bar."
msgstr ""
"Gespeicherte Berichtskonfigurationen werden erstellt, wenn ein Bericht das "
"erste Mal aus dem Menü 'Berichte' geöffnet wird.\n"
"Nachdem Sie die Berichtsoptionen an Ihren Bedarf angepasst haben, wählen "
"Sie \" Berichtskonfiguration speichern\" aus\n"
"dem Menü 'Bericht' oder der Symbolleiste."
#: ../src/report/report-gnome/dialog-report-column-view.c:321
msgid "Contents"
@@ -21096,7 +21062,7 @@ msgstr ""
#. src/report/business-reports/invoice.scm
#: ../intl-scm/guile-strings.c:910 ../intl-scm/guile-strings.c:1092
#: ../intl-scm/guile-strings.c:1302
msgid "Thank you for your patronage"
msgid "Thank you for your patronage!"
msgstr "Vielen Dank für das uns engegengebrachte Vertrauen!"
#. src/report/business-reports/easy-invoice.scm
@@ -26926,16 +26892,14 @@ msgstr "Willkommen zu GnuCash"
#. src/report/utility-reports/welcome-to-gnucash.scm
#: ../intl-scm/guile-strings.c:5846
#, fuzzy
msgid "Welcome to GnuCash ~a !"
msgstr "Willkommen zu GnuCash"
#. src/report/utility-reports/welcome-to-gnucash.scm
#: ../intl-scm/guile-strings.c:5848
#, fuzzy
msgid "GnuCash ~a has lots of nice features. Here are a few."
msgstr ""
"GnuCash 2.4 hat viele neue Funktionen. Hier werden einige Beispiele gegeben."
"GnuCash hat viele neue Funktionen. Hier sind einige Beispiele."
#. src/scm/price-quotes.scm
#: ../intl-scm/guile-strings.c:5852 ../intl-scm/guile-strings.c:5854
+2 -2
View File
@@ -17520,12 +17520,12 @@ msgstr "Virgule (,)"
#: ../src/import-export/csv-exp/assistant-csv-export.glade.h:8
#: ../src/import-export/csv-imp/assistant-csv-trans-import.glade.h:25
msgid "Colon (:)"
msgstr "Colonne (:)"
msgstr "Deux-points (:)"
#: ../src/import-export/csv-exp/assistant-csv-export.glade.h:9
#: ../src/import-export/csv-imp/assistant-csv-trans-import.glade.h:26
msgid "Semicolon (;)"
msgstr "Demie-colonne (;)"
msgstr "Point-virgule (;)"
# messages-i18n.c:257
#: ../src/import-export/csv-exp/assistant-csv-export.glade.h:11
+1 -1
View File
@@ -1687,7 +1687,7 @@ gnc_dbi_safe_sync_all( QofBackend *qbe, QofBook *book )
be->primary_book = book;
gnc_sql_sync_all( &be->sql_be, book );
if ( ERR_BACKEND_NO_ERR != qof_backend_get_error( qbe ) )
if (qof_backend_check_error (qbe))
{
conn_table_operation( (GncSqlConnection*)conn, table_list,
rollback );
+2 -1
View File
@@ -512,7 +512,8 @@ gnc_sql_sync_all( GncSqlBackend* be, /*@ dependent @*/ QofBook *book )
}
else
{
qof_backend_set_error( (QofBackend*)be, ERR_BACKEND_SERVER_ERR );
if (!qof_backend_check_error ((QofBackend*)be))
qof_backend_set_error( (QofBackend*)be, ERR_BACKEND_SERVER_ERR );
is_ok = gnc_sql_connection_rollback_transaction( be->conn );
}
finish_progress( be );
+9 -11
View File
@@ -1038,7 +1038,7 @@ write_book(FILE *out, QofBook *book, sixtp_gdv2 *gd)
g_list_length(gnc_book_get_schedxactions(book)->sx_list),
"budget", qof_collection_count(
qof_book_get_collection(book, GNC_ID_BUDGET)),
"price", gnc_pricedb_get_num_prices(gnc_pricedb_get_db(book)),
"price", gnc_pricedb_get_num_prices(gnc_pricedb_get_db(book)),
NULL))
return FALSE;
@@ -1136,11 +1136,11 @@ write_pricedb(FILE *out, QofBook *book, sixtp_gdv2 *gd)
/* Write out the parent pricedb tag then loop to write out each price.
We do it this way instead of just calling xmlElemDump so that we can
increment the progress bar as we go. */
if (fprintf( out, "<%s version=\"%s\">\n", parent->name,
if (fprintf( out, "<%s version=\"%s\">\n", parent->name,
xmlGetProp(parent, BAD_CAST "version")) < 0)
return FALSE;
/* We create our own output buffer so we can call xmlNodeDumpOutput to get
the indendation correct. */
outbuf = xmlOutputBufferCreateFile(out, NULL);
@@ -1149,7 +1149,7 @@ write_pricedb(FILE *out, QofBook *book, sixtp_gdv2 *gd)
xmlFreeNode(parent);
return FALSE;
}
for (node = parent->children; node; node = node->next)
{
/* Write two spaces since xmlNodeDumpOutput doesn't indent the first line */
@@ -1157,14 +1157,14 @@ write_pricedb(FILE *out, QofBook *book, sixtp_gdv2 *gd)
xmlNodeDumpOutput(outbuf, NULL, node, 1, 1, NULL);
/* It also doesn't terminate the last line */
xmlOutputBufferWrite(outbuf, 1, "\n");
if (ferror(out))
if (ferror(out))
break;
gd->counter.prices_loaded += 1;
run_callback(gd, "prices");
}
xmlOutputBufferClose(outbuf);
if (ferror(out) || fprintf(out, "</%s>\n", parent->name) < 0)
{
xmlFreeNode(parent);
@@ -1675,8 +1675,7 @@ gnc_book_write_accounts_to_xml_file_v2(
if (out && fclose(out))
success = FALSE;
if (!success
&& qof_backend_get_error(be) == ERR_BACKEND_NO_ERR)
if (!success && !qof_backend_check_error(be))
{
/* Use a generic write error code */
@@ -2191,4 +2190,3 @@ gnc_xml2_parse_with_subst (FileBackend *fbe, QofBook *book, GHashTable *subst)
return success;
}
+3 -1
View File
@@ -42,6 +42,7 @@
#include <gnc-engine.h>
#include "../gnc-backend-xml.h"
#include "../io-gncxml-v2.h"
#include <gnc-prefs.h>
#include <test-stuff.h>
#include <unittest-support.h>
@@ -91,6 +92,7 @@ test_load_file(const char *filename)
remove_locks(filename);
ignore_lock = (g_strcmp0(g_getenv("SRCDIR"), ".") != 0);
/* gnc_prefs_set_file_save_compressed(FALSE); */
qof_session_begin(session, filename, ignore_lock, FALSE, TRUE);
qof_session_load(session, NULL);
@@ -105,7 +107,7 @@ test_load_file(const char *filename)
"qof error=%d for file [%s]",
qof_session_get_error(session), filename);
/* Uncomment the line below to generate corrected files */
qof_session_save( session, NULL );
/* qof_session_save( session, NULL ); */
qof_session_end(session);
}
+1 -1
View File
@@ -102,7 +102,7 @@ gnc_environment_setup (void)
gchar *config_path;
gchar *env_file;
GKeyFile *keyfile = g_key_file_new();
GError *error;
GError *error = NULL;
gchar **env_vars;
gsize param_count;
gint i;
+7 -29
View File
@@ -1570,40 +1570,18 @@ get_corr_account_split(const Split *sa, const Split **retval)
{
const Split *current_split;
GList *node;
gnc_numeric sa_value, current_value;
gboolean sa_value_positive, current_value_positive, seen_one = FALSE;
*retval = NULL;
g_return_val_if_fail(sa, FALSE);
sa_value = xaccSplitGetValue (sa);
sa_value_positive = gnc_numeric_positive_p(sa_value);
if (xaccTransCountSplits (sa->parent) > 2)
return FALSE;
for (node = sa->parent->splits; node; node = node->next)
{
current_split = node->data;
if (current_split == sa) continue;
if (!xaccTransStillHasSplit(sa->parent, current_split)) continue;
current_value = xaccSplitGetValue (current_split);
current_value_positive = gnc_numeric_positive_p(current_value);
if ((sa_value_positive && !current_value_positive) ||
(!sa_value_positive && current_value_positive))
{
if (seen_one)
{
*retval = NULL;
return FALSE;
}
else
{
*retval = current_split;
seen_one = TRUE;
}
}
}
return seen_one;
*retval = xaccSplitGetOtherSplit (sa);
if (*retval)
return TRUE;
else
return FALSE;
}
/* TODO: these static consts can be shared. */
+6
View File
@@ -450,6 +450,12 @@ int xaccSplitCompareOtherAccountCodes(const Split *sa, const Split *sb);
* were added for the transaction report, and is in C because the code
* was already written in C for the above functions and duplication
* is silly.
*
* Note that this will only return a real value in case of a
* two-split transaction as that is the only situation in which
* a reliable value can be returned. In other situations
* "-- Split Transaction --" will be returned as Account Name
* or "Split" for Account Code.
*/
char * xaccSplitGetCorrAccountFullName(const Split *sa);
+26
View File
@@ -1276,10 +1276,15 @@ test_get_corr_account_split (Fixture *fixture, gconstpointer pData)
Split *split1 = xaccMallocSplit (book);
Split *split2 = xaccMallocSplit (book);
Split *split3 = xaccMallocSplit (book);
Split *split4 = xaccMallocSplit (book);
Split *split5 = xaccMallocSplit (book);
const Split *result = NULL;
const gnc_numeric factor = gnc_numeric_create (2, 1);
Account *acc1 = xaccMallocAccount (book);
Account *acc2 = xaccMallocAccount (book);
Account *acc3 = xaccMallocAccount (book);
Account *acc4 = xaccMallocAccount (book);
Account *acc5 = xaccMallocAccount (book);
#ifdef USE_CLANG_FUNC_SIG
#define _func "gboolean get_corr_account_split(const Split *, const Split **)"
#else
@@ -1296,14 +1301,23 @@ test_get_corr_account_split (Fixture *fixture, gconstpointer pData)
xaccAccountSetCommodity (acc1, fixture->curr);
xaccAccountSetCommodity (acc2, fixture->curr);
xaccAccountSetCommodity (acc3, fixture->curr);
xaccAccountSetCommodity (acc4, fixture->curr);
xaccAccountSetCommodity (acc5, fixture->curr);
split1->acc = acc1;
split2->acc = acc2;
split3->acc = acc3;
split4->acc = acc4;
split5->acc = acc5;
split1->value = gnc_numeric_create (456, 240);
split2->value = gnc_numeric_neg (fixture->split->value);
split3->value = gnc_numeric_neg (split1->value);
split4->value = gnc_numeric_neg (gnc_numeric_mul (fixture->split->value,
factor,
GNC_DENOM_AUTO,
GNC_HOW_RND_NEVER));
split5->value = fixture->split->value;
g_assert (!fixture->func->get_corr_account_split(fixture->split, &result));
g_assert (result == NULL);
@@ -1320,6 +1334,18 @@ test_get_corr_account_split (Fixture *fixture, gconstpointer pData)
xaccSplitSetParent (split3, txn);
xaccTransCommitEdit (txn);
g_assert (!fixture->func->get_corr_account_split(fixture->split, &result));
g_assert (result == NULL);
/* Test for bug 752035 */
xaccTransBeginEdit (txn);
xaccSplitSetParent (split1, NULL);
xaccSplitSetParent (split2, NULL);
xaccSplitSetParent (split3, NULL);
xaccSplitSetParent (split4, txn);
xaccSplitSetParent (split5, txn);
xaccTransCommitEdit (txn);
g_assert (!fixture->func->get_corr_account_split(fixture->split, &result));
g_assert (result == NULL);
g_assert_cmpint (check->hits, ==, 0);
+37 -31
View File
@@ -1091,6 +1091,35 @@ gnc_file_export (void)
LEAVE (" ");
}
static gboolean
check_file_path (const char *path)
{
/* Remember the directory as the default. */
gchar *default_dir = g_path_get_dirname(path);
const gchar *dotgnucash = gnc_dotgnucash_dir();
gnc_set_default_directory (GNC_PREFS_GROUP_OPEN_SAVE, default_dir);
/* Prevent user to store file in GnuCash' private configuration
* directory (~/.gnucash by default in linux, but can be overridden)
*/
DEBUG("User path: %s, dotgnucash_dir: %s", path,
gnc_dotgnucash_dir());
while (strcmp (default_dir, "/") != 0 && strcmp(default_dir, ".") != 0)
{
char *dirpath = default_dir;
if (strcmp(default_dir, dotgnucash) == 0)
{
g_free (dirpath);
return TRUE;
}
default_dir = g_path_get_dirname (dirpath);
g_free (dirpath);
}
g_free(default_dir);
return FALSE;
}
void
gnc_file_do_export(const char * filename)
{
@@ -1139,24 +1168,12 @@ gnc_file_do_export(const char * filename)
}
/* Some extra steps for file based uri's only */
if (gnc_uri_is_file_protocol(protocol))
if (gnc_uri_is_file_protocol(protocol) && check_file_path (path))
{
/* Remember the directory as the default. */
gchar *default_dir = g_path_get_dirname(path);
gnc_set_default_directory (GNC_PREFS_GROUP_OPEN_SAVE, default_dir);
g_free(default_dir);
/* Prevent user to store file in GnuCash' private configuration
* directory (~/.gnucash by default in linux, but can be overridden)
*/
DEBUG("User path: %s, dotgnucash_dir: %s", path, gnc_dotgnucash_dir());
if (g_str_has_prefix(path, gnc_dotgnucash_dir()))
{
show_session_error (ERR_FILEIO_RESERVED_WRITE, newfile, GNC_FILE_DIALOG_SAVE);
return;
}
show_session_error (ERR_FILEIO_RESERVED_WRITE, newfile,
GNC_FILE_DIALOG_SAVE);
return;
}
/* Check to see if the user specified the same file as the current
* file. If so, prevent the export from happening to avoid killing this file */
current_session = gnc_get_current_session ();
@@ -1377,22 +1394,11 @@ gnc_file_do_save_as (const char* filename)
}
/* Some extra steps for file based uri's only */
if (gnc_uri_is_file_protocol(protocol))
if (gnc_uri_is_file_protocol(protocol) && check_file_path (path))
{
/* Remember the directory as the default. */
gchar *default_dir = g_path_get_dirname(path);
gnc_set_default_directory (GNC_PREFS_GROUP_OPEN_SAVE, default_dir);
g_free(default_dir);
/* Prevent user to store file in GnuCash' private configuration
* directory (~/.gnucash by default in linux, but can be overridden)
*/
DEBUG("User path: %s, dotgnucash_dir: %s", path, gnc_dotgnucash_dir());
if (g_str_has_prefix(path, gnc_dotgnucash_dir()))
{
show_session_error (ERR_FILEIO_RESERVED_WRITE, newfile, GNC_FILE_DIALOG_SAVE);
return;
}
show_session_error (ERR_FILEIO_RESERVED_WRITE, newfile,
GNC_FILE_DIALOG_SAVE);
return;
}
/* Check to see if the user specified the same file as the current
+22 -10
View File
@@ -430,19 +430,31 @@ gnc_launch_assoc (const char *uri)
void
gnc_launch_assoc (const char *uri)
{
wchar_t *winuri = (wchar_t *)g_utf8_to_utf16(uri, -1, NULL, NULL, NULL);
wchar_t *wincmd = (wchar_t *)g_utf8_to_utf16("open", -1, NULL, NULL, NULL);
wchar_t *winuri = NULL;
/* ShellExecuteW open doesn't decode http escapes if it's passed a
* file URI so we have to do it. */
if (strcmp (g_uri_parse_scheme(uri), "file") == 0)
{
gchar *filename = g_filename_from_uri (uri, NULL, NULL);
winuri = (wchar_t *)g_utf8_to_utf16(filename, -1, NULL, NULL, NULL);
}
else
winuri = (wchar_t *)g_utf8_to_utf16(uri, -1, NULL, NULL, NULL);
if (winuri)
{
if ((INT_PTR)ShellExecuteW(NULL, wincmd, winuri, NULL, NULL, SW_SHOWNORMAL) <= 32)
{
const gchar *message =
_("GnuCash could not find the associated file.");
gnc_error_dialog(NULL, "%s", message);
}
g_free (winuri);
wchar_t *wincmd = (wchar_t *)g_utf8_to_utf16("open", -1,
NULL, NULL, NULL);
if ((INT_PTR)ShellExecuteW(NULL, wincmd, winuri,
NULL, NULL, SW_SHOWNORMAL) <= 32)
{
const gchar *message =
_("GnuCash could not find the associated file");
gnc_error_dialog(NULL, "%s: %s", message, uri);
}
g_free (wincmd);
g_free (winuri);
}
g_free (wincmd);
}
#else
+1 -1
View File
@@ -4368,7 +4368,7 @@ gnc_main_window_cmd_help_about (GtkAction *action, GncMainWindow *window)
{
const gchar *fixed_message = _("The GnuCash personal finance manager. "
"The GNU way to manage your money!");
const gchar *copyright = _("© 1997-2014 Contributors");
const gchar *copyright = _("© 1997-2015 Contributors");
gchar **authors = get_file_strsplit("AUTHORS");
gchar **documenters = get_file_strsplit("DOCUMENTERS");
gchar *license = get_file("LICENSE");
@@ -138,6 +138,7 @@ If you make a mistake or want to make changes later, you can edit the created Sc
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
<property name="climb_rate">1</property>
<property name="tooltip_text" translatable="yes">Enter the number of months still to be paid off. This determines both the remaining principle and the duration of the scheduled transaction.</property>
</object>
<packing>
<property name="left_attach">3</property>
+7
View File
@@ -72,6 +72,13 @@ qof_backend_get_error (QofBackend *be)
return err;
}
gboolean
qof_backend_check_error (QofBackend *be)
{
g_return_val_if_fail (be != NULL, TRUE);
return be->last_err != ERR_BACKEND_NO_ERR;
}
void
qof_backend_set_message (QofBackend *be, const char *format, ...)
{
+8
View File
@@ -170,6 +170,14 @@ void qof_backend_set_error (QofBackend *be, QofBackendError err);
*/
QofBackendError qof_backend_get_error (QofBackend *be);
/** Report if the backend is in an error state.
* Since get_error resets the error state, its use for branching as the backend
* bubbles back up to the session would make the session think that there was
* no error.
* \param be The backend being tested.
* \return TRUE if the backend has an error set.
*/
gboolean qof_backend_check_error (QofBackend *be);
/** \brief Load a QOF-compatible backend shared library.
+3
View File
@@ -133,3 +133,6 @@ CLEANFILES = $(BUILT_SOURCES) .py-links gnucash_core.c.py
clean-local:
rm -rf gnucash
uninstall-local:
rm -rf ${pkgpyexecdir}
Regular → Executable
+29 -58
View File
@@ -2,17 +2,17 @@
######################################################################
### gnc-fq-helper - present a scheme interface to Finance::Quote
### Copyright 2001 Rob Browning <rlb@cs.utexas.edu>
###
### 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.
###
###
### 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:
###
@@ -25,11 +25,7 @@ use strict;
use English;
use FileHandle;
# The following include is needed for the ParseDateString function.
# This should eventually be replaced with a requirement for F::Q
# version 1.11 (or better) and the use of the 'isodate' field to
# handle the date part of the conversion. Still need a method to
# handle the time conversion.
# Date::Manip provides ParseDate, ParseDateString, and UnixTime.
use Date::Manip;
=head1 NAME
@@ -118,11 +114,15 @@ non-zero - failure
=cut
# Set a base date with the current time in the current TZ:
my $base_date = new Date::Manip::Date;
$base_date->parse("now");
# The methods we know about. For now we assume they all have the same
# signature so this works OK.
sub check_modules {
my @modules = qw(Finance::Quote);
my @modules = qw(Finance::Quote Date::Manip);
my @missing;
foreach my $mod (@modules) {
@@ -194,18 +194,6 @@ sub schemify_num {
}
}
sub schemify_date {
# return the date in epoch seconds.
my ($datestr) = @_;
my $date = ParseDate($datestr);
my $result = UnixDate($date, "%s");
if($result !~ /^(\+|-)?\d+$/) {
$result = "failed-conversion";
}
return("$result");
}
# sub schemify_range {
# #convert range in form ``num1 - num2'' to ``(num1 num2)''.
# }
@@ -216,33 +204,19 @@ sub get_quote_time {
my $datestr = $$quotehash{$item, 'date'};
my $timestr = $$quotehash{$item, 'time'};
my $format = "%Y-%m-%d %H:%M:%S";
if(!$datestr) {
return undef;
if ($datestr) {
my $parsestr = $datestr . " " . ($timestr ? $timestr : "12:00:00");
my $date = $base_date->new();
my $err = $date->parse($parsestr);
if ($err) {
print $date->err(), " $parsestr\n";
return $base_date->printf($format);
}
return $date->printf($format);
}
my $parsestr = $datestr;
if(!$timestr) {
#fix date handling for quotes with no time.
#Keeps gnucash from getting date wrong in west longitude places.
$parsestr .= " 12:00:00"
} else {
$parsestr .= " $timestr";
}
$parsestr = ParseDateString($parsestr);
my $result = UnixDate($parsestr, "\"%Y-%m-%d %H:%M:%S\"");
if(!$result) {
# Fix date handling for quotes with no date: assume local date
(my $second,my $minute,my $hour,my $dayofmonth,my $month,my $year,my $dayofweek,my $dayofyear,my $daylightsaving) = localtime();
# $result = "\"".sprintf("%04d-%02d-%02d%02d:%02d:%02d",($year+1900),++$month,$dayOfMonth,$hour,$minute,$second)."\"";
$result = "\"" . sprintf("%04d-%02d-%02d", ($year+1900), ++$month, $dayofmonth) . " 12:00:00\"";
}
if($result !~ /^\"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\"$/) {
$result = "failed-conversion";
}
return $result;
return $base_date->printf($format);
}
sub schemify_quote {
@@ -345,9 +319,6 @@ sub parse_input_line {
# Check for and load non-standard modules
check_modules ();
# Help Date::Manip on Windows
Date_Init("TZ=UTC") if ($^O eq "MSWin32" && (!$ENV{'TZ'}));
# Create a stockquote object.
my $quoter = Finance::Quote->new();
my $prgnam = "gnc-fq-helper";
@@ -415,7 +386,7 @@ __END__
# $timezone = 0;
# } else {
# return 0;
# }
# }
# }
# sub get_quote_utc {
Regular → Executable
+12 -11
View File
@@ -2,17 +2,17 @@
######################################################################
### gnc-fq-update - presents a scheme interface to Finance::Quote
### Copyright 2001 Gnumatic, Inc.
###
### 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.
###
###
### 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:
###
@@ -36,6 +36,7 @@ if ($( != 0) {
exit 0 if ($input ne "y");
}
CPAN::Shell->install('Date::Manip'); #Required by gnc-fq-helper
CPAN::Shell->install('Finance::Quote');
## Local Variables:
+3 -3
View File
@@ -494,7 +494,7 @@ gnc_split_register_duplicate_current (SplitRegister *reg)
/* We are on a split in an expanded transaction.
* Just copy the split and add it to the transaction.
* However, if the split-action field is being used as the register
* However, if the split-action field is being used as the register
* number, and the action field is a number, request a new value or
* cancel. Need to get next number and update account last num from
* split account not register account, which may be the same or not */
@@ -566,8 +566,8 @@ gnc_split_register_duplicate_current (SplitRegister *reg)
int split_index;
const char *in_num = NULL;
const char *in_tnum = NULL;
char *out_num;
char *out_tnum;
char *out_num = NULL;
char *out_tnum = NULL;
time64 date;
gboolean use_autoreadonly = qof_book_uses_autoreadonly(gnc_get_current_book());
@@ -648,7 +648,6 @@
(export gnc:account-get-type-string-plural)
(export gnc:accounts-get-commodities)
(export gnc:get-current-account-tree-depth)
(export gnc:split-get-corr-account-full-name)
(export gnc:acccounts-get-all-subaccounts)
(export gnc:make-stats-collector)
(export gnc:make-drcr-collector)
@@ -143,9 +143,6 @@
(let ((root (gnc-get-current-root-account)))
(gnc-account-get-tree-depth root)))
(define (gnc:split-get-corr-account-full-name split)
(xaccSplitGetCorrAccountFullName split))
;; Get all children of this list of accounts.
(define (gnc:acccounts-get-all-subaccounts accountlist)
+36 -31
View File
@@ -1378,40 +1378,45 @@ Credit Card, and Income accounts.")))))
name-sortkey name-subtotal name-date-subtotal
3 2))
(define (get-other-account-names account-list)
( map (lambda (acct) (gnc-account-get-full-name acct)) account-list))
;;(define (get-other-account-names account-list)
;; ( map (lambda (acct) (gnc-account-get-full-name acct)) account-list))
(define (is-filter-member split account-list splits-ok?)
(let ((fullname (gnc:split-get-corr-account-full-name split)))
(define (is-filter-member split account-list)
(let* ((txn (xaccSplitGetParent split))
(splitcount (xaccTransCountSplits txn)))
(if (string=? fullname (_ "-- Split Transaction --"))
;; Yep, this is a split transaction.
(cond
;; A 2-split transaction - test separately so it can be optimized
;; to significantly reduce the number of splits to traverse
;; in guile code
((= splitcount 2)
(let* ((other (xaccSplitGetOtherSplit split))
(other-acct (xaccSplitGetAccount other)))
(member other-acct account-list)))
(if splits-ok?
(let* ((txn (xaccSplitGetParent split))
(splits (xaccTransGetSplitList txn)))
;; A multi-split transaction - run over all splits
((> splitcount 2)
(let ((splits (xaccTransGetSplitList txn)))
;; Walk through the list of splits.
;; if we reach the end, return #f
;; if the 'this' != 'split' and the split->account is a member
;; of the account-list, then return #t, else recurse
(define (is-member splits)
(if (null? splits)
#f
(let* ((this (car splits))
(rest (cdr splits))
(acct (xaccSplitGetAccount this)))
(if (and (not (eq? this split))
(member acct account-list))
#t
(is-member rest)))))
;; Walk through the list of splits.
;; if we reach the end, return #f
;; if the 'this' != 'split' and the split->account is a member
;; of the account-list, then return #t, else recurse
(define (is-member splits)
(if (null? splits)
#f
(let* ((this (car splits))
(rest (cdr splits))
(acct (xaccSplitGetAccount this)))
(if (and (not (eq? this split))
(member acct account-list))
#t
(is-member rest)))))
(is-member splits))
#f)
(is-member splits)))
;; Nope, this is a regular transaction
(member fullname (get-other-account-names account-list))
)))
;; Single transaction splits
(else #f))))
(gnc:report-starting reportname)
@@ -1467,7 +1472,7 @@ Credit Card, and Income accounts.")))))
(set! splits (qof-query-run query))
;;(gnc:warn "Splits in trep-renderer:" splits)
(gnc:warn "Splits in trep-renderer:" splits)
;;(gnc:warn "Filter account names:" (get-other-account-names c_account_2))
@@ -1477,7 +1482,7 @@ Credit Card, and Income accounts.")))))
(begin
;;(gnc:warn "Including Filter Accounts")
(set! splits (filter (lambda (split)
(is-filter-member split c_account_2 #t))
(is-filter-member split c_account_2))
splits))
)
)
@@ -1486,7 +1491,7 @@ Credit Card, and Income accounts.")))))
(begin
;;(gnc:warn "Excluding Filter Accounts")
(set! splits (filter (lambda (split)
(not (is-filter-member split c_account_2 #t)))
(not (is-filter-member split c_account_2)))
splits))
)
)
+1
View File
@@ -137,6 +137,7 @@ EXTRA_DIST = \
$(SCM_FILES) \
swig-unittest-support-python.c \
swig-unittest-support-guile.c \
unittest_support.py \
unittest-support.i
MAINTAINERCLEANFILES = \
+64 -18
View File
@@ -25,11 +25,22 @@
#include <glib.h>
#include <qof.h>
/** @file unittest-support.h
* @brief Macros and logging-capture functions to ease writing GLib-testing
* based unit tests.
*/
/** @name Unit Test Macros
* These macros facilitate combining a suite name and a test name to make a path
* when registering a test function with the corresponding g_test_add and
* g_test_add_func. Create a const char* suitename somewhere in the file and
* pass it as the first parameter, and the test name as the second. The
* remaining parameters are the same as in the underlying function.
*/
/**
* Use this macro to format informative test path output when using g_test_add.
* Suite stands for tests' pack, while path for individual test name.
*/
* Wraps gnc_test_add() for test functions needing a fixture.
*/
#define GNC_TEST_ADD( suite, path, fixture, data, setup, test, teardown )\
{\
@@ -39,9 +50,8 @@
}
/**
* Use this macro to format informative test path output when using g_test_add_func.
* Suite stands for tests' pack, while path for individual test name.
*/
* Wraps gnc_test_add_func() for test functions which don't require a fixture.
*/
#define GNC_TEST_ADD_FUNC( suite, path, test )\
{\
@@ -49,9 +59,8 @@
g_test_add_func( testpath, test );\
g_free( testpath );\
}
/**
* Suppressing Expected Errors
/** @} */
/** @name Suppressing Expected Errors
*
* Functions for suppressing expected errors during tests. Pass
*
@@ -74,6 +83,7 @@
* NB: If you have more than one fatal error in a test function be
* sure to use the test_list_handler: You can have only one fatal
* handler.
* @{
*/
/**
@@ -115,6 +125,11 @@ TestErrorStruct* test_error_struct_new (const char *log_domain,
*/
void test_error_struct_free (TestErrorStruct *);
/**
* Holds a handler instance with its TestErrorStruct, handler id, and whether
* it's a list handler. A test fixture can be set up to hold a GSList of these
* so that they can be automatically unregistered and freed during teardown.
*/
typedef struct
{
TestErrorStruct *error;
@@ -158,7 +173,9 @@ GSList *test_log_set_handler (GSList *list, TestErrorStruct *error,
GSList *test_log_set_fatal_handler (GSList *list, TestErrorStruct *error,
GLogFunc handler);
/* Clears all the log handlers. Pass this to g_slist_free() in teardown */
/**
* Clears all the log handlers. Pass this to g_slist_free() in teardown.
*/
void test_free_log_handler (gpointer item);
/**
@@ -236,7 +253,14 @@ gpointer test_reset_data( void );
*/
void test_free( gpointer data );
/* TestSignal is an opaque struct used to mock handling signals
/** @}
*/
/** @name Test Signals
* Test the emission of signals from objects. Signals are used to coordinate the
* behavior of the GUI with events in other parts of the program. @{
*/
/**
* TestSignal is an opaque struct used to mock handling signals
* emitted by functions-under-test. It registers a handler and counts
* how many times it is called with the right instance and type. The
* struct is allocated using g_slice_new, and it registers a
@@ -249,30 +273,51 @@ void test_free( gpointer data );
* passed to test_signal_new should be NULL to avoid the test.
*/
typedef gpointer TestSignal;
/**
* Create a test signal.
* @param entity: The QofInstance emitting the signal
* @param eventType: The type of the signal
* @param event_data: Any data required by the signal or NULL if none is.
* @return A newly created TestSignal. Use test_signal_free to release it.
*/
TestSignal test_signal_new (QofInstance *entity, QofEventId eventType,
gpointer event_data);
/* test_signal_return_hits gets the number of times the TestSignal has
* been called.
/**
* gets the number of times the TestSignal has been called.
*/
guint test_signal_return_hits (TestSignal sig);
/* test_signal_assert_hits is a convenience macro which wraps
* test_signal_return_hits with and equality assertion.
/**
* Convenience macro which wraps test_signal_return_hits with and equality
* assertion.
*/
#define test_signal_assert_hits(sig, hits) \
g_assert_cmpint (test_signal_return_hits (sig), ==, hits)
/**
* Free a test signal.
*/
void test_signal_free (TestSignal sig);
/* test_object_checked_destroy unrefs obj and returns true if its finalize
* method was called.
/** @}
*/
/** @name Testing for object disposal
* Sometimes we need to make sure that certain objects that we've created aren't leaking. These functions can help.
* @{
*/
/**
* Unrefs obj and returns true if its finalize method was called.
*/
gboolean test_object_checked_destroy (GObject *obj);
/**
* test_destroy() ensures that a GObject is still alive at the time
* Ensures that a GObject is still alive at the time
* it's called and that it is finalized. The first assertion will
* trigger if you pass it a ponter which isn't a GObject -- which
* could be the case if the object has already been finalized. Then it
@@ -284,6 +329,7 @@ gboolean test_object_checked_destroy (GObject *obj);
g_assert (obj != NULL && G_IS_OBJECT (obj)); \
g_assert (test_object_checked_destroy (G_OBJECT (obj)))
/** @} */
/* For Scheme testing access:
void gnc_log_init_filename_special (gchar *filename);
void gnc_log_shutdown (void);
+29 -8
View File
@@ -9,22 +9,43 @@ If there is already a test directory with make check tests in it, copy
the contents of the Makefile.am in this directory to the existing
Makefile.am; otherwise, copy the Makefile.am to your test directory.
Copy test-module.c and test-suite.c to your test directory and rename
them appropriately. You will very likely want several copies of
test-suite.c, one corresponding to each c file in the module directory
that you're testing.
There are two groups of templates here: testmain.c is for a standalone test
program that doesn't group tests into suites. test-module.c and test-suite.c
support collecting a large number of tests separated in suites into a single
test program. In most cases you'll want to use the latter.
For a single file test program, copy testmain.c into your test directory,
renaming it appropriately. Write fixtures and test functions as needed and
register them in main(). Create a target in Makefile.am which has this file as
its source.
To use suites, copy test-module.c and test-suite.c to your test directory and
rename them appropriately. You will very likely want several copies of
test-suite.c, one corresponding to each c file in the module directory that
you're testing.
Edit the test module file to call the (renamed) test_suite_module() in
each test-suite file. Add tests and fixtures as needed to the
test-suite files and add them to the (renamed) test_suite_module()
test-suite files and register them in the (renamed) test_suite_module()
function.
Alternatively you can use the make_testfile perl program in this directory to
create a skeleton test-suite file for your target file. In addition to creating
a template test function for each function in the target source file and a
template test-suite function at the end, it will comment each template function
with the usage of that function both internally and externally. Run `perldoc
make_testfile` to read more.
Edit Makefile.am according to the comments in the file.
Run autogen.sh and configure. "make check" will run all tests; "make
test" will run only the GLib unit tests not guarded by conditionals
(see test-suite.c).
Run autogen.sh and configure. "make check" will run all tests; "make test" will
run only the GLib unit tests not guarded by conditionals (see test-suite.c). For
more control, use gtester as documented in the GLib docs.
See http://www.mail-archive.com/gtk-devel-list@gnome.org/msg06994.html
and http://library.gnome.org/devel/glib/stable/glib-Testing.html
for detailed documentation.
There are some helpful macros and message-trapping functions in
src/test-core/unittest-support.h, whose Doxygen documentation is at
http://code.gnucash.org/docs/head/unittest-support_8h_source.html
+1 -4
View File
@@ -31,8 +31,7 @@ extern GTestSuite *test_suite_module3();
extern GTestSuite *test_suite_module4();
int
main (int argc,
char *argv[])
main (int argc, char *argv[])
{
qof_init(); /* You may or may not need this, depending on
* whether the module you're testing or any
@@ -48,5 +47,3 @@ main (int argc,
return g_test_run(); /* Run the result */
}
+27 -18
View File
@@ -20,10 +20,13 @@
* Boston, MA 02110-1301, USA gnu@gnu.org *
\********************************************************************/
/* This is a template test suite. Copy it to the test directory and name it for
* the corresponding file you're testing with a "utest-" prefix. Add it to the
* test_program_SOURCES in Makefile.am.
*/
#include <config.h>
#include <glib.h>
/* This is optional; you only need it if you have external fixtures or mocks. */
#include "test_module_support.h"
#include <unittest-support.h>
/* Header for this module and any others that you need */
#include <module_1.h>
@@ -31,7 +34,10 @@
* creates a nested set of test suites for us based on this path. */
static const gchar *suitename = "module/module_1";
/* Test fixture: A struct, a setup function, and a teardown function are passed to g_test_add(); add getters, setters, and whatever other functions you need to call from your test functions. */
/* Test fixture: A struct, a setup function, and a teardown function are passed
* to g_test_add(); add getters, setters, and whatever other functions you need
* to call from your test functions.
*/
typedef struct
{
gint foo;
@@ -39,15 +45,17 @@ typedef struct
} Fixture;
static void
setup_module_test(Fixture *fixture, gconstpointer pData)
setup (Fixture *fixture, gconstpointer pData)
{
/* Do something useful */
/* Whatever is needed to populate the fixture and initialize your module for
* running a single test.
*/
}
static void
teardown_module_test(Fixture *fixture, gconstpointer pData)
teardown (Fixture *fixture, gconstpointer pData)
{
/* Clean up after ourselves */
/* Whatever cleanup is needed at the end of the test. */
}
static void
@@ -92,22 +100,23 @@ test_performance_function( void )
* You can also emit arbitrary messages into the test report with
* g_test_message( const char* format, ... )
*/
GTestSuite*
test_suite_module1 ( void )
void
test_suite_module1 (void)
{
Datatype data = something();
g_test_add_func( suitename, test_function );
g_test_add_data_func( suitename, (gconstpointer)(&data),
test_function_with_data );
g_test_add( suitename, Fixture,
data,
setup_module_test,
test_function_with_fixture,
teardown_module_test);
GNC_TEST_ADD_FUNC (suitename, "Test Name 1", test_function);
{
gchar *testpath = g_strdup_printf ("%s/Test Name 2", suitename);
g_test_add_data_func( suitename, (gconstpointer)(&data),
test_function_with_data );
g_free (testpath);
}
GNC_TEST_ADD (suitename, "Test Name 3", Fixture, data, setup,
test_function_with_fixture, teardown);
/* Other conditionals are g_test_quick(), g_test_slow(), and
* g_test_thorough() */
if ( g_test_perf() )
{
g_test_add_func( suitename, test_performance_func );
GNC_TEST_ADD_FUNC (suitename, "Test Name 4", test_performance_func);
}
}
+67 -15
View File
@@ -21,26 +21,78 @@
\********************************************************************/
/* This is a template test program. Copy it to the test sudirectory and rename it test_modulename.c. (Use the same modulename that you gave Makefile.am in the same directory.
Write and link other test files */
#include <glib/glib.h>
/**
* This is a template test program. Copy it to the test sudirectory and rename
* it test_modulename.c. (Use the same modulename that you gave Makefile.am in
* the same directory.
*/
#include <config.h>
#include <glib.h>
/* Add any headers you need for the functions you're testing. */
/* Test fixture: A struct, a setup function, and a teardown function are passed
* to g_test_add(); add getters, setters, and whatever other functions you need
* to call from your test functions.
*/
typedef struct
{
int a;
char* b;
} Fixture;
static void
setup (Fixture *fixture, gconstpointer pData)
{
/* Whatever is needed to populate the fixture and initialize your module for
* running a single test.
*/
}
static void
teardown (Fixture *fixture, gconstpointer pData)
{
/* Whatever cleanup is needed at the end of the test. */
}
static void
example_without_fixture (void)
{
/* This test doesn't need the fixture or any preconditions. You might use
* this for a constructor test, for example.
*/
}
static void
example_with_data( gconstpointer data )
{
/* We want to be able to call this function more than once with different
* data.
*/
}
static void
example_with_fixture (Fixture *fixture, gconstpointer pData)
{
/* This one uses the fixture. */
}
int
main (int argc,
char *argv[])
main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv); // initialize test program
/* Add test functions and suites. See
qof_init(); /* You may or may not need this, depending on
* whether the module you're testing or any
* dependencies use GObject. */
qof_log_init_filename_special("/dev/null"); /* Initialize the
* gnucash logging system. Your tests will
* crash on the first logging call otherwise */
g_test_init (&argc, &argv, NULL); // initialize test program
/* Add test functions. 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 sophisitcated frameworks. */
g_test_add_func ("/TESTPROG/Test Case Name", test_case_test_func);
ScannerFixture, // fixture structure type
NULL, // unused data argument
scanner_fixture_setup, // fixture setup
test_scanner_symbols, // test function
scanner_fixture_teardown); // fixture teardown
g_test_add_func ("/TESTPROG/Test Case Name 1", example_without_fixture);
g_test_add_data_func ("/TESTPROG/Test Case Name 2", NULL);
g_test_add ("/TESTPROG/Test Case Name", Fixture, NULL, setup,
example_with_fixture, teardown);
return g_test_run();
}