587
455
self.assertFileEqual(content, 'test.conf')
590
class TestIniConfigOptionExpansionDefaultValue(tests.TestCaseInTempDir):
591
"""What is the default value of expand for config options.
593
This is an opt-in beta feature used to evaluate whether or not option
594
references can appear in dangerous place raising exceptions, disapearing
595
(and as such corrupting data) or if it's safe to activate the option by
598
Note that these tests relies on config._expand_default_value being already
599
overwritten in the parent class setUp.
603
super(TestIniConfigOptionExpansionDefaultValue, self).setUp()
607
self.warnings.append(args[0] % args[1:])
608
self.overrideAttr(trace, 'warning', warning)
610
def get_config(self, expand):
611
c = config.GlobalConfig.from_string('bzr.config.expand=%s' % (expand,),
615
def assertExpandIs(self, expected):
616
actual = config._get_expand_default_value()
617
#self.config.get_user_option_as_bool('bzr.config.expand')
618
self.assertEquals(expected, actual)
620
def test_default_is_None(self):
621
self.assertEquals(None, config._expand_default_value)
623
def test_default_is_False_even_if_None(self):
624
self.config = self.get_config(None)
625
self.assertExpandIs(False)
627
def test_default_is_False_even_if_invalid(self):
628
self.config = self.get_config('<your choice>')
629
self.assertExpandIs(False)
631
# Huh ? My choice is False ? Thanks, always happy to hear that :D
632
# Wait, you've been warned !
633
self.assertLength(1, self.warnings)
635
'Value "<your choice>" is not a boolean for "bzr.config.expand"',
638
def test_default_is_True(self):
639
self.config = self.get_config(True)
640
self.assertExpandIs(True)
642
def test_default_is_False(self):
643
self.config = self.get_config(False)
644
self.assertExpandIs(False)
647
class TestIniConfigOptionExpansion(tests.TestCase):
648
"""Test option expansion from the IniConfig level.
650
What we really want here is to test the Config level, but the class being
651
abstract as far as storing values is concerned, this can't be done
654
# FIXME: This should be rewritten when all configs share a storage
655
# implementation -- vila 2011-02-18
657
def get_config(self, string=None):
660
c = config.IniBasedConfig.from_string(string)
663
def assertExpansion(self, expected, conf, string, env=None):
664
self.assertEquals(expected, conf.expand_options(string, env))
666
def test_no_expansion(self):
667
c = self.get_config('')
668
self.assertExpansion('foo', c, 'foo')
670
def test_env_adding_options(self):
671
c = self.get_config('')
672
self.assertExpansion('bar', c, '{foo}', {'foo': 'bar'})
674
def test_env_overriding_options(self):
675
c = self.get_config('foo=baz')
676
self.assertExpansion('bar', c, '{foo}', {'foo': 'bar'})
678
def test_simple_ref(self):
679
c = self.get_config('foo=xxx')
680
self.assertExpansion('xxx', c, '{foo}')
682
def test_unknown_ref(self):
683
c = self.get_config('')
684
self.assertRaises(errors.ExpandingUnknownOption,
685
c.expand_options, '{foo}')
687
def test_indirect_ref(self):
688
c = self.get_config('''
692
self.assertExpansion('xxx', c, '{bar}')
694
def test_embedded_ref(self):
695
c = self.get_config('''
699
self.assertExpansion('xxx', c, '{{bar}}')
701
def test_simple_loop(self):
702
c = self.get_config('foo={foo}')
703
self.assertRaises(errors.OptionExpansionLoop, c.expand_options, '{foo}')
705
def test_indirect_loop(self):
706
c = self.get_config('''
710
e = self.assertRaises(errors.OptionExpansionLoop,
711
c.expand_options, '{foo}')
712
self.assertEquals('foo->bar->baz', e.refs)
713
self.assertEquals('{foo}', e.string)
716
conf = self.get_config('''
720
list={foo},{bar},{baz}
722
self.assertEquals(['start', 'middle', 'end'],
723
conf.get_user_option('list', expand=True))
725
def test_cascading_list(self):
726
conf = self.get_config('''
732
self.assertEquals(['start', 'middle', 'end'],
733
conf.get_user_option('list', expand=True))
735
def test_pathological_hidden_list(self):
736
conf = self.get_config('''
742
hidden={start}{middle}{end}
744
# Nope, it's either a string or a list, and the list wins as soon as a
745
# ',' appears, so the string concatenation never occur.
746
self.assertEquals(['{foo', '}', '{', 'bar}'],
747
conf.get_user_option('hidden', expand=True))
749
class TestLocationConfigOptionExpansion(tests.TestCaseInTempDir):
751
def get_config(self, location, string=None):
754
# Since we don't save the config we won't strictly require to inherit
755
# from TestCaseInTempDir, but an error occurs so quickly...
756
c = config.LocationConfig.from_string(string, location)
759
def test_dont_cross_unrelated_section(self):
760
c = self.get_config('/another/branch/path','''
765
[/another/branch/path]
768
self.assertRaises(errors.ExpandingUnknownOption,
769
c.get_user_option, 'bar', expand=True)
771
def test_cross_related_sections(self):
772
c = self.get_config('/project/branch/path','''
776
[/project/branch/path]
779
self.assertEquals('quux', c.get_user_option('bar', expand=True))
782
458
class TestIniBaseConfigOnDisk(tests.TestCaseInTempDir):
784
460
def test_cannot_reload_without_name(self):
1846
1471
self.assertIs(None, bzrdir_config.get_default_stack_on())
1849
class TestSection(tests.TestCase):
1851
# FIXME: Parametrize so that all sections produced by Stores run these
1852
# tests -- vila 2011-04-01
1854
def test_get_a_value(self):
1855
a_dict = dict(foo='bar')
1856
section = config.Section('myID', a_dict)
1857
self.assertEquals('bar', section.get('foo'))
1859
def test_get_unknown_option(self):
1861
section = config.Section(None, a_dict)
1862
self.assertEquals('out of thin air',
1863
section.get('foo', 'out of thin air'))
1865
def test_options_is_shared(self):
1867
section = config.Section(None, a_dict)
1868
self.assertIs(a_dict, section.options)
1871
class TestMutableSection(tests.TestCase):
1873
# FIXME: Parametrize so that all sections (including os.environ and the
1874
# ones produced by Stores) run these tests -- vila 2011-04-01
1877
a_dict = dict(foo='bar')
1878
section = config.MutableSection('myID', a_dict)
1879
section.set('foo', 'new_value')
1880
self.assertEquals('new_value', section.get('foo'))
1881
# The change appears in the shared section
1882
self.assertEquals('new_value', a_dict.get('foo'))
1883
# We keep track of the change
1884
self.assertTrue('foo' in section.orig)
1885
self.assertEquals('bar', section.orig.get('foo'))
1887
def test_set_preserve_original_once(self):
1888
a_dict = dict(foo='bar')
1889
section = config.MutableSection('myID', a_dict)
1890
section.set('foo', 'first_value')
1891
section.set('foo', 'second_value')
1892
# We keep track of the original value
1893
self.assertTrue('foo' in section.orig)
1894
self.assertEquals('bar', section.orig.get('foo'))
1896
def test_remove(self):
1897
a_dict = dict(foo='bar')
1898
section = config.MutableSection('myID', a_dict)
1899
section.remove('foo')
1900
# We get None for unknown options via the default value
1901
self.assertEquals(None, section.get('foo'))
1902
# Or we just get the default value
1903
self.assertEquals('unknown', section.get('foo', 'unknown'))
1904
self.assertFalse('foo' in section.options)
1905
# We keep track of the deletion
1906
self.assertTrue('foo' in section.orig)
1907
self.assertEquals('bar', section.orig.get('foo'))
1909
def test_remove_new_option(self):
1911
section = config.MutableSection('myID', a_dict)
1912
section.set('foo', 'bar')
1913
section.remove('foo')
1914
self.assertFalse('foo' in section.options)
1915
# The option didn't exist initially so it we need to keep track of it
1916
# with a special value
1917
self.assertTrue('foo' in section.orig)
1918
self.assertEquals(config._NewlyCreatedOption, section.orig['foo'])
1921
class TestStore(tests.TestCaseWithTransport):
1923
def assertSectionContent(self, expected, section):
1924
"""Assert that some options have the proper values in a section."""
1925
expected_name, expected_options = expected
1926
self.assertEquals(expected_name, section.id)
1929
dict([(k, section.get(k)) for k in expected_options.keys()]))
1932
class TestReadonlyStore(TestStore):
1934
scenarios = [(key, {'get_store': builder})
1935
for key, builder in test_store_builder_registry.iteritems()]
1938
super(TestReadonlyStore, self).setUp()
1939
self.branch = self.make_branch('branch')
1941
def test_building_delays_load(self):
1942
store = self.get_store(self)
1943
self.assertEquals(False, store.is_loaded())
1944
store._load_from_string('')
1945
self.assertEquals(True, store.is_loaded())
1947
def test_get_no_sections_for_empty(self):
1948
store = self.get_store(self)
1949
store._load_from_string('')
1950
self.assertEquals([], list(store.get_sections()))
1952
def test_get_default_section(self):
1953
store = self.get_store(self)
1954
store._load_from_string('foo=bar')
1955
sections = list(store.get_sections())
1956
self.assertLength(1, sections)
1957
self.assertSectionContent((None, {'foo': 'bar'}), sections[0])
1959
def test_get_named_section(self):
1960
store = self.get_store(self)
1961
store._load_from_string('[baz]\nfoo=bar')
1962
sections = list(store.get_sections())
1963
self.assertLength(1, sections)
1964
self.assertSectionContent(('baz', {'foo': 'bar'}), sections[0])
1966
def test_load_from_string_fails_for_non_empty_store(self):
1967
store = self.get_store(self)
1968
store._load_from_string('foo=bar')
1969
self.assertRaises(AssertionError, store._load_from_string, 'bar=baz')
1972
class TestMutableStore(TestStore):
1974
scenarios = [(key, {'store_id': key, 'get_store': builder})
1975
for key, builder in test_store_builder_registry.iteritems()]
1978
super(TestMutableStore, self).setUp()
1979
self.transport = self.get_transport()
1980
self.branch = self.make_branch('branch')
1982
def has_store(self, store):
1983
store_basename = urlutils.relative_url(self.transport.external_url(),
1984
store.external_url())
1985
return self.transport.has(store_basename)
1987
def test_save_empty_creates_no_file(self):
1988
if self.store_id == 'branch':
1989
raise tests.TestNotApplicable(
1990
'branch.conf is *always* created when a branch is initialized')
1991
store = self.get_store(self)
1993
self.assertEquals(False, self.has_store(store))
1995
def test_save_emptied_succeeds(self):
1996
store = self.get_store(self)
1997
store._load_from_string('foo=bar\n')
1998
section = store.get_mutable_section(None)
1999
section.remove('foo')
2001
self.assertEquals(True, self.has_store(store))
2002
modified_store = self.get_store(self)
2003
sections = list(modified_store.get_sections())
2004
self.assertLength(0, sections)
2006
def test_save_with_content_succeeds(self):
2007
if self.store_id == 'branch':
2008
raise tests.TestNotApplicable(
2009
'branch.conf is *always* created when a branch is initialized')
2010
store = self.get_store(self)
2011
store._load_from_string('foo=bar\n')
2012
self.assertEquals(False, self.has_store(store))
2014
self.assertEquals(True, self.has_store(store))
2015
modified_store = self.get_store(self)
2016
sections = list(modified_store.get_sections())
2017
self.assertLength(1, sections)
2018
self.assertSectionContent((None, {'foo': 'bar'}), sections[0])
2020
def test_set_option_in_empty_store(self):
2021
store = self.get_store(self)
2022
section = store.get_mutable_section(None)
2023
section.set('foo', 'bar')
2025
modified_store = self.get_store(self)
2026
sections = list(modified_store.get_sections())
2027
self.assertLength(1, sections)
2028
self.assertSectionContent((None, {'foo': 'bar'}), sections[0])
2030
def test_set_option_in_default_section(self):
2031
store = self.get_store(self)
2032
store._load_from_string('')
2033
section = store.get_mutable_section(None)
2034
section.set('foo', 'bar')
2036
modified_store = self.get_store(self)
2037
sections = list(modified_store.get_sections())
2038
self.assertLength(1, sections)
2039
self.assertSectionContent((None, {'foo': 'bar'}), sections[0])
2041
def test_set_option_in_named_section(self):
2042
store = self.get_store(self)
2043
store._load_from_string('')
2044
section = store.get_mutable_section('baz')
2045
section.set('foo', 'bar')
2047
modified_store = self.get_store(self)
2048
sections = list(modified_store.get_sections())
2049
self.assertLength(1, sections)
2050
self.assertSectionContent(('baz', {'foo': 'bar'}), sections[0])
2053
class TestIniFileStore(TestStore):
2055
def test_loading_unknown_file_fails(self):
2056
store = config.IniFileStore(self.get_transport(), 'I-do-not-exist')
2057
self.assertRaises(errors.NoSuchFile, store.load)
2059
def test_invalid_content(self):
2060
store = config.IniFileStore(self.get_transport(), 'foo.conf', )
2061
self.assertEquals(False, store.is_loaded())
2062
exc = self.assertRaises(
2063
errors.ParseConfigError, store._load_from_string,
2064
'this is invalid !')
2065
self.assertEndsWith(exc.filename, 'foo.conf')
2066
# And the load failed
2067
self.assertEquals(False, store.is_loaded())
2069
def test_get_embedded_sections(self):
2070
# A more complicated example (which also shows that section names and
2071
# option names share the same name space...)
2072
# FIXME: This should be fixed by forbidding dicts as values ?
2073
# -- vila 2011-04-05
2074
store = config.IniFileStore(self.get_transport(), 'foo.conf', )
2075
store._load_from_string('''
2079
foo_in_DEFAULT=foo_DEFAULT
2087
sections = list(store.get_sections())
2088
self.assertLength(4, sections)
2089
# The default section has no name.
2090
# List values are provided as lists
2091
self.assertSectionContent((None, {'foo': 'bar', 'l': ['1', '2']}),
2093
self.assertSectionContent(
2094
('DEFAULT', {'foo_in_DEFAULT': 'foo_DEFAULT'}), sections[1])
2095
self.assertSectionContent(
2096
('bar', {'foo_in_bar': 'barbar'}), sections[2])
2097
# sub sections are provided as embedded dicts.
2098
self.assertSectionContent(
2099
('baz', {'foo_in_baz': 'barbaz', 'qux': {'foo_in_qux': 'quux'}}),
2103
class TestLockableIniFileStore(TestStore):
2105
def test_create_store_in_created_dir(self):
2106
t = self.get_transport('dir/subdir')
2107
store = config.LockableIniFileStore(t, 'foo.conf')
2108
store.get_mutable_section(None).set('foo', 'bar')
2111
# FIXME: We should adapt the tests in TestLockableConfig about concurrent
2112
# writes. Since this requires a clearer rewrite, I'll just rely on using
2113
# the same code in LockableIniFileStore (copied from LockableConfig, but
2114
# trivial enough, the main difference is that we add @needs_write_lock on
2115
# save() instead of set_user_option() and remove_user_option()). The intent
2116
# is to ensure that we always get a valid content for the store even when
2117
# concurrent accesses occur, read/write, write/write. It may be worth
2118
# looking into removing the lock dir when it;s not needed anymore and look
2119
# at possible fallouts for concurrent lockers -- vila 20110-04-06
2122
class TestSectionMatcher(TestStore):
2124
scenarios = [('location', {'matcher': config.LocationMatcher})]
2126
def get_store(self, file_name):
2127
return config.IniFileStore(self.get_readonly_transport(), file_name)
2129
def test_no_matches_for_empty_stores(self):
2130
store = self.get_store('foo.conf')
2131
store._load_from_string('')
2132
matcher = self.matcher(store, '/bar')
2133
self.assertEquals([], list(matcher.get_sections()))
2135
def test_build_doesnt_load_store(self):
2136
store = self.get_store('foo.conf')
2137
matcher = self.matcher(store, '/bar')
2138
self.assertFalse(store.is_loaded())
2141
class TestLocationSection(tests.TestCase):
2143
def get_section(self, options, extra_path):
2144
section = config.Section('foo', options)
2145
# We don't care about the length so we use '0'
2146
return config.LocationSection(section, 0, extra_path)
2148
def test_simple_option(self):
2149
section = self.get_section({'foo': 'bar'}, '')
2150
self.assertEquals('bar', section.get('foo'))
2152
def test_option_with_extra_path(self):
2153
section = self.get_section({'foo': 'bar', 'foo:policy': 'appendpath'},
2155
self.assertEquals('bar/baz', section.get('foo'))
2157
def test_invalid_policy(self):
2158
section = self.get_section({'foo': 'bar', 'foo:policy': 'die'},
2160
# invalid policies are ignored
2161
self.assertEquals('bar', section.get('foo'))
2164
class TestLocationMatcher(TestStore):
2166
def get_store(self, file_name):
2167
return config.IniFileStore(self.get_readonly_transport(), file_name)
2169
def test_more_specific_sections_first(self):
2170
store = self.get_store('foo.conf')
2171
store._load_from_string('''
2177
self.assertEquals(['/foo', '/foo/bar'],
2178
[section.id for section in store.get_sections()])
2179
matcher = config.LocationMatcher(store, '/foo/bar/baz')
2180
sections = list(matcher.get_sections())
2181
self.assertEquals([3, 2],
2182
[section.length for section in sections])
2183
self.assertEquals(['/foo/bar', '/foo'],
2184
[section.id for section in sections])
2185
self.assertEquals(['baz', 'bar/baz'],
2186
[section.extra_path for section in sections])
2188
def test_appendpath_in_no_name_section(self):
2189
# It's a bit weird to allow appendpath in a no-name section, but
2190
# someone may found a use for it
2191
store = self.get_store('foo.conf')
2192
store._load_from_string('''
2194
foo:policy = appendpath
2196
matcher = config.LocationMatcher(store, 'dir/subdir')
2197
sections = list(matcher.get_sections())
2198
self.assertLength(1, sections)
2199
self.assertEquals('bar/dir/subdir', sections[0].get('foo'))
2201
def test_file_urls_are_normalized(self):
2202
store = self.get_store('foo.conf')
2203
if sys.platform == 'win32':
2204
expected_url = 'file:///C:/dir/subdir'
2205
expected_location = 'C:/dir/subdir'
2207
expected_url = 'file:///dir/subdir'
2208
expected_location = '/dir/subdir'
2209
matcher = config.LocationMatcher(store, expected_url)
2210
self.assertEquals(expected_location, matcher.location)
2213
class TestStackGet(tests.TestCase):
2215
# FIXME: This should be parametrized for all known Stack or dedicated
2216
# paramerized tests created to avoid bloating -- vila 2011-03-31
2218
def test_single_config_get(self):
2219
conf = dict(foo='bar')
2220
conf_stack = config.Stack([conf])
2221
self.assertEquals('bar', conf_stack.get('foo'))
2223
def test_get_first_definition(self):
2224
conf1 = dict(foo='bar')
2225
conf2 = dict(foo='baz')
2226
conf_stack = config.Stack([conf1, conf2])
2227
self.assertEquals('bar', conf_stack.get('foo'))
2229
def test_get_embedded_definition(self):
2230
conf1 = dict(yy='12')
2231
conf2 = config.Stack([dict(xx='42'), dict(foo='baz')])
2232
conf_stack = config.Stack([conf1, conf2])
2233
self.assertEquals('baz', conf_stack.get('foo'))
2235
def test_get_for_empty_stack(self):
2236
conf_stack = config.Stack([])
2237
self.assertEquals(None, conf_stack.get('foo'))
2239
def test_get_for_empty_section_callable(self):
2240
conf_stack = config.Stack([lambda : []])
2241
self.assertEquals(None, conf_stack.get('foo'))
2243
def test_get_for_broken_callable(self):
2244
# Trying to use and invalid callable raises an exception on first use
2245
conf_stack = config.Stack([lambda : object()])
2246
self.assertRaises(TypeError, conf_stack.get, 'foo')
2249
class TestStackWithTransport(tests.TestCaseWithTransport):
2252
super(TestStackWithTransport, self).setUp()
2253
# FIXME: A more elaborate builder for the stack would avoid building a
2254
# branch even for tests that don't need it.
2255
self.branch = self.make_branch('branch')
2258
class TestStackSet(TestStackWithTransport):
2260
scenarios = [(key, {'get_stack': builder})
2261
for key, builder in test_stack_builder_registry.iteritems()]
2263
def test_simple_set(self):
2264
conf = self.get_stack(self)
2265
conf.store._load_from_string('foo=bar')
2266
self.assertEquals('bar', conf.get('foo'))
2267
conf.set('foo', 'baz')
2268
# Did we get it back ?
2269
self.assertEquals('baz', conf.get('foo'))
2271
def test_set_creates_a_new_section(self):
2272
conf = self.get_stack(self)
2273
conf.set('foo', 'baz')
2274
self.assertEquals, 'baz', conf.get('foo')
2277
class TestStackRemove(TestStackWithTransport):
2279
scenarios = [(key, {'get_stack': builder})
2280
for key, builder in test_stack_builder_registry.iteritems()]
2282
def test_remove_existing(self):
2283
conf = self.get_stack(self)
2284
conf.store._load_from_string('foo=bar')
2285
self.assertEquals('bar', conf.get('foo'))
2287
# Did we get it back ?
2288
self.assertEquals(None, conf.get('foo'))
2290
def test_remove_unknown(self):
2291
conf = self.get_stack(self)
2292
self.assertRaises(KeyError, conf.remove, 'I_do_not_exist')
2295
class TestConcreteStacks(TestStackWithTransport):
2297
scenarios = [(key, {'get_stack': builder})
2298
for key, builder in test_stack_builder_registry.iteritems()]
2300
def test_build_stack(self):
2301
stack = self.get_stack(self)
2304
class TestConfigGetOptions(tests.TestCaseWithTransport, TestOptionsMixin):
2307
super(TestConfigGetOptions, self).setUp()
2308
create_configs(self)
2310
def test_no_variable(self):
2311
# Using branch should query branch, locations and bazaar
2312
self.assertOptions([], self.branch_config)
2314
def test_option_in_bazaar(self):
2315
self.bazaar_config.set_user_option('file', 'bazaar')
2316
self.assertOptions([('file', 'bazaar', 'DEFAULT', 'bazaar')],
2319
def test_option_in_locations(self):
2320
self.locations_config.set_user_option('file', 'locations')
2322
[('file', 'locations', self.tree.basedir, 'locations')],
2323
self.locations_config)
2325
def test_option_in_branch(self):
2326
self.branch_config.set_user_option('file', 'branch')
2327
self.assertOptions([('file', 'branch', 'DEFAULT', 'branch')],
2330
def test_option_in_bazaar_and_branch(self):
2331
self.bazaar_config.set_user_option('file', 'bazaar')
2332
self.branch_config.set_user_option('file', 'branch')
2333
self.assertOptions([('file', 'branch', 'DEFAULT', 'branch'),
2334
('file', 'bazaar', 'DEFAULT', 'bazaar'),],
2337
def test_option_in_branch_and_locations(self):
2338
# Hmm, locations override branch :-/
2339
self.locations_config.set_user_option('file', 'locations')
2340
self.branch_config.set_user_option('file', 'branch')
2342
[('file', 'locations', self.tree.basedir, 'locations'),
2343
('file', 'branch', 'DEFAULT', 'branch'),],
2346
def test_option_in_bazaar_locations_and_branch(self):
2347
self.bazaar_config.set_user_option('file', 'bazaar')
2348
self.locations_config.set_user_option('file', 'locations')
2349
self.branch_config.set_user_option('file', 'branch')
2351
[('file', 'locations', self.tree.basedir, 'locations'),
2352
('file', 'branch', 'DEFAULT', 'branch'),
2353
('file', 'bazaar', 'DEFAULT', 'bazaar'),],
2357
class TestConfigRemoveOption(tests.TestCaseWithTransport, TestOptionsMixin):
2360
super(TestConfigRemoveOption, self).setUp()
2361
create_configs_with_file_option(self)
2363
def test_remove_in_locations(self):
2364
self.locations_config.remove_user_option('file', self.tree.basedir)
2366
[('file', 'branch', 'DEFAULT', 'branch'),
2367
('file', 'bazaar', 'DEFAULT', 'bazaar'),],
2370
def test_remove_in_branch(self):
2371
self.branch_config.remove_user_option('file')
2373
[('file', 'locations', self.tree.basedir, 'locations'),
2374
('file', 'bazaar', 'DEFAULT', 'bazaar'),],
2377
def test_remove_in_bazaar(self):
2378
self.bazaar_config.remove_user_option('file')
2380
[('file', 'locations', self.tree.basedir, 'locations'),
2381
('file', 'branch', 'DEFAULT', 'branch'),],
2385
class TestConfigGetSections(tests.TestCaseWithTransport):
2388
super(TestConfigGetSections, self).setUp()
2389
create_configs(self)
2391
def assertSectionNames(self, expected, conf, name=None):
2392
"""Check which sections are returned for a given config.
2394
If fallback configurations exist their sections can be included.
2396
:param expected: A list of section names.
2398
:param conf: The configuration that will be queried.
2400
:param name: An optional section name that will be passed to
2403
sections = list(conf._get_sections(name))
2404
self.assertLength(len(expected), sections)
2405
self.assertEqual(expected, [name for name, _, _ in sections])
2407
def test_bazaar_default_section(self):
2408
self.assertSectionNames(['DEFAULT'], self.bazaar_config)
2410
def test_locations_default_section(self):
2411
# No sections are defined in an empty file
2412
self.assertSectionNames([], self.locations_config)
2414
def test_locations_named_section(self):
2415
self.locations_config.set_user_option('file', 'locations')
2416
self.assertSectionNames([self.tree.basedir], self.locations_config)
2418
def test_locations_matching_sections(self):
2419
loc_config = self.locations_config
2420
loc_config.set_user_option('file', 'locations')
2421
# We need to cheat a bit here to create an option in sections above and
2422
# below the 'location' one.
2423
parser = loc_config._get_parser()
2424
# locations.cong deals with '/' ignoring native os.sep
2425
location_names = self.tree.basedir.split('/')
2426
parent = '/'.join(location_names[:-1])
2427
child = '/'.join(location_names + ['child'])
2429
parser[parent]['file'] = 'parent'
2431
parser[child]['file'] = 'child'
2432
self.assertSectionNames([self.tree.basedir, parent], loc_config)
2434
def test_branch_data_default_section(self):
2435
self.assertSectionNames([None],
2436
self.branch_config._get_branch_data_config())
2438
def test_branch_default_sections(self):
2439
# No sections are defined in an empty locations file
2440
self.assertSectionNames([None, 'DEFAULT'],
2442
# Unless we define an option
2443
self.branch_config._get_location_config().set_user_option(
2444
'file', 'locations')
2445
self.assertSectionNames([self.tree.basedir, None, 'DEFAULT'],
2448
def test_bazaar_named_section(self):
2449
# We need to cheat as the API doesn't give direct access to sections
2450
# other than DEFAULT.
2451
self.bazaar_config.set_alias('bazaar', 'bzr')
2452
self.assertSectionNames(['ALIASES'], self.bazaar_config, 'ALIASES')
2455
1474
class TestAuthenticationConfigFile(tests.TestCase):
2456
1475
"""Test the authentication.conf file matching"""