Rev 6092: Add convert_from_unicode to Option and rewrite the tests to need only an in file:///home/vila/src/bzr/experimental/convert-default-values/

Vincent Ladeuil v.ladeuil+lp at free.fr
Mon Aug 22 11:56:35 UTC 2011


At file:///home/vila/src/bzr/experimental/convert-default-values/

------------------------------------------------------------
revno: 6092
revision-id: v.ladeuil+lp at free.fr-20110822115634-mk8qf81cnqpb1n7y
parent: pqm at pqm.ubuntu.com-20110821172104-y77ef15d94kom6hl
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: convert-default-values
timestamp: Mon 2011-08-22 13:56:34 +0200
message:
  Add convert_from_unicode to Option and rewrite the tests to need only an
  Option object.
-------------- next part --------------
=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py	2011-08-21 15:14:57 +0000
+++ b/bzrlib/config.py	2011-08-22 11:56:34 +0000
@@ -2352,6 +2352,24 @@
             raise AssertionError("%s not supported for 'invalid'" % (invalid,))
         self.invalid = invalid
 
+    def convert_from_unicode(self, unicode_value):
+        if self.from_unicode is None or unicode_value is None:
+            # Cannot convert
+            return unicode_value
+        try:
+            converted = self.from_unicode(unicode_value)
+        except (ValueError, TypeError):
+            # Invalid values are ignored
+            converted = None
+        if converted is None and self.invalid is not None:
+            # The conversion failed
+            if self.invalid == 'warning':
+                trace.warning('Value "%s" is not valid for "%s"',
+                              unicode_value, self.name)
+            elif self.invalid == 'error':
+                raise errors.ConfigOptionValueError(self.name, unicode_value)
+        return converted
+
     def get_default(self):
         for var in self.default_from_env:
             try:
@@ -2969,22 +2987,8 @@
         except KeyError:
             # Not registered
             opt = None
-        if (opt is not None and opt.from_unicode is not None
-            and value is not None):
-            # If a value exists and the option provides a converter, use it
-            try:
-                converted = opt.from_unicode(value)
-            except (ValueError, TypeError):
-                # Invalid values are ignored
-                converted = None
-            if converted is None and opt.invalid is not None:
-                # The conversion failed
-                if opt.invalid == 'warning':
-                    trace.warning('Value "%s" is not valid for "%s"',
-                                  value, name)
-                elif opt.invalid == 'error':
-                    raise errors.ConfigOptionValueError(name, value)
-            value = converted
+        if opt is not None:
+            value = opt.convert_from_unicode(value)
         if value is None:
             # If the option is registered, it may provide a default value
             if opt is not None:

=== modified file 'bzrlib/tests/test_config.py'
--- a/bzrlib/tests/test_config.py	2011-08-21 15:14:57 +0000
+++ b/bzrlib/tests/test_config.py	2011-08-22 11:56:34 +0000
@@ -2238,7 +2238,7 @@
         self.overrideEnv('FOO', 'quux')
         # Env variable provides a default taking over the option one
         self.assertEquals('quux', opt.get_default())
-        
+
     def test_first_default_value_from_env_wins(self):
         opt = config.Option('foo', default='bar',
                             default_from_env=['NO_VALUE', 'FOO', 'BAZ'])
@@ -2248,6 +2248,99 @@
         self.assertEquals('foo', opt.get_default())
 
 
+class TestOptionConverterMixin(object):
+
+    def assertConverted(self, expected, opt, value):
+        self.assertEquals(expected, opt.convert_from_unicode(value))
+
+    def assertWarns(self, opt, value):
+        warnings = []
+        def warning(*args):
+            warnings.append(args[0] % args[1:])
+        self.overrideAttr(trace, 'warning', warning)
+        self.assertEquals(None, opt.convert_from_unicode(value))
+        self.assertLength(1, warnings)
+        self.assertEquals(
+            'Value "%s" is not valid for "%s"' % (value, opt.name),
+            warnings[0])
+
+    def assertErrors(self, opt, value):
+        self.assertRaises(errors.ConfigOptionValueError,
+                          opt.convert_from_unicode, value)
+
+    def assertConvertInvalid(self, opt, invalid_value):
+        opt.invalid = None
+        self.assertEquals(None, opt.convert_from_unicode(invalid_value))
+        opt.invalid = 'warning'
+        self.assertWarns(opt, invalid_value)
+        opt.invalid = 'error'
+        self.assertErrors(opt, invalid_value)
+
+
+class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
+
+    def get_option(self):
+        return config.Option('foo', help='A boolean.',
+                             from_unicode=config.bool_from_store)
+
+    def test_convert_invalid(self):
+        opt = self.get_option()
+        # A string that is not recognized as a boolean
+        self.assertConvertInvalid(opt, u'invalid-boolean')
+        # A list of strings is never recognized as a boolean
+        self.assertConvertInvalid(opt, [u'not', u'a', u'boolean'])
+
+    def test_convert_valid(self):
+        opt = self.get_option()
+        self.assertConverted(True, opt, u'True')
+        self.assertConverted(True, opt, u'1')
+        self.assertConverted(False, opt, u'False')
+
+
+class TestOptionWithIntegerConverter(tests.TestCase, TestOptionConverterMixin):
+
+    def get_option(self):
+        return config.Option('foo', help='An integer.',
+                             from_unicode=config.int_from_store)
+
+    def test_convert_invalid(self):
+        opt = self.get_option()
+        # A string that is not recognized as an integer
+        self.assertConvertInvalid(opt, u'forty-two')
+        # A list of strings is never recognized as an integer
+        self.assertConvertInvalid(opt, [u'a', u'list'])
+
+    def test_convert_valid(self):
+        opt = self.get_option()
+        self.assertConverted(16, opt, u'16')
+
+class TestOptionWithListConverter(tests.TestCase, TestOptionConverterMixin):
+
+    def get_option(self):
+        return config.Option('foo', help='A list.',
+                             from_unicode=config.list_from_store)
+
+    def test_convert_invalid(self):
+        # No string is invalid as all forms can be converted to a list
+        pass
+
+    def test_convert_valid(self):
+        opt = self.get_option()
+        # An empty string is an empty list
+        self.assertConverted([], opt, '') # Using a bare str() just in case
+        self.assertConverted([], opt, u'')
+        # A boolean
+        self.assertConverted([u'True'], opt, u'True')
+        # An integer
+        self.assertConverted([u'42'], opt, u'42')
+        # A single string
+        self.assertConverted([u'bar'], opt, u'bar')
+        # A list remains a list (configObj will turn a string containing commas
+        # into a list, but that's not what we're testing here)
+        self.assertConverted([u'foo', u'1', u'True'],
+                             opt, [u'foo', u'1', u'True'])
+
+
 class TestOptionRegistry(tests.TestCase):
 
     def setUp(self):



More information about the bazaar-commits mailing list