/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
73
        input = """
74
%(script)s
75
76
COMP_WORDS=( %(words)s )
77
COMP_CWORD=%(cword)d
78
%(name)s
79
echo ${#COMPREPLY[*]}
80
IFS=$'\\n'
81
echo "${COMPREPLY[*]}"
82
""" % { 'script': self.script,
0.32.5 by Martin von Gagern
Test bash completion for tags.
83
        'words': 
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
84
        'cword': cword,
85
        'name': getattr(self, 'script_name', '_bzr'),
86
      }
87
        (out, err) = proc.communicate(input)
0.32.5 by Martin von Gagern
Test bash completion for tags.
88
        if '' != err:
89
            raise AssertionError('Unexpected error message:\n%s' % err)
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
90
        self.assertEqual('', err, 'No messages to standard error')
91
        #import sys
92
        #print >>sys.stdout, '---\n%s\n---\n%s\n---\n' % (input, out)
93
        lines = out.split('\n')
94
        nlines = int(lines[0])
95
        del lines[0]
96
        self.assertEqual('', lines[-1], 'Newline at end')
97
        del lines[-1]
98
        if nlines == 0 and len(lines) == 1 and lines[0] == '':
99
            del lines[0]
100
        self.assertEqual(nlines, len(lines), 'No newlines in generated words')
0.32.5 by Martin von Gagern
Test bash completion for tags.
101
        res = set(lines)
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
102
        if expect is not None:
0.32.5 by Martin von Gagern
Test bash completion for tags.
103
            self.assertEqual(set(expect), res)
104
        missing = set(contains) - res
105
        if missing:
106
            raise AssertionError('Completion should contain %r but it has %r'
107
                                 % (missing, res))
108
        surplus = set(omits) & res
109
        if surplus:
110
            raise AssertionError('Completion should omit %r but it has %r'
111
                                 % (surplus, res))
112
        return res
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
113
114
    def get_script(self):
115
        out = StringIO()
116
        bash_completion_function(out, function_only=True)
117
        return out.getvalue()
118
0.32.5 by Martin von Gagern
Test bash completion for tags.
119
120
class TestBashCompletion(TestCase, BashCompletionMixin):
121
    """Test bash completions that don't execute bzr."""
122
123
    def __init__(self, methodName='testMethod'):
124
        super(TestBashCompletion, self).__init__(methodName)
125
        self.script = None
126
127
    def setUp(self):
128
        super(TestBashCompletion, self).setUp()
129
        commands.install_bzr_command_hooks()
130
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
131
    def test_simple_scipt(self):
132
        """Ensure that the test harness works as expected"""
133
        self.script = """
134
_bzr() {
135
    COMPREPLY=()
136
    # add all words in reverse order, with some markup around them
137
    for ((i = ${#COMP_WORDS[@]}; i > 0; --i)); do
138
        COMPREPLY+=( "-${COMP_WORDS[i-1]}+" )
139
    done
140
    # and append the current word
141
    COMPREPLY+=( "+${COMP_WORDS[COMP_CWORD]}-" )
142
}
143
"""
144
        self.complete(['foo', '"bar', "'baz"], cword=1,
145
                      expect=["-'baz+", '-"bar+', '-foo+', '+"bar-'])
146
147
    def test_cmd_ini(self):
148
        c = self.complete(['bzr', 'ini'],
149
                          contains=['init', 'init-repo', 'init-repository'])
150
        self.assertFalse('commit' in c)
151
152
    def test_init_opts(self):
153
        c = self.complete(['bzr', 'init', '-'],
154
                          contains=['-h', '--2a', '--format=2a'])
155
156
    def test_global_opts(self):
157
        c = self.complete(['bzr', '-', 'init'], cword=1,
158
                          contains=['--no-plugins', '-?'])
159
160
    def test_commit_dashm(self):
161
        c = self.complete(['bzr', 'commit', '-m'], expect=['-m'])
162
163
    def test_status_negated(self):
164
        c = self.complete(['bzr', 'status', '--n'],
165
                          contains=['--no-versioned', '--no-verbose'])
166
167
    def test_init_format_any(self):
168
        c = self.complete(['bzr', 'init', '--format', '=', 'directory'],
169
                          cword=3, contains=['1.9', '2a'])
170
171
    def test_init_format_2(self):
172
        c = self.complete(['bzr', 'init', '--format', '=', '2', 'directory'],
173
                          cword=4, contains=['2a'], omits=['1.9'])
0.32.5 by Martin von Gagern
Test bash completion for tags.
174
175
176
class TestBashCompletionInvoking(TestCaseWithTransport, BashCompletionMixin):
177
    """Test bash completions that might execute bzr.
178
179
    Only the syntax ``$(bzr ...`` is supported so far. The bzr command
180
    will be replaced by the bzr instance running this selftest.
181
    """
182
183
    def __init__(self, methodName='testMethod'):
184
        super(TestBashCompletionInvoking, self).__init__(methodName)
185
        self.script = None
186
187
    def setUp(self):
188
        super(TestBashCompletionInvoking, self).setUp()
189
        commands.install_bzr_command_hooks()
190
191
    def get_script(self):
192
        s = super(TestBashCompletionInvoking, self).get_script()
193
        return s.replace("$(bzr ", "$('%s' " % self.get_bzr_path())
194
195
    def test_revspec_tag_all(self):
196
        wt = self.make_branch_and_tree('.', format='2a')
197
        wt.branch.tags.set_tag('tag1', 'null:')
198
        wt.branch.tags.set_tag('tag2', 'null:')
199
        wt.branch.tags.set_tag('3tag', 'null:')
200
        self.complete(['bzr', 'log', '-r', 'tag', ':'],
201
                      expect=['tag1', 'tag2', '3tag'])
202
203
    def test_revspec_tag_prefix(self):
204
        wt = self.make_branch_and_tree('.', format='2a')
205
        wt.branch.tags.set_tag('tag1', 'null:')
206
        wt.branch.tags.set_tag('tag2', 'null:')
207
        wt.branch.tags.set_tag('3tag', 'null:')
208
        self.complete(['bzr', 'log', '-r', 'tag', ':', 't'],
209
                      expect=['tag1', 'tag2'])