~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

Late bind to PatienceSequenceMatcher to allow plugin to override.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
 
1
# Copyright (C) 2005, 2006 by 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
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"
69
 
                        "post_commit=bzrlib.selftest.testconfig.post_commit\n"
 
74
                        "post_commit=bzrlib.tests.test_config.post_commit\n"
70
75
                        "#testing explicit beats globs\n")
71
76
 
72
77
 
 
78
 
73
79
class InstrumentedConfigObj(object):
74
80
    """A config obj look-enough-alike to record calls made to it."""
75
81
 
76
 
    def __init__(self, input):
77
 
        self._calls = [('__init__', input)]
 
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',))
78
98
 
79
99
 
80
100
class FakeBranch(object):
81
101
 
82
102
    def __init__(self):
83
103
        self.base = "http://example.com/branches/demo"
 
104
        self.control_files = FakeControlFiles()
 
105
 
 
106
 
 
107
class FakeControlFiles(object):
 
108
 
 
109
    def __init__(self):
84
110
        self.email = 'Robert Collins <robertc@example.net>\n'
85
111
 
86
 
    def controlfile(self, filename, mode):
 
112
    def get_utf8(self, filename):
87
113
        if filename != 'email':
88
114
            raise NotImplementedError
89
115
        if self.email is not None:
90
116
            return StringIO(self.email)
91
 
        raise errors.NoSuchFile
 
117
        raise errors.NoSuchFile(filename)
92
118
 
93
119
 
94
120
class InstrumentedConfig(config.Config):
108
134
        return self._signatures
109
135
 
110
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
 
111
154
class TestConfig(TestCase):
112
155
 
113
156
    def test_constructs(self):
156
199
        my_config = config.Config()
157
200
        self.assertEqual(None, my_config.post_commit())
158
201
 
 
202
    def test_log_format_default(self):
 
203
        my_config = config.Config()
 
204
        self.assertEqual('long', my_config.log_format())
 
205
 
159
206
 
160
207
class TestConfigPath(TestCase):
161
208
 
162
209
    def setUp(self):
163
210
        super(TestConfigPath, self).setUp()
164
 
        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)
165
213
        os.environ['HOME'] = '/home/bogus'
 
214
        os.environ['APPDATA'] = \
 
215
            r'C:\Documents and Settings\bogus\Application Data'
166
216
 
167
217
    def tearDown(self):
168
 
        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
169
226
        super(TestConfigPath, self).tearDown()
170
227
    
171
228
    def test_config_dir(self):
172
 
        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')
173
234
 
174
235
    def test_config_filename(self):
175
 
        self.assertEqual(config.config_filename(),
176
 
                         '/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')
177
242
 
178
243
    def test_branches_config_filename(self):
179
 
        self.assertEqual(config.branches_config_filename(),
180
 
                         '/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')
181
250
 
182
251
class TestIniConfig(TestCase):
183
252
 
185
254
        my_config = config.IniBasedConfig("nothing")
186
255
 
187
256
    def test_from_fp(self):
188
 
        config_file = StringIO(sample_config_text)
 
257
        config_file = StringIO(sample_config_text.encode('utf-8'))
189
258
        my_config = config.IniBasedConfig(None)
190
259
        self.failUnless(
191
260
            isinstance(my_config._get_parser(file=config_file),
192
261
                        ConfigObj))
193
262
 
194
263
    def test_cached(self):
195
 
        config_file = StringIO(sample_config_text)
 
264
        config_file = StringIO(sample_config_text.encode('utf-8'))
196
265
        my_config = config.IniBasedConfig(None)
197
266
        parser = my_config._get_parser(file=config_file)
198
267
        self.failUnless(my_config._get_parser() is parser)
213
282
        finally:
214
283
            config.ConfigObj = oldparserclass
215
284
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
216
 
        self.assertEqual(parser._calls, [('__init__', config.config_filename())])
 
285
        self.assertEqual(parser._calls, [('__init__', config.config_filename(),
 
286
                                          'utf-8')])
217
287
 
218
288
 
219
289
class TestBranchConfig(TestCaseInTempDir):
234
304
class TestGlobalConfigItems(TestCase):
235
305
 
236
306
    def test_user_id(self):
237
 
        config_file = StringIO(sample_config_text)
 
307
        config_file = StringIO(sample_config_text.encode('utf-8'))
238
308
        my_config = config.GlobalConfig()
239
309
        my_config._parser = my_config._get_parser(file=config_file)
240
 
        self.assertEqual("Robert Collins <robertc@example.com>",
 
310
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
241
311
                         my_config._get_user_id())
242
312
 
243
313
    def test_absent_user_id(self):
247
317
        self.assertEqual(None, my_config._get_user_id())
248
318
 
249
319
    def test_configured_editor(self):
250
 
        config_file = StringIO(sample_config_text)
 
320
        config_file = StringIO(sample_config_text.encode('utf-8'))
251
321
        my_config = config.GlobalConfig()
252
322
        my_config._parser = my_config._get_parser(file=config_file)
253
323
        self.assertEqual("vim", my_config.get_editor())
277
347
        self.assertEqual(False, my_config.signature_needed())
278
348
 
279
349
    def _get_sample_config(self):
280
 
        config_file = StringIO(sample_config_text)
 
350
        config_file = StringIO(sample_config_text.encode('utf-8'))
281
351
        my_config = config.GlobalConfig()
282
352
        my_config._parser = my_config._get_parser(file=config_file)
283
353
        return my_config
310
380
        my_config = self._get_sample_config()
311
381
        self.assertEqual(None, my_config.post_commit())
312
382
 
313
 
 
314
 
 
315
 
class TestLocationConfig(TestCase):
 
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'))
 
398
 
 
399
 
 
400
class TestLocationConfig(TestCaseInTempDir):
316
401
 
317
402
    def test_constructs(self):
318
403
        my_config = config.LocationConfig('http://example.com')
332
417
            config.ConfigObj = oldparserclass
333
418
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
334
419
        self.assertEqual(parser._calls,
335
 
                         [('__init__', config.branches_config_filename())])
 
420
                         [('__init__', config.branches_config_filename(),
 
421
                           'utf-8')])
336
422
 
337
423
    def test_get_global_config(self):
338
424
        my_config = config.LocationConfig('http://example.com')
389
475
        self.get_location_config('/a/c')
390
476
        self.assertEqual('/a/c', self.my_config._get_section())
391
477
 
392
 
    def get_location_config(self, location, global_config=None):
393
 
        if global_config is None:
394
 
            global_file = StringIO(sample_config_text)
395
 
        else:
396
 
            global_file = StringIO(global_config)
397
 
        branches_file = StringIO(sample_branches_text)
398
 
        self.my_config = config.LocationConfig(location)
399
 
        self.my_config._get_parser(branches_file)
400
 
        self.my_config._get_global_config()._get_parser(global_file)
401
478
 
402
479
    def test_location_without_username(self):
403
480
        self.get_location_config('http://www.example.com/useglobal')
404
 
        self.assertEqual('Robert Collins <robertc@example.com>',
 
481
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
405
482
                         self.my_config.username())
406
483
 
407
484
    def test_location_not_listed(self):
 
485
        """Test that the global username is used when no location matches"""
408
486
        self.get_location_config('/home/robertc/sources')
409
 
        self.assertEqual('Robert Collins <robertc@example.com>',
 
487
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
410
488
                         self.my_config.username())
411
489
 
412
490
    def test_overriding_location(self):
455
533
        
456
534
    def test_post_commit_default(self):
457
535
        self.get_location_config('/a/c')
458
 
        self.assertEqual('bzrlib.selftest.testconfig.post_commit',
 
536
        self.assertEqual('bzrlib.tests.test_config.post_commit',
459
537
                         self.my_config.post_commit())
460
538
 
 
539
    def get_location_config(self, location, global_config=None):
 
540
        if global_config is None:
 
541
            global_file = StringIO(sample_config_text.encode('utf-8'))
 
542
        else:
 
543
            global_file = StringIO(global_config.encode('utf-8'))
 
544
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
 
545
        self.my_config = config.LocationConfig(location)
 
546
        self.my_config._get_parser(branches_file)
 
547
        self.my_config._get_global_config()._get_parser(global_file)
 
548
 
 
549
    def test_set_user_setting_sets_and_saves(self):
 
550
        self.get_location_config('/a/c')
 
551
        record = InstrumentedConfigObj("foo")
 
552
        self.my_config._parser = record
 
553
 
 
554
        real_mkdir = os.mkdir
 
555
        self.created = False
 
556
        def checked_mkdir(path, mode=0777):
 
557
            self.log('making directory: %s', path)
 
558
            real_mkdir(path, mode)
 
559
            self.created = True
 
560
 
 
561
        os.mkdir = checked_mkdir
 
562
        try:
 
563
            self.my_config.set_user_option('foo', 'bar')
 
564
        finally:
 
565
            os.mkdir = real_mkdir
 
566
 
 
567
        self.failUnless(self.created, 'Failed to create ~/.bazaar')
 
568
        self.assertEqual([('__contains__', '/a/c'),
 
569
                          ('__contains__', '/a/c/'),
 
570
                          ('__setitem__', '/a/c', {}),
 
571
                          ('__getitem__', '/a/c'),
 
572
                          ('__setitem__', 'foo', 'bar'),
 
573
                          ('write',)],
 
574
                         record._calls[1:])
 
575
 
461
576
 
462
577
class TestBranchConfigItems(TestCase):
463
578
 
466
581
        my_config = config.BranchConfig(branch)
467
582
        self.assertEqual("Robert Collins <robertc@example.net>",
468
583
                         my_config._get_user_id())
469
 
        branch.email = "John"
 
584
        branch.control_files.email = "John"
470
585
        self.assertEqual("John", my_config._get_user_id())
471
586
 
472
587
    def test_not_set_in_branch(self):
473
588
        branch = FakeBranch()
474
589
        my_config = config.BranchConfig(branch)
475
 
        branch.email = None
476
 
        config_file = StringIO(sample_config_text)
 
590
        branch.control_files.email = None
 
591
        config_file = StringIO(sample_config_text.encode('utf-8'))
477
592
        (my_config._get_location_config().
478
593
            _get_global_config()._get_parser(config_file))
479
 
        self.assertEqual("Robert Collins <robertc@example.com>",
 
594
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
480
595
                         my_config._get_user_id())
481
 
        branch.email = "John"
 
596
        branch.control_files.email = "John"
482
597
        self.assertEqual("John", my_config._get_user_id())
483
598
 
484
599
    def test_BZREMAIL_OVERRIDES(self):
499
614
    def test_gpg_signing_command(self):
500
615
        branch = FakeBranch()
501
616
        my_config = config.BranchConfig(branch)
502
 
        config_file = StringIO(sample_config_text)
 
617
        config_file = StringIO(sample_config_text.encode('utf-8'))
503
618
        (my_config._get_location_config().
504
619
            _get_global_config()._get_parser(config_file))
505
620
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
507
622
    def test_get_user_option_global(self):
508
623
        branch = FakeBranch()
509
624
        my_config = config.BranchConfig(branch)
510
 
        config_file = StringIO(sample_config_text)
 
625
        config_file = StringIO(sample_config_text.encode('utf-8'))
511
626
        (my_config._get_location_config().
512
627
            _get_global_config()._get_parser(config_file))
513
628
        self.assertEqual('something',
517
632
        branch = FakeBranch()
518
633
        branch.base='/a/c'
519
634
        my_config = config.BranchConfig(branch)
520
 
        config_file = StringIO(sample_config_text)
 
635
        config_file = StringIO(sample_config_text.encode('utf-8'))
521
636
        (my_config._get_location_config().
522
637
            _get_global_config()._get_parser(config_file))
523
638
        branch_file = StringIO(sample_branches_text)
524
639
        my_config._get_location_config()._get_parser(branch_file)
525
 
        self.assertEqual('bzrlib.selftest.testconfig.post_commit',
 
640
        self.assertEqual('bzrlib.tests.test_config.post_commit',
526
641
                         my_config.post_commit())
 
642
 
 
643
 
 
644
class TestMailAddressExtraction(TestCase):
 
645
 
 
646
    def test_extract_email_address(self):
 
647
        self.assertEqual('jane@test.com',
 
648
                         config.extract_email_address('Jane <jane@test.com>'))
 
649
        self.assertRaises(errors.BzrError,
 
650
                          config.extract_email_address, 'Jane Tester')