/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
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
0.32.5 by Martin von Gagern
Test bash completion for tags.
17
from bzrlib.tests import TestCase, TestCaseWithTransport, Feature
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
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):
0.32.5 by Martin von Gagern
Test bash completion for tags.
26
    """Feature testing whether a bash executable is available."""
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
27
28
    bash_paths = ['/bin/bash', '/usr/bin/bash']
29
30
    def __init__(self):
31
        super(_BashFeature, self).__init__()
32
        self.bash_path = None
33
34
    def available(self):
35
        if self.bash_path is not None:
36
            return self.bash_path is not False
37
        for path in self.bash_paths:
38
            if os.access(path, os.X_OK):
39
                self.bash_path = path
40
                return True
41
        self.bash_path = False
42
        return False
43
44
    def feature_name(self):
45
        return 'bash'
46
47
BashFeature = _BashFeature()
48
49
0.32.5 by Martin von Gagern
Test bash completion for tags.
50
class BashCompletionMixin(object):
51
    """Component for testing execution of a bash completion script."""
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
52
53
    _test_needs_features = [BashFeature]
54
55
    def complete(self, words, cword=-1, expect=None,
56
                 contains=[], omits=[]):
0.32.5 by Martin von Gagern
Test bash completion for tags.
57
        """Perform a bash completion.
58
59
        :param words: a list of words representing the current command.
60
        :param cword: the current word to complete, defaults to the last one.
61
        :param expect: an exact iterable of expected completions.
62
        :param contains: an iterable of words required in the completion result.
63
        :param omits: an iterable of words forbidden in the completion result.
64
        """
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
65
        if self.script is None:
66
            self.script = self.get_script()
67
        proc = subprocess.Popen([BashFeature.bash_path, '--noprofile'],
68
                                stdin=subprocess.PIPE,
69
                                stdout=subprocess.PIPE,
70
                                stderr=subprocess.PIPE)
71
        if cword < 0:
72
            cword = len(words) + cword
0.32.6 by Martin von Gagern
Reformat bash input snippet.
73
        input = '%s\n' % self.script
74
        input += ('COMP_WORDS=( %s )\n' %
75
                  ' '.join(["'"+w.replace("'", "'\\''")+"'" for w in words]))
76
        input += 'COMP_CWORD=%d\n' % cword
77
        input += '%s\n' % getattr(self, 'script_name', '_bzr')
78
        input += 'echo ${#COMPREPLY[*]}\n'
79
        input += "IFS=$'\\n'\n"
80
        input += 'echo "${COMPREPLY[*]}"\n'
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
81
        (out, err) = proc.communicate(input)
0.32.5 by Martin von Gagern
Test bash completion for tags.
82
        if '' != err:
83
            raise AssertionError('Unexpected error message:\n%s' % err)
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
84
        self.assertEqual('', err, 'No messages to standard error')
85
        #import sys
86
        #print >>sys.stdout, '---\n%s\n---\n%s\n---\n' % (input, out)
87
        lines = out.split('\n')
88
        nlines = int(lines[0])
89
        del lines[0]
90
        self.assertEqual('', lines[-1], 'Newline at end')
91
        del lines[-1]
92
        if nlines == 0 and len(lines) == 1 and lines[0] == '':
93
            del lines[0]
94
        self.assertEqual(nlines, len(lines), 'No newlines in generated words')
0.32.5 by Martin von Gagern
Test bash completion for tags.
95
        res = set(lines)
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
96
        if expect is not None:
0.32.5 by Martin von Gagern
Test bash completion for tags.
97
            self.assertEqual(set(expect), res)
98
        missing = set(contains) - res
99
        if missing:
100
            raise AssertionError('Completion should contain %r but it has %r'
101
                                 % (missing, res))
102
        surplus = set(omits) & res
103
        if surplus:
104
            raise AssertionError('Completion should omit %r but it has %r'
105
                                 % (surplus, res))
106
        return res
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
107
108
    def get_script(self):
109
        out = StringIO()
110
        bash_completion_function(out, function_only=True)
111
        return out.getvalue()
112
0.32.5 by Martin von Gagern
Test bash completion for tags.
113
114
class TestBashCompletion(TestCase, BashCompletionMixin):
115
    """Test bash completions that don't execute bzr."""
116
117
    def __init__(self, methodName='testMethod'):
118
        super(TestBashCompletion, self).__init__(methodName)
119
        self.script = None
120
121
    def setUp(self):
122
        super(TestBashCompletion, self).setUp()
123
        commands.install_bzr_command_hooks()
124
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
125
    def test_simple_scipt(self):
126
        """Ensure that the test harness works as expected"""
127
        self.script = """
128
_bzr() {
129
    COMPREPLY=()
130
    # add all words in reverse order, with some markup around them
131
    for ((i = ${#COMP_WORDS[@]}; i > 0; --i)); do
132
        COMPREPLY+=( "-${COMP_WORDS[i-1]}+" )
133
    done
134
    # and append the current word
135
    COMPREPLY+=( "+${COMP_WORDS[COMP_CWORD]}-" )
136
}
137
"""
138
        self.complete(['foo', '"bar', "'baz"], cword=1,
139
                      expect=["-'baz+", '-"bar+', '-foo+', '+"bar-'])
140
141
    def test_cmd_ini(self):
142
        c = self.complete(['bzr', 'ini'],
143
                          contains=['init', 'init-repo', 'init-repository'])
144
        self.assertFalse('commit' in c)
145
146
    def test_init_opts(self):
147
        c = self.complete(['bzr', 'init', '-'],
148
                          contains=['-h', '--2a', '--format=2a'])
149
150
    def test_global_opts(self):
151
        c = self.complete(['bzr', '-', 'init'], cword=1,
152
                          contains=['--no-plugins', '-?'])
153
154
    def test_commit_dashm(self):
155
        c = self.complete(['bzr', 'commit', '-m'], expect=['-m'])
156
157
    def test_status_negated(self):
158
        c = self.complete(['bzr', 'status', '--n'],
159
                          contains=['--no-versioned', '--no-verbose'])
160
161
    def test_init_format_any(self):
162
        c = self.complete(['bzr', 'init', '--format', '=', 'directory'],
163
                          cword=3, contains=['1.9', '2a'])
164
165
    def test_init_format_2(self):
166
        c = self.complete(['bzr', 'init', '--format', '=', '2', 'directory'],
167
                          cword=4, contains=['2a'], omits=['1.9'])
0.32.5 by Martin von Gagern
Test bash completion for tags.
168
169
170
class TestBashCompletionInvoking(TestCaseWithTransport, BashCompletionMixin):
171
    """Test bash completions that might execute bzr.
172
173
    Only the syntax ``$(bzr ...`` is supported so far. The bzr command
174
    will be replaced by the bzr instance running this selftest.
175
    """
176
177
    def __init__(self, methodName='testMethod'):
178
        super(TestBashCompletionInvoking, self).__init__(methodName)
179
        self.script = None
180
181
    def setUp(self):
182
        super(TestBashCompletionInvoking, self).setUp()
183
        commands.install_bzr_command_hooks()
184
185
    def get_script(self):
186
        s = super(TestBashCompletionInvoking, self).get_script()
187
        return s.replace("$(bzr ", "$('%s' " % self.get_bzr_path())
188
189
    def test_revspec_tag_all(self):
190
        wt = self.make_branch_and_tree('.', format='2a')
191
        wt.branch.tags.set_tag('tag1', 'null:')
192
        wt.branch.tags.set_tag('tag2', 'null:')
193
        wt.branch.tags.set_tag('3tag', 'null:')
194
        self.complete(['bzr', 'log', '-r', 'tag', ':'],
195
                      expect=['tag1', 'tag2', '3tag'])
196
197
    def test_revspec_tag_prefix(self):
198
        wt = self.make_branch_and_tree('.', format='2a')
199
        wt.branch.tags.set_tag('tag1', 'null:')
200
        wt.branch.tags.set_tag('tag2', 'null:')
201
        wt.branch.tags.set_tag('3tag', 'null:')
202
        self.complete(['bzr', 'log', '-r', 'tag', ':', 't'],
203
                      expect=['tag1', 'tag2'])