from __future__ import annotations import unittest import subprocess import shutil import pathlib from tests.support import * class TestCommandLine(unittest.TestCase): # Sources to test: normal dry_run force backup filter update python_folder # - single dyn file ✅ ✅ ✅ ✅ ✅ # - multiple dyn files ✅ ✅ ✅ ✅ ✅ # - single python file # - multiple python files # - single folder # - multiple folders # Options to test: # dry run # force # backup # filter # update # python folder def test_help_and_version(self): args = ["-h", "--help", "-v", "--version"] for arg in args: p = subprocess.run(f"dyn2py {arg}", capture_output=True, shell=True) self.assertFalse(p.stderr) dyn_sources = [ {"filename": "python_nodes.dyn", "py_file_count": 6}, {"filename": "single_node.dyn", "py_file_count": 1} ] dyn_sources_error = ["dynamo1file.dyn", "no_python.dyn", "nonexisting.dyn"] @staticmethod def run_command(args: list = []) -> dict: argstring = " ".join(args) process = subprocess.run(f"dyn2py -l WARNING {argstring}", capture_output=True, shell=True) stderr = process.stderr.decode() python_files = {p: p.stat().st_mtime for p in pathlib.Path(OUTPUT_DIR).iterdir() if p.suffix == ".py"} output = { "stderr": stderr, "python_file_mtimes": python_files } return output @staticmethod def generate_test_args(source_dicts: list[dict]) -> list[dict]: tests = [] for i, source_dict in enumerate(source_dicts): for backup_arg in ["-b", "--backup"]: for force_arg in ["-F", "--force"]: for pfolder_option in ["", "-p", "--python-folder"]: test_dicts = [source_dict.copy()] test_dicts[0]["filenames"] = [ test_dicts[0]["filename"]] if i == 0: # Create a multi file version on the first file: d = {} for key in source_dict: if key == "filename": d["filenames"] = [f["filename"] for f in source_dicts] elif isinstance(source_dict[key], (int, float)): d[key] = sum([f[key] for f in source_dicts]) test_dicts.append(d) for test_dict in test_dicts: if pfolder_option: file_dir = INPUT_DIR pfolder_arg = f"{pfolder_option} {OUTPUT_DIR}" else: file_dir = OUTPUT_DIR pfolder_arg = "" test_dict["filepath"] = " ".join( [f"{file_dir}/{f}" for f in test_dict["filenames"]]) test_dict.update({ "pfolder_arg": pfolder_arg, "backup_arg": backup_arg, "force_arg": force_arg }) tests.append(test_dict) return tests def test_dyn_error(self): for s in self.dyn_sources_error: cleanup_output_dir() if pathlib.Path(f"{INPUT_DIR}/{s}").exists(): shutil.copy(f"{INPUT_DIR}/{s}", f"{OUTPUT_DIR}/{s}") file_open = self.run_command( [f"{OUTPUT_DIR}/{s}"]) self.assertTrue(bool(file_open["stderr"])) self.assertEqual( len(file_open["python_file_mtimes"]), 0) def test_dyn(self): dyn_tests = self.generate_test_args(self.dyn_sources) for s in dyn_tests: cleanup_output_dir() if not s["pfolder_arg"]: for filename in s["filenames"]: shutil.copy(f"{INPUT_DIR}/{filename}", f"{OUTPUT_DIR}/{filename}") file_open = self.run_command( [s["pfolder_arg"], s['filepath']]) self.assertFalse( bool(file_open["stderr"]), msg=file_open["stderr"]) self.assertEqual( len(file_open["python_file_mtimes"]), s["py_file_count"]) # Test no overwrite file_no_overwrite = self.run_command( [s["pfolder_arg"], s['filepath']]) self.assertTrue(bool(file_no_overwrite["stderr"])) self.assertEqual( len(file_no_overwrite["python_file_mtimes"]), s["py_file_count"]) for p in file_no_overwrite["python_file_mtimes"]: self.assertEqual( file_no_overwrite["python_file_mtimes"][p], file_open["python_file_mtimes"][p]) # Test force: file_force = self.run_command( [s["pfolder_arg"], s["force_arg"], s['filepath']]) self.assertFalse(bool(file_force["stderr"])) self.assertEqual( len(file_force["python_file_mtimes"]), s["py_file_count"]) for p in file_force["python_file_mtimes"]: self.assertTrue( file_force["python_file_mtimes"][p] > file_open["python_file_mtimes"][p] ) # Test backup file_backup = self.run_command( [s["pfolder_arg"], s["force_arg"], s["backup_arg"], s['filepath']]) self.assertFalse(bool(file_backup["stderr"])) self.assertEqual( len(file_backup["python_file_mtimes"]), s["py_file_count"] * 2) for p in file_force["python_file_mtimes"]: self.assertTrue( file_backup["python_file_mtimes"][p] > file_force["python_file_mtimes"][p] ) def test_single_dyn_dryrun(self): for s in self.dyn_sources: for arg in ["-n", "--dry-run"]: cleanup_output_dir() shutil.copy(f"{INPUT_DIR}/{s['filename']}", f"{OUTPUT_DIR}/{s['filename']}") file_dryrun = self.run_command( [arg, f"{OUTPUT_DIR}/{s['filename']}"]) self.assertFalse(bool(file_dryrun["stderr"])) self.assertFalse(file_dryrun["python_file_mtimes"])