~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

(mbp) merge bzr.dev to 0.8, prepare for release

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
25
25
#import bzrlib specific imports here
26
26
import bzrlib.config as config
27
27
import bzrlib.errors as errors
28
 
from bzrlib.selftest import TestCase, TestCaseInTempDir
29
 
 
30
 
 
 
28
from bzrlib.tests import TestCase, TestCaseInTempDir
 
29
 
 
30
 
 
31
sample_long_alias="log -r-15..-1 --line"
31
32
sample_config_text = ("[DEFAULT]\n"
32
 
                      "email=Robert Collins <robertc@example.com>\n"
 
33
                      u"email=Erik B\u00e5gfors <erik@bagfors.nu>\n"
33
34
                      "editor=vim\n"
34
35
                      "gpg_signing_command=gnome-gpg\n"
35
 
                      "user_global_option=something\n")
 
36
                      "log_format=short\n"
 
37
                      "user_global_option=something\n"
 
38
                      "[ALIASES]\n"
 
39
                      "h=help\n"
 
40
                      "ll=" + sample_long_alias + "\n")
36
41
 
37
42
 
38
43
sample_always_signatures = ("[DEFAULT]\n"
66
71
                        "recurse=False\n"
67
72
                        "[/a/c]\n"
68
73
                        "check_signatures=ignore\n"
 
74
                        "post_commit=bzrlib.tests.test_config.post_commit\n"
69
75
                        "#testing explicit beats globs\n")
70
76
 
71
77
 
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))
 
78
 
 
79
class InstrumentedConfigObj(object):
 
80
    """A config obj look-enough-alike to record calls made to it."""
 
81
 
 
82
    def __contains__(self, thing):
 
83
        self._calls.append(('__contains__', thing))
 
84
        return False
 
85
 
 
86
    def __getitem__(self, key):
 
87
        self._calls.append(('__getitem__', key))
 
88
        return self
 
89
 
 
90
    def __init__(self, input, encoding=None):
 
91
        self._calls = [('__init__', input, encoding)]
 
92
 
 
93
    def __setitem__(self, key, value):
 
94
        self._calls.append(('__setitem__', key, value))
 
95
 
 
96
    def write(self, arg):
 
97
        self._calls.append(('write',))
80
98
 
81
99
 
82
100
class FakeBranch(object):
83
101
 
84
102
    def __init__(self):
85
103
        self.base = "http://example.com/branches/demo"
 
104
        self.control_files = FakeControlFiles()
 
105
 
 
106
 
 
107
class FakeControlFiles(object):
 
108
 
 
109
    def __init__(self):
86
110
        self.email = 'Robert Collins <robertc@example.net>\n'
87
111
 
88
 
    def controlfile(self, filename, mode):
 
112
    def get_utf8(self, filename):
89
113
        if filename != 'email':
90
114
            raise NotImplementedError
91
115
        if self.email is not None:
92
116
            return StringIO(self.email)
93
 
        raise errors.NoSuchFile
 
117
        raise errors.NoSuchFile(filename)
94
118
 
95
119
 
96
120
class InstrumentedConfig(config.Config):
110
134
        return self._signatures
111
135
 
112
136
 
 
137
bool_config = """[DEFAULT]
 
138
active = true
 
139
inactive = false
 
140
[UPPERCASE]
 
141
active = True
 
142
nonactive = False
 
143
"""
 
144
class TestConfigObj(TestCase):
 
145
    def test_get_bool(self):
 
146
        from bzrlib.config import ConfigObj
 
147
        co = ConfigObj(StringIO(bool_config))
 
148
        self.assertIs(co.get_bool('DEFAULT', 'active'), True)
 
149
        self.assertIs(co.get_bool('DEFAULT', 'inactive'), False)
 
150
        self.assertIs(co.get_bool('UPPERCASE', 'active'), True)
 
151
        self.assertIs(co.get_bool('UPPERCASE', 'nonactive'), False)
 
152
 
 
153
 
113
154
class TestConfig(TestCase):
114
155
 
115
156
    def test_constructs(self):
154
195
        my_config = config.Config()
155
196
        self.assertEqual(None, my_config.get_user_option('no_option'))
156
197
 
 
198
    def test_post_commit_default(self):
 
199
        my_config = config.Config()
 
200
        self.assertEqual(None, my_config.post_commit())
 
201
 
 
202
    def test_log_format_default(self):
 
203
        my_config = config.Config()
 
204
        self.assertEqual('long', my_config.log_format())
 
205
 
157
206
 
158
207
class TestConfigPath(TestCase):
159
208
 
160
209
    def setUp(self):
161
210
        super(TestConfigPath, self).setUp()
162
 
        self.oldenv = os.environ.get('HOME', None)
 
211
        self.old_home = os.environ.get('HOME', None)
 
212
        self.old_appdata = os.environ.get('APPDATA', None)
163
213
        os.environ['HOME'] = '/home/bogus'
 
214
        os.environ['APPDATA'] = \
 
215
            r'C:\Documents and Settings\bogus\Application Data'
164
216
 
165
217
    def tearDown(self):
166
 
        os.environ['HOME'] = self.oldenv
 
218
        if self.old_home is None:
 
219
            del os.environ['HOME']
 
220
        else:
 
221
            os.environ['HOME'] = self.old_home
 
222
        if self.old_appdata is None:
 
223
            del os.environ['APPDATA']
 
224
        else:
 
225
            os.environ['APPDATA'] = self.old_appdata
167
226
        super(TestConfigPath, self).tearDown()
168
227
    
169
228
    def test_config_dir(self):
170
 
        self.assertEqual(config.config_dir(), '/home/bogus/.bazaar')
 
229
        if sys.platform == 'win32':
 
230
            self.assertEqual(config.config_dir(), 
 
231
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0')
 
232
        else:
 
233
            self.assertEqual(config.config_dir(), '/home/bogus/.bazaar')
171
234
 
172
235
    def test_config_filename(self):
173
 
        self.assertEqual(config.config_filename(),
174
 
                         '/home/bogus/.bazaar/bazaar.conf')
 
236
        if sys.platform == 'win32':
 
237
            self.assertEqual(config.config_filename(), 
 
238
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/bazaar.conf')
 
239
        else:
 
240
            self.assertEqual(config.config_filename(),
 
241
                             '/home/bogus/.bazaar/bazaar.conf')
175
242
 
176
243
    def test_branches_config_filename(self):
177
 
        self.assertEqual(config.branches_config_filename(),
178
 
                         '/home/bogus/.bazaar/branches.conf')
 
244
        if sys.platform == 'win32':
 
245
            self.assertEqual(config.branches_config_filename(), 
 
246
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/branches.conf')
 
247
        else:
 
248
            self.assertEqual(config.branches_config_filename(),
 
249
                             '/home/bogus/.bazaar/branches.conf')
179
250
 
180
251
class TestIniConfig(TestCase):
181
252
 
183
254
        my_config = config.IniBasedConfig("nothing")
184
255
 
185
256
    def test_from_fp(self):
186
 
        config_file = StringIO(sample_config_text)
 
257
        config_file = StringIO(sample_config_text.encode('utf-8'))
187
258
        my_config = config.IniBasedConfig(None)
188
259
        self.failUnless(
189
260
            isinstance(my_config._get_parser(file=config_file),
190
 
                        ConfigParser))
 
261
                        ConfigObj))
191
262
 
192
263
    def test_cached(self):
193
 
        config_file = StringIO(sample_config_text)
 
264
        config_file = StringIO(sample_config_text.encode('utf-8'))
194
265
        my_config = config.IniBasedConfig(None)
195
266
        parser = my_config._get_parser(file=config_file)
196
267
        self.failUnless(my_config._get_parser() is parser)
203
274
 
204
275
    def test_calls_read_filenames(self):
205
276
        # replace the class that is constructured, to check its parameters
206
 
        oldparserclass = config.ConfigParser
207
 
        config.ConfigParser = InstrumentedConfigParser
 
277
        oldparserclass = config.ConfigObj
 
278
        config.ConfigObj = InstrumentedConfigObj
208
279
        my_config = config.GlobalConfig()
209
280
        try:
210
281
            parser = my_config._get_parser()
211
282
        finally:
212
 
            config.ConfigParser = oldparserclass
213
 
        self.failUnless(isinstance(parser, InstrumentedConfigParser))
214
 
        self.assertEqual(parser._calls, [('read', [config.config_filename()])])
 
283
            config.ConfigObj = oldparserclass
 
284
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
 
285
        self.assertEqual(parser._calls, [('__init__', config.config_filename(),
 
286
                                          'utf-8')])
215
287
 
216
288
 
217
289
class TestBranchConfig(TestCaseInTempDir):
232
304
class TestGlobalConfigItems(TestCase):
233
305
 
234
306
    def test_user_id(self):
235
 
        config_file = StringIO(sample_config_text)
 
307
        config_file = StringIO(sample_config_text.encode('utf-8'))
236
308
        my_config = config.GlobalConfig()
237
309
        my_config._parser = my_config._get_parser(file=config_file)
238
 
        self.assertEqual("Robert Collins <robertc@example.com>",
 
310
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
239
311
                         my_config._get_user_id())
240
312
 
241
313
    def test_absent_user_id(self):
245
317
        self.assertEqual(None, my_config._get_user_id())
246
318
 
247
319
    def test_configured_editor(self):
248
 
        config_file = StringIO(sample_config_text)
 
320
        config_file = StringIO(sample_config_text.encode('utf-8'))
249
321
        my_config = config.GlobalConfig()
250
322
        my_config._parser = my_config._get_parser(file=config_file)
251
323
        self.assertEqual("vim", my_config.get_editor())
275
347
        self.assertEqual(False, my_config.signature_needed())
276
348
 
277
349
    def _get_sample_config(self):
278
 
        config_file = StringIO(sample_config_text)
 
350
        config_file = StringIO(sample_config_text.encode('utf-8'))
279
351
        my_config = config.GlobalConfig()
280
352
        my_config._parser = my_config._get_parser(file=config_file)
281
353
        return my_config
303
375
        my_config = self._get_sample_config()
304
376
        self.assertEqual("something",
305
377
                         my_config.get_user_option('user_global_option'))
306
 
 
 
378
        
 
379
    def test_post_commit_default(self):
 
380
        my_config = self._get_sample_config()
 
381
        self.assertEqual(None, my_config.post_commit())
 
382
 
 
383
    def test_configured_logformat(self):
 
384
        my_config = self._get_sample_config()
 
385
        self.assertEqual("short", my_config.log_format())
 
386
 
 
387
    def test_get_alias(self):
 
388
        my_config = self._get_sample_config()
 
389
        self.assertEqual('help', my_config.get_alias('h'))
 
390
 
 
391
    def test_get_no_alias(self):
 
392
        my_config = self._get_sample_config()
 
393
        self.assertEqual(None, my_config.get_alias('foo'))
 
394
 
 
395
    def test_get_long_alias(self):
 
396
        my_config = self._get_sample_config()
 
397
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
307
398
 
308
399
class TestLocationConfig(TestCase):
309
400
 
312
403
        self.assertRaises(TypeError, config.LocationConfig)
313
404
 
314
405
    def test_branch_calls_read_filenames(self):
 
406
        # This is testing the correct file names are provided.
 
407
        # TODO: consolidate with the test for GlobalConfigs filename checks.
 
408
        #
315
409
        # replace the class that is constructured, to check its parameters
316
 
        oldparserclass = config.ConfigParser
317
 
        config.ConfigParser = InstrumentedConfigParser
 
410
        oldparserclass = config.ConfigObj
 
411
        config.ConfigObj = InstrumentedConfigObj
318
412
        my_config = config.LocationConfig('http://www.example.com')
319
413
        try:
320
414
            parser = my_config._get_parser()
321
415
        finally:
322
 
            config.ConfigParser = oldparserclass
323
 
        self.failUnless(isinstance(parser, InstrumentedConfigParser))
324
 
        self.assertEqual(parser._calls, [('read', [config.branches_config_filename()])])
 
416
            config.ConfigObj = oldparserclass
 
417
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
 
418
        self.assertEqual(parser._calls,
 
419
                         [('__init__', config.branches_config_filename())])
325
420
 
326
421
    def test_get_global_config(self):
327
422
        my_config = config.LocationConfig('http://example.com')
441
536
        self.get_location_config('/a')
442
537
        self.assertEqual('local',
443
538
                         self.my_config.get_user_option('user_local_option'))
 
539
        
 
540
    def test_post_commit_default(self):
 
541
        self.get_location_config('/a/c')
 
542
        self.assertEqual('bzrlib.tests.test_config.post_commit',
 
543
                         self.my_config.post_commit())
 
544
 
 
545
 
 
546
class TestLocationConfig(TestCaseInTempDir):
 
547
 
 
548
    def get_location_config(self, location, global_config=None):
 
549
        if global_config is None:
 
550
            global_file = StringIO(sample_config_text.encode('utf-8'))
 
551
        else:
 
552
            global_file = StringIO(global_config.encode('utf-8'))
 
553
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
 
554
        self.my_config = config.LocationConfig(location)
 
555
        self.my_config._get_parser(branches_file)
 
556
        self.my_config._get_global_config()._get_parser(global_file)
 
557
 
 
558
    def test_set_user_setting_sets_and_saves(self):
 
559
        self.get_location_config('/a/c')
 
560
        record = InstrumentedConfigObj("foo")
 
561
        self.my_config._parser = record
 
562
 
 
563
        real_mkdir = os.mkdir
 
564
        self.created = False
 
565
        def checked_mkdir(path, mode=0777):
 
566
            self.log('making directory: %s', path)
 
567
            real_mkdir(path, mode)
 
568
            self.created = True
 
569
 
 
570
        os.mkdir = checked_mkdir
 
571
        try:
 
572
            self.my_config.set_user_option('foo', 'bar')
 
573
        finally:
 
574
            os.mkdir = real_mkdir
 
575
 
 
576
        self.failUnless(self.created, 'Failed to create ~/.bazaar')
 
577
        self.assertEqual([('__contains__', '/a/c'),
 
578
                          ('__contains__', '/a/c/'),
 
579
                          ('__setitem__', '/a/c', {}),
 
580
                          ('__getitem__', '/a/c'),
 
581
                          ('__setitem__', 'foo', 'bar'),
 
582
                          ('write',)],
 
583
                         record._calls[1:])
444
584
 
445
585
 
446
586
class TestBranchConfigItems(TestCase):
450
590
        my_config = config.BranchConfig(branch)
451
591
        self.assertEqual("Robert Collins <robertc@example.net>",
452
592
                         my_config._get_user_id())
453
 
        branch.email = "John"
 
593
        branch.control_files.email = "John"
454
594
        self.assertEqual("John", my_config._get_user_id())
455
595
 
456
596
    def test_not_set_in_branch(self):
457
597
        branch = FakeBranch()
458
598
        my_config = config.BranchConfig(branch)
459
 
        branch.email = None
460
 
        config_file = StringIO(sample_config_text)
 
599
        branch.control_files.email = None
 
600
        config_file = StringIO(sample_config_text.encode('utf-8'))
461
601
        (my_config._get_location_config().
462
602
            _get_global_config()._get_parser(config_file))
463
 
        self.assertEqual("Robert Collins <robertc@example.com>",
 
603
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
464
604
                         my_config._get_user_id())
465
 
        branch.email = "John"
 
605
        branch.control_files.email = "John"
466
606
        self.assertEqual("John", my_config._get_user_id())
467
607
 
468
608
    def test_BZREMAIL_OVERRIDES(self):
483
623
    def test_gpg_signing_command(self):
484
624
        branch = FakeBranch()
485
625
        my_config = config.BranchConfig(branch)
486
 
        config_file = StringIO(sample_config_text)
 
626
        config_file = StringIO(sample_config_text.encode('utf-8'))
487
627
        (my_config._get_location_config().
488
628
            _get_global_config()._get_parser(config_file))
489
629
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
491
631
    def test_get_user_option_global(self):
492
632
        branch = FakeBranch()
493
633
        my_config = config.BranchConfig(branch)
494
 
        config_file = StringIO(sample_config_text)
 
634
        config_file = StringIO(sample_config_text.encode('utf-8'))
495
635
        (my_config._get_location_config().
496
636
            _get_global_config()._get_parser(config_file))
497
637
        self.assertEqual('something',
498
638
                         my_config.get_user_option('user_global_option'))
 
639
 
 
640
    def test_post_commit_default(self):
 
641
        branch = FakeBranch()
 
642
        branch.base='/a/c'
 
643
        my_config = config.BranchConfig(branch)
 
644
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
645
        (my_config._get_location_config().
 
646
            _get_global_config()._get_parser(config_file))
 
647
        branch_file = StringIO(sample_branches_text)
 
648
        my_config._get_location_config()._get_parser(branch_file)
 
649
        self.assertEqual('bzrlib.tests.test_config.post_commit',
 
650
                         my_config.post_commit())
 
651
 
 
652
 
 
653
class TestMailAddressExtraction(TestCase):
 
654
 
 
655
    def test_extract_email_address(self):
 
656
        self.assertEqual('jane@test.com',
 
657
                         config.extract_email_address('Jane <jane@test.com>'))
 
658
        self.assertRaises(errors.BzrError,
 
659
                          config.extract_email_address, 'Jane Tester')