python-2.5.2/win32/Lib/test/test_cfgparser.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 import ConfigParser
       
     2 import StringIO
       
     3 import unittest
       
     4 
       
     5 from test import test_support
       
     6 
       
     7 
       
     8 class TestCaseBase(unittest.TestCase):
       
     9     def newconfig(self, defaults=None):
       
    10         if defaults is None:
       
    11             self.cf = self.config_class()
       
    12         else:
       
    13             self.cf = self.config_class(defaults)
       
    14         return self.cf
       
    15 
       
    16     def fromstring(self, string, defaults=None):
       
    17         cf = self.newconfig(defaults)
       
    18         sio = StringIO.StringIO(string)
       
    19         cf.readfp(sio)
       
    20         return cf
       
    21 
       
    22     def test_basic(self):
       
    23         cf = self.fromstring(
       
    24             "[Foo Bar]\n"
       
    25             "foo=bar\n"
       
    26             "[Spacey Bar]\n"
       
    27             "foo = bar\n"
       
    28             "[Commented Bar]\n"
       
    29             "foo: bar ; comment\n"
       
    30             "[Long Line]\n"
       
    31             "foo: this line is much, much longer than my editor\n"
       
    32             "   likes it.\n"
       
    33             "[Section\\with$weird%characters[\t]\n"
       
    34             "[Internationalized Stuff]\n"
       
    35             "foo[bg]: Bulgarian\n"
       
    36             "foo=Default\n"
       
    37             "foo[en]=English\n"
       
    38             "foo[de]=Deutsch\n"
       
    39             "[Spaces]\n"
       
    40             "key with spaces : value\n"
       
    41             "another with spaces = splat!\n"
       
    42             )
       
    43         L = cf.sections()
       
    44         L.sort()
       
    45         eq = self.assertEqual
       
    46         eq(L, [r'Commented Bar',
       
    47                r'Foo Bar',
       
    48                r'Internationalized Stuff',
       
    49                r'Long Line',
       
    50                r'Section\with$weird%characters[' '\t',
       
    51                r'Spaces',
       
    52                r'Spacey Bar',
       
    53                ])
       
    54 
       
    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!')
       
    63 
       
    64         self.failIf('__name__' in cf.options("Foo Bar"),
       
    65                     '__name__ "option" should not be exposed by the API!')
       
    66 
       
    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"
       
    75                     " that was removed")
       
    76 
       
    77         self.assertRaises(ConfigParser.NoSectionError,
       
    78                           cf.remove_option, 'No Such Section', 'foo')
       
    79 
       
    80         eq(cf.get('Long Line', 'foo'),
       
    81            'this line is much, much longer than my editor\nlikes it.')
       
    82 
       
    83     def test_case_sensitivity(self):
       
    84         cf = self.newconfig()
       
    85         cf.add_section("A")
       
    86         cf.add_section("a")
       
    87         L = cf.sections()
       
    88         L.sort()
       
    89         eq = self.assertEqual
       
    90         eq(L, ["A", "a"])
       
    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"):
       
    98             self.failUnless(
       
    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"), [])
       
   105 
       
   106         # SF bug #432369:
       
   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")
       
   111 
       
   112         # SF bug #561822:
       
   113         cf = self.fromstring("[section]\nnekey=nevalue\n",
       
   114                              defaults={"key":"value"})
       
   115         self.failUnless(cf.has_option("section", "Key"))
       
   116 
       
   117 
       
   118     def test_default_case_sensitivity(self):
       
   119         cf = self.newconfig({"foo": "Bar"})
       
   120         self.assertEqual(
       
   121             cf.get("DEFAULT", "Foo"), "Bar",
       
   122             "could not locate option, expecting case-insensitive option names")
       
   123         cf = self.newconfig({"Foo": "Bar"})
       
   124         self.assertEqual(
       
   125             cf.get("DEFAULT", "Foo"), "Bar",
       
   126             "could not locate option, expecting case-insensitive defaults")
       
   127 
       
   128     def test_parse_errors(self):
       
   129         self.newconfig()
       
   130         self.parse_error(ConfigParser.ParsingError,
       
   131                          "[Foo]\n  extra-spaces: splat\n")
       
   132         self.parse_error(ConfigParser.ParsingError,
       
   133                          "[Foo]\n  extra-spaces= splat\n")
       
   134         self.parse_error(ConfigParser.ParsingError,
       
   135                          "[Foo]\noption-without-value\n")
       
   136         self.parse_error(ConfigParser.ParsingError,
       
   137                          "[Foo]\n:value-without-option-name\n")
       
   138         self.parse_error(ConfigParser.ParsingError,
       
   139                          "[Foo]\n=value-without-option-name\n")
       
   140         self.parse_error(ConfigParser.MissingSectionHeaderError,
       
   141                          "No Section!\n")
       
   142 
       
   143     def parse_error(self, exc, src):
       
   144         sio = StringIO.StringIO(src)
       
   145         self.assertRaises(exc, self.cf.readfp, sio)
       
   146 
       
   147     def test_query_errors(self):
       
   148         cf = self.newconfig()
       
   149         self.assertEqual(cf.sections(), [],
       
   150                          "new ConfigParser should have no defined sections")
       
   151         self.failIf(cf.has_section("Foo"),
       
   152                     "new ConfigParser should have no acknowledged sections")
       
   153         self.assertRaises(ConfigParser.NoSectionError,
       
   154                           cf.options, "Foo")
       
   155         self.assertRaises(ConfigParser.NoSectionError,
       
   156                           cf.set, "foo", "bar", "value")
       
   157         self.get_error(ConfigParser.NoSectionError, "foo", "bar")
       
   158         cf.add_section("foo")
       
   159         self.get_error(ConfigParser.NoOptionError, "foo", "bar")
       
   160 
       
   161     def get_error(self, exc, section, option):
       
   162         try:
       
   163             self.cf.get(section, option)
       
   164         except exc, e:
       
   165             return e
       
   166         else:
       
   167             self.fail("expected exception type %s.%s"
       
   168                       % (exc.__module__, exc.__name__))
       
   169 
       
   170     def test_boolean(self):
       
   171         cf = self.fromstring(
       
   172             "[BOOLTEST]\n"
       
   173             "T1=1\n"
       
   174             "T2=TRUE\n"
       
   175             "T3=True\n"
       
   176             "T4=oN\n"
       
   177             "T5=yes\n"
       
   178             "F1=0\n"
       
   179             "F2=FALSE\n"
       
   180             "F3=False\n"
       
   181             "F4=oFF\n"
       
   182             "F5=nO\n"
       
   183             "E1=2\n"
       
   184             "E2=foo\n"
       
   185             "E3=-1\n"
       
   186             "E4=0.1\n"
       
   187             "E5=FALSE AND MORE"
       
   188             )
       
   189         for x in range(1, 5):
       
   190             self.failUnless(cf.getboolean('BOOLTEST', 't%d' % x))
       
   191             self.failIf(cf.getboolean('BOOLTEST', 'f%d' % x))
       
   192             self.assertRaises(ValueError,
       
   193                               cf.getboolean, 'BOOLTEST', 'e%d' % x)
       
   194 
       
   195     def test_weird_errors(self):
       
   196         cf = self.newconfig()
       
   197         cf.add_section("Foo")
       
   198         self.assertRaises(ConfigParser.DuplicateSectionError,
       
   199                           cf.add_section, "Foo")
       
   200 
       
   201     def test_write(self):
       
   202         cf = self.fromstring(
       
   203             "[Long Line]\n"
       
   204             "foo: this line is much, much longer than my editor\n"
       
   205             "   likes it.\n"
       
   206             "[DEFAULT]\n"
       
   207             "foo: another very\n"
       
   208             " long line"
       
   209             )
       
   210         output = StringIO.StringIO()
       
   211         cf.write(output)
       
   212         self.assertEqual(
       
   213             output.getvalue(),
       
   214             "[DEFAULT]\n"
       
   215             "foo = another very\n"
       
   216             "\tlong line\n"
       
   217             "\n"
       
   218             "[Long Line]\n"
       
   219             "foo = this line is much, much longer than my editor\n"
       
   220             "\tlikes it.\n"
       
   221             "\n"
       
   222             )
       
   223 
       
   224     def test_set_string_types(self):
       
   225         cf = self.fromstring("[sect]\n"
       
   226                              "option1=foo\n")
       
   227         # Check that we don't get an exception when setting values in
       
   228         # an existing section using strings:
       
   229         class mystr(str):
       
   230             pass
       
   231         cf.set("sect", "option1", "splat")
       
   232         cf.set("sect", "option1", mystr("splat"))
       
   233         cf.set("sect", "option2", "splat")
       
   234         cf.set("sect", "option2", mystr("splat"))
       
   235         try:
       
   236             unicode
       
   237         except NameError:
       
   238             pass
       
   239         else:
       
   240             cf.set("sect", "option1", unicode("splat"))
       
   241             cf.set("sect", "option2", unicode("splat"))
       
   242 
       
   243     def test_read_returns_file_list(self):
       
   244         file1 = test_support.findfile("cfgparser.1")
       
   245         # check when we pass a mix of readable and non-readable files:
       
   246         cf = self.newconfig()
       
   247         parsed_files = cf.read([file1, "nonexistant-file"])
       
   248         self.assertEqual(parsed_files, [file1])
       
   249         self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
       
   250         # check when we pass only a filename:
       
   251         cf = self.newconfig()
       
   252         parsed_files = cf.read(file1)
       
   253         self.assertEqual(parsed_files, [file1])
       
   254         self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
       
   255         # check when we pass only missing files:
       
   256         cf = self.newconfig()
       
   257         parsed_files = cf.read(["nonexistant-file"])
       
   258         self.assertEqual(parsed_files, [])
       
   259         # check when we pass no files:
       
   260         cf = self.newconfig()
       
   261         parsed_files = cf.read([])
       
   262         self.assertEqual(parsed_files, [])
       
   263 
       
   264     # shared by subclasses
       
   265     def get_interpolation_config(self):
       
   266         return self.fromstring(
       
   267             "[Foo]\n"
       
   268             "bar=something %(with1)s interpolation (1 step)\n"
       
   269             "bar9=something %(with9)s lots of interpolation (9 steps)\n"
       
   270             "bar10=something %(with10)s lots of interpolation (10 steps)\n"
       
   271             "bar11=something %(with11)s lots of interpolation (11 steps)\n"
       
   272             "with11=%(with10)s\n"
       
   273             "with10=%(with9)s\n"
       
   274             "with9=%(with8)s\n"
       
   275             "with8=%(With7)s\n"
       
   276             "with7=%(WITH6)s\n"
       
   277             "with6=%(with5)s\n"
       
   278             "With5=%(with4)s\n"
       
   279             "WITH4=%(with3)s\n"
       
   280             "with3=%(with2)s\n"
       
   281             "with2=%(with1)s\n"
       
   282             "with1=with\n"
       
   283             "\n"
       
   284             "[Mutual Recursion]\n"
       
   285             "foo=%(bar)s\n"
       
   286             "bar=%(foo)s\n"
       
   287             "\n"
       
   288             "[Interpolation Error]\n"
       
   289             "name=%(reference)s\n",
       
   290             # no definition for 'reference'
       
   291             defaults={"getname": "%(__name__)s"})
       
   292 
       
   293     def check_items_config(self, expected):
       
   294         cf = self.fromstring(
       
   295             "[section]\n"
       
   296             "name = value\n"
       
   297             "key: |%(name)s| \n"
       
   298             "getdefault: |%(default)s|\n"
       
   299             "getname: |%(__name__)s|",
       
   300             defaults={"default": "<default>"})
       
   301         L = list(cf.items("section"))
       
   302         L.sort()
       
   303         self.assertEqual(L, expected)
       
   304 
       
   305 
       
   306 class ConfigParserTestCase(TestCaseBase):
       
   307     config_class = ConfigParser.ConfigParser
       
   308 
       
   309     def test_interpolation(self):
       
   310         cf = self.get_interpolation_config()
       
   311         eq = self.assertEqual
       
   312         eq(cf.get("Foo", "getname"), "Foo")
       
   313         eq(cf.get("Foo", "bar"), "something with interpolation (1 step)")
       
   314         eq(cf.get("Foo", "bar9"),
       
   315            "something with lots of interpolation (9 steps)")
       
   316         eq(cf.get("Foo", "bar10"),
       
   317            "something with lots of interpolation (10 steps)")
       
   318         self.get_error(ConfigParser.InterpolationDepthError, "Foo", "bar11")
       
   319 
       
   320     def test_interpolation_missing_value(self):
       
   321         cf = self.get_interpolation_config()
       
   322         e = self.get_error(ConfigParser.InterpolationError,
       
   323                            "Interpolation Error", "name")
       
   324         self.assertEqual(e.reference, "reference")
       
   325         self.assertEqual(e.section, "Interpolation Error")
       
   326         self.assertEqual(e.option, "name")
       
   327 
       
   328     def test_items(self):
       
   329         self.check_items_config([('default', '<default>'),
       
   330                                  ('getdefault', '|<default>|'),
       
   331                                  ('getname', '|section|'),
       
   332                                  ('key', '|value|'),
       
   333                                  ('name', 'value')])
       
   334 
       
   335     def test_set_nonstring_types(self):
       
   336         cf = self.newconfig()
       
   337         cf.add_section('non-string')
       
   338         cf.set('non-string', 'int', 1)
       
   339         cf.set('non-string', 'list', [0, 1, 1, 2, 3, 5, 8, 13, '%('])
       
   340         cf.set('non-string', 'dict', {'pi': 3.14159, '%(': 1,
       
   341                                       '%(list)': '%(list)'})
       
   342         cf.set('non-string', 'string_with_interpolation', '%(list)s')
       
   343         self.assertEqual(cf.get('non-string', 'int', raw=True), 1)
       
   344         self.assertRaises(TypeError, cf.get, 'non-string', 'int')
       
   345         self.assertEqual(cf.get('non-string', 'list', raw=True),
       
   346                          [0, 1, 1, 2, 3, 5, 8, 13, '%('])
       
   347         self.assertRaises(TypeError, cf.get, 'non-string', 'list')
       
   348         self.assertEqual(cf.get('non-string', 'dict', raw=True),
       
   349                          {'pi': 3.14159, '%(': 1, '%(list)': '%(list)'})
       
   350         self.assertRaises(TypeError, cf.get, 'non-string', 'dict')
       
   351         self.assertEqual(cf.get('non-string', 'string_with_interpolation',
       
   352                                 raw=True), '%(list)s')
       
   353         self.assertRaises(ValueError, cf.get, 'non-string',
       
   354                           'string_with_interpolation', raw=False)
       
   355 
       
   356 
       
   357 class RawConfigParserTestCase(TestCaseBase):
       
   358     config_class = ConfigParser.RawConfigParser
       
   359 
       
   360     def test_interpolation(self):
       
   361         cf = self.get_interpolation_config()
       
   362         eq = self.assertEqual
       
   363         eq(cf.get("Foo", "getname"), "%(__name__)s")
       
   364         eq(cf.get("Foo", "bar"),
       
   365            "something %(with1)s interpolation (1 step)")
       
   366         eq(cf.get("Foo", "bar9"),
       
   367            "something %(with9)s lots of interpolation (9 steps)")
       
   368         eq(cf.get("Foo", "bar10"),
       
   369            "something %(with10)s lots of interpolation (10 steps)")
       
   370         eq(cf.get("Foo", "bar11"),
       
   371            "something %(with11)s lots of interpolation (11 steps)")
       
   372 
       
   373     def test_items(self):
       
   374         self.check_items_config([('default', '<default>'),
       
   375                                  ('getdefault', '|%(default)s|'),
       
   376                                  ('getname', '|%(__name__)s|'),
       
   377                                  ('key', '|%(name)s|'),
       
   378                                  ('name', 'value')])
       
   379 
       
   380     def test_set_nonstring_types(self):
       
   381         cf = self.newconfig()
       
   382         cf.add_section('non-string')
       
   383         cf.set('non-string', 'int', 1)
       
   384         cf.set('non-string', 'list', [0, 1, 1, 2, 3, 5, 8, 13])
       
   385         cf.set('non-string', 'dict', {'pi': 3.14159})
       
   386         self.assertEqual(cf.get('non-string', 'int'), 1)
       
   387         self.assertEqual(cf.get('non-string', 'list'),
       
   388                          [0, 1, 1, 2, 3, 5, 8, 13])
       
   389         self.assertEqual(cf.get('non-string', 'dict'), {'pi': 3.14159})
       
   390 
       
   391 
       
   392 class SafeConfigParserTestCase(ConfigParserTestCase):
       
   393     config_class = ConfigParser.SafeConfigParser
       
   394 
       
   395     def test_safe_interpolation(self):
       
   396         # See http://www.python.org/sf/511737
       
   397         cf = self.fromstring("[section]\n"
       
   398                              "option1=xxx\n"
       
   399                              "option2=%(option1)s/xxx\n"
       
   400                              "ok=%(option1)s/%%s\n"
       
   401                              "not_ok=%(option2)s/%%s")
       
   402         self.assertEqual(cf.get("section", "ok"), "xxx/%s")
       
   403         self.assertEqual(cf.get("section", "not_ok"), "xxx/xxx/%s")
       
   404 
       
   405     def test_set_nonstring_types(self):
       
   406         cf = self.fromstring("[sect]\n"
       
   407                              "option1=foo\n")
       
   408         # Check that we get a TypeError when setting non-string values
       
   409         # in an existing section:
       
   410         self.assertRaises(TypeError, cf.set, "sect", "option1", 1)
       
   411         self.assertRaises(TypeError, cf.set, "sect", "option1", 1.0)
       
   412         self.assertRaises(TypeError, cf.set, "sect", "option1", object())
       
   413         self.assertRaises(TypeError, cf.set, "sect", "option2", 1)
       
   414         self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0)
       
   415         self.assertRaises(TypeError, cf.set, "sect", "option2", object())
       
   416 
       
   417 
       
   418 def test_main():
       
   419     test_support.run_unittest(
       
   420         ConfigParserTestCase,
       
   421         RawConfigParserTestCase,
       
   422         SafeConfigParserTestCase
       
   423     )
       
   424 
       
   425 if __name__ == "__main__":
       
   426     test_main()