Skip to content

Commit

Permalink
Unit tests: use fprettify as a module instead of relying on subprocesses
Browse files Browse the repository at this point in the history
  • Loading branch information
pseewald committed Oct 3, 2022
1 parent fae7d60 commit b9c5e7d
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 56 deletions.
55 changes: 25 additions & 30 deletions fprettify/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1915,23 +1915,24 @@ def log_message(message, level, filename, line_nr):
logger_to_use = getattr(logger, level)
logger_to_use(message, extra=logger_d)

def build_ws_dict(args):
"""helper function to build whitespace dictionary"""
ws_dict = {}
ws_dict['comma'] = args.whitespace_comma
ws_dict['assignments'] = args.whitespace_assignment
ws_dict['decl'] = args.whitespace_decl
ws_dict['relational'] = args.whitespace_relational
ws_dict['logical'] = args.whitespace_logical
ws_dict['plusminus'] = args.whitespace_plusminus
ws_dict['multdiv'] = args.whitespace_multdiv
ws_dict['print'] = args.whitespace_print
ws_dict['type'] = args.whitespace_type
ws_dict['intrinsics'] = args.whitespace_intrinsics
return ws_dict

def process_args(args):

def build_ws_dict(args):
"""helper function to build whitespace dictionary"""
ws_dict = {}
ws_dict['comma'] = args.whitespace_comma
ws_dict['assignments'] = args.whitespace_assignment
ws_dict['decl'] = args.whitespace_decl
ws_dict['relational'] = args.whitespace_relational
ws_dict['logical'] = args.whitespace_logical
ws_dict['plusminus'] = args.whitespace_plusminus
ws_dict['multdiv'] = args.whitespace_multdiv
ws_dict['print'] = args.whitespace_print
ws_dict['type'] = args.whitespace_type
ws_dict['intrinsics'] = args.whitespace_intrinsics
return ws_dict

args_out = {}

args_out['whitespace_dict'] = build_ws_dict(args)
Expand Down Expand Up @@ -1959,18 +1960,18 @@ def process_args(args):

return args_out

def str2bool(str):
"""helper function to convert strings to bool"""
if str.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif str.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
return None


def get_arg_parser(args={}):
"""helper function to create the parser object"""

def str2bool(str):
"""helper function to convert strings to bool"""
if str.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif str.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
return None

parser = argparse.ArgumentParser(**args)

parser.add_argument("-i", "--indent", type=int, default=3,
Expand Down Expand Up @@ -2046,13 +2047,9 @@ def get_arg_parser(args={}):
return parser



def run(argv=sys.argv): # pragma: no cover
"""Command line interface"""




def get_config_file_list(filename):
"""helper function to create list of config files found in parent directories"""
config_file_list = []
Expand All @@ -2075,7 +2072,6 @@ def get_config_file_list(filename):
arguments['args_for_setting_config_path'] = ['-c', '--config-file']
arguments['description'] = arguments['description'] + " Config files ('.fprettify.rc') in the home (~) directory and any such files located in parent directories of the input file will be used. When the standard input is used, the search is started from the current directory."


parser = get_arg_parser(arguments)

args = parser.parse_args(argv[1:])
Expand Down Expand Up @@ -2132,7 +2128,6 @@ def get_config_file_list(filename):
filearguments['default_config_files'] = ['~/.fprettify.rc'] + get_config_file_list(os.path.abspath(filename) if filename != '-' else os.getcwd())
file_argparser = get_arg_parser(filearguments)


args_tmp = file_argparser.parse_args(argv[1:])
file_args = process_args(args_tmp)
file_args['stdout'] = args_tmp.stdout or directory == '-'
Expand Down
70 changes: 44 additions & 26 deletions fprettify/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,34 @@ def joinpath(path1, path2):
MYPATH = os.path.dirname(os.path.abspath(
inspect.getfile(inspect.currentframe())))

TIMESTAMP = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')

# main directory for running tests
TEST_MAIN_DIR = joinpath(MYPATH, r'../../fortran_tests')

TEST_DIR = joinpath(TEST_MAIN_DIR, r'test_code')
# directory for external Fortran code
TEST_EXT_DIR = joinpath(TEST_MAIN_DIR, r'test_code')

# directory containing Fortran examples
EXAMPLE_DIR = joinpath(MYPATH, r'../../examples/in')
TIMESTAMP = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
BACKUP_DIR = joinpath(MYPATH, r'../../fortran_tests/test_code_in_' + TIMESTAMP)
RESULT_DIR = joinpath(MYPATH, r'../../fortran_tests/test_results')

# backup directory
BACKUP_DIR = joinpath(TEST_MAIN_DIR, r'test_code_in_' + TIMESTAMP)

# where to store summarized results
RESULT_DIR = joinpath(TEST_MAIN_DIR, r'test_results')

# expected hash-sums
RESULT_FILE = joinpath(RESULT_DIR, r'expected_results')

# test failures
FAILED_FILE = joinpath(RESULT_DIR, r'failed_results')

# path to fprettify
RUNSCRIPT = joinpath(MYPATH, r"../../fprettify.py")

fprettify.set_fprettify_logger(logging.ERROR)

fprettify.set_fprettify_logger(logging.ERROR)

class AlienInvasion(Exception):
"""Should not happen"""
Expand Down Expand Up @@ -107,7 +121,7 @@ def setUpClass(cls):
eprint("recognized Fortran files")
eprint(", ".join(fprettify.FORTRAN_EXTENSIONS))
eprint("-" * 70)
eprint("Applying fprettify to Fortran files in " + TEST_DIR)
eprint("Applying fprettify to Fortran files in " + TEST_EXT_DIR)
eprint("Writing backup of original files to " + BACKUP_DIR)
eprint("Storing expected results in " + RESULT_FILE)
eprint("Storing failed results in " + FAILED_FILE)
Expand Down Expand Up @@ -250,12 +264,17 @@ def assert_fprettify_result(self, args, instring, outstring_exp):
assert that result of calling fprettify with args on instring gives
outstring_exp
"""
args.insert(0, RUNSCRIPT)
p1 = subprocess.Popen(
args, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
outstring = p1.communicate(instring.encode(
'UTF-8'))[0].decode('UTF-8').rstrip()
self.assertEqual(outstring_exp.rstrip(), outstring)

parser = fprettify.get_arg_parser()
args = parser.parse_args(args)
args = fprettify.process_args(args)

outfile = io.StringIO()
infile = io.StringIO(instring)

fprettify.reformat_ffile(infile, outfile, orig_filename='StringIO', **args)
outstring = outfile.getvalue()
self.assertEqual(outstring_exp.rstrip(), outstring.rstrip())

def test_io(self):
"""simple test for io (file inplace, stdin & stdout)"""
Expand Down Expand Up @@ -890,7 +909,7 @@ def test_label(self):

self.assert_fprettify_result([], instring, outstring)

def generatesuite(suitename):
def generate_suite(suitename):
config = configparser.ConfigParser()
config.read(joinpath(TEST_MAIN_DIR, 'externalTestCode.config'))

Expand All @@ -899,7 +918,7 @@ def generatesuite(suitename):
if code['suite'] == suitename:
orig = os.getcwd()
try:
os.chdir(TEST_DIR)
os.chdir(TEST_EXT_DIR)

if not os.path.isdir(code['path']):
exec(code['obtain'])
Expand All @@ -910,9 +929,9 @@ def generatesuite(suitename):

def addtestcode(code_path, options):
# dynamically create test cases from fortran files in test directory
for dirpath, _, filenames in os.walk(joinpath(TEST_DIR, code_path)):
for dirpath, _, filenames in os.walk(joinpath(TEST_EXT_DIR, code_path)):
for example in [f for f in filenames if any(f.endswith(_) for _ in fprettify.FORTRAN_EXTENSIONS)]:
rel_dirpath = os.path.relpath(dirpath, start=TEST_DIR)
rel_dirpath = os.path.relpath(dirpath, start=TEST_EXT_DIR)
addtestmethod(FPrettifyTestCase, rel_dirpath, example, options)


Expand All @@ -922,7 +941,7 @@ def addtestmethod(testcase, fpath, ffile, options):
def testmethod(testcase):
"""this is the test method invoked for each example."""

example_path = joinpath(TEST_DIR, fpath)
example_path = joinpath(TEST_EXT_DIR, fpath)
backup_path = joinpath(BACKUP_DIR, fpath)
if not os.path.exists(backup_path):
os.makedirs(backup_path)
Expand All @@ -931,7 +950,7 @@ def testmethod(testcase):
example_backup = joinpath(backup_path, ffile)

def test_result(path, info):
return [os.path.relpath(path, TEST_DIR), info]
return [os.path.relpath(path, TEST_EXT_DIR), info]

with io.open(example, 'r', encoding='utf-8') as infile:
instring = infile.read()
Expand All @@ -942,16 +961,15 @@ def test_result(path, info):

# apply fprettify
with io.open(example, 'r', encoding='utf-8') as infile:
outstring = io.StringIO()
outfile = io.StringIO()

try:
parser = fprettify.get_arg_parser()
args = parser.parse_args(options)

args = parser.parse_args(shlex.split(options))
args = fprettify.process_args(args)

fprettify.reformat_ffile(infile, outstring, **args)
outstring = outstring.getvalue()
fprettify.reformat_ffile(infile, outfile, **args)
outstring = outfile.getvalue()
m = hashlib.sha256()
m.update(outstring.encode('utf-8'))

Expand Down Expand Up @@ -1020,8 +1038,8 @@ def test_result(path, info):
setattr(testcase, testmethod.__name__, testmethod)

# make sure all directories exist
if not os.path.exists(TEST_DIR): # pragma: no cover
os.makedirs(TEST_DIR)
if not os.path.exists(TEST_EXT_DIR): # pragma: no cover
os.makedirs(TEST_EXT_DIR)
if not os.path.exists(BACKUP_DIR): # pragma: no cover
os.makedirs(BACKUP_DIR)
if not os.path.exists(RESULT_DIR): # pragma: no cover
Expand All @@ -1033,4 +1051,4 @@ def test_result(path, info):
io.open(FAILED_FILE, 'w', encoding='utf-8').close()

# ToDo: parameterize regular / cron
generatesuite('cron')
#generate_suite('cron')

0 comments on commit b9c5e7d

Please sign in to comment.