Beispiel #1
0
    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 = alloc.SideArena('<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))
Beispiel #2
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))
Beispiel #3
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()
        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))
Beispiel #4
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))
Beispiel #5
0
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')
Beispiel #6
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()
        trail = parse_lib.Trail()
        arena = alloc.SideArena('<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(comp_lookup=comp_lookup)

        # By default, we get a space on the end.
        m = list(r.Matches(MockApi('mywords t')))
        self.assertEqual(['three ', 'two '], sorted(m))

        # No space
        m = list(r.Matches(MockApi('mywords_nospace t')))
        self.assertEqual(['three', 'two'], sorted(m))

        # Filtered out two and bin
        m = list(r.Matches(MockApi('flagX ')))
        self.assertEqual(['one ', 'three '], sorted(m))

        # Filter out everything EXCEPT two and bin
        m = list(r.Matches(MockApi('flagX_bang ')))
        self.assertEqual(['bin ', 'two '], sorted(m))

        # -X with -P
        m = list(r.Matches(MockApi('flagX_prefix ')))
        self.assertEqual(['__one ', '__three '], sorted(m))

        # TODO: Fix these!

        # -P with plusdirs
        m = list(r.Matches(MockApi('prefix_plusdirs b')))
        self.assertEqual(['__bin ', 'benchmarks/', 'bin/', '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(['benchmarks/', 'bin/', 'build/'], sorted(m))

        # -P with dirnames.  -P is NOT respected.
        m = list(r.Matches(MockApi('prefix_dirnames b')))
        self.assertEqual(['benchmarks/', 'bin/', 'build/'], sorted(m))
Beispiel #7
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 = parse_lib.ParseContext(arena, {})
            mem = state.Mem('', [], {}, arena)

            #
            # 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()
            ex = 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.GetVar('PASSED')
            self.assertEqual(value_e.StrArray, val.tag,
                             "Expected array, got %s" % 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))