Exemple #1
0
def _MakeHistoryEvaluator(history_items):
  parse_ctx = test_lib.InitParseContext()
  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)
Exemple #2
0
  def testCompletesAliases(self):
    # I put some aliases in this file.
    with open('testdata/completion/osh-unit.bash') as f:
      code_str = f.read()
    aliases = {}
    parse_ctx = test_lib.InitParseContext(aliases=aliases)
    parse_ctx.Init_Trail(parse_lib.Trail())
    comp_lookup = completion.Lookup()

    cmd_ev = test_lib.EvalCode(code_str, parse_ctx, comp_lookup=comp_lookup,
                           aliases=aliases)

    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))
Exemple #3
0
def _MakeRootCompleter(parse_ctx=None, comp_lookup=None):
  compopt_state = completion.OptionState()
  comp_ui_state = comp_ui.State()
  comp_lookup = comp_lookup or completion.Lookup()

  mem = state.Mem('', [], None, [])
  parse_opts, exec_opts, mutable_opts = state.MakeOpts(mem, None)
  mem.exec_opts = exec_opts

  state.InitMem(mem, {}, '0.1')
  mutable_opts.Init()

  if not parse_ctx:
    parse_ctx = test_lib.InitParseContext(parse_opts=parse_opts)
    parse_ctx.Init_Trail(parse_lib.Trail())
    parse_ctx.Init_OnePassParse(True)

  if 1:  # enable for details
    debug_f = util.DebugFile(sys.stdout)
  else:
    debug_f = util.NullDebugFile()

  ev = test_lib.InitWordEvaluator(exec_opts=exec_opts)
  return completion.RootCompleter(ev, mem, comp_lookup, compopt_state,
                                  comp_ui_state, parse_ctx, debug_f)
Exemple #4
0
  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()

    parse_ctx = test_lib.InitParseContext()
    parse_ctx.Init_Trail(parse_lib.Trail())

    comp_lookup = completion.Lookup()
    cmd_ev = 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))

    # next 3 fail on darwin
    if not IS_DARWIN:
        # 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))

    if not IS_DARWIN:
        # -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))
Exemple #5
0
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)
Exemple #6
0
    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()
        parse_ctx = test_lib.InitParseContext()
        parse_ctx.Init_Trail(parse_lib.Trail())

        comp_lookup = completion.Lookup()
        cmd_ev = 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()
Exemple #8
0
    def setUp(self):
        """Done on every test."""
        self.arena = alloc.Arena()
        self.arena.PushSource(source.Unused(''))

        loader = pyutil.GetResourceLoader()
        oil_grammar = meta.LoadOilGrammar(loader)

        self.parse_ctx = test_lib.InitParseContext(arena=self.arena,
                                                   oil_grammar=oil_grammar)
        self.parse_ctx.Init_OnePassParse(True)
Exemple #9
0
def _Detect(test, word_str, expected):
    # TODO: This function could be moved to test_lib.
    log('-' * 80)
    w = word_parse_test._assertReadWord(test, word_str)

    actual = word_.DetectShAssignment(w)
    left_token, close_token, part_offset = actual

    expected_left, expected_close, expected_part_offset = expected

    print(left_token, close_token, part_offset)
    print()

    if expected_left is None:
        test.assertEqual(None, left_token)
    else:
        test.assertEqual(expected_left, left_token.id)

    if expected_close is None:
        test.assertEqual(None, close_token)
    else:
        test.assertEqual(expected_left, left_token.id)

    test.assertEqual(expected_part_offset, part_offset)

    parse_ctx = test_lib.InitParseContext()

    if left_token and left_token.id in (Id.Lit_VarLike, Id.Lit_ArrayLhsOpen):
        more_env = []
        preparsed = (left_token, close_token, part_offset, w)
        try:
            cmd_parse._AppendMoreEnv([preparsed], more_env)
        except Exception as e:
            log('Error: %s', e)
        else:
            log('more_env: %s', more_env)

        try:
            assign_pair = cmd_parse._MakeAssignPair(parse_ctx, preparsed)
        except Exception as e:
            log('Error: %s', e)
        else:
            log('assign_pair: %s', assign_pair)
Exemple #10
0
  def testMatchesOracle(self):
    for i, case in enumerate(bash_oracle.CASES):  # generated data
      flags = case.get('_init_completion_flags')
      if flags is None:
        continue

      # This was input
      code_str = case['code']
      assert code_str.endswith('\t')

      log('')
      log('--- Case %d: %r with flags %s', i, code_str, flags)
      log('')
      #print(case)

      oracle_comp_words = case['COMP_WORDS']
      oracle_comp_cword = case['COMP_CWORD']
      oracle_comp_line = case['COMP_LINE']
      oracle_comp_point = case['COMP_POINT']

      # Init completion data
      oracle_words = case['words']
      oracle_cur = case['cur']
      oracle_prev = case['prev']
      oracle_cword = case['cword']
      oracle_split = case['split']

      #
      # First test some invariants on the oracle's data.
      #

      self.assertEqual(code_str[:-1], oracle_comp_line)
      # weird invariant that always holds.  So isn't COMP_CWORD useless?
      self.assertEqual(int(oracle_comp_cword), len(oracle_comp_words)-1)
      # Another weird invariant.  Note this is from the bash ORACLE, not from
      # our mocks.
      self.assertEqual(int(oracle_comp_point), len(code_str) - 1)

      #
      # Now run a piece of code that compares OSH's actual data against the
      # oracle.
      #

      init_code = _INIT_TEMPLATE % {
        'flags': ' '.join(flags),
        'command': oracle_comp_words[0]
      }

      arena = test_lib.MakeArena('<InitCompletionTest>')
      parse_ctx = test_lib.InitParseContext(arena=arena)
      mem = state.Mem('', [], arena, [])
      parse_opts, exec_opts, mutable_opts = state.MakeOpts(mem, None)
      mem.exec_opts = exec_opts

      mutable_opts.Init()

      #
      # Allow our code to access oracle data
      #
      state.SetGlobalArray(mem, 'ORACLE_COMP_WORDS', oracle_comp_words)
      state.SetGlobalString(mem, 'ORACLE_COMP_CWORD', oracle_comp_cword)
      state.SetGlobalString(mem, 'ORACLE_COMP_LINE', oracle_comp_line)
      state.SetGlobalString(mem, 'ORACLE_COMP_POINT', oracle_comp_point)

      state.SetGlobalArray(mem, 'ORACLE_words', oracle_words)
      state.SetGlobalString(mem, 'ORACLE_cur', oracle_cur)
      state.SetGlobalString(mem, 'ORACLE_prev', oracle_prev)
      state.SetGlobalString(mem, 'ORACLE_cword', oracle_cword)
      state.SetGlobalString(mem, 'ORACLE_split', oracle_split)

      comp_lookup = completion.Lookup()
      cmd_ev = test_lib.EvalCode(init_code, parse_ctx, comp_lookup=comp_lookup,
                             mem=mem)

      r = _MakeRootCompleter(comp_lookup=comp_lookup)
      comp = MockApi(code_str[:-1])
      m = list(r.Matches(comp))
      log('matches = %s', m)

      # Unterminated quote in case 5.  Nothing to complete.
      # TODO: use a label
      if i == 5:
        continue

      # Our test shell script records what passed in an array.
      val = mem.GetValue('PASSED')
      self.assertEqual(value_e.MaybeStrArray, val.tag,
          "[case %d] Expected array, got %s" % (i, val))
      actually_passed = val.strs

      should_pass = [
          'COMP_WORDS', 'COMP_CWORD', 'COMP_LINE', 'COMP_POINT',  # old API
          'words', 'cur', 'prev', 'cword', 'split'  # new API
      ]

      if i == 4:
        should_pass.remove('COMP_WORDS')
        should_pass.remove('COMP_CWORD')
        should_pass.remove('cword')
        should_pass.remove('words')  # double quotes aren't the same

      for t in should_pass:
        self.assert_(
            t in actually_passed, "%r was expected to pass (case %d)" % (t, i))

    log('Ran %d cases', len(bash_oracle.CASES))