mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-20 11:48:30 -06:00
Merge Simon Arlott's 'test-xml-save' into stable.
This commit is contained in:
commit
4d46a8191d
@ -133,6 +133,8 @@ void failure_args(
|
||||
#define do_test( result, title ) do_test_call( result, title, __FILE__, __LINE__ )
|
||||
#define success( title ) success_call( title, __FILE__, __LINE__ );
|
||||
#define failure( title ) failure_call( title, __FILE__, __LINE__ );
|
||||
#define failuref( title, format, ... ) failure_args( title, __FILE__, __LINE__, format, ## __VA_ARGS__ );
|
||||
|
||||
|
||||
/** This one doesn't work because macros can't take a variable number of arguments.
|
||||
* well, apparently gcc can, but it's non-standard.
|
||||
|
@ -14,12 +14,17 @@ set(XML_TEST_INCLUDE_DIRS
|
||||
|
||||
|
||||
set(XML_TEST_LIBS gnc-engine gnc-test-engine test-core ${LIBXML2_LDFLAGS} -lz)
|
||||
set(XML_GTEST_LIBS ${XML_TEST_LIBS} gtest)
|
||||
|
||||
function(add_xml_test _TARGET _SOURCE_FILES)
|
||||
gnc_add_test(${_TARGET} "${_SOURCE_FILES}" XML_TEST_INCLUDE_DIRS XML_TEST_LIBS ${ARGN})
|
||||
target_compile_options(${_TARGET} PRIVATE -DU_SHOW_CPLUSPLUS_API=0 -DG_LOG_DOMAIN=\"gnc.backend.xml\")
|
||||
endfunction()
|
||||
|
||||
function(add_xml_gtest _TARGET _SOURCE_FILES)
|
||||
gnc_add_test(${_TARGET} "${_SOURCE_FILES}" XML_TEST_INCLUDE_DIRS XML_GTEST_LIBS ${ARGN})
|
||||
target_compile_options(${_TARGET} PRIVATE -DU_SHOW_CPLUSPLUS_API=0 -DG_LOG_DOMAIN=\"gnc.backend.xml\")
|
||||
endfunction()
|
||||
|
||||
################################
|
||||
|
||||
@ -55,13 +60,28 @@ set(test_backend_xml_module_SOURCES
|
||||
${CMAKE_SOURCE_DIR}/libgnucash/backend/xml/gnc-pricedb-xml-v2.cpp
|
||||
)
|
||||
|
||||
set_local_dist(test_backend_xml_DIST_local CMakeLists.txt grab-types.pl
|
||||
README test-dom-converters1.cpp
|
||||
test-dom-parser1.cpp test-file-stuff.cpp test-file-stuff.h test-kvp-frames.cpp
|
||||
test-load-backend.cpp test-load-example-account.cpp test-load-xml2.cpp
|
||||
test-save-in-lang.cpp test-string-converters.cpp test-xml2-is-file.cpp
|
||||
test-xml-account.cpp test-real-data.sh test-xml-commodity.cpp
|
||||
test-xml-pricedb.cpp test-xml-transaction.cpp)
|
||||
set_local_dist(test_backend_xml_DIST_local
|
||||
CMakeLists.txt
|
||||
grab-types.pl
|
||||
README
|
||||
test-dom-converters1.cpp
|
||||
test-dom-parser1.cpp
|
||||
test-file-stuff.cpp
|
||||
test-file-stuff.h
|
||||
test-kvp-frames.cpp
|
||||
test-load-backend.cpp
|
||||
test-load-example-account.cpp
|
||||
test-load-save-files.cpp
|
||||
test-load-xml2.cpp
|
||||
test-real-data.sh
|
||||
test-save-in-lang.cpp
|
||||
test-string-converters.cpp
|
||||
test-xml2-is-file.cpp
|
||||
test-xml-account.cpp
|
||||
test-xml-commodity.cpp
|
||||
test-xml-pricedb.cpp
|
||||
test-xml-transaction.cpp
|
||||
)
|
||||
set(test_backend_xml_DIST ${test_backend_xml_DIST_local} ${test_backend_xml_test_files_DIST} PARENT_SCOPE)
|
||||
|
||||
add_xml_test(test-dom-converters1 "${test_backend_xml_base_SOURCES};test-dom-converters1.cpp")
|
||||
@ -80,6 +100,9 @@ add_xml_test(test-load-example-account
|
||||
GNC_ACCOUNT_PATH=${CMAKE_SOURCE_DIR}/data/accounts/C
|
||||
)
|
||||
target_compile_options(test-load-example-account PRIVATE -DU_SHOW_CPLUSPLUS_API=0)
|
||||
add_xml_gtest(test-load-save-files gtest-load-save-files.cpp
|
||||
GNC_TEST_FILES=${CMAKE_CURRENT_SOURCE_DIR}/test-files/load-save
|
||||
)
|
||||
add_xml_test(test-string-converters "${test_backend_xml_base_SOURCES};test-string-converters.cpp")
|
||||
add_xml_test(test-xml-account "${test_backend_xml_module_SOURCES};test-xml-account.cpp;test-file-stuff.cpp")
|
||||
add_xml_test(test-xml-commodity "${test_backend_xml_module_SOURCES};test-xml-commodity.cpp;test-file-stuff.cpp")
|
||||
|
@ -6,6 +6,7 @@ TESTS:
|
||||
test-dom-converters1.c: test each simple dom converter
|
||||
test-dom-parser1.c: unused now
|
||||
test-kvp-frames.c: test the kvp frame dom generators and parsers
|
||||
test-load-save-files.c: test loading and saving compressed and uncompressed files
|
||||
test-load-xml2.c: test the larger xml loading
|
||||
test-save-in-lang.c: incomplete test to test saving in different LANGs
|
||||
test-string-converters.c: test some string converters
|
||||
@ -15,4 +16,3 @@ test-xml-transaction.c: ditto Transaction's
|
||||
test-xml2-is-file.c: test the is_file function
|
||||
test-real-data.sh: run the test-xml-{account,commodity,transaction} programs
|
||||
on real data rather than random data
|
||||
|
||||
|
318
libgnucash/backend/xml/test/gtest-load-save-files.cpp
Normal file
318
libgnucash/backend/xml/test/gtest-load-save-files.cpp
Normal file
@ -0,0 +1,318 @@
|
||||
/********************************************************************\
|
||||
* 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 <glib/gfileutils.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include <config.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cashobjects.h>
|
||||
#include <TransLog.h>
|
||||
#include <gnc-engine.h>
|
||||
#include <gnc-prefs.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <unittest-support.h>
|
||||
|
||||
#include "../gnc-backend-xml.h"
|
||||
#include "../io-gncxml-v2.h"
|
||||
|
||||
#define GNC_LIB_NAME "gncmod-backend-xml"
|
||||
#define GNC_LIB_REL_PATH "xml"
|
||||
|
||||
static std::vector<unsigned char> read_file (std::string filename)
|
||||
{
|
||||
gchar *contents;
|
||||
gsize length = 0;
|
||||
|
||||
if (g_file_get_contents (filename.c_str (), &contents, &length, nullptr))
|
||||
{
|
||||
std::vector<unsigned char> data(length);
|
||||
|
||||
memcpy (data.data (), contents, length);
|
||||
g_free (contents);
|
||||
return data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
compare_files (std::string filename1, std::string filename2)
|
||||
{
|
||||
auto contents1 = read_file (filename1);
|
||||
auto contents2 = read_file (filename2);
|
||||
|
||||
if (contents1.size () > 0 && contents1.size () == contents2.size ()
|
||||
&& !memcmp(contents1.data (), contents2.data (), contents1.size ())) {
|
||||
return true;
|
||||
} else {
|
||||
ADD_FAILURE() << "compare_files: " << filename1 << " and " << filename2 << " are different";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
decompress_file (std::string filename, const std::vector<unsigned char> &in, std::vector<unsigned char> &out)
|
||||
{
|
||||
/* 037 0213 are the header id bytes for a gzipped file. */
|
||||
if (in.size () < 2 || in[0] != 037 || in[1] != 0213)
|
||||
{
|
||||
ADD_FAILURE() << "decompress_file: " << filename << " is not compressed";
|
||||
return false;
|
||||
}
|
||||
|
||||
z_stream stream{};
|
||||
stream.next_in = const_cast<unsigned char*>(in.data ());
|
||||
stream.avail_in = in.size ();
|
||||
stream.zalloc = Z_NULL;
|
||||
stream.zfree = Z_NULL;
|
||||
stream.opaque = Z_NULL;
|
||||
stream.next_out = out.data ();
|
||||
stream.avail_out = out.size ();
|
||||
|
||||
/* "add 16 to decode only the gzip format" */
|
||||
int ret = inflateInit2 (&stream, 16 + MAX_WBITS);
|
||||
if (ret != Z_OK)
|
||||
{
|
||||
ADD_FAILURE() << "decompress_file: " << filename << " could not be uncompressed (inflateInit): " << ret;
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = inflate (&stream, Z_NO_FLUSH);
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
ADD_FAILURE() << "decompress_file: " << filename << " could not be uncompressed (inflate "
|
||||
<< in.size () << " into " << out.size() << "): " << ret << " " << stream.msg
|
||||
<< " (avail_in " << stream.avail_in << " avail_out " << stream.avail_out << ")";
|
||||
inflateEnd (&stream);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = inflateEnd (&stream);
|
||||
if (ret != Z_OK)
|
||||
{
|
||||
ADD_FAILURE() << "decompress_file: " << filename << " could not be uncompressed (inflateEnd): " << ret;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stream.avail_in)
|
||||
{
|
||||
ADD_FAILURE() << "decompress_file: " << filename << " has unused compressed data: " << stream.avail_in;
|
||||
return false;
|
||||
}
|
||||
|
||||
out.resize (stream.avail_out);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
compare_compressed_files (std::string uncompressed_filename1, std::string compressed_filename2)
|
||||
{
|
||||
auto uncompressed_contents1 = read_file (uncompressed_filename1);
|
||||
auto compressed_contents2 = read_file (compressed_filename2);
|
||||
/* Allow some space to grow beyond the expected size */
|
||||
std::vector<unsigned char> uncompressed_contents2(uncompressed_contents1.size () * 2);
|
||||
|
||||
if (!decompress_file (compressed_filename2, compressed_contents2, uncompressed_contents2))
|
||||
return false;
|
||||
|
||||
if (uncompressed_contents1.size () > 0
|
||||
&& uncompressed_contents1.size () != uncompressed_contents2.size ())
|
||||
{
|
||||
ADD_FAILURE() << "compare_compressed_files: " << uncompressed_filename1
|
||||
<< " and " << compressed_filename2 << " are different sizes or empty ("
|
||||
<< uncompressed_contents1.size () << " and "
|
||||
<< uncompressed_contents2.size () << ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!memcmp(uncompressed_contents1.data (), uncompressed_contents2.data (), uncompressed_contents1.size ())) {
|
||||
return true;
|
||||
} else {
|
||||
ADD_FAILURE() << "compare_compressed_files: " << uncompressed_filename1
|
||||
<< " and " << compressed_filename2 << " are different";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* The original file is used for comparisons. The file will be different when
|
||||
* there are future changes in the GnuCash output and needs to be updated if
|
||||
* that happens.
|
||||
*
|
||||
* Using the same file each time also checks that nothing in the file will swap
|
||||
* between two stable states (bug 746937).
|
||||
*/
|
||||
class LoadSaveFiles : public testing::TestWithParam<std::string>
|
||||
{
|
||||
public:
|
||||
static void SetUpTestSuite ()
|
||||
{
|
||||
g_setenv ("GNC_UNINSTALLED", "1", TRUE);
|
||||
qof_init ();
|
||||
cashobjects_register ();
|
||||
ASSERT_TRUE(qof_load_backend_library (GNC_LIB_REL_PATH, GNC_LIB_NAME)) << "loading gnc-backend-xml GModule failed";
|
||||
xaccLogDisable ();
|
||||
}
|
||||
|
||||
static void TearDownTestSuite ()
|
||||
{
|
||||
qof_close ();
|
||||
}
|
||||
};
|
||||
|
||||
#define QOF_SESSION_CHECKED_CALL(_function, _session, ...) \
|
||||
do { \
|
||||
_function (_session.get (), ## __VA_ARGS__); \
|
||||
ASSERT_EQ (qof_session_get_error (_session.get ()), 0) << #_function \
|
||||
<< " (" << #_session << ".get (), " << #__VA_ARGS__ << "): " << qof_session_get_error (_session.get ()) \
|
||||
<< " \"" << qof_session_get_error_message (_session.get ()) << "\""; \
|
||||
} while (0)
|
||||
|
||||
TEST_P(LoadSaveFiles, test_file)
|
||||
{
|
||||
auto filename = GetParam();
|
||||
/* Verify that we can write a compressed version of the original file that
|
||||
* has the original content when uncompressed.
|
||||
*/
|
||||
auto new_compressed_file = filename + "-test-compressed~";
|
||||
/* Verify that we can read a compressed file and write an uncompressed file
|
||||
* that has the original content.
|
||||
*/
|
||||
auto new_uncompressed_file = filename + "-test-uncompressed~";
|
||||
const char *logdomain = "backend.xml";
|
||||
GLogLevelFlags loglevel = static_cast<decltype (loglevel)>
|
||||
(G_LOG_LEVEL_WARNING);
|
||||
TestErrorStruct check = { loglevel, const_cast<char*> (logdomain), nullptr };
|
||||
g_log_set_handler (logdomain, loglevel,
|
||||
(GLogFunc)test_checked_handler, &check);
|
||||
|
||||
{
|
||||
auto load_uncompressed_session = std::shared_ptr<QofSession>{qof_session_new (qof_book_new ()), qof_session_destroy};
|
||||
|
||||
QOF_SESSION_CHECKED_CALL(qof_session_begin, load_uncompressed_session, filename.c_str (), SESSION_READ_ONLY);
|
||||
QOF_SESSION_CHECKED_CALL(qof_session_load, load_uncompressed_session, nullptr);
|
||||
|
||||
auto save_compressed_session = std::shared_ptr<QofSession>{qof_session_new (nullptr), qof_session_destroy};
|
||||
|
||||
g_unlink (new_compressed_file.c_str ());
|
||||
g_unlink ((new_compressed_file + ".LCK").c_str ());
|
||||
QOF_SESSION_CHECKED_CALL(qof_session_begin, save_compressed_session, new_compressed_file.c_str (), SESSION_NEW_OVERWRITE);
|
||||
|
||||
qof_event_suspend ();
|
||||
qof_session_swap_data (load_uncompressed_session.get (), save_compressed_session.get ());
|
||||
qof_book_mark_session_dirty (qof_session_get_book (save_compressed_session.get ()));
|
||||
qof_event_resume ();
|
||||
|
||||
qof_session_end (load_uncompressed_session.get ());
|
||||
|
||||
gnc_prefs_set_file_save_compressed (TRUE);
|
||||
QOF_SESSION_CHECKED_CALL(qof_session_save, save_compressed_session, nullptr);
|
||||
|
||||
qof_session_end (save_compressed_session.get ());
|
||||
}
|
||||
|
||||
if (!compare_compressed_files (filename, new_compressed_file))
|
||||
return;
|
||||
|
||||
{
|
||||
auto load_compressed_session = std::shared_ptr<QofSession>{qof_session_new (qof_book_new ()), qof_session_destroy};
|
||||
|
||||
QOF_SESSION_CHECKED_CALL(qof_session_begin, load_compressed_session, new_compressed_file.c_str (), SESSION_READ_ONLY);
|
||||
QOF_SESSION_CHECKED_CALL(qof_session_load, load_compressed_session, nullptr);
|
||||
|
||||
auto save_uncompressed_session = std::shared_ptr<QofSession>{qof_session_new (nullptr), qof_session_destroy};
|
||||
|
||||
g_unlink (new_uncompressed_file.c_str ());
|
||||
g_unlink ((new_uncompressed_file + ".LCK").c_str ());
|
||||
QOF_SESSION_CHECKED_CALL(qof_session_begin, save_uncompressed_session, new_uncompressed_file.c_str (), SESSION_NEW_OVERWRITE);
|
||||
|
||||
qof_event_suspend ();
|
||||
qof_session_swap_data (load_compressed_session.get (), save_uncompressed_session.get ());
|
||||
qof_book_mark_session_dirty (qof_session_get_book (save_uncompressed_session.get ()));
|
||||
qof_event_resume ();
|
||||
|
||||
qof_session_end (load_compressed_session.get ());
|
||||
|
||||
gnc_prefs_set_file_save_compressed (FALSE);
|
||||
QOF_SESSION_CHECKED_CALL(qof_session_save, save_uncompressed_session, nullptr);
|
||||
|
||||
qof_session_end (save_uncompressed_session.get ());
|
||||
}
|
||||
|
||||
if (!compare_files (filename, new_uncompressed_file))
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> ListTestCases ();
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
LoadSaveFilesDir,
|
||||
LoadSaveFiles,
|
||||
testing::ValuesIn (ListTestCases ()));
|
||||
|
||||
std::vector<std::string> ListTestCases ()
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
const char *location = g_getenv ("GNC_TEST_FILES");
|
||||
|
||||
if (!location)
|
||||
location = "test-files/load-save";
|
||||
|
||||
std::shared_ptr<GDir> dir{g_dir_open (location, 0, nullptr), g_dir_close};
|
||||
if (dir)
|
||||
{
|
||||
const gchar *entry;
|
||||
|
||||
while ((entry = g_dir_read_name (dir.get ())) != nullptr)
|
||||
{
|
||||
if (g_str_has_suffix (entry, ".gnucash"))
|
||||
{
|
||||
std::shared_ptr<gchar> to_open{g_build_filename (location, entry, (gchar*)nullptr), g_free};
|
||||
|
||||
if (!g_file_test (to_open.get (), G_FILE_TEST_IS_DIR))
|
||||
files.push_back (to_open.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_FAILURE() << "unable to open directory " << location;
|
||||
}
|
||||
|
||||
EXPECT_FALSE(files.empty()) << "no files found in " << location;
|
||||
return files;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
|
||||
add_subdirectory(load-save)
|
||||
add_subdirectory(xml2)
|
||||
|
||||
set_local_dist(test_backend_xml_test_files_DIST_local CMakeLists.txt )
|
||||
set(test_backend_xml_test_files_DIST ${test_backend_xml_test_files_DIST_local} ${xml2_DIST} PARENT_SCOPE)
|
||||
|
||||
set(test_backend_xml_test_files_DIST ${test_backend_xml_test_files_DIST_local} ${load_save_DIST} ${xml2_DIST} PARENT_SCOPE)
|
||||
|
@ -0,0 +1,4 @@
|
||||
set_dist_list(load_save_DIST
|
||||
bug-746937-sx-split-order.gnucash
|
||||
sample1.gnucash
|
||||
)
|
6
libgnucash/backend/xml/test/test-files/load-save/README
Normal file
6
libgnucash/backend/xml/test/test-files/load-save/README
Normal file
@ -0,0 +1,6 @@
|
||||
These files are used for testing loading and saving
|
||||
|
||||
If the "load-save-files" test fails because the written XML file is now
|
||||
different, zcat *.gnucash-compressed~ to *.gnucash, check that the changes
|
||||
are appropriate, expected and have the right backward/forward compatibility
|
||||
then commit the new versions of the files.
|
@ -0,0 +1,406 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<gnc-v2
|
||||
xmlns:gnc="http://www.gnucash.org/XML/gnc"
|
||||
xmlns:act="http://www.gnucash.org/XML/act"
|
||||
xmlns:book="http://www.gnucash.org/XML/book"
|
||||
xmlns:cd="http://www.gnucash.org/XML/cd"
|
||||
xmlns:cmdty="http://www.gnucash.org/XML/cmdty"
|
||||
xmlns:price="http://www.gnucash.org/XML/price"
|
||||
xmlns:slot="http://www.gnucash.org/XML/slot"
|
||||
xmlns:split="http://www.gnucash.org/XML/split"
|
||||
xmlns:sx="http://www.gnucash.org/XML/sx"
|
||||
xmlns:trn="http://www.gnucash.org/XML/trn"
|
||||
xmlns:ts="http://www.gnucash.org/XML/ts"
|
||||
xmlns:fs="http://www.gnucash.org/XML/fs"
|
||||
xmlns:bgt="http://www.gnucash.org/XML/bgt"
|
||||
xmlns:recurrence="http://www.gnucash.org/XML/recurrence"
|
||||
xmlns:lot="http://www.gnucash.org/XML/lot"
|
||||
xmlns:addr="http://www.gnucash.org/XML/addr"
|
||||
xmlns:billterm="http://www.gnucash.org/XML/billterm"
|
||||
xmlns:bt-days="http://www.gnucash.org/XML/bt-days"
|
||||
xmlns:bt-prox="http://www.gnucash.org/XML/bt-prox"
|
||||
xmlns:cust="http://www.gnucash.org/XML/cust"
|
||||
xmlns:employee="http://www.gnucash.org/XML/employee"
|
||||
xmlns:entry="http://www.gnucash.org/XML/entry"
|
||||
xmlns:invoice="http://www.gnucash.org/XML/invoice"
|
||||
xmlns:job="http://www.gnucash.org/XML/job"
|
||||
xmlns:order="http://www.gnucash.org/XML/order"
|
||||
xmlns:owner="http://www.gnucash.org/XML/owner"
|
||||
xmlns:taxtable="http://www.gnucash.org/XML/taxtable"
|
||||
xmlns:tte="http://www.gnucash.org/XML/tte"
|
||||
xmlns:vendor="http://www.gnucash.org/XML/vendor">
|
||||
<gnc:count-data cd:type="book">1</gnc:count-data>
|
||||
<gnc:book version="2.0.0">
|
||||
<book:id type="guid">78552b4ebbba9bf429f6a1f4b861b538</book:id>
|
||||
<gnc:count-data cd:type="commodity">1</gnc:count-data>
|
||||
<gnc:count-data cd:type="account">9</gnc:count-data>
|
||||
<gnc:count-data cd:type="schedxaction">1</gnc:count-data>
|
||||
<gnc:commodity version="2.0.0">
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
<cmdty:get_quotes/>
|
||||
<cmdty:quote_source>currency</cmdty:quote_source>
|
||||
<cmdty:quote_tz/>
|
||||
</gnc:commodity>
|
||||
<gnc:commodity version="2.0.0">
|
||||
<cmdty:space>template</cmdty:space>
|
||||
<cmdty:id>template</cmdty:id>
|
||||
<cmdty:name>template</cmdty:name>
|
||||
<cmdty:xcode>template</cmdty:xcode>
|
||||
<cmdty:fraction>1</cmdty:fraction>
|
||||
</gnc:commodity>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Root Account</act:name>
|
||||
<act:id type="guid">22067e5b3cf257e20070e0d2307ac0b0</act:id>
|
||||
<act:type>ROOT</act:type>
|
||||
</gnc:account>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Assets</act:name>
|
||||
<act:id type="guid">1244bef69b14889a06271df59645c35d</act:id>
|
||||
<act:type>ASSET</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>100</act:commodity-scu>
|
||||
<act:description>Assets</act:description>
|
||||
<act:slots>
|
||||
<slot>
|
||||
<slot:key>placeholder</slot:key>
|
||||
<slot:value type="string">true</slot:value>
|
||||
</slot>
|
||||
</act:slots>
|
||||
<act:parent type="guid">22067e5b3cf257e20070e0d2307ac0b0</act:parent>
|
||||
</gnc:account>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Current Assets</act:name>
|
||||
<act:id type="guid">be6deddf8a970ff14cb8be91a958a3eb</act:id>
|
||||
<act:type>ASSET</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>100</act:commodity-scu>
|
||||
<act:description>Current Assets</act:description>
|
||||
<act:slots>
|
||||
<slot>
|
||||
<slot:key>placeholder</slot:key>
|
||||
<slot:value type="string">true</slot:value>
|
||||
</slot>
|
||||
</act:slots>
|
||||
<act:parent type="guid">1244bef69b14889a06271df59645c35d</act:parent>
|
||||
</gnc:account>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Bank</act:name>
|
||||
<act:id type="guid">9b0050507226d570c754f688caf3e577</act:id>
|
||||
<act:type>BANK</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>100</act:commodity-scu>
|
||||
<act:slots>
|
||||
<slot>
|
||||
<slot:key>placeholder</slot:key>
|
||||
<slot:value type="string">true</slot:value>
|
||||
</slot>
|
||||
</act:slots>
|
||||
<act:parent type="guid">be6deddf8a970ff14cb8be91a958a3eb</act:parent>
|
||||
</gnc:account>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Current Account</act:name>
|
||||
<act:id type="guid">f0d5a52f1fd957b8a414aedf3f55c626</act:id>
|
||||
<act:type>BANK</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>100</act:commodity-scu>
|
||||
<act:parent type="guid">9b0050507226d570c754f688caf3e577</act:parent>
|
||||
</gnc:account>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Liabilities</act:name>
|
||||
<act:id type="guid">1f5a3d5c6157c5e78d9961bbd3afc85f</act:id>
|
||||
<act:type>LIABILITY</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>100</act:commodity-scu>
|
||||
<act:description>Liabilities</act:description>
|
||||
<act:slots>
|
||||
<slot>
|
||||
<slot:key>placeholder</slot:key>
|
||||
<slot:value type="string">true</slot:value>
|
||||
</slot>
|
||||
</act:slots>
|
||||
<act:parent type="guid">22067e5b3cf257e20070e0d2307ac0b0</act:parent>
|
||||
</gnc:account>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Company</act:name>
|
||||
<act:id type="guid">59b2fcdab565c906362f5a24f4a909f7</act:id>
|
||||
<act:type>LIABILITY</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>100</act:commodity-scu>
|
||||
<act:parent type="guid">1f5a3d5c6157c5e78d9961bbd3afc85f</act:parent>
|
||||
</gnc:account>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Account 1</act:name>
|
||||
<act:id type="guid">b5c34f61b594d4e6c8ce18591a9813ad</act:id>
|
||||
<act:type>LIABILITY</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>100</act:commodity-scu>
|
||||
<act:parent type="guid">59b2fcdab565c906362f5a24f4a909f7</act:parent>
|
||||
</gnc:account>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Account 2</act:name>
|
||||
<act:id type="guid">bce28fe18ad558edb87c8282369ed373</act:id>
|
||||
<act:type>LIABILITY</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>100</act:commodity-scu>
|
||||
<act:slots>
|
||||
<slot>
|
||||
<slot:key>color</slot:key>
|
||||
<slot:value type="string">Not Set</slot:value>
|
||||
</slot>
|
||||
</act:slots>
|
||||
<act:parent type="guid">59b2fcdab565c906362f5a24f4a909f7</act:parent>
|
||||
</gnc:account>
|
||||
<gnc:template-transactions>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>Template Root</act:name>
|
||||
<act:id type="guid">4586cdb4267a59437526549e14b0e74b</act:id>
|
||||
<act:type>ROOT</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>template</cmdty:space>
|
||||
<cmdty:id>template</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>1</act:commodity-scu>
|
||||
<act:non-standard-scu/>
|
||||
</gnc:account>
|
||||
<gnc:account version="2.0.0">
|
||||
<act:name>52f96837087e9670c933f9421b0ac626</act:name>
|
||||
<act:id type="guid">22f2905cbcfa0b910c0dbc348cfc1161</act:id>
|
||||
<act:type>BANK</act:type>
|
||||
<act:commodity>
|
||||
<cmdty:space>template</cmdty:space>
|
||||
<cmdty:id>template</cmdty:id>
|
||||
</act:commodity>
|
||||
<act:commodity-scu>1</act:commodity-scu>
|
||||
<act:non-standard-scu/>
|
||||
<act:parent type="guid">4586cdb4267a59437526549e14b0e74b</act:parent>
|
||||
</gnc:account>
|
||||
<gnc:transaction version="2.0.0">
|
||||
<trn:id type="guid">68bf5e7740392eb15a079ee99f18a357</trn:id>
|
||||
<trn:currency>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</trn:currency>
|
||||
<trn:date-posted>
|
||||
<ts:date>2010-08-01 08:40:17 +0000</ts:date>
|
||||
</trn:date-posted>
|
||||
<trn:date-entered>
|
||||
<ts:date>2010-08-01 08:40:17 +0000</ts:date>
|
||||
</trn:date-entered>
|
||||
<trn:description>Description 2</trn:description>
|
||||
<trn:splits>
|
||||
<trn:split>
|
||||
<split:id type="guid">676a518eb1cf05ca552434533288a5cd</split:id>
|
||||
<split:reconciled-state>n</split:reconciled-state>
|
||||
<split:value>0/100</split:value>
|
||||
<split:quantity>0/1</split:quantity>
|
||||
<split:account type="guid">22f2905cbcfa0b910c0dbc348cfc1161</split:account>
|
||||
<split:slots>
|
||||
<slot>
|
||||
<slot:key>sched-xaction</slot:key>
|
||||
<slot:value type="frame">
|
||||
<slot>
|
||||
<slot:key>account</slot:key>
|
||||
<slot:value type="guid">bce28fe18ad558edb87c8282369ed373</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>credit-formula</slot:key>
|
||||
<slot:value type="string"></slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>credit-numeric</slot:key>
|
||||
<slot:value type="numeric">0/1</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>debit-formula</slot:key>
|
||||
<slot:value type="string">456</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>debit-numeric</slot:key>
|
||||
<slot:value type="numeric">456/1</slot:value>
|
||||
</slot>
|
||||
</slot:value>
|
||||
</slot>
|
||||
</split:slots>
|
||||
</trn:split>
|
||||
<trn:split>
|
||||
<split:id type="guid">1b779b05012759adbac315f1f50af621</split:id>
|
||||
<split:reconciled-state>n</split:reconciled-state>
|
||||
<split:value>0/100</split:value>
|
||||
<split:quantity>0/1</split:quantity>
|
||||
<split:account type="guid">22f2905cbcfa0b910c0dbc348cfc1161</split:account>
|
||||
<split:slots>
|
||||
<slot>
|
||||
<slot:key>sched-xaction</slot:key>
|
||||
<slot:value type="frame">
|
||||
<slot>
|
||||
<slot:key>account</slot:key>
|
||||
<slot:value type="guid">f0d5a52f1fd957b8a414aedf3f55c626</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>credit-formula</slot:key>
|
||||
<slot:value type="string">456</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>credit-numeric</slot:key>
|
||||
<slot:value type="numeric">456/1</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>debit-formula</slot:key>
|
||||
<slot:value type="string"></slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>debit-numeric</slot:key>
|
||||
<slot:value type="numeric">0/1</slot:value>
|
||||
</slot>
|
||||
</slot:value>
|
||||
</slot>
|
||||
</split:slots>
|
||||
</trn:split>
|
||||
</trn:splits>
|
||||
</gnc:transaction>
|
||||
<gnc:transaction version="2.0.0">
|
||||
<trn:id type="guid">2fbcf6cc8224673bc93501399d4ca7be</trn:id>
|
||||
<trn:currency>
|
||||
<cmdty:space>CURRENCY</cmdty:space>
|
||||
<cmdty:id>GBP</cmdty:id>
|
||||
</trn:currency>
|
||||
<trn:date-posted>
|
||||
<ts:date>2010-09-11 23:00:00 +0000</ts:date>
|
||||
</trn:date-posted>
|
||||
<trn:date-entered>
|
||||
<ts:date>2010-09-12 08:51:53 +0000</ts:date>
|
||||
</trn:date-entered>
|
||||
<trn:description>Description 1</trn:description>
|
||||
<trn:slots>
|
||||
<slot>
|
||||
<slot:key>notes</slot:key>
|
||||
<slot:value type="string"></slot:value>
|
||||
</slot>
|
||||
</trn:slots>
|
||||
<trn:splits>
|
||||
<trn:split>
|
||||
<split:id type="guid">378dd92bd1819a52e491b6d8c123f662</split:id>
|
||||
<split:reconciled-state>n</split:reconciled-state>
|
||||
<split:value>0/100</split:value>
|
||||
<split:quantity>0/1</split:quantity>
|
||||
<split:account type="guid">22f2905cbcfa0b910c0dbc348cfc1161</split:account>
|
||||
<split:slots>
|
||||
<slot>
|
||||
<slot:key>sched-xaction</slot:key>
|
||||
<slot:value type="frame">
|
||||
<slot>
|
||||
<slot:key>account</slot:key>
|
||||
<slot:value type="guid">b5c34f61b594d4e6c8ce18591a9813ad</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>credit-formula</slot:key>
|
||||
<slot:value type="string"></slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>credit-numeric</slot:key>
|
||||
<slot:value type="numeric">0/1</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>debit-formula</slot:key>
|
||||
<slot:value type="string">123</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>debit-numeric</slot:key>
|
||||
<slot:value type="numeric">123/1</slot:value>
|
||||
</slot>
|
||||
</slot:value>
|
||||
</slot>
|
||||
</split:slots>
|
||||
</trn:split>
|
||||
<trn:split>
|
||||
<split:id type="guid">75e005248499f7dfb46a80c9778e2e13</split:id>
|
||||
<split:reconciled-state>n</split:reconciled-state>
|
||||
<split:value>0/100</split:value>
|
||||
<split:quantity>0/1</split:quantity>
|
||||
<split:account type="guid">22f2905cbcfa0b910c0dbc348cfc1161</split:account>
|
||||
<split:slots>
|
||||
<slot>
|
||||
<slot:key>sched-xaction</slot:key>
|
||||
<slot:value type="frame">
|
||||
<slot>
|
||||
<slot:key>account</slot:key>
|
||||
<slot:value type="guid">f0d5a52f1fd957b8a414aedf3f55c626</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>credit-formula</slot:key>
|
||||
<slot:value type="string">123</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>credit-numeric</slot:key>
|
||||
<slot:value type="numeric">123/1</slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>debit-formula</slot:key>
|
||||
<slot:value type="string"></slot:value>
|
||||
</slot>
|
||||
<slot>
|
||||
<slot:key>debit-numeric</slot:key>
|
||||
<slot:value type="numeric">0/1</slot:value>
|
||||
</slot>
|
||||
</slot:value>
|
||||
</slot>
|
||||
</split:slots>
|
||||
</trn:split>
|
||||
</trn:splits>
|
||||
</gnc:transaction>
|
||||
</gnc:template-transactions>
|
||||
<gnc:schedxaction version="2.0.0">
|
||||
<sx:id type="guid">52f96837087e9670c933f9421b0ac626</sx:id>
|
||||
<sx:name>Scheduled Transaction</sx:name>
|
||||
<sx:enabled>n</sx:enabled>
|
||||
<sx:autoCreate>y</sx:autoCreate>
|
||||
<sx:autoCreateNotify>n</sx:autoCreateNotify>
|
||||
<sx:advanceCreateDays>90</sx:advanceCreateDays>
|
||||
<sx:advanceRemindDays>0</sx:advanceRemindDays>
|
||||
<sx:instanceCount>5</sx:instanceCount>
|
||||
<sx:start>
|
||||
<gdate>2010-10-05</gdate>
|
||||
</sx:start>
|
||||
<sx:last>
|
||||
<gdate>2011-11-07</gdate>
|
||||
</sx:last>
|
||||
<sx:templ-acct type="guid">22f2905cbcfa0b910c0dbc348cfc1161</sx:templ-acct>
|
||||
<sx:schedule>
|
||||
<gnc:recurrence version="1.0.0">
|
||||
<recurrence:mult>1</recurrence:mult>
|
||||
<recurrence:period_type>month</recurrence:period_type>
|
||||
<recurrence:start>
|
||||
<gdate>2010-10-05</gdate>
|
||||
</recurrence:start>
|
||||
<recurrence:weekend_adj>forward</recurrence:weekend_adj>
|
||||
</gnc:recurrence>
|
||||
</sx:schedule>
|
||||
</gnc:schedxaction>
|
||||
</gnc:book>
|
||||
</gnc-v2>
|
||||
|
1563
libgnucash/backend/xml/test/test-files/load-save/sample1.gnucash
Normal file
1563
libgnucash/backend/xml/test/test-files/load-save/sample1.gnucash
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user