2028
1906
self.assertIs(None, bzrdir_config.get_default_stack_on())
2031
class TestOldConfigHooks(tests.TestCaseWithTransport):
2034
super(TestOldConfigHooks, self).setUp()
2035
create_configs_with_file_option(self)
2037
def assertGetHook(self, conf, name, value):
2041
config.OldConfigHooks.install_named_hook('get', hook, None)
2043
config.OldConfigHooks.uninstall_named_hook, 'get', None)
2044
self.assertLength(0, calls)
2045
actual_value = conf.get_user_option(name)
2046
self.assertEquals(value, actual_value)
2047
self.assertLength(1, calls)
2048
self.assertEquals((conf, name, value), calls[0])
2050
def test_get_hook_bazaar(self):
2051
self.assertGetHook(self.bazaar_config, 'file', 'bazaar')
2053
def test_get_hook_locations(self):
2054
self.assertGetHook(self.locations_config, 'file', 'locations')
2056
def test_get_hook_branch(self):
2057
# Since locations masks branch, we define a different option
2058
self.branch_config.set_user_option('file2', 'branch')
2059
self.assertGetHook(self.branch_config, 'file2', 'branch')
2061
def assertSetHook(self, conf, name, value):
2065
config.OldConfigHooks.install_named_hook('set', hook, None)
2067
config.OldConfigHooks.uninstall_named_hook, 'set', None)
2068
self.assertLength(0, calls)
2069
conf.set_user_option(name, value)
2070
self.assertLength(1, calls)
2071
# We can't assert the conf object below as different configs use
2072
# different means to implement set_user_option and we care only about
2074
self.assertEquals((name, value), calls[0][1:])
2076
def test_set_hook_bazaar(self):
2077
self.assertSetHook(self.bazaar_config, 'foo', 'bazaar')
2079
def test_set_hook_locations(self):
2080
self.assertSetHook(self.locations_config, 'foo', 'locations')
2082
def test_set_hook_branch(self):
2083
self.assertSetHook(self.branch_config, 'foo', 'branch')
2085
def assertRemoveHook(self, conf, name, section_name=None):
2089
config.OldConfigHooks.install_named_hook('remove', hook, None)
2091
config.OldConfigHooks.uninstall_named_hook, 'remove', None)
2092
self.assertLength(0, calls)
2093
conf.remove_user_option(name, section_name)
2094
self.assertLength(1, calls)
2095
# We can't assert the conf object below as different configs use
2096
# different means to implement remove_user_option and we care only about
2098
self.assertEquals((name,), calls[0][1:])
2100
def test_remove_hook_bazaar(self):
2101
self.assertRemoveHook(self.bazaar_config, 'file')
2103
def test_remove_hook_locations(self):
2104
self.assertRemoveHook(self.locations_config, 'file',
2105
self.locations_config.location)
2107
def test_remove_hook_branch(self):
2108
self.assertRemoveHook(self.branch_config, 'file')
2110
def assertLoadHook(self, name, conf_class, *conf_args):
2114
config.OldConfigHooks.install_named_hook('load', hook, None)
2116
config.OldConfigHooks.uninstall_named_hook, 'load', None)
2117
self.assertLength(0, calls)
2119
conf = conf_class(*conf_args)
2120
# Access an option to trigger a load
2121
conf.get_user_option(name)
2122
self.assertLength(1, calls)
2123
# Since we can't assert about conf, we just use the number of calls ;-/
2125
def test_load_hook_bazaar(self):
2126
self.assertLoadHook('file', config.GlobalConfig)
2128
def test_load_hook_locations(self):
2129
self.assertLoadHook('file', config.LocationConfig, self.tree.basedir)
2131
def test_load_hook_branch(self):
2132
self.assertLoadHook('file', config.BranchConfig, self.tree.branch)
2134
def assertSaveHook(self, conf):
2138
config.OldConfigHooks.install_named_hook('save', hook, None)
2140
config.OldConfigHooks.uninstall_named_hook, 'save', None)
2141
self.assertLength(0, calls)
2142
# Setting an option triggers a save
2143
conf.set_user_option('foo', 'bar')
2144
self.assertLength(1, calls)
2145
# Since we can't assert about conf, we just use the number of calls ;-/
2147
def test_save_hook_bazaar(self):
2148
self.assertSaveHook(self.bazaar_config)
2150
def test_save_hook_locations(self):
2151
self.assertSaveHook(self.locations_config)
2153
def test_save_hook_branch(self):
2154
self.assertSaveHook(self.branch_config)
2157
class TestOldConfigHooksForRemote(tests.TestCaseWithTransport):
2158
"""Tests config hooks for remote configs.
2160
No tests for the remove hook as this is not implemented there.
2164
super(TestOldConfigHooksForRemote, self).setUp()
2165
self.transport_server = test_server.SmartTCPServer_for_testing
2166
create_configs_with_file_option(self)
2168
def assertGetHook(self, conf, name, value):
2172
config.OldConfigHooks.install_named_hook('get', hook, None)
2174
config.OldConfigHooks.uninstall_named_hook, 'get', None)
2175
self.assertLength(0, calls)
2176
actual_value = conf.get_option(name)
2177
self.assertEquals(value, actual_value)
2178
self.assertLength(1, calls)
2179
self.assertEquals((conf, name, value), calls[0])
2181
def test_get_hook_remote_branch(self):
2182
remote_branch = branch.Branch.open(self.get_url('tree'))
2183
self.assertGetHook(remote_branch._get_config(), 'file', 'branch')
2185
def test_get_hook_remote_bzrdir(self):
2186
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2187
conf = remote_bzrdir._get_config()
2188
conf.set_option('remotedir', 'file')
2189
self.assertGetHook(conf, 'file', 'remotedir')
2191
def assertSetHook(self, conf, name, value):
2195
config.OldConfigHooks.install_named_hook('set', hook, None)
2197
config.OldConfigHooks.uninstall_named_hook, 'set', None)
2198
self.assertLength(0, calls)
2199
conf.set_option(value, name)
2200
self.assertLength(1, calls)
2201
# We can't assert the conf object below as different configs use
2202
# different means to implement set_user_option and we care only about
2204
self.assertEquals((name, value), calls[0][1:])
2206
def test_set_hook_remote_branch(self):
2207
remote_branch = branch.Branch.open(self.get_url('tree'))
2208
self.addCleanup(remote_branch.lock_write().unlock)
2209
self.assertSetHook(remote_branch._get_config(), 'file', 'remote')
2211
def test_set_hook_remote_bzrdir(self):
2212
remote_branch = branch.Branch.open(self.get_url('tree'))
2213
self.addCleanup(remote_branch.lock_write().unlock)
2214
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2215
self.assertSetHook(remote_bzrdir._get_config(), 'file', 'remotedir')
2217
def assertLoadHook(self, expected_nb_calls, name, conf_class, *conf_args):
2221
config.OldConfigHooks.install_named_hook('load', hook, None)
2223
config.OldConfigHooks.uninstall_named_hook, 'load', None)
2224
self.assertLength(0, calls)
2226
conf = conf_class(*conf_args)
2227
# Access an option to trigger a load
2228
conf.get_option(name)
2229
self.assertLength(expected_nb_calls, calls)
2230
# Since we can't assert about conf, we just use the number of calls ;-/
2232
def test_load_hook_remote_branch(self):
2233
remote_branch = branch.Branch.open(self.get_url('tree'))
2234
self.assertLoadHook(1, 'file', remote.RemoteBranchConfig, remote_branch)
2236
def test_load_hook_remote_bzrdir(self):
2237
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2238
# The config file doesn't exist, set an option to force its creation
2239
conf = remote_bzrdir._get_config()
2240
conf.set_option('remotedir', 'file')
2241
# We get one call for the server and one call for the client, this is
2242
# caused by the differences in implementations betwen
2243
# SmartServerBzrDirRequestConfigFile (in smart/bzrdir.py) and
2244
# SmartServerBranchGetConfigFile (in smart/branch.py)
2245
self.assertLoadHook(2 ,'file', remote.RemoteBzrDirConfig, remote_bzrdir)
2247
def assertSaveHook(self, conf):
2251
config.OldConfigHooks.install_named_hook('save', hook, None)
2253
config.OldConfigHooks.uninstall_named_hook, 'save', None)
2254
self.assertLength(0, calls)
2255
# Setting an option triggers a save
2256
conf.set_option('foo', 'bar')
2257
self.assertLength(1, calls)
2258
# Since we can't assert about conf, we just use the number of calls ;-/
2260
def test_save_hook_remote_branch(self):
2261
remote_branch = branch.Branch.open(self.get_url('tree'))
2262
self.addCleanup(remote_branch.lock_write().unlock)
2263
self.assertSaveHook(remote_branch._get_config())
2265
def test_save_hook_remote_bzrdir(self):
2266
remote_branch = branch.Branch.open(self.get_url('tree'))
2267
self.addCleanup(remote_branch.lock_write().unlock)
2268
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2269
self.assertSaveHook(remote_bzrdir._get_config())
2272
1909
class TestOption(tests.TestCase):
2274
1911
def test_default_value(self):
2275
1912
opt = config.Option('foo', default='bar')
2276
1913
self.assertEquals('bar', opt.get_default())
2278
def test_default_value_from_env(self):
2279
opt = config.Option('foo', default='bar', default_from_env=['FOO'])
2280
self.overrideEnv('FOO', 'quux')
2281
# Env variable provides a default taking over the option one
2282
self.assertEquals('quux', opt.get_default())
2284
def test_first_default_value_from_env_wins(self):
2285
opt = config.Option('foo', default='bar',
2286
default_from_env=['NO_VALUE', 'FOO', 'BAZ'])
2287
self.overrideEnv('FOO', 'foo')
2288
self.overrideEnv('BAZ', 'baz')
2289
# The first env var set wins
2290
self.assertEquals('foo', opt.get_default())
2292
def test_not_supported_list_default_value(self):
2293
self.assertRaises(AssertionError, config.Option, 'foo', default=[1])
2295
def test_not_supported_object_default_value(self):
2296
self.assertRaises(AssertionError, config.Option, 'foo',
2300
class TestOptionConverterMixin(object):
2302
def assertConverted(self, expected, opt, value):
2303
self.assertEquals(expected, opt.convert_from_unicode(value))
2305
def assertWarns(self, opt, value):
2308
warnings.append(args[0] % args[1:])
2309
self.overrideAttr(trace, 'warning', warning)
2310
self.assertEquals(None, opt.convert_from_unicode(value))
2311
self.assertLength(1, warnings)
2313
'Value "%s" is not valid for "%s"' % (value, opt.name),
2316
def assertErrors(self, opt, value):
2317
self.assertRaises(errors.ConfigOptionValueError,
2318
opt.convert_from_unicode, value)
2320
def assertConvertInvalid(self, opt, invalid_value):
2322
self.assertEquals(None, opt.convert_from_unicode(invalid_value))
2323
opt.invalid = 'warning'
2324
self.assertWarns(opt, invalid_value)
2325
opt.invalid = 'error'
2326
self.assertErrors(opt, invalid_value)
2329
class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
2331
def get_option(self):
2332
return config.Option('foo', help='A boolean.',
2333
from_unicode=config.bool_from_store)
2335
def test_convert_invalid(self):
2336
opt = self.get_option()
2337
# A string that is not recognized as a boolean
2338
self.assertConvertInvalid(opt, u'invalid-boolean')
2339
# A list of strings is never recognized as a boolean
2340
self.assertConvertInvalid(opt, [u'not', u'a', u'boolean'])
2342
def test_convert_valid(self):
2343
opt = self.get_option()
2344
self.assertConverted(True, opt, u'True')
2345
self.assertConverted(True, opt, u'1')
2346
self.assertConverted(False, opt, u'False')
2349
class TestOptionWithIntegerConverter(tests.TestCase, TestOptionConverterMixin):
2351
def get_option(self):
2352
return config.Option('foo', help='An integer.',
2353
from_unicode=config.int_from_store)
2355
def test_convert_invalid(self):
2356
opt = self.get_option()
2357
# A string that is not recognized as an integer
2358
self.assertConvertInvalid(opt, u'forty-two')
2359
# A list of strings is never recognized as an integer
2360
self.assertConvertInvalid(opt, [u'a', u'list'])
2362
def test_convert_valid(self):
2363
opt = self.get_option()
2364
self.assertConverted(16, opt, u'16')
2366
class TestOptionWithListConverter(tests.TestCase, TestOptionConverterMixin):
2368
def get_option(self):
2369
return config.Option('foo', help='A list.',
2370
from_unicode=config.list_from_store)
2372
def test_convert_invalid(self):
2373
# No string is invalid as all forms can be converted to a list
2376
def test_convert_valid(self):
2377
opt = self.get_option()
2378
# An empty string is an empty list
2379
self.assertConverted([], opt, '') # Using a bare str() just in case
2380
self.assertConverted([], opt, u'')
2382
self.assertConverted([u'True'], opt, u'True')
2384
self.assertConverted([u'42'], opt, u'42')
2386
self.assertConverted([u'bar'], opt, u'bar')
2387
# A list remains a list (configObj will turn a string containing commas
2388
# into a list, but that's not what we're testing here)
2389
self.assertConverted([u'foo', u'1', u'True'],
2390
opt, [u'foo', u'1', u'True'])
2393
class TestOptionConverterMixin(object):
2395
def assertConverted(self, expected, opt, value):
2396
self.assertEquals(expected, opt.convert_from_unicode(value))
2398
def assertWarns(self, opt, value):
2401
warnings.append(args[0] % args[1:])
2402
self.overrideAttr(trace, 'warning', warning)
2403
self.assertEquals(None, opt.convert_from_unicode(value))
2404
self.assertLength(1, warnings)
2406
'Value "%s" is not valid for "%s"' % (value, opt.name),
2409
def assertErrors(self, opt, value):
2410
self.assertRaises(errors.ConfigOptionValueError,
2411
opt.convert_from_unicode, value)
2413
def assertConvertInvalid(self, opt, invalid_value):
2415
self.assertEquals(None, opt.convert_from_unicode(invalid_value))
2416
opt.invalid = 'warning'
2417
self.assertWarns(opt, invalid_value)
2418
opt.invalid = 'error'
2419
self.assertErrors(opt, invalid_value)
2422
class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
2424
def get_option(self):
2425
return config.Option('foo', help='A boolean.',
2426
from_unicode=config.bool_from_store)
2428
def test_convert_invalid(self):
2429
opt = self.get_option()
2430
# A string that is not recognized as a boolean
2431
self.assertConvertInvalid(opt, u'invalid-boolean')
2432
# A list of strings is never recognized as a boolean
2433
self.assertConvertInvalid(opt, [u'not', u'a', u'boolean'])
2435
def test_convert_valid(self):
2436
opt = self.get_option()
2437
self.assertConverted(True, opt, u'True')
2438
self.assertConverted(True, opt, u'1')
2439
self.assertConverted(False, opt, u'False')
2442
class TestOptionWithIntegerConverter(tests.TestCase, TestOptionConverterMixin):
2444
def get_option(self):
2445
return config.Option('foo', help='An integer.',
2446
from_unicode=config.int_from_store)
2448
def test_convert_invalid(self):
2449
opt = self.get_option()
2450
# A string that is not recognized as an integer
2451
self.assertConvertInvalid(opt, u'forty-two')
2452
# A list of strings is never recognized as an integer
2453
self.assertConvertInvalid(opt, [u'a', u'list'])
2455
def test_convert_valid(self):
2456
opt = self.get_option()
2457
self.assertConverted(16, opt, u'16')
2460
class TestOptionWithListConverter(tests.TestCase, TestOptionConverterMixin):
2462
def get_option(self):
2463
return config.Option('foo', help='A list.',
2464
from_unicode=config.list_from_store)
2466
def test_convert_invalid(self):
2467
opt = self.get_option()
2468
# We don't even try to convert a list into a list, we only expect
2470
self.assertConvertInvalid(opt, [1])
2471
# No string is invalid as all forms can be converted to a list
2473
def test_convert_valid(self):
2474
opt = self.get_option()
2475
# An empty string is an empty list
2476
self.assertConverted([], opt, '') # Using a bare str() just in case
2477
self.assertConverted([], opt, u'')
2479
self.assertConverted([u'True'], opt, u'True')
2481
self.assertConverted([u'42'], opt, u'42')
2483
self.assertConverted([u'bar'], opt, u'bar')
2486
1916
class TestOptionRegistry(tests.TestCase):
2488
1918
def setUp(self):
2489
1919
super(TestOptionRegistry, self).setUp()
2490
1920
# Always start with an empty registry
2491
self.overrideAttr(config, 'option_registry', config.OptionRegistry())
1921
self.overrideAttr(config, 'option_registry', registry.Registry())
2492
1922
self.registry = config.option_registry
2494
1924
def test_register(self):
2495
1925
opt = config.Option('foo')
2496
self.registry.register(opt)
1926
self.registry.register('foo', opt)
2497
1927
self.assertIs(opt, self.registry.get('foo'))
1929
lazy_option = config.Option('lazy_foo')
1931
def test_register_lazy(self):
1932
self.registry.register_lazy('foo', self.__module__,
1933
'TestOptionRegistry.lazy_option')
1934
self.assertIs(self.lazy_option, self.registry.get('foo'))
2499
1936
def test_registered_help(self):
2500
opt = config.Option('foo', help='A simple option')
2501
self.registry.register(opt)
1937
opt = config.Option('foo')
1938
self.registry.register('foo', opt, help='A simple option')
2502
1939
self.assertEquals('A simple option', self.registry.get_help('foo'))
2504
lazy_option = config.Option('lazy_foo', help='Lazy help')
2506
def test_register_lazy(self):
2507
self.registry.register_lazy('lazy_foo', self.__module__,
2508
'TestOptionRegistry.lazy_option')
2509
self.assertIs(self.lazy_option, self.registry.get('lazy_foo'))
2511
def test_registered_lazy_help(self):
2512
self.registry.register_lazy('lazy_foo', self.__module__,
2513
'TestOptionRegistry.lazy_option')
2514
self.assertEquals('Lazy help', self.registry.get_help('lazy_foo'))
2517
1942
class TestRegisteredOptions(tests.TestCase):
2518
1943
"""All registered options should verify some constraints."""
3323
2521
stack = self.get_stack(self)
3326
class TestStackGet(TestStackWithTransport):
3329
super(TestStackGet, self).setUp()
3330
self.conf = self.get_stack(self)
3332
def test_get_for_empty_stack(self):
3333
self.assertEquals(None, self.conf.get('foo'))
3335
def test_get_hook(self):
3336
self.conf.store._load_from_string('foo=bar')
3340
config.ConfigHooks.install_named_hook('get', hook, None)
3341
self.assertLength(0, calls)
3342
value = self.conf.get('foo')
3343
self.assertEquals('bar', value)
3344
self.assertLength(1, calls)
3345
self.assertEquals((self.conf, 'foo', 'bar'), calls[0])
3348
class TestStackGetWithConverter(TestStackGet):
3351
super(TestStackGetWithConverter, self).setUp()
3352
self.overrideAttr(config, 'option_registry', config.OptionRegistry())
3353
self.registry = config.option_registry
3355
def register_bool_option(self, name, default=None, default_from_env=None):
3356
b = config.Option(name, help='A boolean.',
3357
default=default, default_from_env=default_from_env,
3358
from_unicode=config.bool_from_store)
3359
self.registry.register(b)
3361
def test_get_default_bool_None(self):
3362
self.register_bool_option('foo')
3363
self.assertEquals(None, self.conf.get('foo'))
3365
def test_get_default_bool_True(self):
3366
self.register_bool_option('foo', u'True')
3367
self.assertEquals(True, self.conf.get('foo'))
3369
def test_get_default_bool_False(self):
3370
self.register_bool_option('foo', False)
3371
self.assertEquals(False, self.conf.get('foo'))
3373
def test_get_default_bool_False_as_string(self):
3374
self.register_bool_option('foo', u'False')
3375
self.assertEquals(False, self.conf.get('foo'))
3377
def test_get_default_bool_from_env_converted(self):
3378
self.register_bool_option('foo', u'True', default_from_env=['FOO'])
3379
self.overrideEnv('FOO', 'False')
3380
self.assertEquals(False, self.conf.get('foo'))
3382
def test_get_default_bool_when_conversion_fails(self):
3383
self.register_bool_option('foo', default='True')
3384
self.conf.store._load_from_string('foo=invalid boolean')
3385
self.assertEquals(True, self.conf.get('foo'))
3387
def register_integer_option(self, name,
3388
default=None, default_from_env=None):
3389
i = config.Option(name, help='An integer.',
3390
default=default, default_from_env=default_from_env,
3391
from_unicode=config.int_from_store)
3392
self.registry.register(i)
3394
def test_get_default_integer_None(self):
3395
self.register_integer_option('foo')
3396
self.assertEquals(None, self.conf.get('foo'))
3398
def test_get_default_integer(self):
3399
self.register_integer_option('foo', 42)
3400
self.assertEquals(42, self.conf.get('foo'))
3402
def test_get_default_integer_as_string(self):
3403
self.register_integer_option('foo', u'42')
3404
self.assertEquals(42, self.conf.get('foo'))
3406
def test_get_default_integer_from_env(self):
3407
self.register_integer_option('foo', default_from_env=['FOO'])
3408
self.overrideEnv('FOO', '18')
3409
self.assertEquals(18, self.conf.get('foo'))
3411
def test_get_default_integer_when_conversion_fails(self):
3412
self.register_integer_option('foo', default='12')
3413
self.conf.store._load_from_string('foo=invalid integer')
3414
self.assertEquals(12, self.conf.get('foo'))
3416
def register_list_option(self, name, default=None, default_from_env=None):
3417
l = config.Option(name, help='A list.',
3418
default=default, default_from_env=default_from_env,
3419
from_unicode=config.list_from_store)
3420
self.registry.register(l)
3422
def test_get_default_list_None(self):
3423
self.register_list_option('foo')
3424
self.assertEquals(None, self.conf.get('foo'))
3426
def test_get_default_list_empty(self):
3427
self.register_list_option('foo', '')
3428
self.assertEquals([], self.conf.get('foo'))
3430
def test_get_default_list_from_env(self):
3431
self.register_list_option('foo', default_from_env=['FOO'])
3432
self.overrideEnv('FOO', '')
3433
self.assertEquals([], self.conf.get('foo'))
3435
def test_get_with_list_converter_no_item(self):
3436
self.register_list_option('foo', None)
3437
self.conf.store._load_from_string('foo=,')
3438
self.assertEquals([], self.conf.get('foo'))
3440
def test_get_with_list_converter_many_items(self):
3441
self.register_list_option('foo', None)
3442
self.conf.store._load_from_string('foo=m,o,r,e')
3443
self.assertEquals(['m', 'o', 'r', 'e'], self.conf.get('foo'))
3445
def test_get_with_list_converter_embedded_spaces_many_items(self):
3446
self.register_list_option('foo', None)
3447
self.conf.store._load_from_string('foo=" bar", "baz "')
3448
self.assertEquals([' bar', 'baz '], self.conf.get('foo'))
3450
def test_get_with_list_converter_stripped_spaces_many_items(self):
3451
self.register_list_option('foo', None)
3452
self.conf.store._load_from_string('foo= bar , baz ')
3453
self.assertEquals(['bar', 'baz'], self.conf.get('foo'))
3456
class TestStackExpandOptions(tests.TestCaseWithTransport):
3459
super(TestStackExpandOptions, self).setUp()
3460
self.overrideAttr(config, 'option_registry', config.OptionRegistry())
3461
self.registry = config.option_registry
3462
self.conf = build_branch_stack(self)
3464
def assertExpansion(self, expected, string, env=None):
3465
self.assertEquals(expected, self.conf.expand_options(string, env))
3467
def test_no_expansion(self):
3468
self.assertExpansion('foo', 'foo')
3470
def test_expand_default_value(self):
3471
self.conf.store._load_from_string('bar=baz')
3472
self.registry.register(config.Option('foo', default=u'{bar}'))
3473
self.assertEquals('baz', self.conf.get('foo', expand=True))
3475
def test_expand_default_from_env(self):
3476
self.conf.store._load_from_string('bar=baz')
3477
self.registry.register(config.Option('foo', default_from_env=['FOO']))
3478
self.overrideEnv('FOO', '{bar}')
3479
self.assertEquals('baz', self.conf.get('foo', expand=True))
3481
def test_expand_default_on_failed_conversion(self):
3482
self.conf.store._load_from_string('baz=bogus\nbar=42\nfoo={baz}')
3483
self.registry.register(
3484
config.Option('foo', default=u'{bar}',
3485
from_unicode=config.int_from_store))
3486
self.assertEquals(42, self.conf.get('foo', expand=True))
3488
def test_env_adding_options(self):
3489
self.assertExpansion('bar', '{foo}', {'foo': 'bar'})
3491
def test_env_overriding_options(self):
3492
self.conf.store._load_from_string('foo=baz')
3493
self.assertExpansion('bar', '{foo}', {'foo': 'bar'})
3495
def test_simple_ref(self):
3496
self.conf.store._load_from_string('foo=xxx')
3497
self.assertExpansion('xxx', '{foo}')
3499
def test_unknown_ref(self):
3500
self.assertRaises(errors.ExpandingUnknownOption,
3501
self.conf.expand_options, '{foo}')
3503
def test_indirect_ref(self):
3504
self.conf.store._load_from_string('''
3508
self.assertExpansion('xxx', '{bar}')
3510
def test_embedded_ref(self):
3511
self.conf.store._load_from_string('''
3515
self.assertExpansion('xxx', '{{bar}}')
3517
def test_simple_loop(self):
3518
self.conf.store._load_from_string('foo={foo}')
3519
self.assertRaises(errors.OptionExpansionLoop,
3520
self.conf.expand_options, '{foo}')
3522
def test_indirect_loop(self):
3523
self.conf.store._load_from_string('''
3527
e = self.assertRaises(errors.OptionExpansionLoop,
3528
self.conf.expand_options, '{foo}')
3529
self.assertEquals('foo->bar->baz', e.refs)
3530
self.assertEquals('{foo}', e.string)
3532
def test_list(self):
3533
self.conf.store._load_from_string('''
3537
list={foo},{bar},{baz}
3539
self.registry.register(
3540
config.Option('list', from_unicode=config.list_from_store))
3541
self.assertEquals(['start', 'middle', 'end'],
3542
self.conf.get('list', expand=True))
3544
def test_cascading_list(self):
3545
self.conf.store._load_from_string('''
3551
self.registry.register(
3552
config.Option('list', from_unicode=config.list_from_store))
3553
self.assertEquals(['start', 'middle', 'end'],
3554
self.conf.get('list', expand=True))
3556
def test_pathologically_hidden_list(self):
3557
self.conf.store._load_from_string('''
3563
hidden={start}{middle}{end}
3565
# What matters is what the registration says, the conversion happens
3566
# only after all expansions have been performed
3567
self.registry.register(
3568
config.Option('hidden', from_unicode=config.list_from_store))
3569
self.assertEquals(['bin', 'go'],
3570
self.conf.get('hidden', expand=True))
3573
class TestStackCrossSectionsExpand(tests.TestCaseWithTransport):
3576
super(TestStackCrossSectionsExpand, self).setUp()
3578
def get_config(self, location, string):
3581
# Since we don't save the config we won't strictly require to inherit
3582
# from TestCaseInTempDir, but an error occurs so quickly...
3583
c = config.LocationStack(location)
3584
c.store._load_from_string(string)
3587
def test_dont_cross_unrelated_section(self):
3588
c = self.get_config('/another/branch/path','''
3593
[/another/branch/path]
3596
self.assertRaises(errors.ExpandingUnknownOption,
3597
c.get, 'bar', expand=True)
3599
def test_cross_related_sections(self):
3600
c = self.get_config('/project/branch/path','''
3604
[/project/branch/path]
3607
self.assertEquals('quux', c.get('bar', expand=True))
3610
2524
class TestStackSet(TestStackWithTransport):
3612
2526
def test_simple_set(self):