/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.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
17
import bzrlib
5147.5.13 by Martin von Gagern
Import modules in tests, not classes or functions.
18
from bzrlib import commands, tests
19
from bzrlib.plugins.bash_completion.bashcomp import *
20
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
21
import os
22
import subprocess
5147.5.13 by Martin von Gagern
Import modules in tests, not classes or functions.
23
24
0.32.5 by Martin von Gagern
Test bash completion for tags.
25
class BashCompletionMixin(object):
26
    """Component for testing execution of a bash completion script."""
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
27
5147.5.24 by Martin von Gagern
Move ExecutableFeature instances to tests.features module.
28
    _test_needs_features = [tests.features.bash_feature]
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
29
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
30
    def complete(self, words, cword=-1):
0.32.5 by Martin von Gagern
Test bash completion for tags.
31
        """Perform a bash completion.
32
33
        :param words: a list of words representing the current command.
34
        :param cword: the current word to complete, defaults to the last one.
35
        """
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
36
        if self.script is None:
37
            self.script = self.get_script()
5147.5.24 by Martin von Gagern
Move ExecutableFeature instances to tests.features module.
38
        proc = subprocess.Popen([tests.features.bash_feature.path,
39
                                 '--noprofile'],
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
40
                                stdin=subprocess.PIPE,
41
                                stdout=subprocess.PIPE,
42
                                stderr=subprocess.PIPE)
43
        if cword < 0:
44
            cword = len(words) + cword
0.32.6 by Martin von Gagern
Reformat bash input snippet.
45
        input = '%s\n' % self.script
46
        input += ('COMP_WORDS=( %s )\n' %
47
                  ' '.join(["'"+w.replace("'", "'\\''")+"'" for w in words]))
48
        input += 'COMP_CWORD=%d\n' % cword
49
        input += '%s\n' % getattr(self, 'script_name', '_bzr')
50
        input += 'echo ${#COMPREPLY[*]}\n'
51
        input += "IFS=$'\\n'\n"
52
        input += 'echo "${COMPREPLY[*]}"\n'
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
53
        (out, err) = proc.communicate(input)
0.32.5 by Martin von Gagern
Test bash completion for tags.
54
        if '' != err:
55
            raise AssertionError('Unexpected error message:\n%s' % err)
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
56
        self.assertEqual('', err, 'No messages to standard error')
57
        #import sys
58
        #print >>sys.stdout, '---\n%s\n---\n%s\n---\n' % (input, out)
59
        lines = out.split('\n')
60
        nlines = int(lines[0])
61
        del lines[0]
62
        self.assertEqual('', lines[-1], 'Newline at end')
63
        del lines[-1]
64
        if nlines == 0 and len(lines) == 1 and lines[0] == '':
65
            del lines[0]
66
        self.assertEqual(nlines, len(lines), 'No newlines in generated words')
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
67
        self.completion_result = set(lines)
68
        return self.completion_result
69
70
    def assertCompletionEquals(self, *words):
71
        self.assertEqual(set(words), self.completion_result)
72
73
    def assertCompletionContains(self, *words):
74
        missing = set(words) - self.completion_result
0.32.5 by Martin von Gagern
Test bash completion for tags.
75
        if missing:
76
            raise AssertionError('Completion should contain %r but it has %r'
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
77
                                 % (missing, self.completion_result))
78
79
    def assertCompletionOmits(self, *words):
80
        surplus = set(words) & self.completion_result
0.32.5 by Martin von Gagern
Test bash completion for tags.
81
        if surplus:
82
            raise AssertionError('Completion should omit %r but it has %r'
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
83
                                 % (surplus, res, self.completion_result))
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
84
85
    def get_script(self):
0.32.12 by Martin von Gagern
Duplicate script creation steps in get_script testing method.
86
        commands.install_bzr_command_hooks()
87
        dc = DataCollector()
88
        data = dc.collect()
89
        cg = BashCodeGen(data)
90
        res = cg.function()
91
        return res
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
92
0.32.5 by Martin von Gagern
Test bash completion for tags.
93
5147.5.13 by Martin von Gagern
Import modules in tests, not classes or functions.
94
class TestBashCompletion(tests.TestCase, BashCompletionMixin):
0.32.5 by Martin von Gagern
Test bash completion for tags.
95
    """Test bash completions that don't execute bzr."""
96
97
    def __init__(self, methodName='testMethod'):
98
        super(TestBashCompletion, self).__init__(methodName)
99
        self.script = None
100
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
101
    def test_simple_scipt(self):
102
        """Ensure that the test harness works as expected"""
103
        self.script = """
104
_bzr() {
105
    COMPREPLY=()
106
    # add all words in reverse order, with some markup around them
107
    for ((i = ${#COMP_WORDS[@]}; i > 0; --i)); do
108
        COMPREPLY+=( "-${COMP_WORDS[i-1]}+" )
109
    done
110
    # and append the current word
111
    COMPREPLY+=( "+${COMP_WORDS[COMP_CWORD]}-" )
112
}
113
"""
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
114
        self.complete(['foo', '"bar', "'baz"], cword=1)
115
        self.assertCompletionEquals("-'baz+", '-"bar+', '-foo+', '+"bar-')
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
116
117
    def test_cmd_ini(self):
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
118
        self.complete(['bzr', 'ini'])
119
        self.assertCompletionContains('init', 'init-repo', 'init-repository')
120
        self.assertCompletionOmits('commit')
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
121
122
    def test_init_opts(self):
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
123
        self.complete(['bzr', 'init', '-'])
124
        self.assertCompletionContains('-h', '--2a', '--format=2a')
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
125
126
    def test_global_opts(self):
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
127
        self.complete(['bzr', '-', 'init'], cword=1)
128
        self.assertCompletionContains('--no-plugins', '--builtin')
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
129
130
    def test_commit_dashm(self):
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
131
        self.complete(['bzr', 'commit', '-m'])
132
        self.assertCompletionEquals('-m')
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
133
134
    def test_status_negated(self):
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
135
        self.complete(['bzr', 'status', '--n'])
136
        self.assertCompletionContains('--no-versioned', '--no-verbose')
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
137
138
    def test_init_format_any(self):
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
139
        self.complete(['bzr', 'init', '--format', '=', 'directory'], cword=3)
140
        self.assertCompletionContains('1.9', '2a')
0.32.4 by Martin von Gagern
Added some selftests executed through bash.
141
142
    def test_init_format_2(self):
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
143
        self.complete(['bzr', 'init', '--format', '=', '2', 'directory'],
144
                      cword=4)
145
        self.assertCompletionContains('2a')
146
        self.assertCompletionOmits('1.9')
0.32.5 by Martin von Gagern
Test bash completion for tags.
147
148
5147.5.13 by Martin von Gagern
Import modules in tests, not classes or functions.
149
class TestBashCompletionInvoking(tests.TestCaseWithTransport,
150
                                 BashCompletionMixin):
0.32.5 by Martin von Gagern
Test bash completion for tags.
151
    """Test bash completions that might execute bzr.
152
153
    Only the syntax ``$(bzr ...`` is supported so far. The bzr command
154
    will be replaced by the bzr instance running this selftest.
155
    """
156
157
    def __init__(self, methodName='testMethod'):
158
        super(TestBashCompletionInvoking, self).__init__(methodName)
159
        self.script = None
160
161
    def get_script(self):
162
        s = super(TestBashCompletionInvoking, self).get_script()
163
        return s.replace("$(bzr ", "$('%s' " % self.get_bzr_path())
164
165
    def test_revspec_tag_all(self):
5147.5.24 by Martin von Gagern
Move ExecutableFeature instances to tests.features module.
166
        self.requireFeature(tests.features.sed_feature)
0.32.7 by Martin von Gagern
Allow different formats for tag completion.
167
        wt = self.make_branch_and_tree('.', format='dirstate-tags')
0.32.5 by Martin von Gagern
Test bash completion for tags.
168
        wt.branch.tags.set_tag('tag1', 'null:')
0.32.16 by Martin von Gagern
Ensure proper quoting of spaces in tag names.
169
        wt.branch.tags.set_tag('tag2', 'null:')
0.32.5 by Martin von Gagern
Test bash completion for tags.
170
        wt.branch.tags.set_tag('3tag', 'null:')
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
171
        self.complete(['bzr', 'log', '-r', 'tag', ':'])
0.32.16 by Martin von Gagern
Ensure proper quoting of spaces in tag names.
172
        self.assertCompletionEquals('tag1', 'tag2', '3tag')
0.32.5 by Martin von Gagern
Test bash completion for tags.
173
174
    def test_revspec_tag_prefix(self):
5147.5.24 by Martin von Gagern
Move ExecutableFeature instances to tests.features module.
175
        self.requireFeature(tests.features.sed_feature)
0.32.7 by Martin von Gagern
Allow different formats for tag completion.
176
        wt = self.make_branch_and_tree('.', format='dirstate-tags')
0.32.5 by Martin von Gagern
Test bash completion for tags.
177
        wt.branch.tags.set_tag('tag1', 'null:')
0.32.16 by Martin von Gagern
Ensure proper quoting of spaces in tag names.
178
        wt.branch.tags.set_tag('tag2', 'null:')
0.32.5 by Martin von Gagern
Test bash completion for tags.
179
        wt.branch.tags.set_tag('3tag', 'null:')
0.32.11 by Martin von Gagern
Turn completion assertions into separate methods.
180
        self.complete(['bzr', 'log', '-r', 'tag', ':', 't'])
0.32.16 by Martin von Gagern
Ensure proper quoting of spaces in tag names.
181
        self.assertCompletionEquals('tag1', 'tag2')
182
183
    def test_revspec_tag_spaces(self):
184
        self.requireFeature(SedFeature)
185
        wt = self.make_branch_and_tree('.', format='dirstate-tags')
186
        wt.branch.tags.set_tag('tag with spaces', 'null:')
187
        self.complete(['bzr', 'log', '-r', 'tag', ':', 't'])
188
        self.assertCompletionEquals(r'tag\ with\ spaces')
189
        self.complete(['bzr', 'log', '-r', '"tag:t'])
190
        self.assertCompletionEquals('tag:tag with spaces')
191
        self.complete(['bzr', 'log', '-r', "'tag:t"])
192
        self.assertCompletionEquals('tag:tag with spaces')
0.32.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
193
0.32.20 by Martin von Gagern
Allow completion of tags at end of revision range.
194
    def test_revspec_tag_endrange(self):
195
        self.requireFeature(SedFeature)
196
        wt = self.make_branch_and_tree('.', format='dirstate-tags')
197
        wt.branch.tags.set_tag('tag1', 'null:')
198
        wt.branch.tags.set_tag('tag2', 'null:')
199
        self.complete(['bzr', 'log', '-r', '3..tag', ':', 't'])
200
        self.assertCompletionEquals('tag1', 'tag2')
201
        self.complete(['bzr', 'log', '-r', '"3..tag:t'])
202
        self.assertCompletionEquals('3..tag:tag1', '3..tag:tag2')
203
        self.complete(['bzr', 'log', '-r', "'3..tag:t"])
204
        self.assertCompletionEquals('3..tag:tag1', '3..tag:tag2')
205
0.32.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
206
5147.5.13 by Martin von Gagern
Import modules in tests, not classes or functions.
207
class TestBashCodeGen(tests.TestCase):
0.32.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
208
209
    def test_command_names(self):
210
        data = CompletionData()
211
        bar = CommandData('bar')
212
        bar.aliases.append('baz')
213
        data.commands.append(bar)
214
        data.commands.append(CommandData('foo'))
215
        cg = BashCodeGen(data)
216
        self.assertEqual('bar baz foo', cg.command_names())
217
218
    def test_debug_output(self):
219
        data = CompletionData()
220
        self.assertEqual('', BashCodeGen(data, debug=False).debug_output())
221
        self.assertTrue(BashCodeGen(data, debug=True).debug_output())
222
223
    def test_bzr_version(self):
224
        data = CompletionData()
225
        cg = BashCodeGen(data)
226
        self.assertEqual('%s.' % bzrlib.version_string, cg.bzr_version())
227
        data.plugins['foo'] = PluginData('foo', '1.0')
228
        data.plugins['bar'] = PluginData('bar', '2.0')
229
        cg = BashCodeGen(data)
230
        self.assertEqual('''\
231
%s and the following plugins:
232
# bar 2.0
233
# foo 1.0''' % bzrlib.version_string, cg.bzr_version())
234
235
    def test_global_options(self):
236
        data = CompletionData()
237
        data.global_options.add('--foo')
238
        data.global_options.add('--bar')
239
        cg = BashCodeGen(data)
240
        self.assertEqual('--bar --foo', cg.global_options())
241
242
    def test_command_cases(self):
243
        data = CompletionData()
244
        bar = CommandData('bar')
245
        bar.aliases.append('baz')
246
        bar.options.append(OptionData('--opt'))
247
        data.commands.append(bar)
248
        data.commands.append(CommandData('foo'))
249
        cg = BashCodeGen(data)
250
        self.assertEqualDiff('''\
251
\tbar|baz)
0.32.15 by Martin von Gagern
Allow spaces in tag names. Use bash arrays more extensively.
252
\t\tcmdOpts=( --opt )
0.32.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
253
\t\t;;
254
\tfoo)
0.32.15 by Martin von Gagern
Allow spaces in tag names. Use bash arrays more extensively.
255
\t\tcmdOpts=(  )
0.32.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
256
\t\t;;
257
''', cg.command_cases())
258
259
    def test_command_case(self):
260
        cmd = CommandData('cmd')
261
        cmd.plugin = PluginData('plugger', '1.0')
262
        bar = OptionData('--bar')
263
        bar.registry_keys = ['that', 'this']
264
        bar.error_messages.append('Some error message')
265
        cmd.options.append(bar)
266
        cmd.options.append(OptionData('--foo'))
267
        data = CompletionData()
268
        data.commands.append(cmd)
269
        cg = BashCodeGen(data)
270
        self.assertEqualDiff('''\
271
\tcmd)
272
\t\t# plugin "plugger 1.0"
273
\t\t# Some error message
0.32.15 by Martin von Gagern
Allow spaces in tag names. Use bash arrays more extensively.
274
\t\tcmdOpts=( --bar=that --bar=this --foo )
0.32.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
275
\t\tcase $curOpt in
0.32.15 by Martin von Gagern
Allow spaces in tag names. Use bash arrays more extensively.
276
\t\t\t--bar) optEnums=( that this ) ;;
0.32.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
277
\t\tesac
278
\t\t;;
279
''', cg.command_case(cmd))
280
281
5147.5.13 by Martin von Gagern
Import modules in tests, not classes or functions.
282
class TestDataCollector(tests.TestCase):
0.32.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
283
284
    def setUp(self):
285
        super(TestDataCollector, self).setUp()
286
        commands.install_bzr_command_hooks()
287
288
    def test_global_options(self):
289
        dc = DataCollector()
290
        dc.global_options()
291
        self.assertSubset(['--no-plugins', '--builtin'],
292
                           dc.data.global_options)
293
294
    def test_commands(self):
295
        dc = DataCollector()
296
        dc.commands()
297
        self.assertSubset(['init', 'init-repo', 'init-repository'],
298
                           dc.data.all_command_aliases())
299
0.32.19 by Martin von Gagern
Add test ensuring plugin commands get collected.
300
    def test_commands_from_plugins(self):
301
        dc = DataCollector()
302
        dc.commands()
303
        self.assertSubset(['bash-completion'],
304
                           dc.data.all_command_aliases())
305
0.32.9 by Martin von Gagern
Added test cases for DataCollector and BashCodeGen.
306
    def test_commit_dashm(self):
307
        dc = DataCollector()
308
        cmd = dc.command('commit')
309
        self.assertSubset(['-m'],
310
                           [str(o) for o in cmd.options])
311
312
    def test_status_negated(self):
313
        dc = DataCollector()
314
        cmd = dc.command('status')
315
        self.assertSubset(['--no-versioned', '--no-verbose'],
316
                           [str(o) for o in cmd.options])
317
318
    def test_init_format(self):
319
        dc = DataCollector()
320
        cmd = dc.command('init')
321
        for opt in cmd.options:
322
            if opt.name == '--format':
323
                self.assertSubset(['2a'], opt.registry_keys)
324
                return
325
        raise AssertionError('Option --format not found')