~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Jelmer Vernooij
  • Date: 2012-01-06 22:44:57 UTC
  • mfrom: (6436 +trunk)
  • mto: (6437.3.11 2.5)
  • mto: This revision was merged to the branch mainline in revision 6444.
  • Revision ID: jelmer@samba.org-20120106224457-re0pcy0fz31xob77
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
144
144
config.test_stack_builder_registry.register('branch', build_branch_stack)
145
145
 
146
146
 
147
 
def build_remote_branch_stack(test):
 
147
def build_branch_only_stack(test):
148
148
    # There is only one permutation (but we won't be able to handle more with
149
149
    # this design anyway)
150
150
    (transport_class,
151
151
     server_class) = transport_remote.get_test_permutations()[0]
152
152
    build_backing_branch(test, 'branch', transport_class, server_class)
153
153
    b = branch.Branch.open(test.get_url('branch'))
154
 
    return config.RemoteBranchStack(b)
155
 
config.test_stack_builder_registry.register('remote_branch',
156
 
                                            build_remote_branch_stack)
 
154
    return config.BranchOnlyStack(b)
 
155
config.test_stack_builder_registry.register('branch_only',
 
156
                                            build_branch_only_stack)
157
157
 
158
158
def build_remote_control_stack(test):
159
159
    # There is only one permutation (but we won't be able to handle more with
494
494
 
495
495
    def test_signatures_default(self):
496
496
        my_config = config.Config()
497
 
        self.assertFalse(my_config.signature_needed())
 
497
        self.assertFalse(
 
498
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
499
                my_config.signature_needed))
498
500
        self.assertEqual(config.CHECK_IF_POSSIBLE,
499
 
                         my_config.signature_checking())
 
501
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
502
                my_config.signature_checking))
500
503
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
501
 
                         my_config.signing_policy())
 
504
                self.applyDeprecated(deprecated_in((2, 5, 0)),
 
505
                    my_config.signing_policy))
502
506
 
503
507
    def test_signatures_template_method(self):
504
508
        my_config = InstrumentedConfig()
505
 
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
 
509
        self.assertEqual(config.CHECK_NEVER,
 
510
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
511
                my_config.signature_checking))
506
512
        self.assertEqual(['_get_signature_checking'], my_config._calls)
507
513
 
508
514
    def test_signatures_template_method_none(self):
509
515
        my_config = InstrumentedConfig()
510
516
        my_config._signatures = None
511
517
        self.assertEqual(config.CHECK_IF_POSSIBLE,
512
 
                         my_config.signature_checking())
 
518
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
519
                             my_config.signature_checking))
513
520
        self.assertEqual(['_get_signature_checking'], my_config._calls)
514
521
 
515
522
    def test_gpg_signing_command_default(self):
516
523
        my_config = config.Config()
517
 
        self.assertEqual('gpg', my_config.gpg_signing_command())
 
524
        self.assertEqual('gpg',
 
525
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
526
                my_config.gpg_signing_command))
518
527
 
519
528
    def test_get_user_option_default(self):
520
529
        my_config = config.Config()
522
531
 
523
532
    def test_post_commit_default(self):
524
533
        my_config = config.Config()
525
 
        self.assertEqual(None, my_config.post_commit())
 
534
        self.assertEqual(None, self.applyDeprecated(deprecated_in((2, 5, 0)),
 
535
                                                    my_config.post_commit))
 
536
 
526
537
 
527
538
    def test_log_format_default(self):
528
539
        my_config = config.Config()
529
 
        self.assertEqual('long', my_config.log_format())
 
540
        self.assertEqual('long',
 
541
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
542
                                              my_config.log_format))
530
543
 
531
544
    def test_acceptable_keys_default(self):
532
545
        my_config = config.Config()
533
 
        self.assertEqual(None, my_config.acceptable_keys())
 
546
        self.assertEqual(None, self.applyDeprecated(deprecated_in((2, 5, 0)),
 
547
            my_config.acceptable_keys))
534
548
 
535
549
    def test_validate_signatures_in_log_default(self):
536
550
        my_config = config.Config()
1057
1071
si_g = 5g,
1058
1072
si_gb = 5gB,
1059
1073
""")
1060
 
        get_si = conf.get_user_option_as_int_from_SI
 
1074
        def get_si(s, default=None):
 
1075
            return self.applyDeprecated(
 
1076
                deprecated_in((2, 5, 0)),
 
1077
                conf.get_user_option_as_int_from_SI, s, default)
1061
1078
        self.assertEqual(100, get_si('plain'))
1062
1079
        self.assertEqual(5000, get_si('si_k'))
1063
1080
        self.assertEqual(5000, get_si('si_kb'))
1068
1085
        self.assertEqual(None, get_si('non-exist'))
1069
1086
        self.assertEqual(42, get_si('non-exist-with-default',  42))
1070
1087
 
 
1088
 
1071
1089
class TestSupressWarning(TestIniConfig):
1072
1090
 
1073
1091
    def make_warnings_config(self, s):
1229
1247
    def test_signatures_always(self):
1230
1248
        my_config = config.GlobalConfig.from_string(sample_always_signatures)
1231
1249
        self.assertEqual(config.CHECK_NEVER,
1232
 
                         my_config.signature_checking())
 
1250
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1251
                             my_config.signature_checking))
1233
1252
        self.assertEqual(config.SIGN_ALWAYS,
1234
 
                         my_config.signing_policy())
1235
 
        self.assertEqual(True, my_config.signature_needed())
 
1253
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1254
                             my_config.signing_policy))
 
1255
        self.assertEqual(True,
 
1256
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1257
                my_config.signature_needed))
1236
1258
 
1237
1259
    def test_signatures_if_possible(self):
1238
1260
        my_config = config.GlobalConfig.from_string(sample_maybe_signatures)
1239
1261
        self.assertEqual(config.CHECK_NEVER,
1240
 
                         my_config.signature_checking())
 
1262
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1263
                             my_config.signature_checking))
1241
1264
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
1242
 
                         my_config.signing_policy())
1243
 
        self.assertEqual(False, my_config.signature_needed())
 
1265
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1266
                             my_config.signing_policy))
 
1267
        self.assertEqual(False, self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1268
            my_config.signature_needed))
1244
1269
 
1245
1270
    def test_signatures_ignore(self):
1246
1271
        my_config = config.GlobalConfig.from_string(sample_ignore_signatures)
1247
1272
        self.assertEqual(config.CHECK_ALWAYS,
1248
 
                         my_config.signature_checking())
 
1273
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1274
                             my_config.signature_checking))
1249
1275
        self.assertEqual(config.SIGN_NEVER,
1250
 
                         my_config.signing_policy())
1251
 
        self.assertEqual(False, my_config.signature_needed())
 
1276
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1277
                             my_config.signing_policy))
 
1278
        self.assertEqual(False, self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1279
            my_config.signature_needed))
1252
1280
 
1253
1281
    def _get_sample_config(self):
1254
1282
        my_config = config.GlobalConfig.from_string(sample_config_text)
1256
1284
 
1257
1285
    def test_gpg_signing_command(self):
1258
1286
        my_config = self._get_sample_config()
1259
 
        self.assertEqual("gnome-gpg", my_config.gpg_signing_command())
1260
 
        self.assertEqual(False, my_config.signature_needed())
 
1287
        self.assertEqual("gnome-gpg",
 
1288
            self.applyDeprecated(
 
1289
                deprecated_in((2, 5, 0)), my_config.gpg_signing_command))
 
1290
        self.assertEqual(False, self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1291
            my_config.signature_needed))
1261
1292
 
1262
1293
    def test_gpg_signing_key(self):
1263
1294
        my_config = self._get_sample_config()
1264
 
        self.assertEqual("DD4D5088", my_config.gpg_signing_key())
 
1295
        self.assertEqual("DD4D5088",
 
1296
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1297
                my_config.gpg_signing_key))
1265
1298
 
1266
1299
    def _get_empty_config(self):
1267
1300
        my_config = config.GlobalConfig()
1269
1302
 
1270
1303
    def test_gpg_signing_command_unset(self):
1271
1304
        my_config = self._get_empty_config()
1272
 
        self.assertEqual("gpg", my_config.gpg_signing_command())
 
1305
        self.assertEqual("gpg",
 
1306
            self.applyDeprecated(
 
1307
                deprecated_in((2, 5, 0)), my_config.gpg_signing_command))
1273
1308
 
1274
1309
    def test_get_user_option_default(self):
1275
1310
        my_config = self._get_empty_config()
1282
1317
 
1283
1318
    def test_post_commit_default(self):
1284
1319
        my_config = self._get_sample_config()
1285
 
        self.assertEqual(None, my_config.post_commit())
 
1320
        self.assertEqual(None,
 
1321
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1322
                                              my_config.post_commit))
1286
1323
 
1287
1324
    def test_configured_logformat(self):
1288
1325
        my_config = self._get_sample_config()
1289
 
        self.assertEqual("short", my_config.log_format())
 
1326
        self.assertEqual("short",
 
1327
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1328
                                              my_config.log_format))
1290
1329
 
1291
1330
    def test_configured_acceptable_keys(self):
1292
1331
        my_config = self._get_sample_config()
1293
 
        self.assertEqual("amy", my_config.acceptable_keys())
 
1332
        self.assertEqual("amy",
 
1333
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1334
                my_config.acceptable_keys))
1294
1335
 
1295
1336
    def test_configured_validate_signatures_in_log(self):
1296
1337
        my_config = self._get_sample_config()
1532
1573
        self.get_branch_config('http://www.example.com',
1533
1574
                                 global_config=sample_ignore_signatures)
1534
1575
        self.assertEqual(config.CHECK_ALWAYS,
1535
 
                         self.my_config.signature_checking())
 
1576
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1577
                             self.my_config.signature_checking))
1536
1578
        self.assertEqual(config.SIGN_NEVER,
1537
 
                         self.my_config.signing_policy())
 
1579
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1580
                             self.my_config.signing_policy))
1538
1581
 
1539
1582
    def test_signatures_never(self):
1540
1583
        self.get_branch_config('/a/c')
1541
1584
        self.assertEqual(config.CHECK_NEVER,
1542
 
                         self.my_config.signature_checking())
 
1585
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1586
                             self.my_config.signature_checking))
1543
1587
 
1544
1588
    def test_signatures_when_available(self):
1545
1589
        self.get_branch_config('/a/', global_config=sample_ignore_signatures)
1546
1590
        self.assertEqual(config.CHECK_IF_POSSIBLE,
1547
 
                         self.my_config.signature_checking())
 
1591
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1592
                             self.my_config.signature_checking))
1548
1593
 
1549
1594
    def test_signatures_always(self):
1550
1595
        self.get_branch_config('/b')
1551
1596
        self.assertEqual(config.CHECK_ALWAYS,
1552
 
                         self.my_config.signature_checking())
 
1597
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1598
                         self.my_config.signature_checking))
1553
1599
 
1554
1600
    def test_gpg_signing_command(self):
1555
1601
        self.get_branch_config('/b')
1556
 
        self.assertEqual("gnome-gpg", self.my_config.gpg_signing_command())
 
1602
        self.assertEqual("gnome-gpg",
 
1603
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1604
                self.my_config.gpg_signing_command))
1557
1605
 
1558
1606
    def test_gpg_signing_command_missing(self):
1559
1607
        self.get_branch_config('/a')
1560
 
        self.assertEqual("false", self.my_config.gpg_signing_command())
 
1608
        self.assertEqual("false",
 
1609
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1610
                self.my_config.gpg_signing_command))
1561
1611
 
1562
1612
    def test_gpg_signing_key(self):
1563
1613
        self.get_branch_config('/b')
1564
 
        self.assertEqual("DD4D5088", self.my_config.gpg_signing_key())
 
1614
        self.assertEqual("DD4D5088", self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1615
            self.my_config.gpg_signing_key))
1565
1616
 
1566
1617
    def test_gpg_signing_key_default(self):
1567
1618
        self.get_branch_config('/a')
1568
 
        self.assertEqual("erik@bagfors.nu", self.my_config.gpg_signing_key())
 
1619
        self.assertEqual("erik@bagfors.nu",
 
1620
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1621
                self.my_config.gpg_signing_key))
1569
1622
 
1570
1623
    def test_get_user_option_global(self):
1571
1624
        self.get_branch_config('/a')
1659
1712
    def test_post_commit_default(self):
1660
1713
        self.get_branch_config('/a/c')
1661
1714
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1662
 
                         self.my_config.post_commit())
 
1715
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1716
                                              self.my_config.post_commit))
1663
1717
 
1664
1718
    def get_branch_config(self, location, global_config=None,
1665
1719
                          location_config=None):
1774
1828
    def test_signatures_forced(self):
1775
1829
        my_config = self.get_branch_config(
1776
1830
            global_config=sample_always_signatures)
1777
 
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
1778
 
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
1779
 
        self.assertTrue(my_config.signature_needed())
 
1831
        self.assertEqual(config.CHECK_NEVER,
 
1832
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1833
                my_config.signature_checking))
 
1834
        self.assertEqual(config.SIGN_ALWAYS,
 
1835
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1836
                my_config.signing_policy))
 
1837
        self.assertTrue(self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1838
            my_config.signature_needed))
1780
1839
 
1781
1840
    def test_signatures_forced_branch(self):
1782
1841
        my_config = self.get_branch_config(
1783
1842
            global_config=sample_ignore_signatures,
1784
1843
            branch_data_config=sample_always_signatures)
1785
 
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
1786
 
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
1787
 
        self.assertTrue(my_config.signature_needed())
 
1844
        self.assertEqual(config.CHECK_NEVER,
 
1845
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1846
                my_config.signature_checking))
 
1847
        self.assertEqual(config.SIGN_ALWAYS,
 
1848
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1849
                my_config.signing_policy))
 
1850
        self.assertTrue(self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1851
            my_config.signature_needed))
1788
1852
 
1789
1853
    def test_gpg_signing_command(self):
1790
1854
        my_config = self.get_branch_config(
1791
1855
            global_config=sample_config_text,
1792
1856
            # branch data cannot set gpg_signing_command
1793
1857
            branch_data_config="gpg_signing_command=pgp")
1794
 
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
 
1858
        self.assertEqual('gnome-gpg',
 
1859
            self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1860
                my_config.gpg_signing_command))
1795
1861
 
1796
1862
    def test_get_user_option_global(self):
1797
1863
        my_config = self.get_branch_config(global_config=sample_config_text)
1804
1870
                                      location_config=sample_branches_text)
1805
1871
        self.assertEqual(my_config.branch.base, '/a/c')
1806
1872
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1807
 
                         my_config.post_commit())
 
1873
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1874
                                              my_config.post_commit))
1808
1875
        my_config.set_user_option('post_commit', 'rmtree_root')
1809
1876
        # post-commit is ignored when present in branch data
1810
1877
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1811
 
                         my_config.post_commit())
 
1878
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1879
                                              my_config.post_commit))
1812
1880
        my_config.set_user_option('post_commit', 'rmtree_root',
1813
1881
                                  store=config.STORE_LOCATION)
1814
 
        self.assertEqual('rmtree_root', my_config.post_commit())
 
1882
        self.assertEqual('rmtree_root',
 
1883
                         self.applyDeprecated(deprecated_in((2, 5, 0)),
 
1884
                                              my_config.post_commit))
1815
1885
 
1816
1886
    def test_config_precedence(self):
1817
1887
        # FIXME: eager test, luckily no persitent config file makes it fail
2296
2366
class TestOptionConverterMixin(object):
2297
2367
 
2298
2368
    def assertConverted(self, expected, opt, value):
2299
 
        self.assertEquals(expected, opt.convert_from_unicode(value))
2300
 
 
2301
 
    def assertWarns(self, opt, value):
2302
 
        warnings = []
2303
 
        def warning(*args):
2304
 
            warnings.append(args[0] % args[1:])
2305
 
        self.overrideAttr(trace, 'warning', warning)
2306
 
        self.assertEquals(None, opt.convert_from_unicode(value))
2307
 
        self.assertLength(1, warnings)
2308
 
        self.assertEquals(
2309
 
            'Value "%s" is not valid for "%s"' % (value, opt.name),
2310
 
            warnings[0])
2311
 
 
2312
 
    def assertErrors(self, opt, value):
2313
 
        self.assertRaises(errors.ConfigOptionValueError,
2314
 
                          opt.convert_from_unicode, value)
2315
 
 
2316
 
    def assertConvertInvalid(self, opt, invalid_value):
2317
 
        opt.invalid = None
2318
 
        self.assertEquals(None, opt.convert_from_unicode(invalid_value))
2319
 
        opt.invalid = 'warning'
2320
 
        self.assertWarns(opt, invalid_value)
2321
 
        opt.invalid = 'error'
2322
 
        self.assertErrors(opt, invalid_value)
2323
 
 
2324
 
 
2325
 
class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
2326
 
 
2327
 
    def get_option(self):
2328
 
        return config.Option('foo', help='A boolean.',
2329
 
                             from_unicode=config.bool_from_store)
2330
 
 
2331
 
    def test_convert_invalid(self):
2332
 
        opt = self.get_option()
2333
 
        # A string that is not recognized as a boolean
2334
 
        self.assertConvertInvalid(opt, u'invalid-boolean')
2335
 
        # A list of strings is never recognized as a boolean
2336
 
        self.assertConvertInvalid(opt, [u'not', u'a', u'boolean'])
2337
 
 
2338
 
    def test_convert_valid(self):
2339
 
        opt = self.get_option()
2340
 
        self.assertConverted(True, opt, u'True')
2341
 
        self.assertConverted(True, opt, u'1')
2342
 
        self.assertConverted(False, opt, u'False')
2343
 
 
2344
 
 
2345
 
class TestOptionWithIntegerConverter(tests.TestCase, TestOptionConverterMixin):
2346
 
 
2347
 
    def get_option(self):
2348
 
        return config.Option('foo', help='An integer.',
2349
 
                             from_unicode=config.int_from_store)
2350
 
 
2351
 
    def test_convert_invalid(self):
2352
 
        opt = self.get_option()
2353
 
        # A string that is not recognized as an integer
2354
 
        self.assertConvertInvalid(opt, u'forty-two')
2355
 
        # A list of strings is never recognized as an integer
2356
 
        self.assertConvertInvalid(opt, [u'a', u'list'])
2357
 
 
2358
 
    def test_convert_valid(self):
2359
 
        opt = self.get_option()
2360
 
        self.assertConverted(16, opt, u'16')
2361
 
 
2362
 
 
2363
 
class TestOptionWithListConverter(tests.TestCase, TestOptionConverterMixin):
2364
 
 
2365
 
    def get_option(self):
2366
 
        return config.Option('foo', help='A list.',
2367
 
                             from_unicode=config.list_from_store)
2368
 
 
2369
 
    def test_convert_invalid(self):
2370
 
        # No string is invalid as all forms can be converted to a list
2371
 
        pass
2372
 
 
2373
 
    def test_convert_valid(self):
2374
 
        opt = self.get_option()
2375
 
        # An empty string is an empty list
2376
 
        self.assertConverted([], opt, '') # Using a bare str() just in case
2377
 
        self.assertConverted([], opt, u'')
2378
 
        # A boolean
2379
 
        self.assertConverted([u'True'], opt, u'True')
2380
 
        # An integer
2381
 
        self.assertConverted([u'42'], opt, u'42')
2382
 
        # A single string
2383
 
        self.assertConverted([u'bar'], opt, u'bar')
2384
 
        # A list remains a list (configObj will turn a string containing commas
2385
 
        # into a list, but that's not what we're testing here)
2386
 
        self.assertConverted([u'foo', u'1', u'True'],
2387
 
                             opt, [u'foo', u'1', u'True'])
2388
 
 
2389
 
 
2390
 
class TestOptionConverterMixin(object):
2391
 
 
2392
 
    def assertConverted(self, expected, opt, value):
2393
 
        self.assertEquals(expected, opt.convert_from_unicode(value))
2394
 
 
2395
 
    def assertWarns(self, opt, value):
2396
 
        warnings = []
2397
 
        def warning(*args):
2398
 
            warnings.append(args[0] % args[1:])
2399
 
        self.overrideAttr(trace, 'warning', warning)
2400
 
        self.assertEquals(None, opt.convert_from_unicode(value))
2401
 
        self.assertLength(1, warnings)
2402
 
        self.assertEquals(
2403
 
            'Value "%s" is not valid for "%s"' % (value, opt.name),
2404
 
            warnings[0])
2405
 
 
2406
 
    def assertErrors(self, opt, value):
2407
 
        self.assertRaises(errors.ConfigOptionValueError,
2408
 
                          opt.convert_from_unicode, value)
2409
 
 
2410
 
    def assertConvertInvalid(self, opt, invalid_value):
2411
 
        opt.invalid = None
2412
 
        self.assertEquals(None, opt.convert_from_unicode(invalid_value))
2413
 
        opt.invalid = 'warning'
2414
 
        self.assertWarns(opt, invalid_value)
2415
 
        opt.invalid = 'error'
2416
 
        self.assertErrors(opt, invalid_value)
2417
 
 
2418
 
 
2419
 
class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
2420
 
 
2421
 
    def get_option(self):
2422
 
        return config.Option('foo', help='A boolean.',
2423
 
                             from_unicode=config.bool_from_store)
2424
 
 
2425
 
    def test_convert_invalid(self):
2426
 
        opt = self.get_option()
2427
 
        # A string that is not recognized as a boolean
2428
 
        self.assertConvertInvalid(opt, u'invalid-boolean')
2429
 
        # A list of strings is never recognized as a boolean
2430
 
        self.assertConvertInvalid(opt, [u'not', u'a', u'boolean'])
2431
 
 
2432
 
    def test_convert_valid(self):
2433
 
        opt = self.get_option()
2434
 
        self.assertConverted(True, opt, u'True')
2435
 
        self.assertConverted(True, opt, u'1')
2436
 
        self.assertConverted(False, opt, u'False')
2437
 
 
2438
 
 
2439
 
class TestOptionWithIntegerConverter(tests.TestCase, TestOptionConverterMixin):
2440
 
 
2441
 
    def get_option(self):
2442
 
        return config.Option('foo', help='An integer.',
2443
 
                             from_unicode=config.int_from_store)
2444
 
 
2445
 
    def test_convert_invalid(self):
2446
 
        opt = self.get_option()
2447
 
        # A string that is not recognized as an integer
2448
 
        self.assertConvertInvalid(opt, u'forty-two')
2449
 
        # A list of strings is never recognized as an integer
2450
 
        self.assertConvertInvalid(opt, [u'a', u'list'])
2451
 
 
2452
 
    def test_convert_valid(self):
2453
 
        opt = self.get_option()
2454
 
        self.assertConverted(16, opt, u'16')
2455
 
 
2456
 
 
2457
 
class TestOptionWithListConverter(tests.TestCase, TestOptionConverterMixin):
2458
 
 
2459
 
    def get_option(self):
2460
 
        return config.Option('foo', help='A list.',
2461
 
                             from_unicode=config.list_from_store)
 
2369
        self.assertEquals(expected, opt.convert_from_unicode(None, value))
 
2370
 
 
2371
    def assertWarns(self, opt, value):
 
2372
        warnings = []
 
2373
        def warning(*args):
 
2374
            warnings.append(args[0] % args[1:])
 
2375
        self.overrideAttr(trace, 'warning', warning)
 
2376
        self.assertEquals(None, opt.convert_from_unicode(None, value))
 
2377
        self.assertLength(1, warnings)
 
2378
        self.assertEquals(
 
2379
            'Value "%s" is not valid for "%s"' % (value, opt.name),
 
2380
            warnings[0])
 
2381
 
 
2382
    def assertErrors(self, opt, value):
 
2383
        self.assertRaises(errors.ConfigOptionValueError,
 
2384
                          opt.convert_from_unicode, None, value)
 
2385
 
 
2386
    def assertConvertInvalid(self, opt, invalid_value):
 
2387
        opt.invalid = None
 
2388
        self.assertEquals(None, opt.convert_from_unicode(None, invalid_value))
 
2389
        opt.invalid = 'warning'
 
2390
        self.assertWarns(opt, invalid_value)
 
2391
        opt.invalid = 'error'
 
2392
        self.assertErrors(opt, invalid_value)
 
2393
 
 
2394
 
 
2395
class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
 
2396
 
 
2397
    def get_option(self):
 
2398
        return config.Option('foo', help='A boolean.',
 
2399
                             from_unicode=config.bool_from_store)
 
2400
 
 
2401
    def test_convert_invalid(self):
 
2402
        opt = self.get_option()
 
2403
        # A string that is not recognized as a boolean
 
2404
        self.assertConvertInvalid(opt, u'invalid-boolean')
 
2405
        # A list of strings is never recognized as a boolean
 
2406
        self.assertConvertInvalid(opt, [u'not', u'a', u'boolean'])
 
2407
 
 
2408
    def test_convert_valid(self):
 
2409
        opt = self.get_option()
 
2410
        self.assertConverted(True, opt, u'True')
 
2411
        self.assertConverted(True, opt, u'1')
 
2412
        self.assertConverted(False, opt, u'False')
 
2413
 
 
2414
 
 
2415
class TestOptionWithIntegerConverter(tests.TestCase, TestOptionConverterMixin):
 
2416
 
 
2417
    def get_option(self):
 
2418
        return config.Option('foo', help='An integer.',
 
2419
                             from_unicode=config.int_from_store)
 
2420
 
 
2421
    def test_convert_invalid(self):
 
2422
        opt = self.get_option()
 
2423
        # A string that is not recognized as an integer
 
2424
        self.assertConvertInvalid(opt, u'forty-two')
 
2425
        # A list of strings is never recognized as an integer
 
2426
        self.assertConvertInvalid(opt, [u'a', u'list'])
 
2427
 
 
2428
    def test_convert_valid(self):
 
2429
        opt = self.get_option()
 
2430
        self.assertConverted(16, opt, u'16')
 
2431
 
 
2432
 
 
2433
class TestOptionWithSIUnitConverter(tests.TestCase, TestOptionConverterMixin):
 
2434
 
 
2435
    def get_option(self):
 
2436
        return config.Option('foo', help='An integer in SI units.',
 
2437
                             from_unicode=config.int_SI_from_store)
 
2438
 
 
2439
    def test_convert_invalid(self):
 
2440
        opt = self.get_option()
 
2441
        self.assertConvertInvalid(opt, u'not-a-unit')
 
2442
        self.assertConvertInvalid(opt, u'Gb') # Forgot the int
 
2443
        self.assertConvertInvalid(opt, u'1b') # Forgot the unit
 
2444
        self.assertConvertInvalid(opt, u'1GG')
 
2445
        self.assertConvertInvalid(opt, u'1Mbb')
 
2446
        self.assertConvertInvalid(opt, u'1MM')
 
2447
 
 
2448
    def test_convert_valid(self):
 
2449
        opt = self.get_option()
 
2450
        self.assertConverted(int(5e3), opt, u'5kb')
 
2451
        self.assertConverted(int(5e6), opt, u'5M')
 
2452
        self.assertConverted(int(5e6), opt, u'5MB')
 
2453
        self.assertConverted(int(5e9), opt, u'5g')
 
2454
        self.assertConverted(int(5e9), opt, u'5gB')
 
2455
        self.assertConverted(100, opt, u'100')
 
2456
 
 
2457
 
 
2458
class TestListOption(tests.TestCase, TestOptionConverterMixin):
 
2459
 
 
2460
    def get_option(self):
 
2461
        return config.ListOption('foo', help='A list.')
2462
2462
 
2463
2463
    def test_convert_invalid(self):
2464
2464
        opt = self.get_option()
2614
2614
    def setUp(self):
2615
2615
        super(TestCommandLineStore, self).setUp()
2616
2616
        self.store = config.CommandLineStore()
 
2617
        self.overrideAttr(config, 'option_registry', config.OptionRegistry())
2617
2618
 
2618
2619
    def get_section(self):
2619
2620
        """Get the unique section for the command line overrides."""
2634
2635
        self.assertEqual('b', section.get('a'))
2635
2636
 
2636
2637
    def test_list_override(self):
 
2638
        opt = config.ListOption('l')
 
2639
        config.option_registry.register(opt)
2637
2640
        self.store._from_cmdline(['l=1,2,3'])
2638
2641
        val = self.get_section().get('l')
2639
2642
        self.assertEqual('1,2,3', val)
2640
2643
        # Reminder: lists should be registered as such explicitely, otherwise
2641
2644
        # the conversion needs to be done afterwards.
2642
 
        self.assertEqual(['1', '2', '3'], config.list_from_store(val))
 
2645
        self.assertEqual(['1', '2', '3'],
 
2646
                         opt.convert_from_unicode(self.store, val))
2643
2647
 
2644
2648
    def test_multiple_overrides(self):
2645
2649
        self.store._from_cmdline(['a=b', 'x=y'])
2651
2655
        self.assertRaises(errors.BzrCommandError,
2652
2656
                          self.store._from_cmdline, ['a=b', 'c'])
2653
2657
 
 
2658
class TestStoreMinimalAPI(tests.TestCaseWithTransport):
 
2659
 
 
2660
    scenarios = [(key, {'get_store': builder}) for key, builder
 
2661
                 in config.test_store_builder_registry.iteritems()] + [
 
2662
        ('cmdline', {'get_store': lambda test: config.CommandLineStore()})]
 
2663
 
 
2664
    def test_id(self):
 
2665
        store = self.get_store(self)
 
2666
        if type(store) == config.TransportIniFileStore:
 
2667
            raise tests.TestNotApplicable(
 
2668
                "%s is not a concrete Store implementation"
 
2669
                " so it doesn't need an id" % (store.__class__.__name__,))
 
2670
        self.assertIsNot(None, store.id)
 
2671
 
2654
2672
 
2655
2673
class TestStore(tests.TestCaseWithTransport):
2656
2674
 
2699
2717
        self.assertRaises(AssertionError, store._load_from_string, 'bar=baz')
2700
2718
 
2701
2719
 
 
2720
class TestStoreQuoting(TestStore):
 
2721
 
 
2722
    scenarios = [(key, {'get_store': builder}) for key, builder
 
2723
                 in config.test_store_builder_registry.iteritems()]
 
2724
 
 
2725
    def setUp(self):
 
2726
        super(TestStoreQuoting, self).setUp()
 
2727
        self.store = self.get_store(self)
 
2728
        # We need a loaded store but any content will do
 
2729
        self.store._load_from_string('')
 
2730
 
 
2731
    def assertIdempotent(self, s):
 
2732
        """Assert that quoting an unquoted string is a no-op and vice-versa.
 
2733
 
 
2734
        What matters here is that option values, as they appear in a store, can
 
2735
        be safely round-tripped out of the store and back.
 
2736
 
 
2737
        :param s: A string, quoted if required.
 
2738
        """
 
2739
        self.assertEquals(s, self.store.quote(self.store.unquote(s)))
 
2740
        self.assertEquals(s, self.store.unquote(self.store.quote(s)))
 
2741
 
 
2742
    def test_empty_string(self):
 
2743
        if isinstance(self.store, config.IniFileStore):
 
2744
            # configobj._quote doesn't handle empty values
 
2745
            self.assertRaises(AssertionError,
 
2746
                              self.assertIdempotent, '')
 
2747
        else:
 
2748
            self.assertIdempotent('')
 
2749
        # But quoted empty strings are ok
 
2750
        self.assertIdempotent('""')
 
2751
 
 
2752
    def test_embedded_spaces(self):
 
2753
        self.assertIdempotent('" a b c "')
 
2754
 
 
2755
    def test_embedded_commas(self):
 
2756
        self.assertIdempotent('" a , b c "')
 
2757
 
 
2758
    def test_simple_comma(self):
 
2759
        if isinstance(self.store, config.IniFileStore):
 
2760
            # configobj requires that lists are special-cased
 
2761
           self.assertRaises(AssertionError,
 
2762
                             self.assertIdempotent, ',')
 
2763
        else:
 
2764
            self.assertIdempotent(',')
 
2765
        # When a single comma is required, quoting is also required
 
2766
        self.assertIdempotent('","')
 
2767
 
 
2768
    def test_list(self):
 
2769
        if isinstance(self.store, config.IniFileStore):
 
2770
            # configobj requires that lists are special-cased
 
2771
            self.assertRaises(AssertionError,
 
2772
                              self.assertIdempotent, 'a,b')
 
2773
        else:
 
2774
            self.assertIdempotent('a,b')
 
2775
 
 
2776
 
 
2777
class TestDictFromStore(tests.TestCase):
 
2778
 
 
2779
    def test_unquote_not_string(self):
 
2780
        conf = config.MemoryStack('x=2\n[a_section]\na=1\n')
 
2781
        value = conf.get('a_section')
 
2782
        # Urgh, despite 'conf' asking for the no-name section, we get the
 
2783
        # content of another section as a dict o_O
 
2784
        self.assertEquals({'a': '1'}, value)
 
2785
        unquoted = conf.store.unquote(value)
 
2786
        # Which cannot be unquoted but shouldn't crash either (the use cases
 
2787
        # are getting the value or displaying it. In the later case, '%s' will
 
2788
        # do).
 
2789
        self.assertEquals({'a': '1'}, unquoted)
 
2790
        self.assertEquals("{u'a': u'1'}", '%s' % (unquoted,))
 
2791
 
 
2792
 
2702
2793
class TestIniFileStoreContent(tests.TestCaseWithTransport):
2703
2794
    """Simulate loading a config store with content of various encodings.
2704
2795
 
2909
3000
        self.assertLength(1, calls)
2910
3001
        self.assertEquals((store,), calls[0])
2911
3002
 
 
3003
    def test_set_mark_dirty(self):
 
3004
        stack = config.MemoryStack('')
 
3005
        self.assertLength(0, stack.store.dirty_sections)
 
3006
        stack.set('foo', 'baz')
 
3007
        self.assertLength(1, stack.store.dirty_sections)
 
3008
        self.assertTrue(stack.store._need_saving())
 
3009
 
 
3010
    def test_remove_mark_dirty(self):
 
3011
        stack = config.MemoryStack('foo=bar')
 
3012
        self.assertLength(0, stack.store.dirty_sections)
 
3013
        stack.remove('foo')
 
3014
        self.assertLength(1, stack.store.dirty_sections)
 
3015
        self.assertTrue(stack.store._need_saving())
 
3016
 
 
3017
 
 
3018
class TestStoreSaveChanges(tests.TestCaseWithTransport):
 
3019
    """Tests that config changes are kept in memory and saved on-demand."""
 
3020
 
 
3021
    def setUp(self):
 
3022
        super(TestStoreSaveChanges, self).setUp()
 
3023
        self.transport = self.get_transport()
 
3024
        # Most of the tests involve two stores pointing to the same persistent
 
3025
        # storage to observe the effects of concurrent changes
 
3026
        self.st1 = config.TransportIniFileStore(self.transport, 'foo.conf')
 
3027
        self.st2 = config.TransportIniFileStore(self.transport, 'foo.conf')
 
3028
        self.warnings = []
 
3029
        def warning(*args):
 
3030
            self.warnings.append(args[0] % args[1:])
 
3031
        self.overrideAttr(trace, 'warning', warning)
 
3032
 
 
3033
    def has_store(self, store):
 
3034
        store_basename = urlutils.relative_url(self.transport.external_url(),
 
3035
                                               store.external_url())
 
3036
        return self.transport.has(store_basename)
 
3037
 
 
3038
    def get_stack(self, store):
 
3039
        # Any stack will do as long as it uses the right store, just a single
 
3040
        # no-name section is enough
 
3041
        return config.Stack([store.get_sections], store)
 
3042
 
 
3043
    def test_no_changes_no_save(self):
 
3044
        s = self.get_stack(self.st1)
 
3045
        s.store.save_changes()
 
3046
        self.assertEquals(False, self.has_store(self.st1))
 
3047
 
 
3048
    def test_unrelated_concurrent_update(self):
 
3049
        s1 = self.get_stack(self.st1)
 
3050
        s2 = self.get_stack(self.st2)
 
3051
        s1.set('foo', 'bar')
 
3052
        s2.set('baz', 'quux')
 
3053
        s1.store.save()
 
3054
        # Changes don't propagate magically
 
3055
        self.assertEquals(None, s1.get('baz'))
 
3056
        s2.store.save_changes()
 
3057
        self.assertEquals('quux', s2.get('baz'))
 
3058
        # Changes are acquired when saving
 
3059
        self.assertEquals('bar', s2.get('foo'))
 
3060
        # Since there is no overlap, no warnings are emitted
 
3061
        self.assertLength(0, self.warnings)
 
3062
 
 
3063
    def test_concurrent_update_modified(self):
 
3064
        s1 = self.get_stack(self.st1)
 
3065
        s2 = self.get_stack(self.st2)
 
3066
        s1.set('foo', 'bar')
 
3067
        s2.set('foo', 'baz')
 
3068
        s1.store.save()
 
3069
        # Last speaker wins
 
3070
        s2.store.save_changes()
 
3071
        self.assertEquals('baz', s2.get('foo'))
 
3072
        # But the user get a warning
 
3073
        self.assertLength(1, self.warnings)
 
3074
        warning = self.warnings[0]
 
3075
        self.assertStartsWith(warning, 'Option foo in section None')
 
3076
        self.assertEndsWith(warning, 'was changed from <CREATED> to bar.'
 
3077
                            ' The baz value will be saved.')
 
3078
 
 
3079
    def test_concurrent_deletion(self):
 
3080
        self.st1._load_from_string('foo=bar')
 
3081
        self.st1.save()
 
3082
        s1 = self.get_stack(self.st1)
 
3083
        s2 = self.get_stack(self.st2)
 
3084
        s1.remove('foo')
 
3085
        s2.remove('foo')
 
3086
        s1.store.save_changes()
 
3087
        # No warning yet
 
3088
        self.assertLength(0, self.warnings)
 
3089
        s2.store.save_changes()
 
3090
        # Now we get one
 
3091
        self.assertLength(1, self.warnings)
 
3092
        warning = self.warnings[0]
 
3093
        self.assertStartsWith(warning, 'Option foo in section None')
 
3094
        self.assertEndsWith(warning, 'was changed from bar to <CREATED>.'
 
3095
                            ' The <DELETED> value will be saved.')
 
3096
 
 
3097
 
 
3098
class TestQuotingIniFileStore(tests.TestCaseWithTransport):
 
3099
 
 
3100
    def get_store(self):
 
3101
        return config.TransportIniFileStore(self.get_transport(), 'foo.conf')
 
3102
 
 
3103
    def test_get_quoted_string(self):
 
3104
        store = self.get_store()
 
3105
        store._load_from_string('foo= " abc "')
 
3106
        stack = config.Stack([store.get_sections])
 
3107
        self.assertEquals(' abc ', stack.get('foo'))
 
3108
 
 
3109
    def test_set_quoted_string(self):
 
3110
        store = self.get_store()
 
3111
        stack = config.Stack([store.get_sections], store)
 
3112
        stack.set('foo', ' a b c ')
 
3113
        store.save()
 
3114
        self.assertFileEqual('foo = " a b c "' + os.linesep, 'foo.conf')
 
3115
 
2912
3116
 
2913
3117
class TestTransportIniFileStore(TestStore):
2914
3118
 
3259
3463
        self.assertLength(0, sections)
3260
3464
 
3261
3465
 
3262
 
class TestStackGet(tests.TestCase):
3263
 
 
3264
 
    # FIXME: This should be parametrized for all known Stack or dedicated
3265
 
    # paramerized tests created to avoid bloating -- vila 2011-03-31
3266
 
 
3267
 
    def overrideOptionRegistry(self):
 
3466
class TestBaseStackGet(tests.TestCase):
 
3467
 
 
3468
    def setUp(self):
 
3469
        super(TestBaseStackGet, self).setUp()
3268
3470
        self.overrideAttr(config, 'option_registry', config.OptionRegistry())
3269
3471
 
3270
 
    def test_single_config_get(self):
3271
 
        conf = dict(foo='bar')
3272
 
        conf_stack = config.Stack([conf])
3273
 
        self.assertEquals('bar', conf_stack.get('foo'))
 
3472
    def test_get_first_definition(self):
 
3473
        store1 = config.IniFileStore()
 
3474
        store1._load_from_string('foo=bar')
 
3475
        store2 = config.IniFileStore()
 
3476
        store2._load_from_string('foo=baz')
 
3477
        conf = config.Stack([store1.get_sections, store2.get_sections])
 
3478
        self.assertEquals('bar', conf.get('foo'))
3274
3479
 
3275
3480
    def test_get_with_registered_default_value(self):
3276
 
        conf_stack = config.Stack([dict()])
3277
 
        opt = config.Option('foo', default='bar')
3278
 
        self.overrideOptionRegistry()
3279
 
        config.option_registry.register('foo', opt)
 
3481
        config.option_registry.register(config.Option('foo', default='bar'))
 
3482
        conf_stack = config.Stack([])
3280
3483
        self.assertEquals('bar', conf_stack.get('foo'))
3281
3484
 
3282
3485
    def test_get_without_registered_default_value(self):
3283
 
        conf_stack = config.Stack([dict()])
3284
 
        opt = config.Option('foo')
3285
 
        self.overrideOptionRegistry()
3286
 
        config.option_registry.register('foo', opt)
 
3486
        config.option_registry.register(config.Option('foo'))
 
3487
        conf_stack = config.Stack([])
3287
3488
        self.assertEquals(None, conf_stack.get('foo'))
3288
3489
 
3289
3490
    def test_get_without_default_value_for_not_registered(self):
3290
 
        conf_stack = config.Stack([dict()])
3291
 
        opt = config.Option('foo')
3292
 
        self.overrideOptionRegistry()
 
3491
        conf_stack = config.Stack([])
3293
3492
        self.assertEquals(None, conf_stack.get('foo'))
3294
3493
 
3295
 
    def test_get_first_definition(self):
3296
 
        conf1 = dict(foo='bar')
3297
 
        conf2 = dict(foo='baz')
3298
 
        conf_stack = config.Stack([conf1, conf2])
3299
 
        self.assertEquals('bar', conf_stack.get('foo'))
3300
 
 
3301
 
    def test_get_embedded_definition(self):
3302
 
        conf1 = dict(yy='12')
3303
 
        conf2 = config.Stack([dict(xx='42'), dict(foo='baz')])
3304
 
        conf_stack = config.Stack([conf1, conf2])
3305
 
        self.assertEquals('baz', conf_stack.get('foo'))
3306
 
 
3307
3494
    def test_get_for_empty_section_callable(self):
3308
3495
        conf_stack = config.Stack([lambda : []])
3309
3496
        self.assertEquals(None, conf_stack.get('foo'))
3310
3497
 
3311
3498
    def test_get_for_broken_callable(self):
3312
3499
        # Trying to use and invalid callable raises an exception on first use
3313
 
        conf_stack = config.Stack([lambda : object()])
 
3500
        conf_stack = config.Stack([object])
3314
3501
        self.assertRaises(TypeError, conf_stack.get, 'foo')
3315
3502
 
3316
3503
 
 
3504
class TestStackWithSimpleStore(tests.TestCase):
 
3505
 
 
3506
    def setUp(self):
 
3507
        super(TestStackWithSimpleStore, self).setUp()
 
3508
        self.overrideAttr(config, 'option_registry', config.OptionRegistry())
 
3509
        self.registry = config.option_registry
 
3510
 
 
3511
    def get_conf(self, content=None):
 
3512
        return config.MemoryStack(content)
 
3513
 
 
3514
    def test_override_value_from_env(self):
 
3515
        self.registry.register(
 
3516
            config.Option('foo', default='bar', override_from_env=['FOO']))
 
3517
        self.overrideEnv('FOO', 'quux')
 
3518
        # Env variable provides a default taking over the option one
 
3519
        conf = self.get_conf('foo=store')
 
3520
        self.assertEquals('quux', conf.get('foo'))
 
3521
 
 
3522
    def test_first_override_value_from_env_wins(self):
 
3523
        self.registry.register(
 
3524
            config.Option('foo', default='bar',
 
3525
                          override_from_env=['NO_VALUE', 'FOO', 'BAZ']))
 
3526
        self.overrideEnv('FOO', 'foo')
 
3527
        self.overrideEnv('BAZ', 'baz')
 
3528
        # The first env var set wins
 
3529
        conf = self.get_conf('foo=store')
 
3530
        self.assertEquals('foo', conf.get('foo'))
 
3531
 
 
3532
 
 
3533
class TestMemoryStack(tests.TestCase):
 
3534
 
 
3535
    def test_get(self):
 
3536
        conf = config.MemoryStack('foo=bar')
 
3537
        self.assertEquals('bar', conf.get('foo'))
 
3538
 
 
3539
    def test_set(self):
 
3540
        conf = config.MemoryStack('foo=bar')
 
3541
        conf.set('foo', 'baz')
 
3542
        self.assertEquals('baz', conf.get('foo'))
 
3543
 
 
3544
    def test_no_content(self):
 
3545
        conf = config.MemoryStack()
 
3546
        # No content means no loading
 
3547
        self.assertFalse(conf.store.is_loaded())
 
3548
        self.assertRaises(NotImplementedError, conf.get, 'foo')
 
3549
        # But a content can still be provided
 
3550
        conf.store._load_from_string('foo=bar')
 
3551
        self.assertEquals('bar', conf.get('foo'))
 
3552
 
 
3553
 
3317
3554
class TestStackWithTransport(tests.TestCaseWithTransport):
3318
3555
 
3319
3556
    scenarios = [(key, {'get_stack': builder}) for key, builder
3349
3586
        self.assertEquals((self.conf, 'foo', 'bar'), calls[0])
3350
3587
 
3351
3588
 
3352
 
class TestStackGetWithConverter(tests.TestCaseWithTransport):
 
3589
class TestStackGetWithConverter(tests.TestCase):
3353
3590
 
3354
3591
    def setUp(self):
3355
3592
        super(TestStackGetWithConverter, self).setUp()
3356
3593
        self.overrideAttr(config, 'option_registry', config.OptionRegistry())
3357
3594
        self.registry = config.option_registry
3358
 
        # We just want a simple stack with a simple store so we can inject
3359
 
        # whatever content the tests need without caring about what section
3360
 
        # names are valid for a given store/stack.
3361
 
        store = config.TransportIniFileStore(self.get_transport(), 'foo.conf')
3362
 
        self.conf = config.Stack([store.get_sections], store)
 
3595
 
 
3596
    def get_conf(self, content=None):
 
3597
        return config.MemoryStack(content)
3363
3598
 
3364
3599
    def register_bool_option(self, name, default=None, default_from_env=None):
3365
3600
        b = config.Option(name, help='A boolean.',
3369
3604
 
3370
3605
    def test_get_default_bool_None(self):
3371
3606
        self.register_bool_option('foo')
3372
 
        self.assertEquals(None, self.conf.get('foo'))
 
3607
        conf = self.get_conf('')
 
3608
        self.assertEquals(None, conf.get('foo'))
3373
3609
 
3374
3610
    def test_get_default_bool_True(self):
3375
3611
        self.register_bool_option('foo', u'True')
3376
 
        self.assertEquals(True, self.conf.get('foo'))
 
3612
        conf = self.get_conf('')
 
3613
        self.assertEquals(True, conf.get('foo'))
3377
3614
 
3378
3615
    def test_get_default_bool_False(self):
3379
3616
        self.register_bool_option('foo', False)
3380
 
        self.assertEquals(False, self.conf.get('foo'))
 
3617
        conf = self.get_conf('')
 
3618
        self.assertEquals(False, conf.get('foo'))
3381
3619
 
3382
3620
    def test_get_default_bool_False_as_string(self):
3383
3621
        self.register_bool_option('foo', u'False')
3384
 
        self.assertEquals(False, self.conf.get('foo'))
 
3622
        conf = self.get_conf('')
 
3623
        self.assertEquals(False, conf.get('foo'))
3385
3624
 
3386
3625
    def test_get_default_bool_from_env_converted(self):
3387
3626
        self.register_bool_option('foo', u'True', default_from_env=['FOO'])
3388
3627
        self.overrideEnv('FOO', 'False')
3389
 
        self.assertEquals(False, self.conf.get('foo'))
 
3628
        conf = self.get_conf('')
 
3629
        self.assertEquals(False, conf.get('foo'))
3390
3630
 
3391
3631
    def test_get_default_bool_when_conversion_fails(self):
3392
3632
        self.register_bool_option('foo', default='True')
3393
 
        self.conf.store._load_from_string('foo=invalid boolean')
3394
 
        self.assertEquals(True, self.conf.get('foo'))
 
3633
        conf = self.get_conf('foo=invalid boolean')
 
3634
        self.assertEquals(True, conf.get('foo'))
3395
3635
 
3396
3636
    def register_integer_option(self, name,
3397
3637
                                default=None, default_from_env=None):
3402
3642
 
3403
3643
    def test_get_default_integer_None(self):
3404
3644
        self.register_integer_option('foo')
3405
 
        self.assertEquals(None, self.conf.get('foo'))
 
3645
        conf = self.get_conf('')
 
3646
        self.assertEquals(None, conf.get('foo'))
3406
3647
 
3407
3648
    def test_get_default_integer(self):
3408
3649
        self.register_integer_option('foo', 42)
3409
 
        self.assertEquals(42, self.conf.get('foo'))
 
3650
        conf = self.get_conf('')
 
3651
        self.assertEquals(42, conf.get('foo'))
3410
3652
 
3411
3653
    def test_get_default_integer_as_string(self):
3412
3654
        self.register_integer_option('foo', u'42')
3413
 
        self.assertEquals(42, self.conf.get('foo'))
 
3655
        conf = self.get_conf('')
 
3656
        self.assertEquals(42, conf.get('foo'))
3414
3657
 
3415
3658
    def test_get_default_integer_from_env(self):
3416
3659
        self.register_integer_option('foo', default_from_env=['FOO'])
3417
3660
        self.overrideEnv('FOO', '18')
3418
 
        self.assertEquals(18, self.conf.get('foo'))
 
3661
        conf = self.get_conf('')
 
3662
        self.assertEquals(18, conf.get('foo'))
3419
3663
 
3420
3664
    def test_get_default_integer_when_conversion_fails(self):
3421
3665
        self.register_integer_option('foo', default='12')
3422
 
        self.conf.store._load_from_string('foo=invalid integer')
3423
 
        self.assertEquals(12, self.conf.get('foo'))
 
3666
        conf = self.get_conf('foo=invalid integer')
 
3667
        self.assertEquals(12, conf.get('foo'))
3424
3668
 
3425
3669
    def register_list_option(self, name, default=None, default_from_env=None):
3426
 
        l = config.Option(name, help='A list.',
3427
 
                          default=default, default_from_env=default_from_env,
3428
 
                          from_unicode=config.list_from_store)
 
3670
        l = config.ListOption(name, help='A list.', default=default,
 
3671
                              default_from_env=default_from_env)
3429
3672
        self.registry.register(l)
3430
3673
 
3431
3674
    def test_get_default_list_None(self):
3432
3675
        self.register_list_option('foo')
3433
 
        self.assertEquals(None, self.conf.get('foo'))
 
3676
        conf = self.get_conf('')
 
3677
        self.assertEquals(None, conf.get('foo'))
3434
3678
 
3435
3679
    def test_get_default_list_empty(self):
3436
3680
        self.register_list_option('foo', '')
3437
 
        self.assertEquals([], self.conf.get('foo'))
 
3681
        conf = self.get_conf('')
 
3682
        self.assertEquals([], conf.get('foo'))
3438
3683
 
3439
3684
    def test_get_default_list_from_env(self):
3440
3685
        self.register_list_option('foo', default_from_env=['FOO'])
3441
3686
        self.overrideEnv('FOO', '')
3442
 
        self.assertEquals([], self.conf.get('foo'))
 
3687
        conf = self.get_conf('')
 
3688
        self.assertEquals([], conf.get('foo'))
3443
3689
 
3444
3690
    def test_get_with_list_converter_no_item(self):
3445
3691
        self.register_list_option('foo', None)
3446
 
        self.conf.store._load_from_string('foo=,')
3447
 
        self.assertEquals([], self.conf.get('foo'))
 
3692
        conf = self.get_conf('foo=,')
 
3693
        self.assertEquals([], conf.get('foo'))
3448
3694
 
3449
3695
    def test_get_with_list_converter_many_items(self):
3450
3696
        self.register_list_option('foo', None)
3451
 
        self.conf.store._load_from_string('foo=m,o,r,e')
3452
 
        self.assertEquals(['m', 'o', 'r', 'e'], self.conf.get('foo'))
 
3697
        conf = self.get_conf('foo=m,o,r,e')
 
3698
        self.assertEquals(['m', 'o', 'r', 'e'], conf.get('foo'))
3453
3699
 
3454
3700
    def test_get_with_list_converter_embedded_spaces_many_items(self):
3455
3701
        self.register_list_option('foo', None)
3456
 
        self.conf.store._load_from_string('foo=" bar", "baz "')
3457
 
        self.assertEquals([' bar', 'baz '], self.conf.get('foo'))
 
3702
        conf = self.get_conf('foo=" bar", "baz "')
 
3703
        self.assertEquals([' bar', 'baz '], conf.get('foo'))
3458
3704
 
3459
3705
    def test_get_with_list_converter_stripped_spaces_many_items(self):
3460
3706
        self.register_list_option('foo', None)
3461
 
        self.conf.store._load_from_string('foo= bar ,  baz ')
3462
 
        self.assertEquals(['bar', 'baz'], self.conf.get('foo'))
 
3707
        conf = self.get_conf('foo= bar ,  baz ')
 
3708
        self.assertEquals(['bar', 'baz'], conf.get('foo'))
3463
3709
 
3464
3710
 
3465
3711
class TestIterOptionRefs(tests.TestCase):
3578
3824
list={foo},{bar},{baz}
3579
3825
''')
3580
3826
        self.registry.register(
3581
 
            config.Option('list', from_unicode=config.list_from_store))
 
3827
            config.ListOption('list'))
3582
3828
        self.assertEquals(['start', 'middle', 'end'],
3583
3829
                           self.conf.get('list', expand=True))
3584
3830
 
3590
3836
list={foo}
3591
3837
''')
3592
3838
        self.registry.register(
3593
 
            config.Option('list', from_unicode=config.list_from_store))
 
3839
            config.ListOption('list'))
3594
3840
        self.assertEquals(['start', 'middle', 'end'],
3595
3841
                           self.conf.get('list', expand=True))
3596
3842
 
3605
3851
''')
3606
3852
        # What matters is what the registration says, the conversion happens
3607
3853
        # only after all expansions have been performed
3608
 
        self.registry.register(
3609
 
            config.Option('hidden', from_unicode=config.list_from_store))
 
3854
        self.registry.register(config.ListOption('hidden'))
3610
3855
        self.assertEquals(['bin', 'go'],
3611
3856
                          self.conf.get('hidden', expand=True))
3612
3857
 
4477
4722
 
4478
4723
    def test_auto_user_id(self):
4479
4724
        """Automatic inference of user name.
4480
 
        
 
4725
 
4481
4726
        This is a bit hard to test in an isolated way, because it depends on
4482
4727
        system functions that go direct to /etc or perhaps somewhere else.
4483
4728
        But it's reasonable to say that on Unix, with an /etc/mailname, we ought
4493
4738
        else:
4494
4739
            self.assertEquals((None, None), (realname, address))
4495
4740
 
 
4741
 
 
4742
class EmailOptionTests(tests.TestCase):
 
4743
 
 
4744
    def test_default_email_uses_BZR_EMAIL(self):
 
4745
        conf = config.MemoryStack('email=jelmer@debian.org')
 
4746
        # BZR_EMAIL takes precedence over EMAIL
 
4747
        self.overrideEnv('BZR_EMAIL', 'jelmer@samba.org')
 
4748
        self.overrideEnv('EMAIL', 'jelmer@apache.org')
 
4749
        self.assertEquals('jelmer@samba.org', conf.get('email'))
 
4750
 
 
4751
    def test_default_email_uses_EMAIL(self):
 
4752
        conf = config.MemoryStack('')
 
4753
        self.overrideEnv('BZR_EMAIL', None)
 
4754
        self.overrideEnv('EMAIL', 'jelmer@apache.org')
 
4755
        self.assertEquals('jelmer@apache.org', conf.get('email'))
 
4756
 
 
4757
    def test_BZR_EMAIL_overrides(self):
 
4758
        conf = config.MemoryStack('email=jelmer@debian.org')
 
4759
        self.overrideEnv('BZR_EMAIL', 'jelmer@apache.org')
 
4760
        self.assertEquals('jelmer@apache.org', conf.get('email'))
 
4761
        self.overrideEnv('BZR_EMAIL', None)
 
4762
        self.overrideEnv('EMAIL', 'jelmer@samba.org')
 
4763
        self.assertEquals('jelmer@debian.org', conf.get('email'))