mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Test loading and saving XML files with and without compression
Add new test files that are written with the latest version of GnuCash. Test loading them, saving to compressed files, loading those compressed files and writing to an uncompressed file. At every stage check it matches the canonical version.
This commit is contained in:
parent
ab4e595670
commit
35bee1382d
@ -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