from __future__ import unicode_literals

import unittest

from parsing.exceptions import ParseError
from ..parsers import (
    simple_value,
    double_quoted_value,
    single_quoted_value,
    quoted_value,
    value,
    label,
    attribute,
    attributes,
    opening_tag,
    closing_tag,
)


class BaseTestCases(object):
    class TestParser(unittest.TestCase):
        PARSER = None
        VALUES = {}

        def test_it_should_parse_the_expected_content(self):
            for k, v in self.VALUES.items():
                if v is None:
                    with self.assertRaises(ParseError):
                        self.PARSER.parse_string(k)
                else:
                    self.assertEqual(self.PARSER.parse_string(k), v)


class TestSimpleValue(BaseTestCases.TestParser):
    PARSER = simple_value
    VALUES = {
        'arst-ARST_arst-1234_': ('arst-ARST_arst-1234_', ''),
        'arst-ARST arst-1234_': ('arst-ARST', ' arst-1234_'),
        ' arst-ARST arst-1234_': None,
    }


class TestDoubleQuotedValue(BaseTestCases.TestParser):
    PARSER = double_quoted_value
    VALUES = {
        '"\'\'ienienartieanrst098098234!@#$ARtienarsy einarsti ryuq  qy"': (
            '\'\'ienienartieanrst098098234!@#$ARtienarsy einarsti ryuq  qy',
            '',
        ),
        '"inarst': None,
    }


class TestSingleQuotedValue(BaseTestCases.TestParser):
    PARSER = single_quoted_value
    VALUES = {
        "'\"\"ienienartieanrst098098234!@#$ARtienarsy einarsti ryuq  qy'": (
            '""ienienartieanrst098098234!@#$ARtienarsy einarsti ryuq  qy',
            '',
        ),
        "'inarst": None,
    }


class TestQuotedValue(BaseTestCases.TestParser):
    PARSER = quoted_value
    VALUES = dict(
        TestDoubleQuotedValue.VALUES.items() +
        TestSingleQuotedValue.VALUES.items()
    )


class TestValue(BaseTestCases.TestParser):
    PARSER = value
    VALUES = dict(
        TestSimpleValue.VALUES.items() +
        TestQuotedValue.VALUES.items()
    )


class TestLabel(BaseTestCases.TestParser):
    PARSER = label
    VALUES = {
        'a': ('a', ''),
        'A': ('A', ''),
        '9a': None,
        'test-label': ('test-label', ''),
        'test-label9': ('test-label9', ''),
        'test-label9_': None,
        'test-label9-': None,
    }


class TestAttribute(BaseTestCases.TestParser):
    PARSER = attribute
    VALUES = {
        'arst=1234': (('arst', '1234'), ''),
        'arst  =  1234': (('arst', '1234'), ''),
        'arst ="1234"': (('arst', '1234'), ''),
        "arst= '1234'": (('arst', '1234'), ''),
        "arst '1234'": None,
    }


class TestAttributes(BaseTestCases.TestParser):
    PARSER = attributes
    VALUES = {
        'arst=1234': ((('arst', '1234'),), ''),
        'arst=1234 test_label  = 1234 test-label = "1234" yo=\'dude\'': (
            (
                ('arst', '1234'),
                ('test_label', '1234'),
                ('test-label', '1234'),
                ('yo', 'dude'),
            ),
            '',
        ),
    }


class TestOpeningTag(BaseTestCases.TestParser):
    PARSER = opening_tag
    VALUE = {
        '<p>': (('p',), ''),
        '<p style="color: red;">': (('p', ('style', 'color: red;')), ''),
    }


class TestClosingTag(BaseTestCases.TestParser):
    PARSER = closing_tag
    VALUE = {
        '</p>': ('p', ''),
        '</  p  >': ('p', ''),
    }

@@ -290,16 +290,38 @@
 ng_tag,%0A
+    self_closing_tag,%0A
 )%0A%0A%0Aclas
@@ -3126,37 +3126,38 @@
 ng_tag%0A    VALUE
+S
  = %7B%0A
-
         '%3Cp%3E': (
@@ -3200,16 +3200,24 @@
 r: red;%22
+ id=%22yo%22
 %3E': (('p
@@ -3219,16 +3219,17 @@
  (('p', 
+(
 ('style'
@@ -3244,16 +3244,31 @@
 : red;')
+, ('id', 'yo'))
 ), ''),%0A
@@ -3357,16 +3357,17 @@
    VALUE
+S
  = %7B%0A   
@@ -3417,18 +3417,282 @@
  ('p', ''),%0A
-
     %7D%0A
+%0A%0A#class TestSelfClosingTag(BaseTestCases.TestParser):%0A    #PARSER = self_closing_tag%0A    #VALUES = %7B%0A        #'%3Cbr/%3E': (),%0A        ##'%3Ctest-xml-tag test-attr=%221234%22/%3E': ((, ''),%0A    #%7D%0A%0A    #def test_it(self):%0A        #self.assertEqual((('br',), ''), ('br', ''))%0A

Add tests