2199
2329
opt = config.Option('foo', default='bar')
2200
2330
self.assertEquals('bar', opt.get_default())
2332
def test_callable_default_value(self):
2333
def bar_as_unicode():
2335
opt = config.Option('foo', default=bar_as_unicode)
2336
self.assertEquals('bar', opt.get_default())
2338
def test_default_value_from_env(self):
2339
opt = config.Option('foo', default='bar', default_from_env=['FOO'])
2340
self.overrideEnv('FOO', 'quux')
2341
# Env variable provides a default taking over the option one
2342
self.assertEquals('quux', opt.get_default())
2344
def test_first_default_value_from_env_wins(self):
2345
opt = config.Option('foo', default='bar',
2346
default_from_env=['NO_VALUE', 'FOO', 'BAZ'])
2347
self.overrideEnv('FOO', 'foo')
2348
self.overrideEnv('BAZ', 'baz')
2349
# The first env var set wins
2350
self.assertEquals('foo', opt.get_default())
2352
def test_not_supported_list_default_value(self):
2353
self.assertRaises(AssertionError, config.Option, 'foo', default=[1])
2355
def test_not_supported_object_default_value(self):
2356
self.assertRaises(AssertionError, config.Option, 'foo',
2359
def test_not_supported_callable_default_value_not_unicode(self):
2360
def bar_not_unicode():
2362
opt = config.Option('foo', default=bar_not_unicode)
2363
self.assertRaises(AssertionError, opt.get_default)
2366
class TestOptionConverterMixin(object):
2368
def assertConverted(self, expected, opt, value):
2369
self.assertEquals(expected, opt.convert_from_unicode(value),
2370
'Expecting %s, got %s' % (expected, value,))
2372
def assertWarns(self, opt, value):
2375
warnings.append(args[0] % args[1:])
2376
self.overrideAttr(trace, 'warning', warning)
2377
self.assertEquals(None, opt.convert_from_unicode(value))
2378
self.assertLength(1, warnings)
2380
'Value "%s" is not valid for "%s"' % (value, opt.name),
2383
def assertErrors(self, opt, value):
2384
self.assertRaises(errors.ConfigOptionValueError,
2385
opt.convert_from_unicode, value)
2387
def assertConvertInvalid(self, opt, invalid_value):
2389
self.assertEquals(None, opt.convert_from_unicode(invalid_value),
2390
'%s is not None' % (invalid_value,))
2391
opt.invalid = 'warning'
2392
self.assertWarns(opt, invalid_value)
2393
opt.invalid = 'error'
2394
self.assertErrors(opt, invalid_value)
2397
class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
2399
def get_option(self):
2400
return config.Option('foo', help='A boolean.',
2401
from_unicode=config.bool_from_store)
2403
def test_convert_invalid(self):
2404
opt = self.get_option()
2405
# A string that is not recognized as a boolean
2406
self.assertConvertInvalid(opt, u'invalid-boolean')
2407
# A list of strings is never recognized as a boolean
2408
self.assertConvertInvalid(opt, [u'not', u'a', u'boolean'])
2410
def test_convert_valid(self):
2411
opt = self.get_option()
2412
self.assertConverted(True, opt, u'True')
2413
self.assertConverted(True, opt, u'1')
2414
self.assertConverted(False, opt, u'False')
2417
class TestOptionWithIntegerConverter(tests.TestCase, TestOptionConverterMixin):
2419
def get_option(self):
2420
return config.Option('foo', help='An integer.',
2421
from_unicode=config.int_from_store)
2423
def test_convert_invalid(self):
2424
opt = self.get_option()
2425
# A string that is not recognized as an integer
2426
self.assertConvertInvalid(opt, u'forty-two')
2427
# A list of strings is never recognized as an integer
2428
self.assertConvertInvalid(opt, [u'a', u'list'])
2430
def test_convert_valid(self):
2431
opt = self.get_option()
2432
self.assertConverted(16, opt, u'16')
2435
class TestOptionWithSIUnitConverter(tests.TestCase, TestOptionConverterMixin):
2437
def get_option(self):
2438
return config.Option('foo', help='An integer in SI units.',
2439
from_unicode=config.int_SI_from_store)
2441
def test_convert_invalid(self):
2442
opt = self.get_option()
2443
self.assertConvertInvalid(opt, u'not-a-unit')
2444
self.assertConvertInvalid(opt, u'Gb') # Forgot the int
2445
self.assertConvertInvalid(opt, u'1b') # Forgot the unit
2446
self.assertConvertInvalid(opt, u'1GG')
2447
self.assertConvertInvalid(opt, u'1Mbb')
2448
self.assertConvertInvalid(opt, u'1MM')
2450
def test_convert_valid(self):
2451
opt = self.get_option()
2452
self.assertConverted(int(5e3), opt, u'5kb')
2453
self.assertConverted(int(5e6), opt, u'5M')
2454
self.assertConverted(int(5e6), opt, u'5MB')
2455
self.assertConverted(int(5e9), opt, u'5g')
2456
self.assertConverted(int(5e9), opt, u'5gB')
2457
self.assertConverted(100, opt, u'100')
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
# No string is invalid as all forms can be converted to a list
2470
def test_convert_valid(self):
2471
opt = self.get_option()
2472
# An empty string is an empty list
2473
self.assertConverted([], opt, '') # Using a bare str() just in case
2474
self.assertConverted([], opt, u'')
2476
self.assertConverted([u'True'], opt, u'True')
2478
self.assertConverted([u'42'], opt, u'42')
2480
self.assertConverted([u'bar'], opt, u'bar')
2481
# A list remains a list (configObj will turn a string containing commas
2482
# into a list, but that's not what we're testing here)
2483
self.assertConverted([u'foo', u'1', u'True'],
2484
opt, [u'foo', u'1', u'True'])
2487
class TestOptionConverterMixin(object):
2489
def assertConverted(self, expected, opt, value):
2490
self.assertEquals(expected, opt.convert_from_unicode(value))
2492
def assertWarns(self, opt, value):
2495
warnings.append(args[0] % args[1:])
2496
self.overrideAttr(trace, 'warning', warning)
2497
self.assertEquals(None, opt.convert_from_unicode(value))
2498
self.assertLength(1, warnings)
2500
'Value "%s" is not valid for "%s"' % (value, opt.name),
2503
def assertErrors(self, opt, value):
2504
self.assertRaises(errors.ConfigOptionValueError,
2505
opt.convert_from_unicode, value)
2507
def assertConvertInvalid(self, opt, invalid_value):
2509
self.assertEquals(None, opt.convert_from_unicode(invalid_value))
2510
opt.invalid = 'warning'
2511
self.assertWarns(opt, invalid_value)
2512
opt.invalid = 'error'
2513
self.assertErrors(opt, invalid_value)
2516
class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
2518
def get_option(self):
2519
return config.Option('foo', help='A boolean.',
2520
from_unicode=config.bool_from_store)
2522
def test_convert_invalid(self):
2523
opt = self.get_option()
2524
# A string that is not recognized as a boolean
2525
self.assertConvertInvalid(opt, u'invalid-boolean')
2526
# A list of strings is never recognized as a boolean
2527
self.assertConvertInvalid(opt, [u'not', u'a', u'boolean'])
2529
def test_convert_valid(self):
2530
opt = self.get_option()
2531
self.assertConverted(True, opt, u'True')
2532
self.assertConverted(True, opt, u'1')
2533
self.assertConverted(False, opt, u'False')
2536
class TestOptionWithIntegerConverter(tests.TestCase, TestOptionConverterMixin):
2538
def get_option(self):
2539
return config.Option('foo', help='An integer.',
2540
from_unicode=config.int_from_store)
2542
def test_convert_invalid(self):
2543
opt = self.get_option()
2544
# A string that is not recognized as an integer
2545
self.assertConvertInvalid(opt, u'forty-two')
2546
# A list of strings is never recognized as an integer
2547
self.assertConvertInvalid(opt, [u'a', u'list'])
2549
def test_convert_valid(self):
2550
opt = self.get_option()
2551
self.assertConverted(16, opt, u'16')
2554
class TestOptionWithListConverter(tests.TestCase, TestOptionConverterMixin):
2556
def get_option(self):
2557
return config.Option('foo', help='A list.',
2558
from_unicode=config.list_from_store)
2560
def test_convert_invalid(self):
2561
opt = self.get_option()
2562
# We don't even try to convert a list into a list, we only expect
2564
self.assertConvertInvalid(opt, [1])
2565
# No string is invalid as all forms can be converted to a list
2567
def test_convert_valid(self):
2568
opt = self.get_option()
2569
# An empty string is an empty list
2570
self.assertConverted([], opt, '') # Using a bare str() just in case
2571
self.assertConverted([], opt, u'')
2573
self.assertConverted([u'True'], opt, u'True')
2575
self.assertConverted([u'42'], opt, u'42')
2577
self.assertConverted([u'bar'], opt, u'bar')
2203
2580
class TestOptionRegistry(tests.TestCase):
2205
2582
def setUp(self):
2206
2583
super(TestOptionRegistry, self).setUp()
2207
2584
# Always start with an empty registry
2208
self.overrideAttr(config, 'option_registry', registry.Registry())
2585
self.overrideAttr(config, 'option_registry', config.OptionRegistry())
2209
2586
self.registry = config.option_registry
2211
2588
def test_register(self):
2212
2589
opt = config.Option('foo')
2213
self.registry.register('foo', opt)
2590
self.registry.register(opt)
2214
2591
self.assertIs(opt, self.registry.get('foo'))
2216
lazy_option = config.Option('lazy_foo')
2218
def test_register_lazy(self):
2219
self.registry.register_lazy('foo', self.__module__,
2220
'TestOptionRegistry.lazy_option')
2221
self.assertIs(self.lazy_option, self.registry.get('foo'))
2223
2593
def test_registered_help(self):
2224
opt = config.Option('foo')
2225
self.registry.register('foo', opt, help='A simple option')
2594
opt = config.Option('foo', help='A simple option')
2595
self.registry.register(opt)
2226
2596
self.assertEquals('A simple option', self.registry.get_help('foo'))
2598
lazy_option = config.Option('lazy_foo', help='Lazy help')
2600
def test_register_lazy(self):
2601
self.registry.register_lazy('lazy_foo', self.__module__,
2602
'TestOptionRegistry.lazy_option')
2603
self.assertIs(self.lazy_option, self.registry.get('lazy_foo'))
2605
def test_registered_lazy_help(self):
2606
self.registry.register_lazy('lazy_foo', self.__module__,
2607
'TestOptionRegistry.lazy_option')
2608
self.assertEquals('Lazy help', self.registry.get_help('lazy_foo'))
2229
2611
class TestRegisteredOptions(tests.TestCase):
2230
2612
"""All registered options should verify some constraints."""
2915
3427
class TestStackGet(TestStackWithTransport):
3430
super(TestStackGet, self).setUp()
3431
self.conf = self.get_stack(self)
2917
3433
def test_get_for_empty_stack(self):
2918
conf = self.get_stack(self)
2919
self.assertEquals(None, conf.get('foo'))
3434
self.assertEquals(None, self.conf.get('foo'))
2921
3436
def test_get_hook(self):
2922
conf = self.get_stack(self)
2923
conf.store._load_from_string('foo=bar')
3437
self.conf.set('foo', 'bar')
2925
3439
def hook(*args):
2926
3440
calls.append(args)
2927
3441
config.ConfigHooks.install_named_hook('get', hook, None)
2928
3442
self.assertLength(0, calls)
2929
value = conf.get('foo')
3443
value = self.conf.get('foo')
2930
3444
self.assertEquals('bar', value)
2931
3445
self.assertLength(1, calls)
2932
self.assertEquals((conf, 'foo', 'bar'), calls[0])
3446
self.assertEquals((self.conf, 'foo', 'bar'), calls[0])
3449
class TestStackGetWithConverter(tests.TestCaseWithTransport):
3452
super(TestStackGetWithConverter, self).setUp()
3453
self.overrideAttr(config, 'option_registry', config.OptionRegistry())
3454
self.registry = config.option_registry
3455
# We just want a simple stack with a simple store so we can inject
3456
# whatever content the tests need without caring about what section
3457
# names are valid for a given store/stack.
3458
store = config.TransportIniFileStore(self.get_transport(), 'foo.conf')
3459
self.conf = config.Stack([store.get_sections], store)
3461
def register_bool_option(self, name, default=None, default_from_env=None):
3462
b = config.Option(name, help='A boolean.',
3463
default=default, default_from_env=default_from_env,
3464
from_unicode=config.bool_from_store)
3465
self.registry.register(b)
3467
def test_get_default_bool_None(self):
3468
self.register_bool_option('foo')
3469
self.assertEquals(None, self.conf.get('foo'))
3471
def test_get_default_bool_True(self):
3472
self.register_bool_option('foo', u'True')
3473
self.assertEquals(True, self.conf.get('foo'))
3475
def test_get_default_bool_False(self):
3476
self.register_bool_option('foo', False)
3477
self.assertEquals(False, self.conf.get('foo'))
3479
def test_get_default_bool_False_as_string(self):
3480
self.register_bool_option('foo', u'False')
3481
self.assertEquals(False, self.conf.get('foo'))
3483
def test_get_default_bool_from_env_converted(self):
3484
self.register_bool_option('foo', u'True', default_from_env=['FOO'])
3485
self.overrideEnv('FOO', 'False')
3486
self.assertEquals(False, self.conf.get('foo'))
3488
def test_get_default_bool_when_conversion_fails(self):
3489
self.register_bool_option('foo', default='True')
3490
self.conf.store._load_from_string('foo=invalid boolean')
3491
self.assertEquals(True, self.conf.get('foo'))
3493
def register_integer_option(self, name,
3494
default=None, default_from_env=None):
3495
i = config.Option(name, help='An integer.',
3496
default=default, default_from_env=default_from_env,
3497
from_unicode=config.int_from_store)
3498
self.registry.register(i)
3500
def test_get_default_integer_None(self):
3501
self.register_integer_option('foo')
3502
self.assertEquals(None, self.conf.get('foo'))
3504
def test_get_default_integer(self):
3505
self.register_integer_option('foo', 42)
3506
self.assertEquals(42, self.conf.get('foo'))
3508
def test_get_default_integer_as_string(self):
3509
self.register_integer_option('foo', u'42')
3510
self.assertEquals(42, self.conf.get('foo'))
3512
def test_get_default_integer_from_env(self):
3513
self.register_integer_option('foo', default_from_env=['FOO'])
3514
self.overrideEnv('FOO', '18')
3515
self.assertEquals(18, self.conf.get('foo'))
3517
def test_get_default_integer_when_conversion_fails(self):
3518
self.register_integer_option('foo', default='12')
3519
self.conf.store._load_from_string('foo=invalid integer')
3520
self.assertEquals(12, self.conf.get('foo'))
3522
def register_list_option(self, name, default=None, default_from_env=None):
3523
l = config.Option(name, help='A list.',
3524
default=default, default_from_env=default_from_env,
3525
from_unicode=config.list_from_store)
3526
self.registry.register(l)
3528
def test_get_default_list_None(self):
3529
self.register_list_option('foo')
3530
self.assertEquals(None, self.conf.get('foo'))
3532
def test_get_default_list_empty(self):
3533
self.register_list_option('foo', '')
3534
self.assertEquals([], self.conf.get('foo'))
3536
def test_get_default_list_from_env(self):
3537
self.register_list_option('foo', default_from_env=['FOO'])
3538
self.overrideEnv('FOO', '')
3539
self.assertEquals([], self.conf.get('foo'))
3541
def test_get_with_list_converter_no_item(self):
3542
self.register_list_option('foo', None)
3543
self.conf.store._load_from_string('foo=,')
3544
self.assertEquals([], self.conf.get('foo'))
3546
def test_get_with_list_converter_many_items(self):
3547
self.register_list_option('foo', None)
3548
self.conf.store._load_from_string('foo=m,o,r,e')
3549
self.assertEquals(['m', 'o', 'r', 'e'], self.conf.get('foo'))
3551
def test_get_with_list_converter_embedded_spaces_many_items(self):
3552
self.register_list_option('foo', None)
3553
self.conf.store._load_from_string('foo=" bar", "baz "')
3554
self.assertEquals([' bar', 'baz '], self.conf.get('foo'))
3556
def test_get_with_list_converter_stripped_spaces_many_items(self):
3557
self.register_list_option('foo', None)
3558
self.conf.store._load_from_string('foo= bar , baz ')
3559
self.assertEquals(['bar', 'baz'], self.conf.get('foo'))
3562
class TestIterOptionRefs(tests.TestCase):
3563
"""iter_option_refs is a bit unusual, document some cases."""
3565
def assertRefs(self, expected, string):
3566
self.assertEquals(expected, list(config.iter_option_refs(string)))
3568
def test_empty(self):
3569
self.assertRefs([(False, '')], '')
3571
def test_no_refs(self):
3572
self.assertRefs([(False, 'foo bar')], 'foo bar')
3574
def test_single_ref(self):
3575
self.assertRefs([(False, ''), (True, '{foo}'), (False, '')], '{foo}')
3577
def test_broken_ref(self):
3578
self.assertRefs([(False, '{foo')], '{foo')
3580
def test_embedded_ref(self):
3581
self.assertRefs([(False, '{'), (True, '{foo}'), (False, '}')],
3584
def test_two_refs(self):
3585
self.assertRefs([(False, ''), (True, '{foo}'),
3586
(False, ''), (True, '{bar}'),
3590
def test_newline_in_refs_are_not_matched(self):
3591
self.assertRefs([(False, '{\nxx}{xx\n}{{\n}}')], '{\nxx}{xx\n}{{\n}}')
3594
class TestStackExpandOptions(tests.TestCaseWithTransport):
3597
super(TestStackExpandOptions, self).setUp()
3598
self.overrideAttr(config, 'option_registry', config.OptionRegistry())
3599
self.registry = config.option_registry
3600
self.conf = build_branch_stack(self)
3602
def assertExpansion(self, expected, string, env=None):
3603
self.assertEquals(expected, self.conf.expand_options(string, env))
3605
def test_no_expansion(self):
3606
self.assertExpansion('foo', 'foo')
3608
def test_expand_default_value(self):
3609
self.conf.store._load_from_string('bar=baz')
3610
self.registry.register(config.Option('foo', default=u'{bar}'))
3611
self.assertEquals('baz', self.conf.get('foo', expand=True))
3613
def test_expand_default_from_env(self):
3614
self.conf.store._load_from_string('bar=baz')
3615
self.registry.register(config.Option('foo', default_from_env=['FOO']))
3616
self.overrideEnv('FOO', '{bar}')
3617
self.assertEquals('baz', self.conf.get('foo', expand=True))
3619
def test_expand_default_on_failed_conversion(self):
3620
self.conf.store._load_from_string('baz=bogus\nbar=42\nfoo={baz}')
3621
self.registry.register(
3622
config.Option('foo', default=u'{bar}',
3623
from_unicode=config.int_from_store))
3624
self.assertEquals(42, self.conf.get('foo', expand=True))
3626
def test_env_adding_options(self):
3627
self.assertExpansion('bar', '{foo}', {'foo': 'bar'})
3629
def test_env_overriding_options(self):
3630
self.conf.store._load_from_string('foo=baz')
3631
self.assertExpansion('bar', '{foo}', {'foo': 'bar'})
3633
def test_simple_ref(self):
3634
self.conf.store._load_from_string('foo=xxx')
3635
self.assertExpansion('xxx', '{foo}')
3637
def test_unknown_ref(self):
3638
self.assertRaises(errors.ExpandingUnknownOption,
3639
self.conf.expand_options, '{foo}')
3641
def test_indirect_ref(self):
3642
self.conf.store._load_from_string('''
3646
self.assertExpansion('xxx', '{bar}')
3648
def test_embedded_ref(self):
3649
self.conf.store._load_from_string('''
3653
self.assertExpansion('xxx', '{{bar}}')
3655
def test_simple_loop(self):
3656
self.conf.store._load_from_string('foo={foo}')
3657
self.assertRaises(errors.OptionExpansionLoop,
3658
self.conf.expand_options, '{foo}')
3660
def test_indirect_loop(self):
3661
self.conf.store._load_from_string('''
3665
e = self.assertRaises(errors.OptionExpansionLoop,
3666
self.conf.expand_options, '{foo}')
3667
self.assertEquals('foo->bar->baz', e.refs)
3668
self.assertEquals('{foo}', e.string)
3670
def test_list(self):
3671
self.conf.store._load_from_string('''
3675
list={foo},{bar},{baz}
3677
self.registry.register(
3678
config.Option('list', from_unicode=config.list_from_store))
3679
self.assertEquals(['start', 'middle', 'end'],
3680
self.conf.get('list', expand=True))
3682
def test_cascading_list(self):
3683
self.conf.store._load_from_string('''
3689
self.registry.register(
3690
config.Option('list', from_unicode=config.list_from_store))
3691
self.assertEquals(['start', 'middle', 'end'],
3692
self.conf.get('list', expand=True))
3694
def test_pathologically_hidden_list(self):
3695
self.conf.store._load_from_string('''
3701
hidden={start}{middle}{end}
3703
# What matters is what the registration says, the conversion happens
3704
# only after all expansions have been performed
3705
self.registry.register(
3706
config.Option('hidden', from_unicode=config.list_from_store))
3707
self.assertEquals(['bin', 'go'],
3708
self.conf.get('hidden', expand=True))
3711
class TestStackCrossSectionsExpand(tests.TestCaseWithTransport):
3714
super(TestStackCrossSectionsExpand, self).setUp()
3716
def get_config(self, location, string):
3719
# Since we don't save the config we won't strictly require to inherit
3720
# from TestCaseInTempDir, but an error occurs so quickly...
3721
c = config.LocationStack(location)
3722
c.store._load_from_string(string)
3725
def test_dont_cross_unrelated_section(self):
3726
c = self.get_config('/another/branch/path','''
3731
[/another/branch/path]
3734
self.assertRaises(errors.ExpandingUnknownOption,
3735
c.get, 'bar', expand=True)
3737
def test_cross_related_sections(self):
3738
c = self.get_config('/project/branch/path','''
3742
[/project/branch/path]
3745
self.assertEquals('quux', c.get('bar', expand=True))
3748
class TestStackCrossStoresExpand(tests.TestCaseWithTransport):
3750
def test_cross_global_locations(self):
3751
l_store = config.LocationStore()
3752
l_store._load_from_string('''
3758
g_store = config.GlobalStore()
3759
g_store._load_from_string('''
3765
stack = config.LocationStack('/branch')
3766
self.assertEquals('glob-bar', stack.get('lbar', expand=True))
3767
self.assertEquals('loc-foo', stack.get('gfoo', expand=True))
3770
class TestStackExpandSectionLocals(tests.TestCaseWithTransport):
3772
def test_expand_locals_empty(self):
3773
l_store = config.LocationStore()
3774
l_store._load_from_string('''
3775
[/home/user/project]
3780
stack = config.LocationStack('/home/user/project/')
3781
self.assertEquals('', stack.get('base', expand=True))
3782
self.assertEquals('', stack.get('rel', expand=True))
3784
def test_expand_basename_locally(self):
3785
l_store = config.LocationStore()
3786
l_store._load_from_string('''
3787
[/home/user/project]
3791
stack = config.LocationStack('/home/user/project/branch')
3792
self.assertEquals('branch', stack.get('bfoo', expand=True))
3794
def test_expand_basename_locally_longer_path(self):
3795
l_store = config.LocationStore()
3796
l_store._load_from_string('''
3801
stack = config.LocationStack('/home/user/project/dir/branch')
3802
self.assertEquals('branch', stack.get('bfoo', expand=True))
3804
def test_expand_relpath_locally(self):
3805
l_store = config.LocationStore()
3806
l_store._load_from_string('''
3807
[/home/user/project]
3808
lfoo = loc-foo/{relpath}
3811
stack = config.LocationStack('/home/user/project/branch')
3812
self.assertEquals('loc-foo/branch', stack.get('lfoo', expand=True))
3814
def test_expand_relpath_unknonw_in_global(self):
3815
g_store = config.GlobalStore()
3816
g_store._load_from_string('''
3821
stack = config.LocationStack('/home/user/project/branch')
3822
self.assertRaises(errors.ExpandingUnknownOption,
3823
stack.get, 'gfoo', expand=True)
3825
def test_expand_local_option_locally(self):
3826
l_store = config.LocationStore()
3827
l_store._load_from_string('''
3828
[/home/user/project]
3829
lfoo = loc-foo/{relpath}
3833
g_store = config.GlobalStore()
3834
g_store._load_from_string('''
3840
stack = config.LocationStack('/home/user/project/branch')
3841
self.assertEquals('glob-bar', stack.get('lbar', expand=True))
3842
self.assertEquals('loc-foo/branch', stack.get('gfoo', expand=True))
3844
def test_locals_dont_leak(self):
3845
"""Make sure we chose the right local in presence of several sections.
3847
l_store = config.LocationStore()
3848
l_store._load_from_string('''
3850
lfoo = loc-foo/{relpath}
3851
[/home/user/project]
3852
lfoo = loc-foo/{relpath}
3855
stack = config.LocationStack('/home/user/project/branch')
3856
self.assertEquals('loc-foo/branch', stack.get('lfoo', expand=True))
3857
stack = config.LocationStack('/home/user/bar/baz')
3858
self.assertEquals('loc-foo/bar/baz', stack.get('lfoo', expand=True))
2935
3862
class TestStackSet(TestStackWithTransport):
2937
3864
def test_simple_set(self):
2938
3865
conf = self.get_stack(self)
2939
conf.store._load_from_string('foo=bar')
2940
self.assertEquals('bar', conf.get('foo'))
3866
self.assertEquals(None, conf.get('foo'))
2941
3867
conf.set('foo', 'baz')
2942
3868
# Did we get it back ?
2943
3869
self.assertEquals('baz', conf.get('foo'))