diff --git a/korona/html/construct.py b/korona/html/construct.py
index 10c80ac..c560973 100644
--- a/korona/html/construct.py
+++ b/korona/html/construct.py
@@ -10,6 +10,7 @@
anchor_tag,
abbr_tag,
acronym_tag,
+ area_tag,
bold_tag,
base_tag
)
@@ -98,7 +99,7 @@ def get_coords(self, shape, coords):
"""Returns coordinates after a series of validations.
Args:
- shape (str): Shape of a link (Ex. rect/circle/poly)
+ shape (str): Shape of a link (Ex. rect/circle/poly/etc.)
coords (mixed): A list/tuple/str of coordinate values.
Returns:
@@ -143,6 +144,9 @@ def pre_validate(self, href, attribute_name, value):
'href attribute is set.'
.format(attribute_name))
+ if not isinstance(value, str):
+ raise ValueError(': {0} should be a string'.format(value))
+
def validate_values(self, href, attribute_name, value):
"""Validates whether the given attribute value is a valid value or not.
Some of the attributes have confined values. Even if we give some
@@ -199,6 +203,167 @@ def construct_tag(self):
return acronym_tag.render(self.values)
+class Area(object):
+ """Class for constructing area tag.
+
+ Args:
+ alt (str): Specifies an alternate text for the area. Required if the
+ href attribute is present.
+ coords (mixed): Specifies the coordinates of the area.
+ download (str): Specifies that the target will be downloaded when a
+ user clicks on the hyper link.
+ href (str): Specifies the hyperlink target for the area.
+ hreflang (str): Specifies the language of the target URL.
+ media (str): Specifies what media/device the target URL is optimized
+ for.
+ nohref(bool): Specifies that an area has no associated link.
+ rel (str): Specifies the relationship between the current document
+ and the target URL.
+ shape (str): Specifies the shape of the area.
+ target(str): Specifies where to open the target URL.
+ type (str): Specifies the media type of the target URL.
+ """
+ def __init__(self,
+ alt=None,
+ coords=None,
+ download=None,
+ href=None,
+ hreflang=None,
+ media=None,
+ nohref=False,
+ rel=None,
+ shape=None,
+ target=None,
+ type=None):
+ self.tag = 'area'
+ self.validate_alt(href=href, attribute_name='alt', value=alt)
+ coordinates = self.get_coords(shape=shape, coords=coords)
+ self.pre_validate(href=href, attribute_name='download', value=download)
+ self.validate_string(value=href)
+ self.pre_validate(href=href, attribute_name='hreflang', value=hreflang)
+ self.pre_validate(href=href, attribute_name='media', value=media)
+ self.validate_values(href=href, attribute_name='rel', value=rel)
+ self.validate_values(href=href, attribute_name='shape', value=shape)
+ self.pre_validate(href=href, attribute_name='targte', value=target)
+ self.pre_validate(href=href, attribute_name='type', value=type)
+ self.values = {'alt': alt,
+ 'coords': coordinates,
+ 'download': download,
+ 'href': href,
+ 'hreflang': hreflang,
+ 'media': media,
+ 'nohref': nohref,
+ 'rel': rel,
+ 'shape': shape,
+ 'target': target,
+ 'type': type}
+
+ def construct_tag(self):
+ """Returns the constructed area tag ."""
+ return area_tag.render(self.values)
+
+ def validate_string(self, value):
+ """Validates whether the given value is a string or not."""
+ if not value:
+ return
+
+ # If the attribute value is not a string raise a ValueError.
+ if not isinstance(value, str):
+ raise ValueError(': {0} should be a string'.format(value))
+
+ def validate_alt(self, href, attribute_name, value):
+ """Validates area's alt attribute."""
+ if href and not value:
+ raise AttributeError(': {0} attribute is required if the '
+ 'href attribute is present.'
+ .format(attribute_name))
+
+ if not href and value:
+ raise AttributeError(': {0} attribute is only used when '
+ 'href attribute is set.'
+ .format(attribute_name))
+
+ if value and not isinstance(value, str):
+ raise ValueError(': {0} should be a string'.format(value))
+
+ def pre_validate(self, href, attribute_name, value):
+ """Validates whether an attribute is dependant on another attribute or
+ not. Some of the attributes requires href attribute to be set.
+ """
+ if not value:
+ return
+
+ if not href:
+ raise AttributeError(': {0} attribute is only used when '
+ 'href attribute is set.'
+ .format(attribute_name))
+
+ if not isinstance(value, str):
+ raise ValueError(': {0} should be a string'.format(value))
+
+ def get_coords(self, shape, coords):
+ """Returns coordinates after a series of validations.
+
+ Args:
+ shape (str): Shape of a link (Ex. rect/circle/poly/etc.)
+ coords (mixed): A list/tuple/str of coordinate values.
+
+ Returns:
+ str: A string of coordinate values.
+ """
+ if not coords:
+ return
+
+ if (coords and not shape) or (shape and not coords):
+ raise AttributeError(': shape attribute should be present '
+ 'when coords are specified.')
+
+ if isinstance(coords, str):
+ coords = coords.split(',')
+
+ if isinstance(coords, dict):
+ raise ValueError(': {0} should be either list/tuple/str not '
+ 'a dictionary'
+ .format(coords))
+
+ if shape == 'rect' and len(coords) != RECTANGLE_SHAPE_COORDINATES:
+ raise ValueError(': {0} coordinates should be given for '
+ 'rectangle shape'
+ .format(RECTANGLE_SHAPE_COORDINATES))
+
+ if shape == 'circle' and len(coords) != CIRCLE_SHAPE_COORDINATES:
+ raise ValueError(': {0} coordinates should be given for '
+ 'circle shape'
+ .format(CIRCLE_SHAPE_COORDINATES))
+
+ return ','.join(str(coord) for coord in coords)
+
+ def validate_values(self, href, attribute_name, value):
+ """Validates whether the given attribute value is a valid value or not.
+ Some of the attributes have confined values. Even if we give some
+ other value, the html output would not be correct.
+ """
+ if not value:
+ return
+
+ if attribute_name == 'rel' and not href:
+ raise AttributeError(': {attribute_name} is only used when '
+ 'href attribute is set.'
+ .format(attribute_name=attribute_name))
+
+ if not isinstance(value, str):
+ raise ValueError(': {0} should be a string value.'
+ .format(attribute_name))
+
+ attribute_values = TAG_ATTRIBUTES[self.tag][attribute_name]['values']
+
+ if value not in attribute_values:
+ raise AttributeError(': {attribute_name} attribute values '
+ 'should be one of these: {values}'
+ .format(attribute_name=attribute_name,
+ values=','.join(attribute_values)))
+
+
class B(object):
"""Class for constructing bold tag.
diff --git a/korona/templates/html/__init__.py b/korona/templates/html/__init__.py
index 80c799e..8517393 100644
--- a/korona/templates/html/__init__.py
+++ b/korona/templates/html/__init__.py
@@ -4,6 +4,7 @@
anchor_tag,
abbr_tag,
acronym_tag,
+ area_tag,
bold_tag,
base_tag
)
diff --git a/korona/templates/html/tags.py b/korona/templates/html/tags.py
index c199dfd..57528e0 100644
--- a/korona/templates/html/tags.py
+++ b/korona/templates/html/tags.py
@@ -26,6 +26,20 @@
{% if text -%} {{ text }} {% endif -%}
""")
+area_tag = env.from_string("""
+
+ {% if target %} target="{{ target }}" {% endif -%}
+""")
+
bold_tag = env.from_string("""
{% if text -%} {{ text }} {% endif -%}
""")
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 953e2b6..a4b1e3d 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -6,6 +6,7 @@
A,
Abbr,
Acronym,
+ Area,
B,
Base
)
@@ -13,6 +14,7 @@
anchor_tag,
abbr_tag,
acronym_tag,
+ area_tag,
bold_tag,
base_tag
)
@@ -79,6 +81,8 @@ def test_construct_anchor_tag_coords(attributes):
@parametrize('attributes,exception,error_msg', [
({'rel': 1}, AttributeError, 'only used when href attribute is set.'),
+ ({'type': 1}, AttributeError, 'only used when href attribute is set.'),
+ ({'href': 'abc', 'type': 1}, ValueError, 'should be a string'),
({'charset': 1}, ValueError, 'should be a string'),
({'rel': 1, 'href': 'www.google.com'}, ValueError, 'should be a string'),
({'shape': 'circle', 'coords': [1, 2, 3, 4]},
@@ -144,6 +148,104 @@ def test_construct_acronym_tag(attributes):
assert acronym.construct_tag() == acronym_tag.render(attributes)
+@parametrize('attributes', [
+ ({'href': 'www.google.com', 'alt': 'abc'}),
+ ({'href': 'www.google.com', 'alt': 'abc', 'rel': 'nofollow'}),
+ ({'download': 'abc',
+ 'href': 'www.google.com',
+ 'hreflang': 'en',
+ 'rel': 'nofollow',
+ 'target': '_blank',
+ 'type': 'text/html',
+ 'alt': 'abc'}),
+ ({'href': 'www.google.com', 'alt': 'abc'})
+])
+def test_construct_area_tag(attributes):
+ """Test for validating whether the area tag is constructed correctly or
+ not.
+ """
+ area = Area(**attributes)
+ assert area.construct_tag() == area_tag.render(attributes)
+
+
+@parametrize('attributes', [
+ ({'shape': 'rect', 'coords': [1, 2, 3, 4]}),
+ ({'shape': 'circle', 'coords': [1, 2, 3]}),
+ ({'shape': 'poly', 'coords': [1, 2, 3, 4, 5, 6]}),
+ ({'shape': 'rect', 'coords': (1, 2, 3, 4)}),
+ ({'shape': 'circle', 'coords': (1, 2, 3)}),
+ ({'shape': 'poly', 'coords': (1, 2, 3, 4, 5, 6)}),
+ ({'shape': 'rect', 'coords': '1,2,3,4'}),
+ ({'shape': 'circle', 'coords': '1,2,3'}),
+ ({'shape': 'poly', 'coords': '1,2,3,4,5,6'}),
+])
+def test_construct_area_tag_coords(attributes):
+ """Test for validating the shape and coordinate attributes given."""
+ area = Area(**attributes)
+
+ if not isinstance(attributes['coords'], str):
+ attributes['coords'] = (','.join(str(coord)
+ for coord in attributes['coords']))
+
+ assert area.construct_tag() == area_tag.render(attributes)
+
+
+@parametrize('attributes,exception,error_msg', [
+ ({'rel': 1}, AttributeError, 'only used when href attribute is set.'),
+ ({'rel': 1, 'href': 'www.google.com', 'alt': 'abc'},
+ ValueError,
+ 'should be a string'),
+ ({'shape': 'circle', 'coords': [1, 2, 3, 4]},
+ ValueError,
+ 'coordinates should be given for circle shape'),
+ ({'shape': 'rect', 'coords': [1, 2, 3, 4, 5]},
+ ValueError,
+ 'coordinates should be given for rectangle shape'),
+ ({'shape': 'circle', 'coords': [1, 2]},
+ ValueError,
+ 'coordinates should be given for circle shape'),
+ ({'shape': 'rect', 'coords': [1, 2, 3]},
+ ValueError,
+ 'coordinates should be given for rectangle shape'),
+ ({'shape': 'rect', 'coords': {'x': 1, 'y': 2}},
+ ValueError,
+ 'should be either list/tuple/str not a dictionary'),
+ ({'coords': [1, 2, 3]},
+ AttributeError,
+ 'shape attribute should be present when coords are specified'),
+ ({'download': 'abc'},
+ AttributeError,
+ 'only used when href attribute is set.'),
+ ({'href': 'abc', 'alt': 'abc', 'download': 123},
+ ValueError,
+ 'should be a string'),
+ ({'href': 123, 'alt': 'abc'},
+ ValueError,
+ 'should be a string'),
+ ({'href': 'www.google.com', 'alt': 'abc', 'rel': 'abc'},
+ AttributeError,
+ 'attribute values should be one of these'),
+ ({'shape': 'abc'},
+ AttributeError,
+ 'attribute values should be one of these'),
+ ({'alt': 'abc'},
+ AttributeError,
+ 'attribute is only used when href attribute is set.'),
+ ({'href': 'abc'},
+ AttributeError,
+ 'attribute is required if the href attribute is present'),
+ ({'href': 'www.google.com', 'alt': 123},
+ ValueError,
+ 'should be a string')
+])
+def test_construct_area_tag_error(attributes, exception, error_msg):
+ """Test for validating area tag's attributes."""
+ with pytest.raises(exception) as exc:
+ Area(**attributes)
+
+ assert error_msg in str(exc)
+
+
@parametrize('attributes', [
({'text': 'abc'}),
({'text': None})