diff options
author | John Wiegley <johnw@newartisans.com> | 2009-02-26 00:56:47 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-02-26 03:16:39 -0400 |
commit | d58797e98c82ced16fbc0a213fd104fb72a9de08 (patch) | |
tree | cecde49eece8edc80e334f74895e0861a56c0fdb | |
parent | 74e569e220bee08d6c9eda59b5e4021748344994 (diff) | |
download | fork-ledger-d58797e98c82ced16fbc0a213fd104fb72a9de08.tar.gz fork-ledger-d58797e98c82ced16fbc0a213fd104fb72a9de08.tar.bz2 fork-ledger-d58797e98c82ced16fbc0a213fd104fb72a9de08.zip |
The -B, -G, -V reports now show rounding amounts
This way, if the running total is off by a penny or two due to rounding
of one or more commodities in the account, the user will see it.
This commit also reorganizes the testing code a bit, which I did after
adding the ninth test series (ConfirmTests), to validate the new
rounding code.
-rw-r--r-- | Makefile.am | 94 | ||||
-rw-r--r-- | src/account.cc | 9 | ||||
-rw-r--r-- | src/chain.cc | 5 | ||||
-rw-r--r-- | src/filters.cc | 112 | ||||
-rw-r--r-- | src/filters.h | 24 | ||||
-rw-r--r-- | src/post.cc | 12 | ||||
-rw-r--r-- | src/post.h | 2 | ||||
-rw-r--r-- | src/report.h | 14 | ||||
-rwxr-xr-x | test/ConfirmTests.py | 110 | ||||
-rw-r--r-- | test/DataTests.cc (renamed from test/data_tests.cc) | 0 | ||||
-rw-r--r-- | test/ExprTests.cc (renamed from test/expr_tests.cc) | 0 | ||||
-rw-r--r-- | test/MathTests.cc (renamed from test/math_tests.cc) | 0 | ||||
-rwxr-xr-x | test/RegressTests.py (renamed from test/regress.py) | 2 | ||||
-rw-r--r-- | test/ReportTests.cc (renamed from test/report_tests.cc) | 0 | ||||
-rw-r--r-- | test/UtilTests.cc (renamed from test/util_tests.cc) | 0 | ||||
-rw-r--r-- | test/extra_tests.cc | 3 | ||||
-rwxr-xr-x | test/fullcheck.sh (renamed from tools/fullcheck) | 0 | ||||
-rw-r--r-- | test/input/standard.dat (renamed from tools/standard.dat) | 0 | ||||
-rwxr-xr-x | test/runtests.py (renamed from tools/runtests.py) | 0 | ||||
-rwxr-xr-x | tools/confirm.py | 60 | ||||
-rwxr-xr-x | tools/regtest | 22 | ||||
-rw-r--r-- | tools/template.h | 248 |
22 files changed, 294 insertions, 423 deletions
diff --git a/Makefile.am b/Makefile.am index 45181855..0d63b7e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -240,16 +240,16 @@ endif TESTS = if HAVE_PYTHON -TESTS += RegressionTests BaselineTests +TESTS += RegressTests BaselineTests ConfirmTests endif if HAVE_CPPUNIT TESTS += \ - util_tests \ - math_tests \ - expr_tests \ - data_tests \ - report_tests + UtilTests \ + MathTests \ + ExprTests \ + DataTests \ + ReportTests endif if HAVE_BOOST_PYTHON @@ -258,22 +258,22 @@ endif check_PROGRAMS = $(TESTS) -util_tests_SOURCES = \ +UtilTests_SOURCES = \ test/UnitTests.cc \ test/UnitTests.h \ - test/util_tests.cc \ + test/UtilTests.cc \ test/unit/t_utils.cc \ test/unit/t_utils.h \ test/unit/t_times.cc \ test/unit/t_times.h -util_tests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) -util_tests_LDADD = libledger_util.la -lcppunit +UtilTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) +UtilTests_LDADD = libledger_util.la -lcppunit -math_tests_SOURCES = \ +MathTests_SOURCES = \ test/UnitTests.cc \ test/UnitTests.h \ - test/math_tests.cc \ + test/MathTests.cc \ test/unit/t_commodity.cc \ test/unit/t_commodity.h \ test/unit/t_amount.cc \ @@ -281,41 +281,41 @@ math_tests_SOURCES = \ test/unit/t_balance.cc \ test/unit/t_balance.h -math_tests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) -math_tests_LDADD = libledger_math.la $(util_tests_LDADD) +MathTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) +MathTests_LDADD = libledger_math.la $(UtilTests_LDADD) -expr_tests_SOURCES = \ +ExprTests_SOURCES = \ test/UnitTests.cc \ test/UnitTests.h \ - test/expr_tests.cc \ + test/ExprTests.cc \ test/unit/t_expr.cc \ test/unit/t_expr.h -expr_tests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) -expr_tests_LDADD = libledger_expr.la $(math_tests_LDADD) +ExprTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) +ExprTests_LDADD = libledger_expr.la $(MathTests_LDADD) -data_tests_SOURCES = \ +DataTests_SOURCES = \ test/UnitTests.cc \ test/UnitTests.h \ - test/data_tests.cc + test/DataTests.cc -data_tests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) -data_tests_LDADD = libledger_data.la $(expr_tests_LDADD) +DataTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) +DataTests_LDADD = libledger_data.la $(ExprTests_LDADD) -report_tests_SOURCES = \ +ReportTests_SOURCES = \ test/UnitTests.cc \ test/UnitTests.h \ - test/report_tests.cc + test/ReportTests.cc -report_tests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) -report_tests_LDADD = libledger_report.la $(data_tests_LDADD) +ReportTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags) +ReportTests_LDADD = libledger_report.la $(DataTests_LDADD) all_tests_sources = \ - $(util_tests_SOURCES) \ - $(math_tests_SOURCES) \ - $(expr_tests_SOURCES) \ - $(data_tests_SOURCES) \ - $(report_tests_SOURCES) + $(UtilTests_SOURCES) \ + $(MathTests_SOURCES) \ + $(ExprTests_SOURCES) \ + $(DataTests_SOURCES) \ + $(ReportTests_SOURCES) PyUnitTests_SOURCES = test/PyUnitTests.py @@ -358,31 +358,39 @@ PyUnitTests: $(srcdir)/test/PyUnitTests.py \ | sed "s/%builddir%/$(ESC_builddir)/g" > $@ chmod 755 $@ -RegressionTests_SOURCES = test/regress.py +RegressTests_SOURCES = test/RegressTests.py EXTRA_DIST += test/regress test/convert.py -RegressionTests: $(srcdir)/test/regress.py - echo "$(PYTHON) $(srcdir)/test/regress.py $(top_builddir)/ledger$(EXEEXT) $(srcdir)/test/regress" > $@ +RegressTests: $(srcdir)/test/RegressTests.py + echo "$(PYTHON) $(srcdir)/test/RegressTests.py $(top_builddir)/ledger$(EXEEXT) $(srcdir)/test/regress" > $@ chmod 755 $@ -BaselineTests_SOURCES = test/regress.py +BaselineTests_SOURCES = test/RegressTests.py EXTRA_DIST += test/baseline -BaselineTests: $(srcdir)/test/regress.py - echo "$(PYTHON) $(srcdir)/test/regress.py $(top_builddir)/ledger$(EXEEXT) $(srcdir)/test/baseline" > $@ +BaselineTests: $(srcdir)/test/RegressTests.py + echo "$(PYTHON) $(srcdir)/test/RegressTests.py $(top_builddir)/ledger$(EXEEXT) $(srcdir)/test/baseline" > $@ chmod 755 $@ -FULLCHECK=$(srcdir)/tools/fullcheck +ConfirmTests_SOURCES = test/ConfirmTests.py + +EXTRA_DIST += test/input + +ConfirmTests: $(srcdir)/test/ConfirmTests.py + echo "$(PYTHON) $(srcdir)/test/ConfirmTests.py $(top_builddir)/ledger$(EXEEXT) $(srcdir)/test/input" > $@ + chmod 755 $@ + +FULLCHECK=$(srcdir)/test/fullcheck.sh if HAVE_CPPUNIT fullcheck: $(TESTS) - sh $(FULLCHECK) $(top_builddir)/util_tests$(EXEEXT) --verify - sh $(FULLCHECK) $(top_builddir)/math_tests$(EXEEXT) --verify - sh $(FULLCHECK) $(top_builddir)/expr_tests$(EXEEXT) --verify - sh $(FULLCHECK) $(top_builddir)/data_tests$(EXEEXT) --verify - sh $(FULLCHECK) $(top_builddir)/report_tests$(EXEEXT) --verify + sh $(FULLCHECK) $(top_builddir)/UtilTests$(EXEEXT) --verify + sh $(FULLCHECK) $(top_builddir)/MathTests$(EXEEXT) --verify + sh $(FULLCHECK) $(top_builddir)/ExprTests$(EXEEXT) --verify + sh $(FULLCHECK) $(top_builddir)/DataTests$(EXEEXT) --verify + sh $(FULLCHECK) $(top_builddir)/ReportTests$(EXEEXT) --verify else fullcheck: check @test 1 -eq 1 diff --git a/src/account.cc b/src/account.cc index d65b6911..9bc96564 100644 --- a/src/account.cc +++ b/src/account.cc @@ -196,6 +196,10 @@ namespace { return long(account.depth); } + value_t ignore(account_t&) { + return false; + } + value_t get_depth_spacer(account_t& account) { std::size_t depth = 0; @@ -259,6 +263,11 @@ expr_t::ptr_op_t account_t::lookup(const string& name) if (name == "total") return WRAP_FUNCTOR(get_wrapper<&get_total>); break; + + case 'u': + if (name == "use_direct_amount") + return WRAP_FUNCTOR(get_wrapper<&ignore>); + break; } return NULL; diff --git a/src/chain.cc b/src/chain.cc index 0ad1709f..d33742a5 100644 --- a/src/chain.cc +++ b/src/chain.cc @@ -79,9 +79,12 @@ post_handler_ptr chain_post_handlers(report_t& report, // the running total unpredictably. if (report.HANDLED(revalued)) handler.reset(new changed_value_posts - (handler, report.HANDLED(revalued_total_) ? + (handler, + report.HANDLER(display_amount_).expr, + report.HANDLED(revalued_total_) ? report.HANDLER(revalued_total_).expr : report.HANDLER(display_total_).expr, + report.HANDLER(display_total_).expr, report, report.HANDLED(revalued_only))); // calc_posts computes the running total. When this appears will diff --git a/src/filters.cc b/src/filters.cc index 7f305dd3..3071a951 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -213,14 +213,17 @@ void calc_posts::operator()(post_t& post) } namespace { - void handle_value(const value_t& value, - account_t * account, - xact_t * xact, - unsigned int flags, - std::list<post_t>& temps, - item_handler<post_t>& handler, - const date_t& date = date_t(), - const value_t& total = value_t()) + typedef function<void (post_t *)> post_functor_t; + + void handle_value(const value_t& value, + account_t * account, + xact_t * xact, + std::list<post_t>& temps, + item_handler<post_t>& handler, + const date_t& date = date_t(), + const value_t& total = value_t(), + const bool direct_amount = false, + const optional<post_functor_t>& functor = none) { temps.push_back(post_t(account)); post_t& post(temps.back()); @@ -259,7 +262,7 @@ namespace { case value_t::BALANCE: case value_t::SEQUENCE: xdata.value = temp; - flags |= POST_EXT_COMPOUND; + xdata.add_flags(POST_EXT_COMPOUND); break; case value_t::DATETIME: @@ -272,8 +275,13 @@ namespace { if (! total.is_null()) xdata.total = total; - if (flags) - xdata.add_flags(flags); + if (direct_amount) + xdata.add_flags(POST_EXT_DIRECT_AMT); + + if (functor) + (*functor)(&post); + + DEBUG("filter.changed_value.rounding", "post.amount = " << post.amount); handler(post); } @@ -314,7 +322,7 @@ void collapse_posts::report_subtotal() earliest_date : last_xact->_date); DEBUG("filter.collapse", "Pseudo-xact date = " << *xact._date); - handle_value(subtotal, &totals_account, &xact, 0, post_temps, *handler); + handle_value(subtotal, &totals_account, &xact, post_temps, *handler); } component_posts.clear(); @@ -374,7 +382,7 @@ void related_posts::flush() item_handler<post_t>::flush(); } -void changed_value_posts::output_diff(post_t * post, const date_t& date) +void changed_value_posts::output_revaluation(post_t * post, const date_t& date) { if (is_valid(date)) post->xdata().date = date; @@ -391,36 +399,80 @@ void changed_value_posts::output_diff(post_t * post, const date_t& date) post->xdata().date = date_t(); DEBUG("filter.changed_value", - "output_diff(last_balance) = " << last_balance); + "output_revaluation(last_balance) = " << last_total); DEBUG("filter.changed_value", - "output_diff(repriced_total) = " << repriced_total); + "output_revaluation(repriced_total) = " << repriced_total); + + if (! last_total.is_null()) { + if (value_t diff = repriced_total - last_total) { + DEBUG("filter.changed_value", "output_revaluation(strip(diff)) = " + << diff.strip_annotations(report.what_to_keep())); + + xact_temps.push_back(xact_t()); + xact_t& xact = xact_temps.back(); + xact.payee = _("Commodities revalued"); + xact._date = is_valid(date) ? date : post->date(); + + handle_value(diff, &revalued_account, &xact, post_temps, *handler, + *xact._date, repriced_total, false, + optional<post_functor_t> + (bind(&changed_value_posts::output_rounding, this, _1))); + } + } +} - if (value_t diff = repriced_total - last_balance) { - DEBUG("filter.changed_value", "output_diff(strip(diff)) = " - << diff.strip_annotations(report.what_to_keep())); +void changed_value_posts::output_rounding(post_t * post) +{ + bind_scope_t bound_scope(report, *post); + value_t new_display_total(display_total_expr.calc(bound_scope)); - xact_temps.push_back(xact_t()); - xact_t& xact = xact_temps.back(); - xact.payee = _("Commodities revalued"); - xact._date = is_valid(date) ? date : post->date(); + DEBUG("filter.changed_value.rounding", + "rounding.new_display_total = " << new_display_total); + + if (! last_display_total.is_null()) { + if (value_t repriced_amount = display_amount_expr.calc(bound_scope)) { + DEBUG("filter.changed_value.rounding", + "rounding.repriced_amount = " << repriced_amount); - handle_value(diff, &revalued_account, &xact, POST_EXT_NO_TOTAL, - post_temps, *handler, *xact._date, repriced_total); + value_t precise_display_total(new_display_total.truncated() - + repriced_amount.truncated()); + + DEBUG("filter.changed_value.rounding", + "rounding.precise_display_total = " << precise_display_total); + DEBUG("filter.changed_value.rounding", + "rounding.last_display_total = " << last_display_total); + + if (value_t diff = precise_display_total - last_display_total) { + DEBUG("filter.changed_value.rounding", + "rounding.diff = " << diff); + + xact_temps.push_back(xact_t()); + xact_t& xact = xact_temps.back(); + xact.payee = _("Commodity rounding"); + xact._date = post->date(); + + handle_value(diff, &rounding_account, &xact, post_temps, + *handler, *xact._date, precise_display_total, true); + } + } } + last_display_total = new_display_total; } void changed_value_posts::operator()(post_t& post) { if (last_post) - output_diff(last_post, post.date()); + output_revaluation(last_post, post.date()); if (changed_values_only) post.xdata().add_flags(POST_EXT_DISPLAYED); + output_rounding(&post); + item_handler<post_t>::operator()(post); bind_scope_t bound_scope(report, post); - last_balance = total_expr.calc(bound_scope); + last_total = total_expr.calc(bound_scope); last_post = &post; } @@ -462,8 +514,8 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, xact._date = range_start; foreach (values_map::value_type& pair, values) - handle_value(pair.second.value, pair.second.account, &xact, 0, - post_temps, *handler); + handle_value(pair.second.value, pair.second.account, &xact, post_temps, + *handler); values.clear(); } @@ -581,8 +633,8 @@ void posts_as_equity::report_subtotal() value_t total = 0L; foreach (values_map::value_type& pair, values) { - handle_value(pair.second.value, pair.second.account, &xact, 0, - post_temps, *handler); + handle_value(pair.second.value, pair.second.account, &xact, post_temps, + *handler); total += pair.second.value; } values.clear(); diff --git a/src/filters.h b/src/filters.h index 8bc121ba..9ac2a6b9 100644 --- a/src/filters.h +++ b/src/filters.h @@ -449,12 +449,16 @@ class changed_value_posts : public item_handler<post_t> // This filter requires that calc_posts be used at some point // later in the chain. + expr_t display_amount_expr; expr_t total_expr; + expr_t display_total_expr; report_t& report; bool changed_values_only; post_t * last_post; - value_t last_balance; + value_t last_total; + value_t last_display_total; account_t revalued_account; + account_t rounding_account; std::list<xact_t> xact_temps; std::list<post_t> post_temps; @@ -463,14 +467,19 @@ class changed_value_posts : public item_handler<post_t> public: changed_value_posts(post_handler_ptr handler, + const expr_t& _display_amount_expr, const expr_t& _total_expr, + const expr_t& _display_total_expr, report_t& _report, bool _changed_values_only) - : item_handler<post_t>(handler), total_expr(_total_expr), - report(_report), changed_values_only(_changed_values_only), - last_post(NULL), revalued_account(NULL, _("<Revalued>")) { + : item_handler<post_t>(handler), + display_amount_expr(_display_amount_expr), total_expr(_total_expr), + display_total_expr(_display_total_expr), report(_report), + changed_values_only(_changed_values_only), last_post(NULL), + revalued_account(NULL, _("<Revalued>")), + rounding_account(NULL, _("<Rounding>")){ TRACE_CTOR(changed_value_posts, - "post_handler_ptr, const expr_t&, report_t&, bool"); + "post_handler_ptr, const expr_t&, const expr_t&, report_t&, bool"); } virtual ~changed_value_posts() { TRACE_DTOR(changed_value_posts); @@ -479,13 +488,14 @@ public: virtual void flush() { if (last_post && last_post->date() <= CURRENT_DATE()) { - output_diff(last_post, CURRENT_DATE()); + output_revaluation(last_post, CURRENT_DATE()); last_post = NULL; } item_handler<post_t>::flush(); } - void output_diff(post_t * post, const date_t& current); + void output_revaluation(post_t * post, const date_t& current); + void output_rounding(post_t * post); virtual void operator()(post_t& post); }; diff --git a/src/post.cc b/src/post.cc index b10ab81a..8293bfe4 100644 --- a/src/post.cc +++ b/src/post.cc @@ -158,6 +158,10 @@ namespace { } } + value_t get_use_direct_amount(post_t& post) { + return post.has_xdata() && post.xdata().has_flags(POST_EXT_DIRECT_AMT); + } + value_t get_commodity(post_t& post) { return string_value(post.amount.commodity().symbol()); } @@ -282,6 +286,11 @@ expr_t::ptr_op_t post_t::lookup(const string& name) return WRAP_FUNCTOR(get_wrapper<&get_total>); break; + case 'u': + if (name == "use_direct_amount") + return WRAP_FUNCTOR(get_wrapper<&get_use_direct_amount>); + break; + case 'v': if (name == "virtual") return WRAP_FUNCTOR(get_wrapper<&get_virtual>); @@ -333,8 +342,7 @@ void post_t::add_to_value(value_t& value, expr_t& expr) { if (xdata_ && xdata_->has_flags(POST_EXT_COMPOUND)) { add_or_set_value(value, xdata_->value); - } - else if (! xdata_ || ! xdata_->has_flags(POST_EXT_NO_TOTAL)) { + } else { bind_scope_t bound_scope(*expr.get_context(), *this); add_or_set_value(value, expr.calc(bound_scope)); } @@ -134,7 +134,7 @@ public: #define POST_EXT_HANDLED 0x02 #define POST_EXT_TO_DISPLAY 0x04 #define POST_EXT_DISPLAYED 0x08 -#define POST_EXT_NO_TOTAL 0x10 +#define POST_EXT_DIRECT_AMT 0x10 #define POST_EXT_SORT_CALC 0x20 #define POST_EXT_COMPOUND 0x40 #define POST_EXT_MATCHES 0x80 diff --git a/src/report.h b/src/report.h index 6839de0e..1d867c68 100644 --- a/src/report.h +++ b/src/report.h @@ -245,7 +245,7 @@ public: OPTION(report_t, base); OPTION_(report_t, basis, DO() { // -B - parent->HANDLER(revalued).off(); + parent->HANDLER(revalued).on_only(); parent->HANDLER(amount_).set_expr("rounded(cost)"); }); @@ -401,15 +401,17 @@ public: // Since we are displaying the amounts of revalued postings, they // will end up being composite totals, and hence a pair of pairs. parent->HANDLER(display_amount_) - .set_expr("is_seq(get_at(amount_expr, 0)) ?" - " get_at(get_at(amount_expr, 0), 0) :" - " market(get_at(amount_expr, 0), date, exchange) -" - " get_at(amount_expr, 1)"); + .set_expr("use_direct_amount ? amount :" + " (is_seq(get_at(amount_expr, 0)) ?" + " get_at(get_at(amount_expr, 0), 0) :" + " market(get_at(amount_expr, 0), date, exchange)" + " - get_at(amount_expr, 1))"); parent->HANDLER(revalued_total_) .set_expr("(market(get_at(total_expr, 0), date, exchange), " "get_at(total_expr, 1))"); parent->HANDLER(display_total_) - .set_expr("market(get_at(total_expr, 0), date, exchange)" + .set_expr("use_direct_amount ? total_expr :" + " market(get_at(total_expr, 0), date, exchange)" " - get_at(total_expr, 1)"); }); diff --git a/test/ConfirmTests.py b/test/ConfirmTests.py new file mode 100755 index 00000000..50791e43 --- /dev/null +++ b/test/ConfirmTests.py @@ -0,0 +1,110 @@ +#!/usr/bin/python + +# This script confirms both that the register report "adds up", and that its +# final balance is the same as what the balance report shows. + +import sys +import os +import re + +from subprocess import Popen, PIPE + +commands = [ + "-f '$tests/standard.dat' -O 0ecbb1b15e2cf3e515cc0f8533e5bb0fb2326728", + "-f '$tests/standard.dat' -B c56a21d23a6535184e7152ee138c28974f14280c", + "-f '$tests/standard.dat' -V c56a21d23a6535184e7152ee138c28974f14280c", + "-f '$tests/standard.dat' -G c56a21d23a6535184e7152ee138c28974f14280c", + "-f '$tests/standard.dat' -B c0226fafdf9e6711ac9121cf263e2d50791859cb", + "-f '$tests/standard.dat' -V c0226fafdf9e6711ac9121cf263e2d50791859cb", + "-f '$tests/standard.dat' -G c0226fafdf9e6711ac9121cf263e2d50791859cb" +] + +ledger = sys.argv[1] +tests = sys.argv[2] +succeeded = 0 +failed = 0 + +if not os.path.isfile(ledger): + sys.exit(1) +if not os.path.isdir(tests) and not os.path.isfile(tests): + sys.exit(1) + +def clean(num): + num = re.sub("(\s+|\$|,)","", num) + m = re.search("([-0-9.]+)", num) + if m: + return float(m.group(1)) + else: + return float(num) + +def confirm_report(args): + index = 1 + last_line = "" + failure = False + running_total = 0.0 + + p = Popen(re.sub('\$cmd', 'reg', args), shell=True, + stdin=PIPE, stdout=PIPE, stderr=PIPE, + close_fds=True) + + for line in p.stdout.readlines(): + match = re.match("\\s*([-$,0-9.]+)\\s+([-$,0-9.]+)", line[54:]) + if not match: + continue + value = clean(match.group(1)) + total = clean(match.group(2)) + + running_total += value + diff = abs(running_total - total) + if re.search(' -[VGB] ', args) and diff < 0.015: + diff = 0.0 + if diff > 0.001: + print "DISCREPANCY: %.3f (%.3f - %.3f) at line %d:" % \ + (running_total - total, running_total, total, index) + print line, + running_total = total + failure = True + + index += 1 + last_line = line + + balance_total = 0.0 + + p = Popen(re.sub('\$cmd', 'bal', args), shell=True, + stdin=PIPE, stdout=PIPE, stderr=PIPE, + close_fds=True) + + for line in p.stdout.readlines(): + if line[0] != '-': + balance_total = clean(line[:20]) + + diff = abs(balance_total - running_total) + if re.search(' -[VGB] ', args) and diff < 0.015: + diff = 0.0 + if diff > 0.001: + print + print "DISCREPANCY: %.3f (%.3f - %.3f) between register and balance" % \ + (balance_total - running_total, balance_total, running_total) + print last_line, + failure = True + + return not failure + +for cmd in commands: + if confirm_report("%s --args-only --columns=80 %s" % + (ledger, re.sub('\$tests', tests, cmd))): + print ".", + succeeded += 1 + else: + print "E", + failed += 1 + +print +if succeeded > 0: + print "OK (%d) " % succeeded, +if failed > 0: + print "FAILED (%d)" % failed, +print + +sys.exit(failed) + diff --git a/test/data_tests.cc b/test/DataTests.cc index 8fa1db8a..8fa1db8a 100644 --- a/test/data_tests.cc +++ b/test/DataTests.cc diff --git a/test/expr_tests.cc b/test/ExprTests.cc index d3f0a734..d3f0a734 100644 --- a/test/expr_tests.cc +++ b/test/ExprTests.cc diff --git a/test/math_tests.cc b/test/MathTests.cc index c1e8c839..c1e8c839 100644 --- a/test/math_tests.cc +++ b/test/MathTests.cc diff --git a/test/regress.py b/test/RegressTests.py index 33140e6c..088a4263 100755 --- a/test/regress.py +++ b/test/RegressTests.py @@ -125,6 +125,8 @@ def test_regression(test_file): if success: succeeded += 1 print ".", + else: + print "E", if not use_stdin: os.remove(tempdata[1]) diff --git a/test/report_tests.cc b/test/ReportTests.cc index 2fabbe9a..2fabbe9a 100644 --- a/test/report_tests.cc +++ b/test/ReportTests.cc diff --git a/test/util_tests.cc b/test/UtilTests.cc index f584db89..f584db89 100644 --- a/test/util_tests.cc +++ b/test/UtilTests.cc diff --git a/test/extra_tests.cc b/test/extra_tests.cc deleted file mode 100644 index 4d8d6a9e..00000000 --- a/test/extra_tests.cc +++ /dev/null @@ -1,3 +0,0 @@ -#include <cppunit/extensions/HelperMacros.h> - -CPPUNIT_REGISTRY_ADD_TO_DEFAULT("extra"); diff --git a/tools/fullcheck b/test/fullcheck.sh index 5763278c..5763278c 100755 --- a/tools/fullcheck +++ b/test/fullcheck.sh diff --git a/tools/standard.dat b/test/input/standard.dat index 62fa7f86..62fa7f86 100644 --- a/tools/standard.dat +++ b/test/input/standard.dat diff --git a/tools/runtests.py b/test/runtests.py index 9afbd25d..9afbd25d 100755 --- a/tools/runtests.py +++ b/test/runtests.py diff --git a/tools/confirm.py b/tools/confirm.py deleted file mode 100755 index 94e066a4..00000000 --- a/tools/confirm.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/python - -# This script confirms what ledger tells you. - -import sys -import os -import re - -def clean(num): - num = re.sub("(\s+|\$|,)","", num) - m = re.search("([-0-9.]+)", num) - if m: - return float(m.group(1)) - else: - return float(num) - -running_total = 0.0 -index = 1 -last_line = "" -errors = 0 - -args = sys.argv[1] -for line in os.popen(re.sub('\$cmd', 'reg', args)): - match = re.match("\\s*([-$,0-9.]+)\\s+([-$,0-9.]+)", line[54:]) - if not match: - continue - value = clean(match.group(1)) - total = clean(match.group(2)) - - running_total += value - diff = abs(running_total - total) - if re.search(' -[VGB] ', args) and diff < 0.015: - diff = 0.0 - if diff > 0.001: - print "DISCREPANCY: %.3f (%.3f - %.3f) at line %d:" % \ - (running_total - total, running_total, total, index) - print line, - running_total = total - errors += 1 - - index += 1 - last_line = line - -balance_total = 0.0 - -for line in os.popen(re.sub('\$cmd', 'bal', args)): - if line[0] != '-': - balance_total = clean(line[:20]) - -diff = abs(balance_total - running_total) -if re.search(' -[VGB] ', args) and diff < 0.015: - diff = 0.0 -if diff > 0.001: - print - print "DISCREPANCY: %.3f (%.3f - %.3f) between register and balance" % \ - (balance_total - running_total, balance_total, running_total) - print last_line, - errors += 1 - -sys.exit(errors) diff --git a/tools/regtest b/tools/regtest deleted file mode 100755 index b42b4981..00000000 --- a/tools/regtest +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -errors=0 - -for test in \ - "-O \$cmd 0ecbb1b15e2cf3e515cc0f8533e5bb0fb2326728" \ - "-B \$cmd c56a21d23a6535184e7152ee138c28974f14280c" \ - "-V \$cmd c56a21d23a6535184e7152ee138c28974f14280c" \ - "-G \$cmd c56a21d23a6535184e7152ee138c28974f14280c" \ - "-B \$cmd c0226fafdf9e6711ac9121cf263e2d50791859cb" \ - "-V \$cmd c0226fafdf9e6711ac9121cf263e2d50791859cb" \ - "-G \$cmd c0226fafdf9e6711ac9121cf263e2d50791859cb" -do - echo testing: $test - python tools/confirm.py "ledger -f tools/standard.dat --args-only --columns=80 $test" - errors=`expr $errors + $?` -done - -if [ $errors = 0 ]; then - echo All tests completed successfully. -fi -exit $errors diff --git a/tools/template.h b/tools/template.h deleted file mode 100644 index ce55cf02..00000000 --- a/tools/template.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2003-2009, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @defgroup the_group Group Title - * @addtogroup the_group - */ - -/** - * @file template.h - * @author John Wiegley - * - * @ingroup the_group - * - * @brief Brief description - * - * Full description. - */ -#ifndef _TEMPLATE_H -#define _TEMPLATE_H - -namespace template { - -/** - * @brief Brief description - * - * Full description. - */ -class template_t : public ordered_field_operators<template_t> -#if 0 - public boost::noncopyable -#endif -{ -public: - /** - * @name Class statics - */ - /*@{*/ - - static bool stream_fullstrings; - - /*@}*/ - - /** - * @name Constructors - */ - /*@{*/ - - /** - * @see other_function - * @warning Watch out! - */ - template_t() { - TRACE_CTOR(template_t, ""); - } - - /*@}*/ - - /** - * @name Destructor - */ - /*@{*/ - - ~template_t() { - TRACE_DTOR(template_t); - } - - /*@}*/ - - /** - * @name Assignment and copy - */ - /*@{*/ - - template_t(const template_t& other) { - TRACE_CTOR(template_t, "copy"); - } - - template_t& operator=(const template_t& other); - - /*@}*/ - -private: - template_t(const template_t& other); - -public: - /** - * @name Comparison - */ - /*@{*/ - - /** - * Compare two template objects. - * @param other - * @return An integer <0, 0 or >0. - */ - int compare(const template_t& other) const; - - template <typename T> - bool operator==(const T& val) const { - return compare(val) == 0; - } - template <typename T> - bool operator<(const T& other) const { - return compare(other) < 0; - } - template <typename T> - bool operator>(const T& other) const { - return compare(other) > 0; - } - - /*@}*/ - - /** - * @name Binary arithmetic - */ - /*@{*/ - - template_t& operator+=(const template_t& other); - template_t& operator-=(const template_t& other); - template_t& operator*=(const template_t& other); - template_t& operator/=(const template_t& other); - - /*@}*/ - - /** - * @name Unary arithmetic - */ - /*@{*/ - - template_t operator-() const { - return template_t(); - } - - /*@}*/ - - /** - * @name Truth tests - */ - /*@{*/ - - operator bool() const { - return false; - } - - /*@}*/ - - /** - * @name Conversion - */ - /*@{*/ - - operator int() const { - return 0; - } - - /*@}*/ - - /** - * @name Parsing - */ - /*@{*/ - - bool parse(std::istream& in); - bool parse(const string& str) { - std::istringstream stream(str); - bool result = parse(stream, flags); - assert(stream.eof()); - return result; - } - - /*@}*/ - - /** - * @name Printing - */ - /*@{*/ - - void print(std::ostream& out) const; - - /*@}*/ - - /** - * @name Serialization - */ - /*@{*/ - - void read(std::istream& in); - void read(const char *& data); - void write(std::ostream& out) const; - - /*@}*/ - - /** - * @name XML Serialization - */ - /*@{*/ - - void read_xml(std::istream& in); - void write_xml(std::ostream& out, const int depth = 0) const; - - /*@}*/ - - /** - * @name Debugging - */ - /*@{*/ - - void dump(std::ostream& out) const { - print(out); - } - - bool valid() const; - - /*@}*/ -}; - -} // namespace template - -#endif // _TEMPLATE_H |