summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/CheckManpage.py1
-rwxr-xr-xtest/CheckOptions.py70
-rwxr-xr-xtest/CheckTexinfo.py41
-rwxr-xr-xtest/DocTests.py6
-rw-r--r--test/baseline/opt-permissive.test19
-rw-r--r--test/regress/634AA589.test19
6 files changed, 115 insertions, 41 deletions
diff --git a/test/CheckManpage.py b/test/CheckManpage.py
index 6b0f2476..944f4e07 100755
--- a/test/CheckManpage.py
+++ b/test/CheckManpage.py
@@ -17,6 +17,7 @@ class CheckManpage (CheckOptions):
def __init__(self, args):
CheckOptions.__init__(self, args)
self.option_pattern = '\.It Fl \\\\-([-A-Za-z]+)'
+ self.function_pattern = '\.It Fn ([-A-Za-z_]+)'
self.source_file = join(self.source, 'doc', 'ledger.1')
self.source_type = 'manpage'
diff --git a/test/CheckOptions.py b/test/CheckOptions.py
index 57d711db..5059a289 100755
--- a/test/CheckOptions.py
+++ b/test/CheckOptions.py
@@ -3,10 +3,12 @@
from __future__ import print_function
-import sys
import re
import os
+import sys
+import shlex
import argparse
+import subprocess
from os.path import *
from subprocess import Popen, PIPE
@@ -20,22 +22,32 @@ class CheckOptions (object):
self.ledger = os.path.abspath(args.ledger)
self.source = os.path.abspath(args.source)
- self.missing_baseline_tests = set()
self.missing_options = set()
self.unknown_options = set()
+ self.missing_functions = set()
+ self.unknown_functions = set()
- self.known_alternates = [
- 'cost',
- 'first',
- 'import',
- 'last',
- 'leeway',
- 'period-sort'
- ]
+ def find_pattern(self, filename, pattern):
+ regex = re.compile(pattern)
+ return {match.group(1) for match in {regex.match(line) for line in open(filename)} if match}
def find_options(self, filename):
- regex = re.compile(self.option_pattern)
- return {match.group(1) for match in {regex.match(line) for line in open(filename)} if match}
+ return self.find_pattern(filename, self.option_pattern)
+
+ def find_functions(self, filename):
+ return self.find_pattern(filename, self.function_pattern)
+ def find_alternates(self):
+ command = shlex.split('grep --no-filename OPT_ALT')
+ 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');
+ except subprocess.CalledProcessError:
+ output = ''
+
+ regex = re.compile(r'OPT_ALT\([^,]*,\s*([^)]+?)_?\)');
+ alternates = {match.group(1).replace('_', '-') for match in {regex.search(line) for line in output} if match}
+ return alternates
def ledger_options(self):
pipe = Popen('%s --debug option.names parse true' %
@@ -44,21 +56,43 @@ class CheckOptions (object):
ledger_options = {match.group(1).replace('_', '-') for match in {regex.search(line.decode()) for line in pipe.stderr} if match}
return ledger_options
+ 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');
+ except subprocess.CalledProcessError:
+ output = ''
+
+ regex = re.compile(r'fn_([^(]+)\(');
+ functions = {match.group(1) for match in {regex.search(line) for line in output} if match}
+ return functions
+
def main(self):
options = self.find_options(self.source_file)
-
for option in self.ledger_options():
if option not in options:
self.missing_options.add(option)
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 = {option for option in options if option not in self.known_alternates}
+ functions = self.find_functions(self.source_file)
+ for function in self.ledger_functions():
+ if function not in functions:
+ self.missing_functions.add(function)
+ else:
+ functions.remove(function)
+ known_functions = ['tag', 'has_tag']
+ self.unknown_functions = {function for function in functions if function not in known_functions}
if len(self.missing_options):
- print("Missing %s entries for:%s%s\n" % (self.source_type, self.sep, self.sep.join(sorted(list(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)))))
if len(self.unknown_options):
- print("%s entry for unknown options:%s%s" % (self.source_type, self.sep, self.sep.join(sorted(list(self.unknown_options)))))
-
- errors = len(self.missing_options) + len(self.unknown_options)
+ print("%s entry for unknown options:%s%s\n" % (self.source_type, self.sep, self.sep.join(sorted(list(self.unknown_options)))))
+ if len(self.missing_functions):
+ print("Missing %s function entries for:%s%s\n" % (self.source_type, '\n ', '\n '.join(sorted(list(self.missing_functions)))))
+ if len(self.unknown_functions):
+ print("%s entry for unknown functions:%s%s\n" % (self.source_type, '\n ', '\n '.join(sorted(list(self.unknown_functions)))))
+ errors = len(self.missing_options) + len(self.unknown_options) + len(self.missing_functions) + len(self.unknown_functions)
return errors
diff --git a/test/CheckTexinfo.py b/test/CheckTexinfo.py
index 34d0e153..cd167eba 100755
--- a/test/CheckTexinfo.py
+++ b/test/CheckTexinfo.py
@@ -16,10 +16,47 @@ from CheckOptions import CheckOptions
class CheckTexinfo (CheckOptions):
def __init__(self, args):
CheckOptions.__init__(self, args)
- self.option_pattern = '@item --([-A-Za-z]+).*@c option'
+ self.option_pattern = '^@item\s+--([-A-Za-z]+)'
+ self.function_pattern = '^@defun\s+([-A-Za-z_]+)'
self.source_file = join(self.source, 'doc', 'ledger3.texi')
self.source_type = 'texinfo'
+
+ def find_functions(self, filename):
+ functions = set()
+ state_normal = 0
+ state_function = 1
+ state = state_normal
+ function = None
+ fun_doc = str()
+ fun_example = False
+ item_regex = re.compile(self.function_pattern)
+ itemx_regex = re.compile('^@defunx')
+ example_regex = re.compile('^@smallexample\s+@c\s+command:')
+ fix_regex = re.compile('FIX')
+ comment_regex = re.compile('^\s*@c')
+ for line in open(filename):
+ line = line.strip()
+ if state == state_normal:
+ match = item_regex.match(line)
+ if match:
+ state = state_function
+ function = match.group(1)
+ elif state == state_function:
+ if line == '@end defun':
+ if function and fun_example and len(fun_doc) and not fix_regex.search(fun_doc):
+ functions.add(function)
+ state = state_normal
+ fun_example = None
+ fun_doc = str()
+ elif itemx_regex.match(line):
+ continue
+ elif example_regex.match(line):
+ fun_example = True
+ elif not comment_regex.match(line):
+ fun_doc += line
+ return functions
+
def find_options(self, filename):
options = set()
state_normal = 0
@@ -27,7 +64,7 @@ class CheckTexinfo (CheckOptions):
state = state_normal
option = None
opt_doc = str()
- item_regex = re.compile('^@item --([-A-Za-z]+)')
+ item_regex = re.compile(self.option_pattern)
itemx_regex = re.compile('^@itemx')
fix_regex = re.compile('FIX')
comment_regex = re.compile('^\s*@c')
diff --git a/test/DocTests.py b/test/DocTests.py
index d3434b43..cbad9ca7 100755
--- a/test/DocTests.py
+++ b/test/DocTests.py
@@ -4,6 +4,7 @@
import os
import re
import sys
+import shlex
import hashlib
import argparse
import subprocess
@@ -33,6 +34,7 @@ class DocTests:
line = self.file.readline()
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("@}","}")
return example
@@ -111,11 +113,11 @@ class DocTests:
else:
return None
- command = command.rstrip().split()
+ command = shlex.split(command)
if command[0] == '$': command.remove('$')
index = command.index('ledger')
command[index] = self.ledger
- for i,argument in enumerate('--args-only --columns 80'.split()):
+ for i,argument in enumerate(shlex.split('--args-only --columns 80')):
command.insert(index+i+1, argument)
try:
diff --git a/test/baseline/opt-permissive.test b/test/baseline/opt-permissive.test
index e69de29b..8f8ff031 100644
--- a/test/baseline/opt-permissive.test
+++ b/test/baseline/opt-permissive.test
@@ -0,0 +1,19 @@
+
+; The option --permissive quiets balance assertions
+
+2014-05-01 * Opening balance
+ Assets:Cash $100
+ Equity:Opening balance
+
+2014-05-10 * Spend money
+ Expenses:Foo $10
+ Assets:Cash -$10 = $80
+
+test bal --permissive
+ $90 Assets:Cash
+ $-100 Equity:Opening balance
+ $10 Expenses:Foo
+--------------------
+ 0
+end test
+
diff --git a/test/regress/634AA589.test b/test/regress/634AA589.test
deleted file mode 100644
index 8f8ff031..00000000
--- a/test/regress/634AA589.test
+++ /dev/null
@@ -1,19 +0,0 @@
-
-; The option --permissive quiets balance assertions
-
-2014-05-01 * Opening balance
- Assets:Cash $100
- Equity:Opening balance
-
-2014-05-10 * Spend money
- Expenses:Foo $10
- Assets:Cash -$10 = $80
-
-test bal --permissive
- $90 Assets:Cash
- $-100 Equity:Opening balance
- $10 Expenses:Foo
---------------------
- 0
-end test
-