import pytest
from time import time

from base10.base import Dialect, Metric, Reader, Writer
from base10.exceptions import DialectError


class TestDialects:

    def test_dialect_construction(self):
        assert isinstance(Dialect(), Dialect)

    def test_dialect_from_string_exception(self):
        dialect = Dialect()

        with pytest.raises(DialectError) as exc:
            dialect.from_string('')

        assert 'Attempt to read with a write-only dialect' == str(exc.value)

    def test_dialect_to_string_exception(self):
        dialect = Dialect()

        with pytest.raises(DialectError) as exc:
            dialect.to_string(None)

        assert 'Attempt to write with a read-only dialect' == str(exc.value)


class TestMetrics:

    def setup_method(self):
        self.metric_name = 'metric'
        self.metric_fields = ['value']
        self.metric_metadata = ['hostname']
        self.metric_values = {'value': 0, 'hostname': 'test', 'time': time()}

    def test_metric_properties(self):
        metric = Metric(self.metric_name, self.metric_fields,
                        self.metric_metadata, **self.metric_values)

        assert metric.name == self.metric_name
        assert metric.fields == self.metric_fields
        assert metric.metadata == self.metric_metadata
        assert metric.values == self.metric_values

    def test_metric_handle_time_field(self):
        metric = Metric(self.metric_name, self.metric_fields + ['time'],
                        self.metric_metadata, **self.metric_values)

        assert 'time' not in metric.fields

    def test_metric_add_time(self):
        alternative_values = {
            'value': 0,
            'hostname': 'test'
        }  # Note: No explicit time

        metric = Metric(self.metric_name, self.metric_fields,
                        self.metric_metadata, **alternative_values)

        assert 'time' in metric.values

    def test_metric_repr(self):
        metric = Metric(self.metric_name, self.metric_fields,
                        self.metric_metadata, **self.metric_values)

        assert repr(
            metric) == '<Metric:"{}" Fields:{} Metadata:{} Values:{}>'.format(
                self.metric_name, self.metric_fields, self.metric_metadata,
                self.metric_values)

    def test_metric_name_exception(self):
        alternative_values = {
            'value': 0,
            'host': 'test',
            'time': time()
        }  # Note: "host" not "hostname"

        with pytest.raises(NameError) as exc:
            metric = Metric(self.metric_name, self.metric_fields,
                            self.metric_metadata, **alternative_values)

        assert "Expected ['hostname', 'value'] but got ['host', 'value']" in str(
            exc.value)


class TestTransports:

    def test_reader_construction(self):
        with pytest.raises(TypeError) as exc:
            reader = Reader()

        assert "Can't instantiate" in str(exc.value)

    def test_writer_construction(self):
        with pytest.raises(TypeError) as exc:
            writer = Writer()

        assert "Can't instantiate" in str(exc.value)

@@ -1930,32 +1930,88 @@
 ric_repr(self):%0A
+        import re%0A        from ast import literal_eval%0A%0A
         metric =
@@ -2137,42 +2137,14 @@
     
-assert repr(%0A            metric) =
+regex 
 = '%3C
@@ -2151,18 +2151,23 @@
 Metric:%22
-%7B%7D
+(%5B%5E%22%5D+)
 %22 Fields
@@ -2171,96 +2171,341 @@
 lds:
-%7B%7D Metadata:%7B%7D Values:%7B%7D%3E'.format(%0A                self.metric_name, self.metric_fields,
+(%5C%5B%5B%5E%5C%5D%5D+%5C%5D) Metadata:(%5C%5B%5B%5E%5C%5D%5D+%5C%5D) Values:(%7B%5B%5E%7D%5D+%7D)%3E'%0A%0A        match = re.match(regex, repr(metric))%0A%0A        assert match is not None%0A        assert match.lastindex == 4%0A        assert match.group(1) == self.metric_name%0A        assert literal_eval(match.group(2)) == self.metric_fields%0A        assert literal_eval(match.group(3)) ==
  sel
@@ -2521,17 +2521,16 @@
 metadata
-,
 %0A       
@@ -2522,39 +2522,70 @@
 etadata%0A        
-       
+assert literal_eval(match.group(4)) ==
  self.metric_val
@@ -2583,25 +2583,24 @@
 etric_values
-)
 %0A%0A    def te

Fix for dict ordering issue in Metric.__repr__