summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-02-26 00:56:47 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-02-26 03:16:39 -0400
commitd58797e98c82ced16fbc0a213fd104fb72a9de08 (patch)
treececde49eece8edc80e334f74895e0861a56c0fdb
parent74e569e220bee08d6c9eda59b5e4021748344994 (diff)
downloadfork-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.am94
-rw-r--r--src/account.cc9
-rw-r--r--src/chain.cc5
-rw-r--r--src/filters.cc112
-rw-r--r--src/filters.h24
-rw-r--r--src/post.cc12
-rw-r--r--src/post.h2
-rw-r--r--src/report.h14
-rwxr-xr-xtest/ConfirmTests.py110
-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-xtest/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.cc3
-rwxr-xr-xtest/fullcheck.sh (renamed from tools/fullcheck)0
-rw-r--r--test/input/standard.dat (renamed from tools/standard.dat)0
-rwxr-xr-xtest/runtests.py (renamed from tools/runtests.py)0
-rwxr-xr-xtools/confirm.py60
-rwxr-xr-xtools/regtest22
-rw-r--r--tools/template.h248
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));
}
diff --git a/src/post.h b/src/post.h
index 0865137f..4c20fb37 100644
--- a/src/post.h
+++ b/src/post.h
@@ -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