~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to tests/test_bashcomp.py

Added some selftests executed through bash.

Based on a discussion with Vincent Ladeuil in the merge request proposing inclusion of the plugin into the bzr source tree:
https://code.launchpad.net/~gagern/bzr/bug560030-include-bash-completion-plugin/+merge/23912

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2010 by Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
from bzrlib.tests import TestCase, Feature
 
18
from bzrlib import commands
 
19
from StringIO import StringIO
 
20
from ..bashcomp import bash_completion_function
 
21
import os
 
22
import subprocess
 
23
 
 
24
 
 
25
class _BashFeature(Feature):
 
26
 
 
27
    bash_paths = ['/bin/bash', '/usr/bin/bash']
 
28
 
 
29
    def __init__(self):
 
30
        super(_BashFeature, self).__init__()
 
31
        self.bash_path = None
 
32
 
 
33
    def available(self):
 
34
        if self.bash_path is not None:
 
35
            return self.bash_path is not False
 
36
        for path in self.bash_paths:
 
37
            if os.access(path, os.X_OK):
 
38
                self.bash_path = path
 
39
                return True
 
40
        self.bash_path = False
 
41
        return False
 
42
 
 
43
    def feature_name(self):
 
44
        return 'bash'
 
45
 
 
46
BashFeature = _BashFeature()
 
47
 
 
48
 
 
49
class TestBashCompletion(TestCase):
 
50
 
 
51
    _test_needs_features = [BashFeature]
 
52
 
 
53
    def __init__(self, methodName='testMethod'):
 
54
        super(TestBashCompletion, self).__init__(methodName)
 
55
        self.script = None
 
56
 
 
57
    def setUp(self):
 
58
        super(TestBashCompletion, self).setUp()
 
59
        commands.install_bzr_command_hooks()
 
60
 
 
61
    def complete(self, words, cword=-1, expect=None,
 
62
                 contains=[], omits=[]):
 
63
        if self.script is None:
 
64
            self.script = self.get_script()
 
65
        proc = subprocess.Popen([BashFeature.bash_path, '--noprofile'],
 
66
                                stdin=subprocess.PIPE,
 
67
                                stdout=subprocess.PIPE,
 
68
                                stderr=subprocess.PIPE)
 
69
        if cword < 0:
 
70
            cword = len(words) + cword
 
71
        input = """
 
72
%(script)s
 
73
 
 
74
COMP_WORDS=( %(words)s )
 
75
COMP_CWORD=%(cword)d
 
76
%(name)s
 
77
echo ${#COMPREPLY[*]}
 
78
IFS=$'\\n'
 
79
echo "${COMPREPLY[*]}"
 
80
""" % { 'script': self.script,
 
81
        'words': ' '.join(["'"+w.replace("'", "'\\''")+"'" for w in words]),
 
82
        'cword': cword,
 
83
        'name': getattr(self, 'script_name', '_bzr'),
 
84
      }
 
85
        (out, err) = proc.communicate(input)
 
86
        self.assertEqual('', err, 'No messages to standard error')
 
87
        #import sys
 
88
        #print >>sys.stdout, '---\n%s\n---\n%s\n---\n' % (input, out)
 
89
        lines = out.split('\n')
 
90
        nlines = int(lines[0])
 
91
        del lines[0]
 
92
        self.assertEqual('', lines[-1], 'Newline at end')
 
93
        del lines[-1]
 
94
        if nlines == 0 and len(lines) == 1 and lines[0] == '':
 
95
            del lines[0]
 
96
        self.assertEqual(nlines, len(lines), 'No newlines in generated words')
 
97
        if expect is not None:
 
98
            self.assertEqual(expect, lines)
 
99
        for item in contains:
 
100
            self.assertTrue(item in lines)
 
101
        for item in omits:
 
102
            self.assertFalse(item in lines)
 
103
        return lines
 
104
 
 
105
    def get_script(self):
 
106
        out = StringIO()
 
107
        bash_completion_function(out, function_only=True)
 
108
        return out.getvalue()
 
109
 
 
110
    def test_simple_scipt(self):
 
111
        """Ensure that the test harness works as expected"""
 
112
        self.script = """
 
113
_bzr() {
 
114
    COMPREPLY=()
 
115
    # add all words in reverse order, with some markup around them
 
116
    for ((i = ${#COMP_WORDS[@]}; i > 0; --i)); do
 
117
        COMPREPLY+=( "-${COMP_WORDS[i-1]}+" )
 
118
    done
 
119
    # and append the current word
 
120
    COMPREPLY+=( "+${COMP_WORDS[COMP_CWORD]}-" )
 
121
}
 
122
"""
 
123
        self.complete(['foo', '"bar', "'baz"], cword=1,
 
124
                      expect=["-'baz+", '-"bar+', '-foo+', '+"bar-'])
 
125
 
 
126
    def test_cmd_ini(self):
 
127
        c = self.complete(['bzr', 'ini'],
 
128
                          contains=['init', 'init-repo', 'init-repository'])
 
129
        self.assertFalse('commit' in c)
 
130
 
 
131
    def test_init_opts(self):
 
132
        c = self.complete(['bzr', 'init', '-'],
 
133
                          contains=['-h', '--2a', '--format=2a'])
 
134
 
 
135
    def test_global_opts(self):
 
136
        c = self.complete(['bzr', '-', 'init'], cword=1,
 
137
                          contains=['--no-plugins', '-?'])
 
138
 
 
139
    def test_commit_dashm(self):
 
140
        c = self.complete(['bzr', 'commit', '-m'], expect=['-m'])
 
141
 
 
142
    def test_status_negated(self):
 
143
        c = self.complete(['bzr', 'status', '--n'],
 
144
                          contains=['--no-versioned', '--no-verbose'])
 
145
 
 
146
    def test_init_format_any(self):
 
147
        c = self.complete(['bzr', 'init', '--format', '=', 'directory'],
 
148
                          cword=3, contains=['1.9', '2a'])
 
149
 
 
150
    def test_init_format_2(self):
 
151
        c = self.complete(['bzr', 'init', '--format', '=', '2', 'directory'],
 
152
                          cword=4, contains=['2a'], omits=['1.9'])