summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt13
-rwxr-xr-xtest/CheckBaselineTests.py12
-rwxr-xr-xtest/CheckOptions.py2
-rwxr-xr-xtest/DocTests.py98
-rwxr-xr-xtest/RegressTests.py7
-rw-r--r--test/baseline/cmd-cleared.test2
-rw-r--r--test/baseline/cmd-convert.test (renamed from test/baseline/cmd-convert.test.disable)4
-rw-r--r--test/baseline/dir-fixed.test (renamed from test/baseline/feat-fixated-prices_2.test)0
-rw-r--r--test/baseline/opt-auto-match.test47
-rw-r--r--test/baseline/opt-cleared-format.test20
-rw-r--r--test/baseline/opt-explicit.test14
-rw-r--r--test/baseline/opt-file.test (renamed from test/baseline/opt-file.test.disable)0
-rw-r--r--test/baseline/opt-generated.test0
-rw-r--r--test/baseline/opt-init-file.dat1
-rw-r--r--test/baseline/opt-init-file.test10
-rw-r--r--test/baseline/opt-no-pager.test0
-rw-r--r--test/baseline/opt-no-revalued.test58
-rw-r--r--test/baseline/opt-no-rounding.test81
-rw-r--r--test/baseline/opt-price-db.dat2
-rw-r--r--test/baseline/opt-price-db.test8
-rw-r--r--test/baseline/opt-rich-data.test10
-rw-r--r--test/baseline/opt-script.dat3
-rw-r--r--test/baseline/opt-script.test15
-rw-r--r--test/baseline/opt-value-expr.test48
-rw-r--r--test/baseline/opt-verify-memory.test0
-rwxr-xr-xtest/convert.py2
-rw-r--r--test/regress/1057.test11
-rw-r--r--test/regress/25A099C9.test61
-rw-r--r--test/regress/25A099C9.test.disable43
-rw-r--r--test/regress/8EAF77C0.test2
-rw-r--r--test/regress/AEDE9734.test6
-rw-r--r--test/unit/CMakeLists.txt11
-rw-r--r--test/unit/t_value.cc711
33 files changed, 1183 insertions, 119 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 6eb9f956..d0b62f6e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -25,6 +25,8 @@ macro(add_ledger_harness_tests _class)
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test/RegressTests.py
$<TARGET_FILE:ledger> ${PROJECT_SOURCE_DIR}
${TestFile} ${TEST_PYTHON_FLAGS})
+ set_tests_properties(${_class}Test_${TestFile_Name}
+ PROPERTIES ENVIRONMENT "TZ=${Ledger_TEST_TIMEZONE}")
set_target_properties(check
PROPERTIES DEPENDS ${_class}Test_${TestFile_Name})
endif()
@@ -44,14 +46,21 @@ if (PYTHONINTERP_FOUND)
add_test(NAME ${_class}Test_${TestFile_Name}
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test/${_class}.py
--ledger $<TARGET_FILE:ledger> --file ${TestFile})
- set_target_properties(check PROPERTIES DEPENDS ${_class}Test_${TestFile_Name})
+ set_tests_properties(${_class}Test_${TestFile_Name}
+ PROPERTIES ENVIRONMENT "TZ=${Ledger_TEST_TIMEZONE}")
+ set_target_properties(check
+ PROPERTIES DEPENDS ${_class}Test_${TestFile_Name})
endforeach()
- list(APPEND CheckOptions CheckManpage CheckTexinfo CheckBaselineTests)
+ # CheckManpage and CheckTexinfo are disabled, since they do not work
+ # reliably yet, instead they are being run as a Travis CI report.
+ list(APPEND CheckOptions CheckBaselineTests) #CheckManpage CheckTexinfo
foreach(_class ${CheckOptions})
add_test(NAME ${_class}
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test/${_class}.py
--ledger $<TARGET_FILE:ledger> --source ${PROJECT_SOURCE_DIR})
+ set_tests_properties(${_class}
+ PROPERTIES ENVIRONMENT "TZ=${Ledger_TEST_TIMEZONE}")
endforeach()
endif()
diff --git a/test/CheckBaselineTests.py b/test/CheckBaselineTests.py
index 3c3e590b..8659d1b5 100755
--- a/test/CheckBaselineTests.py
+++ b/test/CheckBaselineTests.py
@@ -21,29 +21,23 @@ class CheckBaselineTests (CheckOptions):
self.untested_options = [
'anon',
'args-only',
- 'cache',
'debug',
'download',
- 'file',
'force-color',
'force-pager',
- 'full-help',
+ 'generated',
'help',
- 'help-calc',
- 'help-comm',
- 'help-disp',
'import',
- 'init-file',
'no-color',
+ 'no-pager',
'options',
- 'price-db',
'price-exp',
'revalued-total',
- 'script',
'seed',
'trace',
'verbose',
'verify',
+ 'verify-memory',
'version'
]
diff --git a/test/CheckOptions.py b/test/CheckOptions.py
index 5059a289..e4a1fdc3 100755
--- a/test/CheckOptions.py
+++ b/test/CheckOptions.py
@@ -83,7 +83,7 @@ class CheckOptions (object):
self.missing_functions.add(function)
else:
functions.remove(function)
- known_functions = ['tag', 'has_tag']
+ known_functions = ['tag', 'has_tag', 'meta', 'has_meta']
self.unknown_functions = {function for function in functions if function not in known_functions}
if len(self.missing_options):
diff --git a/test/DocTests.py b/test/DocTests.py
index cbad9ca7..7af7abc3 100755
--- a/test/DocTests.py
+++ b/test/DocTests.py
@@ -19,13 +19,17 @@ class DocTests:
self.verbose = args.verbose
self.tests = args.examples
- self.examples = dict()
- self.test_files = list()
- self.testin_token = 'command'
- self.testout_token = 'output'
- self.testdat_token = 'input'
+ self.examples = dict()
+ self.test_files = list()
+ self.testin_token = 'command'
+ self.testout_token = 'output'
+ self.testdat_token = 'input'
+ self.testfile_token = 'file'
self.validate_token = 'validate'
- self.testwithdat_token = 'with_input'
+ self.validate_cmd_token = 'validate-command'
+ self.validate_dat_token = 'validate-data'
+ self.testwithdat_token = 'with_input'
+ self.testwithfile_token = 'with_file'
def read_example(self):
endexample = re.compile(r'^@end\s+smallexample\s*$')
@@ -35,15 +39,15 @@ class DocTests:
self.current_line += 1
if len(line) <= 0 or endexample.match(line): break
# Replace special texinfo character sequences with their ASCII counterpart
- example += line.replace("@@","@").replace("@{","{").replace("@}","}")
+ example += re.sub(r'@([@{}])', r'\1', line)
return example
def test_id(self, example):
return hashlib.sha1(example.rstrip()).hexdigest()[0:7].upper()
def find_examples(self):
- startexample = re.compile(r'^@smallexample\s+@c\s+(%s|%s|%s)(?::([\dA-Fa-f]+|validate))?(?:,(.*))?'
- % (self.testin_token, self.testout_token, self.testdat_token))
+ startexample = re.compile(r'^@smallexample\s+@c\s+(%s|%s|%s|%s)(?::([\dA-Fa-f]+|validate))?(?:,(.*))?'
+ % (self.testin_token, self.testout_token, self.testdat_token, self.testfile_token))
while True:
line = self.file.readline()
self.current_line += 1
@@ -78,9 +82,9 @@ class DocTests:
if test_id == self.validate_token:
test_id = "Val-" + str(test_begin_line)
if test_kind == self.testin_token:
- test_kind = "validate-command"
+ test_kind = self.validate_cmd_token
elif test_kind == self.testdat_token:
- test_kind = "validate-data"
+ test_kind = self.validate_dat_token
try:
self.examples[test_id]
except KeyError:
@@ -104,16 +108,17 @@ class DocTests:
validate_command = False
try:
command = example[self.testin_token][self.testin_token]
+ command = re.sub(r'\\\n', '', command)
except KeyError:
- if 'validate-data' in example:
+ if self.validate_dat_token in example:
command = '$ ledger bal'
- elif 'validate-command' in example:
+ elif self.validate_cmd_token in example:
validate_command = True
- command = example['validate-command']['validate-command']
+ command = example[self.validate_cmd_token][self.validate_cmd_token]
else:
return None
- command = shlex.split(command)
+ command = filter(lambda x: x != '\n', shlex.split(command))
if command[0] == '$': command.remove('$')
index = command.index('ledger')
command[index] = self.ledger
@@ -145,7 +150,7 @@ class DocTests:
for test_id in tests:
validation = False
- if "validate-data" in self.examples[test_id] or "validate-command" in self.examples[test_id]:
+ if self.validate_dat_token in self.examples[test_id] or self.validate_cmd_token in self.examples[test_id]:
validation = True
example = self.examples[test_id]
try:
@@ -154,51 +159,52 @@ class DocTests:
failed.add(test_id)
continue
- try:
- output = example[self.testout_token][self.testout_token]
- except KeyError:
- output = None
-
- try:
- input = example[self.testdat_token][self.testdat_token]
- except KeyError:
- try:
- with_input = example[self.testin_token]['opts'][self.testwithdat_token]
- input = self.examples[with_input][self.testdat_token][self.testdat_token]
- except KeyError:
- try:
- input = example['validate-data']['validate-data']
- except KeyError:
- input = None
+ output = example.get(self.testout_token, {}).get(self.testout_token)
+ input = example.get(self.testdat_token, {}).get(self.testdat_token)
+ if not input:
+ with_input = example.get(self.testin_token, {}).get('opts', {}).get(self.testwithdat_token)
+ input = self.examples.get(with_input, {}).get(self.testdat_token, {}).get(self.testdat_token)
+ if not input:
+ input = example.get(self.validate_dat_token, {}).get(self.validate_dat_token)
- if command and (output or validation):
+ if command and (output != None or validation):
test_file_created = False
if findex:
scriptpath = os.path.dirname(os.path.realpath(__file__))
- test_input_dir = scriptpath + '/../test/input/'
+ test_input_dir = os.path.join(scriptpath, '..', 'test', 'input')
test_file = command[findex]
if not os.path.exists(test_file):
if input:
test_file_created = True
with open(test_file, 'w') as f:
f.write(input)
- elif os.path.exists(test_input_dir + test_file):
- command[findex] = test_input_dir + test_file
- error = False
+ elif os.path.exists(os.path.join(test_input_dir, test_file)):
+ command[findex] = os.path.join(test_input_dir, test_file)
+ try:
+ convert_idx = command.index('convert')
+ convert_file = command[convert_idx+1]
+ convert_data = example[self.testfile_token][self.testfile_token]
+ if not os.path.exists(convert_file):
+ with open(convert_file, 'w') as f:
+ f.write(convert_data)
+ except ValueError:
+ pass
+ error = None
try:
verify = subprocess.check_output(command, stderr=subprocess.STDOUT)
- except:
- verify = str()
- error = True
- valid = (output == verify) or (not error and validation)
+ valid = (output == verify) or (not error and validation)
+ except subprocess.CalledProcessError, e:
+ error = e.output
+ valid = False
+ failed.add(test_id)
if valid and test_file_created:
os.remove(test_file)
if self.verbose > 0:
- print test_id, ':', 'Passed' if valid else 'FAILED'
+ print test_id, ':', 'Passed' if valid else 'FAILED: {}'.format(error) if error else 'FAILED'
else:
sys.stdout.write('.' if valid else 'E')
- if not valid:
+ if not (valid or error):
failed.add(test_id)
if self.verbose > 1:
print ' '.join(command)
@@ -206,6 +212,12 @@ class DocTests:
for line in unified_diff(output.split('\n'), verify.split('\n'), fromfile='generated', tofile='expected'):
print(line)
print
+ else:
+ if self.verbose > 0:
+ print test_id, ':', 'Skipped'
+ else:
+ sys.stdout.write('X')
+
if not self.verbose:
print
if len(failed) > 0:
diff --git a/test/RegressTests.py b/test/RegressTests.py
index 0fef2127..a5bab42d 100755
--- a/test/RegressTests.py
+++ b/test/RegressTests.py
@@ -57,9 +57,6 @@ class RegressFile(object):
in_error = False
line = self.fd.readline()
- if not line:
- print >>sys.stderr, "WARNING: Empty testfile detected: %s" % (self.filename)
- return False
#print "line =", line
while line:
if line.startswith("test "):
@@ -167,6 +164,10 @@ class RegressFile(object):
harness.failure(os.path.basename(self.filename))
def run_tests(self):
+ if os.path.getsize(self.filename) == 0:
+ print >>sys.stderr, "WARNING: Empty testfile detected: %s" % (self.filename)
+ harness.failure(os.path.basename(self.filename))
+ return False
test = self.read_test()
while test:
self.run_test(test)
diff --git a/test/baseline/cmd-cleared.test b/test/baseline/cmd-cleared.test
index 501d207f..91219a40 100644
--- a/test/baseline/cmd-cleared.test
+++ b/test/baseline/cmd-cleared.test
@@ -30,7 +30,7 @@ test cleared
-20 0 F
-30 -30 12-Feb-26 G
-40 0 H
----------------- ---------------- ---------
+---------------- ---------------- ---------
0 0
end test
diff --git a/test/baseline/cmd-convert.test.disable b/test/baseline/cmd-convert.test
index d444da52..8ee5bb2e 100644
--- a/test/baseline/cmd-convert.test.disable
+++ b/test/baseline/cmd-convert.test
@@ -17,7 +17,7 @@ end test
test -f /dev/null --input-date-format "%m/%d/%Y" convert test/baseline/cmd-convert3.dat -> 1
__ERROR__
-While parsing file "$sourcepath/test/baseline/cmd-convert3.dat", line 1:
+While parsing file "$sourcepath/test/baseline/cmd-convert3.dat", line 1:
While parsing CSV line:
01/01/2011,,
@@ -26,7 +26,7 @@ end test
test -f /dev/null convert test/baseline/cmd-convert4.dat -> 1
__ERROR__
-While parsing file "$sourcepath/test/baseline/cmd-convert4.dat", line 1:
+While parsing file "$sourcepath/test/baseline/cmd-convert4.dat", line 1:
While parsing CSV line:
bogus,$10,
diff --git a/test/baseline/feat-fixated-prices_2.test b/test/baseline/dir-fixed.test
index ecbdfe9a..ecbdfe9a 100644
--- a/test/baseline/feat-fixated-prices_2.test
+++ b/test/baseline/dir-fixed.test
diff --git a/test/baseline/opt-auto-match.test b/test/baseline/opt-auto-match.test
index 7c3fb40a..54a1053b 100644
--- a/test/baseline/opt-auto-match.test
+++ b/test/baseline/opt-auto-match.test
@@ -14,17 +14,58 @@
Expenses:Food 20.00 EUR
Liabilities:CC -20.00 EUR
+test --input-date-format "%Y-%m-%d" convert test/baseline/opt-auto-match.dat
+2012/03/01 * Food
+ Expenses:Unknown 10
+ Equity:Unknown
+
+2012/03/02 * Phone
+ Expenses:Unknown 10
+ Equity:Unknown
+
+2012/03/02 * Dining
+ Expenses:Unknown 10
+ Equity:Unknown
+end test
+
test --input-date-format "%Y-%m-%d" --auto-match convert test/baseline/opt-auto-match.dat
2012/03/01 * Food
- Assets:Cash 10
+ Expenses:Food 10
Equity:Unknown
2012/03/02 * Phone
- Assets:Cash 10
+ Expenses:Phone 10
Equity:Unknown
2012/03/02 * Dining
- Liabilities:CC 10
+ Expenses:Food 10
Equity:Unknown
end test
+test --input-date-format "%Y-%m-%d" --account Assets:Bank convert test/baseline/opt-auto-match.dat
+2012/03/01 * Food
+ Expenses:Unknown 10
+ Assets:Bank
+
+2012/03/02 * Phone
+ Expenses:Unknown 10
+ Assets:Bank
+
+2012/03/02 * Dining
+ Expenses:Unknown 10
+ Assets:Bank
+end test
+
+test --input-date-format "%Y-%m-%d" --auto-match --account Assets:Bank convert test/baseline/opt-auto-match.dat
+2012/03/01 * Food
+ Expenses:Food 10
+ Assets:Bank
+
+2012/03/02 * Phone
+ Expenses:Phone 10
+ Assets:Bank
+
+2012/03/02 * Dining
+ Expenses:Food 10
+ Assets:Bank
+end test
diff --git a/test/baseline/opt-cleared-format.test b/test/baseline/opt-cleared-format.test
index e69de29b..4d3ea267 100644
--- a/test/baseline/opt-cleared-format.test
+++ b/test/baseline/opt-cleared-format.test
@@ -0,0 +1,20 @@
+test cleared --file test/input/drewr3.dat --cleared-format "%-30(account) %15(get_at(total_expr, 0)) %15(get_at(total_expr, 1))\n%/"
+Assets $ -3,804.00 $ 775.00
+Assets:Checking $ 1,396.00 $ 775.00
+Assets:Checking:Business $ 30.00 0
+Assets:Savings $ -5,200.00 0
+Equity:Opening Balances $ -1,000.00 $ -1,000.00
+Expenses $ 6,654.00 $ 225.00
+Expenses:Auto $ 5,500.00 0
+Expenses:Books $ 20.00 0
+Expenses:Escrow $ 300.00 0
+Expenses:Food:Groceries $ 334.00 $ 225.00
+Expenses:Interest:Mortgage $ 500.00 0
+Income $ -2,030.00 0
+Income:Salary $ -2,000.00 0
+Income:Sales $ -30.00 0
+Liabilities $ -63.60 0
+Liabilities:MasterCard $ -20.00 0
+Liabilities:Mortgage:Principal $ 200.00 0
+Liabilities:Tithe $ -243.60 0
+end test
diff --git a/test/baseline/opt-explicit.test b/test/baseline/opt-explicit.test
index defae179..20b74913 100644
--- a/test/baseline/opt-explicit.test
+++ b/test/baseline/opt-explicit.test
@@ -2,16 +2,18 @@ account Assets:Cash
account Expenses:Phone
account Expenses:Rent
commodity GBP
+tag bar
-2012-03-20 Phone
+2012-03-20 * Phone
+ ; :bar:
Expenses:Phone 20.00 GBP
Assets:Cash
-2012-03-21 Rent
+2012-03-21 * Rent
Expenses:Rent 550.00 GBP
Assets:Cash
-2012-03-22 Food
+2012-03-22 * Food
; :food:
Expenses:Food 20.00 EUR
Assets:Cash
@@ -27,8 +29,8 @@ test bal --explicit --strict
--------------------
0
__ERROR__
-Warning: "$FILE", line 16: Unknown account 'Expenses:Food'
-Warning: "$FILE", line 16: Unknown commodity 'EUR'
-Warning: "$FILE", line 17: Unknown metadata tag 'food'
+Warning: "$FILE", line 18: Unknown account 'Expenses:Food'
+Warning: "$FILE", line 18: Unknown commodity 'EUR'
+Warning: "$FILE", line 19: Unknown metadata tag 'food'
end test
diff --git a/test/baseline/opt-file.test.disable b/test/baseline/opt-file.test
index 66d0ab1b..66d0ab1b 100644
--- a/test/baseline/opt-file.test.disable
+++ b/test/baseline/opt-file.test
diff --git a/test/baseline/opt-generated.test b/test/baseline/opt-generated.test
deleted file mode 100644
index e69de29b..00000000
--- a/test/baseline/opt-generated.test
+++ /dev/null
diff --git a/test/baseline/opt-init-file.dat b/test/baseline/opt-init-file.dat
new file mode 100644
index 00000000..92c5307a
--- /dev/null
+++ b/test/baseline/opt-init-file.dat
@@ -0,0 +1 @@
+--decimal-comma
diff --git a/test/baseline/opt-init-file.test b/test/baseline/opt-init-file.test
new file mode 100644
index 00000000..128814e1
--- /dev/null
+++ b/test/baseline/opt-init-file.test
@@ -0,0 +1,10 @@
+2012-03-17 Quick
+ Expenses:Food 12,50 €
+ Assets:Cash
+
+test --init-file test/baseline/opt-init-file.dat bal
+ -12,50 € Assets:Cash
+ 12,50 € Expenses:Food
+--------------------
+ 0
+end test
diff --git a/test/baseline/opt-no-pager.test b/test/baseline/opt-no-pager.test
deleted file mode 100644
index e69de29b..00000000
--- a/test/baseline/opt-no-pager.test
+++ /dev/null
diff --git a/test/baseline/opt-no-revalued.test b/test/baseline/opt-no-revalued.test
new file mode 100644
index 00000000..487ffa30
--- /dev/null
+++ b/test/baseline/opt-no-revalued.test
@@ -0,0 +1,58 @@
+2009/01/01 Sample 1a
+ Assets:Brokerage:Stocks 100 S
+ Assets:Brokerage:Cash -100 P
+
+P 2009/01/01 00:00:00 S 2 P
+
+2009/02/01 Sample 2a
+ Assets:Brokerage:Stocks 100 S @ 1 P
+ Assets:Brokerage:Cash
+
+P 2009/02/01 00:00:00 S 4 P
+
+2009/03/01 Sample 3a
+ Assets:Brokerage:Stocks 100 S @@ 100 P
+ Assets:Brokerage:Cash
+
+P 2009/03/01 00:00:00 S 8 P
+
+2009/04/01 Sample 4a
+ Assets:Brokerage:Cash 100 P
+ Assets:Brokerage:Stocks -100 S {1 P}
+
+P 2009/04/01 00:00:00 S 16 P
+
+; In this usage case, the top amount is always secondary
+; 2010/01/01 Sample 1b
+; Assets:Brokerage:Cash -100 P
+; Assets:Brokerage:Stocks 100 S
+;
+; P 2010/01/01 00:00:00 S 2 P
+
+2010/02/01 Sample 2b
+ Assets:Brokerage:Cash
+ Assets:Brokerage:Stocks 100 S @ 1 P
+
+P 2010/02/01 00:00:00 S 4 P
+
+2010/03/01 Sample 3b
+ Assets:Brokerage:Cash
+ Assets:Brokerage:Stocks 100 S @@ 100 P
+
+P 2010/03/01 00:00:00 S 8 P
+
+2010/04/01 Sample 4b
+ Assets:Brokerage:Stocks -100 S {1 P}
+ Assets:Brokerage:Cash 100 P
+
+P 2010/04/01 00:00:00 S 16 P
+
+test reg --market --no-revalued stocks
+09-Jan-01 Sample 1a Asset:Brokerage:Stocks 200 P 200 P
+09-Feb-01 Sample 2a Asset:Brokerage:Stocks 400 P 800 P
+09-Mar-01 Sample 3a Asset:Brokerage:Stocks 800 P 2400 P
+09-Apr-01 Sample 4a Asset:Brokerage:Stocks -1600 P 3200 P
+10-Feb-01 Sample 2b Asset:Brokerage:Stocks 400 P 1200 P
+10-Mar-01 Sample 3b Asset:Brokerage:Stocks 800 P 3200 P
+10-Apr-01 Sample 4b Asset:Brokerage:Stocks -1600 P 4800 P
+end test
diff --git a/test/baseline/opt-no-rounding.test b/test/baseline/opt-no-rounding.test
index e69de29b..5d0758c6 100644
--- a/test/baseline/opt-no-rounding.test
+++ b/test/baseline/opt-no-rounding.test
@@ -0,0 +1,81 @@
+2012-01-01 * Opening balance
+ Assets:Current 17.43 EUR
+ Assets:Investments 200 "LU02" @ 24.77 EUR
+ Assets:Investments 58 "LU02" @ 24.79900855 EUR
+ Equity:Opening balance
+
+2012-01-01 * Opening balance
+ Assets:Pension 785.44 GBP
+ Assets:Pension 97.0017 "H2" @ 5.342999720204 GBP
+ Assets:Pension 4.3441 "H1" @ 5.289999915108 GBP
+ Equity:Opening balance
+
+2012-01-01 * Opening balance: misc
+ Assets:Piggy bank 3.51 GBP
+ Equity:Opening balance
+
+2012-01-01 * Opening balance
+ Assets:Rewards 9836 AAdvantage
+ Equity:Opening balance
+
+2012-01-03 * Receivable
+ Assets:Current
+ Assets:Receivable -161.06 EUR
+ Assets:Receivable -9.99 GBP @@ 11.65 EUR
+
+2012-01-27 * Test
+ Income:Test -2759.50 GBP
+ Income:Test -110.76 GBP
+ Assets:Foo 345.57 GBP
+ Expenses:Test 16.47 GBP
+ Expenses:Test 6.33 GBP
+ Expenses:Test 261.39 GBP
+ Assets:Current
+
+test reg -X EUR -H --no-rounding
+12-Jan-01 Opening balance Assets:Current 17.43 EUR 17.43 EUR
+ Assets:Investments 4959.80 EUR 4977.23 EUR
+ Assets:Investments 1438.34 EUR 6415.57 EUR
+ Equity:Opening balance -6409.77 EUR 5.80 EUR
+12-Jan-01 Opening balance Assets:Pension 785.44 GBP 5.80 EUR
+ 785.44 GBP
+ Assets:Pension 97.0017 H2 5.80 EUR
+ 785.44 GBP
+ 97.0017 H2
+ Assets:Pension 4.3441 H1 5.80 EUR
+ 785.44 GBP
+ 4.3441 H1
+ 97.0017 H2
+ Equity:Opening balance -1326.70 GBP 5.80 EUR
+ -541.26 GBP
+ 4.3441 H1
+ 97.0017 H2
+12-Jan-01 Opening balance: misc Assets:Piggy bank 3.51 GBP 5.80 EUR
+ -537.75 GBP
+ 4.3441 H1
+ 97.0017 H2
+ Equity:Opening balance -3.51 GBP 5.80 EUR
+ -541.26 GBP
+ 4.3441 H1
+ 97.0017 H2
+12-Jan-01 Opening balance Assets:Rewards 9836 AAdvantage 9836 AAdvantage
+ 5.80 EUR
+ -541.26 GBP
+ 4.3441 H1
+ 97.0017 H2
+ Equity:Opening balance -9836 AAdvantage 5.80 EUR
+ -541.26 GBP
+ 4.3441 H1
+ 97.0017 H2
+12-Jan-03 Commodities revalued <Revalued> 0 5.80 EUR
+12-Jan-03 Receivable Assets:Current 172.71 EUR 178.51 EUR
+ Assets:Receivable -161.06 EUR 17.45 EUR
+ Assets:Receivable -11.65 EUR 5.80 EUR
+12-Jan-27 Test Income:Test -3218.04 EUR -3212.23 EUR
+ Income:Test -129.16 EUR -3341.40 EUR
+ Assets:Foo 402.99 EUR -2938.41 EUR
+ Expenses:Test 19.21 EUR -2919.20 EUR
+ Expenses:Test 7.38 EUR -2911.82 EUR
+ Expenses:Test 304.82 EUR -2606.99 EUR
+ Assets:Current 2612.80 EUR 5.80 EUR
+end test
diff --git a/test/baseline/opt-price-db.dat b/test/baseline/opt-price-db.dat
new file mode 100644
index 00000000..abc51a0a
--- /dev/null
+++ b/test/baseline/opt-price-db.dat
@@ -0,0 +1,2 @@
+P 2012-03-16 06:47:12 CAD $2.50
+P 2012-03-17 06:47:12 CAD $3.50
diff --git a/test/baseline/opt-price-db.test b/test/baseline/opt-price-db.test
new file mode 100644
index 00000000..06021e4a
--- /dev/null
+++ b/test/baseline/opt-price-db.test
@@ -0,0 +1,8 @@
+2012-03-17 KFC
+ Expenses:Food 20 CAD
+ Assets:Cash
+
+test pricedb --price-db test/baseline/opt-price-db.dat
+P 2012/03/16 06:47:12 CAD $2.5
+P 2012/03/17 06:47:12 CAD $3.5
+end test
diff --git a/test/baseline/opt-rich-data.test b/test/baseline/opt-rich-data.test
index fbb73ebe..265af531 100644
--- a/test/baseline/opt-rich-data.test
+++ b/test/baseline/opt-rich-data.test
@@ -1,3 +1,13 @@
+test -f /dev/null convert test/baseline/feat-convert-with-directives.dat --now '2014/08/01'
+2012/01/01 * KFC
+ Expenses:Unknown $10
+ Equity:Unknown
+
+2012/01/02 * REWE SAGT DANKE 123454321
+ Expenses:Unknown 10€
+ Equity:Unknown
+end test
+
test -f /dev/null convert test/baseline/feat-convert-with-directives.dat --detail --now '2014/08/01'
2012/01/01 * KFC
; CSV: 2012/01/01,KFC,$10
diff --git a/test/baseline/opt-script.dat b/test/baseline/opt-script.dat
new file mode 100644
index 00000000..ac6085d5
--- /dev/null
+++ b/test/baseline/opt-script.dat
@@ -0,0 +1,3 @@
+--no-pager --columns=80 bal
+--no-pager --columns=80 reg
+--no-pager --columns=80 print
diff --git a/test/baseline/opt-script.test b/test/baseline/opt-script.test
new file mode 100644
index 00000000..041c15ee
--- /dev/null
+++ b/test/baseline/opt-script.test
@@ -0,0 +1,15 @@
+2012-03-17 KFC
+ Expenses:Food 20 CAD
+ Assets:Cash
+
+test --script test/baseline/opt-script.dat
+ -20 CAD Assets:Cash
+ 20 CAD Expenses:Food
+--------------------
+ 0
+12-Mar-17 KFC Expenses:Food 20 CAD 20 CAD
+ Assets:Cash -20 CAD 0
+2012/03/17 KFC
+ Expenses:Food 20 CAD
+ Assets:Cash
+end test
diff --git a/test/baseline/opt-value-expr.test b/test/baseline/opt-value-expr.test
index e69de29b..8b68a80e 100644
--- a/test/baseline/opt-value-expr.test
+++ b/test/baseline/opt-value-expr.test
@@ -0,0 +1,48 @@
+
+D 1000.00 EUR
+D 1000.00 USD
+D 1000.00 DM
+
+2015-01-01 * Buy 2 FOO
+ Assets:Investments 2 FOO @@ 20.00 EUR
+ Assets:Cash -20.00 EUR
+
+2015-05-01 * Spend on food
+ Expenses:Food 20.00 USD
+ ; Just to be silly, always valuate *these* $20 as 30 DM, no matter what
+ ; the user asks for with -V or -X
+ ; VALUE:: 30 DM
+ Assets:Cash -20.00 USD
+
+P 2015-05-01 USD 20 DM
+
+P 2015-06-01 USD 22 DM
+
+test bal assets:investments -V --value-expr "25.00 EUR"
+ 50.00 EUR Assets:Investments
+end test
+
+test bal assets:investments -G --value-expr "date < [March 2015] ? 22.00 EUR : 25.00 EUR" --now "2015-02-20"
+ 24.00 EUR Assets:Investments
+end test
+
+test bal assets:investments -G --value-expr "date < [March 2015] ? 22.00 EUR : 25.00 EUR" --now "2015-03-20"
+ 30.00 EUR Assets:Investments
+end test
+
+test bal expenses:food
+ 20.00 USD Expenses:Food
+end test
+
+test bal expenses:food -V
+ 600.00 DM Expenses:Food
+end test
+
+test bal expenses:food -X "DM" --now "2015-05-02"
+ 600.00 DM Expenses:Food
+end test
+
+test bal expenses:food -X "DM" --now "2015-06-02"
+ 600.00 DM Expenses:Food
+end test
+
diff --git a/test/baseline/opt-verify-memory.test b/test/baseline/opt-verify-memory.test
deleted file mode 100644
index e69de29b..00000000
--- a/test/baseline/opt-verify-memory.test
+++ /dev/null
diff --git a/test/convert.py b/test/convert.py
index 5328c4ae..857d4d30 100755
--- a/test/convert.py
+++ b/test/convert.py
@@ -3,7 +3,7 @@
# convert.py: This script converts a Boost.Test unit test into an
# equivalent Python unit test.
#
-# Copyright (c) 2003-2015, John Wiegley. All rights reserved.
+# Copyright (c) 2003-2016, 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
diff --git a/test/regress/1057.test b/test/regress/1057.test
new file mode 100644
index 00000000..1cd91ee7
--- /dev/null
+++ b/test/regress/1057.test
@@ -0,0 +1,11 @@
+2014/04/03 www.amazon.fr
+ Dépense:Loisir:Ordi:Matériel 101,50 € ; disque dur portable 2,5" 2000 Go
+ Dépense:Maison:Service:Poste
+ * Passif:Crédit:BanqueAccord -171,63 €
+
+test -f test/regress/1057.test --now=2014/06/27 emacs
+(("$sourcepath/test/regress/1057.test" 1 (21308 60112 0) nil "www.amazon.fr"
+ (2 "Dépense:Loisir:Ordi:Matériel" "101,50 €" nil " disque dur portable 2,5\" 2000 Go")
+ (3 "Dépense:Maison:Service:Poste" "70,13 €" nil)
+ (4 "Passif:Crédit:BanqueAccord" "-171,63 €" t)))
+end test
diff --git a/test/regress/25A099C9.test b/test/regress/25A099C9.test
new file mode 100644
index 00000000..cfc0eabd
--- /dev/null
+++ b/test/regress/25A099C9.test
@@ -0,0 +1,61 @@
+test -f test/garbage-input.dat reg -> 29
+__ERROR__
+While parsing file "$sourcepath/test/garbage-input.dat", line 1:
+Error: Directive '/*' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 32:
+Error: Directive '/**' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 36:
+Error: Directive '/**' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 66:
+Error: No quantity specified for amount
+While parsing file "$sourcepath/test/garbage-input.dat", line 69:
+Error: Unexpected whitespace at beginning of line
+While parsing file "$sourcepath/test/garbage-input.dat", line 78:
+Error: Directive '};' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 82:
+Error: Directive '/**' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 93:
+Error: Unexpected whitespace at beginning of line
+While parsing file "$sourcepath/test/garbage-input.dat", line 97:
+Error: Directive '{' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 98:
+Error: Directive 'public:' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 120:
+Error: Directive 'protected:' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 131:
+Error: Directive 'public:' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 711:
+Error: Unexpected whitespace at beginning of line
+While parsing file "$sourcepath/test/garbage-input.dat", line 740:
+Error: Directive 'private:' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 749:
+Error: Unexpected whitespace at beginning of line
+While parsing file "$sourcepath/test/garbage-input.dat", line 750:
+Error: Directive '};' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 752:
+Error: Invalid date/time: line amount_t amoun
+While parsing file "$sourcepath/test/garbage-input.dat", line 756:
+Error: Directive '}' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 758:
+Error: Invalid date/time: line string amount_
+While parsing file "$sourcepath/test/garbage-input.dat", line 762:
+Error: Directive '}' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 764:
+Error: Invalid date/time: line string amount_
+While parsing file "$sourcepath/test/garbage-input.dat", line 768:
+Error: Directive '}' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 770:
+Error: Invalid date/time: line string amount_
+While parsing file "$sourcepath/test/garbage-input.dat", line 774:
+Error: Directive '}' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 776:
+Error: Invalid date/time: line std::ostream&
+While parsing file "$sourcepath/test/garbage-input.dat", line 782:
+Error: Directive '}' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 783:
+Error: Invalid date/time: line std::istream&
+While parsing file "$sourcepath/test/garbage-input.dat", line 786:
+Error: Directive '}' requires an argument
+While parsing file "$sourcepath/test/garbage-input.dat", line 789:
+Error: Unexpected whitespace at beginning of line
+end test
diff --git a/test/regress/25A099C9.test.disable b/test/regress/25A099C9.test.disable
deleted file mode 100644
index e511c799..00000000
--- a/test/regress/25A099C9.test.disable
+++ /dev/null
@@ -1,43 +0,0 @@
-test -f test/garbage-input.dat reg -> 20
-__ERROR__
-While parsing file "$sourcepath/test/garbage-input.dat", line 2:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 33:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 37:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 66:
-Error: No quantity specified for amount
-While parsing file "$sourcepath/test/garbage-input.dat", line 69:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 83:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 93:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 99:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 121:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 132:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 711:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 741:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 749:
-Error: Unexpected whitespace at beginning of line
-While parsing file "$sourcepath/test/garbage-input.dat", line 752:
-Error: Invalid date/time: line amount_t amoun
-While parsing file "$sourcepath/test/garbage-input.dat", line 758:
-Error: Invalid date/time: line string amount_
-While parsing file "$sourcepath/test/garbage-input.dat", line 764:
-Error: Invalid date/time: line string amount_
-While parsing file "$sourcepath/test/garbage-input.dat", line 770:
-Error: Invalid date/time: line string amount_
-While parsing file "$sourcepath/test/garbage-input.dat", line 776:
-Error: Invalid date/time: line std::ostream&
-While parsing file "$sourcepath/test/garbage-input.dat", line 783:
-Error: Invalid date/time: line std::istream&
-While parsing file "$sourcepath/test/garbage-input.dat", line 789:
-Error: Unexpected whitespace at beginning of line
-end test
diff --git a/test/regress/8EAF77C0.test b/test/regress/8EAF77C0.test
index 9d63951d..074160cc 100644
--- a/test/regress/8EAF77C0.test
+++ b/test/regress/8EAF77C0.test
@@ -1,6 +1,6 @@
2011/08/05 Rehab Donation
Asset:Bank:Boi:Current:Dk 10
- Expense:Misc:Charity
+ Expenses:Misc:Charity
2011/08/07 Net Salary
Asset:Bank:Boi:Savings:Dk -3016.24
diff --git a/test/regress/AEDE9734.test b/test/regress/AEDE9734.test
index cd2245b8..81315779 100644
--- a/test/regress/AEDE9734.test
+++ b/test/regress/AEDE9734.test
@@ -1,12 +1,12 @@
2011-02-23 Rocket Fuel
- Expense:Travel $100000000.00 ; trip: Moon
+ Expenses:Travel $100000000.00 ; trip: Moon
Asset:NASA
2011-02-23 Liquid Oxygen
- Expense:Travel $232233223.00 ; trip: Moon
+ Expenses:Travel $232233223.00 ; trip: Moon
Asset:NASA
test bal --group-by "tag('trip')"
Moon
- $332233223.00 Expense:Travel
+ $332233223.00 Expenses:Travel
end test
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 23bb0ea4..9cacb4e7 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -1,15 +1,24 @@
macro(add_ledger_test _name)
target_link_libraries(${_name} libledger)
add_test(Ledger${_name} ${PROJECT_BINARY_DIR}/${_name})
+ set_tests_properties(Ledger${_name}
+ PROPERTIES ENVIRONMENT "TZ=${Ledger_TEST_TIMEZONE}")
endmacro(add_ledger_test _name)
include_directories(${PROJECT_SOURCE_DIR}/src)
if (BUILD_LIBRARY)
add_executable(UtilTests t_times.cc)
+ if (CMAKE_SYSTEM_NAME STREQUAL Darwin AND HAVE_BOOST_PYTHON)
+ target_link_libraries(UtilTests ${PYTHON_LIBRARIES})
+ endif()
add_ledger_test(UtilTests)
- add_executable(MathTests t_amount.cc t_commodity.cc t_balance.cc t_expr.cc)
+ add_executable(MathTests t_amount.cc t_commodity.cc t_balance.cc t_expr.cc t_value.cc)
+ set_source_files_properties(t_amount.cc t_value.cc PROPERTIES COMPILE_FLAGS "-Wno-unused-comparison")
+ if (CMAKE_SYSTEM_NAME STREQUAL Darwin AND HAVE_BOOST_PYTHON)
+ target_link_libraries(MathTests ${PYTHON_LIBRARIES})
+ endif()
add_ledger_test(MathTests)
set_target_properties(check PROPERTIES DEPENDS LedgerUtilTests)
diff --git a/test/unit/t_value.cc b/test/unit/t_value.cc
new file mode 100644
index 00000000..2daedcb1
--- /dev/null
+++ b/test/unit/t_value.cc
@@ -0,0 +1,711 @@
+#define BOOST_TEST_DYN_LINK
+
+#include <boost/test/unit_test.hpp>
+
+#include <system.hh>
+
+#include "value.h"
+
+using namespace ledger;
+
+struct value_fixture {
+ value_fixture() {
+ times_initialize();
+ amount_t::initialize();
+ value_t::initialize();
+
+
+ // Cause the display precision for dollars to be initialized to 2.
+ amount_t x1("$1.00");
+ BOOST_CHECK(x1);
+
+ amount_t::stream_fullstrings = true; // make reports from UnitTests accurate
+ }
+
+ ~value_fixture()
+ {
+ amount_t::stream_fullstrings = false;
+ amount_t::shutdown();
+ times_shutdown();
+ value_t::shutdown();
+ }
+};
+
+BOOST_FIXTURE_TEST_SUITE(value, value_fixture)
+
+BOOST_AUTO_TEST_CASE(testConstructors)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_t(NULL)));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(4UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("3 EUR"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("tag"), true);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testAssignment)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2 = true;
+ value_t v3 = boost::posix_time::from_time_t(time_t(NULL));
+ value_t v4 = date_t(parse_date("2014/08/14"));
+ value_t v5 = -2L;
+ value_t v6 = 4UL;
+ value_t v7 = 1.00;
+ value_t v8 = amount_t("4 GBP");
+ value_t v9 = balance_t("3 EUR");
+ value_t v10 = mask_t("regex");
+ value_t v11 = s1;
+ value_t v12 = value_t(string("$1"));
+ value_t v13 = value_t("2 CAD");
+ value_t v14 = value_t("comment", true);
+ value_t v15 = value_t(string("tag"), true);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testEquality)
+{
+ struct tm localtime;
+ strptime("10 February 2010", "%d %b %Y", &localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::ptime_from_tm(localtime));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(2UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16;
+
+ BOOST_CHECK_EQUAL(v1, value_t());
+ BOOST_CHECK_EQUAL(v2, value_t(true));
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::ptime_from_tm(localtime)));
+ BOOST_CHECK(!(v4 == value_t(date_t(parse_date("2014/08/15")))));
+
+ value_t v19(amount_t("2"));
+ value_t v20(balance_t("2"));
+ BOOST_CHECK_EQUAL(v5, v6);
+ BOOST_CHECK_EQUAL(v5, v19);
+ BOOST_CHECK_EQUAL(v5, v20);
+ BOOST_CHECK(v19 == v5);
+ BOOST_CHECK(v19 == v20);
+ BOOST_CHECK(v19 == value_t(amount_t("2")));
+ BOOST_CHECK(v20 == v5);
+ BOOST_CHECK(v20 == v19);
+ BOOST_CHECK(v20 == value_t(balance_t(2L)));
+ BOOST_CHECK(v14 == v15);
+ BOOST_CHECK(v10 == value_t(mask_t("regex")));
+ BOOST_CHECK(v11 == value_t(s1));
+
+ BOOST_CHECK_THROW(v8 == v10, value_error);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v19.valid());
+ BOOST_CHECK(v20.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testSequence)
+{
+ value_t::sequence_t s1;
+ value_t v1(s1);
+ BOOST_CHECK(v1.is_sequence());
+ v1.push_back(value_t(2L));
+ v1.push_back(value_t("3 GBP"));
+
+ value_t v2("3 GBP");
+ value_t seq(v1);
+ const value_t v3(seq);
+
+ value_t::sequence_t::iterator i = std::find(seq.begin(), seq.end(), v2);
+ if (i != seq.end())
+ BOOST_CHECK(v2 == *i);
+
+ value_t::sequence_t::const_iterator j = std::find(v3.begin(), v3.end(), v2);
+ if (j != v3.end())
+ BOOST_CHECK(v2 == *j);
+
+ BOOST_CHECK(v2 == seq[1]);
+ BOOST_CHECK(v2 == v3[1]);
+ v1.pop_back();
+ v1.pop_back();
+ v1.push_front(v2);
+ v1.push_front(value_t(2L));
+ BOOST_CHECK(v2 == v1[1]);
+ BOOST_CHECK(seq == v1);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(seq.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testAddition)
+{
+ struct tm localtime;
+ strptime("10 February 2010 00:00:00", "%d %b %Y %H:%M:%S", &localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::ptime_from_tm(localtime));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(2UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16(amount_t("2"));
+
+ v14 += v15;
+ BOOST_CHECK_EQUAL(v14, value_t(string("commentcomment"), true));
+ v14 += v12;
+ BOOST_CHECK_EQUAL(v14, value_t(string("commentcomment$1.00"), true));
+
+ strptime("10 February 2010 00:00:00", "%d %b %Y %H:%M:%S", &localtime);
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::ptime_from_tm(localtime)));
+ v3 += value_t(2L);
+ strptime("10 February 2010 00:00:02", "%d %b %Y %H:%M:%S", &localtime);
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::ptime_from_tm(localtime)));
+ v3 += value_t(amount_t("2"));
+ strptime("10 February 2010 00:00:04", "%d %b %Y %H:%M:%S", &localtime);
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::ptime_from_tm(localtime)));
+
+ v4 += value_t(2L);
+ BOOST_CHECK_EQUAL(v4, value_t(date_t(parse_date("2014/08/16"))));
+ v4 += value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v4, value_t(date_t(parse_date("2014/08/18"))));
+
+ v5 += value_t(2L);
+ BOOST_CHECK_EQUAL(v5, value_t(4L));
+ v5 += value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, value_t(amount_t("6")));
+ v5 += v8;
+
+ v16 += value_t(2L);
+ v16 += value_t(amount_t("2"));
+ v16 += v8;
+ BOOST_CHECK_EQUAL(v5, v16);
+
+ v8 += value_t("6");
+ BOOST_CHECK_EQUAL(v8, v16);
+
+ value_t v17(6L);
+ v17 += value_t(amount_t("4 GBP"));
+ BOOST_CHECK_EQUAL(v8, v17);
+
+ value_t v18(6L);
+ v18 += v9;
+ value_t v19(amount_t("6"));
+ v19 += v9;
+ BOOST_CHECK_EQUAL(v18, v19);
+
+ v9 += value_t(2L);
+ v9 += value_t(amount_t("4"));
+ v9 += v19;
+ v18 += v19;
+ BOOST_CHECK_EQUAL(v9, v18);
+
+ value_t v20(s1);
+ v11 += value_t(2L);
+ v11 += value_t("4 GBP");
+ BOOST_CHECK_THROW(v11 += v20,value_error);
+ BOOST_CHECK_THROW(v10 += v8, value_error);
+
+ v20 += value_t(2L);
+ v20 += value_t("4 GBP");
+ BOOST_CHECK_EQUAL(v11, v20);
+ v11 += v20;
+ v20 += v20;
+ BOOST_CHECK_EQUAL(v11, v20);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v16.valid());
+ BOOST_CHECK(v17.valid());
+ BOOST_CHECK(v18.valid());
+ BOOST_CHECK(v19.valid());
+ BOOST_CHECK(v20.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testSubtraction)
+{
+ struct tm localtime;
+ strptime("10 February 2010 00:00:04", "%d %b %Y %H:%M:%S", &localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::ptime_from_tm(localtime));
+ value_t v4(date_t(parse_date("2014/08/18")));
+ value_t v5(6L);
+ value_t v6(6UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16(amount_t("6"));
+
+ v3 -= value_t(2L);
+ strptime("10 February 2010 00:00:02", "%d %b %Y %H:%M:%S", &localtime);
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::ptime_from_tm(localtime)));
+ v3 -= value_t(amount_t("2"));
+ strptime("10 February 2010 00:00:00", "%d %b %Y %H:%M:%S", &localtime);
+ BOOST_CHECK_EQUAL(v3, value_t(boost::posix_time::ptime_from_tm(localtime)));
+
+ v4 -= value_t(2L);
+ BOOST_CHECK_EQUAL(v4, value_t(date_t(parse_date("2014/08/16"))));
+ v4 -= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v4, value_t(date_t(parse_date("2014/08/14"))));
+
+ v5 -= value_t(2L);
+ BOOST_CHECK_EQUAL(v5, value_t(4L));
+ v5 -= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, value_t(amount_t("2")));
+ v5 -= v8;
+
+ v16 -= value_t(2L);
+ v16 -= value_t(amount_t("2"));
+ v16 -= v8;
+ BOOST_CHECK_EQUAL(v5, v16);
+
+ v8 -= value_t("2");
+ BOOST_CHECK_EQUAL(-v8, v16);
+
+ value_t v18(6L);
+ v18 -= v9;
+ value_t v19(amount_t("6"));
+ v19 -= v9;
+ BOOST_CHECK_EQUAL(v18, v19);
+
+ v9 -= value_t(-2L);
+ v9 -= value_t(amount_t("-10"));
+ v9 -= value_t(amount_t("12 GBP"));
+ v9 -= v19;
+ BOOST_CHECK_EQUAL(v9, v18);
+ v18 -=v19;
+ BOOST_CHECK_EQUAL(v18, value_t("0"));
+
+ value_t v20(s1);
+ value_t v21(2L);
+ value_t v22("4 GBP");
+ v11.push_back(v21);
+ v11.push_back(v22);
+ BOOST_CHECK_THROW(v11 -= v20,value_error);
+ BOOST_CHECK_THROW(v10 -= v8, value_error);
+
+ v20.push_back(v21);
+ v20.push_back(v22);
+ v11 -= v20;
+ value_t v23(s1);
+ v23.push_back(value_t(0L));
+ v23.push_back(value_t("0"));
+ BOOST_CHECK_EQUAL(v11, v23);
+ v20 -= v21;
+ v20 -= v22;
+ BOOST_CHECK_EQUAL(v20, value_t(s1));
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v16.valid());
+ BOOST_CHECK(v18.valid());
+ BOOST_CHECK(v19.valid());
+ BOOST_CHECK(v20.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testMultiplication)
+{
+ struct tm localtime;
+ strptime("10 February 2010 00:00:00", "%d %b %Y %H:%M:%S", &localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::ptime_from_tm(localtime));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(2UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16(amount_t("2"));
+
+ v14 *= value_t(2L);
+ BOOST_CHECK_EQUAL(v14, value_t(string("commentcomment"), true));
+
+ v5 *= value_t(2L);
+ BOOST_CHECK_EQUAL(v5, value_t(4L));
+ v5 *= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, value_t(amount_t("8")));
+
+ v16 *= value_t(2L);
+ v16 *= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, v16);
+
+ v8 *= v9;
+ BOOST_CHECK_EQUAL(v8, value_t("16 GBP"));
+
+ value_t v17(v9);
+ v9 *= value_t(2L);
+ BOOST_CHECK_EQUAL(v9, value_t("8 GBP"));
+ v17 += value_t(2L);
+ v17 *= value_t(2L);
+ value_t v18("8 GBP");
+ v18 += value_t(4L);
+ BOOST_CHECK_EQUAL(v17, v18);
+
+ value_t v20(s1);
+ v11.push_back(value_t(2L));
+ v11.push_back(value_t("2 GBP"));
+ v20.push_back(value_t(4L));
+ v20.push_back(value_t("4 GBP"));
+ v11 *= value_t(2L);
+ BOOST_CHECK_EQUAL(v11 ,v20);
+
+ BOOST_CHECK_THROW(v10 *= v8, value_error);
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v16.valid());
+ BOOST_CHECK(v17.valid());
+ BOOST_CHECK(v18.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testDivision)
+{
+ struct tm localtime;
+ strptime("10 February 2010 00:00:00", "%d %b %Y %H:%M:%S", &localtime);
+ value_t::sequence_t s1;
+
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::ptime_from_tm(localtime));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(8L);
+ value_t v6(2UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+ value_t v16(amount_t("8"));
+
+ v5 /= value_t(2L);
+ BOOST_CHECK_EQUAL(v5, value_t(4L));
+ v5 /= value_t(amount_t("8"));
+ BOOST_CHECK_EQUAL(v5, value_t(amount_t("2")));
+
+ v16 /= value_t(2L);
+ v16 /= value_t(amount_t("2"));
+ BOOST_CHECK_EQUAL(v5, v16);
+
+ v8 /= v9;
+ v8 /= value_t(balance_t(2L));
+ BOOST_CHECK_EQUAL(v8, value_t("0.5 GBP"));
+
+ value_t v17(v9);
+ v9 /= value_t(2L);
+ BOOST_CHECK_EQUAL(v9, value_t("2 GBP"));
+ v17 /= value_t("2 GBP");
+ v17 /= value_t("2");
+ BOOST_CHECK_EQUAL(v17, value_t(balance_t("1 GBP")));
+
+ BOOST_CHECK_THROW(v10 /= v8, value_error);
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+ BOOST_CHECK(v16.valid());
+ BOOST_CHECK(v17.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testType)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_t(NULL)));
+ value_t v4(date_t(parse_date("2014/08/14")));
+ value_t v5(2L);
+ value_t v6(4UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("3 EUR"));
+ value_t v10(mask_t("regex"));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string("tag"), true);
+
+ BOOST_CHECK(v1.is_null());
+ BOOST_CHECK(v2.is_boolean());
+ BOOST_CHECK(v3.is_datetime());
+ BOOST_CHECK(v4.is_date());
+ BOOST_CHECK(v5.is_long());
+ BOOST_CHECK(v6.is_amount());
+ BOOST_CHECK(v7.is_amount());
+ BOOST_CHECK(v8.is_amount());
+ BOOST_CHECK(v9.is_balance());
+ BOOST_CHECK(v10.is_mask());
+ BOOST_CHECK(v11.is_sequence());
+ BOOST_CHECK(v12.is_amount());
+ BOOST_CHECK(v13.is_amount());
+ BOOST_CHECK(v14.is_string());
+ BOOST_CHECK(v15.is_string());
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testForZero)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_t(NULL)));
+ value_t v4(date_t(0));
+ value_t v5(2L);
+ value_t v6(0UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("0"));
+ value_t v10(mask_t(""));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("2 CAD");
+ value_t v14("comment", true);
+ value_t v15(string(""), true);
+
+ BOOST_CHECK(v1.is_null());
+ BOOST_CHECK(v2.is_nonzero());
+ BOOST_CHECK(!v3.is_zero());
+ BOOST_CHECK(v4.is_nonzero());
+ BOOST_CHECK(v5.is_nonzero());
+ BOOST_CHECK(v6.is_realzero());
+ BOOST_CHECK(v7.is_nonzero());
+ BOOST_CHECK(v8.is_nonzero());
+ BOOST_CHECK(v9.is_zero());
+ BOOST_CHECK_THROW(v10.is_zero(), value_error);
+ BOOST_CHECK(v11.is_zero());
+ BOOST_CHECK(v12.is_nonzero());
+ BOOST_CHECK(v13.is_nonzero());
+ BOOST_CHECK(v14.is_nonzero());
+ BOOST_CHECK(v15.is_zero());
+
+ v11.push_back(v6);
+ BOOST_CHECK(v11.is_nonzero());
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_CASE(testNegation)
+{
+ value_t::sequence_t s1;
+ value_t v1;
+ value_t v2(true);
+ value_t v3(boost::posix_time::from_time_t(time_t(NULL)));
+ value_t v4(date_t(parse_date("2014/08/09")));
+ value_t v5(2L);
+ value_t v6(0UL);
+ value_t v7(1.00);
+ value_t v8(amount_t("4 GBP"));
+ value_t v9(balance_t("4 GBP"));
+ value_t v10(mask_t(""));
+ value_t v11(s1);
+ value_t v12(string("$1"));
+ value_t v13("$-1");
+ value_t v14("comment", true);
+ value_t v15(string("comment"), true);
+
+ BOOST_CHECK_THROW(v1.negated(), value_error);
+ BOOST_CHECK_EQUAL(v2.negated(), value_t(false));
+ v5.in_place_negate();
+ BOOST_CHECK_EQUAL(v5, value_t(-2L));
+ v8.in_place_negate();
+ v9.in_place_negate();
+ BOOST_CHECK_EQUAL(v8, v9);
+ BOOST_CHECK_THROW(v10.negated(), value_error);
+ BOOST_CHECK_EQUAL(-v12, v13);
+ BOOST_CHECK_THROW(-v14, value_error);
+
+ BOOST_CHECK(v1.valid());
+ BOOST_CHECK(v2.valid());
+ BOOST_CHECK(v3.valid());
+ BOOST_CHECK(v4.valid());
+ BOOST_CHECK(v5.valid());
+ BOOST_CHECK(v6.valid());
+ BOOST_CHECK(v7.valid());
+ BOOST_CHECK(v8.valid());
+ BOOST_CHECK(v9.valid());
+ BOOST_CHECK(v10.valid());
+ BOOST_CHECK(v11.valid());
+ BOOST_CHECK(v12.valid());
+ BOOST_CHECK(v13.valid());
+ BOOST_CHECK(v14.valid());
+ BOOST_CHECK(v15.valid());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+