import colander

from daybed import schemas
from daybed.tests.support import unittest


class PointFieldTests(unittest.TestCase):
    def setUp(self):
        self.schema = schemas.PointField.definition()
        definition = self.schema.deserialize(
            {'name': 'location',
             'type': 'point'})
        self.validator = schemas.PointField.validation(**definition)

    def test_deserialization_is_idempotent(self):
        self.assertEquals([0.4, 45.0],
                          self.validator.deserialize([0.4, 45.0]))

    def test_coordinates_are_deserialized_as_float_or_integer(self):
        self.assertEquals([0.4, 45.0],
                          self.validator.deserialize('[0.4, 45.0]'))
        self.assertEquals([0, 45],
                          self.validator.deserialize('[0, 45]'))

    def test_coordinates_can_have_several_dimensions(self):
        self.assertEquals([0.4, 45.0, 1280],
                          self.validator.deserialize('[0.4, 45.0, 1280]'))
        self.assertEquals([0.4, 45.0, 1280, 2048],
                          self.validator.deserialize(
                              '[0.4, 45.0, 1280, 2048]'))

    def test_coordinates_cannot_be_null_if_required(self):
        self.assertRaises(colander.Invalid,
                          self.validator.deserialize, colander.null)

    def test_coordinates_can_be_null_if_not_required(self):
        definition = self.schema.deserialize(
            {'name': 'location',
             'type': 'point',
             'required': 'false'})
        validator = schemas.PointField.validation(**definition)
        self.assertEquals(colander.null,
                          validator.deserialize(colander.null))

    def test_coordinates_must_be_valid_json(self):
        self.assertRaises(colander.Invalid,
                          self.validator.deserialize, '[0.4,,45.0]')

    def test_coordinates_cannot_be_invalid_data(self):
        self.assertRaises(colander.Invalid,
                          self.validator.deserialize, '[0.4]')
        self.assertRaises(colander.Invalid,
                          self.validator.deserialize, '[[0.4, 45.0]]')
        self.assertRaises(colander.Invalid,
                          self.validator.deserialize, '"0.4, 45.0"')
        self.assertRaises(colander.Invalid,
                          self.validator.deserialize, '["a", "b"]')

    def test_coordinates_cannot_exceed_earth(self):
        self.assertRaises(colander.Invalid,
                          self.validator.deserialize, '[181.0, 91.0]')
        self.assertRaises(colander.Invalid,
                          self.validator.deserialize, '[-181.0, -91.0]')
        self.assertRaises(colander.Invalid,
                          self.validator.deserialize, '[120.0, -91.0]')


class EuclideanPointFieldTests(unittest.TestCase):
    def test_point_euclidean(self):
        schema = schemas.PointField.definition()
        definition = schema.deserialize(
            {'name': 'location',
             'type': 'point',
             'gps': False})
        validator = schemas.PointField.validation(**definition)
        self.assertEquals([181.0, 91.0],
                          validator.deserialize('[181.0, 91.0]'))


class LineFieldTests(unittest.TestCase):
    def setUp(self):