diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..d978679 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +omit = *tests* diff --git a/.gitignore b/.gitignore index 3208b8e..8efd63d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,5 @@ docs/_build # IDEs /.idea +*.ropeproject +*.swp diff --git a/AUTHORS.rst b/AUTHORS.rst index 129a51e..045d7fd 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -11,3 +11,4 @@ Contributors ~~~~~~~~~~~~ * Khaled Porlin - https://github.com/porlin72 +* Agam Dua - https://github.com/agamdua diff --git a/drf_braces/tests/test_utils.py b/drf_braces/tests/test_utils.py new file mode 100644 index 0000000..165b901 --- /dev/null +++ b/drf_braces/tests/test_utils.py @@ -0,0 +1,50 @@ +from __future__ import print_function, unicode_literals + +import unittest + +from drf_braces.utils import ( + get_class_name_with_new_suffix, + get_attr_from_base_classes, +) +from rest_framework import fields + + +class TestUtils(unittest.TestCase): + def test_get_class_name_with_new_suffix(self): + new_name = get_class_name_with_new_suffix( + klass=fields.IntegerField, + existing_suffix='Field', + new_suffix='StrawberryFields' + ) + self.assertEqual(new_name, 'IntegerStrawberryFields') + + new_name = get_class_name_with_new_suffix( + klass=fields.IntegerField, + existing_suffix='straws', + new_suffix='Blueberries' + ) + self.assertEqual(new_name, 'IntegerFieldBlueberries') + + def test_get_attr_from_base_classes(self): + Parent = type(str('Parent'), (), {'fields': 'pancakes'}) + + self.assertEqual( + get_attr_from_base_classes((Parent,), [], 'fields'), 'pancakes' + ) + + self.assertEqual( + get_attr_from_base_classes( + (Parent,), {'fields': 'mushrooms'}, 'fields' + ), + 'mushrooms' + ) + + self.assertEqual( + get_attr_from_base_classes((Parent,), [], '', default='maple_syrup'), + 'maple_syrup' + ) + + with self.assertRaises(AttributeError): + get_attr_from_base_classes( + (Parent,), {'fields': 'mushrooms'}, 'catchmeifyoucan' + ) diff --git a/drf_braces/utils.py b/drf_braces/utils.py index 1817cd6..2f81150 100644 --- a/drf_braces/utils.py +++ b/drf_braces/utils.py @@ -117,6 +117,21 @@ def initialize_class_using_reference_object(reference_object, klass, **kwargs): def get_class_name_with_new_suffix(klass, existing_suffix, new_suffix): + """ + Generates new name by replacing the existing suffix with a new one. + + Args: + klass (type): original class from which new name is generated + existing_suffix (str): the suffix which needs to remain where it is + new_suffix (str): the new suffix desired + + Example: + >>> get_class_name_with_new_suffix(FooForm, 'Form', 'NewForm') + 'FooNewForm' + + Returns: + new_name (str): the name with the new suffix + """ class_name = klass.__name__ if existing_suffix in class_name: @@ -129,7 +144,27 @@ def get_class_name_with_new_suffix(klass, existing_suffix, new_suffix): return new_name -def get_attr_from_base_classes(bases, attrs, attr, **kwargs): +def get_attr_from_base_classes(bases, attrs, attr, default=None): + """ + The attribute is retrieved from the base classes if they are not already + present on the object. + + Args: + bases (tuple, list): The base classes for a class. + attrs (dict): The attributes of the class. + attr (str): Specific attribute being looked for. + default (any): Whatever default value is expected if the + attr is not found. + + Returns: + attribute value as found in base classes or a default when attribute + is not found and default is provided. + + Raises: + AttributeError: When the attribute is not present anywhere in the + call chain hierarchy specified through bases and the attributes + of the class itself + """ if attr in attrs: return attrs[attr] @@ -139,8 +174,8 @@ def get_attr_from_base_classes(bases, attrs, attr, **kwargs): except AttributeError: continue - if 'default' in kwargs: - return kwargs['default'] + if default: + return default raise AttributeError( 'None of the bases have {} attribute'