Ejemplo n.º 1
0
    def testCommentValidator(self):
        validator = name_validator.NameValidator()
        good_comments = [
            'Responses with Content-Type', 'application/json', ',',
            '[minimum: 4.4.1]',
            'API key. Your API key identifies your project',
            'OAuth 2.0 token for the current user.'
        ]
        # A list of input comments, and their expected replacements
        bad_comments = [
            ('/*', ''),
            ('*/', ''),
            ('\"""', ''),
            ('///', ''),
            ('\\*', ''),
            ('/*Some Comment String*/', 'Some Comment String'),
            ('\""" A long comment string """', ' A long comment string '),
            ('///Escaped comment string', 'Escaped comment string'),
        ]

        for comment in good_comments:
            validator.ValidateAndSanitizeComment(comment)
        for comment, replacement in bad_comments:
            self.assertEqual(replacement,
                             validator.ValidateAndSanitizeComment(comment))
Ejemplo n.º 2
0
    def testApiVersionValidator(self):
        validator = name_validator.NameValidator()
        good_names = ['v1', 'v1.2', '1.2']
        bad_names = [
            '.1', 'v1_2', '1 2', 'no-dash', 'no spaces', 'no/slash', 'no:colon'
        ]

        for varname in good_names:
            validator.ValidateApiVersion(varname)
        for varname in bad_names:
            print "'%s'" % varname
            self.assertRaises(ValueError, validator.ValidateApiVersion,
                              varname)
Ejemplo n.º 3
0
    def testApiNameValidator(self):
        validator = name_validator.NameValidator()
        good_names = ['valid', 'isValid', 'is2Valid']
        bad_names = [
            '1noLeadingNumbers', '^test', 'NotValid', 'no-dash',
            'dot.is.not.valid', 'no spaces', 'no/slash', 'no:colon'
        ]

        for varname in good_names:
            validator.ValidateApiName(varname)
        for varname in bad_names:
            print "'%s'" % varname
            self.assertRaises(ValueError, validator.ValidateApiName, varname)
Ejemplo n.º 4
0
    def testVariableNameValidator(self):
        validator = name_validator.NameValidator()
        good_names = [
            '$ref', '_a', '_private', 'a_var.name', 't1', 'max-results'
        ]
        bad_names = [
            '$', '1st_result', '^test', '.variable', '1', '_', 'not_valid.',
            'no spaces', 'no/slash'
        ]

        for varname in good_names:
            validator.Validate(varname)
        for varname in bad_names:
            print "'%s'" % varname
            self.assertRaises(ValueError, validator.Validate, varname)
Ejemplo n.º 5
0
class CodeObject(UseableInTemplates):
    """Template objects which represents an element that might be in code.

  This is the base class for things which might be code elements, such as
  classes, variables and methods.
  """

    _validator = name_validator.NameValidator()

    def __init__(self, def_dict, api, parent=None, language_model=None):
        """Construct a CodeObject.

    Args:
      def_dict: (dict) The discovery dictionary for this element.
      api: (Api) The Api instance which owns this element.
      parent: (CodeObject) The parent of this element.
      language_model: (LanguageModel) The language we are targetting.
        Dynamically defaults to the parent's language model.
    """
        super(CodeObject, self).__init__(def_dict)
        self._api = api
        self._children = []
        self._parent = None
        self._language_model = language_model
        self.SetParent(parent)
        # Sanitize the 'description'. It is a block of user written text we want to
        # emit whenever possible.
        if 'description' in def_dict:
            self.SetTemplateValue(
                'description',
                self.ValidateAndSanitizeComment(
                    self.StripHTML(def_dict['description'])))

    @staticmethod
    def ValidateName(name):
        """Validate that the name is safe to use in generated code."""
        CodeObject._validator.Validate(name)

    @staticmethod
    def ValidateAndSanitizeComment(comment):
        """Remove unsafe constructions from a string and make it safe in templates.

    Make sure a string intended as a comment has only safe constructs in it and
    then make it as safe to expand directly in a template.

    Args:
      comment: (str) A string which is expected to be a documentation comment.

    Returns:
      (str) The comment with HTML-unsafe constructions removed.
    """
        return CodeObject._validator.ValidateAndSanitizeComment(comment)

    @staticmethod
    def StripHTML(input_string):
        """Strip HTML from a string."""
        stripper = html_stripper.HTMLStripper()
        stripper.feed(input_string)
        return stripper.GetFedData()

    @property
    def api(self):
        return self._api

    @property
    def children(self):
        return self._children

    @property
    def parent(self):
        return self._parent

    @property
    def codeName(self):  # pylint: disable-msg=C6409
        """Returns a language appropriate name for this object.

    This property should only be used during template expansion. It is computed
    once, using the LanguageModel in play, and then that value is cached.

    Returns:
      (str) a name for an instance of this object.
    """
        code_name = self.GetTemplateValue('codeName')
        if not code_name:
            code_name = self.values['wireName']
            language_model = self._FindNearestLanguageModel()
            if language_model:
                code_name = language_model.ToMemberName(code_name, self._api)
            self.SetTemplateValue('codeName', code_name)
        return code_name

    @property
    def fullClassName(self):  # pylint: disable-msg=C6409
        """Returns the fully qualified class name for this object.

    Walks up the parent chain building a fully qualified class name. If the
    object is in a package, include the package name.

    Returns:
      (str) The class name of this object.
    """
        p = self.FindTopParent()
        package = p.values.get('package')
        if package:
            language_model = self._FindNearestLanguageModel()
            if language_model:
                class_name_delimiter = language_model.class_name_delimiter
            else:
                class_name_delimiter = '.'
            return package.name + class_name_delimiter + self.RelativeClassName(
                None)
        return self.RelativeClassName(None)

    @property
    def packageRelativeClassName(self):  # pylint: disable-msg=C6409
        """Returns the class name for this object relative to its package.

    Walks up the parent chain building a fully qualified class name.

    Returns:
      (str) The class name of this object.
    """
        return self.RelativeClassName(None)

    def RelativeClassName(self, other):
        """Returns the class name for this object relative to another.

    Args:
      other: (CodeObject) Another code object which might be a parent.
    Returns:
      (str) The class name of this object relative to another.
    """
        if self == other:
            return ''
        full_name = ''
        if self.parent:
            full_name = self.parent.RelativeClassName(other)
        if full_name:
            language_model = self._FindNearestLanguageModel()
            if language_model:
                class_name_delimiter = language_model.class_name_delimiter
            else:
                class_name_delimiter = ''
            full_name += class_name_delimiter
        full_name += self.values.get(
            'className',
            self.values.get('codeName', self.values.get('name', '')))
        return full_name

    def FindTopParent(self):
        if self.parent:
            return self.parent.FindTopParent()
        return self

    def SetLanguageModel(self, language_model):
        """Changes the language model of this code object."""
        self._language_model = language_model

    def SetParent(self, parent):
        """Changes the parent of this code object.

    Args:
      parent: (CodeObject) the new parent.
    """
        if self._parent:
            self._parent.children.remove(self)
        self._parent = parent
        if self._parent:
            self._parent.children.append(self)

    def _FindNearestLanguageModel(self):
        """Find the nearest LanguageModel by walking my parents."""
        if self._language_model:
            return self._language_model
        if self._parent:
            # Access to protected member OK here. pylint: disable-msg=W0212
            return self._parent._FindNearestLanguageModel()
        return None

    @property
    def codeType(self):  # pylint: disable-msg=C6409
        """Accessor for codeType for use in templates.

    If the template value for codeType was explicitly set, return that,
    otherwise use the code_type member. This is only safe to call for code
    objects which implemnt code_type.

    Returns:
      (str) the value for codeType
    """
        return self.GetTemplateValue('codeType') or self.code_type