from __future__ import absolute_import, unicode_literals

import unittest

from six import add_metaclass, text_type

from ..event_encoder import (
    CustomDimension, CustomMetric, Encoder, EventEncoder, TrackedAttribute)


@add_metaclass(EventEncoder)
class SomeEvent(object):

    required = TrackedAttribute('encoded_name', int, required=True)
    not_required = TrackedAttribute('other_name', text_type)


@add_metaclass(EventEncoder)
class CustomEvent(object):
    custom_dimension = CustomDimension(1)
    custom_metric = CustomMetric(5)


class TestEventEncoder(unittest.TestCase):

    def test_metaclass_instantiation(self):
        # Given
        event = SomeEvent()

        # Then
        self.assertIsInstance(event, SomeEvent)
        self.assertIsInstance(event, Encoder)
        self.assertIsInstance(event, object)

    def test_type_validation(self):
        # Given
        event = SomeEvent()

        # When/Then
        with self.assertRaises(TypeError):
            event.required = 'non-int'

    def test_missing_required_attribute(self):
        # Given
        event = SomeEvent()

        # When/Then
        with self.assertRaises(ValueError):
            event.required

    def test_missing_non_required_attribute(self):
        # Given
        event = SomeEvent()

        # When
        value = event.not_required

        # Then
        self.assertEqual(value, None)

    def test_attribute_value(self):
        # Given
        event = SomeEvent(required=5)
        expected = ('encoded_name', 5)

        # When
        value = event.required

        # Then
        self.assertEqual(value, expected)

    def test_set_invalid_attribute(self):
        # When/Then
        with self.assertRaises(AttributeError):
            SomeEvent(missing=5)

        # Given
        event = SomeEvent()

        # When/Then
        with self.assertRaises(AttributeError):
            event.missing = 5

    def test_custom_dimension_empty(self):
        # Given
        event = CustomEvent()

        # When
        value = event.custom_dimension

        # Then
        self.assertEqual(value, None)

    def test_custom_dimension_type(self):
        # Given
        event = CustomEvent()

        # When
        with self.assertRaises(TypeError):
            event.custom_dimension = 1

    def test_custom_dimension_valid(self):
        # Given
        event = CustomEvent(custom_dimension='name')
        expected = ('cd1', 'name')

        # When
        value = event.custom_dimension

        # Then
        self.assertEqual(value, expected)

    def test_custom_metric_empty(self):
        # Given
        event = CustomEvent()

        # When
        value = event.custom_metric

        # Then
        self.assertEqual(value, None)

    def test_custom_metric_type(self):
        # Given
        event = CustomEvent()

        # When
        with self.assertRaises(TypeError):
            event.custom_metric = 'name'

    def test_custom_metric_valid(self):
        # Given
        event = CustomEvent(custom_metric=2)
        expected = ('cm5', 2)

        # When
        value = event.custom_metric

        # Then
        self.assertEqual(value, expected)

@@ -406,66 +406,8 @@
 pe)%0A
-%0A%0A@add_metaclass(EventEncoder)%0Aclass CustomEvent(object):%0A
     
@@ -1929,38 +1929,36 @@
         event = 
-Cust
+S
 om
+e
 Event()%0A%0A       
@@ -2125,38 +2125,36 @@
         event = 
-Cust
+S
 om
+e
 Event()%0A%0A       
@@ -2311,38 +2311,36 @@
         event = 
-Cust
+S
 om
+e
 Event(custom_dim
@@ -2567,38 +2567,36 @@
         event = 
-Cust
+S
 om
+e
 Event()%0A%0A       
@@ -2761,30 +2761,28 @@
     event = 
-Cust
+S
 om
+e
 Event()%0A%0A   
@@ -2950,22 +2950,20 @@
 event = 
-Cust
+S
 om
+e
 Event(cu

Remove extra test class