فهرست منبع

Improved messaging for simple type validator

English language is a tricky old thing and I've pulled out the validator type
parsing so that we can prefix our validator types with the correct article,
'an' or 'a'.

Doing a bit of extra hard work to ensure the error message is clear and
well constructed english.

Signed-off-by: Mazz Mosley <[email protected]>
Mazz Mosley 10 سال پیش
والد
کامیت
418ec5336b
2فایلهای تغییر یافته به همراه50 افزوده شده و 6 حذف شده
  1. 35 6
      compose/config/validation.py
  2. 15 0
      tests/unit/config_test.py

+ 35 - 6
compose/config/validation.py

@@ -117,6 +117,38 @@ def process_errors(errors, service_name=None):
         else:
             return str(schema['type'])
 
+    def _parse_valid_types_from_validator(validator):
+        """
+        A validator value can be either an array of valid types or a string of
+        a valid type. Parse the valid types and prefix with the correct article.
+        """
+        pre_msg_type_prefix = "a"
+        last_msg_type_prefix = "a"
+        types_requiring_an = ["array", "object"]
+
+        if isinstance(validator, list):
+            last_type = validator.pop()
+            types_from_validator = ", ".join(validator)
+
+            if validator[0] in types_requiring_an:
+                pre_msg_type_prefix = "an"
+
+            if last_type in types_requiring_an:
+                last_msg_type_prefix = "an"
+
+            msg = "{} {} or {} {}".format(
+                pre_msg_type_prefix,
+                types_from_validator,
+                last_msg_type_prefix,
+                last_type
+            )
+        else:
+            if validator in types_requiring_an:
+                pre_msg_type_prefix = "an"
+            msg = "{} {}".format(pre_msg_type_prefix, validator)
+
+        return msg
+
     root_msgs = []
     invalid_keys = []
     required = []
@@ -176,19 +208,16 @@ def process_errors(errors, service_name=None):
                     service_name, config_key, valid_type_msg)
                 )
             elif error.validator == 'type':
-                msg = "a"
-                if error.validator_value == "array":
-                    msg = "an"
+                msg = _parse_valid_types_from_validator(error.validator_value)
 
                 if len(error.path) > 0:
                     config_key = " ".join(["'%s'" % k for k in error.path])
                     type_errors.append(
                         "Service '{}' configuration key {} contains an invalid "
-                        "type, it should be {} {}".format(
+                        "type, it should be {}".format(
                             service_name,
                             config_key,
-                            msg,
-                            error.validator_value))
+                            msg))
                 else:
                     root_msgs.append(
                         "Service '{}' doesn\'t have any configuration options. "

+ 15 - 0
tests/unit/config_test.py

@@ -269,6 +269,21 @@ class ConfigTest(unittest.TestCase):
             )
             self.assertEqual(service[0]['entrypoint'], entrypoint)
 
+    def test_validation_message_for_invalid_type_when_multiple_types_allowed(self):
+        expected_error_msg = "Service 'web' configuration key 'mem_limit' contains an invalid type, it should be a number or a string"
+
+        with self.assertRaisesRegexp(ConfigurationError, expected_error_msg):
+            config.load(
+                config.ConfigDetails(
+                    {'web': {
+                        'image': 'busybox',
+                        'mem_limit': ['incorrect']
+                    }},
+                    'working_dir',
+                    'filename.yml'
+                )
+            )
+
 
 class InterpolationTest(unittest.TestCase):
     @mock.patch.dict(os.environ)