~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Robert Collins
  • Date: 2006-06-26 16:23:10 UTC
  • mfrom: (1780.2.1 misc-fixen)
  • mto: This revision was merged to the branch mainline in revision 1815.
  • Revision ID: robertc@robertcollins.net-20060626162310-98f5b55b8cc19d46
(robertc) Misc minor typos and the like.

Show diffs side-by-side

added added

removed removed

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