blob: fa01627ef80b665b34f5cef37d563d0e76f76ccf [file] [log] [blame]
Fred Drake8ef67672000-09-27 22:45:25 +00001import ConfigParser
2import StringIO
3
Barry Warsaw408b6d32002-07-30 23:27:12 +00004from test.test_support import TestFailed, verify
Fred Drake3d5f7e82000-12-04 16:30:40 +00005
6
Fred Drake8ef67672000-09-27 22:45:25 +00007def basic(src):
Fred Drake8ef67672000-09-27 22:45:25 +00008 print "Testing basic accessors..."
9 cf = ConfigParser.ConfigParser()
10 sio = StringIO.StringIO(src)
11 cf.readfp(sio)
12 L = cf.sections()
13 L.sort()
Fred Drakecc1f9512001-02-14 15:30:31 +000014 verify(L == [r'Commented Bar',
15 r'Foo Bar',
16 r'Internationalized Stuff',
Andrew M. Kuchling1bf71172002-03-08 18:10:12 +000017 r'Long Line',
Fred Drakecc1f9512001-02-14 15:30:31 +000018 r'Section\with$weird%characters[' '\t',
Fred Drake176916a2002-09-27 16:21:18 +000019 r'Spaces',
Fred Drakecc1f9512001-02-14 15:30:31 +000020 r'Spacey Bar',
21 ],
Fred Drake95b96d32001-02-12 17:23:20 +000022 "unexpected list of section names")
Fred Drake8ef67672000-09-27 22:45:25 +000023
24 # The use of spaces in the section names serves as a regression test for
25 # SourceForge bug #115357.
Fred Drake8ef67672000-09-27 22:45:25 +000026 # http://sourceforge.net/bugs/?func=detailbug&group_id=5470&bug_id=115357
Fred Drake95b96d32001-02-12 17:23:20 +000027 verify(cf.get('Foo Bar', 'foo', raw=1) == 'bar')
28 verify(cf.get('Spacey Bar', 'foo', raw=1) == 'bar')
29 verify(cf.get('Commented Bar', 'foo', raw=1) == 'bar')
Fred Drake176916a2002-09-27 16:21:18 +000030 verify(cf.get('Spaces', 'key with spaces', raw=1) == 'value')
31 verify(cf.get('Spaces', 'another with spaces', raw=1) == 'splat!')
Fred Drake8ef67672000-09-27 22:45:25 +000032
Fred Drake95b96d32001-02-12 17:23:20 +000033 verify('__name__' not in cf.options("Foo Bar"),
34 '__name__ "option" should not be exposed by the API!')
Fred Drake8ef67672000-09-27 22:45:25 +000035
Fred Drake3d5f7e82000-12-04 16:30:40 +000036 # Make sure the right things happen for remove_option();
37 # added to include check for SourceForge bug #123324:
Fred Drake95b96d32001-02-12 17:23:20 +000038 verify(cf.remove_option('Foo Bar', 'foo'),
39 "remove_option() failed to report existance of option")
40 verify(not cf.has_option('Foo Bar', 'foo'),
41 "remove_option() failed to remove option")
42 verify(not cf.remove_option('Foo Bar', 'foo'),
43 "remove_option() failed to report non-existance of option"
44 " that was removed")
Fred Drake3d5f7e82000-12-04 16:30:40 +000045 try:
46 cf.remove_option('No Such Section', 'foo')
47 except ConfigParser.NoSectionError:
48 pass
49 else:
50 raise TestFailed(
51 "remove_option() failed to report non-existance of option"
52 " that never existed")
53
Andrew M. Kuchling1bf71172002-03-08 18:10:12 +000054 verify(cf.get('Long Line', 'foo', raw=1) ==
55 'this line is much, much longer than my editor\nlikes it.')
Fred Drake3d5f7e82000-12-04 16:30:40 +000056
Andrew M. Kuchling1bf71172002-03-08 18:10:12 +000057
Fred Drake3c823aa2001-02-26 21:55:34 +000058def case_sensitivity():
59 print "Testing case sensitivity..."
60 cf = ConfigParser.ConfigParser()
61 cf.add_section("A")
62 cf.add_section("a")
63 L = cf.sections()
64 L.sort()
65 verify(L == ["A", "a"])
66 cf.set("a", "B", "value")
67 verify(cf.options("a") == ["b"])
68 verify(cf.get("a", "b", raw=1) == "value",
69 "could not locate option, expecting case-insensitive option names")
70 verify(cf.has_option("a", "b"))
71 cf.set("A", "A-B", "A-B value")
72 for opt in ("a-b", "A-b", "a-B", "A-B"):
73 verify(cf.has_option("A", opt),
74 "has_option() returned false for option which should exist")
75 verify(cf.options("A") == ["a-b"])
76 verify(cf.options("a") == ["b"])
77 cf.remove_option("a", "B")
78 verify(cf.options("a") == [])
79
Fred Drakebeb67132001-07-06 17:22:48 +000080 # SF bug #432369:
81 cf = ConfigParser.ConfigParser()
82 sio = StringIO.StringIO("[MySection]\nOption: first line\n\tsecond line\n")
83 cf.readfp(sio)
84 verify(cf.options("MySection") == ["option"])
85 verify(cf.get("MySection", "Option") == "first line\nsecond line")
86
Fred Drake309db062002-09-27 15:35:23 +000087 # SF bug #561822:
88 cf = ConfigParser.ConfigParser(defaults={"key":"value"})
89 cf.readfp(StringIO.StringIO("[section]\nnekey=nevalue\n"))
90 verify(cf.has_option("section", "Key"))
91
Fred Drake3c823aa2001-02-26 21:55:34 +000092
Fred Drake168bead2001-10-08 17:13:12 +000093def boolean(src):
94 print "Testing interpretation of boolean Values..."
95 cf = ConfigParser.ConfigParser()
96 sio = StringIO.StringIO(src)
97 cf.readfp(sio)
98 for x in range(1, 5):
99 verify(cf.getboolean('BOOLTEST', 't%d' % (x)) == 1)
100 for x in range(1, 5):
101 verify(cf.getboolean('BOOLTEST', 'f%d' % (x)) == 0)
102 for x in range(1, 5):
103 try:
104 cf.getboolean('BOOLTEST', 'e%d' % (x))
105 except ValueError:
106 pass
107 else:
108 raise TestFailed(
109 "getboolean() failed to report a non boolean value")
110
111
Fred Drake8ef67672000-09-27 22:45:25 +0000112def interpolation(src):
Fred Drake8ef67672000-09-27 22:45:25 +0000113 print "Testing value interpolation..."
114 cf = ConfigParser.ConfigParser({"getname": "%(__name__)s"})
115 sio = StringIO.StringIO(src)
116 cf.readfp(sio)
Fred Drake95b96d32001-02-12 17:23:20 +0000117 verify(cf.get("Foo", "getname") == "Foo")
118 verify(cf.get("Foo", "bar") == "something with interpolation (1 step)")
119 verify(cf.get("Foo", "bar9")
120 == "something with lots of interpolation (9 steps)")
121 verify(cf.get("Foo", "bar10")
122 == "something with lots of interpolation (10 steps)")
Fred Drake8ef67672000-09-27 22:45:25 +0000123 expect_get_error(cf, ConfigParser.InterpolationDepthError, "Foo", "bar11")
124
Fred Drake3af0eb82002-10-25 18:09:24 +0000125 # Now make sure we don't interpolate if we use RawConfigParser:
126 cf = ConfigParser.RawConfigParser({"getname": "%(__name__)s"})
127 sio = StringIO.StringIO(src)
128 cf.readfp(sio)
129 verify(cf.get("Foo", "getname") == "%(__name__)s")
130 verify(cf.get("Foo", "bar")
131 == "something %(with1)s interpolation (1 step)")
132 verify(cf.get("Foo", "bar9")
133 == "something %(with9)s lots of interpolation (9 steps)")
134 verify(cf.get("Foo", "bar10")
135 == "something %(with10)s lots of interpolation (10 steps)")
136 verify(cf.get("Foo", "bar11")
137 == "something %(with11)s lots of interpolation (11 steps)")
138
Fred Drake95b96d32001-02-12 17:23:20 +0000139
Fred Drake8ef67672000-09-27 22:45:25 +0000140def parse_errors():
Fred Drake95b96d32001-02-12 17:23:20 +0000141 print "Testing parse errors..."
Fred Drake8ef67672000-09-27 22:45:25 +0000142 expect_parse_error(ConfigParser.ParsingError,
143 """[Foo]\n extra-spaces: splat\n""")
144 expect_parse_error(ConfigParser.ParsingError,
145 """[Foo]\n extra-spaces= splat\n""")
146 expect_parse_error(ConfigParser.ParsingError,
147 """[Foo]\noption-without-value\n""")
148 expect_parse_error(ConfigParser.ParsingError,
149 """[Foo]\n:value-without-option-name\n""")
150 expect_parse_error(ConfigParser.ParsingError,
151 """[Foo]\n=value-without-option-name\n""")
152 expect_parse_error(ConfigParser.MissingSectionHeaderError,
153 """No Section!\n""")
154
Fred Drake95b96d32001-02-12 17:23:20 +0000155
Fred Drake8ef67672000-09-27 22:45:25 +0000156def query_errors():
Fred Drake8ef67672000-09-27 22:45:25 +0000157 print "Testing query interface..."
158 cf = ConfigParser.ConfigParser()
Fred Drake95b96d32001-02-12 17:23:20 +0000159 verify(cf.sections() == [],
160 "new ConfigParser should have no defined sections")
161 verify(not cf.has_section("Foo"),
162 "new ConfigParser should have no acknowledged sections")
Fred Drake8ef67672000-09-27 22:45:25 +0000163 try:
164 cf.options("Foo")
165 except ConfigParser.NoSectionError, e:
Fred Drake95b96d32001-02-12 17:23:20 +0000166 pass
Fred Drake8ef67672000-09-27 22:45:25 +0000167 else:
Fred Drake95b96d32001-02-12 17:23:20 +0000168 raise TestFailed(
169 "Failed to catch expected NoSectionError from options()")
Fred Drake8ef67672000-09-27 22:45:25 +0000170 try:
171 cf.set("foo", "bar", "value")
172 except ConfigParser.NoSectionError, e:
Fred Drake95b96d32001-02-12 17:23:20 +0000173 pass
Fred Drake8ef67672000-09-27 22:45:25 +0000174 else:
Fred Drake95b96d32001-02-12 17:23:20 +0000175 raise TestFailed("Failed to catch expected NoSectionError from set()")
Fred Drake8ef67672000-09-27 22:45:25 +0000176 expect_get_error(cf, ConfigParser.NoSectionError, "foo", "bar")
177 cf.add_section("foo")
178 expect_get_error(cf, ConfigParser.NoOptionError, "foo", "bar")
179
Fred Drake95b96d32001-02-12 17:23:20 +0000180
Fred Drake8ef67672000-09-27 22:45:25 +0000181def weird_errors():
Fred Drake8ef67672000-09-27 22:45:25 +0000182 print "Testing miscellaneous error conditions..."
183 cf = ConfigParser.ConfigParser()
184 cf.add_section("Foo")
185 try:
186 cf.add_section("Foo")
187 except ConfigParser.DuplicateSectionError, e:
Fred Drake95b96d32001-02-12 17:23:20 +0000188 pass
Fred Drake8ef67672000-09-27 22:45:25 +0000189 else:
Fred Drake95b96d32001-02-12 17:23:20 +0000190 raise TestFailed("Failed to catch expected DuplicateSectionError")
191
Fred Drake8ef67672000-09-27 22:45:25 +0000192
193def expect_get_error(cf, exctype, section, option, raw=0):
194 try:
195 cf.get(section, option, raw=raw)
196 except exctype, e:
Fred Drake95b96d32001-02-12 17:23:20 +0000197 pass
Fred Drake8ef67672000-09-27 22:45:25 +0000198 else:
Fred Drake95b96d32001-02-12 17:23:20 +0000199 raise TestFailed("Failed to catch expected " + exctype.__name__)
200
Fred Drake8ef67672000-09-27 22:45:25 +0000201
202def expect_parse_error(exctype, src):
203 cf = ConfigParser.ConfigParser()
204 sio = StringIO.StringIO(src)
205 try:
206 cf.readfp(sio)
207 except exctype, e:
Fred Drake95b96d32001-02-12 17:23:20 +0000208 pass
Fred Drake8ef67672000-09-27 22:45:25 +0000209 else:
Fred Drake95b96d32001-02-12 17:23:20 +0000210 raise TestFailed("Failed to catch expected " + exctype.__name__)
211
Fred Drake8ef67672000-09-27 22:45:25 +0000212
Fred Drake3af0eb82002-10-25 18:09:24 +0000213# The long string literals present in the rest of the file screw up
214# font-lock in Emacs/XEmacs, so this stuff needs to stay near the end
215# of this file.
216
217def write(src):
218 print "Testing writing of files..."
219 cf = ConfigParser.ConfigParser()
220 sio = StringIO.StringIO(src)
221 cf.readfp(sio)
222 output = StringIO.StringIO()
223 cf.write(output)
224 verify(output, """[DEFAULT]
225foo = another very
226 long line
227
228[Long Line]
229foo = this line is much, much longer than my editor
230 likes it.
231""")
232
233
Fred Drake8ef67672000-09-27 22:45:25 +0000234basic(r"""
235[Foo Bar]
236foo=bar
237[Spacey Bar]
Fred Drake004d5e62000-10-23 17:22:08 +0000238foo = bar
Fred Drake8ef67672000-09-27 22:45:25 +0000239[Commented Bar]
240foo: bar ; comment
Andrew M. Kuchling1bf71172002-03-08 18:10:12 +0000241[Long Line]
242foo: this line is much, much longer than my editor
243 likes it.
Fred Drakecc1f9512001-02-14 15:30:31 +0000244[Section\with$weird%characters[""" '\t' r"""]
Fred Drake95b96d32001-02-12 17:23:20 +0000245[Internationalized Stuff]
246foo[bg]: Bulgarian
247foo=Default
248foo[en]=English
249foo[de]=Deutsch
Fred Drake176916a2002-09-27 16:21:18 +0000250[Spaces]
251key with spaces : value
252another with spaces = splat!
Fred Drake8ef67672000-09-27 22:45:25 +0000253""")
Andrew M. Kuchling1bf71172002-03-08 18:10:12 +0000254write("""[Long Line]
255foo: this line is much, much longer than my editor
256 likes it.
257[DEFAULT]
258foo: another very
259 long line""")
Fred Drake3c823aa2001-02-26 21:55:34 +0000260case_sensitivity()
Fred Drake168bead2001-10-08 17:13:12 +0000261boolean(r"""
262[BOOLTEST]
263T1=1
264T2=TRUE
265T3=True
266T4=oN
267T5=yes
268F1=0
269F2=FALSE
270F3=False
271F4=oFF
272F5=nO
273E1=2
274E2=foo
275E3=-1
276E4=0.1
277E5=FALSE AND MORE
278""")
Fred Drake8ef67672000-09-27 22:45:25 +0000279interpolation(r"""
280[Foo]
281bar=something %(with1)s interpolation (1 step)
282bar9=something %(with9)s lots of interpolation (9 steps)
283bar10=something %(with10)s lots of interpolation (10 steps)
284bar11=something %(with11)s lots of interpolation (11 steps)
285with11=%(with10)s
286with10=%(with9)s
287with9=%(with8)s
288with8=%(with7)s
289with7=%(with6)s
290with6=%(with5)s
291with5=%(with4)s
292with4=%(with3)s
293with3=%(with2)s
294with2=%(with1)s
295with1=with
296
297[Mutual Recursion]
298foo=%(bar)s
299bar=%(foo)s
300""")
301parse_errors()
302query_errors()
303weird_errors()