~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Aaron Bentley
  • Date: 2006-11-10 01:55:55 UTC
  • mto: This revision was merged to the branch mainline in revision 2127.
  • Revision ID: aaron.bentley@utoronto.ca-20061110015555-f48202744b630209
Ignore html docs (both kinds)

Show diffs side-by-side

added added

removed removed

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