from __future__ import unicode_literals

from sqlakeyset.serial import Serial

import csv
import io
from pytest import raises
import decimal
import datetime
import pytz
utc = pytz.utc

DEFAULTS = dict(
    lineterminator=str(''),
    delimiter=str('~'),
    doublequote=False,
    escapechar=str('\\'),
    quoting=csv.QUOTE_NONE)

s = Serial(**DEFAULTS)


class Z(str):
    pass


def unser_z(x):
    return x[::-1]


def ser_z(x):
    return 'z', x[::-1]


s.custom_serializations[Z] = ser_z
s.custom_unserializations['z'] = unser_z


with io.open('tests/blns.txt') as f:
    NAUGHTY = f.read().splitlines()


def test_ser():
    STRINGS = [
        'abc',
        r'abc\~',
        '~'.join(['\\', '~']),
        r'abc~1234\~1234',
        '~~~~~~~\\\\\\\\`````\\\\\\\\\\``\\`\''
    ]

    assert s.split(s.join(STRINGS)) == STRINGS
    assert s.split(s.join(NAUGHTY)) == NAUGHTY


def test_serial():
    assert s.serialize_value(None) == 'x'
    assert s.serialize_value(True) == 'true'
    assert s.serialize_value(False) == 'false'
    assert s.serialize_value(5) == 'i:5'
    assert s.serialize_value(5.0) == 'f:5.0'
    assert s.serialize_value(decimal.Decimal('5.5')) == 'n:5.5'
    assert s.serialize_value('abc') == 's:abc'
    assert s.serialize_value(b'abc') == 'b:YWJj'
    assert s.serialize_value(b'abc') == 'b:YWJj'
    assert s.serialize_value(datetime.date(2007, 12, 5)) == 'd:2007-12-05'
    assert s.serialize_value(datetime.datetime(2007, 12, 5, 12, 30, 30, tzinfo=utc)) \
        == 'dt:2007-12-05 12:30:30+00:00'
    assert s.serialize_value(datetime.time(12, 34, 56)) == 't:12:34:56'
    with raises(NotImplementedError):
        s.serialize_value(csv.reader)


def test_unserial():
    def twoway(x):
        assert s.unserialize_value(s.serialize_value(x)) == x

    twoway(None)
    twoway(True)
    twoway(False)
    twoway(5)
    twoway(5.0)
    twoway(decimal.Decimal('5.5'))
    twoway('abc')
    twoway(b'abc')
    twoway(b'abc')
    twoway(datetime.date(2007, 12, 5))
    twoway(datetime.datetime(2007, 12, 5, 12, 30, 30, tzinfo=utc))
    twoway(Z('abc'))

    with raises(ValueError):
        s.unserialize_value('zzzz:abc')

@@ -38,64 +38,79 @@
 ls%0A%0A
-from sqlakeyset.serial 
+import csv%0Aimport io%0Aimport uuid%0A
 import 
-Seri
+decim
 al%0A
-%0A
 import 
-csv
+datetime
 %0Aimport 
 io%0Af
@@ -105,18 +105,21 @@
 %0Aimport 
-io
+pytz%0A
 %0Afrom py
@@ -141,50 +141,45 @@
 ses%0A
-import decimal%0A
+from sqlakeyset.serial 
 import 
-datetime%0Aimport pytz
+Serial%0A
 %0Autc
@@ -1616,16 +1616,153 @@
 :34:56'%0A
+    assert s.serialize_value(uuid.UUID('939d4cc9-830d-4cca-bd74-3ec3d541a9b3')) %5C%0A        == 'uuid:939d4cc9-830d-4cca-bd74-3ec3d541a9b3'%0A
     with
@@ -2233,16 +2233,78 @@
 ('abc'))
+%0A    twoway(uuid.UUID('939d4cc9-830d-4cca-bd74-3ec3d541a9b3'))
 %0A%0A    wi

Add tests to serialize and unserialize uuid.UUID objects