~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

Always include working tree when calculating file ids for diff

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, TestCaseWithTransport
 
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(TestCaseWithTransport):
 
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
    def test_has_explicit_nickname(self):
 
352
        b = self.make_branch('.')
 
353
        self.assertFalse(b.get_config().has_explicit_nickname())
 
354
        b.nick = 'foo'
 
355
        self.assertTrue(b.get_config().has_explicit_nickname())
 
356
 
 
357
 
 
358
class TestGlobalConfigItems(TestCase):
 
359
 
 
360
    def test_user_id(self):
 
361
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
362
        my_config = config.GlobalConfig()
 
363
        my_config._parser = my_config._get_parser(file=config_file)
 
364
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
 
365
                         my_config._get_user_id())
 
366
 
 
367
    def test_absent_user_id(self):
 
368
        config_file = StringIO("")
 
369
        my_config = config.GlobalConfig()
 
370
        my_config._parser = my_config._get_parser(file=config_file)
 
371
        self.assertEqual(None, my_config._get_user_id())
 
372
 
 
373
    def test_configured_editor(self):
 
374
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
375
        my_config = config.GlobalConfig()
 
376
        my_config._parser = my_config._get_parser(file=config_file)
 
377
        self.assertEqual("vim", my_config.get_editor())
 
378
 
 
379
    def test_signatures_always(self):
 
380
        config_file = StringIO(sample_always_signatures)
 
381
        my_config = config.GlobalConfig()
 
382
        my_config._parser = my_config._get_parser(file=config_file)
 
383
        self.assertEqual(config.CHECK_NEVER,
 
384
                         my_config.signature_checking())
 
385
        self.assertEqual(config.SIGN_ALWAYS,
 
386
                         my_config.signing_policy())
 
387
        self.assertEqual(True, my_config.signature_needed())
 
388
 
 
389
    def test_signatures_if_possible(self):
 
390
        config_file = StringIO(sample_maybe_signatures)
 
391
        my_config = config.GlobalConfig()
 
392
        my_config._parser = my_config._get_parser(file=config_file)
 
393
        self.assertEqual(config.CHECK_NEVER,
 
394
                         my_config.signature_checking())
 
395
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
 
396
                         my_config.signing_policy())
 
397
        self.assertEqual(False, my_config.signature_needed())
 
398
 
 
399
    def test_signatures_ignore(self):
 
400
        config_file = StringIO(sample_ignore_signatures)
 
401
        my_config = config.GlobalConfig()
 
402
        my_config._parser = my_config._get_parser(file=config_file)
 
403
        self.assertEqual(config.CHECK_ALWAYS,
 
404
                         my_config.signature_checking())
 
405
        self.assertEqual(config.SIGN_NEVER,
 
406
                         my_config.signing_policy())
 
407
        self.assertEqual(False, my_config.signature_needed())
 
408
 
 
409
    def _get_sample_config(self):
 
410
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
411
        my_config = config.GlobalConfig()
 
412
        my_config._parser = my_config._get_parser(file=config_file)
 
413
        return my_config
 
414
 
 
415
    def test_gpg_signing_command(self):
 
416
        my_config = self._get_sample_config()
 
417
        self.assertEqual("gnome-gpg", my_config.gpg_signing_command())
 
418
        self.assertEqual(False, my_config.signature_needed())
 
419
 
 
420
    def _get_empty_config(self):
 
421
        config_file = StringIO("")
 
422
        my_config = config.GlobalConfig()
 
423
        my_config._parser = my_config._get_parser(file=config_file)
 
424
        return my_config
 
425
 
 
426
    def test_gpg_signing_command_unset(self):
 
427
        my_config = self._get_empty_config()
 
428
        self.assertEqual("gpg", my_config.gpg_signing_command())
 
429
 
 
430
    def test_get_user_option_default(self):
 
431
        my_config = self._get_empty_config()
 
432
        self.assertEqual(None, my_config.get_user_option('no_option'))
 
433
 
 
434
    def test_get_user_option_global(self):
 
435
        my_config = self._get_sample_config()
 
436
        self.assertEqual("something",
 
437
                         my_config.get_user_option('user_global_option'))
 
438
        
 
439
    def test_post_commit_default(self):
 
440
        my_config = self._get_sample_config()
 
441
        self.assertEqual(None, my_config.post_commit())
 
442
 
 
443
    def test_configured_logformat(self):
 
444
        my_config = self._get_sample_config()
 
445
        self.assertEqual("short", my_config.log_format())
 
446
 
 
447
    def test_get_alias(self):
 
448
        my_config = self._get_sample_config()
 
449
        self.assertEqual('help', my_config.get_alias('h'))
 
450
 
 
451
    def test_get_no_alias(self):
 
452
        my_config = self._get_sample_config()
 
453
        self.assertEqual(None, my_config.get_alias('foo'))
 
454
 
 
455
    def test_get_long_alias(self):
 
456
        my_config = self._get_sample_config()
 
457
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
 
458
 
 
459
 
 
460
class TestLocationConfig(TestCaseInTempDir):
 
461
 
 
462
    def test_constructs(self):
 
463
        my_config = config.LocationConfig('http://example.com')
 
464
        self.assertRaises(TypeError, config.LocationConfig)
 
465
 
 
466
    def test_branch_calls_read_filenames(self):
 
467
        # This is testing the correct file names are provided.
 
468
        # TODO: consolidate with the test for GlobalConfigs filename checks.
 
469
        #
 
470
        # replace the class that is constructured, to check its parameters
 
471
        oldparserclass = config.ConfigObj
 
472
        config.ConfigObj = InstrumentedConfigObj
 
473
        try:
 
474
            my_config = config.LocationConfig('http://www.example.com')
 
475
            parser = my_config._get_parser()
 
476
        finally:
 
477
            config.ConfigObj = oldparserclass
 
478
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
 
479
        self.assertEqual(parser._calls,
 
480
                         [('__init__', config.locations_config_filename(),
 
481
                           'utf-8')])
 
482
        config.ensure_config_dir_exists()
 
483
        #os.mkdir(config.config_dir())
 
484
        f = file(config.branches_config_filename(), 'wb')
 
485
        f.write('')
 
486
        f.close()
 
487
        oldparserclass = config.ConfigObj
 
488
        config.ConfigObj = InstrumentedConfigObj
 
489
        try:
 
490
            my_config = config.LocationConfig('http://www.example.com')
 
491
            parser = my_config._get_parser()
 
492
        finally:
 
493
            config.ConfigObj = oldparserclass
 
494
 
 
495
    def test_get_global_config(self):
 
496
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
 
497
        global_config = my_config._get_global_config()
 
498
        self.failUnless(isinstance(global_config, config.GlobalConfig))
 
499
        self.failUnless(global_config is my_config._get_global_config())
 
500
 
 
501
    def test__get_section_no_match(self):
 
502
        self.get_branch_config('/')
 
503
        self.assertEqual(None, self.my_location_config._get_section())
 
504
        
 
505
    def test__get_section_exact(self):
 
506
        self.get_branch_config('http://www.example.com')
 
507
        self.assertEqual('http://www.example.com',
 
508
                         self.my_location_config._get_section())
 
509
   
 
510
    def test__get_section_suffix_does_not(self):
 
511
        self.get_branch_config('http://www.example.com-com')
 
512
        self.assertEqual(None, self.my_location_config._get_section())
 
513
 
 
514
    def test__get_section_subdir_recursive(self):
 
515
        self.get_branch_config('http://www.example.com/com')
 
516
        self.assertEqual('http://www.example.com',
 
517
                         self.my_location_config._get_section())
 
518
 
 
519
    def test__get_section_subdir_matches(self):
 
520
        self.get_branch_config('http://www.example.com/useglobal')
 
521
        self.assertEqual('http://www.example.com/useglobal',
 
522
                         self.my_location_config._get_section())
 
523
 
 
524
    def test__get_section_subdir_nonrecursive(self):
 
525
        self.get_branch_config(
 
526
            'http://www.example.com/useglobal/childbranch')
 
527
        self.assertEqual('http://www.example.com',
 
528
                         self.my_location_config._get_section())
 
529
 
 
530
    def test__get_section_subdir_trailing_slash(self):
 
531
        self.get_branch_config('/b')
 
532
        self.assertEqual('/b/', self.my_location_config._get_section())
 
533
 
 
534
    def test__get_section_subdir_child(self):
 
535
        self.get_branch_config('/a/foo')
 
536
        self.assertEqual('/a/*', self.my_location_config._get_section())
 
537
 
 
538
    def test__get_section_subdir_child_child(self):
 
539
        self.get_branch_config('/a/foo/bar')
 
540
        self.assertEqual('/a/', self.my_location_config._get_section())
 
541
 
 
542
    def test__get_section_trailing_slash_with_children(self):
 
543
        self.get_branch_config('/a/')
 
544
        self.assertEqual('/a/', self.my_location_config._get_section())
 
545
 
 
546
    def test__get_section_explicit_over_glob(self):
 
547
        self.get_branch_config('/a/c')
 
548
        self.assertEqual('/a/c', self.my_location_config._get_section())
 
549
 
 
550
 
 
551
    def test_location_without_username(self):
 
552
        self.get_branch_config('http://www.example.com/useglobal')
 
553
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
 
554
                         self.my_config.username())
 
555
 
 
556
    def test_location_not_listed(self):
 
557
        """Test that the global username is used when no location matches"""
 
558
        self.get_branch_config('/home/robertc/sources')
 
559
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
 
560
                         self.my_config.username())
 
561
 
 
562
    def test_overriding_location(self):
 
563
        self.get_branch_config('http://www.example.com/foo')
 
564
        self.assertEqual('Robert Collins <robertc@example.org>',
 
565
                         self.my_config.username())
 
566
 
 
567
    def test_signatures_not_set(self):
 
568
        self.get_branch_config('http://www.example.com',
 
569
                                 global_config=sample_ignore_signatures)
 
570
        self.assertEqual(config.CHECK_ALWAYS,
 
571
                         self.my_config.signature_checking())
 
572
        self.assertEqual(config.SIGN_NEVER,
 
573
                         self.my_config.signing_policy())
 
574
 
 
575
    def test_signatures_never(self):
 
576
        self.get_branch_config('/a/c')
 
577
        self.assertEqual(config.CHECK_NEVER,
 
578
                         self.my_config.signature_checking())
 
579
        
 
580
    def test_signatures_when_available(self):
 
581
        self.get_branch_config('/a/', global_config=sample_ignore_signatures)
 
582
        self.assertEqual(config.CHECK_IF_POSSIBLE,
 
583
                         self.my_config.signature_checking())
 
584
        
 
585
    def test_signatures_always(self):
 
586
        self.get_branch_config('/b')
 
587
        self.assertEqual(config.CHECK_ALWAYS,
 
588
                         self.my_config.signature_checking())
 
589
        
 
590
    def test_gpg_signing_command(self):
 
591
        self.get_branch_config('/b')
 
592
        self.assertEqual("gnome-gpg", self.my_config.gpg_signing_command())
 
593
 
 
594
    def test_gpg_signing_command_missing(self):
 
595
        self.get_branch_config('/a')
 
596
        self.assertEqual("false", self.my_config.gpg_signing_command())
 
597
 
 
598
    def test_get_user_option_global(self):
 
599
        self.get_branch_config('/a')
 
600
        self.assertEqual('something',
 
601
                         self.my_config.get_user_option('user_global_option'))
 
602
 
 
603
    def test_get_user_option_local(self):
 
604
        self.get_branch_config('/a')
 
605
        self.assertEqual('local',
 
606
                         self.my_config.get_user_option('user_local_option'))
 
607
        
 
608
    def test_post_commit_default(self):
 
609
        self.get_branch_config('/a/c')
 
610
        self.assertEqual('bzrlib.tests.test_config.post_commit',
 
611
                         self.my_config.post_commit())
 
612
 
 
613
    def get_branch_config(self, location, global_config=None):
 
614
        if global_config is None:
 
615
            global_file = StringIO(sample_config_text.encode('utf-8'))
 
616
        else:
 
617
            global_file = StringIO(global_config.encode('utf-8'))
 
618
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
 
619
        self.my_config = config.BranchConfig(FakeBranch(location))
 
620
        # Force location config to use specified file
 
621
        self.my_location_config = self.my_config._get_location_config()
 
622
        self.my_location_config._get_parser(branches_file)
 
623
        # Force global config to use specified file
 
624
        self.my_config._get_global_config()._get_parser(global_file)
 
625
 
 
626
    def test_set_user_setting_sets_and_saves(self):
 
627
        self.get_branch_config('/a/c')
 
628
        record = InstrumentedConfigObj("foo")
 
629
        self.my_location_config._parser = record
 
630
 
 
631
        real_mkdir = os.mkdir
 
632
        self.created = False
 
633
        def checked_mkdir(path, mode=0777):
 
634
            self.log('making directory: %s', path)
 
635
            real_mkdir(path, mode)
 
636
            self.created = True
 
637
 
 
638
        os.mkdir = checked_mkdir
 
639
        try:
 
640
            self.my_config.set_user_option('foo', 'bar', local=True)
 
641
        finally:
 
642
            os.mkdir = real_mkdir
 
643
 
 
644
        self.failUnless(self.created, 'Failed to create ~/.bazaar')
 
645
        self.assertEqual([('__contains__', '/a/c'),
 
646
                          ('__contains__', '/a/c/'),
 
647
                          ('__setitem__', '/a/c', {}),
 
648
                          ('__getitem__', '/a/c'),
 
649
                          ('__setitem__', 'foo', 'bar'),
 
650
                          ('write',)],
 
651
                         record._calls[1:])
 
652
 
 
653
    def test_set_user_setting_sets_and_saves2(self):
 
654
        self.get_branch_config('/a/c')
 
655
        self.assertIs(self.my_config.get_user_option('foo'), None)
 
656
        self.my_config.set_user_option('foo', 'bar')
 
657
        self.assertEqual(
 
658
            self.my_config.branch.control_files.files['branch.conf'], 
 
659
            'foo = bar')
 
660
        self.assertEqual(self.my_config.get_user_option('foo'), 'bar')
 
661
        self.my_config.set_user_option('foo', 'baz', local=True)
 
662
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
 
663
        self.my_config.set_user_option('foo', 'qux')
 
664
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
 
665
        
 
666
 
 
667
precedence_global = 'option = global'
 
668
precedence_branch = 'option = branch'
 
669
precedence_location = """
 
670
[http://]
 
671
recurse = true
 
672
option = recurse
 
673
[http://example.com/specific]
 
674
option = exact
 
675
"""
 
676
 
 
677
 
 
678
class TestBranchConfigItems(TestCaseInTempDir):
 
679
 
 
680
    def get_branch_config(self, global_config=None, location=None, 
 
681
                          location_config=None, branch_data_config=None):
 
682
        my_config = config.BranchConfig(FakeBranch(location))
 
683
        if global_config is not None:
 
684
            global_file = StringIO(global_config.encode('utf-8'))
 
685
            my_config._get_global_config()._get_parser(global_file)
 
686
        self.my_location_config = my_config._get_location_config()
 
687
        if location_config is not None:
 
688
            location_file = StringIO(location_config.encode('utf-8'))
 
689
            self.my_location_config._get_parser(location_file)
 
690
        if branch_data_config is not None:
 
691
            my_config.branch.control_files.files['branch.conf'] = \
 
692
                branch_data_config
 
693
        return my_config
 
694
 
 
695
    def test_user_id(self):
 
696
        branch = FakeBranch(user_id='Robert Collins <robertc@example.net>')
 
697
        my_config = config.BranchConfig(branch)
 
698
        self.assertEqual("Robert Collins <robertc@example.net>",
 
699
                         my_config.username())
 
700
        branch.control_files.email = "John"
 
701
        my_config.set_user_option('email', 
 
702
                                  "Robert Collins <robertc@example.org>")
 
703
        self.assertEqual("John", my_config.username())
 
704
        branch.control_files.email = None
 
705
        self.assertEqual("Robert Collins <robertc@example.org>",
 
706
                         my_config.username())
 
707
 
 
708
    def test_not_set_in_branch(self):
 
709
        my_config = self.get_branch_config(sample_config_text)
 
710
        my_config.branch.control_files.email = None
 
711
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
 
712
                         my_config._get_user_id())
 
713
        my_config.branch.control_files.email = "John"
 
714
        self.assertEqual("John", my_config._get_user_id())
 
715
 
 
716
    def test_BZREMAIL_OVERRIDES(self):
 
717
        os.environ['BZREMAIL'] = "Robert Collins <robertc@example.org>"
 
718
        branch = FakeBranch()
 
719
        my_config = config.BranchConfig(branch)
 
720
        self.assertEqual("Robert Collins <robertc@example.org>",
 
721
                         my_config.username())
 
722
    
 
723
    def test_signatures_forced(self):
 
724
        my_config = self.get_branch_config(
 
725
            global_config=sample_always_signatures)
 
726
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
 
727
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
 
728
        self.assertTrue(my_config.signature_needed())
 
729
 
 
730
    def test_signatures_forced_branch(self):
 
731
        my_config = self.get_branch_config(
 
732
            global_config=sample_ignore_signatures,
 
733
            branch_data_config=sample_always_signatures)
 
734
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
 
735
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
 
736
        self.assertTrue(my_config.signature_needed())
 
737
 
 
738
    def test_gpg_signing_command(self):
 
739
        my_config = self.get_branch_config(
 
740
            # branch data cannot set gpg_signing_command
 
741
            branch_data_config="gpg_signing_command=pgp")
 
742
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
743
        my_config._get_global_config()._get_parser(config_file)
 
744
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
 
745
 
 
746
    def test_get_user_option_global(self):
 
747
        branch = FakeBranch()
 
748
        my_config = config.BranchConfig(branch)
 
749
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
750
        (my_config._get_global_config()._get_parser(config_file))
 
751
        self.assertEqual('something',
 
752
                         my_config.get_user_option('user_global_option'))
 
753
 
 
754
    def test_post_commit_default(self):
 
755
        branch = FakeBranch()
 
756
        my_config = self.get_branch_config(sample_config_text, '/a/c',
 
757
                                           sample_branches_text)
 
758
        self.assertEqual(my_config.branch.base, '/a/c')
 
759
        self.assertEqual('bzrlib.tests.test_config.post_commit',
 
760
                         my_config.post_commit())
 
761
        my_config.set_user_option('post_commit', 'rmtree_root')
 
762
        # post-commit is ignored when bresent in branch data
 
763
        self.assertEqual('bzrlib.tests.test_config.post_commit',
 
764
                         my_config.post_commit())
 
765
        my_config.set_user_option('post_commit', 'rmtree_root', local=True)
 
766
        self.assertEqual('rmtree_root', my_config.post_commit())
 
767
 
 
768
    def test_config_precedence(self):
 
769
        my_config = self.get_branch_config(global_config=precedence_global)
 
770
        self.assertEqual(my_config.get_user_option('option'), 'global')
 
771
        my_config = self.get_branch_config(global_config=precedence_global, 
 
772
                                      branch_data_config=precedence_branch)
 
773
        self.assertEqual(my_config.get_user_option('option'), 'branch')
 
774
        my_config = self.get_branch_config(global_config=precedence_global, 
 
775
                                      branch_data_config=precedence_branch,
 
776
                                      location_config=precedence_location)
 
777
        self.assertEqual(my_config.get_user_option('option'), 'recurse')
 
778
        my_config = self.get_branch_config(global_config=precedence_global, 
 
779
                                      branch_data_config=precedence_branch,
 
780
                                      location_config=precedence_location,
 
781
                                      location='http://example.com/specific')
 
782
        self.assertEqual(my_config.get_user_option('option'), 'exact')
 
783
 
 
784
 
 
785
class TestMailAddressExtraction(TestCase):
 
786
 
 
787
    def test_extract_email_address(self):
 
788
        self.assertEqual('jane@test.com',
 
789
                         config.extract_email_address('Jane <jane@test.com>'))
 
790
        self.assertRaises(errors.BzrError,
 
791
                          config.extract_email_address, 'Jane Tester')