summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2015-08-04 14:33:03 -0700
committerJohn Wiegley <johnw@newartisans.com>2015-08-04 14:33:03 -0700
commita3e946f90f902600819f64217c8cd98c72bb21ba (patch)
treed7f0de1c234b457ce608c38d71040bca4cff43eb
parent947a46ebebd141e928a9fcebb584e34df4e210a7 (diff)
parentfbba9adc16c515632a5009d2ec88c9fcab532676 (diff)
downloadfork-ledger-a3e946f90f902600819f64217c8cd98c72bb21ba.tar.gz
fork-ledger-a3e946f90f902600819f64217c8cd98c72bb21ba.tar.bz2
fork-ledger-a3e946f90f902600819f64217c8cd98c72bb21ba.zip
Merge remote-tracking branch 'origin/master' into next
-rw-r--r--doc/ledger3.texi2
-rw-r--r--src/filters.cc33
-rw-r--r--src/filters.h13
-rw-r--r--src/value.cc4
-rw-r--r--test/unit/CMakeLists.txt2
-rw-r--r--test/unit/t_value.cc714
6 files changed, 752 insertions, 16 deletions
diff --git a/doc/ledger3.texi b/doc/ledger3.texi
index eeae7ad3..c4266c20 100644
--- a/doc/ledger3.texi
+++ b/doc/ledger3.texi
@@ -7874,7 +7874,7 @@ considering children.
The cost of a posting; the cost of an account, without its
children.
-@item l
+@item depth
The depth (``level'') of an account. If an account has one parent,
its depth is one.
diff --git a/src/filters.cc b/src/filters.cc
index b6530c04..d9fb64b0 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -448,16 +448,20 @@ void collapse_posts::report_subtotal()
DEBUG("filters.collapse", "Pseudo-xact date = " << *xact._date);
DEBUG("filters.collapse", "earliest date = " << earliest_date);
DEBUG("filters.collapse", "latest date = " << latest_date);
+
+ foreach (totals_map::value_type& pat, totals) {
+ handle_value(/* value= */ pat.second,
+ /* account= */ &temps.create_account(pat.first),
+ /* xact= */ &xact,
+ /* temps= */ temps,
+ /* handler= */ handler,
+ /* date= */ latest_date,
+ /* act_date_p= */ false);
+ }
- handle_value(/* value= */ subtotal,
- /* account= */ totals_account,
- /* xact= */ &xact,
- /* temps= */ temps,
- /* handler= */ handler,
- /* date= */ latest_date,
- /* act_date_p= */ false);
}
+ totals.clear();
component_posts.clear();
last_xact = NULL;
@@ -466,6 +470,20 @@ void collapse_posts::report_subtotal()
count = 0;
}
+value_t& collapse_posts::find_totals(account_t* account)
+{
+ unsigned short depth=3;
+
+ if(depth==0)
+ return totals[_("<Total>")];
+
+ if(account->depth==depth)
+ return totals[account->fullname()];
+
+ //else recurse
+ return find_totals(account->parent);
+}
+
void collapse_posts::operator()(post_t& post)
{
// If we've reached a new xact, report on the subtotal
@@ -475,6 +493,7 @@ void collapse_posts::operator()(post_t& post)
report_subtotal();
post.add_to_value(subtotal, amount_expr);
+ post.add_to_value(find_totals(post.account), amount_expr);
component_posts.push_back(&post);
diff --git a/src/filters.h b/src/filters.h
index 1404b38e..9b745235 100644
--- a/src/filters.h
+++ b/src/filters.h
@@ -421,6 +421,9 @@ public:
class collapse_posts : public item_handler<post_t>
{
+
+ typedef std::map<string,value_t> totals_map;
+
expr_t& amount_expr;
predicate_t display_predicate;
predicate_t only_predicate;
@@ -429,7 +432,7 @@ class collapse_posts : public item_handler<post_t>
xact_t * last_xact;
post_t * last_post;
temporaries_t temps;
- account_t * totals_account;
+ totals_map totals;
bool only_collapse_if_zero;
std::list<post_t *> component_posts;
report_t& report;
@@ -448,17 +451,13 @@ public:
only_predicate(_only_predicate), count(0),
last_xact(NULL), last_post(NULL),
only_collapse_if_zero(_only_collapse_if_zero), report(_report) {
- create_accounts();
TRACE_CTOR(collapse_posts, "post_handler_ptr, ...");
}
virtual ~collapse_posts() {
TRACE_DTOR(collapse_posts);
handler.reset();
}
-
- void create_accounts() {
- totals_account = &temps.create_account(_("<Total>"));
- }
+ value_t& find_totals(account_t* account);
virtual void flush() {
report_subtotal();
@@ -480,7 +479,7 @@ public:
last_post = NULL;
temps.clear();
- create_accounts();
+ totals.clear();
component_posts.clear();
item_handler<post_t>::clear();
diff --git a/src/value.cc b/src/value.cc
index 2737add9..4ea7c7a8 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -341,6 +341,10 @@ value_t& value_t::operator+=(const value_t& val)
}
switch (type()) {
+ case VOID:
+ *this = value_t(val);
+ return *this;
+
case DATETIME:
switch (val.type()) {
case INTEGER:
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index b440d2ed..de7fdd26 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -12,7 +12,7 @@ if (BUILD_LIBRARY)
endif()
add_ledger_test(UtilTests)
- add_executable(MathTests t_amount.cc t_commodity.cc t_balance.cc t_expr.cc)
+ add_executable(MathTests t_amount.cc t_commodity.cc t_balance.cc t_expr.cc t_value.cc)
set_source_files_properties(t_amount.cc PROPERTIES COMPILE_FLAGS "-Wno-unused-comparison")
if (CMAKE_SYSTEM_NAME STREQUAL Darwin AND HAVE_BOOST_PYTHON)
target_link_libraries(MathTests ${PYTHON_LIBRARIES})
diff --git a/test/unit/t_value.cc b/test/unit/t_value.cc
new file mode 100644
index 00000000..e8367bbe
--- /dev/null
+++ b/test/unit/t_value.cc
@@ -0,0 +1,714 @@
+#define BOOST_TEST_DYN_LINK
+
+#include <boost/test/unit_test.hpp>
+
+#include <system.hh>
+
+#include "value.h"
+
+using namespace ledger;
+
+struct value_fixture {
+ value_fixture() {
+ times_initialize();
+ amount_t::initialize();
+ value_t::initialize();
+
+
+ // Cause the display precision for dollars to be initialized to 2.
+ amount_t x1("$1.00");
+ BOOST_CHECK(x1);
+
+ amount_t::stream_fullstrings = true; // make reports from UnitTests accurate
+ }
+
+ ~value_fixture()
+ {
+ amount_t::stream_fullstrings = false;
+ amount_t::shutdown();
+ times_shutdown();
+ value_t::shutdown();
+ }
+};
+
+BOOST_FIXTURE_TEST_SUITE(value, value_fixture)
+
+BOOST_AUTO_TEST_CASE(testConstructors)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_t(NULL)));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(4UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("3 EUR"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("tag"), true);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testAssignment)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2 = true;
+ value_t v3 = boost::posix_time::from_time_t(time_t(NULL));
+ value_t v4 = date_t(parse_date("2014/08/14"));
+ value_t v5 = -2L;
+ value_t v6 = 4UL;
+ value_t v7 = 1.00;
+ value_t v8 = amount_t("4 GBP");
+ value_t v9 = balance_t("3 EUR");
+ value_t v10 = mask_t("regex");
+ value_t v11 = s1;
+ value_t v12 = value_t(string("$1"));
+ value_t v13 = value_t("2 CAD");
+ value_t v14 = value_t("comment", true);
+ value_t v15 = value_t(string("tag"), true);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testEquality)
+{
+ struct tm localtime;
+ strptime("10 February 2010", "%d %b %Y", &localtime);
+ time_t time_var = mktime(&localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_var));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(2UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16;
+
+ BOOST_CHECK_EQUAL(v1, value_t());
+ BOOST_CHECK_EQUAL(v2, value_t(true));
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::from_time_t(time_var)));
+ BOOST_CHECK(!(v4 == value_t(date_t(parse_date("2014/08/15")))));
+
+ value_t v19(amount_t("2"));
+ value_t v20(balance_t("2"));
+ BOOST_CHECK_EQUAL(v5, v6);
+ BOOST_CHECK_EQUAL(v5, v19);
+ BOOST_CHECK_EQUAL(v5, v20);
+ BOOST_CHECK(v19 == v5);
+ BOOST_CHECK(v19 == v20);
+ BOOST_CHECK(v19 == value_t(amount_t("2")));
+ BOOST_CHECK(v20 == v5);
+ BOOST_CHECK(v20 == v19);
+ BOOST_CHECK(v20 == value_t(balance_t(2L)));
+ BOOST_CHECK(v14 == v15);
+ BOOST_CHECK(v10 == value_t(mask_t("regex")));
+ BOOST_CHECK(v11 == value_t(s1));
+
+ BOOST_CHECK_THROW(v8 == v10, value_error);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v19.valid());
+ BOOST_CHECK(v20.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testSequence)
+{
+ value_t::sequence_t s1;
+ value_t v1(s1);
+ BOOST_CHECK(v1.is_sequence());
+ v1.push_back(value_t(2L));
+ v1.push_back(value_t("3 GBP"));
+
+ value_t v2("3 GBP");
+ value_t seq(v1);
+ const value_t v3(seq);
+
+ value_t::sequence_t::iterator i = std::find(seq.begin(), seq.end(), v2);
+ if (i != seq.end())
+ BOOST_CHECK(v2 == *i);
+
+ value_t::sequence_t::const_iterator j = std::find(v3.begin(), v3.end(), v2);
+ if (j != v3.end())
+ BOOST_CHECK(v2 == *j);
+
+ BOOST_CHECK(v2 == seq[1]);
+ BOOST_CHECK(v2 == v3[1]);
+ v1.pop_back();
+ v1.pop_back();
+ v1.push_front(v2);
+ v1.push_front(value_t(2L));
+ BOOST_CHECK(v2 == v1[1]);
+ BOOST_CHECK(seq == v1);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(seq.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testAddition)
+{
+ struct tm localtime;
+ strptime("10 February 2010 00:00:00", "%d %b %Y %H:%M:%S", &localtime);
+ time_t time_var = mktime(&localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_var));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(2UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16(amount_t("2"));
+
+ v14 += v15;
+ BOOST_CHECK_EQUAL(v14, value_t(string("commentcomment"), true));
+ v14 += v12;
+ BOOST_CHECK_EQUAL(v14, value_t(string("commentcomment$1.00"), true));
+
+ v3 += value_t(2L);
+ strptime("10 February 2010 00:00:02", "%d %b %Y %H:%M:%S", &localtime);
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::from_time_t(mktime(&localtime))));
+ v3 += value_t(amount_t("2"));
+ strptime("10 February 2010 00:00:04", "%d %b %Y %H:%M:%S", &localtime);
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::from_time_t(mktime(&localtime))));
+
+ v4 += value_t(2L);
+ BOOST_CHECK_EQUAL(v4, value_t(date_t(parse_date("2014/08/16"))));
+ v4 += value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v4, value_t(date_t(parse_date("2014/08/18"))));
+
+ v5 += value_t(2L);
+ BOOST_CHECK_EQUAL(v5, value_t(4L));
+ v5 += value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, value_t(amount_t("6")));
+ v5 += v8;
+
+ v16 += value_t(2L);
+ v16 += value_t(amount_t("2"));
+ v16 += v8;
+ BOOST_CHECK_EQUAL(v5, v16);
+
+ v8 += value_t("6");
+ BOOST_CHECK_EQUAL(v8, v16);
+
+ value_t v17(6L);
+ v17 += value_t(amount_t("4 GBP"));
+ BOOST_CHECK_EQUAL(v8, v17);
+
+ value_t v18(6L);
+ v18 += v9;
+ value_t v19(amount_t("6"));
+ v19 += v9;
+ BOOST_CHECK_EQUAL(v18, v19);
+
+ v9 += value_t(2L);
+ v9 += value_t(amount_t("4"));
+ v9 += v19;
+ v18 += v19;
+ BOOST_CHECK_EQUAL(v9, v18);
+
+ value_t v20(s1);
+ v11 += value_t(2L);
+ v11 += value_t("4 GBP");
+ BOOST_CHECK_THROW(v11 += v20,value_error);
+ BOOST_CHECK_THROW(v10 += v8, value_error);
+
+ v20 += value_t(2L);
+ v20 += value_t("4 GBP");
+ BOOST_CHECK_EQUAL(v11, v20);
+ v11 += v20;
+ v20 += v20;
+ BOOST_CHECK_EQUAL(v11, v20);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v16.valid());
+ BOOST_CHECK(v17.valid());
+ BOOST_CHECK(v18.valid());
+ BOOST_CHECK(v19.valid());
+ BOOST_CHECK(v20.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testSubtraction)
+{
+ struct tm localtime;
+ strptime("10 February 2010 00:00:04", "%d %b %Y %H:%M:%S", &localtime);
+ time_t time_var = mktime(&localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_var));
+ value_t v4(date_t(parse_date("2014/08/18")));
+ value_t v5(6L);
+ value_t v6(6UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16(amount_t("6"));
+
+ v3 -= value_t(2L);
+ strptime("10 February 2010 00:00:02", "%d %b %Y %H:%M:%S", &localtime);
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::from_time_t(mktime(&localtime))));
+ v3 -= value_t(amount_t("2"));
+ strptime("10 February 2010 00:00:00", "%d %b %Y %H:%M:%S", &localtime);
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::from_time_t(mktime(&localtime))));
+
+ v4 -= value_t(2L);
+ BOOST_CHECK_EQUAL(v4, value_t(date_t(parse_date("2014/08/16"))));
+ v4 -= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v4, value_t(date_t(parse_date("2014/08/14"))));
+
+ v5 -= value_t(2L);
+ BOOST_CHECK_EQUAL(v5, value_t(4L));
+ v5 -= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, value_t(amount_t("2")));
+ v5 -= v8;
+
+ v16 -= value_t(2L);
+ v16 -= value_t(amount_t("2"));
+ v16 -= v8;
+ BOOST_CHECK_EQUAL(v5, v16);
+
+ v8 -= value_t("2");
+ BOOST_CHECK_EQUAL(-v8, v16);
+
+ value_t v18(6L);
+ v18 -= v9;
+ value_t v19(amount_t("6"));
+ v19 -= v9;
+ BOOST_CHECK_EQUAL(v18, v19);
+
+ v9 -= value_t(-2L);
+ v9 -= value_t(amount_t("-10"));
+ v9 -= value_t(amount_t("12 GBP"));
+ v9 -= v19;
+ BOOST_CHECK_EQUAL(v9, v18);
+ v18 -=v19;
+ BOOST_CHECK_EQUAL(v18, value_t("0"));
+
+ value_t v20(s1);
+ value_t v21(2L);
+ value_t v22("4 GBP");
+ v11.push_back(v21);
+ v11.push_back(v22);
+ BOOST_CHECK_THROW(v11 -= v20,value_error);
+ BOOST_CHECK_THROW(v10 -= v8, value_error);
+
+ v20.push_back(v21);
+ v20.push_back(v22);
+ v11 -= v20;
+ value_t v23(s1);
+ v23.push_back(value_t(0L));
+ v23.push_back(value_t("0"));
+ BOOST_CHECK_EQUAL(v11, v23);
+ v20 -= v21;
+ v20 -= v22;
+ BOOST_CHECK_EQUAL(v20, value_t(s1));
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v16.valid());
+ BOOST_CHECK(v18.valid());
+ BOOST_CHECK(v19.valid());
+ BOOST_CHECK(v20.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testMultiplication)
+{
+ struct tm localtime;
+ strptime("10 February 2010 00:00:00", "%d %b %Y %H:%M:%S", &localtime);
+ time_t time_var = mktime(&localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_var));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(2UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16(amount_t("2"));
+
+ v14 *= value_t(2L);
+ BOOST_CHECK_EQUAL(v14, value_t(string("commentcomment"), true));
+
+ v5 *= value_t(2L);
+ BOOST_CHECK_EQUAL(v5, value_t(4L));
+ v5 *= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, value_t(amount_t("8")));
+
+ v16 *= value_t(2L);
+ v16 *= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, v16);
+
+ v8 *= v9;
+ BOOST_CHECK_EQUAL(v8, value_t("16 GBP"));
+
+ value_t v17(v9);
+ v9 *= value_t(2L);
+ BOOST_CHECK_EQUAL(v9, value_t("8 GBP"));
+ v17 += value_t(2L);
+ v17 *= value_t(2L);
+ value_t v18("8 GBP");
+ v18 += value_t(4L);
+ BOOST_CHECK_EQUAL(v17, v18);
+
+ value_t v20(s1);
+ v11.push_back(value_t(2L));
+ v11.push_back(value_t("2 GBP"));
+ v20.push_back(value_t(4L));
+ v20.push_back(value_t("4 GBP"));
+ v11 *= value_t(2L);
+ BOOST_CHECK_EQUAL(v11 ,v20);
+
+ BOOST_CHECK_THROW(v10 *= v8, value_error);
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v16.valid());
+ BOOST_CHECK(v17.valid());
+ BOOST_CHECK(v18.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testDivision)
+{
+ struct tm localtime;
+ strptime("10 February 2010 00:00:00", "%d %b %Y %H:%M:%S", &localtime);
+ time_t time_var = mktime(&localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_var));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(8L);
+ value_t v6(2UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16(amount_t("8"));
+
+ v5 /= value_t(2L);
+ BOOST_CHECK_EQUAL(v5, value_t(4L));
+ v5 /= value_t(amount_t("8"));
+ BOOST_CHECK_EQUAL(v5, value_t(amount_t("2")));
+
+ v16 /= value_t(2L);
+ v16 /= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, v16);
+
+ v8 /= v9;
+ v8 /= value_t(balance_t(2L));
+ BOOST_CHECK_EQUAL(v8, value_t("0.5 GBP"));
+
+ value_t v17(v9);
+ v9 /= value_t(2L);
+ BOOST_CHECK_EQUAL(v9, value_t("2 GBP"));
+ v17 /= value_t("2 GBP");
+ v17 /= value_t("2");
+ BOOST_CHECK_EQUAL(v17, value_t(balance_t("1 GBP")));
+
+ BOOST_CHECK_THROW(v10 /= v8, value_error);
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v16.valid());
+ BOOST_CHECK(v17.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testType)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_t(NULL)));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(4UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("3 EUR"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("tag"), true);
+
+ BOOST_CHECK(v1.is_null());
+ BOOST_CHECK(v2.is_boolean());
+ BOOST_CHECK(v3.is_datetime());
+ BOOST_CHECK(v4.is_date());
+ BOOST_CHECK(v5.is_long());
+ BOOST_CHECK(v6.is_amount());
+ BOOST_CHECK(v7.is_amount());
+ BOOST_CHECK(v8.is_amount());
+ BOOST_CHECK(v9.is_balance());
+ BOOST_CHECK(v10.is_mask());
+ BOOST_CHECK(v11.is_sequence());
+ BOOST_CHECK(v12.is_amount());
+ BOOST_CHECK(v13.is_amount());
+ BOOST_CHECK(v14.is_string());
+ BOOST_CHECK(v15.is_string());
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testForZero)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_t(NULL)));
+ value_t v4(date_t(0));
+ value_t v5(2L);
+ value_t v6(0UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("0"));
+ value_t v10(mask_t(""));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string(""), true);
+
+ BOOST_CHECK(v1.is_null());
+ BOOST_CHECK(v2.is_nonzero());
+ BOOST_CHECK(!v3.is_zero());
+ BOOST_CHECK(v4.is_nonzero());
+ BOOST_CHECK(v5.is_nonzero());
+ BOOST_CHECK(v6.is_realzero());
+ BOOST_CHECK(v7.is_nonzero());
+ BOOST_CHECK(v8.is_nonzero());
+ BOOST_CHECK(v9.is_zero());
+ BOOST_CHECK_THROW(v10.is_zero(), value_error);
+ BOOST_CHECK(v11.is_zero());
+ BOOST_CHECK(v12.is_nonzero());
+ BOOST_CHECK(v13.is_nonzero());
+ BOOST_CHECK(v14.is_nonzero());
+ BOOST_CHECK(v15.is_zero());
+
+ v11.push_back(v6);
+ BOOST_CHECK(v11.is_nonzero());
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testNegation)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_t(NULL)));
+ value_t v4(date_t(parse_date("2014/08/09")));
+ value_t v5(2L);
+ value_t v6(0UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t(""));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("$-1");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+
+ BOOST_CHECK_THROW(v1.negated(), value_error);
+ BOOST_CHECK_EQUAL(v2.negated(), value_t(false));
+ v5.in_place_negate();
+ BOOST_CHECK_EQUAL(v5, value_t(-2L));
+ v8.in_place_negate();
+ v9.in_place_negate();
+ BOOST_CHECK_EQUAL(v8, v9);
+ BOOST_CHECK_THROW(v10.negated(), value_error);
+ BOOST_CHECK_EQUAL(-v12, v13);
+ BOOST_CHECK_THROW(-v14, value_error);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+