/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Jan Hudec
  • Date: 2006-11-25 20:38:39 UTC
  • mto: (2199.1.1 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 2200.
  • Revision ID: bulb@ucw.cz-20061125203839-9nuhv32z63hb8811
Option --pull for merge command.

Option --pull was added to merge command, that, if the merge would be
trivial, ie. if the common ancestor is equal to the local tip, causes pull of
the remote instead of creating the merger.

Simple test for this option is included.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
 
2
#   Authors: Robert Collins <robert.collins@canonical.com>
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
#
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
"""Tests for finding and reading the bzr config file[s]."""
 
19
# import system imports here
 
20
from bzrlib.util.configobj.configobj import ConfigObj, ConfigObjError
 
21
from cStringIO import StringIO
 
22
import os
 
23
import sys
 
24
 
 
25
#import bzrlib specific imports here
 
26
from bzrlib import (
 
27
    config,
 
28
    errors,
 
29
    osutils,
 
30
    urlutils,
 
31
    )
 
32
from bzrlib.branch import Branch
 
33
from bzrlib.bzrdir import BzrDir
 
34
from bzrlib.tests import TestCase, TestCaseInTempDir, TestCaseWithTransport
 
35
 
 
36
 
 
37
sample_long_alias="log -r-15..-1 --line"
 
38
sample_config_text = ("[DEFAULT]\n"
 
39
                      u"email=Erik B\u00e5gfors <erik@bagfors.nu>\n"
 
40
                      "editor=vim\n"
 
41
                      "gpg_signing_command=gnome-gpg\n"
 
42
                      "log_format=short\n"
 
43
                      "user_global_option=something\n"
 
44
                      "[ALIASES]\n"
 
45
                      "h=help\n"
 
46
                      "ll=" + sample_long_alias + "\n")
 
47
 
 
48
 
 
49
sample_always_signatures = ("[DEFAULT]\n"
 
50
                            "check_signatures=ignore\n"
 
51
                            "create_signatures=always")
 
52
 
 
53
 
 
54
sample_ignore_signatures = ("[DEFAULT]\n"
 
55
                            "check_signatures=require\n"
 
56
                            "create_signatures=never")
 
57
 
 
58
 
 
59
sample_maybe_signatures = ("[DEFAULT]\n"
 
60
                            "check_signatures=ignore\n"
 
61
                            "create_signatures=when-required")
 
62
 
 
63
 
 
64
sample_branches_text = ("[http://www.example.com]\n"
 
65
                        "# Top level policy\n"
 
66
                        "email=Robert Collins <robertc@example.org>\n"
 
67
                        "[http://www.example.com/ignoreparent]\n"
 
68
                        "# different project: ignore parent dir config\n"
 
69
                        "ignore_parents=true\n"
 
70
                        "[http://www.example.com/norecurse]\n"
 
71
                        "# configuration items that only apply to this dir\n"
 
72
                        "recurse=false\n"
 
73
                        "[/b/]\n"
 
74
                        "check_signatures=require\n"
 
75
                        "# test trailing / matching with no children\n"
 
76
                        "[/a/]\n"
 
77
                        "check_signatures=check-available\n"
 
78
                        "gpg_signing_command=false\n"
 
79
                        "user_local_option=local\n"
 
80
                        "# test trailing / matching\n"
 
81
                        "[/a/*]\n"
 
82
                        "#subdirs will match but not the parent\n"
 
83
                        "[/a/c]\n"
 
84
                        "check_signatures=ignore\n"
 
85
                        "post_commit=bzrlib.tests.test_config.post_commit\n"
 
86
                        "#testing explicit beats globs\n")
 
87
 
 
88
 
 
89
 
 
90
class InstrumentedConfigObj(object):
 
91
    """A config obj look-enough-alike to record calls made to it."""
 
92
 
 
93
    def __contains__(self, thing):
 
94
        self._calls.append(('__contains__', thing))
 
95
        return False
 
96
 
 
97
    def __getitem__(self, key):
 
98
        self._calls.append(('__getitem__', key))
 
99
        return self
 
100
 
 
101
    def __init__(self, input, encoding=None):
 
102
        self._calls = [('__init__', input, encoding)]
 
103
 
 
104
    def __setitem__(self, key, value):
 
105
        self._calls.append(('__setitem__', key, value))
 
106
 
 
107
    def write(self, arg):
 
108
        self._calls.append(('write',))
 
109
 
 
110
 
 
111
class FakeBranch(object):
 
112
 
 
113
    def __init__(self, base=None, user_id=None):
 
114
        if base is None:
 
115
            self.base = "http://example.com/branches/demo"
 
116
        else:
 
117
            self.base = base
 
118
        self.control_files = FakeControlFiles(user_id=user_id)
 
119
 
 
120
    def lock_write(self):
 
121
        pass
 
122
 
 
123
    def unlock(self):
 
124
        pass
 
125
 
 
126
 
 
127
class FakeControlFiles(object):
 
128
 
 
129
    def __init__(self, user_id=None):
 
130
        self.email = user_id
 
131
        self.files = {}
 
132
 
 
133
    def get_utf8(self, filename):
 
134
        if filename != 'email':
 
135
            raise NotImplementedError
 
136
        if self.email is not None:
 
137
            return StringIO(self.email)
 
138
        raise errors.NoSuchFile(filename)
 
139
 
 
140
    def get(self, filename):
 
141
        try:
 
142
            return StringIO(self.files[filename])
 
143
        except KeyError:
 
144
            raise errors.NoSuchFile(filename)
 
145
 
 
146
    def put(self, filename, fileobj):
 
147
        self.files[filename] = fileobj.read()
 
148
 
 
149
 
 
150
class InstrumentedConfig(config.Config):
 
151
    """An instrumented config that supplies stubs for template methods."""
 
152
    
 
153
    def __init__(self):
 
154
        super(InstrumentedConfig, self).__init__()
 
155
        self._calls = []
 
156
        self._signatures = config.CHECK_NEVER
 
157
 
 
158
    def _get_user_id(self):
 
159
        self._calls.append('_get_user_id')
 
160
        return "Robert Collins <robert.collins@example.org>"
 
161
 
 
162
    def _get_signature_checking(self):
 
163
        self._calls.append('_get_signature_checking')
 
164
        return self._signatures
 
165
 
 
166
 
 
167
bool_config = """[DEFAULT]
 
168
active = true
 
169
inactive = false
 
170
[UPPERCASE]
 
171
active = True
 
172
nonactive = False
 
173
"""
 
174
class TestConfigObj(TestCase):
 
175
    def test_get_bool(self):
 
176
        from bzrlib.config import ConfigObj
 
177
        co = ConfigObj(StringIO(bool_config))
 
178
        self.assertIs(co.get_bool('DEFAULT', 'active'), True)
 
179
        self.assertIs(co.get_bool('DEFAULT', 'inactive'), False)
 
180
        self.assertIs(co.get_bool('UPPERCASE', 'active'), True)
 
181
        self.assertIs(co.get_bool('UPPERCASE', 'nonactive'), False)
 
182
 
 
183
 
 
184
class TestConfig(TestCase):
 
185
 
 
186
    def test_constructs(self):
 
187
        config.Config()
 
188
 
 
189
    def test_no_default_editor(self):
 
190
        self.assertRaises(NotImplementedError, config.Config().get_editor)
 
191
 
 
192
    def test_user_email(self):
 
193
        my_config = InstrumentedConfig()
 
194
        self.assertEqual('robert.collins@example.org', my_config.user_email())
 
195
        self.assertEqual(['_get_user_id'], my_config._calls)
 
196
 
 
197
    def test_username(self):
 
198
        my_config = InstrumentedConfig()
 
199
        self.assertEqual('Robert Collins <robert.collins@example.org>',
 
200
                         my_config.username())
 
201
        self.assertEqual(['_get_user_id'], my_config._calls)
 
202
 
 
203
    def test_signatures_default(self):
 
204
        my_config = config.Config()
 
205
        self.assertFalse(my_config.signature_needed())
 
206
        self.assertEqual(config.CHECK_IF_POSSIBLE,
 
207
                         my_config.signature_checking())
 
208
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
 
209
                         my_config.signing_policy())
 
210
 
 
211
    def test_signatures_template_method(self):
 
212
        my_config = InstrumentedConfig()
 
213
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
 
214
        self.assertEqual(['_get_signature_checking'], my_config._calls)
 
215
 
 
216
    def test_signatures_template_method_none(self):
 
217
        my_config = InstrumentedConfig()
 
218
        my_config._signatures = None
 
219
        self.assertEqual(config.CHECK_IF_POSSIBLE,
 
220
                         my_config.signature_checking())
 
221
        self.assertEqual(['_get_signature_checking'], my_config._calls)
 
222
 
 
223
    def test_gpg_signing_command_default(self):
 
224
        my_config = config.Config()
 
225
        self.assertEqual('gpg', my_config.gpg_signing_command())
 
226
 
 
227
    def test_get_user_option_default(self):
 
228
        my_config = config.Config()
 
229
        self.assertEqual(None, my_config.get_user_option('no_option'))
 
230
 
 
231
    def test_post_commit_default(self):
 
232
        my_config = config.Config()
 
233
        self.assertEqual(None, my_config.post_commit())
 
234
 
 
235
    def test_log_format_default(self):
 
236
        my_config = config.Config()
 
237
        self.assertEqual('long', my_config.log_format())
 
238
 
 
239
 
 
240
class TestConfigPath(TestCase):
 
241
 
 
242
    def setUp(self):
 
243
        super(TestConfigPath, self).setUp()
 
244
        self.old_home = os.environ.get('HOME', None)
 
245
        self.old_appdata = os.environ.get('APPDATA', None)
 
246
        os.environ['HOME'] = '/home/bogus'
 
247
        os.environ['APPDATA'] = \
 
248
            r'C:\Documents and Settings\bogus\Application Data'
 
249
 
 
250
    def tearDown(self):
 
251
        if self.old_home is None:
 
252
            del os.environ['HOME']
 
253
        else:
 
254
            os.environ['HOME'] = self.old_home
 
255
        if self.old_appdata is None:
 
256
            del os.environ['APPDATA']
 
257
        else:
 
258
            os.environ['APPDATA'] = self.old_appdata
 
259
        super(TestConfigPath, self).tearDown()
 
260
    
 
261
    def test_config_dir(self):
 
262
        if sys.platform == 'win32':
 
263
            self.assertEqual(config.config_dir(), 
 
264
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0')
 
265
        else:
 
266
            self.assertEqual(config.config_dir(), '/home/bogus/.bazaar')
 
267
 
 
268
    def test_config_filename(self):
 
269
        if sys.platform == 'win32':
 
270
            self.assertEqual(config.config_filename(), 
 
271
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/bazaar.conf')
 
272
        else:
 
273
            self.assertEqual(config.config_filename(),
 
274
                             '/home/bogus/.bazaar/bazaar.conf')
 
275
 
 
276
    def test_branches_config_filename(self):
 
277
        if sys.platform == 'win32':
 
278
            self.assertEqual(config.branches_config_filename(), 
 
279
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/branches.conf')
 
280
        else:
 
281
            self.assertEqual(config.branches_config_filename(),
 
282
                             '/home/bogus/.bazaar/branches.conf')
 
283
 
 
284
    def test_locations_config_filename(self):
 
285
        if sys.platform == 'win32':
 
286
            self.assertEqual(config.locations_config_filename(), 
 
287
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/locations.conf')
 
288
        else:
 
289
            self.assertEqual(config.locations_config_filename(),
 
290
                             '/home/bogus/.bazaar/locations.conf')
 
291
 
 
292
class TestIniConfig(TestCase):
 
293
 
 
294
    def test_contructs(self):
 
295
        my_config = config.IniBasedConfig("nothing")
 
296
 
 
297
    def test_from_fp(self):
 
298
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
299
        my_config = config.IniBasedConfig(None)
 
300
        self.failUnless(
 
301
            isinstance(my_config._get_parser(file=config_file),
 
302
                        ConfigObj))
 
303
 
 
304
    def test_cached(self):
 
305
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
306
        my_config = config.IniBasedConfig(None)
 
307
        parser = my_config._get_parser(file=config_file)
 
308
        self.failUnless(my_config._get_parser() is parser)
 
309
 
 
310
 
 
311
class TestGetConfig(TestCase):
 
312
 
 
313
    def test_constructs(self):
 
314
        my_config = config.GlobalConfig()
 
315
 
 
316
    def test_calls_read_filenames(self):
 
317
        # replace the class that is constructured, to check its parameters
 
318
        oldparserclass = config.ConfigObj
 
319
        config.ConfigObj = InstrumentedConfigObj
 
320
        my_config = config.GlobalConfig()
 
321
        try:
 
322
            parser = my_config._get_parser()
 
323
        finally:
 
324
            config.ConfigObj = oldparserclass
 
325
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
 
326
        self.assertEqual(parser._calls, [('__init__', config.config_filename(),
 
327
                                          'utf-8')])
 
328
 
 
329
 
 
330
class TestBranchConfig(TestCaseWithTransport):
 
331
 
 
332
    def test_constructs(self):
 
333
        branch = FakeBranch()
 
334
        my_config = config.BranchConfig(branch)
 
335
        self.assertRaises(TypeError, config.BranchConfig)
 
336
 
 
337
    def test_get_location_config(self):
 
338
        branch = FakeBranch()
 
339
        my_config = config.BranchConfig(branch)
 
340
        location_config = my_config._get_location_config()
 
341
        self.assertEqual(branch.base, location_config.location)
 
342
        self.failUnless(location_config is my_config._get_location_config())
 
343
 
 
344
    def test_get_config(self):
 
345
        """The Branch.get_config method works properly"""
 
346
        b = BzrDir.create_standalone_workingtree('.').branch
 
347
        my_config = b.get_config()
 
348
        self.assertIs(my_config.get_user_option('wacky'), None)
 
349
        my_config.set_user_option('wacky', 'unlikely')
 
350
        self.assertEqual(my_config.get_user_option('wacky'), 'unlikely')
 
351
 
 
352
        # Ensure we get the same thing if we start again
 
353
        b2 = Branch.open('.')
 
354
        my_config2 = b2.get_config()
 
355
        self.assertEqual(my_config2.get_user_option('wacky'), 'unlikely')
 
356
 
 
357
    def test_has_explicit_nickname(self):
 
358
        b = self.make_branch('.')
 
359
        self.assertFalse(b.get_config().has_explicit_nickname())
 
360
        b.nick = 'foo'
 
361
        self.assertTrue(b.get_config().has_explicit_nickname())
 
362
 
 
363
    def test_config_url(self):
 
364
        """The Branch.get_config will use section that uses a local url"""
 
365
        branch = self.make_branch('branch')
 
366
        self.assertEqual('branch', branch.nick)
 
367
 
 
368
        locations = config.locations_config_filename()
 
369
        config.ensure_config_dir_exists()
 
370
        local_url = urlutils.local_path_to_url('branch')
 
371
        open(locations, 'wb').write('[%s]\nnickname = foobar' 
 
372
                                    % (local_url,))
 
373
        self.assertEqual('foobar', branch.nick)
 
374
 
 
375
    def test_config_local_path(self):
 
376
        """The Branch.get_config will use a local system path"""
 
377
        branch = self.make_branch('branch')
 
378
        self.assertEqual('branch', branch.nick)
 
379
 
 
380
        locations = config.locations_config_filename()
 
381
        config.ensure_config_dir_exists()
 
382
        open(locations, 'wb').write('[%s/branch]\nnickname = barry' 
 
383
                                    % (osutils.getcwd().encode('utf8'),))
 
384
        self.assertEqual('barry', branch.nick)
 
385
 
 
386
    def test_config_creates_local(self):
 
387
        """Creating a new entry in config uses a local path."""
 
388
        branch = self.make_branch('branch')
 
389
        branch.set_push_location('http://foobar')
 
390
        locations = config.locations_config_filename()
 
391
        local_path = osutils.getcwd().encode('utf8')
 
392
        # Surprisingly ConfigObj doesn't create a trailing newline
 
393
        self.check_file_contents(locations,
 
394
            '[%s/branch]\npush_location = http://foobar' % (local_path,))
 
395
 
 
396
    def test_autonick_urlencoded(self):
 
397
        b = self.make_branch('!repo')
 
398
        self.assertEqual('!repo', b.get_config().get_nickname())
 
399
 
 
400
 
 
401
class TestGlobalConfigItems(TestCase):
 
402
 
 
403
    def test_user_id(self):
 
404
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
405
        my_config = config.GlobalConfig()
 
406
        my_config._parser = my_config._get_parser(file=config_file)
 
407
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
 
408
                         my_config._get_user_id())
 
409
 
 
410
    def test_absent_user_id(self):
 
411
        config_file = StringIO("")
 
412
        my_config = config.GlobalConfig()
 
413
        my_config._parser = my_config._get_parser(file=config_file)
 
414
        self.assertEqual(None, my_config._get_user_id())
 
415
 
 
416
    def test_configured_editor(self):
 
417
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
418
        my_config = config.GlobalConfig()
 
419
        my_config._parser = my_config._get_parser(file=config_file)
 
420
        self.assertEqual("vim", my_config.get_editor())
 
421
 
 
422
    def test_signatures_always(self):
 
423
        config_file = StringIO(sample_always_signatures)
 
424
        my_config = config.GlobalConfig()
 
425
        my_config._parser = my_config._get_parser(file=config_file)
 
426
        self.assertEqual(config.CHECK_NEVER,
 
427
                         my_config.signature_checking())
 
428
        self.assertEqual(config.SIGN_ALWAYS,
 
429
                         my_config.signing_policy())
 
430
        self.assertEqual(True, my_config.signature_needed())
 
431
 
 
432
    def test_signatures_if_possible(self):
 
433
        config_file = StringIO(sample_maybe_signatures)
 
434
        my_config = config.GlobalConfig()
 
435
        my_config._parser = my_config._get_parser(file=config_file)
 
436
        self.assertEqual(config.CHECK_NEVER,
 
437
                         my_config.signature_checking())
 
438
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
 
439
                         my_config.signing_policy())
 
440
        self.assertEqual(False, my_config.signature_needed())
 
441
 
 
442
    def test_signatures_ignore(self):
 
443
        config_file = StringIO(sample_ignore_signatures)
 
444
        my_config = config.GlobalConfig()
 
445
        my_config._parser = my_config._get_parser(file=config_file)
 
446
        self.assertEqual(config.CHECK_ALWAYS,
 
447
                         my_config.signature_checking())
 
448
        self.assertEqual(config.SIGN_NEVER,
 
449
                         my_config.signing_policy())
 
450
        self.assertEqual(False, my_config.signature_needed())
 
451
 
 
452
    def _get_sample_config(self):
 
453
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
454
        my_config = config.GlobalConfig()
 
455
        my_config._parser = my_config._get_parser(file=config_file)
 
456
        return my_config
 
457
 
 
458
    def test_gpg_signing_command(self):
 
459
        my_config = self._get_sample_config()
 
460
        self.assertEqual("gnome-gpg", my_config.gpg_signing_command())
 
461
        self.assertEqual(False, my_config.signature_needed())
 
462
 
 
463
    def _get_empty_config(self):
 
464
        config_file = StringIO("")
 
465
        my_config = config.GlobalConfig()
 
466
        my_config._parser = my_config._get_parser(file=config_file)
 
467
        return my_config
 
468
 
 
469
    def test_gpg_signing_command_unset(self):
 
470
        my_config = self._get_empty_config()
 
471
        self.assertEqual("gpg", my_config.gpg_signing_command())
 
472
 
 
473
    def test_get_user_option_default(self):
 
474
        my_config = self._get_empty_config()
 
475
        self.assertEqual(None, my_config.get_user_option('no_option'))
 
476
 
 
477
    def test_get_user_option_global(self):
 
478
        my_config = self._get_sample_config()
 
479
        self.assertEqual("something",
 
480
                         my_config.get_user_option('user_global_option'))
 
481
        
 
482
    def test_post_commit_default(self):
 
483
        my_config = self._get_sample_config()
 
484
        self.assertEqual(None, my_config.post_commit())
 
485
 
 
486
    def test_configured_logformat(self):
 
487
        my_config = self._get_sample_config()
 
488
        self.assertEqual("short", my_config.log_format())
 
489
 
 
490
    def test_get_alias(self):
 
491
        my_config = self._get_sample_config()
 
492
        self.assertEqual('help', my_config.get_alias('h'))
 
493
 
 
494
    def test_get_no_alias(self):
 
495
        my_config = self._get_sample_config()
 
496
        self.assertEqual(None, my_config.get_alias('foo'))
 
497
 
 
498
    def test_get_long_alias(self):
 
499
        my_config = self._get_sample_config()
 
500
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
 
501
 
 
502
 
 
503
class TestLocationConfig(TestCaseInTempDir):
 
504
 
 
505
    def test_constructs(self):
 
506
        my_config = config.LocationConfig('http://example.com')
 
507
        self.assertRaises(TypeError, config.LocationConfig)
 
508
 
 
509
    def test_branch_calls_read_filenames(self):
 
510
        # This is testing the correct file names are provided.
 
511
        # TODO: consolidate with the test for GlobalConfigs filename checks.
 
512
        #
 
513
        # replace the class that is constructured, to check its parameters
 
514
        oldparserclass = config.ConfigObj
 
515
        config.ConfigObj = InstrumentedConfigObj
 
516
        try:
 
517
            my_config = config.LocationConfig('http://www.example.com')
 
518
            parser = my_config._get_parser()
 
519
        finally:
 
520
            config.ConfigObj = oldparserclass
 
521
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
 
522
        self.assertEqual(parser._calls,
 
523
                         [('__init__', config.locations_config_filename(),
 
524
                           'utf-8')])
 
525
        config.ensure_config_dir_exists()
 
526
        #os.mkdir(config.config_dir())
 
527
        f = file(config.branches_config_filename(), 'wb')
 
528
        f.write('')
 
529
        f.close()
 
530
        oldparserclass = config.ConfigObj
 
531
        config.ConfigObj = InstrumentedConfigObj
 
532
        try:
 
533
            my_config = config.LocationConfig('http://www.example.com')
 
534
            parser = my_config._get_parser()
 
535
        finally:
 
536
            config.ConfigObj = oldparserclass
 
537
 
 
538
    def test_get_global_config(self):
 
539
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
 
540
        global_config = my_config._get_global_config()
 
541
        self.failUnless(isinstance(global_config, config.GlobalConfig))
 
542
        self.failUnless(global_config is my_config._get_global_config())
 
543
 
 
544
    def test__get_matching_sections_no_match(self):
 
545
        self.get_branch_config('/')
 
546
        self.assertEqual([], self.my_location_config._get_matching_sections())
 
547
        
 
548
    def test__get_matching_sections_exact(self):
 
549
        self.get_branch_config('http://www.example.com')
 
550
        self.assertEqual([('http://www.example.com', '')],
 
551
                         self.my_location_config._get_matching_sections())
 
552
   
 
553
    def test__get_matching_sections_suffix_does_not(self):
 
554
        self.get_branch_config('http://www.example.com-com')
 
555
        self.assertEqual([], self.my_location_config._get_matching_sections())
 
556
 
 
557
    def test__get_matching_sections_subdir_recursive(self):
 
558
        self.get_branch_config('http://www.example.com/com')
 
559
        self.assertEqual([('http://www.example.com', 'com')],
 
560
                         self.my_location_config._get_matching_sections())
 
561
 
 
562
    def test__get_matching_sections_ignoreparent(self):
 
563
        self.get_branch_config('http://www.example.com/ignoreparent')
 
564
        self.assertEqual([('http://www.example.com/ignoreparent', '')],
 
565
                         self.my_location_config._get_matching_sections())
 
566
 
 
567
    def test__get_matching_sections_ignoreparent_subdir(self):
 
568
        self.get_branch_config(
 
569
            'http://www.example.com/ignoreparent/childbranch')
 
570
        self.assertEqual([('http://www.example.com/ignoreparent', 'childbranch')],
 
571
                         self.my_location_config._get_matching_sections())
 
572
 
 
573
    def test__get_matching_sections_norecurse(self):
 
574
        self.get_branch_config('http://www.example.com/norecurse')
 
575
        self.assertEqual([('http://www.example.com/norecurse', ''),
 
576
                          ('http://www.example.com', 'norecurse')],
 
577
                         self.my_location_config._get_matching_sections())
 
578
 
 
579
    def test__get_matching_sections_norecurse_subdir(self):
 
580
        self.get_branch_config(
 
581
            'http://www.example.com/norecurse/childbranch')
 
582
        self.assertEqual([('http://www.example.com', 'norecurse/childbranch')],
 
583
                         self.my_location_config._get_matching_sections())
 
584
 
 
585
    def test__get_matching_sections_subdir_trailing_slash(self):
 
586
        self.get_branch_config('/b')
 
587
        self.assertEqual([('/b/', '')],
 
588
                         self.my_location_config._get_matching_sections())
 
589
 
 
590
    def test__get_matching_sections_subdir_child(self):
 
591
        self.get_branch_config('/a/foo')
 
592
        self.assertEqual([('/a/*', ''), ('/a/', 'foo')],
 
593
                         self.my_location_config._get_matching_sections())
 
594
 
 
595
    def test__get_matching_sections_subdir_child_child(self):
 
596
        self.get_branch_config('/a/foo/bar')
 
597
        self.assertEqual([('/a/*', 'bar'), ('/a/', 'foo/bar')],
 
598
                         self.my_location_config._get_matching_sections())
 
599
 
 
600
    def test__get_matching_sections_trailing_slash_with_children(self):
 
601
        self.get_branch_config('/a/')
 
602
        self.assertEqual([('/a/', '')],
 
603
                         self.my_location_config._get_matching_sections())
 
604
 
 
605
    def test__get_matching_sections_explicit_over_glob(self):
 
606
        # XXX: 2006-09-08 jamesh
 
607
        # This test only passes because ord('c') > ord('*').  If there
 
608
        # was a config section for '/a/?', it would get precedence
 
609
        # over '/a/c'.
 
610
        self.get_branch_config('/a/c')
 
611
        self.assertEqual([('/a/c', ''), ('/a/*', ''), ('/a/', 'c')],
 
612
                         self.my_location_config._get_matching_sections())
 
613
 
 
614
    def test_location_without_username(self):
 
615
        self.get_branch_config('http://www.example.com/ignoreparent')
 
616
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
 
617
                         self.my_config.username())
 
618
 
 
619
    def test_location_not_listed(self):
 
620
        """Test that the global username is used when no location matches"""
 
621
        self.get_branch_config('/home/robertc/sources')
 
622
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
 
623
                         self.my_config.username())
 
624
 
 
625
    def test_overriding_location(self):
 
626
        self.get_branch_config('http://www.example.com/foo')
 
627
        self.assertEqual('Robert Collins <robertc@example.org>',
 
628
                         self.my_config.username())
 
629
 
 
630
    def test_signatures_not_set(self):
 
631
        self.get_branch_config('http://www.example.com',
 
632
                                 global_config=sample_ignore_signatures)
 
633
        self.assertEqual(config.CHECK_ALWAYS,
 
634
                         self.my_config.signature_checking())
 
635
        self.assertEqual(config.SIGN_NEVER,
 
636
                         self.my_config.signing_policy())
 
637
 
 
638
    def test_signatures_never(self):
 
639
        self.get_branch_config('/a/c')
 
640
        self.assertEqual(config.CHECK_NEVER,
 
641
                         self.my_config.signature_checking())
 
642
        
 
643
    def test_signatures_when_available(self):
 
644
        self.get_branch_config('/a/', global_config=sample_ignore_signatures)
 
645
        self.assertEqual(config.CHECK_IF_POSSIBLE,
 
646
                         self.my_config.signature_checking())
 
647
        
 
648
    def test_signatures_always(self):
 
649
        self.get_branch_config('/b')
 
650
        self.assertEqual(config.CHECK_ALWAYS,
 
651
                         self.my_config.signature_checking())
 
652
        
 
653
    def test_gpg_signing_command(self):
 
654
        self.get_branch_config('/b')
 
655
        self.assertEqual("gnome-gpg", self.my_config.gpg_signing_command())
 
656
 
 
657
    def test_gpg_signing_command_missing(self):
 
658
        self.get_branch_config('/a')
 
659
        self.assertEqual("false", self.my_config.gpg_signing_command())
 
660
 
 
661
    def test_get_user_option_global(self):
 
662
        self.get_branch_config('/a')
 
663
        self.assertEqual('something',
 
664
                         self.my_config.get_user_option('user_global_option'))
 
665
 
 
666
    def test_get_user_option_local(self):
 
667
        self.get_branch_config('/a')
 
668
        self.assertEqual('local',
 
669
                         self.my_config.get_user_option('user_local_option'))
 
670
 
 
671
    def test_post_commit_default(self):
 
672
        self.get_branch_config('/a/c')
 
673
        self.assertEqual('bzrlib.tests.test_config.post_commit',
 
674
                         self.my_config.post_commit())
 
675
 
 
676
    def get_branch_config(self, location, global_config=None):
 
677
        if global_config is None:
 
678
            global_file = StringIO(sample_config_text.encode('utf-8'))
 
679
        else:
 
680
            global_file = StringIO(global_config.encode('utf-8'))
 
681
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
 
682
        self.my_config = config.BranchConfig(FakeBranch(location))
 
683
        # Force location config to use specified file
 
684
        self.my_location_config = self.my_config._get_location_config()
 
685
        self.my_location_config._get_parser(branches_file)
 
686
        # Force global config to use specified file
 
687
        self.my_config._get_global_config()._get_parser(global_file)
 
688
 
 
689
    def test_set_user_setting_sets_and_saves(self):
 
690
        self.get_branch_config('/a/c')
 
691
        record = InstrumentedConfigObj("foo")
 
692
        self.my_location_config._parser = record
 
693
 
 
694
        real_mkdir = os.mkdir
 
695
        self.created = False
 
696
        def checked_mkdir(path, mode=0777):
 
697
            self.log('making directory: %s', path)
 
698
            real_mkdir(path, mode)
 
699
            self.created = True
 
700
 
 
701
        os.mkdir = checked_mkdir
 
702
        try:
 
703
            self.my_config.set_user_option('foo', 'bar', local=True)
 
704
        finally:
 
705
            os.mkdir = real_mkdir
 
706
 
 
707
        self.failUnless(self.created, 'Failed to create ~/.bazaar')
 
708
        self.assertEqual([('__contains__', '/a/c'),
 
709
                          ('__contains__', '/a/c/'),
 
710
                          ('__setitem__', '/a/c', {}),
 
711
                          ('__getitem__', '/a/c'),
 
712
                          ('__setitem__', 'foo', 'bar'),
 
713
                          ('write',)],
 
714
                         record._calls[1:])
 
715
 
 
716
    def test_set_user_setting_sets_and_saves2(self):
 
717
        self.get_branch_config('/a/c')
 
718
        self.assertIs(self.my_config.get_user_option('foo'), None)
 
719
        self.my_config.set_user_option('foo', 'bar')
 
720
        self.assertEqual(
 
721
            self.my_config.branch.control_files.files['branch.conf'], 
 
722
            'foo = bar')
 
723
        self.assertEqual(self.my_config.get_user_option('foo'), 'bar')
 
724
        self.my_config.set_user_option('foo', 'baz', local=True)
 
725
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
 
726
        self.my_config.set_user_option('foo', 'qux')
 
727
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
 
728
        
 
729
 
 
730
precedence_global = 'option = global'
 
731
precedence_branch = 'option = branch'
 
732
precedence_location = """
 
733
[http://]
 
734
recurse = true
 
735
option = recurse
 
736
[http://example.com/specific]
 
737
option = exact
 
738
"""
 
739
 
 
740
 
 
741
class TestBranchConfigItems(TestCaseInTempDir):
 
742
 
 
743
    def get_branch_config(self, global_config=None, location=None, 
 
744
                          location_config=None, branch_data_config=None):
 
745
        my_config = config.BranchConfig(FakeBranch(location))
 
746
        if global_config is not None:
 
747
            global_file = StringIO(global_config.encode('utf-8'))
 
748
            my_config._get_global_config()._get_parser(global_file)
 
749
        self.my_location_config = my_config._get_location_config()
 
750
        if location_config is not None:
 
751
            location_file = StringIO(location_config.encode('utf-8'))
 
752
            self.my_location_config._get_parser(location_file)
 
753
        if branch_data_config is not None:
 
754
            my_config.branch.control_files.files['branch.conf'] = \
 
755
                branch_data_config
 
756
        return my_config
 
757
 
 
758
    def test_user_id(self):
 
759
        branch = FakeBranch(user_id='Robert Collins <robertc@example.net>')
 
760
        my_config = config.BranchConfig(branch)
 
761
        self.assertEqual("Robert Collins <robertc@example.net>",
 
762
                         my_config.username())
 
763
        branch.control_files.email = "John"
 
764
        my_config.set_user_option('email', 
 
765
                                  "Robert Collins <robertc@example.org>")
 
766
        self.assertEqual("John", my_config.username())
 
767
        branch.control_files.email = None
 
768
        self.assertEqual("Robert Collins <robertc@example.org>",
 
769
                         my_config.username())
 
770
 
 
771
    def test_not_set_in_branch(self):
 
772
        my_config = self.get_branch_config(sample_config_text)
 
773
        my_config.branch.control_files.email = None
 
774
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
 
775
                         my_config._get_user_id())
 
776
        my_config.branch.control_files.email = "John"
 
777
        self.assertEqual("John", my_config._get_user_id())
 
778
 
 
779
    def test_BZR_EMAIL_OVERRIDES(self):
 
780
        os.environ['BZR_EMAIL'] = "Robert Collins <robertc@example.org>"
 
781
        branch = FakeBranch()
 
782
        my_config = config.BranchConfig(branch)
 
783
        self.assertEqual("Robert Collins <robertc@example.org>",
 
784
                         my_config.username())
 
785
    
 
786
    def test_signatures_forced(self):
 
787
        my_config = self.get_branch_config(
 
788
            global_config=sample_always_signatures)
 
789
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
 
790
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
 
791
        self.assertTrue(my_config.signature_needed())
 
792
 
 
793
    def test_signatures_forced_branch(self):
 
794
        my_config = self.get_branch_config(
 
795
            global_config=sample_ignore_signatures,
 
796
            branch_data_config=sample_always_signatures)
 
797
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
 
798
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
 
799
        self.assertTrue(my_config.signature_needed())
 
800
 
 
801
    def test_gpg_signing_command(self):
 
802
        my_config = self.get_branch_config(
 
803
            # branch data cannot set gpg_signing_command
 
804
            branch_data_config="gpg_signing_command=pgp")
 
805
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
806
        my_config._get_global_config()._get_parser(config_file)
 
807
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
 
808
 
 
809
    def test_get_user_option_global(self):
 
810
        branch = FakeBranch()
 
811
        my_config = config.BranchConfig(branch)
 
812
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
813
        (my_config._get_global_config()._get_parser(config_file))
 
814
        self.assertEqual('something',
 
815
                         my_config.get_user_option('user_global_option'))
 
816
 
 
817
    def test_post_commit_default(self):
 
818
        branch = FakeBranch()
 
819
        my_config = self.get_branch_config(sample_config_text, '/a/c',
 
820
                                           sample_branches_text)
 
821
        self.assertEqual(my_config.branch.base, '/a/c')
 
822
        self.assertEqual('bzrlib.tests.test_config.post_commit',
 
823
                         my_config.post_commit())
 
824
        my_config.set_user_option('post_commit', 'rmtree_root')
 
825
        # post-commit is ignored when bresent in branch data
 
826
        self.assertEqual('bzrlib.tests.test_config.post_commit',
 
827
                         my_config.post_commit())
 
828
        my_config.set_user_option('post_commit', 'rmtree_root', local=True)
 
829
        self.assertEqual('rmtree_root', my_config.post_commit())
 
830
 
 
831
    def test_config_precedence(self):
 
832
        my_config = self.get_branch_config(global_config=precedence_global)
 
833
        self.assertEqual(my_config.get_user_option('option'), 'global')
 
834
        my_config = self.get_branch_config(global_config=precedence_global, 
 
835
                                      branch_data_config=precedence_branch)
 
836
        self.assertEqual(my_config.get_user_option('option'), 'branch')
 
837
        my_config = self.get_branch_config(global_config=precedence_global, 
 
838
                                      branch_data_config=precedence_branch,
 
839
                                      location_config=precedence_location)
 
840
        self.assertEqual(my_config.get_user_option('option'), 'recurse')
 
841
        my_config = self.get_branch_config(global_config=precedence_global, 
 
842
                                      branch_data_config=precedence_branch,
 
843
                                      location_config=precedence_location,
 
844
                                      location='http://example.com/specific')
 
845
        self.assertEqual(my_config.get_user_option('option'), 'exact')
 
846
 
 
847
 
 
848
class TestMailAddressExtraction(TestCase):
 
849
 
 
850
    def test_extract_email_address(self):
 
851
        self.assertEqual('jane@test.com',
 
852
                         config.extract_email_address('Jane <jane@test.com>'))
 
853
        self.assertRaises(errors.NoEmailInUsername,
 
854
                          config.extract_email_address, 'Jane Tester')