def test_argument_range(self): ap = ArgumentParser('usage: test.py [options] args', arg_limits=(2, 4)) ap.parse_args(['1', '2']) ap.parse_args(['1', '2', '3', '4']) assert_raises_with_msg(DataError, "Expected 2 to 4 arguments, got 1.", ap.parse_args, ['one is not enough'])
def test_check_variable_number_of_args(self): ap = ArgumentParser('usage: robot.py [options] args', arg_limits=(1,)) ap.parse_args(['one_is_ok']) ap.parse_args(['two', 'ok']) ap.parse_args(['this', 'should', 'also', 'work', '!']) assert_raises_with_msg(DataError, "Expected at least 1 argument, got 0.", ap.parse_args, [])
def test_custom_validator_return_value(self): def validate(options, args): return options, [a.upper() for a in args] ap = ArgumentParser(USAGE2, validator=validate) opts, args = ap.parse_args(['-v', 'value', 'inp1', 'inp2']) assert_equals(opts['variable'], 'value') assert_equals(args, ['INP1', 'INP2'])
def test_arguments(self): os.environ['ROBOT_TEST_OPTIONS'] = '-o opt arg1 arg2' ap = ArgumentParser('Usage:\n -o --opt value', env_options='ROBOT_TEST_OPTIONS') opts, args = ap.parse_args([]) assert_equals(opts['opt'], 'opt') assert_equals(args, ['arg1', 'arg2'])
def test_non_list_args(self): ap = ArgumentParser('''Options: -t --toggle -v --value value -m --multi multi * ''') opts, args = ap.parse_args(()) assert_equals(opts, {'toggle': False, 'value': None, 'multi': []}) assert_equals(args, []) opts, args = ap.parse_args(('-t', '-v', 'xxx', '-m', '1', '-m2', 'arg')) assert_equals(opts, {'toggle': True, 'value': 'xxx', 'multi': ['1', '2']}) assert_equals(args, ['arg'])
def _robot_options(self): arg_parser = ArgumentParser(USAGE, auto_pythonpath=False, auto_argumentfile=True, env_options='ROBOT_OPTIONS') valid_args = self._filter_args(arg_parser) return arg_parser.parse_args(valid_args)[0]
def robot_options(): arg_parser = ArgumentParser(USAGE, auto_pythonpath=False, auto_argumentfile=True, env_options="ROBOT_OPTIONS") valid_args = filter_args(arg_parser) return arg_parser.parse_args(valid_args)[0]
def test_arguments(self): os.environ['ROBOT_TEST_OPTIONS'] = '-o opt arg1 arg2' ap = ArgumentParser('Usage:\n -o --opt value', env_options='ROBOT_TEST_OPTIONS') opts, args = ap.parse_args([]) assert_equal(opts['opt'], 'opt') assert_equal(args, ['arg1', 'arg2'])
class TestDefaultsFromEnvironmentVariables(unittest.TestCase): def setUp(self): os.environ['ROBOT_TEST_OPTIONS'] = '-t --value default -m1 --multi=2' self.ap = ArgumentParser('''Options: -t --toggle -v --value value -m --multi multi * ''', env_options='ROBOT_TEST_OPTIONS') def tearDown(self): os.environ.pop('ROBOT_TEST_OPTIONS') def test_toggle(self): opts, args = self.ap.parse_args([]) assert_equals(opts['toggle'], True) opts, args = self.ap.parse_args(['--toggle']) assert_equals(opts['toggle'], False) def test_value(self): opts, args = self.ap.parse_args([]) assert_equals(opts['value'], 'default') opts, args = self.ap.parse_args(['--value', 'given']) assert_equals(opts['value'], 'given') def test_multi_value(self): opts, args = self.ap.parse_args([]) assert_equals(opts['multi'], ['1', '2']) opts, args = self.ap.parse_args(['-m3', '--multi', '4']) assert_equals(opts['multi'], ['1', '2', '3', '4']) def test_arguments(self): os.environ['ROBOT_TEST_OPTIONS'] = '-o opt arg1 arg2' ap = ArgumentParser('Usage:\n -o --opt value', env_options='ROBOT_TEST_OPTIONS') opts, args = ap.parse_args([]) assert_equals(opts['opt'], 'opt') assert_equals(args, ['arg1', 'arg2']) def test_environment_variable_not_set(self): ap = ArgumentParser('Usage:\n -o --opt value', env_options='NOT_SET') opts, args = ap.parse_args(['arg']) assert_equals(opts['opt'], None) assert_equals(args, ['arg']) def test_non_list_args(self): opts, args = self.ap.parse_args(()) assert_equals(opts, {'toggle': True, 'value': 'default', 'multi': ['1', '2']}) assert_equals(args, []) opts, args = self.ap.parse_args(('-t', '-v', 'given', '-m3', 'a', 'b')) assert_equals(opts, {'toggle': False, 'value': 'given', 'multi': ['1', '2', '3']}) assert_equals(args, ['a', 'b'])
def test_non_ascii_chars(self): ap = ArgumentParser(USAGE2) inargs = '-x foo=bar --variable a=1,2,3 arg1 arg2'.split() exp_opts = {'var-able': 'foo=bar', 'variable': 'a=1,2,3', '42': False} exp_args = ['arg1', 'arg2'] opts, args = ap.parse_args(inargs) assert_equals(opts, exp_opts) assert_equals(args, exp_args)
def test_special_options_are_removed(self): ap = ArgumentParser('''Usage: -h --help -v --version --argumentfile path --option ''') opts, args = ap.parse_args(['--option']) assert_equal(opts, {'option': True})
def test_flag_option_with_no_prefix(self): ap = ArgumentParser(' -S --nostatusrc\n --name name') for inargs, exp in [('', None), ('--name whatever', None), ('--nostatusrc', False), ('-S', False), ('--nostatusrc -S --nostatusrc -S -S', False), ('--statusrc', True), ('--statusrc --statusrc -S', False), ('--nostatusrc --nostatusrc -S --statusrc', True)]: opts, args = ap.parse_args(inargs.split() + ['arg']) assert_equal(opts['statusrc'], exp, inargs) assert_equal(args, ['arg'])
def test_special_options_are_removed(self): ap = ArgumentParser('''Usage: -h --help -v --version --pythonpath path --escape x:y * --argumentfile path --option ''') opts, args = ap.parse_args(['--option']) assert_equals(opts, {'option': True})
def test_special_options_can_be_turned_to_normal_optios(self): ap = ArgumentParser('''Usage: -h --help -v --version --pythonpath path --escape x:y --argumentfile path ''', auto_help=False, auto_version=False, auto_escape=False, auto_pythonpath=False, auto_argumentfile=False) opts, args = ap.parse_args(['--help', '-v', '--escape', 'xxx']) assert_equals(opts, {'help': True, 'version': True, 'pythonpath': None, 'escape': 'xxx', 'argumentfile': None})
def test_flag_option_with_no_prefix(self): ap = ArgumentParser(' -S --nostatusrc\n --name name') for inargs, exp in [('', None), ('--name whatever', None), ('--nostatusrc', False), ('-S', False), ('--nostatusrc -S --nostatusrc -S -S', False), ('--statusrc', True), ('--statusrc --statusrc -S', False), ('--nostatusrc --nostatusrc -S --statusrc', True)]: opts, args = ap.parse_args(inargs.split() + ['arg']) assert_equals(opts['statusrc'], exp, inargs) assert_equals(args, ['arg'])
def test_special_options_can_be_turned_to_normal_options(self): ap = ArgumentParser('''Usage: -h --help -v --version --argumentfile path ''', auto_help=False, auto_version=False, auto_argumentfile=False) opts, args = ap.parse_args(['--help', '-v', '--arg', 'xxx']) assert_equal(opts, { 'help': True, 'version': True, 'argumentfile': 'xxx' })
def test_check_args_with_correct_args(self): for arg_limits in [None, (1, 1), 1, (1,)]: ap = ArgumentParser(USAGE, arg_limits=arg_limits) assert_equals(ap.parse_args(['hello'])[1], ['hello'])
class TestArgumentParserParseArgs(unittest.TestCase): def setUp(self): self.ap = ArgumentParser(USAGE) def test_missing_argument_file_throws_data_error(self): inargs = '--argumentfile missing_argument_file_that_really_is_not_there.txt'.split( ) self.assertRaises(DataError, self.ap.parse_args, inargs) def test_single_options(self): inargs = '-d reports --reportfile report.html -T arg'.split() opts, args = self.ap.parse_args(inargs) assert_equals( opts, { 'reportdir': 'reports', 'reportfile': 'report.html', 'variable': [], 'name': None, 'toggle': True }) def test_multi_options(self): inargs = '-v a:1 -v b:2 --name my_name --variable c:3 arg'.split() opts, args = self.ap.parse_args(inargs) assert_equals( opts, { 'variable': ['a:1', 'b:2', 'c:3'], 'name': 'my_name', 'reportdir': None, 'reportfile': None, 'toggle': False }) assert_equals(args, ['arg']) def test_toggle_options(self): for inargs, exp in [('arg', False), ('--toggle arg', True), ('--toggle --name whatever -t arg', False), ('-t -T --toggle arg', True)]: opts, args = self.ap.parse_args(inargs.split()) assert_equals(opts['toggle'], exp) assert_equals(args, ['arg']) def test_single_option_multiple_times(self): for inargs in [ '--name Foo -N Bar arg', '-N Zap --name Foo --name Bar arg', '-N 1 -N 2 -N 3 -t --variable foo -N 4 --name Bar arg' ]: opts, args = self.ap.parse_args(inargs.split()) assert_equals(opts['name'], 'Bar') assert_equals(args, ['arg']) def test_case_insensitive_long_options(self): opts, args = self.ap.parse_args('--VarIable X:y --TOGGLE arg'.split()) assert_equals(opts['variable'], ['X:y']) assert_equals(opts['toggle'], True) assert_equals(args, ['arg']) def test_case_insensitive_long_options_with_equal_sign(self): opts, args = self.ap.parse_args( '--VariAble=X:y --VARIABLE=ZzZ'.split()) assert_equals(opts['variable'], ['X:y', 'ZzZ']) assert_equals(args, []) def test_unescape_options(self): cli = '--escape quot:Q -E space:SP -E lt:LT -E gt:GT ' \ + '-N QQQLTmySPfineSPnameGTQQQ sourceSPwithSPspaces' opts, args = self.ap.parse_args(cli.split()) assert_equals(opts['name'], '"""<my fine name>"""') assert_equals(args, ['source with spaces']) assert_true('escape' not in opts) def test_split_pythonpath(self): ap = ArgumentParser('ignored') data = [(['path'], ['path']), (['path1', 'path2'], ['path1', 'path2']), (['path1:path2'], ['path1', 'path2']), (['p1:p2:p3', 'p4', '.'], ['p1', 'p2', 'p3', 'p4', '.'])] if os.sep == '\\': data += [(['c:\\path'], ['c:\\path']), (['c:\\path', 'd:\\path'], ['c:\\path', 'd:\\path']), (['c:\\path:d:\\path'], ['c:\\path', 'd:\\path']), (['c:/path:x:yy:d:\\path', 'c', '.', 'x:/xxx'], ['c:\\path', 'x', 'yy', 'd:\\path', 'c', '.', 'x:\\xxx'])] for inp, exp in data: assert_equals(ap._split_pythonpath(inp), exp) def test_get_pythonpath(self): ap = ArgumentParser('ignored') p1 = os.path.abspath('.') p2 = os.path.abspath('..') assert_equals(ap._get_pythonpath(p1), [p1]) assert_equals(ap._get_pythonpath([p1, p2]), [p1, p2]) assert_equals(ap._get_pythonpath([p1 + ':' + p2]), [p1, p2]) assert_true(p1 in ap._get_pythonpath(os.path.join(p2, '*'))) def test_arguments_are_globbed(self): _, args = self.ap.parse_args([__file__.replace('test_', '?????')]) assert_equals(args, [__file__]) # Needed to ensure that the globbed directory contains files globexpr = os.path.join(os.path.dirname(__file__), '*') _, args = self.ap.parse_args([globexpr]) assert_true(len(args) > 1) def test_arguments_with_glob_patterns_arent_removed_if_they_dont_match( self): _, args = self.ap.parse_args(['*.non.existing', 'non.ex.??']) assert_equals(args, ['*.non.existing', 'non.ex.??']) def test_special_options_are_removed(self): ap = ArgumentParser('''Usage: -h --help -v --version --pythonpath path --escape x:y * --argumentfile path --option ''') opts, args = ap.parse_args(['--option']) assert_equals(opts, {'option': True}) def test_special_options_can_be_turned_to_normal_optios(self): ap = ArgumentParser('''Usage: -h --help -v --version --pythonpath path --escape x:y --argumentfile path ''', auto_help=False, auto_version=False, auto_escape=False, auto_pythonpath=False, auto_argumentfile=False) opts, args = ap.parse_args(['--help', '-v', '--escape', 'xxx']) assert_equals( opts, { 'help': True, 'version': True, 'pythonpath': None, 'escape': 'xxx', 'argumentfile': None })
def test_no_arguments(self): ap = ArgumentParser('usage: test.py [options]', arg_limits=(0, 0)) ap.parse_args([]) assert_raises_with_msg(DataError, "Expected 0 arguments, got 2.", ap.parse_args, ['1', '2'])
class TestArgumentParserParseArgs(unittest.TestCase): def setUp(self): self.ap = ArgumentParser(USAGE) def test_missing_argument_file_throws_data_error(self): inargs = '--argumentfile missing_argument_file_that_really_is_not_there.txt'.split( ) self.assertRaises(DataError, self.ap.parse_args, inargs) def test_single_options(self): inargs = '-d reports --reportfile reps.html -T arg'.split() opts, args = self.ap.parse_args(inargs) assert_equal( opts, { 'reportdir': 'reports', 'reportfile': 'reps.html', 'escape': [], 'variable': [], 'name': None, 'toggle': True }) def test_multi_options(self): inargs = '-v a:1 -v b:2 --name my_name --variable c:3 arg'.split() opts, args = self.ap.parse_args(inargs) assert_equal( opts, { 'variable': ['a:1', 'b:2', 'c:3'], 'escape': [], 'name': 'my_name', 'reportdir': None, 'reportfile': None, 'toggle': None }) assert_equal(args, ['arg']) def test_flag_options(self): for inargs, exp in [('', None), ('--name whatever', None), ('--toggle', True), ('-T', True), ('--toggle --name whatever -t', True), ('-t -T --toggle', True), ('--notoggle', False), ('--notoggle --name xxx --notoggle', False), ('--toggle --notoggle', False), ('-t -t -T -T --toggle -T --notoggle', False), ('--notoggle --toggle --notoggle', False), ('--notoggle --toggle', True), ('--notoggle --notoggle -T', True)]: opts, args = self.ap.parse_args(inargs.split() + ['arg']) assert_equal(opts['toggle'], exp, inargs) assert_equal(args, ['arg']) def test_flag_option_with_no_prefix(self): ap = ArgumentParser(' -S --nostatusrc\n --name name') for inargs, exp in [('', None), ('--name whatever', None), ('--nostatusrc', False), ('-S', False), ('--nostatusrc -S --nostatusrc -S -S', False), ('--statusrc', True), ('--statusrc --statusrc -S', False), ('--nostatusrc --nostatusrc -S --statusrc', True)]: opts, args = ap.parse_args(inargs.split() + ['arg']) assert_equal(opts['statusrc'], exp, inargs) assert_equal(args, ['arg']) def test_single_option_multiple_times(self): for inargs in [ '--name Foo -N Bar arg', '-N Zap --name Foo --name Bar arg', '-N 1 -N 2 -N 3 -t --variable foo -N 4 --name Bar arg' ]: opts, args = self.ap.parse_args(inargs.split()) assert_equal(opts['name'], 'Bar') assert_equal(args, ['arg']) def test_case_insensitive_long_options(self): opts, args = self.ap.parse_args('--VarIable X:y --TOGGLE arg'.split()) assert_equal(opts['variable'], ['X:y']) assert_equal(opts['toggle'], True) assert_equal(args, ['arg']) def test_case_insensitive_long_options_with_equal_sign(self): opts, args = self.ap.parse_args( '--VariAble=X:y --VARIABLE=ZzZ'.split()) assert_equal(opts['variable'], ['X:y', 'ZzZ']) assert_equal(args, []) def test_split_pythonpath(self): ap = ArgumentParser('ignored') data = [(['path'], ['path']), (['path1', 'path2'], ['path1', 'path2']), (['path1:path2'], ['path1', 'path2']), (['p1:p2:p3', 'p4', '.'], ['p1', 'p2', 'p3', 'p4', '.'])] if os.sep == '\\': data += [(['c:\\path'], ['c:\\path']), (['c:\\path', 'd:\\path'], ['c:\\path', 'd:\\path']), (['c:\\path:d:\\path'], ['c:\\path', 'd:\\path']), (['c:/path:x:yy:d:\\path', 'c', '.', 'x:/xxx'], ['c:\\path', 'x', 'yy', 'd:\\path', 'c', '.', 'x:\\xxx'])] for inp, exp in data: assert_equal(ap._split_pythonpath(inp), exp) def test_get_pythonpath(self): ap = ArgumentParser('ignored') p1 = os.path.abspath('.') p2 = os.path.abspath('..') assert_equal(ap._get_pythonpath(p1), [p1]) assert_equal(ap._get_pythonpath([p1, p2]), [p1, p2]) assert_equal(ap._get_pythonpath([p1 + ':' + p2]), [p1, p2]) assert_true(p1 in ap._get_pythonpath(os.path.join(p2, '*'))) def test_arguments_are_globbed(self): _, args = self.ap.parse_args([__file__.replace('test_', '?????')]) assert_equal(args, [__file__]) # Needed to ensure that the globbed directory contains files globexpr = os.path.join(os.path.dirname(__file__), '*') _, args = self.ap.parse_args([globexpr]) assert_true(len(args) > 1) def test_arguments_with_glob_patterns_arent_removed_if_they_dont_match( self): _, args = self.ap.parse_args(['*.non.existing', 'non.ex.??']) assert_equal(args, ['*.non.existing', 'non.ex.??']) def test_special_options_are_removed(self): ap = ArgumentParser('''Usage: -h --help -v --version --argumentfile path --option ''') opts, args = ap.parse_args(['--option']) assert_equal(opts, {'option': True}) def test_special_options_can_be_turned_to_normal_options(self): ap = ArgumentParser('''Usage: -h --help -v --version --argumentfile path ''', auto_help=False, auto_version=False, auto_argumentfile=False) opts, args = ap.parse_args(['--help', '-v', '--arg', 'xxx']) assert_equal(opts, { 'help': True, 'version': True, 'argumentfile': 'xxx' }) def test_auto_pythonpath_is_deprecated(self): with warnings.catch_warnings(record=True) as w: ArgumentParser('-x', auto_pythonpath=False) assert_equal( str(w[0].message), "ArgumentParser option 'auto_pythonpath' is deprecated " "since Robot Framework 5.0.") def test_non_list_args(self): ap = ArgumentParser('''Options: -t --toggle -v --value value -m --multi multi * ''') opts, args = ap.parse_args(()) assert_equal(opts, {'toggle': None, 'value': None, 'multi': []}) assert_equal(args, []) opts, args = ap.parse_args( ('-t', '-v', 'xxx', '-m', '1', '-m2', 'arg')) assert_equal(opts, { 'toggle': True, 'value': 'xxx', 'multi': ['1', '2'] }) assert_equal(args, ['arg'])
def test_argument_range(self): ap = ArgumentParser('usage: test.py [options] args', arg_limits=(2,4)) ap.parse_args(['1', '2']) ap.parse_args(['1', '2', '3', '4']) assert_raises_with_msg(DataError, "Expected 2 to 4 arguments, got 1.", ap.parse_args, ['one is not enough'])
def test_check_args_with_correct_args(self): for arg_limits in [None, (1, 1), 1, (1, )]: ap = ArgumentParser(USAGE, arg_limits=arg_limits) assert_equals(ap.parse_args(['hello'])[1], ['hello'])
def test_environment_variable_not_set(self): ap = ArgumentParser('Usage:\n -o --opt value', env_options='NOT_SET') opts, args = ap.parse_args(['arg']) assert_equal(opts['opt'], None) assert_equal(args, ['arg'])
class RobotParallel(object): """Robot framework parallel run for given data sources.""" def __init__(self): """Initializes robot parallel class.""" self._ap = ArgumentParser(USAGE, arg_limits=(1,), env_options='ROBOT_OPTIONS', validator=self._validate) self.inputs = { 'args': [], 'datas': [], 'output': None, 'output_dir': None, 'outputs': [], 'rerun': False, 'root_name': None, 'shell': sep == '\\', 'start_time': self._get_timestamp() } self.logger = None self.responses = None def execute(self, processor, processes=None, max_tasks=4): """Executes all prepared commands in their own respective worker.""" pool = Pool(processes=processes, maxtasksperchild=max_tasks) try: self.responses = pool.imap(processor, self.inputs['datas']) pool.close() except KeyboardInterrupt: try: pool.terminate() pool.join() # pylint: disable=undefined-variable except WindowsError: pass @staticmethod def exit(exit_code): """Exit from this run with given exit code.""" exit(exit_code) def flush_stdout(self): """Flush stdout responses.""" for response in self.responses: if not isfile(response['output']): self.inputs['outputs'].remove(response['output']) output = response['stdout'] if output != '': if self.inputs['shell']: output = output.replace('\r\n', '\n') print(output) # self.logger.console(output) def merge_results(self): """Merges all output results into one output.""" root_name = self.inputs['root_name'] options = { 'endtime': self._get_timestamp(), 'name': root_name, 'output': self.inputs['output'], 'outputdir': self.inputs['output_dir'], 'starttime': self.inputs['start_time'] } if self.inputs['rerun']: options['prerebotmodifier'] = RenameTestSuite(root_name) settings = RebotSettings(**options) result = Results(settings, *self.inputs['outputs']).result suite = ParallelTestSuite(name=options['name'], statistics=result.statistics.total) # pylint: disable=protected-access self.logger._writer.suite_separator() self.logger.end_suite(suite) return ResultWriter(*(result,)).write_results(settings) def parse_arguments(self, cli_args): """Parses data inputs dictionary from given CLI arguments.""" options, arguments = self._ap.parse_args(cli_args) self.logger = ConsoleOutput(colors=options.get('consolecolors', 'AUTO'), stderr=options.get('stderr', None), stdout=options.get('stdout', None)) self.inputs['root_name'] = options.get('name', self._get_name(arguments[0])) self.inputs['output'] = options.pop('output', 'output.xml') self.inputs['output_dir'] = abspath(options.pop('outputdir', '.')) self.inputs['rerun'] = 'rerunfailed' in options self.inputs['args'] = self._generate_worker_arguments(options) self._generate_worker_inputs(arguments) @staticmethod def _validate(options, arguments): """Validates options and arguments.""" return dict((name, value) for name, value in options.items() if value not in (None, [])), arguments def _append_worker_data(self, source): """Append source as part of worker data.""" output = 'output-%s.xml' % hexlify(urandom(16)) output_path = join(self.inputs['output_dir'], output) commands = self.inputs['args'][:] if self.inputs['rerun']: commands += ['--name', '%s.%s' % (self.inputs['root_name'], self._get_name(source, False))] commands += ['--output', output, source] self.inputs['datas'].append({'commands': commands, 'output': output_path}) self.inputs['outputs'].append(output_path) def _generate_worker_arguments(self, options): """Returns generated worker CLI arguments.""" responses = [executable, '-m', 'robot'] options['log'] = 'NONE' options.pop('name', None) options['nostatusrc'] = True options['outputdir'] = self.inputs['output_dir'] options['report'] = 'NONE' if self.inputs['rerun']: options['runemptysuite'] = True options['variable'] = options.get('variable', []) options['variable'].append('ROBOT_PARALLEL:True') for key, value in options.iteritems(): if isinstance(value, bool): responses.append('--%s' % key) elif isinstance(value, list): for item in value: responses.append('--%s' % key) responses.append(item) else: responses.append('--%s' % key) responses.append(value) return responses def _generate_worker_inputs(self, paths): """Generates worker data inputs.""" for path in paths: if isdir(path): for file_name in listdir(path): file_path = join(path, file_name) if isfile(file_path): self._append_worker_data(file_path) else: self._append_worker_data(path) @staticmethod def _get_name(path, top_level=True): """Returns suite name created from data source path.""" file_path = splitext(path)[0] target = dirname(file_path) or file_path if top_level else file_path tail = basename(target) name = tail.split('__', 1)[-1].replace('_', ' ') return name.strip().title() @staticmethod def _get_timestamp(): """Returns timestamp.""" return datetime.now().strftime('%Y%m%d%H%M%S%f')
def test_default_validation(self): ap = ArgumentParser(USAGE) for args in [(), ('1',), ('m', 'a', 'n', 'y')]: assert_equals(ap.parse_args(args)[1], list(args))
def test_default_validation(self): ap = ArgumentParser(USAGE) for args in [(), ('1', ), ('m', 'a', 'n', 'y')]: assert_equals(ap.parse_args(args)[1], list(args))
def test_reading_args_from_usage_when_it_has_just_options(self): ap = ArgumentParser('usage: test.py [options]') ap.parse_args([], check_args=True) assert_raises_with_msg(DataError, "Expected 0 arguments, got 2.", ap._check_args, ['1', '2'])
class TestArgumentParserParseArgs(unittest.TestCase): def setUp(self): self.ap = ArgumentParser(USAGE) def test_single_options(self): inargs = '-d reports --reportfile report.html -? arg'.split() exp_opts = { 'reportdir': 'reports', 'reportfile': 'report.html', 'variable': [], 'name': None, 'escape': [], 'help': True, 'version': False } exp_args = ['arg'] opts, args = self.ap.parse_args(inargs) assert_equals(opts, exp_opts) assert_equals(args, exp_args) def test_multi_options(self): inargs = '-v a:1 -v b:2 --name my_name --variable c:3 arg'.split() exp_opts = { 'variable': ['a:1', 'b:2', 'c:3'], 'name': 'my_name', 'reportdir': None, 'reportfile': None, 'escape': [], 'help': False, 'version': False } exp_args = ['arg'] opts, args = self.ap.parse_args(inargs) assert_equals(opts, exp_opts) assert_equals(args, exp_args) def test_toggle_options(self): for inargs, exp in [('arg', False), ('--help arg', True), ('--help --name whatever -h arg', False), ('-? -h --help arg', True)]: opts, args = self.ap.parse_args(inargs.split()) assert_equals(opts['help'], exp) assert_equals(args, ['arg']) def test_single_option_multiple_times(self): for inargs in [ '--name Foo -N Bar arg', '-N Zap --name Foo --name Bar arg', '-N 1 -N 2 -N 3 -h --variable foo -N 4 --name Bar arg' ]: opts, args = self.ap.parse_args(inargs.split()) assert_equals(opts['name'], 'Bar') assert_equals(args, ['arg']) def test_case_insensitive_long_options(self): opts, args = self.ap.parse_args('--EsCape X:y --HELP arg'.split()) assert_equals(opts['escape'], ['X:y']) assert_equals(opts['help'], True) assert_equals(args, ['arg']) def test_case_insensitive_long_options_with_equal_sign(self): opts, args = self.ap.parse_args('--EsCape=X:y --escAPE=ZZ'.split()) assert_equals(opts['escape'], ['X:y', 'ZZ']) assert_equals(args, []) def test_non_ascii_chars(self): ap = ArgumentParser(USAGE2) inargs = '-x foo=bar --variable a=1,2,3 arg1 arg2'.split() exp_opts = {'var-able': 'foo=bar', 'variable': 'a=1,2,3', '42': False} exp_args = ['arg1', 'arg2'] opts, args = ap.parse_args(inargs) assert_equals(opts, exp_opts) assert_equals(args, exp_args) def test_check_args_with_correct_args(self): for args in [('hello', ), ('hello world', )]: self.ap.parse_args(args, check_args=True) def test_check_args_with_wrong_number_of_args(self): for args in [(), ('arg1', 'arg2', 'arg3')]: assert_raises(DataError, self.ap._check_args, args) def test_check_variable_number_of_args(self): ap = ArgumentParser('usage: robot.py [options] args') ap.parse_args(['one_is_ok'], check_args=True) ap.parse_args(['two', 'ok'], check_args=True) ap.parse_args(['this', 'should', 'also', 'work', '!'], check_args=True) assert_raises_with_msg(DataError, "Expected at least 1 argument, got 0.", ap._check_args, []) def test_arg_limits_to_constructor(self): ap = ArgumentParser('usage: test.py [options] args', arg_limits=(2, 4)) assert_raises_with_msg(DataError, "Expected 2 to 4 arguments, got 1.", ap._check_args, ['one is not enough']) def test_reading_args_from_usage_when_it_has_just_options(self): ap = ArgumentParser('usage: test.py [options]') ap.parse_args([], check_args=True) assert_raises_with_msg(DataError, "Expected 0 arguments, got 2.", ap._check_args, ['1', '2']) def test_check_args_fails_when_no_args_specified(self): assert_raises(FrameworkError, ArgumentParser('test').parse_args, [], check_args=True) def test_unescape_options(self): cli = '--escape quot:Q -E space:SP -E lt:LT -E gt:GT ' \ + '-N QQQLTmySPfineSPnameGTQQQ sourceSPwithSPspaces' opts, args = self.ap.parse_args(cli.split(), unescape='escape') assert_equals(opts['name'], '"""<my fine name>"""') assert_equals(opts['escape'], ['quot:Q', 'space:SP', 'lt:LT', 'gt:GT']) assert_equals(args, ['source with spaces']) def test_split_pythonpath(self): ap = ArgumentParser('ignored') data = [(['path'], ['path']), (['path1', 'path2'], ['path1', 'path2']), (['path1:path2'], ['path1', 'path2']), (['p1:p2:p3', 'p4', '.'], ['p1', 'p2', 'p3', 'p4', '.'])] if os.sep == '\\': data += [(['c:\\path'], ['c:\\path']), (['c:\\path', 'd:\\path'], ['c:\\path', 'd:\\path']), (['c:\\path:d:\\path'], ['c:\\path', 'd:\\path']), (['c:/path:x:yy:d:\\path', 'c', '.', 'x:/xxx'], ['c:\\path', 'x', 'yy', 'd:\\path', 'c', '.', 'x:\\xxx'])] for inp, exp in data: assert_equals(ap._split_pythonpath(inp), exp) def test_get_pythonpath(self): ap = ArgumentParser('ignored') p1 = os.path.abspath('.') p2 = os.path.abspath('..') assert_equals(ap._get_pythonpath(p1), [p1]) assert_equals(ap._get_pythonpath([p1, p2]), [p1, p2]) assert_equals(ap._get_pythonpath([p1 + ':' + p2]), [p1, p2]) assert_true(p1 in ap._get_pythonpath(os.path.join(p2, '*'))) def test_arguments_are_globbed(self): _, args = self.ap.parse_args([__file__.replace('test_', '?????')]) assert_equals(args, [__file__]) # Needed to ensure that the globbed directory contains files globexpr = os.path.join(os.path.dirname(__file__), '*') _, args = self.ap.parse_args([globexpr]) assert_true(len(args) > 1) def test_arguments_with_glob_patterns_arent_removed_if_they_dont_match( self): _, args = self.ap.parse_args(['*.non.existing', 'non.ex.??']) assert_equals(args, ['*.non.existing', 'non.ex.??'])
def test_environment_variable_not_set(self): ap = ArgumentParser('Usage:\n -o --opt value', env_options='NOT_SET') opts, args = ap.parse_args(['arg']) assert_equals(opts['opt'], None) assert_equals(args, ['arg'])
class TestArgumentParserParseArgs(unittest.TestCase): def setUp(self): self.ap = ArgumentParser(USAGE) def test_missing_argument_file_throws_data_error(self): inargs = '--argumentfile missing_argument_file_that_really_is_not_there.txt'.split() self.assertRaises(DataError, self.ap.parse_args, inargs) def test_single_options(self): inargs = '-d reports --reportfile report.html -T arg'.split() opts, args = self.ap.parse_args(inargs) assert_equals(opts, {'reportdir':'reports', 'reportfile':'report.html', 'variable':[], 'name':None, 'toggle': True}) def test_multi_options(self): inargs = '-v a:1 -v b:2 --name my_name --variable c:3 arg'.split() opts, args = self.ap.parse_args(inargs) assert_equals(opts, {'variable':['a:1','b:2','c:3'], 'name':'my_name', 'reportdir':None, 'reportfile':None, 'toggle': False}) assert_equals(args, ['arg']) def test_toggle_options(self): for inargs, exp in [('arg', False), ('--toggle arg', True), ('--toggle --name whatever -t arg', False), ('-t -T --toggle arg', True)]: opts, args = self.ap.parse_args(inargs.split()) assert_equals(opts['toggle'], exp) assert_equals(args, ['arg']) def test_single_option_multiple_times(self): for inargs in ['--name Foo -N Bar arg', '-N Zap --name Foo --name Bar arg', '-N 1 -N 2 -N 3 -t --variable foo -N 4 --name Bar arg']: opts, args = self.ap.parse_args(inargs.split()) assert_equals(opts['name'], 'Bar') assert_equals(args, ['arg']) def test_case_insensitive_long_options(self): opts, args = self.ap.parse_args('--VarIable X:y --TOGGLE arg'.split()) assert_equals(opts['variable'], ['X:y']) assert_equals(opts['toggle'], True) assert_equals(args, ['arg']) def test_case_insensitive_long_options_with_equal_sign(self): opts, args = self.ap.parse_args('--VariAble=X:y --VARIABLE=ZzZ'.split()) assert_equals(opts['variable'], ['X:y', 'ZzZ']) assert_equals(args, []) def test_unescape_options(self): cli = '--escape quot:Q -E space:SP -E lt:LT -E gt:GT ' \ + '-N QQQLTmySPfineSPnameGTQQQ sourceSPwithSPspaces' opts, args = self.ap.parse_args(cli.split()) assert_equals(opts['name'], '"""<my fine name>"""') assert_equals(args, ['source with spaces']) assert_true('escape' not in opts) def test_split_pythonpath(self): ap = ArgumentParser('ignored') data = [(['path'], ['path']), (['path1','path2'], ['path1','path2']), (['path1:path2'], ['path1','path2']), (['p1:p2:p3','p4','.'], ['p1','p2','p3','p4','.'])] if os.sep == '\\': data += [(['c:\\path'], ['c:\\path']), (['c:\\path','d:\\path'], ['c:\\path','d:\\path']), (['c:\\path:d:\\path'], ['c:\\path','d:\\path']), (['c:/path:x:yy:d:\\path','c','.','x:/xxx'], ['c:\\path', 'x', 'yy', 'd:\\path', 'c', '.', 'x:\\xxx'])] for inp, exp in data: assert_equals(ap._split_pythonpath(inp), exp) def test_get_pythonpath(self): ap = ArgumentParser('ignored') p1 = os.path.abspath('.') p2 = os.path.abspath('..') assert_equals(ap._get_pythonpath(p1), [p1]) assert_equals(ap._get_pythonpath([p1,p2]), [p1,p2]) assert_equals(ap._get_pythonpath([p1 + ':' + p2]), [p1,p2]) assert_true(p1 in ap._get_pythonpath(os.path.join(p2,'*'))) def test_arguments_are_globbed(self): _, args = self.ap.parse_args([__file__.replace('test_', '?????')]) assert_equals(args, [__file__]) # Needed to ensure that the globbed directory contains files globexpr = os.path.join(os.path.dirname(__file__), '*') _, args = self.ap.parse_args([globexpr]) assert_true(len(args) > 1) def test_arguments_with_glob_patterns_arent_removed_if_they_dont_match(self): _, args = self.ap.parse_args(['*.non.existing', 'non.ex.??']) assert_equals(args, ['*.non.existing', 'non.ex.??']) def test_special_options_are_removed(self): ap = ArgumentParser('''Usage: -h --help -v --version --pythonpath path --escape x:y * --argumentfile path --option ''') opts, args = ap.parse_args(['--option']) assert_equals(opts, {'option': True}) def test_special_options_can_be_turned_to_normal_optios(self): ap = ArgumentParser('''Usage: -h --help -v --version --pythonpath path --escape x:y --argumentfile path ''', auto_help=False, auto_version=False, auto_escape=False, auto_pythonpath=False, auto_argumentfile=False) opts, args = ap.parse_args(['--help', '-v', '--escape', 'xxx']) assert_equals(opts, {'help': True, 'version': True, 'pythonpath': None, 'escape': 'xxx', 'argumentfile': None})
def __init__(self, file=None, encoding='cp1252', dialect='Excel-EU', delimiter=';', quotechar='"', escapechar='\\', doublequote=True, skipinitialspace=False, lineterminator='\r\n', sheet_name=0, reader_class=None, file_search_strategy='PATH', file_regex=r'(?i)(.*?)(\.csv)', include=None, exclude=None): """**Example:** .. code :: robotframework *** Settings *** Library DataDriver Options ~~~~~~~ .. code :: robotframework *** Settings *** Library DataDriver ... file=None ... encoding=cp1252 ... dialect=Excel-EU ... delimiter=; ... quotechar=" ... escapechar=\\\\ ... doublequote=True ... skipinitialspace=False ... lineterminator=\\r\\n ... sheet_name=0 ... reader_class=None ... file_search_strategy=PATH ... file_regex=(?i)(.*?)(\\.csv) ... include=None ... exclude=None | Encoding ^^^^^^^^ ``encoding`` must be set if it shall not be cp1252 **cp1252** is the same like: - Windows-1252 - Latin-1 - ANSI - Windows Western European See `Python Standard Encoding <https://docs.python.org/3/library/codecs.html#standard-encodings>`_ for more encodings | Example Excel (US / comma seperated) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Dialect Defaults: .. code :: python delimiter = ',' quotechar = '"' doublequote = True skipinitialspace = False lineterminator = '\\r\\n' quoting = QUOTE_MINIMAL Usage in Robot Framework .. code :: robotframework *** Settings *** Library DataDriver my_data_file.csv dialect=excel encoding=${None} | Example Excel Tab (\\\\t seperated) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Dialect Defaults: .. code :: python delimiter = '\\t' quotechar = '"' doublequote = True skipinitialspace = False lineterminator = '\\r\\n' quoting = QUOTE_MINIMAL Usage in Robot Framework .. code :: robotframework *** Settings *** Library DataDriver my_data_file.csv dialect=excel_tab | Example Unix Dialect ^^^^^^^^^^^^^^^^^^^^ Dialect Defaults: .. code :: python delimiter = ',' quotechar = '"' doublequote = True skipinitialspace = False lineterminator = '\\n' quoting = QUOTE_ALL Usage in Robot Framework .. code :: robotframework *** Settings *** Library DataDriver my_data_file.csv dialect=unix_dialect | Example User Defined ^^^^^^^^^^^^^^^^^^^^ User may define the format completely free. If an option is not set, the default values are used. To register a userdefined format user have to set the option ``dialect`` to ``UserDefined`` Usage in Robot Framework .. code :: robotframework *** Settings *** Library DataDriver my_data_file.csv ... dialect=UserDefined ... delimiter=. ... lineterminator=\\n """ self.ROBOT_LIBRARY_LISTENER = self try: re.compile(file_regex) except re.error as e: file_regex = r'(?i)(.*?)(\.csv)' BuiltIn().log_to_console( f'[ DataDriver ] invalid Regex! used {file_regex} instead.') BuiltIn().log_to_console(e) arg_parser = ArgumentParser(USAGE, auto_pythonpath=False, auto_argumentfile=True, env_options='ROBOT_OPTIONS') valid_args = self._filter_args(sys.argv[1:], arg_parser._short_opts, arg_parser._long_opts) options, data_sources = arg_parser.parse_args(valid_args) self.include = options['include'] if not include else include self.exclude = options['exclude'] if not exclude else exclude self.reader_config = ReaderConfig( file=file, encoding=encoding, dialect=dialect, delimiter=delimiter, quotechar=quotechar, escapechar=escapechar, doublequote=doublequote, skipinitialspace=skipinitialspace, lineterminator=lineterminator, sheet_name=sheet_name, reader_class=reader_class, file_search_strategy=file_search_strategy.upper(), file_regex=file_regex, include=self.include, exclude=self.exclude) self.suite_source = None self.template_test = None self.template_keyword = None self.data_table = None self.test_case_data = TestCaseData()