diff options
Diffstat (limited to 'test')
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() + |