Example #1
0
def is_tutorial_default_message(default_message, languages=None):
    """Validates the specified set of default messages.

    Args:
        default_message (dict): A set of default messages.
        languages (list): A list of available languages.

    Returns:
        <bool, str|None>: A pair containing the value True if the specified message set
            is valid, False otherwise; and an error message in case the set is invalid.
    Raises:
        TypeError: If the default_message argument is not a dictionary, or if the
            languages argument is not a list or NoneType.
    """
    check_arg_type(is_tutorial_default_message, "default_message", default_message, dict)
    check_arg_type(is_tutorial_default_message, "languages", languages, (list, type(None)))

    unexpected_keys = find_unexpected_keys(default_message, is_tutorial_configuration.DEFAULT_MESSAGE_FIELDS)
    if unexpected_keys:
        message = "The tutorial's 'default-message' contains the following unrecognized fields: '{}'."
        return (False, message.format("', '".join(unexpected_keys)))

    for key, message in default_message.iteritems():
        if not is_configuration_string(message, languages):
            return (False, "The tutorial's default message field '{}' is invalid. A message must be a non-empty or normalized string.".format(key))

    return (True, None)
Example #2
0
def __is_multiple_option_input(question_input, languages=None):
    unexpected_keys = find_unexpected_keys(question_input, __is_multiple_option_input.FIELDS)
    if unexpected_keys:
        message = "The multiple-option input configuration contains the following unrecognized fields: '{}'."
        return (False, message.format("', '".join(unexpected_keys)))

    for key in ["enable-multiple-choices", "enable-other-option", "enable-illustrations"]:
        field = question_input.get(key)
        if field is not None and not isinstance(field, bool):
            return (False, "The '{}' field must be a boolean value.".format(key))

    options = question_input.get("options")
    if options is not None:
        enable_illustrations = question_input.get("enable-illustrations", False)
        if not isinstance(options, list) or len(options) < 1:
            return (False, "The 'options' field must be a non-empty list.")
        else:
            for option in options:
                label = option.get("label")
                error = (False, "An option label must be a non-empty or normalized string.")
                try:
                    if label is None or not is_configuration_string(label, languages):
                        return error
                except TypeError:
                    return error

                value = option.get("value")
                if value is None or not isinstance(value, basestring):
                    return (False, "An option value must be a string.")

                # If the 'enable-illustrations' flag is set to True, validate illustrations.
                illustration = option.get("illustration") if enable_illustrations else None
                if illustration is not None:
                    missing = [k for k in illustration.keys() if k not in __is_multiple_option_input.ILLUSTRATION_FIELDS or illustration[k] is None]
                    if missing:
                        missing = "', '".join(missing)
                        return (False, "The illustration is missing the following fields: '{}'.".format(missing))

                    for key in __is_multiple_option_input.ILLUSTRATION_FIELDS:
                        try:
                            field = illustration.get(key)
                            if is_empty_string(field):
                                return (False, "An illustration's '{}' field must be a non-empty string.".format(key))
                        except:
                            return (False, "An illustration's '{}' field must be a string.".format(key))
    else:
        return (False, "The 'options' field must be a non-empty list.")

    return (True, None)
Example #3
0
def __is_text_input(question_input, languages=None):
    """Validates the specified text input configuration.

    Args:
        question_input (dict): An input configuration to validate.
        languages (list): A list of languages that the normalized string dictionary must contain,
            where each item of the list is a language code.

    Returns:
        <bool, str|None>: A pair containing the value True if the specified configuration
            is valid, False otherwise; as well as an error message in case it is invalid.
    """
    unexpected_keys = find_unexpected_keys(question_input, __is_text_input.FIELDS)
    if unexpected_keys:
        message = "The text input configuration contains the following unrecognized fields: '{}'."
        return (False, message.format("', '".join(unexpected_keys)))

    placeholder = question_input.get("placeholder")
    if placeholder is not None:
        error = (False, "A placeholder must be a non-empty or normalized string.")
        try:
            if not is_configuration_string(placeholder, languages):
                return error
        except TypeError:
            return error

    enable_long_text = question_input.get("enable-long-text")
    if enable_long_text is not None and not isinstance(enable_long_text, bool):
        return (False, "The 'enable-long-text' field must be a boolean value.")

    min_length = question_input.get("min-length")
    if min_length is not None:
        if not isinstance(min_length, int):
            return (False, "The 'min-length' field must be an integer value.")
        elif min_length < 0:
            return (False, "The 'min-length' must be a positive integer.")

    max_length = question_input.get("max-length")
    if max_length is not None:
        if not isinstance(max_length, int):
            return (False, "The 'max-length' field must be an integer value.")
        elif max_length < 0:
            return (False, "The 'min-length' must be a positive integer.")
        elif min_length is not None and max_length < min_length:
            return (False, "The 'max-length' must be greater than or equal to the 'min-length'.")

    return (True, None)
Example #4
0
def is_question_help(question_help, languages=None):
    """Validates the specified question help.

    A help is a non-empty or normalized string.

    Args:
        help (str|dict): The help to validate.
        languages (list): A list of languages that the normalized string dictionary must contain, where each item of the
            list is a language code. Note that this parameter is used if and only if the help is a normalized string.

    Returns:
        <bool, str|None>: A pair containing the value True if the help is valid,
            False otherwise; as well as an error message in case it is invalid.

    Raises:
        TypeError: If the question_help argument is not a string or dictionary, or if
            languages is not a list or NoneType.
    """
    if not is_configuration_string(question_help, languages):
        return (False, "A question help field must be a non-empty or normalized string.")

    return (True, None)
Example #5
0
 def is_messages(assertion_messages):
     check_arg_type(is_messages, "assertion_messages", assertion_messages, dict)
     if any(not is_configuration_string(m, languages) for m in assertion_messages.itervalues()):
         return (False, "A tutorial subject assertion message must be a non-empty or normalized string.")
     return (True, None)
Example #6
0
 def test_illegal_configuration_strings(self):
     self.assertRaises(TypeError, helper.is_configuration_string, None)
     self.assertRaises(TypeError, helper.is_configuration_string, 42)
     self.assertRaises(TypeError, helper.is_configuration_string, [])
     self.assertRaises(TypeError, helper.is_configuration_string, {}, 42)
     self.assertRaises(TypeError, helper.is_configuration_string, {},
                       ("en", "fr"))
     self.assertRaises(TypeError, helper.is_configuration_string, {}, "")
     self.assertFalse(helper.is_configuration_string({}),
                      "Empty dictionary")
     self.assertFalse(helper.is_configuration_string({"en": ""}),
                      "Empty string with a valid language code")
     self.assertFalse(helper.is_configuration_string({"en": None}),
                      "Valid language code with non-string (None) value")
     self.assertFalse(helper.is_configuration_string({"en": 32}),
                      "Valid language code with non-string (int) value")
     self.assertFalse(helper.is_configuration_string({"en": {}}),
                      "Valid language code with non-string (dict) value")
     self.assertFalse(
         helper.is_configuration_string({"en 12": "What is your name?"}),
         "Invalid language code")
     self.assertFalse(
         helper.is_configuration_string({
             "en": "What is your name?",
             "fr": ""
         }), "Missing question")
     self.assertFalse(
         helper.is_configuration_string({"en": "What is your name?"},
                                        ["fr"]),
         "Missing a required language")
     self.assertFalse(
         helper.is_configuration_string({
             "en": "???",
             "fr": "???"
         }, [1, 2, 3]), "Illegal required language codes")
     self.assertFalse(helper.is_configuration_string(""), "Empty string.")
     self.assertFalse(helper.is_configuration_string("   "),
                      "Empty string (whitespace only).")
     self.assertFalse(helper.is_configuration_string("\r\n\t"),
                      "Empty string (escape sequences).")
Example #7
0
 def test_valid_configuration_strings(self):
     self.assertTrue(helper.is_configuration_string("Hello, World"),
                     "Non-empty string.")
     self.assertTrue(helper.is_configuration_string("   *"),
                     "String with leading whitespace and asterisk.")
     self.assertTrue(helper.is_configuration_string("trailblazer   "),
                     "String with trailing whitespace.")
     self.assertTrue(helper.is_configuration_string("    Hello, World    "),
                     "String with leading and trailing whitespace.")
     self.assertTrue(helper.is_configuration_string("\r\n\t\\"),
                     "Escape sequences with backslash character.")
     self.assertTrue(
         helper.is_configuration_string(
             {"en": "What is the answer to life?"}), "Normalized string")
     self.assertTrue(helper.is_configuration_string({"en": "???"}),
                     "Normalized string (syntactically)")
     self.assertTrue(
         helper.is_configuration_string(
             {"fr-CH": "Mais où est donc Ornicar?"}),
         "Normalized swiss-french string")
     self.assertTrue(
         helper.is_configuration_string({
             "en": "What is the answer to life?",
             "fr": "Mais où est donc Ornicar?"
         }), "Normalized string with multiple languages")
     self.assertTrue(
         helper.is_configuration_string({
             "en": "???",
             "fr": "???"
         }, []),
         "Normalized string with an empty list of required languages")
     self.assertTrue(
         helper.is_configuration_string({
             "en": "???",
             "fr": "???"
         }, ["en"]), "Normalized string with required language")
     self.assertTrue(
         helper.is_configuration_string({
             "en": "???",
             "fr": "???"
         }, ["en", "fr"]),
         "Normalized string with multiple required languages")
 def test_illegal_configuration_strings(self):
     self.assertRaises(TypeError, helper.is_configuration_string, None)
     self.assertRaises(TypeError, helper.is_configuration_string, 42)
     self.assertRaises(TypeError, helper.is_configuration_string, [])
     self.assertRaises(TypeError, helper.is_configuration_string, {}, 42)
     self.assertRaises(TypeError, helper.is_configuration_string, {}, ("en", "fr"))
     self.assertRaises(TypeError, helper.is_configuration_string, {}, "")
     self.assertFalse(helper.is_configuration_string({}), "Empty dictionary")
     self.assertFalse(helper.is_configuration_string({"en":""}), "Empty string with a valid language code")
     self.assertFalse(helper.is_configuration_string({"en":None}), "Valid language code with non-string (None) value")
     self.assertFalse(helper.is_configuration_string({"en":32}), "Valid language code with non-string (int) value")
     self.assertFalse(helper.is_configuration_string({"en":{}}), "Valid language code with non-string (dict) value")
     self.assertFalse(helper.is_configuration_string({"en 12":"What is your name?"}), "Invalid language code")
     self.assertFalse(helper.is_configuration_string({"en":"What is your name?", "fr":""}), "Missing question")
     self.assertFalse(helper.is_configuration_string({"en":"What is your name?"}, ["fr"]), "Missing a required language")
     self.assertFalse(helper.is_configuration_string({"en":"???", "fr":"???"}, [1, 2, 3]), "Illegal required language codes")
     self.assertFalse(helper.is_configuration_string(""), "Empty string.")
     self.assertFalse(helper.is_configuration_string("   "), "Empty string (whitespace only).")
     self.assertFalse(helper.is_configuration_string("\r\n\t"), "Empty string (escape sequences).")
 def test_valid_configuration_strings(self):
     self.assertTrue(helper.is_configuration_string("Hello, World"), "Non-empty string.")
     self.assertTrue(helper.is_configuration_string("   *"), "String with leading whitespace and asterisk.")
     self.assertTrue(helper.is_configuration_string("trailblazer   "), "String with trailing whitespace.")
     self.assertTrue(helper.is_configuration_string("    Hello, World    "), "String with leading and trailing whitespace.")
     self.assertTrue(helper.is_configuration_string("\r\n\t\\"), "Escape sequences with backslash character.")
     self.assertTrue(helper.is_configuration_string({"en":"What is the answer to life?"}), "Normalized string")
     self.assertTrue(helper.is_configuration_string({"en":"???"}), "Normalized string (syntactically)")
     self.assertTrue(helper.is_configuration_string({"fr-CH":"Mais où est donc Ornicar?"}), "Normalized swiss-french string")
     self.assertTrue(helper.is_configuration_string({"en":"What is the answer to life?", "fr":"Mais où est donc Ornicar?"}), "Normalized string with multiple languages")
     self.assertTrue(helper.is_configuration_string({"en":"???", "fr":"???"}, []), "Normalized string with an empty list of required languages")
     self.assertTrue(helper.is_configuration_string({"en":"???", "fr":"???"}, ["en"]), "Normalized string with required language")
     self.assertTrue(helper.is_configuration_string({"en":"???", "fr":"???"}, ["en", "fr"]), "Normalized string with multiple required languages")