def test_read_and_proc_no_template_engine(): with tempfile.NamedTemporaryFile() as tf: fpath = tf.name template_vars = None viewcfg = { 'empy': False, 'jinja2': False, 'contin': False, 'inline': False } asedit = None tf.write("a=b\n".encode()) tf.flush() r = read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg, asedit=asedit) assert r == ['a=b'] # last \\ is ignored, becoming just '' tf.write("c=\\\nd\n\\".encode()) tf.flush() viewcfg = { 'empy': False, 'jinja2': False, 'contin': True, 'inline': False } r = read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg, asedit=asedit) assert r == ['a=b', 'c=d', '']
def test_empysupport_empyprocess(self): lines = ["My name is @name", ""] variables = {'name': 'Cylc'} template_dir = tempfile.gettempdir() r = empysupport.empyprocess(lines, template_dir, variables) # after this, we would normally have an error in unittest as follows: # AttributeError: ProxyFile instance has no attribute 'getvalue' # That's due to a Proxy installed by EmPy to replace sys.stdout. # We restore the sys.stdout in the end of the tests # TODO: is it OK? Does everything else works OK in Jinja after this? # Note: writing multiple methods will result in an error too self.assertEqual(1, len(r)) self.assertEqual('My name is Cylc', r[0]) sys.stdout.getvalue = lambda: '' lines = [] template_dir = tempfile.gettempdir() r = empysupport.empyprocess(lines, template_dir) self.assertEqual(0, len(r)) # --- testing fileparse (here due to stdout issue) with tempfile.NamedTemporaryFile() as tf: fpath = tf.name template_vars = {'name': 'Cylc'} viewcfg = { 'empy': True, 'jinja2': False, 'contin': False, 'inline': False } asedit = None tf.write("#!empy\na=@name\n".encode()) tf.flush() r = read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg, asedit=asedit) self.assertEqual(['a=Cylc'], r) del template_vars['name'] with self.assertRaises(EmPyError): read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg, asedit=asedit) sys.stdout.getvalue = lambda: '' sys.stdout.getvalue = lambda: ''
def test_empysupport_empyprocess(self): lines = ["My name is @name", ""] variables = {'name': 'Cylc'} template_dir = tempfile.gettempdir() r = empysupport.empyprocess(lines, template_dir, variables) # after this, we would normally have an error in unittest as follows: # AttributeError: ProxyFile instance has no attribute 'getvalue' # That's due to a Proxy installed by EmPy to replace sys.stdout. # We restore the sys.stdout in the end of the tests # TODO: is it OK? Does everything else works OK in Jinja after this? # Note: writing multiple methods will result in an error too self.assertEqual(1, len(r)) self.assertEqual('My name is Cylc', r[0]) sys.stdout.getvalue = lambda: '' lines = [] template_dir = tempfile.gettempdir() r = empysupport.empyprocess(lines, template_dir) self.assertEqual(0, len(r)) # --- testing fileparse (here due to stdout issue) with tempfile.NamedTemporaryFile() as tf: fpath = tf.name template_vars = { 'name': 'Cylc' } viewcfg = { 'empy': True, 'jinja2': False, 'contin': False, 'inline': False } asedit = None tf.write("#!empy\na=@name\n".encode()) tf.flush() r = read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg, asedit=asedit) self.assertEqual(['a=Cylc'], r) del template_vars['name'] with self.assertRaises(EmPyError): read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg, asedit=asedit) sys.stdout.getvalue = lambda: '' sys.stdout.getvalue = lambda: ''
def test_inline(): with tempfile.NamedTemporaryFile() as tf: fpath = tf.name template_vars = None viewcfg = { 'empy': False, 'jinja2': False, 'contin': False, 'inline': True, 'mark': None, 'single': None, 'label': None } asedit = None with tempfile.NamedTemporaryFile() as include_file: include_file.write("c=d".encode()) include_file.flush() tf.write( ("a=b\n%include \"{0}\"".format(include_file.name)).encode()) tf.flush() r = read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg, asedit=asedit) assert r == ['a=b', 'c=d']
def test_read_and_proc_jinja2_error(): with tempfile.NamedTemporaryFile() as tf: fpath = tf.name template_vars = {'name': 'Cylc'} viewcfg = { 'empy': False, 'jinja2': True, 'contin': False, 'inline': False } tf.write("#!jinja2\na={{ name \n".encode()) tf.flush() with pytest.raises(Jinja2Error) as cm: read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg) assert ("unexpected end of template, expected " "'end of print statement'.") in str(cm.value)
def test_inline_error(): with tempfile.NamedTemporaryFile() as tf: fpath = tf.name template_vars = None viewcfg = { 'empy': False, 'jinja2': False, 'contin': False, 'inline': True, 'mark': None, 'single': None, 'label': None } tf.write("a=b\n%include \"404.txt\"".encode()) tf.flush() with pytest.raises(IncludeFileNotFoundError) as cm: read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg) assert "404.txt" in str(cm.value)
def test_read_and_proc_raises_TemplateVarLanguageClash(monkeypatch, tmp_path, templating, hashbang): """func fails when diffn't templating engines set in hashbang and plugin. """ def fake_process_plugins(_): extra_vars = { 'env': {}, 'template_variables': { 'foo': 52 }, 'templating_detected': templating } return extra_vars monkeypatch.setattr(fileparse, 'process_plugins', fake_process_plugins) file_ = tmp_path / 'flow.cylc' file_.write_text(f'#!{hashbang}\nfoo') with pytest.raises(TemplateVarLanguageClash) as exc: read_and_proc(file_) assert exc.type == TemplateVarLanguageClash
def test_read_and_proc_jinja2(): with tempfile.NamedTemporaryFile() as tf: fpath = tf.name template_vars = {'name': 'Cylc'} viewcfg = { 'empy': False, 'jinja2': True, 'contin': False, 'inline': False } tf.write("#!jinja2\na={{ name }}\n".encode()) tf.flush() r = read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg) assert r == ['a=Cylc']
def test_read_and_proc_jinja2_error_missing_shebang(): with tempfile.NamedTemporaryFile() as tf: fpath = tf.name template_vars = {'name': 'Cylc'} viewcfg = { 'empy': False, 'jinja2': True, 'contin': False, 'inline': False } # first line is missing shebang! tf.write("a={{ name }}\n".encode()) tf.flush() r = read_and_proc(fpath=fpath, template_vars=template_vars, viewcfg=viewcfg) assert r == ['a={{ name }}']
def main(parser, options, reg): suite, suiterc = parse_suite_arg(options, reg) if options.geditor: editor = glbl_cfg().get(['editors', 'gui']) else: editor = glbl_cfg().get(['editors', 'terminal']) # read in the suite.rc file viewcfg = { 'mark': options.mark, 'single': options.single, 'label': options.label, 'empy': options.empy or options.process, 'jinja2': options.jinja2 or options.process, 'contin': options.cat or options.process, 'inline': (options.inline or options.jinja2 or options.empy or options.process), } lines = read_and_proc(suiterc, load_template_vars(options.templatevars, options.templatevars_file), viewcfg=viewcfg, asedit=options.asedit) if options.stdout: for line in lines: print(line) sys.exit(0) # write to a temporary file viewfile = NamedTemporaryFile( suffix=".suite.rc", prefix=suite.replace('/', '_') + '.', ) for line in lines: viewfile.write((line + '\n').encode()) viewfile.seek(0, 0) # set the file to be read only os.chmod(viewfile.name, 0o400) # capture the temp file's mod time in case the user edits it # and overrides the readonly mode. modtime1 = os.stat(viewfile.name).st_mtime # in case editor has options, e.g. 'emacs -nw': command_list = shlex.split(editor) command_list.append(viewfile.name) command = ' '.join(command_list) # THIS BLOCKS UNTIL THE COMMAND COMPLETES retcode = call(command_list) if retcode != 0: # the command returned non-zero exist status raise CylcError(f'{command} failed: {retcode}') # !!!VIEWING FINISHED!!! # Did the user edit the file modtime2 = os.stat(viewfile.name).st_mtime if modtime2 > modtime1: print() print('WARNING: YOU HAVE EDITED A TEMPORARY READ-ONLY SUITE COPY:', file=sys.stderr) print(viewfile.name, file=sys.stderr) print('In future use \'cylc [prep] edit\' to edit a suite.', file=sys.stderr) print() # DONE viewfile.close()
def main(parser: COP, options: 'Values', reg: str) -> None: workflow, flow_file = parse_reg(reg, src=True) if options.geditor: editor = glbl_cfg().get(['editors', 'gui']) else: editor = glbl_cfg().get(['editors', 'terminal']) # read in the flow.cylc file viewcfg = { 'mark': options.mark, 'single': options.single, 'label': options.label, 'empy': options.empy or options.process, 'jinja2': options.jinja2 or options.process, 'contin': options.cat or options.process, 'inline': (options.inline or options.jinja2 or options.empy or options.process), } lines = read_and_proc(flow_file, load_template_vars(options.templatevars, options.templatevars_file), viewcfg=viewcfg) if options.stdout: for line in lines: print(line) sys.exit(0) # write to a temporary file viewfile = NamedTemporaryFile( suffix=".flow.cylc", prefix=workflow.replace('/', '_') + '.', ) for line in lines: viewfile.write((line + '\n').encode()) viewfile.seek(0, 0) # set the file to be read only os.chmod(viewfile.name, 0o400) # capture the temp file's mod time in case the user edits it # and overrides the readonly mode. modtime1 = os.stat(viewfile.name).st_mtime # in case editor has options, e.g. 'emacs -nw': command_list = shlex.split(editor) command_list.append(viewfile.name) command = ' '.join(command_list) # THIS BLOCKS UNTIL THE COMMAND COMPLETES retcode = call(command_list) # nosec (editor command is user configurable) if retcode != 0: # the command returned non-zero exist status raise CylcError(f'{command} failed: {retcode}') # !!!VIEWING FINISHED!!! # Did the user edit the file modtime2 = os.stat(viewfile.name).st_mtime if modtime2 > modtime1: print( "\nWARNING: YOU HAVE EDITED A TEMPORARY READ-ONLY COPY " f"OF THE WORKFLOW:\n {viewfile.name}\n", file=sys.stderr) # DONE viewfile.close()