def test_parser_unrecognized_context_format(): p = FyooParser() with pytest.raises(ValueError, match='idontexist'): p.parse_args([ '--context=a: ABC', '--context-format=idontexist', ])
def test_parser_non_dictionary(): p = FyooParser() with pytest.raises(ValueError, match='dictionary'): p.parse_args([ '--context=- a: ABC', '--context-format=yaml', ])
def test_file_loaded_template_throws_explicit_exception(): p = FyooParser() p.add_argument('first_arg') with pytest.raises(fyoo.exception.FyooTemplateException): p.parse_args([ '--jinja-template-folder=tests/sql', r'{% include "count.sql.jinja" %}', ])
def test_template_throw_error(): p = FyooParser() p.add_argument('first_arg') with pytest.raises(FyooTemplateException, match='Cool Err'): p.parse_args([ r'{{ throw("Cool Err") }}', ])
def test_file_loaded_template_doesnt_exist(): p = FyooParser() p.add_argument('first_arg') with pytest.raises(jinja2.exceptions.TemplateNotFound): p.parse_args([ '--jinja-template-folder=tests/sql', '--set=table=customers', r'{% include "i-dont-exist.sql.jinja" %}', ])
def test_passed_namespace_no_args_in_this_parser(): p = FyooParser() n = p.parse_args([ '--context=a: ABC', '--context-format=yaml', '--set=b=DEF', '--set=c=GHI', ]) assert p.parse_args([]).__dict__ == {}
def test_fyoo_context_overrides_extension(): p1 = FyooParser() p1.add_argument('first_arg') assert 'function' in p1.parse_args([ r'{{ date }}', ]).first_arg p2 = FyooParser() p2.add_argument('first_arg') assert p2.parse_args([ '--set=date=ABC', r'{{ date }}', ]).first_arg == 'ABC'
def test_implicit_type_boolean_true(): p = FyooParser() p.add_argument('first_arg') assert p.parse_args([ '--set=ist=tRuE', r'{% if ist and ist != "tRuE" %}shouldbetrue{% else %}{% endif %}', ]).first_arg == 'shouldbetrue'
def test_implicit_type_boolean_dif_cap(): p = FyooParser() p.add_argument('first_arg') assert p.parse_args([ '--set=isf=fAlSe', r'{% if isf %}{% else %}shouldbefalse{% endif %}', ]).first_arg == 'shouldbefalse'
def test_implicit_type_float(): p = FyooParser() p.add_argument('first_arg') assert p.parse_args([ '--set=isi=3.1', r'{{ isi + 1 }}', ]).first_arg == '4.1'
def test_jinja_extension(): p = FyooParser() p.add_argument('first_arg') assert p.parse_args([ '--jinja-extension=tests.fyoo.test_parser.TestJinjaExtension', r'{{ testing }}', ]).first_arg == '123'
def test_fyoo_context_priority(): p = FyooParser() p.add_argument('first_arg') assert p.parse_args([ '--context={"a":"ABC"}', '--context={"a":"DEF"}', r'{{ a }}', ]).first_arg == 'DEF'
def test_passed_namespace_no_args_twice(): """Make sure that parser can parse multiple times. (an early implementation added actions multiple times and would break this) """ p = FyooParser() assert p.parse_args([]).__dict__ == {} assert p.parse_args([]).__dict__ == {}
def test_fyoo_context_set_override(): p = FyooParser() p.add_argument('first_arg') assert p.parse_args([ '--set=a=GHI', '--context={"a":"ABC"}', '--context={"a":"DEF"}', r'{{ a }}', ]).first_arg == 'GHI'
def test_file_loaded_template(): p = FyooParser() p.add_argument('first_arg') assert p.parse_args([ '--jinja-template-folder=tests/sql', '--set=table=customers', r'{% include "count.sql.jinja" %}', ]).first_arg.strip() == r''' select count(*) as c from customers '''.strip()
class CliSingleton: __instance = None DESCRIPTION = ''' This utility wraps around a command, and templates in context to the latter command's arguments. The child process will replace the fyoo/python process. '''.strip() HELP = { 'exec': ''' Execute a subcommand. The subcommand will spawn a child process that will become a parent (implemented by ``os.execvp``). '''.strip(), 'command': 'Enter any number of arguments as a command.', 'dry_run': 'Do not actually kick off command.', 'verbose': 'Show the command before running it.', } def __init__(self): _C = CliSingleton self.parser = FyooParser( 'fyoo', description=_C.DESCRIPTION, formatter_class=lambda prog: argparse. ArgumentDefaultsHelpFormatter(prog, width=120)) self.parser.add_argument('-v', '--verbose', action='store_true', default=False, help=_C.HELP['verbose']) self.parser.add_argument('-dr', '--dry-run', action='store_true', default=False, help=_C.HELP['dry_run']) subparsers = self.parser.add_subparsers( parser_class=argparse.ArgumentParser) subparsers.required = True exec_parser = subparsers.add_parser('--', help=_C.HELP['exec']) exec_parser.set_defaults(callback=self.exec) exec_parser.add_argument('command', nargs=argparse.REMAINDER, help=_C.HELP['command']) # pylint: disable=no-self-use def exec(self, dry_run: bool, verbose: bool, command: List[str]): if dry_run or verbose: print(json.dumps(command)) if not dry_run: if shutil.which(command[0]) is None: self.parser.error(f"Executable '{command[0]}' does not exist") os.execvp(command[0], command) def main(self, args: Sequence[Text]) -> None: try: arg_dict = vars(self.parser.parse_args(args)) except TypeError as err: if err.args == ( 'sequence item 0: expected str instance, NoneType found', ): self.parser.error('Please provide a subcommand') raise callback = arg_dict.pop('callback') callback(**arg_dict) def __new__(cls, *args, **kwargs): if not kwargs.pop('_is_instance_call', False): raise ValueError("Can not instantiate, use .instance() instead") return super(CliSingleton, cls).__new__(cls, *args, **kwargs) @classmethod def instance(cls): if cls.__instance is None: cls.__instance = cls.__new__(cls, _is_instance_call=True) cls.__instance.__init__() return cls.__instance @classmethod def remove(cls): if cls.__instance is not None: CliSingleton.__instance = None
def test_unrecognized_extension(): p = FyooParser() with pytest.raises(ModuleNotFoundError): p.parse_args(['--jinja-extension=i.dont.exist'])
def test_file_no_loaded_template_doesnt_exist(): p = FyooParser() p.add_argument('first_arg') with pytest.raises(TypeError, match='no loader for this environment specified'): p.parse_args([r'{% include "count.sql.jinja" %}'])
def test_set_by_env_var(): p = FyooParser() p.add_argument('first_arg') with patch('os.environ', {'FYOO__SET__a': 'somea'}): assert p.parse_args([r'{{ a }}']).first_arg == 'somea'
def test_template_raw_datetime_strptime(): p = FyooParser() p.add_argument('first_arg') assert p.parse_args([ r'{{ raw_datetime.strptime("2020", "%Y") }}', ]).first_arg == '2020-01-01 00:00:00'