summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2007-05-08 10:33:13 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 03:38:42 -0400
commit4e9056b6ce395531098a72d431b911f4ecbbbaab (patch)
treea4d49c084665b7e2026c6653151c34feeb1f8be9
parent0477dd119a3f06c81e7d71123e42441872182440 (diff)
downloadfork-ledger-4e9056b6ce395531098a72d431b911f4ecbbbaab.tar.gz
fork-ledger-4e9056b6ce395531098a72d431b911f4ecbbbaab.tar.bz2
fork-ledger-4e9056b6ce395531098a72d431b911f4ecbbbaab.zip
It is now an error to use an uninitialized amount for any operation
other than is_null and parse.
-rw-r--r--src/amount.cc173
-rw-r--r--src/amount.h5
-rw-r--r--tests/numerics/t_amount.cc84
-rw-r--r--tests/python/numerics/t_amount.py66
4 files changed, 152 insertions, 176 deletions
diff --git a/src/amount.cc b/src/amount.cc
index 274d3001..382ea36c 100644
--- a/src/amount.cc
+++ b/src/amount.cc
@@ -133,6 +133,8 @@ void amount_t::shutdown()
void amount_t::_init()
{
+ // This is only called on an initialized amount by amount_t::parse.
+
if (! quantity) {
quantity = new bigint_t;
}
@@ -140,6 +142,7 @@ void amount_t::_init()
_release();
quantity = new bigint_t;
}
+ commodity_ = NULL;
}
void amount_t::_copy(const amount_t& amt)
@@ -301,28 +304,25 @@ namespace {
}
}
-amount_t::amount_t(const double val)
+amount_t::amount_t(const double val) : commodity_(NULL)
{
TRACE_CTOR(amount_t, "const double");
quantity = new bigint_t;
quantity->prec = convert_double(MPZ(quantity), val);
- commodity_ = NULL;
}
-amount_t::amount_t(const unsigned long val)
+amount_t::amount_t(const unsigned long val) : commodity_(NULL)
{
TRACE_CTOR(amount_t, "const unsigned long");
quantity = new bigint_t;
mpz_set_ui(MPZ(quantity), val);
- commodity_ = NULL;
}
-amount_t::amount_t(const long val)
+amount_t::amount_t(const long val) : commodity_(NULL)
{
TRACE_CTOR(amount_t, "const long");
quantity = new bigint_t;
mpz_set_si(MPZ(quantity), val);
- commodity_ = NULL;
}
@@ -340,15 +340,17 @@ amount_t& amount_t::operator=(const amount_t& amt)
int amount_t::compare(const amount_t& amt) const
{
- if (! quantity) {
- if (! amt.quantity)
- return 0;
- return - amt.sign();
+ if (! quantity || ! amt.quantity) {
+ if (quantity)
+ throw_(amount_error, "Cannot compare an amount to an uninitialized amount");
+ else if (amt.quantity)
+ throw_(amount_error, "Cannot compare an uninitialized amount to an amount");
+ else
+ throw_(amount_error, "Cannot compare two uninitialized amounts");
}
- if (! amt.quantity)
- return sign();
-
- if (has_commodity() && amt.commodity() && commodity() != amt.commodity())
+
+ if (has_commodity() && amt.has_commodity() &&
+ commodity() != amt.commodity())
throw_(amount_error,
"Cannot compare amounts with different commodities: " <<
commodity().symbol() << " and " << amt.commodity().symbol());
@@ -371,6 +373,15 @@ int amount_t::compare(const amount_t& amt) const
amount_t& amount_t::operator+=(const amount_t& amt)
{
+ if (! quantity || ! amt.quantity) {
+ if (quantity)
+ throw_(amount_error, "Cannot add an amount to an uninitialized amount");
+ else if (amt.quantity)
+ throw_(amount_error, "Cannot add an uninitialized amount to an amount");
+ else
+ throw_(amount_error, "Cannot add two uninitialized amounts");
+ }
+
if (commodity() != amt.commodity())
throw_(amount_error,
"Adding amounts with different commodities: " <<
@@ -378,14 +389,6 @@ amount_t& amount_t::operator+=(const amount_t& amt)
" != " <<
(amt.has_commodity() ? amt.commodity().symbol() : "NONE"));
- if (! amt.quantity)
- return *this;
-
- if (! quantity) {
- _copy(amt);
- return *this;
- }
-
_dup();
if (quantity->prec == amt.quantity->prec) {
@@ -406,6 +409,15 @@ amount_t& amount_t::operator+=(const amount_t& amt)
amount_t& amount_t::operator-=(const amount_t& amt)
{
+ if (! quantity || ! amt.quantity) {
+ if (quantity)
+ throw_(amount_error, "Cannot subtract an amount from an uninitialized amount");
+ else if (amt.quantity)
+ throw_(amount_error, "Cannot subtract an uninitialized amount from an amount");
+ else
+ throw_(amount_error, "Cannot subtract two uninitialized amounts");
+ }
+
if (commodity() != amt.commodity())
throw_(amount_error,
"Subtracting amounts with different commodities: " <<
@@ -413,16 +425,6 @@ amount_t& amount_t::operator-=(const amount_t& amt)
" != " <<
(amt.has_commodity() ? amt.commodity().symbol() : "NONE"));
- if (! amt.quantity)
- return *this;
-
- if (! quantity) {
- quantity = new bigint_t(*amt.quantity);
- commodity_ = amt.commodity_;
- mpz_neg(MPZ(quantity), MPZ(quantity));
- return *this;
- }
-
_dup();
if (quantity->prec == amt.quantity->prec) {
@@ -491,6 +493,15 @@ namespace {
amount_t& amount_t::operator*=(const amount_t& amt)
{
+ if (! quantity || ! amt.quantity) {
+ if (quantity)
+ throw_(amount_error, "Cannot multiply an amount by an uninitialized amount");
+ else if (amt.quantity)
+ throw_(amount_error, "Cannot multiply an uninitialized amount by an amount");
+ else
+ throw_(amount_error, "Cannot multiply two uninitialized amounts");
+ }
+
if (has_commodity() && amt.has_commodity() &&
commodity() != amt.commodity())
throw_(amount_error,
@@ -499,16 +510,6 @@ amount_t& amount_t::operator*=(const amount_t& amt)
" != " <<
(amt.has_commodity() ? amt.commodity().symbol() : "NONE"));
- if (! amt.quantity) {
- *this = *this - *this; // preserve our commodity
- goto finish;
- }
- else if (! quantity) {
- *this = amt;
- *this = *this - *this; // preserve the foreign commodity
- goto finish;
- }
-
_dup();
mpz_mul(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
@@ -531,6 +532,15 @@ amount_t& amount_t::operator*=(const amount_t& amt)
amount_t& amount_t::operator/=(const amount_t& amt)
{
+ if (! quantity || ! amt.quantity) {
+ if (quantity)
+ throw_(amount_error, "Cannot divide an amount by an uninitialized amount");
+ else if (amt.quantity)
+ throw_(amount_error, "Cannot divide an uninitialized amount by an amount");
+ else
+ throw_(amount_error, "Cannot divide two uninitialized amounts");
+ }
+
if (has_commodity() && amt.has_commodity() &&
commodity() != amt.commodity())
throw_(amount_error,
@@ -539,14 +549,8 @@ amount_t& amount_t::operator/=(const amount_t& amt)
" != " <<
(amt.has_commodity() ? amt.commodity().symbol() : "NONE"));
- if (! amt.quantity || ! amt) {
+ if (! amt)
throw_(amount_error, "Divide by zero");
- }
- else if (! quantity) {
- *this = amt;
- *this = *this - *this; // preserve the foreign commodity
- goto finish;
- }
_dup();
@@ -584,6 +588,9 @@ amount_t& amount_t::operator/=(const amount_t& amt)
amount_t::precision_t amount_t::precision() const
{
+ if (! quantity)
+ throw_(amount_error, "Cannot determine precision of an uninitialized amount");
+
return quantity->prec;
}
@@ -592,6 +599,8 @@ amount_t& amount_t::in_place_negate()
if (quantity) {
_dup();
mpz_neg(MPZ(quantity), MPZ(quantity));
+ } else {
+ throw_(amount_error, "Cannot negate an uninitialized amount");
}
return *this;
}
@@ -600,7 +609,10 @@ amount_t amount_t::round(precision_t prec) const
{
amount_t t = *this;
- if (! quantity || quantity->prec <= prec) {
+ if (! quantity)
+ throw_(amount_error, "Cannot round an uninitialized amount");
+
+ if (quantity->prec <= prec) {
if (quantity && quantity->has_flags(BIGINT_KEEP_PREC)) {
t._dup();
t.quantity->drop_flags(BIGINT_KEEP_PREC);
@@ -620,15 +632,10 @@ amount_t amount_t::round(precision_t prec) const
amount_t amount_t::unround() const
{
- if (! quantity) {
- amount_t t(0L);
- assert(t.quantity);
- t.quantity->add_flags(BIGINT_KEEP_PREC);
- return t;
- }
- else if (quantity->has_flags(BIGINT_KEEP_PREC)) {
+ if (! quantity)
+ throw_(amount_error, "Cannot unround an uninitialized amount");
+ else if (quantity->has_flags(BIGINT_KEEP_PREC))
return *this;
- }
amount_t t = *this;
t._dup();
@@ -639,6 +646,9 @@ amount_t amount_t::unround() const
amount_t& amount_t::in_place_reduce()
{
+ if (! quantity)
+ throw_(amount_error, "Cannot reduce an uninitialized amount");
+
while (commodity_ && commodity().smaller()) {
*this *= commodity().smaller()->number();
commodity_ = commodity().smaller()->commodity_;
@@ -648,6 +658,9 @@ amount_t& amount_t::in_place_reduce()
amount_t& amount_t::in_place_unreduce()
{
+ if (! quantity)
+ throw_(amount_error, "Cannot unreduce an uninitialized amount");
+
while (commodity_ && commodity().larger()) {
*this /= commodity().larger()->number();
commodity_ = commodity().larger()->commodity_;
@@ -663,6 +676,8 @@ optional<amount_t> amount_t::value(const optional<moment_t>& moment) const
optional<amount_t> amt(commodity().value(moment));
if (amt)
return (*amt * number()).round();
+ } else {
+ throw_(amount_error, "Cannot determine value of an uninitialized amount");
}
return optional<amount_t>();
}
@@ -670,13 +685,16 @@ optional<amount_t> amount_t::value(const optional<moment_t>& moment) const
int amount_t::sign() const
{
- return quantity ? mpz_sgn(MPZ(quantity)) : 0;
+ if (! quantity)
+ throw_(amount_error, "Cannot determine sign of an uninitialized amount");
+
+ return mpz_sgn(MPZ(quantity));
}
bool amount_t::is_zero() const
{
if (! quantity)
- return true;
+ throw_(amount_error, "Cannot determine sign if an uninitialized amount is zero");
if (has_commodity()) {
if (quantity->prec <= commodity().precision())
@@ -691,7 +709,7 @@ bool amount_t::is_zero() const
double amount_t::to_double(bool no_check) const
{
if (! quantity)
- return 0.0;
+ throw_(amount_error, "Cannot convert an uninitialized amount to a double");
mpz_t remainder;
mpz_init(remainder);
@@ -722,7 +740,7 @@ double amount_t::to_double(bool no_check) const
long amount_t::to_long(bool no_check) const
{
if (! quantity)
- return 0;
+ throw_(amount_error, "Cannot convert an uninitialized amount to a long");
mpz_set(temp, MPZ(quantity));
mpz_ui_pow_ui(divisor, 10, quantity->prec);
@@ -754,6 +772,11 @@ void amount_t::annotate_commodity(const annotation_t& details)
commodity_t * this_base;
annotated_commodity_t * this_ann = NULL;
+ if (! quantity)
+ throw_(amount_error, "Cannot annotate the commodity of an uninitialized amount");
+ else if (! has_commodity())
+ throw_(amount_error, "Cannot annotate an amount with no commodity");
+
if (commodity().annotated) {
this_ann = &commodity().as_annotated();
this_base = &this_ann->referent();
@@ -780,6 +803,10 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
const bool _keep_date,
const bool _keep_tag) const
{
+ if (! quantity)
+ throw_(amount_error,
+ "Cannot strip commodity annotations from an uninitialized amount");
+
if (! commodity().annotated ||
(_keep_price && _keep_date && _keep_tag))
return *this;
@@ -817,12 +844,20 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
bool amount_t::commodity_annotated() const
{
+ if (! quantity)
+ throw_(amount_error,
+ "Cannot determine if an uninitialized amount's commodity is annotated");
+
assert(! commodity().annotated || commodity().as_annotated().details);
return commodity().annotated;
}
annotation_t amount_t::annotation_details() const
{
+ if (! quantity)
+ throw_(amount_error,
+ "Cannot return commodity annotation details of an uninitialized amount");
+
assert(! commodity().annotated || commodity().as_annotated().details);
if (commodity().annotated) {
@@ -1019,7 +1054,7 @@ void amount_t::parse(std::istream& in, flags_t flags)
if (quant.empty())
throw_(amount_error, "No quantity specified for amount");
- _init();
+ _init(); // this will reuse a current value
// Create the commodity if has not already been seen, and update the
// precision if something greater was used for the quantity.
@@ -1133,6 +1168,9 @@ void amount_t::parse_conversion(const string& larger_str,
void amount_t::print(std::ostream& _out, bool omit_commodity,
bool full_precision) const
{
+ if (! quantity)
+ throw_(amount_error, "Cannot write out an uninitialized amount");
+
amount_t base(*this);
if (! amount_t::keep_base)
base.in_place_unreduce();
@@ -1341,6 +1379,9 @@ void amount_t::read(char *& data)
void amount_t::write(std::ostream& out) const
{
+ if (! quantity)
+ throw_(amount_error, "Cannot serialize an uninitialized amount");
+
if (commodity_)
write_binary_long(out, commodity_->ident);
else
@@ -1435,11 +1476,7 @@ void amount_t::write_quantity(std::ostream& out) const
{
char byte;
- if (! quantity) {
- byte = 0;
- out.write(&byte, sizeof(byte));
- return;
- }
+ assert(quantity);
if (quantity->index == 0) {
quantity->index = ++bigints_index;
diff --git a/src/amount.h b/src/amount.h
index 5f8fa2ec..9ac6ec0a 100644
--- a/src/amount.h
+++ b/src/amount.h
@@ -403,7 +403,7 @@ public:
bool is_null() const {
if (! quantity) {
- assert(! has_commodity());
+ assert(! commodity_);
return true;
}
return false;
@@ -477,6 +477,8 @@ public:
bool has_commodity() const;
void set_commodity(commodity_t& comm) {
+ if (! quantity)
+ *this = 0L;
commodity_ = &comm;
}
void clear_commodity() {
@@ -486,6 +488,7 @@ public:
amount_t number() const {
if (! has_commodity())
return *this;
+
amount_t temp(*this);
temp.clear_commodity();
return temp;
diff --git a/tests/numerics/t_amount.cc b/tests/numerics/t_amount.cc
index a59ff2ea..002b70b0 100644
--- a/tests/numerics/t_amount.cc
+++ b/tests/numerics/t_amount.cc
@@ -34,10 +34,10 @@ void AmountTestCase::testConstructors()
amount_t x10(x6);
amount_t x11(x8);
- assertEqual(amount_t(0L), x0);
- assertEqual(amount_t(), x0);
- assertEqual(amount_t("0"), x0);
- assertEqual(amount_t("0.0"), x0);
+ assertThrow(amount_t(0L) == x0, amount_error);
+ assertThrow(amount_t() == x0, amount_error);
+ assertThrow(amount_t("0") == x0, amount_error);
+ assertThrow(amount_t("0.0") == x0, amount_error);
assertEqual(x2, x1);
assertEqual(x5, x1);
assertEqual(x7, x1);
@@ -108,7 +108,6 @@ void AmountTestCase::testCommodityConstructors()
void AmountTestCase::testAssignment()
{
- amount_t x0;
amount_t x1 = 123456L;
amount_t x2 = 123456UL;
amount_t x3 = 123.456;
@@ -119,7 +118,6 @@ void AmountTestCase::testAssignment()
amount_t x9 = x3;
amount_t x10 = amount_t(x6);
- assertEqual(amount_t(0L), x0);
assertEqual(x2, x1);
assertEqual(x5, x1);
assertEqual(x7, x1);
@@ -128,7 +126,6 @@ void AmountTestCase::testAssignment()
assertEqual(x10, x3);
assertEqual(x10, x9);
- x0 = amount_t();
x1 = 123456L;
x2 = 123456UL;
x3 = 123.456;
@@ -139,7 +136,6 @@ void AmountTestCase::testAssignment()
x9 = x3;
x10 = amount_t(x6);
- assertEqual(amount_t(0L), x0);
assertEqual(x2, x1);
assertEqual(x5, x1);
assertEqual(x7, x1);
@@ -148,7 +144,6 @@ void AmountTestCase::testAssignment()
assertEqual(x10, x3);
assertEqual(x10, x9);
- assertTrue(x0.valid());
assertTrue(x1.valid());
assertTrue(x2.valid());
assertTrue(x3.valid());
@@ -246,12 +241,12 @@ void AmountTestCase::testCommodityEquality()
amount_t x10 = "-123.45€";
assertTrue(x0.is_null());
- assertTrue(x0.is_zero());
- assertTrue(x0.is_realzero());
- assertTrue(x0.sign() == 0);
- assertTrue(x0.compare(x1) < 0);
- assertTrue(x0.compare(x2) > 0);
- assertTrue(x0.compare(x0) == 0);
+ assertThrow(x0.is_zero(), amount_error);
+ assertThrow(x0.is_realzero(), amount_error);
+ assertThrow(x0.sign() == 0, amount_error);
+ assertThrow(x0.compare(x1) < 0, amount_error);
+ assertThrow(x0.compare(x2) > 0, amount_error);
+ assertThrow(x0.compare(x0) == 0, amount_error);
assertTrue(x1 != x2);
assertTrue(x1 != x4);
@@ -286,12 +281,12 @@ void AmountTestCase::testComparisons()
amount_t x5("-123.45");
amount_t x6("123.45");
- assertTrue(x0 > x1);
- assertTrue(x0 < x2);
- assertTrue(x0 > x3);
- assertTrue(x0 < x4);
- assertTrue(x0 > x5);
- assertTrue(x0 < x6);
+ assertThrow(x0 > x1, amount_error);
+ assertThrow(x0 < x2, amount_error);
+ assertThrow(x0 > x3, amount_error);
+ assertThrow(x0 < x4, amount_error);
+ assertThrow(x0 > x5, amount_error);
+ assertThrow(x0 < x6, amount_error);
assertTrue(x1 > x3);
assertTrue(x3 <= x5);
@@ -317,7 +312,6 @@ void AmountTestCase::testComparisons()
void AmountTestCase::testCommodityComparisons()
{
- amount_t x0;
amount_t x1("$-123");
amount_t x2("$123.00");
amount_t x3(internalAmount("$-123.4544"));
@@ -325,13 +319,6 @@ void AmountTestCase::testCommodityComparisons()
amount_t x5("$-123.45");
amount_t x6("$123.45");
- assertTrue(x0 > x1);
- assertTrue(x0 < x2);
- assertTrue(x0 > x3);
- assertTrue(x0 < x4);
- assertTrue(x0 > x5);
- assertTrue(x0 < x6);
-
assertTrue(x1 > x3);
assertTrue(x3 <= x5);
assertTrue(x3 < x5);
@@ -340,7 +327,6 @@ void AmountTestCase::testCommodityComparisons()
assertTrue(x3 < x1);
assertTrue(x3 < x4);
- assertValid(x0);
assertValid(x1);
assertValid(x2);
assertValid(x3);
@@ -847,7 +833,6 @@ void AmountTestCase::testCommodityDivision()
void AmountTestCase::testNegation()
{
- amount_t x0;
amount_t x1(-123456L);
amount_t x3(-123.456);
amount_t x5("-123456");
@@ -856,7 +841,6 @@ void AmountTestCase::testNegation()
amount_t x8(string("-123.456"));
amount_t x9(- x3);
- assertEqual(amount_t(0L), x0);
assertEqual(x5, x1);
assertEqual(x7, x1);
assertEqual(x6, x3);
@@ -868,7 +852,6 @@ void AmountTestCase::testNegation()
assertEqual(x3, x10);
- assertTrue(x0.valid());
assertTrue(x1.valid());
assertTrue(x3.valid());
assertTrue(x5.valid());
@@ -940,7 +923,7 @@ void AmountTestCase::testAbs()
amount_t x1(-1234L);
amount_t x2(1234L);
- assertEqual(amount_t(), x0.abs());
+ assertThrow(x0.abs(), amount_error);
assertEqual(amount_t(1234L), x1.abs());
assertEqual(amount_t(1234L), x2.abs());
@@ -951,15 +934,12 @@ void AmountTestCase::testAbs()
void AmountTestCase::testCommodityAbs()
{
- amount_t x0;
amount_t x1("$-1234.56");
amount_t x2("$1234.56");
- assertEqual(amount_t(), x0.abs());
assertEqual(amount_t("$1234.56"), x1.abs());
assertEqual(amount_t("$1234.56"), x2.abs());
- assertValid(x0);
assertValid(x1);
assertValid(x2);
}
@@ -1010,7 +990,7 @@ void AmountTestCase::testFractionalRound()
assertEqual(amount_t("0.0000000000000000000000000000000000001"),
x5.round(37));
- assertEqual(amount_t(), x5.round(36));
+ assertEqual(amount_t(0L), x5.round(36));
assertTrue(x1.valid());
assertTrue(x2.valid());
@@ -1127,7 +1107,7 @@ void AmountTestCase::testSign()
amount_t x3("1");
amount_t x4("-1");
- assertEqual(x0.sign(), 0);
+ assertThrow(x0.sign(), amount_error);
assertTrue(x1.sign() > 0);
assertTrue(x2.sign() < 0);
assertTrue(x3.sign() > 0);
@@ -1142,19 +1122,16 @@ void AmountTestCase::testSign()
void AmountTestCase::testCommoditySign()
{
- amount_t x0;
amount_t x1(internalAmount("$0.0000000000000000000000000000000000001"));
amount_t x2(internalAmount("$-0.0000000000000000000000000000000000001"));
amount_t x3("$1");
amount_t x4("$-1");
- assertFalse(x0.sign());
assertTrue(x1.sign() != 0);
assertTrue(x2.sign() != 0);
assertTrue(x3.sign() > 0);
assertTrue(x4.sign() < 0);
- assertValid(x0);
assertValid(x1);
assertValid(x2);
assertValid(x3);
@@ -1167,10 +1144,7 @@ void AmountTestCase::testTruth()
amount_t x1("1234");
amount_t x2("1234.56");
- if (x0)
- assertTrue(false);
- else
- assertTrue(true);
+ assertThrow(x0 ? 1 : 0, amount_error);
assertTrue(x1);
assertTrue(x2);
@@ -1204,10 +1178,9 @@ void AmountTestCase::testForZero()
amount_t x0;
amount_t x1("0.000000000000000000001");
- assertFalse(x0);
assertTrue(x1);
- assertTrue(x0.is_zero());
- assertTrue(x0.is_realzero());
+ assertThrow(x0.is_zero(), amount_error);
+ assertThrow(x0.is_realzero(), amount_error);
assertFalse(x1.is_zero());
assertFalse(x1.is_realzero());
@@ -1271,9 +1244,7 @@ void AmountTestCase::testPrinting()
{
std::ostringstream bufstr;
- bufstr << x0;
-
- assertEqual(std::string("0"), bufstr.str());
+ assertThrow(bufstr << x0, amount_error);
}
{
@@ -1290,19 +1261,11 @@ void AmountTestCase::testPrinting()
void AmountTestCase::testCommodityPrinting()
{
- amount_t x0;
amount_t x1(internalAmount("$982340823.386238098235098235098235098"));
amount_t x2("$982340823.38");
{
std::ostringstream bufstr;
- bufstr << x0;
-
- assertEqual(std::string("0"), bufstr.str());
- }
-
- {
- std::ostringstream bufstr;
bufstr << x1;
assertEqual(std::string("$982340823.386238098235098235098235098"),
@@ -1324,7 +1287,6 @@ void AmountTestCase::testCommodityPrinting()
assertEqual(std::string("$964993493285024293.18"), bufstr.str());
}
- assertValid(x0);
assertValid(x1);
assertValid(x2);
}
diff --git a/tests/python/numerics/t_amount.py b/tests/python/numerics/t_amount.py
index dd87b2cd..bde8eae1 100644
--- a/tests/python/numerics/t_amount.py
+++ b/tests/python/numerics/t_amount.py
@@ -33,10 +33,10 @@ class AmountTestCase(unittest.TestCase):
x9 = amount(x3)
x10 = amount(x6)
- self.assertEqual(amount(0), x0)
- self.assertEqual(amount(), x0)
- self.assertEqual(amount("0"), x0)
- self.assertEqual(amount("0.0"), x0)
+ self.assertRaises(exceptions.ArithmeticError, operator.eq, amount(0), x0)
+ self.assertRaises(exceptions.ArithmeticError, operator.eq, amount(), x0)
+ self.assertRaises(exceptions.ArithmeticError, operator.eq, amount("0"), x0)
+ self.assertRaises(exceptions.ArithmeticError, operator.eq, amount("0.0"), x0)
self.assertEqual(x2, x1)
self.assertEqual(x5, x1)
self.assertEqual(x6, x3)
@@ -98,7 +98,6 @@ class AmountTestCase(unittest.TestCase):
self.assertValid(x10)
def testAssignment(self):
- x0 = amount()
x1 = amount(123456)
x2 = amount(123456L)
x3 = amount(123.456)
@@ -107,14 +106,12 @@ class AmountTestCase(unittest.TestCase):
x9 = x3
x10 = amount(x6)
- self.assertEqual(amount(0), x0)
self.assertEqual(x2, x1)
self.assertEqual(x5, x1)
self.assertEqual(x6, x3)
self.assertEqual(x10, x3)
self.assertEqual(x10, x9)
- x0 = amount()
x1 = amount(123456)
x2 = amount(123456L)
x3 = amount(123.456)
@@ -123,14 +120,12 @@ class AmountTestCase(unittest.TestCase):
x9 = x3
x10 = amount(x6)
- self.assertEqual(amount(0), x0)
self.assertEqual(x2, x1)
self.assertEqual(x5, x1)
self.assertEqual(x6, x3)
self.assertEqual(x10, x3)
self.assertEqual(x10, x9)
- self.assertValid(x0)
self.assertValid(x1)
self.assertValid(x2)
self.assertValid(x3)
@@ -217,12 +212,10 @@ class AmountTestCase(unittest.TestCase):
x10 = amount("-123.45€")
self.assertTrue(x0.is_null())
- self.assertTrue(x0.is_zero())
- self.assertTrue(x0.is_realzero())
- self.assertTrue(x0.sign() == 0)
- self.assertTrue(x0.compare(x1) < 0)
- self.assertTrue(x0.compare(x2) > 0)
- self.assertTrue(x0.compare(x0) == 0)
+ self.assertRaises(exceptions.ArithmeticError, amount.is_zero, x0)
+ self.assertRaises(exceptions.ArithmeticError, amount.is_realzero, x0)
+ self.assertRaises(exceptions.ArithmeticError, amount.sign, x0)
+ self.assertRaises(exceptions.ArithmeticError, amount.compare, x0, 0)
self.assertTrue(x1 != x2)
self.assertTrue(x1 != x4)
@@ -255,12 +248,12 @@ class AmountTestCase(unittest.TestCase):
x5 = amount("-123.45")
x6 = amount("123.45")
- self.assertTrue(x0 > x1)
- self.assertTrue(x0 < x2)
- self.assertTrue(x0 > x3)
- self.assertTrue(x0 < x4)
- self.assertTrue(x0 > x5)
- self.assertTrue(x0 < x6)
+ self.assertRaises(exceptions.ArithmeticError, operator.gt, x0, x1)
+ self.assertRaises(exceptions.ArithmeticError, operator.lt, x0, x2)
+ self.assertRaises(exceptions.ArithmeticError, operator.gt, x0, x3)
+ self.assertRaises(exceptions.ArithmeticError, operator.lt, x0, x4)
+ self.assertRaises(exceptions.ArithmeticError, operator.gt, x0, x5)
+ self.assertRaises(exceptions.ArithmeticError, operator.lt, x0, x6)
self.assertTrue(x1 > x3)
self.assertTrue(x3 <= x5)
@@ -284,7 +277,6 @@ class AmountTestCase(unittest.TestCase):
self.assertValid(x6)
def testCommodityComparisons(self):
- x0 = amount()
x1 = amount("$-123")
x2 = amount("$123.00")
x3 = amount(internalAmount("$-123.4544"))
@@ -292,13 +284,6 @@ class AmountTestCase(unittest.TestCase):
x5 = amount("$-123.45")
x6 = amount("$123.45")
- self.assertTrue(x0 > x1)
- self.assertTrue(x0 < x2)
- self.assertTrue(x0 > x3)
- self.assertTrue(x0 < x4)
- self.assertTrue(x0 > x5)
- self.assertTrue(x0 < x6)
-
self.assertTrue(x1 > x3)
self.assertTrue(x3 <= x5)
self.assertTrue(x3 < x5)
@@ -307,7 +292,6 @@ class AmountTestCase(unittest.TestCase):
self.assertTrue(x3 < x1)
self.assertTrue(x3 < x4)
- self.assertValid(x0)
self.assertValid(x1)
self.assertValid(x2)
self.assertValid(x3)
@@ -792,14 +776,12 @@ class AmountTestCase(unittest.TestCase):
self.assertValid(x7)
def testNegation(self):
- x0 = amount()
x1 = amount(-123456)
x3 = amount(-123.456)
x5 = amount("-123456")
x6 = amount("-123.456")
x9 = amount(- x3)
- self.assertEqual(amount(0), x0)
self.assertEqual(x5, x1)
self.assertEqual(x6, x3)
self.assertEqual(- x6, x9)
@@ -809,7 +791,6 @@ class AmountTestCase(unittest.TestCase):
self.assertEqual(x3, x10)
- self.assertValid(x0)
self.assertValid(x1)
self.assertValid(x3)
self.assertValid(x5)
@@ -875,7 +856,7 @@ class AmountTestCase(unittest.TestCase):
x1 = amount(-1234)
x2 = amount(1234)
- self.assertEqual(amount(), abs(x0))
+ self.assertRaises(exceptions.ArithmeticError, amount.abs, x0)
self.assertEqual(amount(1234), abs(x1))
self.assertEqual(amount(1234), abs(x2))
@@ -884,15 +865,12 @@ class AmountTestCase(unittest.TestCase):
self.assertValid(x2)
def testCommodityAbs(self):
- x0 = amount()
x1 = amount("$-1234.56")
x2 = amount("$1234.56")
- self.assertEqual(amount(), abs(x0))
self.assertEqual(amount("$1234.56"), abs(x1))
self.assertEqual(amount("$1234.56"), abs(x2))
- self.assertValid(x0)
self.assertValid(x1)
self.assertValid(x2)
@@ -941,7 +919,7 @@ class AmountTestCase(unittest.TestCase):
self.assertEqual(amount("0.0000000000000000000000000000000000001"),
x5.round(37))
- self.assertEqual(amount(), x5.round(36))
+ self.assertEqual(amount(0), x5.round(36))
self.assertValid(x1)
self.assertValid(x2)
@@ -1050,7 +1028,7 @@ class AmountTestCase(unittest.TestCase):
x3 = amount("1")
x4 = amount("-1")
- self.assertEqual(x0.sign(), 0)
+ self.assertRaises(exceptions.ArithmeticError, amount.sign, x0)
self.assertTrue(x1.sign() > 0)
self.assertTrue(x2.sign() < 0)
self.assertTrue(x3.sign() > 0)
@@ -1063,19 +1041,16 @@ class AmountTestCase(unittest.TestCase):
self.assertValid(x4)
def testCommoditySign(self):
- x0 = amount()
x1 = amount(internalAmount("$0.0000000000000000000000000000000000001"))
x2 = amount(internalAmount("$-0.0000000000000000000000000000000000001"))
x3 = amount("$1")
x4 = amount("$-1")
- self.assertFalse(x0.sign())
self.assertTrue(x1.sign() != 0)
self.assertTrue(x2.sign() != 0)
self.assertTrue(x3.sign() > 0)
self.assertTrue(x4.sign() < 0)
- self.assertValid(x0)
self.assertValid(x1)
self.assertValid(x2)
self.assertValid(x3)
@@ -1086,7 +1061,7 @@ class AmountTestCase(unittest.TestCase):
x1 = amount("1234")
x2 = amount("1234.56")
- self.assertFalse(x0)
+ self.assertRaises(exceptions.ArithmeticError, operator.truth, x0)
self.assertTrue(x1)
self.assertTrue(x2)
@@ -1115,10 +1090,9 @@ class AmountTestCase(unittest.TestCase):
x0 = amount()
x1 = amount("0.000000000000000000001")
- self.assertFalse(x0)
self.assertTrue(x1)
- self.assertTrue(x0.is_zero())
- self.assertTrue(x0.is_realzero())
+ self.assertRaises(exceptions.ArithmeticError, amount.is_zero, x0)
+ self.assertRaises(exceptions.ArithmeticError, amount.is_realzero, x0)
self.assertFalse(x1.is_zero())
self.assertFalse(x1.is_realzero())