summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt12
-rwxr-xr-xtest/CheckBaselineTests.py26
-rw-r--r--test/CheckComments.py46
-rwxr-xr-xtest/CheckManpage.py24
-rwxr-xr-xtest/CheckOptions.py29
-rwxr-xr-xtest/CheckTexinfo.py24
-rwxr-xr-xtest/ConfirmTests.py26
-rwxr-xr-xtest/DocTests.py3
-rwxr-xr-xtest/GenerateTests.py41
-rwxr-xr-xtest/LedgerHarness.py90
-rwxr-xr-xtest/RegressTests.py141
-rw-r--r--test/baseline/feat-value_py.test (renamed from test/baseline/feat-value_py3.test)0
-rw-r--r--test/baseline/feat-value_py2.test23
-rwxr-xr-xtest/convert.py2
-rw-r--r--test/manual/transaction-notes-1.test11
-rw-r--r--test/python/JournalTest.py2
-rw-r--r--test/python/PostingTest.py2
-rw-r--r--test/python/TransactionTest.py2
-rw-r--r--test/regress/1182_2.test2
-rw-r--r--test/regress/B21BF389.py3
-rw-r--r--test/unit/t_expr.cc4
21 files changed, 225 insertions, 288 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 301959db..25d91a9e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -19,19 +19,11 @@ macro(add_ledger_harness_tests _class)
file(GLOB ${_class}_TESTS *.test)
foreach(TestFile ${${_class}_TESTS})
get_filename_component(TestFile_Name ${TestFile} NAME_WE)
- string(FIND ${TestFile_Name} "_py" TestFile_IsPythonTest)
- if ((TestFile_IsPythonTest GREATER -1))
- get_filename_component(TestFile_FullName ${TestFile} NAME)
- string(FIND ${TestFile_FullName} "_py.test" TestFile_IsAnyPythonTest)
- string(FIND ${TestFile_FullName} "_py${Python_VERSION_MAJOR}.test" TestFile_IsThisPythonTest)
- if ((TestFile_IsAnyPythonTest EQUAL -1) AND (TestFile_IsThisPythonTest EQUAL -1))
- continue()
- endif()
- endif()
+ string(FIND ${TestFile_Name} "_py.test" TestFile_IsPythonTest)
if ((TestFile_IsPythonTest EQUAL -1) OR HAVE_BOOST_PYTHON)
add_test(NAME ${_class}Test_${TestFile_Name}
COMMAND ${Python_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test/RegressTests.py
- $<TARGET_FILE:ledger> ${PROJECT_SOURCE_DIR}
+ --ledger $<TARGET_FILE:ledger> --sourcepath ${PROJECT_SOURCE_DIR}
${TestFile} ${TEST_PYTHON_FLAGS})
set_tests_properties(${_class}Test_${TestFile_Name}
PROPERTIES ENVIRONMENT "TZ=${Ledger_TEST_TIMEZONE}")
diff --git a/test/CheckBaselineTests.py b/test/CheckBaselineTests.py
index fa9fa2bc..1a983b00 100755
--- a/test/CheckBaselineTests.py
+++ b/test/CheckBaselineTests.py
@@ -1,10 +1,9 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
+import argparse
import sys
import re
import os
-import argparse
from os.path import *
from subprocess import Popen, PIPE
@@ -52,24 +51,9 @@ class CheckBaselineTests (CheckOptions):
return errors
if __name__ == "__main__":
- def getargs():
- parser = argparse.ArgumentParser(prog='CheckBaselineTests',
- description='Check that ledger options are tested')
- parser.add_argument('-l', '--ledger',
- dest='ledger',
- type=str,
- action='store',
- required=True,
- help='the path to the ledger executable to test with')
- parser.add_argument('-s', '--source',
- dest='source',
- type=str,
- action='store',
- required=True,
- help='the path to the top level ledger source directory')
- return parser.parse_args()
-
- args = getargs()
+ args = argparse.ArgumentParser(prog='CheckBaselineTests',
+ description='Check that ledger options are tested',
+ parents=[CheckOptions.parser()]).parse_args()
script = CheckBaselineTests(args)
status = script.main()
sys.exit(status)
diff --git a/test/CheckComments.py b/test/CheckComments.py
index 446137b0..9bcfcbb3 100644
--- a/test/CheckComments.py
+++ b/test/CheckComments.py
@@ -1,20 +1,19 @@
+#!/usr/bin/env python3
+
import sys
import re
import os
+import argparse
-ok = 100.0
-if sys.argv[1] == '-l':
- ok = float(sys.argv[2])
- sys.argv = [sys.argv[0]] + sys.argv[3:]
-
-debug = False
-if sys.argv[1] == '-v':
- debug = True
- sys.argv = [sys.argv[0]] + sys.argv[2:]
+parser = argparse.ArgumentParser( prog='CheckComments')
+parser.add_argument('-v', '--debug', dest='debug', action='store_true')
+parser.add_argument('-l', '--limit', dest='ok', type=float, default=100.0)
+parser.add_argument('path', nargs='+', help='Path to source file to check comments')
+args = parser.parse_args()
errors = 0
-for path in sys.argv[1:]:
+for path in args.path:
other_depth = 0
brace_depth = 0
code_count = 0
@@ -26,6 +25,7 @@ for path in sys.argv[1:]:
ctor_dtor = False
linenum = 0
+ print(f'checking {path}')
fd = open(path, 'r')
for line in fd.readlines():
linenum += 1
@@ -48,48 +48,48 @@ for path in sys.argv[1:]:
match = re.search('(namespace|enum|class|struct|union)', line)
if match:
kind = match.group(1)
- if debug: print "kind =", kind
+ if args.debug: print("kind =", kind)
elif kind == "function":
match = re.search('(\S+)\(', line)
if match:
function_name = match.group(1)
long_comments[function_name] = comment_count
comment_count = 0
- if debug: print "name found %s" % function_name
+ if args.debug: print("name found %s" % function_name)
if re.search('{', line) and not re.search('@{', line):
if kind == "function":
brace_depth += 1
- if debug: print "brace_depth =", brace_depth
+ if args.debug: print("brace_depth =", brace_depth)
else:
other_depth += 1
kind = "function"
- if debug: print "other_depth =", other_depth
+ if args.debug: print("other_depth =", other_depth)
if re.search('}', line) and not re.search('@}', line):
if brace_depth > 0:
brace_depth -= 1
- if debug: print "brace_depth =", brace_depth
+ if args.debug: print("brace_depth =", brace_depth)
if brace_depth == 0:
- if debug: print "function done"
+ if args.debug: print("function done")
if function_name in long_comments:
comment_count += long_comments[function_name]
if code_count == 0:
- percent = ok
- print "%7s %4d/%4d %s:%d: %s" % \
+ percent = args.ok
+ print("%7s %4d/%4d %s:%d: %s" % \
("empty", comment_count, code_count,
os.path.basename(path), linenum,
- function_name)
+ function_name))
errors += 1
else:
percent = 100.0 * (float(comment_count) /
float(code_count))
- if percent < ok and not ctor_dtor:
- print "%6.0f%% %4d/%4d %s:%d: %s" % \
+ if percent < args.ok and not ctor_dtor:
+ print("%6.0f%% %4d/%4d %s:%d: %s" % \
(percent, comment_count, code_count,
os.path.basename(path), linenum,
- function_name)
+ function_name))
errors += 1
code_count = 0
comment_count = 0
@@ -98,7 +98,7 @@ for path in sys.argv[1:]:
ctor_dtor = False
else:
other_depth -= 1
- if debug: print "other_depth =", other_depth
+ if args.debug: print("other_depth =", other_depth)
if brace_depth > 0:
if re.search("TRACE_[CD]TOR", line):
diff --git a/test/CheckManpage.py b/test/CheckManpage.py
index 3da9d872..1795b77e 100755
--- a/test/CheckManpage.py
+++ b/test/CheckManpage.py
@@ -1,5 +1,4 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
import sys
import re
@@ -20,24 +19,9 @@ class CheckManpage (CheckOptions):
self.source_type = 'manpage'
if __name__ == "__main__":
- def getargs():
- parser = argparse.ArgumentParser(prog='CheckManpage',
- description='Check that ledger options are documented in the manpage')
- parser.add_argument('-l', '--ledger',
- dest='ledger',
- type=str,
- action='store',
- required=True,
- help='the path to the ledger executable to test with')
- parser.add_argument('-s', '--source',
- dest='source',
- type=str,
- action='store',
- required=True,
- help='the path to the top level ledger source directory')
- return parser.parse_args()
-
- args = getargs()
+ args = argparse.ArgumentParser(prog='CheckManpage',
+ description='Check that ledger options are documented in the manpage'
+ parents=[CheckOptions.parser()]).parse_args()
script = CheckManpage(args)
status = script.main()
sys.exit(status)
diff --git a/test/CheckOptions.py b/test/CheckOptions.py
index 3f08fb0d..cdd9b244 100755
--- a/test/CheckOptions.py
+++ b/test/CheckOptions.py
@@ -1,10 +1,10 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
import re
import os
import sys
import shlex
+import pathlib
import argparse
import subprocess
@@ -12,6 +12,15 @@ from os.path import *
from subprocess import Popen, PIPE
class CheckOptions (object):
+ @staticmethod
+ def parser():
+ parser = argparse.ArgumentParser(add_help=False)
+ parser.add_argument('-l', '--ledger', type=pathlib.Path, required=True,
+ help='the path to the ledger executable to test with')
+ parser.add_argument('-s', '--source', type=pathlib.Path, required=True,
+ help='the path to the top level ledger source directory')
+ return parser
+
def __init__(self, args):
self.option_pattern = None
self.source_file = None
@@ -40,7 +49,7 @@ class CheckOptions (object):
for source_file in ['session', 'report']:
command.append(os.path.join(self.source, 'src', '%s.cc' % source_file))
try:
- output = subprocess.check_output(command).split('\n');
+ output = subprocess.check_output(command, universal_newlines=True).split('\n')
except subprocess.CalledProcessError:
output = ''
@@ -58,7 +67,7 @@ class CheckOptions (object):
def ledger_functions(self):
command = shlex.split('grep --no-filename fn_ %s' % (os.path.join(self.source, 'src', 'report.h')))
try:
- output = subprocess.check_output(command).split('\n');
+ output = subprocess.check_output(command, universal_newlines=True).split('\n');
except subprocess.CalledProcessError:
output = ''
@@ -74,7 +83,13 @@ class CheckOptions (object):
else:
options.remove(option)
known_alternates = self.find_alternates()
- self.unknown_options = {option for option in options if option not in known_alternates}
+ self.unknown_options = options - known_alternates
+ self.missing_options -= {
+ # The option --explicit is a no-op as of March 2020 and is
+ # therefore intentionally undocumented.
+ # For details see commit 43b07fbab3b4c144eca4a771524e59c531ffa074
+ 'explicit'
+ }
functions = self.find_functions(self.source_file)
for function in self.ledger_functions():
@@ -82,8 +97,8 @@ class CheckOptions (object):
self.missing_functions.add(function)
else:
functions.remove(function)
- known_functions = ['tag', 'has_tag', 'meta', 'has_meta']
- self.unknown_functions = {function for function in functions if function not in known_functions}
+ known_functions = {'tag', 'has_tag', 'meta', 'has_meta'}
+ self.unknown_functions = functions - known_functions
if len(self.missing_options):
print("Missing %s option entries for:%s%s\n" % (self.source_type, self.sep, self.sep.join(sorted(list(self.missing_options)))))
diff --git a/test/CheckTexinfo.py b/test/CheckTexinfo.py
index fa709e1b..7b13c50e 100755
--- a/test/CheckTexinfo.py
+++ b/test/CheckTexinfo.py
@@ -1,5 +1,4 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
import sys
import re
@@ -91,24 +90,9 @@ class CheckTexinfo (CheckOptions):
return options
if __name__ == "__main__":
- def getargs():
- parser = argparse.ArgumentParser(prog='CheckTexinfo',
- description='Check that ledger options are documented in the texinfo manual')
- parser.add_argument('-l', '--ledger',
- dest='ledger',
- type=str,
- action='store',
- required=True,
- help='the path to the ledger executable to test with')
- parser.add_argument('-s', '--source',
- dest='source',
- type=str,
- action='store',
- required=True,
- help='the path to the top level ledger source directory')
- return parser.parse_args()
-
- args = getargs()
+ args = argparse.ArgumentParser(prog='CheckTexinfo',
+ description='Check that ledger options are documented in the texinfo manual',
+ parents=[CheckOptions.parser()]).parse_args()
script = CheckTexinfo(args)
status = script.main()
sys.exit(status)
diff --git a/test/ConfirmTests.py b/test/ConfirmTests.py
index e82479ed..54187130 100755
--- a/test/ConfirmTests.py
+++ b/test/ConfirmTests.py
@@ -1,20 +1,24 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# This script confirms both that the register report "adds up", and that its
# final balance is the same as what the balance report shows.
+import argparse
+import pathlib
import sys
import os
import re
from LedgerHarness import LedgerHarness
-harness = LedgerHarness(sys.argv)
-tests = sys.argv[3]
+parser = argparse.ArgumentParser(prog='ConfirmTests', parents=[LedgerHarness.parser()])
+parser.add_argument('tests', type=pathlib.Path)
+args = parser.parse_args()
+harness = LedgerHarness(args.ledger, args.sourcepath, args.verify, args.gmalloc, args.python)
-if not os.path.isdir(tests) and not os.path.isfile(tests):
- sys.stderr.write("'%s' is not a directory or file (cwd %s)" %
- (tests, os.getcwd()))
+if not os.path.isdir(args.tests) and not os.path.isfile(args.tests):
+ print(f'{args.tests} is not a directory or file (cwd: {os.getcwd()})'
+ , file=sys.stderr)
sys.exit(1)
commands = [
@@ -56,8 +60,8 @@ def confirm_report(command):
if re.search(' -[VGB] ', command) and diff < 0.015:
diff = 0.0
if diff > 0.001:
- print("DISCREPANCY: %.3f (%.3f - %.3f) at line %d:" % \)
- (running_total - total, running_total, total, index)
+ print("DISCREPANCY: %.3f (%.3f - %.3f) at line %d:" % \
+ (running_total - total, running_total, total, index))
print(line,)
running_total = total
failure = True
@@ -78,15 +82,15 @@ def confirm_report(command):
diff = 0.0
if diff > 0.001:
print()
- print("DISCREPANCY: %.3f (%.3f - %.3f) between register and balance" % \)
- (balance_total - running_total, balance_total, running_total)
+ print("DISCREPANCY: %.3f (%.3f - %.3f) between register and balance" % \
+ (balance_total - running_total, balance_total, running_total))
print(last_line,)
failure = True
return not failure
for cmd in commands:
- if confirm_report('$ledger --rounding $cmd ' + re.sub('\$tests', tests, cmd)):
+ if confirm_report('$ledger --rounding $cmd ' + re.sub('\$tests', str(args.tests), cmd)):
harness.success()
else:
harness.failure()
diff --git a/test/DocTests.py b/test/DocTests.py
index daecdd90..e12a4ae4 100755
--- a/test/DocTests.py
+++ b/test/DocTests.py
@@ -1,5 +1,4 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
from io import open
diff --git a/test/GenerateTests.py b/test/GenerateTests.py
index 2b966e35..1301bcd0 100755
--- a/test/GenerateTests.py
+++ b/test/GenerateTests.py
@@ -1,9 +1,12 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# This script confirms both that the register report "adds up", and that its
# final balance is the same as what the balance report shows.
+import argparse
+import pathlib
import sys
+import os
import re
from difflib import ndiff
@@ -15,19 +18,21 @@ try:
except:
pass
-args = sys.argv
-jobs = 1
-match = re.match('-j([0-9]+)?', args[1])
-if match:
- args = [args[0]] + args[2:]
- if match.group(1):
- jobs = int(match.group(1))
-if jobs == 1:
- multiproc = False
-
from LedgerHarness import LedgerHarness
-harness = LedgerHarness(args)
+parser = argparse.ArgumentParser(prog='GenerateTests', parents=[LedgerHarness.parser()])
+parser.add_argument('-j', '--jobs', type=int, default=1)
+parser.add_argument('tests', type=pathlib.Path)
+parser.add_argument('beg_range', nargs='?', type=int, default=1)
+parser.add_argument('end_range', nargs='?', type=int, default=20)
+args = parser.parse_args()
+multiproc &= (args.jobs >= 1)
+harness = LedgerHarness(args.ledger, args.sourcepath, args.verify, args.gmalloc, args.python)
+
+if not os.path.isdir(args.tests) and not os.path.isfile(args.tests):
+ print(f'{args.tests} is not a directory or file (cwd: {os.getcwd()})'
+ , file=sys.stderr)
+ sys.exit(1)
#def normalize(line):
# match = re.match("((\s*)([A-Za-z]+)?(\s*)([-0-9.]+)(\s*)([A-Za-z]+)?)( (.+))?$", line)
@@ -123,12 +128,6 @@ def generation_test(seed):
return success
-beg_range = 1
-end_range = 20
-if len(args) > 4:
- beg_range = int(args[3])
- end_range = int(args[4])
-
def run_gen_test(i):
if generation_test(i):
harness.success()
@@ -137,14 +136,14 @@ def run_gen_test(i):
return harness.failed
if multiproc:
- pool = Pool(jobs*2)
+ pool = Pool(args.jobs*2)
else:
pool = None
if pool:
- pool.map(run_gen_test, range(beg_range, end_range))
+ pool.map(run_gen_test, range(args.beg_range, args.end_range))
else:
- for i in range(beg_range, end_range):
+ for i in range(args.beg_range, args.end_range):
run_gen_test(i)
if pool:
diff --git a/test/LedgerHarness.py b/test/LedgerHarness.py
index 5051fc8b..e2c96894 100755
--- a/test/LedgerHarness.py
+++ b/test/LedgerHarness.py
@@ -1,6 +1,8 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
+import argparse
+import pathlib
+import shlex
import sys
import os
import re
@@ -34,27 +36,36 @@ copyreg.pickle(types.MethodType, _pickle_method, _unpickle_method)
class LedgerHarness:
ledger = None
sourcepath = None
+ skipped = 0
succeeded = 0
failed = 0
verify = False
gmalloc = False
python = False
- def __init__(self, argv):
- if not os.path.isfile(argv[1]):
- print("Cannot find ledger at '%s'" % argv[1])
+ @staticmethod
+ def parser():
+ parser = argparse.ArgumentParser(add_help=False)
+ parser.add_argument('-l', '--ledger', type=pathlib.Path, required=True)
+ parser.add_argument('-s', '--sourcepath', type=pathlib.Path, required=True)
+ parser.add_argument('--verify', action='store_true')
+ parser.add_argument('--gmalloc', action='store_true')
+ parser.add_argument('--python', action='store_true')
+ return parser
+
+ def __init__(self, ledger, sourcepath, verify=False, gmalloc=False, python=False):
+ if not ledger.is_file():
+ print("Cannot find ledger at '{ledger}'", file=sys.stderr)
sys.exit(1)
- if not os.path.isdir(argv[2]):
- print("Cannot find source path at '%s'" % argv[2])
+ if not sourcepath.is_dir():
+ print("Cannot find source path at '{sourcepath}'", file=sys.stderr)
sys.exit(1)
- self.ledger = os.path.realpath(argv[1])
- self.sourcepath = os.path.realpath(argv[2])
- self.succeeded = 0
- self.failed = 0
- self.verify = '--verify' in argv
- self.gmalloc = '--gmalloc' in argv
- self.python = '--python' in argv
+ self.ledger = ledger.resolve()
+ self.sourcepath = sourcepath.resolve()
+ self.verify = verify
+ self.gmalloc = gmalloc
+ self.python = python
def run(self, command, verify=None, gmalloc=None, columns=True):
env = os.environ.copy()
@@ -71,34 +82,29 @@ class LedgerHarness:
env['MALLOC_FILL_SPACE'] = '1'
env['MALLOC_STRICT_SIZE'] = '1'
+ cmd = [str(self.ledger), '--args-only']
if (verify is not None and verify) or \
(verify is None and self.verify):
- insert = ' --verify'
- else:
- insert = ''
-
+ cmd.append('--verify')
if columns:
- insert += ' --columns=80'
-
- command = command.replace('$ledger', '"%s"%s %s' % \
- (self.ledger, insert, '--args-only'))
+ cmd.append('--columns=80')
+ command = command.replace('$ledger', shlex.join(cmd))
valgrind = '/usr/bin/valgrind'
if not os.path.isfile(valgrind):
valgrind = '/opt/local/bin/valgrind'
- if os.path.isfile(valgrind) and '--verify' in insert:
- command = valgrind + ' -q ' + command
+ if os.path.isfile(valgrind) and '--verify' in cmd:
+ command = shlex.join([valgrind, '-q', command])
- # If we are running under msys2, use bash to execute the test commands
- if 'MSYSTEM' in os.environ:
+ ismsys2 = 'MSYSTEM' in os.environ
+ if ismsys2:
+ # If we are running under msys2, use bash to execute the test commands
bash_path = os.environ['MINGW_PREFIX'] + '/../usr/bin/bash.exe'
- return Popen([bash_path, '-c', command], shell=False,
- close_fds=False, env=env, stdin=PIPE, stdout=PIPE,
- stderr=PIPE, cwd=self.sourcepath)
+ command = shlex.join([bash_path, '-c', command])
- return Popen(command, shell=True, close_fds=True, env=env,
- stdin=PIPE, stdout=PIPE, stderr=PIPE,
+ return Popen(command, shell=not ismsys2, close_fds=not ismsys2,
+ env=env, stdin=PIPE, stdout=PIPE, stderr=PIPE,
cwd=self.sourcepath)
def read(self, fd):
@@ -113,10 +119,7 @@ class LedgerHarness:
def readlines(self, fd):
lines = []
for line in fd.readlines():
- if sys.version_info.major == 2:
- line = unicode(line, 'utf-8')
- else:
- line = line.decode('utf-8')
+ line = line.decode('utf-8')
if not line.startswith('GuardMalloc'):
lines.append(line)
return lines
@@ -134,6 +137,11 @@ class LedgerHarness:
sys.stdout.flush()
self.succeeded += 1
+ def skip(self):
+ sys.stdout.write("S")
+ sys.stdout.flush()
+ self.skipped += 1
+
def failure(self, name=None):
sys.stdout.write("E")
if name:
@@ -144,16 +152,20 @@ class LedgerHarness:
def exit(self):
print()
if self.succeeded > 0:
- print("OK (%d) " % self.succeeded,)
+ print(f"OK ({self.succeeded})")
+ if self.skipped > 0:
+ print(f"SKIPPED ({self.skipped})")
if self.failed > 0:
- print("FAILED (%d)" % self.failed,)
+ print(f"FAILED ({self.failed})")
print()
sys.exit(self.failed)
if __name__ == '__main__':
- harness = LedgerHarness(sys.argv)
- proc = harness.run('$ledger -f doc/sample.dat reg')
+ parser = argparse.ArgumentParser(prog='LedgerHarness', parents=[LedgerHarness.parser()])
+ args = LedgerHarness.parser().parse_args()
+ harness = LedgerHarness(args.ledger, args.sourcepath, args.verify, args.gmalloc, args.python)
+ proc = harness.run('$ledger -f test/input/sample.dat reg')
print('STDOUT:')
print(proc.stdout.read())
print('STDERR:')
diff --git a/test/RegressTests.py b/test/RegressTests.py
index 849c4137..47abc3d0 100755
--- a/test/RegressTests.py
+++ b/test/RegressTests.py
@@ -1,8 +1,9 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
from io import open
+import argparse
+import pathlib
import sys
import os
import re
@@ -19,22 +20,16 @@ from difflib import unified_diff
from LedgerHarness import LedgerHarness
-args = sys.argv
-jobs = 1
-match = re.match('-j([0-9]+)?', args[1])
-if match:
- args = [args[0]] + args[2:]
- if match.group(1):
- jobs = int(match.group(1))
-if jobs == 1:
- multiproc = False
-
-harness = LedgerHarness(args)
-tests = args[3]
-
-if not os.path.isdir(tests) and not os.path.isfile(tests):
- sys.stderr.write("'%s' is not a directory or file (cwd %s)" %
- (tests, os.getcwd()))
+parser = argparse.ArgumentParser(prog='RegressTests', parents=[LedgerHarness.parser()])
+parser.add_argument('-j', '--jobs', type=int, default=1)
+parser.add_argument('tests', type=pathlib.Path)
+args = parser.parse_args()
+multiproc &= (args.jobs >= 1)
+harness = LedgerHarness(args.ledger, args.sourcepath, args.verify, args.gmalloc, args.python)
+
+if not args.tests.is_dir() and not args.tests.is_file():
+ print(f'{args.tests} is not a directory or file (cwd: {os.getcwd()})'
+ , file=sys.stderr)
sys.exit(1)
class RegressFile(object):
@@ -43,33 +38,31 @@ class RegressFile(object):
self.fd = open(self.filename, encoding='utf-8')
def transform_line(self, line):
- line = line.replace('$sourcepath', harness.sourcepath)
- line = line.replace('$FILE', os.path.realpath(self.filename))
- return line
+ return line\
+ .replace('$sourcepath', str(harness.sourcepath))\
+ .replace('$FILE', str(self.filename.resolve()))
def read_test(self):
- test = {
- 'command': None,
- 'output': None,
- 'error': None,
- 'exitcode': 0
- }
+ class Test:
+ command = None
+ output = None
+ error = None
+ exitcode = 0
in_output = False
in_error = False
line = self.fd.readline()
- if sys.version_info.major == 2 and type(line) is str:
- line = unicode(line, 'utf-8')
+ test = Test()
while line:
if line.startswith("test "):
command = line[5:]
match = re.match('(.*) -> ([0-9]+)', command)
if match:
- test['command'] = self.transform_line(match.group(1))
- test['exitcode'] = int(match.group(2))
+ test.command = self.transform_line(match.group(1))
+ test.exitcode = int(match.group(2))
else:
- test['command'] = command
+ test.command = command
in_output = True
elif in_output:
@@ -77,57 +70,50 @@ class RegressFile(object):
in_output = in_error = False
break
elif in_error:
- if test['error'] is None:
- test['error'] = []
- test['error'].append(self.transform_line(line))
+ if test.error is None:
+ test.error = []
+ test.error.append(self.transform_line(line))
else:
if line.startswith("__ERROR__"):
in_error = True
else:
- if test['output'] is None:
- test['output'] = []
- test['output'].append(self.transform_line(line))
-
+ if test.output is None:
+ test.output = []
+ test.output.append(self.transform_line(line))
line = self.fd.readline()
- if sys.version_info.major == 2 and type(line) is str:
- line = unicode(line, 'utf-8')
#print("line =", line)
- return test['command'] and test
+ return test.command and test
def notify_user(self, msg, test):
print(msg)
print("--")
- print(self.transform_line(test['command']),)
+ print(self.transform_line(test.command),)
print("--")
def run_test(self, test):
use_stdin = False
if sys.platform == 'win32':
- test['command'] = test['command'].replace('/dev/null', 'nul')
+ test.command = test.command.replace('/dev/null', 'nul')
# There is no equivalent to /dev/stdout, /dev/stderr, /dev/stdin
# on Windows, so skip tests that require them.
- if '/dev/std' in test['command']:
- harness.success()
+ if '/dev/std' in test.command:
+ harness.skipped()
return
- if test['command'].find("-f ") != -1:
- test['command'] = '$ledger ' + test['command']
- if re.search("-f (-|/dev/stdin)(\s|$)", test['command']):
+ if test.command.find('-f ') != -1:
+ test.command = '$ledger ' + test.command
+ if re.search('-f (-|/dev/stdin)(\s|$)', test.command):
use_stdin = True
else:
- test['command'] = (('$ledger -f "%s" ' %
- os.path.realpath(self.filename)) +
- test['command'])
+ test.command = f'$ledger -f "{str(self.filename.resolve())}" {test.command}'
- p = harness.run(test['command'],
- columns=(not re.search('--columns', test['command'])))
+ p = harness.run(test.command,
+ columns=(not re.search('--columns', test.command)))
if use_stdin:
fd = open(self.filename, encoding='utf-8')
try:
- stdin = fd.read()
- if sys.version_info.major > 2:
- stdin = stdin.encode('utf-8')
+ stdin = fd.read().encode('utf-8')
p.stdin.write(stdin)
finally:
fd.close()
@@ -136,9 +122,9 @@ class RegressFile(object):
success = True
printed = False
index = 0
- if test['output'] is not None:
+ if test.output is not None:
process_output = harness.readlines(p.stdout)
- expected_output = test['output']
+ expected_output = test.output
if sys.platform == 'win32':
process_output = [l.replace('\r\n', '\n').replace('\\', '/')
for l in process_output]
@@ -155,21 +141,19 @@ class RegressFile(object):
self.notify_user("FAILURE in output from %s:" % self.filename, test)
success = False
printed = True
- if sys.version_info.major == 2 and type(line) is str:
- line = unicode(line, 'utf-8')
print(' ', line,)
printed = False
index = 0
process_error = harness.readlines(p.stderr)
- if test['error'] is not None or process_error is not None:
- if test['error'] is None:
- test['error'] = []
+ if test.error is not None or process_error is not None:
+ if test.error is None:
+ test.error = []
if sys.platform == 'win32':
process_error = [l.replace('\r\n', '\n').replace('\\', '/')
for l in process_error]
- test['error'] = [l.replace('\\', '/') for l in test['error']]
- for line in unified_diff(test['error'], process_error):
+ test.error = [l.replace('\\', '/') for l in test.error]
+ for line in unified_diff(test.error, process_error):
index += 1
if index < 3:
continue
@@ -181,24 +165,24 @@ class RegressFile(object):
printed = True
print(" ", line,)
- if test['exitcode'] == p.wait():
+ if test.exitcode == p.wait():
if success:
harness.success()
else:
- harness.failure(os.path.basename(self.filename))
+ harness.failure(self.filename.name)
print("STDERR:")
print(p.stderr.read())
else:
if success: print
self.notify_user("FAILURE in exit code (%d != %d) from %s:"
- % (test['exitcode'], p.returncode, self.filename),
+ % (test.exitcode, p.returncode, self.filename),
test)
- harness.failure(os.path.basename(self.filename))
+ harness.failure(self.filename.name)
def run_tests(self):
if os.path.getsize(self.filename) == 0:
print("WARNING: Empty testfile detected: %s" % (self.filename), file=sys.stderr)
- harness.failure(os.path.basename(self.filename))
+ harness.failure(self.filename.name)
return False
test = self.read_test()
while test:
@@ -215,22 +199,21 @@ def do_test(path):
if __name__ == '__main__':
if multiproc:
- pool = Pool(jobs*2)
+ pool = Pool(args.jobs*2)
else:
pool = None
- if os.path.isdir(tests):
- tests = [os.path.join(tests, x)
- for x in os.listdir(tests)
- if (x.endswith('.test') and
- (not '_py.test' in x or (harness.python and
- not harness.verify)))]
+ if args.tests.is_dir():
+ tests = [p for p in args.tests.iterdir()
+ if (p.suffix == '.test' and
+ (not p.match('*_py.test') or (harness.python and
+ not harness.verify)))]
if pool:
pool.map(do_test, tests, 1)
else:
map(do_test, tests)
else:
- entry = RegressFile(tests)
+ entry = RegressFile(args.tests)
entry.run_tests()
entry.close()
diff --git a/test/baseline/feat-value_py3.test b/test/baseline/feat-value_py.test
index f82fbf2b..f82fbf2b 100644
--- a/test/baseline/feat-value_py3.test
+++ b/test/baseline/feat-value_py.test
diff --git a/test/baseline/feat-value_py2.test b/test/baseline/feat-value_py2.test
deleted file mode 100644
index 4378c91a..00000000
--- a/test/baseline/feat-value_py2.test
+++ /dev/null
@@ -1,23 +0,0 @@
-python
- def print_type(val):
- print(type(val), val)
-
-eval print_type(true)
-eval print_type([2010/08/10])
-eval print_type(10)
-eval print_type($10.00)
-eval print_type($10.00 + CAD 30)
-eval print_type("Hello!")
-eval print_type(/Hello!/)
-;eval print_type((1, 2, 3))
-
-test reg
-<type 'bool'> True
-<type 'datetime.date'> 2010-08-10
-<class 'ledger.Amount'> 10
-<class 'ledger.Amount'> $10.00
-<class 'ledger.Balance'> $10.00
-CAD 30
-<type 'unicode'> Hello!
-<class 'ledger.Value'> Hello!
-end test
diff --git a/test/convert.py b/test/convert.py
index 85e52701..a54edaac 100755
--- a/test/convert.py
+++ b/test/convert.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# convert.py: This script converts a Boost.Test unit test into an
# equivalent Python unit test.
diff --git a/test/manual/transaction-notes-1.test b/test/manual/transaction-notes-1.test
index 05ab3412..4085a6e2 100644
--- a/test/manual/transaction-notes-1.test
+++ b/test/manual/transaction-notes-1.test
@@ -2,14 +2,14 @@
Expenses:Food $4.50
Assets:Checking
-2009/11/01 Panera Bread
+2009/11/02 Panera Bread
; Type: Coffee
; Let’s see, I ate a whole bunch of stuff, drank some coffee,
; pondered a bagel, then decided against the donut.
Expenses:Food $4.50
Assets:Checking
-2009/11/01 Panera Bread
+2009/11/03 Panera Bread
; Type: Dining
; :Eating:
; This is another long note, after the metadata.
@@ -18,5 +18,10 @@
test reg --columns=60 food and note eat
09-Nov-01 Panera Bread Expenses:Food $4.50 $4.50
-09-Nov-01 Panera Bread Expenses:Food $4.50 $9.00
+09-Nov-03 Panera Bread Expenses:Food $4.50 $9.00
+end test
+
+test reg --columns=60 food and =eat
+09-Nov-01 Panera Bread Expenses:Food $4.50 $4.50
+09-Nov-03 Panera Bread Expenses:Food $4.50 $9.00
end test
diff --git a/test/python/JournalTest.py b/test/python/JournalTest.py
index 84ad2f43..59442968 100644
--- a/test/python/JournalTest.py
+++ b/test/python/JournalTest.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
import unittest
diff --git a/test/python/PostingTest.py b/test/python/PostingTest.py
index 0dd18112..f6b9bc04 100644
--- a/test/python/PostingTest.py
+++ b/test/python/PostingTest.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
import unittest
import operator
diff --git a/test/python/TransactionTest.py b/test/python/TransactionTest.py
index c87f8c4b..12069389 100644
--- a/test/python/TransactionTest.py
+++ b/test/python/TransactionTest.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
import unittest
import operator
diff --git a/test/regress/1182_2.test b/test/regress/1182_2.test
index d3c88dd8..6c018e94 100644
--- a/test/regress/1182_2.test
+++ b/test/regress/1182_2.test
@@ -13,5 +13,5 @@ __ERROR__
While parsing file "$FILE", line 5:
While parsing automated transaction:
> ============
-Error: Expected predicate after '='
+Error: note operator not followed by argument
end test
diff --git a/test/regress/B21BF389.py b/test/regress/B21BF389.py
index 11208e91..e130b7b3 100644
--- a/test/regress/B21BF389.py
+++ b/test/regress/B21BF389.py
@@ -1,5 +1,4 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
import sys
import ledger
diff --git a/test/unit/t_expr.cc b/test/unit/t_expr.cc
index c10ee029..ff30b3ed 100644
--- a/test/unit/t_expr.cc
+++ b/test/unit/t_expr.cc
@@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(testPredicateTokenizer6)
#ifndef NOT_FOR_PYTHON
query_t::lexer_t tokens(args.begin(), args.end());
- BOOST_CHECK_EQUAL(query_t::lexer_t::token_t::TOK_EQ, tokens.next_token().kind);
+ BOOST_CHECK_EQUAL(query_t::lexer_t::token_t::TOK_NOTE, tokens.next_token().kind);
BOOST_CHECK_EQUAL(query_t::lexer_t::token_t::TERM, tokens.next_token().kind);
BOOST_CHECK_EQUAL(query_t::lexer_t::token_t::TOK_AND, tokens.next_token().kind);
BOOST_CHECK_EQUAL(query_t::lexer_t::token_t::TERM, tokens.next_token().kind);
@@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(testPredicateTokenizer7)
#ifndef NOT_FOR_PYTHON
query_t::lexer_t tokens(args.begin(), args.end());
- BOOST_CHECK_EQUAL(query_t::lexer_t::token_t::TOK_EQ, tokens.next_token().kind);
+ BOOST_CHECK_EQUAL(query_t::lexer_t::token_t::TOK_NOTE, tokens.next_token().kind);
BOOST_CHECK_EQUAL(query_t::lexer_t::token_t::TERM, tokens.next_token().kind);
BOOST_CHECK_EQUAL(query_t::lexer_t::token_t::END_REACHED, tokens.next_token().kind);
#endif