Unit test for Python are now auto-generated from the C++ tests.

This commit is contained in:
John Wiegley 2009-01-28 20:49:26 -04:00
parent 3020f0f851
commit e851c02d27
17 changed files with 475 additions and 1629 deletions

View file

@ -437,10 +437,42 @@ extra_tests_SOURCES = \
extra_tests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags)
extra_tests_LDADD = $(math_tests_LDADD) libledger_extra.la
all_tests_sources = \
$(util_tests_SOURCES) \
$(math_tests_SOURCES) \
$(expr_tests_SOURCES) \
$(data_tests_SOURCES) \
$(parse_tests_SOURCES) \
$(report_tests_SOURCES) \
$(extra_tests_SOURCES)
EXTRA_DIST += test/python
PyUnitTests_SOURCES = test/__init__.py test/PyUnitTests.py test/UnitTests.py
all_py_tests_sources = \
$(patsubst test/unit/%.cc,test/python/%.py, \
$(filter test/unit/t_%.cc,$(all_tests_sources)))
test/python/%.py: test/unit/%.cc test/convert.py
$(PYTHON) $(srcdir)/test/convert.py $< $@
test/python/UnitTests.py: $(all_py_tests_sources)
@echo "from unittest import TextTestRunner, TestSuite" > $@
@for file in $$(ls $(srcdir)/test/unit/*.cc); do \
base=$$(basename $$file); \
base=$$(echo $$base | sed 's/\.cc//'); \
echo "import $$base" >> $@; \
done
@echo "suites = [" >> $@
@for file in $$(ls $(srcdir)/test/unit/*.cc); do \
base=$$(basename $$file); \
base=$$(echo $$base | sed 's/\.cc//'); \
echo " $$base.suite()," >> $@; \
done
@echo "]" >> $@
@echo "TextTestRunner().run(TestSuite(suites))" >> $@
ESC_python=`echo "$(PYTHON)" | sed 's/\//\\\\\//g'`
ESC_srcdir=`echo "$(srcdir)" | sed 's/\//\\\\\//g'`
ESC_builddir=`echo "$(top_builddir)" | sed 's/\//\\\\\//g'`
@ -448,7 +480,9 @@ ESC_distdir=`echo "$(distdir)" | sed 's/\//\\\\\//g'`
# jww (2007-05-10): This rule will not be triggered on systems that
# define an EXEEXT.
PyUnitTests: $(srcdir)/test/PyUnitTests.py
PyUnitTests: $(srcdir)/test/PyUnitTests.py test/python/UnitTests.py
@echo all_test_sources: $(all_tests_sources)
@echo all_py_test_sources: $(all_py_tests_sources)
cat $(srcdir)/test/PyUnitTests.py \
| sed "s/%python%/$(ESC_python)/" \
| sed "s/%srcdir%/$(ESC_srcdir)/g" \

View file

@ -97,13 +97,23 @@ void py_parse_str_2(amount_t& amount, const string& str, unsigned char flags) {
amount.parse(str, flags);
}
void py_print(amount_t& amount, object out) {
if (PyFile_Check(out.ptr())) {
pyofstream outstr(reinterpret_cast<PyFileObject *>(out.ptr()));
amount.print(outstr);
} else {
PyErr_SetString(PyExc_IOError,
"Argument to amount.print_(file) is not a file object");
}
}
void py_read_1(amount_t& amount, object in) {
if (PyFile_Check(in.ptr())) {
pyifstream instr(reinterpret_cast<PyFileObject *>(in.ptr()));
amount.read(instr);
} else {
PyErr_SetString(PyExc_IOError,
"Argument to amount.parse(file) is not a file object");
"Argument to amount.read(file) is not a file object");
}
}
void py_read_2(amount_t& amount, const std::string& str) {
@ -111,6 +121,25 @@ void py_read_2(amount_t& amount, const std::string& str) {
amount.read(p);
}
void py_write_xml_1(amount_t& amount, object out) {
if (PyFile_Check(out.ptr())) {
pyofstream outstr(reinterpret_cast<PyFileObject *>(out.ptr()));
amount.write_xml(outstr);
} else {
PyErr_SetString(PyExc_IOError,
"Argument to amount.write_xml(file) is not a file object");
}
}
void py_write_xml_2(amount_t& amount, object out, const int depth) {
if (PyFile_Check(out.ptr())) {
pyofstream outstr(reinterpret_cast<PyFileObject *>(out.ptr()));
amount.write_xml(outstr, depth);
} else {
PyErr_SetString(PyExc_IOError,
"Argument to amount.write_xml(file, depth) is not a file object");
}
}
#define EXC_TRANSLATOR(type) \
void exc_translate_ ## type(const type& err) { \
PyErr_SetString(PyExc_ArithmeticError, err.what()); \
@ -124,12 +153,10 @@ void export_amount()
scope().attr("AMOUNT_PARSE_NO_REDUCE") = AMOUNT_PARSE_NO_REDUCE;
class_< amount_t > ("Amount")
#if 0
.def("initialize", &amount_t::initialize)
.staticmethod("initialize")
.def("shutdown", &amount_t::shutdown)
.staticmethod("shutdown")
#endif
.add_static_property("current_pool",
make_getter(&amount_t::current_pool,
@ -266,7 +293,7 @@ internal precision.")
.def(double() / self)
#endif
.add_property("precision", &amount_t::precision)
.def("precision", &amount_t::precision)
.def("negate", &amount_t::negate)
.def("in_place_negate", &amount_t::in_place_negate,
@ -317,22 +344,21 @@ internal precision.")
#endif
.def("fits_in_long", &amount_t::fits_in_long)
.add_property("quantity_string", &amount_t::quantity_string)
.def("quantity_string", &amount_t::quantity_string)
.add_property("commodity",
make_function(&amount_t::commodity,
return_value_policy<reference_existing_object>()),
make_function(&amount_t::set_commodity,
with_custodian_and_ward<1, 2>()))
.def("commodity", &amount_t::commodity,
return_value_policy<reference_existing_object>())
.def("set_commodity", &amount_t::set_commodity,
with_custodian_and_ward<1, 2>())
.def("has_commodity", &amount_t::has_commodity)
.def("clear_commodity", &amount_t::clear_commodity)
.add_property("number", &amount_t::number)
.def("number", &amount_t::number)
.def("annotate", &amount_t::annotate)
.def("is_annotated", &amount_t::is_annotated)
#if 0
.add_property("annotation", &amount_t::annotation)
.def("annotation", &amount_t::annotation)
#endif
.def("strip_annotations", &amount_t::strip_annotations)
@ -344,10 +370,18 @@ internal precision.")
.def("parse_conversion", &amount_t::parse_conversion)
.staticmethod("parse_conversion")
.def("print_", py_print)
.def("read", py_read_1)
.def("read", py_read_2)
.def("write", &amount_t::write)
.def("read_xml", &amount_t::read_xml)
.def("write_xml", py_write_xml_1)
.def("write_xml", py_write_xml_2)
.def("dump", &amount_t::dump)
.def("valid", &amount_t::valid)
;

View file

@ -40,6 +40,13 @@ namespace ledger {
using namespace boost::python;
void py_add_price(commodity_t& commodity,
const datetime_t& date,
const amount_t& price)
{
commodity.add_price(date, price);
}
void export_commodity()
{
scope().attr("COMMODITY_STYLE_DEFAULTS") = COMMODITY_STYLE_DEFAULTS;
@ -57,7 +64,9 @@ void export_commodity()
.def("drop_flags", &commodity_t::drop_flags)
.add_property("precision", &commodity_t::precision)
.def("add_price", py_add_price)
.def("precision", &commodity_t::precision)
;
}

View file

@ -32,12 +32,6 @@
#include "pyinterp.h"
#include "pyutils.h"
#include <boost/cast.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/to_python_converter.hpp>
#include <Python.h>
#include <datetime.h>
// jww (2007-05-04): Convert time duration objects to PyDelta
@ -121,12 +115,26 @@ struct datetime_from_python
typedef register_python_conversion<datetime_t, datetime_to_python, datetime_from_python>
datetime_python_conversion;
datetime_t py_parse_datetime(const string& str) {
return parse_datetime(str);
}
date_t py_parse_date(const string& str) {
return parse_date(str);
}
void export_times()
{
date_python_conversion();
datetime_python_conversion();
date_python_conversion();
register_optional_to_python<datetime_t>();
register_optional_to_python<date_t>();
scope().attr("parse_datetime") = &py_parse_datetime;
scope().attr("parse_date") = &py_parse_date;
scope().attr("current_time") = current_time;
scope().attr("current_date") = current_date;
}
} // namespace ledger

View file

@ -3,4 +3,4 @@
PYTHONPATH="%builddir%":"%srcdir%":$PYTHONPATH \
LD_LIBRARY_PATH="%builddir%/.libs":$LD_LIBRARY_PATH \
DYLD_LIBRARY_PATH="%builddir%/.libs":$DYLD_LIBRARY_PATH \
%python% "%srcdir%"/test/UnitTests.py
%python% "%builddir%"/test/python/UnitTests.py

View file

@ -1,9 +0,0 @@
from unittest import TextTestRunner, TestSuite
import test.python.math.t_amount as t_amount
suites = [
t_amount.suite(),
]
TextTestRunner().run(TestSuite(suites))

174
test/convert.py Executable file
View file

@ -0,0 +1,174 @@
#!/usr/bin/env python
# convert.py: This script converts a C++ Ledger unit test into an equivalent
# Python unit test.
#
# 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.
import re
import sys
import os
source = os.path.abspath(sys.argv[1])
base = os.path.splitext(source)[0]
target = os.path.abspath(sys.argv[2])
dirname = os.path.dirname(target)
if not os.path.isdir(dirname):
os.makedirs(dirname)
fd = open(source, "r")
fo = open(target, "w")
fo.write('''# -*- coding: utf-8 -*-
import unittest
import exceptions
import operator
from ledger import *
from StringIO import *
from datetime import *
internalAmount = Amount.exact
class %sTestCase(unittest.TestCase):
testSession = None
def assertValid(self, amt):
self.assertTrue(amt.valid())''' % os.path.basename(base))
not_for_python = 0
for line in fd.readlines():
if re.match('^#ifndef NOT_FOR_PYTHON', line):
not_for_python += 1
continue
elif not_for_python > 0:
if re.match('^#endif // NOT_FOR_PYTHON', line):
not_for_python -= 1
continue
if re.match('^(using|CPP|[#{}/])', line):
continue
if re.match('^\s+[{}]\s+$', line):
continue
if not re.search('assert', line):
match = re.match('void [^:]+::(test[^(]+|setUp|tearDown)\(\)', line)
if match:
fo.write(' def %s(self):\n' % match.group(1))
continue
match = re.search(' ([a-z:_<>]+?)&?\s+([a-z0-9_]+)(\((.+?)\))?;', line)
if match:
if match.group(1) != "std::string":
line = ' %s = %s(%s)\n' % (match.group(2), match.group(1),
match.group(4) or "")
else:
line = ''
match = re.search(' ([a-z:_<>]+?)&?\s+([a-z0-9]+)\s*=\s*([^(]+);', line)
if match:
line = ' %s = %s(%s)\n' % (match.group(2), match.group(1),
match.group(3))
match = re.search(' ([a-z:_<>]+?)\s+([a-z0-9]+)\s*=\s*(.+?)$', line)
if match:
line = ' %s = %s\n' % (match.group(2), match.group(3))
line = re.sub('CPPUNIT_ASSERT', 'self.assertTrue', line)
line = re.sub('assertValid', 'self.assertValid', line)
line = re.sub('assertTrue', 'self.assertTrue', line)
line = re.sub('assertFalse', 'self.assertFalse', line)
line = re.sub('assertNotEqual', 'self.assertNotEqual', line)
line = re.sub('assertEqual', 'self.assertEqual', line)
line = re.sub('assertThrow\(([^,]+), ([^,)]+?)\)',
'self.assertRaises(\\2, lambda: \\1)', line)
#line = re.sub('optional<([^>]+?)>', '\\1', line)
line = re.sub('amount_t::precision_t\(([^)]+?)\)', '\\1', line)
# Determine this list automatically by scanning the class_ lines in
# python/*.cc
line = re.sub('amount_t::', 'Amount.', line)
line = re.sub('commodity_t\(([^)]+?)\)', '\\1', line)
line = re.sub('commodity_t::', 'Commodity.', line)
line = re.sub('balance_t::', 'Balance.', line)
line = re.sub('balance_pair_t::', 'BalancePair.', line)
line = re.sub('value_t::', 'Value.', line)
line = re.sub('amount_t', 'Amount', line)
line = re.sub('commodity_t', 'Commodity', line)
line = re.sub('balance_t', 'Balance', line)
line = re.sub('balance_pair_t', 'BalancePair', line)
line = re.sub('value_t', 'Value', line)
line = re.sub('ledger::', '', line)
line = re.sub('std::istringstream', 'StringIO', line)
line = re.sub('std::ostringstream', 'StringIO', line)
line = re.sub('set_session_context\(&session\)',
'self.testSession = session()\n set_session_context(self.testSession)', line)
line = re.sub('set_session_context\(\)',
'set_session_context()\n self.testSession = None', line)
line = re.sub('([a-z_]+?)_t\b', '\\1', line)
line = re.sub('std::string\(([^)]+?)\)', '\\1', line)
line = re.sub('string\(([^)]+?)\)', '\\1', line)
line = re.sub('\.print\(([^)]+?)\)', '.print_(\\1)', line)
line = re.sub('true', 'True', line)
line = re.sub('false', 'False', line)
line = re.sub('([0-9]+)[FL]', '\\1', line)
line = re.sub('([0-9]+)UL', '\\1L', line)
line = re.sub(';', '', line)
line = re.sub('//', '#', line)
line = re.sub('->', '.', line)
line = re.sub('(\s+|\()(\S+?) \? (.+?) : (.+?)\)',
'\\1\\3 if \\2 else \\4)', line)
line = re.sub('if \((.+?)\)( {)?$', 'if \\1:', line)
line = re.sub('(} )?else( {)?$', 'else:', line)
line = re.sub('amount_error', 'exceptions.ArithmeticError', line)
match = re.match('^ ', line)
if match:
fo.write(' ' + line)
else:
fo.write(line)
fo.write('''
def suite():
return unittest.TestLoader().loadTestsFromTestCase(%sTestCase)
if __name__ == '__main__':
unittest.main()
''' % os.path.basename(base))
fo.close()
fd.close()

File diff suppressed because it is too large Load diff

View file

@ -42,11 +42,13 @@ void AmountTestCase::testParser()
assertEqual(amount_t::precision_t(2), x12.commodity().precision());
#ifndef NOT_FOR_PYTHON
string buf("$100...");
std::istringstream input(buf);
amount_t x13;
x13.parse(input);
assertEqual(x12, x13);
#endif // NOT_FOR_PYTHON
amount_t x14;
assertThrow(x14.parse("DM"), amount_error);
@ -210,6 +212,7 @@ void AmountTestCase::testCommodityConstructors()
assertValid(x10);
}
#ifndef NOT_FOR_PYTHON
void AmountTestCase::testAssignment()
{
amount_t x0;
@ -315,6 +318,7 @@ void AmountTestCase::testCommodityAssignment()
assertValid(x9);
assertValid(x10);
}
#endif // NOT_FOR_PYTHON
void AmountTestCase::testEquality()
{
@ -350,35 +354,24 @@ void AmountTestCase::testEquality()
void AmountTestCase::testCommodityEquality()
{
amount_t x0;
amount_t x1;
amount_t x2;
amount_t x3;
amount_t x4;
amount_t x5;
amount_t x6;
amount_t x7;
amount_t x8;
amount_t x9;
amount_t x10;
x1 = "$123.45";
x2 = "-$123.45";
x3 = "$-123.45";
x4 = "DM 123.45";
x5 = "-DM 123.45";
x6 = "DM -123.45";
x7 = "123.45 euro";
x8 = "-123.45 euro";
x9 = "123.45€";
x10 = "-123.45€";
amount_t x1("$123.45");
amount_t x2("-$123.45");
amount_t x3("$-123.45");
amount_t x4("DM 123.45");
amount_t x5("-DM 123.45");
amount_t x6("DM -123.45");
amount_t x7("123.45 euro");
amount_t x8("-123.45 euro");
amount_t x9("123.45€");
amount_t x10("-123.45€");
assertTrue(x0.is_null());
assertThrow(x0.is_zero(), amount_error);
assertThrow(x0.is_realzero(), amount_error);
assertThrow(assert(x0.sign() == 0), amount_error);
assertThrow(assert(x0.compare(x1) < 0), amount_error);
assertThrow(assert(x0.compare(x2) > 0), amount_error);
assertThrow(assert(x0.compare(x0) == 0), 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);
@ -1335,7 +1328,7 @@ void AmountTestCase::testTruth()
amount_t x1("1234");
amount_t x2("1234.56");
assertThrow(assert(x0 ? 1 : 0), amount_error);
assertThrow(x0 ? 1 : 0, amount_error);
assertTrue(x1);
assertTrue(x2);
@ -1442,24 +1435,24 @@ void AmountTestCase::testCommodityConversion()
assertValid(x1);
}
#ifndef NOT_FOR_PYTHON
void AmountTestCase::testPrinting()
{
amount_t x0;
amount_t x1("982340823.380238098235098235098235098");
#if 0
{
std::ostringstream bufstr;
assertThrow(bufstr << x0, amount_error);
std::ostringstream bufstr;
x0.print(bufstr);
assertEqual(std::string("<null>"), bufstr.str());
}
#endif
{
std::ostringstream bufstr;
bufstr << x1;
std::ostringstream bufstr;
x1.print(bufstr);
assertEqual(std::string("982340823.380238098235098235098235098"),
bufstr.str());
assertEqual(std::string("982340823.380238098235098235098235098"),
bufstr.str());
}
assertValid(x0);
@ -1472,26 +1465,26 @@ void AmountTestCase::testCommodityPrinting()
amount_t x2("$982340823.38");
{
std::ostringstream bufstr;
bufstr << x1;
std::ostringstream bufstr;
x1.print(bufstr);
assertEqual(std::string("$982340823.386238098235098235098235098"),
bufstr.str());
assertEqual(std::string("$982340823.386238098235098235098235098"),
bufstr.str());
}
{
std::ostringstream bufstr;
bufstr << (x1 * x2).to_string();
std::ostringstream bufstr;
(x1 * x2).print(bufstr);
assertEqual(std::string("$964993493285024293.18099172508158508135413499124"),
bufstr.str());
assertEqual(std::string("$964993493285024293.18099172508158508135413499124"),
bufstr.str());
}
{
std::ostringstream bufstr;
bufstr << (x2 * x1).to_string();
std::ostringstream bufstr;
(x2 * x1).print(bufstr);
assertEqual(std::string("$964993493285024293.18"), bufstr.str());
assertEqual(std::string("$964993493285024293.18"), bufstr.str());
}
assertValid(x1);
@ -1512,14 +1505,14 @@ void AmountTestCase::testSerialization()
std::string buf;
{
std::ostringstream storage;
assertThrow(x0.write(storage), amount_error);
x1.write(storage);
x2.write(storage);
x3.write(storage);
x4.write(storage);
x5.write(storage);
buf = storage.str();
std::ostringstream storage;
assertThrow(x0.write(storage), amount_error);
x1.write(storage);
x2.write(storage);
x3.write(storage);
x4.write(storage);
x5.write(storage);
buf = storage.str();
}
amount_t x1b;
@ -1528,12 +1521,12 @@ void AmountTestCase::testSerialization()
amount_t x4b;
amount_t x5b;
{
std::istringstream storage(buf);
x1b.read(storage);
x2b.read(storage);
x3b.read(storage);
x4b.read(storage);
x5b.read(storage);
std::istringstream storage(buf);
x1b.read(storage);
x2b.read(storage);
x3b.read(storage);
x4b.read(storage);
x5b.read(storage);
}
assertEqual(x1, x1b);
@ -1541,6 +1534,7 @@ void AmountTestCase::testSerialization()
assertEqual(x3, x3b);
assertEqual(x4, x4b);
#ifndef NOT_FOR_PYTHON
const char * ptr = buf.c_str();
amount_t x1c;
@ -1549,17 +1543,18 @@ void AmountTestCase::testSerialization()
amount_t x4c;
amount_t x5c;
{
x1c.read(ptr);
x2c.read(ptr);
x3c.read(ptr);
x4c.read(ptr);
x5c.read(ptr);
x1c.read(ptr);
x2c.read(ptr);
x3c.read(ptr);
x4c.read(ptr);
x5c.read(ptr);
}
assertEqual(x1, x1b);
assertEqual(x2, x2b);
assertEqual(x3, x3b);
assertEqual(x4, x4b);
#endif // NOT_FOR_PYTHON
assertValid(x1);
assertValid(x2);
@ -1574,3 +1569,14 @@ void AmountTestCase::testSerialization()
assertValid(x3c);
assertValid(x4c);
}
void AmountTestCase::testXmlSerialization()
{
amount_t x1("$8,192.34");
std::ostringstream storage;
x1.write_xml(storage);
assertEqual(std::string("<amount>\n <commodity flags=\"PT\">\n <symbol>$</symbol>\n </commodity>\n <quantity>8192.34</quantity>\n</amount>\n"), storage.str());
}
#endif // NOT_FOR_PYTHON

View file

@ -48,6 +48,7 @@ class AmountTestCase : public CPPUNIT_NS::TestCase
CPPUNIT_TEST(testPrinting);
CPPUNIT_TEST(testCommodityPrinting);
CPPUNIT_TEST(testSerialization);
CPPUNIT_TEST(testXmlSerialization);
CPPUNIT_TEST_SUITE_END();
@ -99,6 +100,7 @@ public:
void testPrinting();
void testCommodityPrinting();
void testSerialization();
void testXmlSerialization();
private:
AmountTestCase(const AmountTestCase &copy);

View file

@ -26,4 +26,5 @@ void BalanceTestCase::tearDown()
void BalanceTestCase::testConstructors()
{
int x = 1;
}

View file

@ -17,14 +17,25 @@ void CommodityTestCase::tearDown() {
void CommodityTestCase::testPriceHistory()
{
datetime_t jan17_05 = parse_datetime("2005/01/17 00:00:00");
datetime_t jan17_06 = parse_datetime("2006/01/17 00:00:00");
datetime_t jan17_07 = parse_datetime("2007/01/17 00:00:00");
datetime_t feb27_07 = parse_datetime("2007/02/27 18:00:00");
datetime_t feb28_07 = parse_datetime("2007/02/28 06:00:00");
datetime_t feb28_07sbm = parse_datetime("2007/02/28 11:59:59");
datetime_t mar01_07 = parse_datetime("2007/03/01 00:00:00");
datetime_t apr15_07 = parse_datetime("2007/04/15 13:00:00");
#ifndef NOT_FOR_PYTHON
datetime_t jan17_05;
datetime_t jan17_06;
datetime_t jan17_07;
datetime_t feb27_07;
datetime_t feb28_07;
datetime_t feb28_07sbm;
datetime_t mar01_07;
datetime_t apr15_07;
#endif // NOT_FOR_PYTHON
jan17_05 = parse_datetime("2005/01/17 00:00:00");
jan17_06 = parse_datetime("2006/01/17 00:00:00");
jan17_07 = parse_datetime("2007/01/17 00:00:00");
feb27_07 = parse_datetime("2007/02/27 18:00:00");
feb28_07 = parse_datetime("2007/02/28 06:00:00");
feb28_07sbm = parse_datetime("2007/02/28 11:59:59");
mar01_07 = parse_datetime("2007/03/01 00:00:00");
apr15_07 = parse_datetime("2007/04/15 13:00:00");
amount_t x0;
amount_t x1("100.10 AAPL");
@ -45,15 +56,18 @@ void CommodityTestCase::testPriceHistory()
aapl.add_price(jan17_05, amount_t("EUR 23.00"));
aapl.add_price(jan17_06, amount_t("CAD 25.00"));
commodity_t& euro(amount_t("EUR 1.00").commodity());
amount_t one_euro("EUR 1.00");
commodity_t& euro(one_euro.commodity());
euro.add_price(feb27_07, amount_t("CAD 1.40"));
euro.add_price(jan17_05, amount_t("$0.78"));
commodity_t& cad(amount_t("CAD 1.00").commodity());
amount_t one_cad("CAD 1.00");
commodity_t& cad(one_cad.commodity());
cad.add_price(jan17_06, amount_t("$1.11"));
#ifndef NOT_FOR_PYTHON
optional<amount_t> amt = x1.value(feb28_07sbm);
assertTrue(amt);
assertEqual(amount_t("$1831.83"), *amt);
@ -76,6 +90,7 @@ void CommodityTestCase::testPriceHistory()
amt = x1.value(current_time, cad);
assertTrue(amt);
assertEqual(amount_t("CAD 3223.22"), *amt);
#endif // NOT_FOR_PYTHON
assertValid(x1);
}
@ -83,15 +98,18 @@ void CommodityTestCase::testPriceHistory()
void CommodityTestCase::testLots()
{
// jww (2007-04-17): tbd
int x = 1;
}
void CommodityTestCase::testScalingBase()
{
// jww (2007-04-17): tbd
int x = 1;
}
void CommodityTestCase::testReduction()
{
// jww (2007-04-17): tbd
int x = 1;
}

View file

@ -9,15 +9,20 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ValueExprTestCase, "expr");
void ValueExprTestCase::setUp()
{
amount_t::initialize();
#ifndef NOT_FOR_PYTHON
expr_t::initialize();
#endif // NOT_FOR_PYTHON
}
void ValueExprTestCase::tearDown()
{
#ifndef NOT_FOR_PYTHON
expr_t::shutdown();
#endif // NOT_FOR_PYTHON
amount_t::shutdown();
}
void ValueExprTestCase::testConstructors()
{
int x = 1;
}

View file

@ -1,81 +1,109 @@
#include "t_times.h"
#include "utils.h"
using namespace ledger;
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(DateTimeTestCase, "util");
void DateTimeTestCase::setUp() {}
void DateTimeTestCase::tearDown() {}
void DateTimeTestCase::setUp() {
int x = 1;
}
void DateTimeTestCase::tearDown() {
int x = 1;
}
void DateTimeTestCase::testConstructors()
{
#if 0
std::time_t time_t_now = std::time(NULL);
struct tm * moment = std::localtime(&time_t_now);
#ifndef NOT_FOR_PYTHON
std::time_t now = std::time(NULL);
struct tm * moment = std::localtime(&now);
std::time_t localMoment = std::mktime(moment);
#endif // NOT_FOR_PYTHON
ptime d0;
ptime d1(parse_datetime("1990/01/01"));
ptime d3(boost::posix_time::from_time_t(localMoment));
ptime d4(parse_datetime("2006/12/25"));
//ptime d5(parse_datetime("12/25"));
ptime d6(parse_datetime("2006.12.25"));
//ptime d7(parse_datetime("12.25"));
ptime d8(parse_datetime("2006-12-25"));
//ptime d9(parse_datetime("12-25"));
#if 0
ptime d10(parse_datetime("tue"));
ptime d11(parse_datetime("tuesday"));
ptime d12(parse_datetime("feb"));
ptime d13(parse_datetime("february"));
ptime d14(parse_datetime("2006"));
#endif
ptime d15(d3);
#ifndef NOT_FOR_PYTHON
datetime_t d0;
datetime_t d1;
datetime_t d3;
datetime_t d4;
datetime_t d5;
datetime_t d6;
datetime_t d7;
datetime_t d8;
datetime_t d9;
datetime_t d10;
datetime_t d11;
datetime_t d12;
datetime_t d13;
datetime_t d14;
datetime_t d15;
#endif // NOT_FOR_PYTHON
d1 = parse_datetime("1990/01/01");
#ifndef NOT_FOR_PYTHON
d3 = boost::posix_time::from_time_t(localMoment);
#endif // NOT_FOR_PYTHON
d4 = parse_datetime("2006/12/25");
d5 = parse_datetime("12/25");
d6 = parse_datetime("2006.12.25");
d7 = parse_datetime("12.25");
d8 = parse_datetime("2006-12-25");
d9 = parse_datetime("12-25");
d10 = parse_datetime("tue");
d11 = parse_datetime("tuesday");
d12 = parse_datetime("feb");
d13 = parse_datetime("february");
d14 = parse_datetime("2006");
#ifndef NOT_FOR_PYTHON
d15 = d3;
#endif // NOT_FOR_PYTHON
#ifndef NOT_FOR_PYTHON
assertTrue(d0.is_not_a_date_time());
assertFalse(d1.is_not_a_date_time());
assertFalse(d4.is_not_a_date_time());
#endif // NOT_FOR_PYTHON
assertTrue(now > d1);
//assertTrue(now <= d3);
assertTrue(now > d4);
assertTrue(current_time > d1);
assertTrue(current_time > d4);
#ifndef NOT_FOR_PYTHON
assertEqual(d3, d15);
#endif // NOT_FOR_PYTHON
assertEqual(d4, d6);
assertEqual(d4, d8);
//assertEqual(d5, d7);
//assertEqual(d5, d9);
#if 0
assertEqual(d5, d7);
assertEqual(d5, d9);
assertEqual(d10, d11);
assertEqual(d12, d13);
#endif
#if 0
assertThrow(parse_datetime("2007/02/29"), datetime_error *);
assertThrow(parse_datetime("2007/13/01"), datetime_error *);
assertThrow(parse_datetime("2007/00/01"), datetime_error *);
assertThrow(parse_datetime("2007/01/00"), datetime_error *);
assertThrow(parse_datetime("2007/00/00"), datetime_error *);
assertThrow(parse_datetime("2007/05/32"), datetime_error *);
#ifndef NOT_FOR_PYTHON
assertThrow(parse_datetime("2007/02/29"), boost::gregorian::bad_day_of_month);
//assertThrow(parse_datetime("2007/13/01"), datetime_error);
//assertThrow(parse_datetime("2007/00/01"), datetime_error);
assertThrow(parse_datetime("2007/01/00"), boost::gregorian::bad_day_of_month);
//assertThrow(parse_datetime("2007/00/00"), boost::gregorian::bad_day_of_month);
//assertThrow(parse_datetime("2007/05/32"), boost::gregorian::bad_day_of_month);
assertThrow(parse_datetime("2006x/12/25"), datetime_error *);
assertThrow(parse_datetime("2006/12x/25"), datetime_error *);
//assertThrow(parse_datetime("2006/12/25x"), datetime_error *);
assertThrow(parse_datetime("2006x/12/25"), datetime_error);
assertThrow(parse_datetime("2006/12x/25"), datetime_error);
assertThrow(parse_datetime("2006/12/25x"), datetime_error);
assertThrow(parse_datetime("feb/12/25"), datetime_error *);
assertThrow(parse_datetime("2006/mon/25"), datetime_error *);
assertThrow(parse_datetime("2006/12/web"), datetime_error *);
assertThrow(parse_datetime("feb/12/25"), datetime_error);
assertThrow(parse_datetime("2006/mon/25"), datetime_error);
assertThrow(parse_datetime("2006/12/web"), datetime_error);
assertThrow(parse_datetime("12*25"), datetime_error *);
assertThrow(parse_datetime("12*25"), datetime_error);
assertThrow(parse_datetime("tuf"), datetime_error *);
assertThrow(parse_datetime("tufsday"), datetime_error *);
assertThrow(parse_datetime("fec"), datetime_error *);
assertThrow(parse_datetime("fecruary"), datetime_error *);
assertThrow(parse_datetime("207x"), datetime_error *);
assertThrow(parse_datetime("hello"), datetime_error *);
interval_t i1;
interval_t i2;
#endif
assertThrow(parse_datetime("tuf"), datetime_error);
assertThrow(parse_datetime("tufsday"), datetime_error);
assertThrow(parse_datetime("fec"), datetime_error);
assertThrow(parse_datetime("fecruary"), datetime_error);
assertThrow(parse_datetime("207x"), datetime_error);
assertThrow(parse_datetime("hello"), datetime_error);
#endif // NOT_FOR_PYTHON
#endif
}

View file

@ -2,9 +2,14 @@
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(UtilitiesTestCase, "util");
void UtilitiesTestCase::setUp() {}
void UtilitiesTestCase::tearDown() {}
void UtilitiesTestCase::setUp() {
int x = 1;
}
void UtilitiesTestCase::tearDown() {
int x = 1;
}
void UtilitiesTestCase::testConstructors()
{
int x = 1;
}