5 from test
import test_support
8 class TestCaseBase(unittest
.TestCase
):
9 def newconfig(self
, defaults
=None):
11 self
.cf
= self
.config_class()
13 self
.cf
= self
.config_class(defaults
)
16 def fromstring(self
, string
, defaults
=None):
17 cf
= self
.newconfig(defaults
)
18 sio
= StringIO
.StringIO(string
)
29 "foo: bar ; comment\n"
31 "foo: this line is much, much longer than my editor\n"
33 "[Section\\with$weird%characters[\t]\n"
34 "[Internationalized Stuff]\n"
35 "foo[bg]: Bulgarian\n"
40 "key with spaces : value\n"
41 "another with spaces = splat!\n"
46 eq(L
, [r
'Commented Bar',
48 r
'Internationalized Stuff',
50 r
'Section\with$weird%characters[' '\t',
55 # The use of spaces in the section names serves as a
56 # regression test for SourceForge bug #583248:
57 # http://www.python.org/sf/583248
58 eq(cf
.get('Foo Bar', 'foo'), 'bar')
59 eq(cf
.get('Spacey Bar', 'foo'), 'bar')
60 eq(cf
.get('Commented Bar', 'foo'), 'bar')
61 eq(cf
.get('Spaces', 'key with spaces'), 'value')
62 eq(cf
.get('Spaces', 'another with spaces'), 'splat!')
64 self
.failIf('__name__' in cf
.options("Foo Bar"),
65 '__name__ "option" should not be exposed by the API!')
67 # Make sure the right things happen for remove_option();
68 # added to include check for SourceForge bug #123324:
69 self
.failUnless(cf
.remove_option('Foo Bar', 'foo'),
70 "remove_option() failed to report existance of option")
71 self
.failIf(cf
.has_option('Foo Bar', 'foo'),
72 "remove_option() failed to remove option")
73 self
.failIf(cf
.remove_option('Foo Bar', 'foo'),
74 "remove_option() failed to report non-existance of option"
77 self
.assertRaises(ConfigParser
.NoSectionError
,
78 cf
.remove_option
, 'No Such Section', 'foo')
80 eq(cf
.get('Long Line', 'foo'),
81 'this line is much, much longer than my editor\nlikes it.')
83 def test_case_sensitivity(self
):
91 cf
.set("a", "B", "value")
92 eq(cf
.options("a"), ["b"])
93 eq(cf
.get("a", "b"), "value",
94 "could not locate option, expecting case-insensitive option names")
95 self
.failUnless(cf
.has_option("a", "b"))
96 cf
.set("A", "A-B", "A-B value")
97 for opt
in ("a-b", "A-b", "a-B", "A-B"):
99 cf
.has_option("A", opt
),
100 "has_option() returned false for option which should exist")
101 eq(cf
.options("A"), ["a-b"])
102 eq(cf
.options("a"), ["b"])
103 cf
.remove_option("a", "B")
104 eq(cf
.options("a"), [])
107 cf
= self
.fromstring(
108 "[MySection]\nOption: first line\n\tsecond line\n")
109 eq(cf
.options("MySection"), ["option"])
110 eq(cf
.get("MySection", "Option"), "first line\nsecond line")
113 cf
= self
.fromstring("[section]\nnekey=nevalue\n",
114 defaults
={"key":"value"})
115 self
.failUnless(cf
.has_option("section", "Key"))
118 def test_parse_errors(self
):
120 self
.parse_error(ConfigParser
.ParsingError
,
121 "[Foo]\n extra-spaces: splat\n")
122 self
.parse_error(ConfigParser
.ParsingError
,
123 "[Foo]\n extra-spaces= splat\n")
124 self
.parse_error(ConfigParser
.ParsingError
,
125 "[Foo]\noption-without-value\n")
126 self
.parse_error(ConfigParser
.ParsingError
,
127 "[Foo]\n:value-without-option-name\n")
128 self
.parse_error(ConfigParser
.ParsingError
,
129 "[Foo]\n=value-without-option-name\n")
130 self
.parse_error(ConfigParser
.MissingSectionHeaderError
,
133 def parse_error(self
, exc
, src
):
134 sio
= StringIO
.StringIO(src
)
135 self
.assertRaises(exc
, self
.cf
.readfp
, sio
)
137 def test_query_errors(self
):
138 cf
= self
.newconfig()
139 self
.assertEqual(cf
.sections(), [],
140 "new ConfigParser should have no defined sections")
141 self
.failIf(cf
.has_section("Foo"),
142 "new ConfigParser should have no acknowledged sections")
143 self
.assertRaises(ConfigParser
.NoSectionError
,
145 self
.assertRaises(ConfigParser
.NoSectionError
,
146 cf
.set, "foo", "bar", "value")
147 self
.get_error(ConfigParser
.NoSectionError
, "foo", "bar")
148 cf
.add_section("foo")
149 self
.get_error(ConfigParser
.NoOptionError
, "foo", "bar")
151 def get_error(self
, exc
, section
, option
):
153 self
.cf
.get(section
, option
)
157 self
.fail("expected exception type %s.%s"
158 % (exc
.__module
__, exc
.__name
__))
160 def test_boolean(self
):
161 cf
= self
.fromstring(
179 for x
in range(1, 5):
180 self
.failUnless(cf
.getboolean('BOOLTEST', 't%d' % x
))
181 self
.failIf(cf
.getboolean('BOOLTEST', 'f%d' % x
))
182 self
.assertRaises(ValueError,
183 cf
.getboolean
, 'BOOLTEST', 'e%d' % x
)
185 def test_weird_errors(self
):
186 cf
= self
.newconfig()
187 cf
.add_section("Foo")
188 self
.assertRaises(ConfigParser
.DuplicateSectionError
,
189 cf
.add_section
, "Foo")
191 def test_write(self
):
192 cf
= self
.fromstring(
194 "foo: this line is much, much longer than my editor\n"
197 "foo: another very\n"
200 output
= StringIO
.StringIO()
205 "foo = another very\n"
209 "foo = this line is much, much longer than my editor\n"
214 # shared by subclasses
215 def get_interpolation_config(self
):
216 return self
.fromstring(
218 "bar=something %(with1)s interpolation (1 step)\n"
219 "bar9=something %(with9)s lots of interpolation (9 steps)\n"
220 "bar10=something %(with10)s lots of interpolation (10 steps)\n"
221 "bar11=something %(with11)s lots of interpolation (11 steps)\n"
222 "with11=%(with10)s\n"
234 "[Mutual Recursion]\n"
238 "[Interpolation Error]\n"
239 "name=%(reference)s\n",
240 # no definition for 'reference'
241 defaults
={"getname": "%(__name__)s"})
243 def check_items_config(self
, expected
):
244 cf
= self
.fromstring(
248 "getdefault: |%(default)s|\n"
249 "getname: |%(__name__)s|",
250 defaults
={"default": "<default>"})
251 L
= list(cf
.items("section"))
253 self
.assertEqual(L
, expected
)
256 class ConfigParserTestCase(TestCaseBase
):
257 config_class
= ConfigParser
.ConfigParser
259 def test_interpolation(self
):
260 cf
= self
.get_interpolation_config()
261 eq
= self
.assertEqual
262 eq(cf
.get("Foo", "getname"), "Foo")
263 eq(cf
.get("Foo", "bar"), "something with interpolation (1 step)")
264 eq(cf
.get("Foo", "bar9"),
265 "something with lots of interpolation (9 steps)")
266 eq(cf
.get("Foo", "bar10"),
267 "something with lots of interpolation (10 steps)")
268 self
.get_error(ConfigParser
.InterpolationDepthError
, "Foo", "bar11")
270 def test_interpolation_missing_value(self
):
271 cf
= self
.get_interpolation_config()
272 e
= self
.get_error(ConfigParser
.InterpolationError
,
273 "Interpolation Error", "name")
274 self
.assertEqual(e
.reference
, "reference")
275 self
.assertEqual(e
.section
, "Interpolation Error")
276 self
.assertEqual(e
.option
, "name")
278 def test_items(self
):
279 self
.check_items_config([('default', '<default>'),
280 ('getdefault', '|<default>|'),
281 ('getname', '|section|'),
286 class RawConfigParserTestCase(TestCaseBase
):
287 config_class
= ConfigParser
.RawConfigParser
289 def test_interpolation(self
):
290 cf
= self
.get_interpolation_config()
291 eq
= self
.assertEqual
292 eq(cf
.get("Foo", "getname"), "%(__name__)s")
293 eq(cf
.get("Foo", "bar"),
294 "something %(with1)s interpolation (1 step)")
295 eq(cf
.get("Foo", "bar9"),
296 "something %(with9)s lots of interpolation (9 steps)")
297 eq(cf
.get("Foo", "bar10"),
298 "something %(with10)s lots of interpolation (10 steps)")
299 eq(cf
.get("Foo", "bar11"),
300 "something %(with11)s lots of interpolation (11 steps)")
302 def test_items(self
):
303 self
.check_items_config([('default', '<default>'),
304 ('getdefault', '|%(default)s|'),
305 ('getname', '|%(__name__)s|'),
306 ('key', '|%(name)s|'),
310 class SafeConfigParserTestCase(ConfigParserTestCase
):
311 config_class
= ConfigParser
.SafeConfigParser
313 def test_safe_interpolation(self
):
314 # See http://www.python.org/sf/511737
315 cf
= self
.fromstring("[section]\n"
317 "option2=%(option1)s/xxx\n"
318 "ok=%(option1)s/%%s\n"
319 "not_ok=%(option2)s/%%s")
320 self
.assertEqual(cf
.get("section", "ok"), "xxx/%s")
321 self
.assertEqual(cf
.get("section", "not_ok"), "xxx/xxx/%s")
325 suite
= unittest
.TestSuite()
326 suite
.addTests([unittest
.makeSuite(ConfigParserTestCase
),
327 unittest
.makeSuite(RawConfigParserTestCase
),
328 unittest
.makeSuite(SafeConfigParserTestCase
)])
329 test_support
.run_suite(suite
)
331 if __name__
== "__main__":