def testBraceExpand(self): arena = test_lib.MakeArena('<cmd_exec_test.py>') c_parser = test_lib.InitCommandParser('echo _{a,b}_', arena=arena) node = c_parser._ParseCommandLine() print(node) ex = test_lib.InitExecutor(arena=arena)
def testStringLineReader(self): arena = test_lib.MakeArena('<reader_test.py>') r = reader.StringLineReader('one\ntwo', arena) self.assertEqual((0, 'one\n', 0), r.GetLine()) self.assertEqual((1, 'two', 0), r.GetLine()) self.assertEqual((-1, None, 0), r.GetLine())
def _InitMem(): # empty environment, no arena. arena = test_lib.MakeArena('<state_test.py>') line_id = arena.AddLine(1, 'foo') span = ast.line_span(line_id, 0, 1) # dummy arena.AddLineSpan(span) return state.Mem('', [], {}, arena)
def ParseAndEval(code_str): arena = test_lib.MakeArena('<arith_parse_test.py>') parse_ctx = test_lib.InitParseContext(arena=arena) w_parser = test_lib.InitWordParser(code_str, arena=arena) # This is weird but works w_parser._Next(lex_mode_e.Arith) # Calling private method anode = w_parser.a_parser.Parse() print('node:', anode) mem = state.Mem('', [], arena, []) parse_opts, exec_opts, mutable_opts = state.MakeOpts(mem, None) mem.exec_opts = exec_opts state.InitMem(mem, {}, '0.1') splitter = split.SplitContext(mem) errfmt = ui.ErrorFormatter(arena) word_ev = word_eval.CompletionWordEvaluator(mem, exec_opts, mutable_opts, splitter, errfmt) arith_ev = sh_expr_eval.ArithEvaluator(mem, exec_opts, parse_ctx, arena) arith_ev.word_ev = word_ev return arith_ev.EvalToInt(anode)
def _TestGetCompletionType(buf): ev = test_lib.MakeTestEvaluator() arena = test_lib.MakeArena('<completion_test.py>') parse_ctx = parse_lib.ParseContext(arena, {}) w_parser, c_parser = parse_ctx.MakeParserForCompletion(buf, arena) print('---', buf) return completion._GetCompletionType(w_parser, c_parser, ev, debug_f)
def _MakeHistoryEvaluator(history_items): arena = test_lib.MakeArena('<reader_test.py>') trail = parse_lib.Trail() parse_ctx = parse_lib.ParseContext(arena, {}, trail=trail) debug_f = util.DebugFile(sys.stdout) readline = _MockReadlineHistory(history_items) return reader.HistoryEvaluator(readline, parse_ctx, debug_f)
def testPipeline2(self): arena = test_lib.MakeArena('testPipeline') ex = test_lib.InitExecutor(arena=arena) Banner('ls | cut -d . -f 1 | head') p = process.Pipeline() p.Add(_ExtProc(['ls'])) p.Add(_ExtProc(['cut', '-d', '.', '-f', '1'])) node = _CommandNode('head', arena) p.AddLast((ex, node)) fd_state = process.FdState() print(p.Run(_WAITER, _FD_STATE)) # Simulating subshell for each command node1 = _CommandNode('ls', arena) node2 = _CommandNode('head', arena) node3 = _CommandNode('sort --reverse', arena) p = process.Pipeline() p.Add(Process(process.SubProgramThunk(ex, node1))) p.Add(Process(process.SubProgramThunk(ex, node2))) p.Add(Process(process.SubProgramThunk(ex, node3))) last_thunk = (ex, _CommandNode('cat', arena)) p.AddLast(last_thunk) print(p.Run(_WAITER, _FD_STATE))
def testNoInfiniteLoop(self): # This was ONE place where we got an infinite loop. with open('testdata/completion/return-124.bash') as f: code_str = f.read() trail = parse_lib.Trail() arena = test_lib.MakeArena('<completion_test.py>') parse_opts = parse_lib.OilParseOptions() parse_ctx = parse_lib.ParseContext(arena, parse_opts, {}, None, trail=trail) comp_lookup = completion.Lookup() ex = test_lib.EvalCode(code_str, parse_ctx, comp_lookup=comp_lookup) r = _MakeRootCompleter(parse_ctx=parse_ctx, comp_lookup=comp_lookup) m = list(r.Matches(MockApi('bad '))) self.assertEqual([], sorted(m)) # Error: spec not changed m = list(r.Matches(MockApi('both '))) self.assertEqual([], sorted(m)) # Redefines completions m = list(r.Matches(MockApi('both2 '))) self.assertEqual(['both2 b1 ', 'both2 b2 '], sorted(m))
def setUp(self): arena = test_lib.MakeArena('<ui_test.py>') mem = state.Mem('', [], arena, []) parse_ctx = test_lib.InitParseContext() self.p = prompt.Evaluator('osh', parse_ctx, mem) # note: this has a separate 'mem' object self.p.word_ev = test_lib.InitWordEvaluator()
def testCompletesAliases(self): # I put some aliases in this file. with open('testdata/completion/osh-unit.bash') as f: code_str = f.read() trail = parse_lib.Trail() arena = test_lib.MakeArena('<completion_test.py>') parse_ctx = parse_lib.ParseContext(arena, {}, trail=trail) comp_lookup = completion.Lookup() ex = test_lib.EvalCode(code_str, parse_ctx, comp_lookup=comp_lookup) r = _MakeRootCompleter(parse_ctx=parse_ctx, comp_lookup=comp_lookup) # The original command m = list(r.Matches(MockApi('ls '))) self.assertEqual(['ls one ', 'ls two '], sorted(m)) # Alias for the command m = list(r.Matches(MockApi('ll '))) self.assertEqual(['ll one ', 'll two '], sorted(m)) # DOUBLE alias expansion goes back to original m = list(r.Matches(MockApi('ll_classify '))) self.assertEqual(['ll_classify one ', 'll_classify two '], sorted(m)) # Trailing space m = list(r.Matches(MockApi('ll_trailing '))) self.assertEqual(['ll_trailing one ', 'll_trailing two '], sorted(m)) # It should NOT clobber completio registered for aliases m = list(r.Matches(MockApi('ll_own_completion '))) self.assertEqual( ['ll_own_completion own ', 'll_own_completion words '], sorted(m))
def testRunsUserDefinedFunctions(self): # This is here because it's hard to test readline with the spec tests. with open('testdata/completion/osh-unit.bash') as f: code_str = f.read() trail = parse_lib.Trail() arena = test_lib.MakeArena('<completion_test.py>') parse_opts = parse_lib.OilParseOptions() parse_ctx = parse_lib.ParseContext(arena, parse_opts, {}, None, trail=trail) comp_lookup = completion.Lookup() ex = test_lib.EvalCode(code_str, parse_ctx, comp_lookup=comp_lookup) r = _MakeRootCompleter(comp_lookup=comp_lookup) # By default, we get a space on the end. m = list(r.Matches(MockApi('mywords t'))) self.assertEqual(['mywords three ', 'mywords two '], sorted(m)) # No space m = list(r.Matches(MockApi('mywords_nospace t'))) self.assertEqual(['mywords_nospace three', 'mywords_nospace two'], sorted(m)) # Filtered out two and bin m = list(r.Matches(MockApi('flagX '))) self.assertEqual(['flagX one ', 'flagX three '], sorted(m)) # Filter out everything EXCEPT two and bin m = list(r.Matches(MockApi('flagX_bang '))) self.assertEqual(['flagX_bang bin ', 'flagX_bang two '], sorted(m)) # -X with -P m = list(r.Matches(MockApi('flagX_prefix '))) self.assertEqual(['flagX_prefix __one ', 'flagX_prefix __three '], sorted(m)) # -P with plusdirs m = list(r.Matches(MockApi('prefix_plusdirs b'))) self.assertEqual([ 'prefix_plusdirs __bin ', 'prefix_plusdirs benchmarks/', 'prefix_plusdirs bin/', 'prefix_plusdirs build/' ], sorted(m)) # -X with plusdirs. We're filtering out bin/, and then it's added back by # plusdirs. The filter doesn't kill it. m = list(r.Matches(MockApi('flagX_plusdirs b'))) self.assertEqual([ 'flagX_plusdirs benchmarks/', 'flagX_plusdirs bin/', 'flagX_plusdirs build/' ], sorted(m)) # -P with dirnames. -P is NOT respected. m = list(r.Matches(MockApi('prefix_dirnames b'))) self.assertEqual([ 'prefix_dirnames benchmarks/', 'prefix_dirnames bin/', 'prefix_dirnames build/' ], sorted(m))
def InitCommandParser(code_str): from osh.word_parse import WordParser from osh.cmd_parse import CommandParser arena = test_lib.MakeArena('<cmd_exec_test.py>') line_reader, lexer = parse_lib.InitLexer(code_str, arena) w_parser = WordParser(lexer, line_reader) c_parser = CommandParser(w_parser, lexer, line_reader, arena) return c_parser
def _MakeParser(code_str): # NOTE: We need the extra ]] token arena = test_lib.MakeArena('<bool_parse_test.py>') w_parser = test_lib.InitWordParser(code_str + ' ]]', arena=arena) w_parser._Next(lex_mode_e.DBracket) # for tests only p = bool_parse.BoolParser(w_parser) p._Next() return p
def testBraceExpand(self): # TODO: Move this to test_lib? c_parser = InitCommandParser('echo _{a,b}_') node = c_parser._ParseCommandLine() print(node) arena = test_lib.MakeArena('<cmd_exec_test.py>') ex = test_lib.InitExecutor(arena)
def _MakeHistoryEvaluator(history_items): arena = test_lib.MakeArena('<reader_test.py>') parse_opts = parse_lib.OilParseOptions() parse_ctx = parse_lib.ParseContext(arena, parse_opts, {}, None) parse_ctx.Init_Trail(parse_lib.Trail()) debug_f = util.DebugFile(sys.stdout) readline = _MockReadlineHistory(history_items) return history.Evaluator(readline, parse_ctx, debug_f)
def testPrompt(self): arena = test_lib.MakeArena('<ui_test.py>') ex = test_lib.InitExecutor(arena=arena) p = ui.Prompt(arena, ex.parse_ctx, ex) # Rgression for caching bug! self.assertEqual('foo', p.EvalPrompt(runtime.Str('foo'))) self.assertEqual('foo', p.EvalPrompt(runtime.Str('foo')))
def _MakeParser(code_str): # NOTE: We need the extra ]] token arena = test_lib.MakeArena('<bool_parse_test.py>') parse_ctx = parse_lib.ParseContext(arena, {}) w_parser, _ = parse_ctx.MakeParserForCompletion(code_str + ' ]]', arena) w_parser._Next(lex_mode_e.DBRACKET) # for tests only p = bool_parse.BoolParser(w_parser) p._Next() return p
def _MakeParser(code_str): # NOTE: We need the extra ]] token arena = test_lib.MakeArena('<bool_parse_test.py>') w_parser, _ = parse_lib.MakeParserForCompletion(code_str + ' ]]', arena) w_parser._Next(lex_mode_e.DBRACKET) # for tests only p = bool_parse.BoolParser(w_parser) if not p._Next(): raise AssertionError return p
def _InitMem(): # empty environment, no arena. arena = test_lib.MakeArena('<state_test.py>') line_id = arena.AddLine(1, 'foo') unused = arena.AddLineSpan(line_id, 0, 1) # dummy mem = state.Mem('', [], arena, []) parse_opts, exec_opts, mutable_opts = state.MakeOpts(mem, None) mem.exec_opts = exec_opts return mem
def testEvaluator(self): arena = test_lib.MakeArena('<ui_test.py>') mem = state.Mem('', [], {}, arena) ex = test_lib.InitExecutor(arena=arena) p = prompt.Evaluator('osh', arena, ex.parse_ctx, ex, mem) # Rgression for caching bug! self.assertEqual('foo', p.EvalPrompt(value.Str('foo'))) self.assertEqual('foo', p.EvalPrompt(value.Str('foo')))
def InitExecutor(arena=None): if not arena: arena = test_lib.MakeArena('<InitExecutor>') mem = state.Mem('', [], {}, None) fd_state = process.FdState() status_lines = None # not needed for what we're testing funcs = {} comp_funcs = {} exec_opts = state.ExecOpts(mem) return cmd_exec.Executor(mem, fd_state, status_lines, funcs, completion, comp_funcs, exec_opts, arena)
def _assert_ParseCommandListError(test, code_str): arena = test_lib.MakeArena('<cmd_parse_test>') c_parser = test_lib.InitCommandParser(code_str, arena=arena) try: node = c_parser._ParseCommandLine() except error.Parse as e: ui.PrettyPrintError(e, arena) else: print('UNEXPECTED:') node.PrettyPrint() test.fail("Expected %r to fail" % code_str)
def _assertSpanForWord(test, word_str): arena = test_lib.MakeArena('word_parse_test.py') w_parser = test_lib.InitWordParser(word_str, arena=arena) w = _assertReadWordWithArena(test, w_parser) span_id = word_.LeftMostSpanForWord(w) print(word_str) print(span_id) if span_id != runtime.NO_SPID: span = arena.GetLineSpan(span_id) print(span)
def main(argv): init_code = ' echo hi >&2 ' arena = test_lib.MakeArena('<InitCompletionTest>') parse_ctx = parse_lib.ParseContext(arena, {}) mem = state.Mem('', [], {}, arena) comp_lookup = completion.Lookup() ex = test_lib.EvalCode(init_code, parse_ctx, comp_lookup=comp_lookup, mem=mem) print('hi')
def testErrorFormatter(self): arena = test_lib.MakeArena('') line_id = arena.AddLine('[line one]', 1) span_id = arena.AddLineSpan(line_id, 0, 2) spid1 = arena.AddLineSpan(line_id, 2, 2) errfmt = ui.ErrorFormatter(arena) # no location info errfmt.Print('hello') errfmt.PushLocation(span_id) errfmt.Print('zero') errfmt.Print('zero', span_id=spid1)
def ParseAndEval(code_str): arena = test_lib.MakeArena('<arith_parse_test.py>') w_parser = test_lib.InitWordParser(code_str, arena=arena) w_parser._Next(lex_mode_e.Arith) # Calling private method anode = w_parser._ReadArithExpr() # need the right lex state? print('node:', anode) mem = state.Mem('', [], {}, arena) exec_opts = state.ExecOpts(mem, None) splitter = split.SplitContext(mem) ev = word_eval.CompletionWordEvaluator(mem, exec_opts, splitter, arena) arith_ev = expr_eval.ArithEvaluator(mem, exec_opts, ev, arena) value = arith_ev.Eval(anode) return value
def _assertReadWordWithArena(test, word_str): print('\n---', word_str) arena = test_lib.MakeArena('word_parse_test.py') w_parser = _InitWordParser(word_str, arena=arena) w = w_parser.ReadWord(lex_mode_e.Outer) assert w is not None ast_lib.PrettyPrint(w) # Next word must be Eof_Real w2 = w_parser.ReadWord(lex_mode_e.Outer) test.assertTrue( test_lib.TokenWordsEqual( osh_word.TokenWord(syntax_asdl.token(Id.Eof_Real, '')), w2), w2) return arena, w
def testShellFuncExecution(self): arena = test_lib.MakeArena('testShellFuncExecution') c_parser = test_lib.InitCommandParser("""\ f() { COMPREPLY=(f1 f2) } """, arena=arena) func_node = c_parser.ParseLogicalLine() print(func_node) ex = test_lib.InitExecutor(arena=arena) a = completion.ShellFuncAction(ex, func_node) comp = self._MakeComp(['f'], 0, 'f') matches = list(a.Matches(comp)) self.assertEqual(['f1', 'f2'], matches)
def InitExecutor(arena=None): arena = arena or test_lib.MakeArena('<InitExecutor>') mem = state.Mem('', [], {}, arena) fd_state = process.FdState() funcs = {} comp_funcs = {} # For the tests, we do not use 'readline'. exec_opts = state.ExecOpts(mem, None) parse_ctx = parse_lib.ParseContext(arena, {}) debug_f = util.DebugFile(sys.stderr) devtools = dev.DevTools(dev.CrashDumper(''), debug_f, debug_f) return cmd_exec.Executor(mem, fd_state, funcs, comp_funcs, exec_opts, parse_ctx, devtools)
def testPipeline(self): arena = test_lib.MakeArena('testPipeline') node = _CommandNode('uniq -c', arena) ex = test_lib.InitExecutor(arena=arena) print('BEFORE', os.listdir('/dev/fd')) p = process.Pipeline() p.Add(_ExtProc(['ls'])) p.Add(_ExtProc(['cut', '-d', '.', '-f', '2'])) p.Add(_ExtProc(['sort'])) p.AddLast((ex, node)) pipe_status = p.Run(_WAITER, _FD_STATE) log('pipe_status: %s', pipe_status) print('AFTER', os.listdir('/dev/fd'))