def test_scl_with_nested_calls(self): # https://github.com/bkabrda/devassistant/issues/234 # tests proper nesting of SCL commands and also elimination of identical calls inp = [{ 'scl enable hamham foo': [{ 'scl enable spamspam': [{ 'cl': 'ls' }] }] }] c = Command('scl enable spamspam', inp) with pytest.raises(RunException): c.run() # make sure to remove scl command processors from ClHelper ClHelper.command_processors = {} res_lines = [[ 'scl enable spamspam - << DA_SCL_enable_spamspam_EOF', 'scl enable hamham foo - << DA_SCL_enable_hamham_foo_EOF', 'ls', 'DA_SCL_enable_hamham_foo_EOF', 'DA_SCL_enable_spamspam_EOF' ]] # shuffle first two and last two lines to get possible permutations of scl # call order (command processors are in dict, which has arbitrary order) res_lines.append(copy.deepcopy(res_lines[0])) res_lines[1][0], res_lines[1][1] = res_lines[1][1], res_lines[1][0] res_lines[1][3], res_lines[1][4] = res_lines[1][4], res_lines[1][3] assert ('DEBUG', '\n'.join(res_lines[0])) in self.tlh.msgs or \ ('DEBUG', '\n'.join(res_lines[1])) in self.tlh.msgs
def test_overrides_core_runners(self): Command('load_cmd', 'crt/commands/log.py').run() r = Command('log_i', 'message').run() assert ('INFO', 'Got you!') in self.tlh.msgs assert ('INFO', 'message') not in self.tlh.msgs assert r == (True, 'heee heee')
def test_run_with_specified_args(self): kwargs = { 'spam': 'something', 'nospam': 'hahaha', '__magic_val__': 'it\'s magical', '__assistant__': self.ass['leaf'] } com = Command( 'use', { 'sect': 'self.run', 'args': { 'spam': 'something else', 'spam2': 'blah' } }, kwargs) class Matcher(object): def __eq__(self, other): assert len(other) == 4 assert other['spam'] == 'something else' assert other['spam2'] == 'blah' assert other['__magic_val__'] == 'it\'s magical' assert '__assistant__' in other return True flexmock(lang).should_receive('run_section').with_args(list, Matcher()) com.run()
def test_correct_cases(self, tmpdir, path, comm_args, normalized, varnames): if not varnames: varnames = ['contdir', 'topdir', 'topdir_normalized'] kwargs = {'name': path} comm_args['from'] = '$name' c = Command('setup_project_dir', comm_args, kwargs=kwargs) with tmpdir.as_cwd(): ret = c.run() create_topdir = comm_args.get('create_topdir', True) p = path if create_topdir is True: assert ret == (True, p) elif create_topdir == 'normalized': p = os.path.join(os.path.dirname(path), normalized) assert ret == (True, p) else: p = os.path.dirname(path) assert ret == (True, p) assert os.path.isdir(p) # if os.path.dirname(path) == '', then '.' should be saved instead assert kwargs[varnames[0]] == (os.path.dirname(path) or '.') assert kwargs[varnames[1]] == os.path.basename(path) assert kwargs[varnames[2]] == normalized
def test_scl_passes_scls_list_to_command_invocation(self): # please don't use $__scls__ in actual assistants :) # scl runner has to use the unformatted input inp = [{'log_i': '$__scls__'}] c = Command('scl enable foo bar', inp) c.run() assert ('INFO', "[['enable', 'foo', 'bar']]") in self.tlh.msgs
def test_doesn_fail_when_dir_exists_but_overrided(self, tmpdir): c = Command('setup_project_dir', { 'from': 'foo', 'on_existing': 'pass' }) with tmpdir.as_cwd(): os.makedirs('foo') assert c.run() == (True, 'foo')
def test_scl_passes_scls_list_to_command_invocation(self): # please don't use $__scls__ in actual assistants :) # scl runner has to use the unformatted input inp = [{'log_i': '$__scls__'}] fmtd_inp = [{'log_i': 'this should not be used'}] c = Command('scl enable foo bar', inp) c.run() assert ('INFO', "[['enable', 'foo', 'bar']]") in self.tlh.msgs
def test_render_dir(self, tmpdir): dr = 'dirwithmoretemplates' self.make_sure_file_does_not_exists(tmpdir, dr) inp = {'template': {'source': dr}, 'data': {'foo': 'foo', 'bar': 'bar'}, 'destination': tmpdir.strpath} c = Command('jinja_render_dir', inp, kwargs={'__files_dir__': [self.filesdir]}) c.run() assert self.is_file_exists(tmpdir, 'asd') and self.get_file_contents(tmpdir, 'asd') == 'foo' assert self.is_file_exists(tmpdir, 'foo/sdf') and self.get_file_contents(tmpdir, 'foo/sdf') == 'bar'
def test_render_tpl_file_default_case_2(self, tmpdir): fn = 'jinja_template.py' # Case 2: output filename will be the same! fntpl = fn self.make_sure_file_does_not_exists(tmpdir, fn) inp = {'template': {'source': fntpl}, 'data': {'what': 'foo'}, 'destination': tmpdir.strpath} c = Command('jinja_render', inp, kwargs={'__files_dir__': [self.filesdir]}) c.run() assert self.is_file_exists(tmpdir, fn) and self.get_file_contents(tmpdir, fn) == 'print("foo")'
def test_render_tpl_file_set_output_case(self, tmpdir): # Case 3: set desired output name explicitly fn ='rendered_jinja_template.py' fntpl = 'jinja_template.py.tpl' self.make_sure_file_does_not_exists(tmpdir, fn) inp = {'template': {'source': fntpl}, 'data': {'what': 'foo'}, 'output': fn, 'destination': tmpdir.strpath} c = Command('jinja_render', inp, kwargs={'__files_dir__': [self.filesdir]}) c.run() assert self.is_file_exists(tmpdir, fn) and self.get_file_contents(tmpdir, fn) == 'print("foo")'
def test_render_with_tpl_in_file_subdir(self, tmpdir): # if we get a template with source e.g. dirwithmoretemplates/foo.tpl, # we should still get just foo.tpl without the subdir as a result fn = 'asd' fntpl = 'dirwithmoretemplates/asd.tpl' self.make_sure_file_does_not_exists(tmpdir, fn) inp = {'template': {'source': fntpl}, 'data': {'foo': 'foo'}, 'output': fn, 'destination': tmpdir.strpath} c = Command('jinja_render', inp, kwargs={'__files_dir__': [self.filesdir]}) c.run() assert self.is_file_exists(tmpdir, fn) and self.get_file_contents(tmpdir, fn) == 'foo'
def _test_loaded_commands_work(self, prefix='', which=['CR1', 'CR2']): if 'CR1' in which: r1 = Command(prefix + 'barbarbar', 'foo').run() assert ('INFO', 'CR1: Doing something ...') in self.tlh.msgs assert r1 == (True, 'foobar') else: with pytest.raises(CommandException): Command(prefix + 'barbarbar', 'foo').run() if 'CR2' in which: r2 = Command(prefix + 'spamspamspam', 'foo').run() assert ('INFO', 'CR2: Doing something ...') in self.tlh.msgs assert r2 == (True, 'foospam') else: with pytest.raises(CommandException): Command(prefix + 'spamspamspam', 'foo').run()
def test_passes_env(self): self.cl( Command('cl_i', 'echo $DEVASSISTANTTESTFOO', kwargs={'__env__': { 'DEVASSISTANTTESTFOO': 'foo' }})).run() assert ('INFO', 'foo') in self.tlh.msgs
def test_run_password(self): flexmock(DialogHelper) DialogHelper.should_receive('ask_for_password').and_return('foobar') comm = Command('ask_password', {}, {'__ui__': 'cli'}) res = self.acr(comm).run() assert res[0] is True assert res[1] == 'foobar'
def test_run_confirm(self, decision): flexmock(DialogHelper) DialogHelper.should_receive('ask_for_confirm_with_message').and_return( decision) comm = Command('ask_confirm', {}, {'__ui__': 'cli'}) res = self.acr(comm).run() assert res[0] is decision assert res[1] == decision
def test_run_input(self, inp): flexmock(DialogHelper) DialogHelper.should_receive('ask_for_input_with_prompt').and_return( inp) comm = Command('ask_input', {}, {'__ui__': 'cli'}) res = self.acr(comm).run() assert res[0] is bool(inp) assert res[1] == inp
def test_basic(self): r = Command('load_cmd', { 'source': 'a.py' }, { '__files_dir__': [self.fixtures] }).run() assert r[0] == True assert set(r[1]) == set(['CR1', 'CR2']) self._test_loaded_commands_work()
def test_render_tpl_file_default_case_2(self, tmpdir): fn = 'jinja_template.py' # Case 2: output filename will be the same! fntpl = fn self.make_sure_file_does_not_exists(tmpdir, fn) inp = { 'template': { 'source': fntpl }, 'data': { 'what': 'foo' }, 'destination': tmpdir.strpath } c = Command('jinja_render', inp, kwargs={'__files_dir__': [self.filesdir]}) c.run() assert self.is_file_exists(tmpdir, fn) and \ self.get_file_contents(tmpdir, fn) == 'print("foo")'
def test_prefix(self): r = Command('load_cmd', { 'from_file': 'crt/commands/a.py', 'prefix': 'prefix' }).run() assert r[0] == True assert set(r[1]) == set(['CR1', 'CR2']) self._test_loaded_commands_work(prefix='prefix.') # also test that they're not loaded in the '' prefix self._test_loaded_commands_work(which=[])
def test_run_with_specified_args(self): kwargs = {'spam': 'something', 'nospam': 'hahaha', '__magic_val__': 'it\'s magical', '__assistant__': self.ass['leaf']} com = Command('use', {'sect': 'self.run', 'args': {'spam': 'something else', 'spam2': 'blah'}}, kwargs) class Matcher(object): def __eq__(self, other): assert len(other) == 4 assert other['spam'] == 'something else' assert other['spam2'] == 'blah' assert other['__magic_val__'] == 'it\'s magical' assert '__assistant__' in other return True flexmock(lang).should_receive('run_section').with_args(list, Matcher()) com.run()
def test_scl_with_nested_calls(self): # https://github.com/bkabrda/devassistant/issues/234 # tests proper nesting of SCL commands and also elimination of identical calls inp = [{'scl enable hamham foo': [{'scl enable spamspam': [{'cl': 'ls'}]}]}] c = Command('scl enable spamspam', inp) with pytest.raises(RunException): c.run() # make sure to remove scl command processors from ClHelper ClHelper.command_processors = {} res_lines = [['scl enable spamspam - << DA_SCL_enable_spamspam_EOF', 'scl enable hamham foo - << DA_SCL_enable_hamham_foo_EOF', 'ls', 'DA_SCL_enable_hamham_foo_EOF', 'DA_SCL_enable_spamspam_EOF']] # shuffle first two and last two lines to get possible permutations of scl # call order (command processors are in dict, which has arbitrary order) res_lines.append(copy.deepcopy(res_lines[0])) res_lines[1][0], res_lines[1][1] = res_lines[1][1], res_lines[1][0] res_lines[1][3], res_lines[1][4] = res_lines[1][4], res_lines[1][3] assert ('DEBUG', '\n'.join(res_lines[0])) in self.tlh.msgs or \ ('DEBUG', '\n'.join(res_lines[1])) in self.tlh.msgs
def test_load_only(self): r = Command('load_cmd', { 'from_file': { 'source': 'a.py' }, 'load_only': 'CR1' }, { '__files_dir__': [self.fixtures] }).run() assert r == (True, ['CR1']) self._test_loaded_commands_work(which=['CR1'])
def test_render_tpl_file_set_output_case(self, tmpdir): # Case 3: set desired output name explicitly fn = 'rendered_jinja_template.py' fntpl = 'jinja_template.py.tpl' self.make_sure_file_does_not_exists(tmpdir, fn) inp = { 'template': { 'source': fntpl }, 'data': { 'what': 'foo' }, 'output': fn, 'destination': tmpdir.strpath } c = Command('jinja_render', inp, kwargs={'__files_dir__': [self.filesdir]}) c.run() assert self.is_file_exists(tmpdir, fn) and \ self.get_file_contents(tmpdir, fn) == 'print("foo")'
def test_render_dir(self, tmpdir): dr = 'dirwithmoretemplates' self.make_sure_file_does_not_exists(tmpdir, dr) inp = { 'template': { 'source': dr }, 'data': { 'foo': 'foo', 'bar': 'bar' }, 'destination': tmpdir.strpath } c = Command('jinja_render_dir', inp, kwargs={'__files_dir__': [self.filesdir]}) c.run() assert self.is_file_exists(tmpdir, 'asd') and \ self.get_file_contents(tmpdir, 'asd') == 'foo' assert self.is_file_exists(tmpdir, 'foo/sdf') and \ self.get_file_contents(tmpdir, 'foo/sdf') == 'bar'
def test_render_with_tpl_in_file_subdir(self, tmpdir): # if we get a template with source e.g. dirwithmoretemplates/foo.tpl, # we should still get just foo.tpl without the subdir as a result fn = 'asd' fntpl = 'dirwithmoretemplates/asd.tpl' self.make_sure_file_does_not_exists(tmpdir, fn) inp = { 'template': { 'source': fntpl }, 'data': { 'foo': 'foo' }, 'output': fn, 'destination': tmpdir.strpath } c = Command('jinja_render', inp, kwargs={'__files_dir__': [self.filesdir]}) c.run() assert self.is_file_exists(tmpdir, fn) and self.get_file_contents( tmpdir, fn) == 'foo'
def test_set(self): res = EnvCommandRunner( Command('env_set', { 'foo': 'changed', 'some': 'value' }, self.kwargs)).run() assert res == (True, {'foo': 'changed', 'some': 'value'}) assert self.kwargs == { '__env__': { 'foo': 'changed', 'some': 'value', 'spam': 'spam' } }
def test_fails_when_dir_exists(self, tmpdir): c = Command('setup_project_dir', {'from': 'foo'}) with tmpdir.as_cwd(): open('foo', 'w').close() with pytest.raises(CommandException): c.run()
def test_doesn_fail_when_dir_exists_but_overrided(self, tmpdir): c = Command('setup_project_dir', {'from': 'foo', 'on_existing': 'pass'}) with tmpdir.as_cwd(): os.makedirs('foo') assert c.run() == (True, 'foo')
def test_log_wrong_level(self): with pytest.raises(CommandException): self.l(Command('log_b', 'bar')).run()
def test_failure_cases(self, inp): c = Command('setup_project_dir', inp) with pytest.raises(CommandException): c.run()
def test_replaces_bad_chars_with_underscores(self): bad_string = '-+\\|()[]{}<>,./:\'" \t;`!@#$%^&*' self.n(Command('normalize', bad_string)).run() == (True, '_' * len(bad_string))
def test_strips_digits_at_start(self): self.n(Command('normalize', '42blah')).run() == (True, 'blah')
def test_unset_more(self): res = EnvCommandRunner( Command('env_unset', ['foo', 'spam'], self.kwargs)).run() assert res == (True, {'foo': 'bar', 'spam': 'spam'}) assert self.kwargs == {'__env__': {}}
def test_matches(self): assert self.ccr.matches(Command('use', None)) assert not self.ccr.matches(Command('foo', None))
def test_unicode_chars(self): s = 'ěšč' assert self.n(Command('normalize', s)).run() == (True, 'esc') s = u'ěšč' assert self.n(Command('normalize', s)).run() == (True, 'esc')
def test_ok_chars(self): i = {'what': 'foo-bar.+*', 'ok_chars': '-.'} assert self.n(Command('normalize', i)).run() == (True, 'foo-bar.__')
def _run_pingpong(self, script, ctxt): return Command( 'pingpong', '{0} {1}'.format(sys.executable, os.path.join(self.fixtures, script)), ctxt).run()
def test_specified_by_string(self): r = Command('load_cmd', 'crt/commands/a.py').run() assert r[0] == True assert set(r[1]) == set(['CR1', 'CR2']) self._test_loaded_commands_work()