Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

All encoders and decoders now implemented

  • Loading branch information...
commit 668685b374e08f85204fe676df3195e5544f2b21 1 parent 73d9d64
@samuel samuel authored
View
16 bert/__init__.py
@@ -1,3 +1,15 @@
-from bert.erlang import ErlangTermDecoder, Atom, Binary
-from bert.converters import BERTDecoder
+from bert.erlang import ErlangTermDecoder, ErlangTermEncoder, Atom, Binary
+from bert.converters import BERTDecoder, BERTEncoder
+
+def erlang_encode(obj):
+ return ErlangTermEncoder().encode(obj)
+
+def erlang_decode(obj):
+ return ErlangTermDecoder().decode(obj)
+
+def encode(obj):
+ return BERTEncoder().encode(obj)
+
+def decode(obj):
+ return BERTDecoder().decode(obj)
View
55 bert/converters.py
@@ -1,13 +1,19 @@
import datetime
import re
+import time
-from bert.erlang import ErlangTermDecoder
+from bert.erlang import ErlangTermDecoder, ErlangTermEncoder, Atom
-class BERTDecoder(ErlangTermDecoder):
- def __init__(self):
- pass
+def utc_to_datetime(seconds, microseconds):
+ return datetime.datetime.utcfromtimestamp(seconds).replace(microsecond=microseconds)
+
+def datetime_to_utc(dt):
+ # Can't use time.mktime as it assume local timezone
+ delta = dt - datetime.datetime(1970, 1, 1, 0, 0)
+ return delta.days * 24 * 60 * 60 + delta.seconds, dt.microsecond
+class BERTDecoder(ErlangTermDecoder):
def decode(self, bytes, offset=0):
obj = super(BERTDecoder, self).decode(bytes, offset)
return self.convert(obj)
@@ -28,12 +34,12 @@ def convert_bert(self, item):
return None
elif item[1] == "dict":
return dict((self.convert(k), self.convert(v)) for k, v in item[2])
- elif item[1] == "true":
+ elif item[1] in ("true", True):
return True
- elif item[1] == "false":
+ elif item[1] in ("false", False):
return False
elif item[1] == "time":
- return datetime.timedelta(seconds=item[2] * 1000000 + item[3], microseconds=item[4])
+ return utc_to_datetime(item[2] * 1000000 + item[3], item[4])
elif item[1] == "regex":
flags = 0
if 'extended' in item[3]:
@@ -45,4 +51,37 @@ def convert_bert(self, item):
if 'dotall' in item[3]:
flags |= re.DOTALL
return re.compile(item[2], flags)
- return None
+ raise NotImplementedError("Unknown BERT type %s" % item[1])
+
+class BERTEncoder(ErlangTermEncoder):
+ def encode(self, obj):
+ bert = self.convert(obj)
+ return super(BERTEncoder, self).encode(bert)
+
+ def convert(self, obj):
+ if obj is True:
+ return (Atom("bert"), Atom("true"))
+ elif obj is False:
+ return (Atom("bert"), Atom("false"))
+ elif obj is None:
+ return (Atom("bert"), Atom("nil"))
+ elif isinstance(obj, dict):
+ return (Atom("bert"), Atom("dict"), [(self.convert(k), self.convert(v)) for k, v in obj.items()])
+ elif isinstance(obj, datetime.datetime):
+ seconds, microseconds = datetime_to_utc(obj)
+ megaseconds = seconds // 1000000
+ seconds = seconds % 1000000
+ return (Atom("bert"), Atom("time"), megaseconds, seconds, microseconds)
+ # elif isinstance(obj, re):
+ elif isinstance(obj, list):
+ return [self.convert(item) for item in obj]
+ elif isinstance(obj, tuple):
+ return tuple(self.convert(item) for item in obj)
+ return obj
+
+def datetime_to_split_time(dt):
+ seconds = int(time.mktime(dt.timetuple()))
+ megaseconds = seconds // 1000000
+ seconds = seconds % 1000000
+ microseconds = dt.microsecond
+ return megaseconds, seconds, microseconds
View
98 bert/erlang.py
@@ -1,27 +1,32 @@
"""Erlang External Term Format serializer/deserializer"""
+from __future__ import division
+
+import math
import struct
-NEW_FLOAT_EXT = 70 # [Float64:IEEE float]
-SMALL_INTEGER_EXT = 97 # [UInt8:Int] Unsigned 8 bit integer
-INTEGER_EXT = 98 # [Int32:Int] Signed 32 bit integer in big-endian format
-FLOAT_EXT = 99 # [31:Float String] Float in string format (formatted "%.20e", sscanf "%lf"). Superseded by NEW_FLOAT_EXT
-ATOM_EXT = 100 # [UInt16:Len, Len:AtomName] max Len is 255
-SMALL_TUPLE_EXT = 104 # [UInt8:Arity, N:Elements]
-LARGE_TUPLE_EXT = 105 # [UInt32:Arity, N:Elements]
-NIL_EXT = 106 # empty list
-STRING_EXT = 107 # [UInt32:Len, Len:Characters]
-LIST_EXT = 108 # [UInt32:Len, Elements, Tail]
-BINARY_EXT = 109 # [UInt32:Len, Len:Data]
-SMALL_BIG_EXT = 110 # [UInt8:n, UInt8:Sign, n:nums]
-LARGE_BIG_EXT = 111 # [UInt32:n, UInt8:Sign, n:nums]
+NEW_FLOAT_EXT = 'F' # 70 [Float64:IEEE float]
+SMALL_INTEGER_EXT = 'a' # 97 [UInt8:Int] Unsigned 8 bit integer
+INTEGER_EXT = 'b' # 98 [Int32:Int] Signed 32 bit integer in big-endian format
+FLOAT_EXT = 'c' # 99 [31:Float String] Float in string format (formatted "%.20e", sscanf "%lf"). Superseded by NEW_FLOAT_EXT
+ATOM_EXT = 'd' # 100 [UInt16:Len, Len:AtomName] max Len is 255
+SMALL_TUPLE_EXT = 'h' # 104 [UInt8:Arity, N:Elements]
+LARGE_TUPLE_EXT = 'i' # 105 [UInt32:Arity, N:Elements]
+NIL_EXT = 'j' # 106 empty list
+STRING_EXT = 'k' # 107 [UInt32:Len, Len:Characters]
+LIST_EXT = 'l' # 108 [UInt32:Len, Elements, Tail]
+BINARY_EXT = 'm' # 109 [UInt32:Len, Len:Data]
+SMALL_BIG_EXT = 'n' # 110 [UInt8:n, UInt8:Sign, n:nums]
+LARGE_BIG_EXT = 'o' # 111 [UInt32:n, UInt8:Sign, n:nums]
class Atom(str):
- pass
+ def __repr__(self):
+ return "Atom(%s)" % super(Atom, self).__repr__()
class Binary(str):
- pass
+ def __repr__(self):
+ return "Binary(%s)" % super(Binary, self).__repr__()
class ErlangTermDecoder(object):
def __init__(self):
@@ -33,7 +38,7 @@ def decode(self, bytes, offset=0):
return self._decode(bytes, offset)[0]
def _decode(self, bytes, offset=0):
- tag = ord(bytes[offset])
+ tag = bytes[offset]
offset += 1
if tag == SMALL_INTEGER_EXT:
return ord(bytes[offset]), offset+1
@@ -106,3 +111,64 @@ def _decode(self, bytes, offset=0):
else:
raise NotImplementedError("Unsupported tag %d" % tag)
+class ErlangTermEncoder(object):
+ def __init__(self):
+ pass
+
+ def encode(self, obj):
+ bytes = [chr(131)]
+ self._encode(obj, bytes)
+ return "".join(bytes)
+
+ def _encode(self, obj, bytes):
+ if obj is False:
+ bytes += [ATOM_EXT, struct.pack(">H", 5), "false"]
+ elif obj is True:
+ bytes += [ATOM_EXT, struct.pack(">H", 4), "true"]
+ elif isinstance(obj, (int, long)):
+ if 0 <= obj <= 255:
+ bytes += [SMALL_INTEGER_EXT, chr(obj)]
+ elif -2147483648 <= obj <= 2147483647:
+ bytes += [INTEGER_EXT, struct.pack(">l", obj)]
+ else:
+ n = int(math.ceil(math.log(obj, 2) / 8))
+ if n <= 256:
+ bytes += [SMALL_BIG_EXT, chr(n)]
+ else:
+ bytes += [LARGE_BIG_EXT, struct.pack(">L", n)]
+ if obj >= 0:
+ bytes.append("\x00")
+ else:
+ bytes.append("\x01")
+ obj = -obj
+ while obj > 0:
+ bytes.append(chr(obj & 0xff))
+ obj >>= 8
+ elif isinstance(obj, float):
+ floatstr = "%.20e" % obj
+ bytes += [FLOAT_EXT, floatstr + "\x00"*(31-len(floatstr))]
+ elif isinstance(obj, Atom):
+ bytes += [ATOM_EXT, struct.pack(">H", len(obj)), obj]
+ elif isinstance(obj, (Binary, buffer)):
+ bytes += [BINARY_EXT, struct.pack(">L", len(obj)), obj]
+ elif isinstance(obj, str):
+ bytes += [STRING_EXT, struct.pack(">H", len(obj)), obj]
+ elif isinstance(obj, unicode):
+ self._encode([ord(x) for x in obj], bytes)
+ elif isinstance(obj, tuple):
+ n = len(obj)
+ if n < 256:
+ bytes += [SMALL_TUPLE_EXT, chr(n)]
+ else:
+ bytes += [LARGE_TUPLE_EXT, struct.pack(">L", n)]
+ for item in obj:
+ self._encode(item, bytes)
+ elif obj == []:
+ bytes.append(NIL_EXT)
+ elif isinstance(obj, list):
+ bytes += [LIST_EXT, struct.pack(">L", len(obj))]
+ for item in obj:
+ self._encode(item, bytes)
+ bytes.append(NIL_EXT) # list tail - no such thing in Python
+ else:
+ raise NotImplementedError("Unable to serialize %r" % obj)
View
5 test.py
@@ -3,6 +3,7 @@
import unittest
if __name__ == '__main__':
- from tests.erlangdecoder import *
- from tests.bertdecoder import *
+ from tests import *
+ from tests.erlangtests import *
+ from tests.berttests import *
unittest.main()
View
21 tests/__init__.py
@@ -0,0 +1,21 @@
+
+import datetime
+import unittest
+
+from bert.converters import utc_to_datetime, datetime_to_utc
+
+class TestDateConversion(unittest.TestCase):
+ test_dates = [
+ (datetime.datetime(1970, 1, 1, 0, 0, 0, 0), (0, 0)),
+ (datetime.datetime(2009, 1, 8, 4, 27, 47), (1231388867, 0)),
+ (datetime.datetime(2009, 10, 8, 4, 27, 47, 123), (1254976067, 123)),
+ (datetime.datetime(2009, 1, 8, 4, 27, 47, 456), (1231388867, 456)),
+ ]
+
+ def testToDatetime(self):
+ for dt, tstamp in self.test_dates:
+ self.failUnlessEqual(dt, utc_to_datetime(tstamp[0], tstamp[1]))
+
+ def testFromDatetime(self):
+ for dt, tstamp in self.test_dates:
+ self.failUnlessEqual(tstamp, datetime_to_utc(dt))
View
60 tests/bertdecoder.py
@@ -1,60 +0,0 @@
-#!/usr/bin/env python
-
-import datetime
-import re
-import unittest
-
-from bert import BERTDecoder
-
-class BERTDecoderTest(unittest.TestCase):
- def setUp(self):
- self.decoder = BERTDecoder()
-
- def tearDown(self):
- pass
-
- def testNone(self):
- self.failUnlessEqual(None, self.convert(("bert", "nil")))
-
- def testNestedNone(self):
- self.failUnlessEqual([None, (None,)], self.convert([("bert", "nil"), (("bert", "nil"),)]))
-
- def testDict(self):
- self.failUnlessEqual({'foo': 'bar'}, self.convert(('bert', 'dict', [('foo', 'bar')])))
-
- def testEmptyDict(self):
- self.failUnlessEqual({}, self.convert(('bert', 'dict', [])))
-
- def testNestedDict(self):
- self.failUnlessEqual({'foo': {'baz': 'bar'}},
- self.convert(
- ('bert', 'dict', [
- ('foo', ('bert', 'dict', [
- ('baz', 'bar')]))])))
-
- def testTrue(self):
- self.failUnlessEqual(True, self.convert(('bert', 'true')))
-
- def testFalse(self):
- self.failUnlessEqual(False, self.convert(('bert', 'false')))
-
- def testTime(self):
- self.failUnlessEqual(datetime.timedelta(seconds=123*1000000+456, microseconds=789),
- self.convert(('bert', 'time', 123, 456, 789)))
-
- def testRegex(self):
- before = ('bert', 'regex', '^c(a)t$', ('caseless', 'extended'))
- # after = re.compile('^c(a)t$', re.I|re.X)
- # self.failUnlessEqual(after, self.convert(before))
- self.failUnlessEqual(str(type(self.convert(before))), "<type '_sre.SRE_Pattern'>")
-
- def testOther(self):
- """Conversion shouldn't change non-bert values"""
- before = [1, 2.0, ("foo", "bar")]
- self.failUnlessEqual(before, self.convert(before))
-
- def convert(self, term):
- return self.decoder.convert(term)
-
-if __name__ == '__main__':
- unittest.main()
View
51 tests/berttests.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+import datetime
+import re
+import unittest
+
+from bert import BERTDecoder, BERTEncoder
+
+bert_tests = [
+ # nil
+ (None, ("bert", "nil")),
+ # nested nil
+ ([None, (None,)], [("bert", "nil"), (("bert", "nil"),)]),
+ # dict
+ ({'foo': 'bar'}, ('bert', 'dict', [('foo', 'bar')])),
+ # empty dict
+ ({}, ('bert', 'dict', [])),
+ # nested dict
+ ({'foo': {'baz': 'bar'}}, ('bert', 'dict', [('foo', ('bert', 'dict', [('baz', 'bar')]))])),
+ # true
+ (True, ('bert', 'true')),
+ # false
+ (False, ('bert', 'false')),
+ # time
+ (datetime.datetime.utcfromtimestamp(123*1000000+456).replace(microsecond=789), ('bert', 'time', 123, 456, 789)),
+ # regex
+ # (re.compile('^c(a)t$', re.I|re.X), ('bert', 'regex', '^c(a)t$', ('caseless', 'extended'))),
+ # other
+ ([1, 2.0, ("foo", "bar")], [1, 2.0, ("foo", "bar")]),
+]
+
+class BERTTestCase(unittest.TestCase):
+ def testDecode(self):
+ convert = BERTDecoder().convert
+ for python, bert in bert_tests:
+ self.failUnlessEqual(python, convert(bert))
+
+ def testEncode(self):
+ convert = BERTEncoder().convert
+ for python, bert in bert_tests:
+ self.failUnlessEqual(bert, convert(python))
+
+ def testRegex(self):
+ convert = BERTDecoder().convert
+ before = ('bert', 'regex', '^c(a)t$', ('caseless', 'extended'))
+ # after = re.compile('^c(a)t$', re.I|re.X)
+ # self.failUnlessEqual(after, self.convert(before))
+ self.failUnlessEqual(str(type(convert(before))), "<type '_sre.SRE_Pattern'>")
+
+if __name__ == '__main__':
+ unittest.main()
View
102 tests/erlangdecoder.py
@@ -1,102 +0,0 @@
-#!/usr/bin/env python
-
-import unittest
-
-from bert import ErlangTermDecoder, Atom, Binary
-
-class ErlangDecoderTest(unittest.TestCase):
- def setUp(self):
- self.decoder = ErlangTermDecoder()
-
- def testNil(self):
- decoded = self.decode([131, 106])
- self.failUnlessEqual([], decoded)
- self.failUnless(isinstance(decoded, list))
-
- def testBinary(self):
- decoded = self.decode([131,109,0,0,0,3,102,111,111])
- self.failUnlessEqual("foo", decoded)
- self.failUnless(isinstance(decoded, Binary))
-
- def testAtom(self):
- decoded = self.decode([131,100,0,3,102,111,111])
- self.failUnlessEqual("foo", decoded)
- self.failUnless(isinstance(decoded, Atom))
-
- def testAtomFalse(self):
- decoded = self.decode([131,100,0,4,116,114,117,101])
- self.failUnlessEqual(True, decoded)
-
- def testAtomFalse(self):
- decoded = self.decode([131,100,0,5,102,97,108,115,101])
- self.failUnlessEqual(False, decoded)
-
- def testString(self):
- decoded = self.decode([131,107,0,3,102,111,111])
- self.failUnlessEqual("foo", decoded)
-
- def testSmallInteger(self):
- decoded = self.decode([131,97,123])
- self.failUnlessEqual(123, decoded)
-
- def testInteger(self):
- decoded = self.decode([131,98,0,0,48,57])
- self.failUnlessEqual(12345, decoded)
-
- def testFloat(self):
- decoded = self.decode([131,99,49,46,50,51,52,52,57,57,57,57,57,57,57,57,57,57,57,57,51,48,55,50,101,43,48,48,0,0,0,0,0])
- self.failUnlessEqual(1.2345, decoded)
-
- def testFloat(self):
- decoded = self.decode([131,99,49,46,50,51,52,52,57,57,57,57,57,57,57,57,57,57,57,57,51,48,55,50,101,43,48,48,0,0,0,0,0])
- self.failUnlessEqual(1.2345, decoded)
-
- def testTuple(self):
- decoded = self.decode([131,104,3,100,0,3,102,111,111,107,0,4,116,101,115,116,97,123])
- self.failUnless(isinstance(decoded, tuple))
- self.failUnlessEqual(("foo", "test", 123), decoded)
-
- def testList(self):
- decoded = self.decode([131,108,0,0,0,3,98,0,0,4,0,107,0,4,116,101,115,116,99,
- 52,46,48,57,54,48,48,48,48,48,48,48,48,48,48,48,48,48,
- 56,53,50,55,101,43,48,48,0,0,0,0,0,106])
- self.failUnless(isinstance(decoded, list))
- self.failUnlessEqual([1024, "test", 4.096], decoded)
-
- def testSmallBig(self):
- decoded = self.decode([131,110,8,0,210,10,31,235,140,169,84,171])
- self.failUnlessEqual(12345678901234567890, decoded)
-
- def testLargeBig(self):
- decoded = self.decode([131,111,0,0,1,68,0,210,10,63,206,150,241,207,172,75,241,
- 123,239,97,17,61,36,94,147,169,136,23,160,194,1,165,37,
- 183,227,81,27,0,235,231,229,213,80,111,152,189,144,241,
- 195,221,82,131,209,41,252,38,234,72,195,49,119,241,7,
- 243,243,51,143,183,150,131,5,116,236,105,156,89,34,152,
- 152,105,202,17,98,89,61,204,161,180,82,27,108,1,134,24,
- 233,162,51,170,20,239,17,91,125,79,20,82,85,24,36,254,
- 127,150,148,206,114,63,215,139,154,167,118,189,187,43,7,
- 88,148,120,127,73,2,52,46,160,204,222,239,58,167,137,
- 126,164,175,98,228,193,7,29,243,99,108,124,48,201,80,96,
- 191,171,149,122,162,68,81,102,247,202,239,176,196,61,17,
- 6,42,58,89,245,56,175,24,167,129,19,223,189,84,108,52,
- 224,0,238,147,214,131,86,201,60,231,73,223,168,46,245,
- 252,164,36,82,149,239,209,167,210,137,206,117,33,248,8,
- 177,90,118,166,217,122,219,48,136,16,243,127,211,115,99,
- 152,91,26,172,54,86,31,173,48,41,208,151,56,209,2,230,
- 251,72,20,57,220,41,46,181,146,246,145,65,27,205,184,96,
- 66,198,4,131,76,192,184,175,78,43,129,237,236,63,59,31,
- 171,49,193,94,74,255,79,30,1,135,72,15,46,90,68,6,240,
- 186,107,170,103,86,72,93,23,230,73,46,66,20,97,50,193,
- 59,209,43,234,46,228,146,21,147,233,39,69,208,40,205,
- 144,251,16])
- self.failUnlessEqual(123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890, decoded)
-
-
- def decode(self, binaryterm):
- if isinstance(binaryterm, (list, tuple)):
- binaryterm = "".join(chr(x) for x in binaryterm)
- return self.decoder.decode(binaryterm)
-
-if __name__ == '__main__':
- unittest.main()
View
50 tests/erlangtests.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+import unittest
+
+from bert import erlang_encode, erlang_decode, Atom, Binary
+
+erlang_term_binaries = [
+ # nil
+ ([], list, "\x83j"),
+ # binary
+ (Binary("foo"), Binary, '\x83m\x00\x00\x00\x03foo'),
+ # atom
+ (Atom("foo"), Atom, '\x83d\x00\x03foo'),
+ # atom true
+ (True, bool, '\x83d\x00\x04true'),
+ # atom false
+ (False, bool, '\x83d\x00\x05false'),
+ # string
+ ("foo", str, '\x83k\x00\x03foo'),
+ # small integer
+ (123, int, '\x83a{'),
+ # integer
+ (12345, int, '\x83b\x00\x0009'),
+ # float
+ (1.2345, float, '\x83c1.23449999999999993072e+00\x00\x00\x00\x00\x00'),
+ # tuple
+ ((Atom("foo"), "test", 123), tuple, '\x83h\x03d\x00\x03fook\x00\x04testa{'),
+ # list
+ ([1024, "test", 4.096], list, '\x83l\x00\x00\x00\x03b\x00\x00\x04\x00k\x00\x04testc4.09600000000000008527e+00\x00\x00\x00\x00\x00j'),
+ # small big
+ (12345678901234567890, long, '\x83n\x08\x00\xd2\n\x1f\xeb\x8c\xa9T\xab'),
+ # large big
+ (123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,
+ long, '\x83o\x00\x00\x01D\x00\xd2\n?\xce\x96\xf1\xcf\xacK\xf1{\xefa\x11=$^\x93\xa9\x88\x17\xa0\xc2\x01\xa5%\xb7\xe3Q\x1b\x00\xeb\xe7\xe5\xd5Po\x98\xbd\x90\xf1\xc3\xddR\x83\xd1)\xfc&\xeaH\xc31w\xf1\x07\xf3\xf33\x8f\xb7\x96\x83\x05t\xeci\x9cY"\x98\x98i\xca\x11bY=\xcc\xa1\xb4R\x1bl\x01\x86\x18\xe9\xa23\xaa\x14\xef\x11[}O\x14RU\x18$\xfe\x7f\x96\x94\xcer?\xd7\x8b\x9a\xa7v\xbd\xbb+\x07X\x94x\x7fI\x024.\xa0\xcc\xde\xef:\xa7\x89~\xa4\xafb\xe4\xc1\x07\x1d\xf3cl|0\xc9P`\xbf\xab\x95z\xa2DQf\xf7\xca\xef\xb0\xc4=\x11\x06*:Y\xf58\xaf\x18\xa7\x81\x13\xdf\xbdTl4\xe0\x00\xee\x93\xd6\x83V\xc9<\xe7I\xdf\xa8.\xf5\xfc\xa4$R\x95\xef\xd1\xa7\xd2\x89\xceu!\xf8\x08\xb1Zv\xa6\xd9z\xdb0\x88\x10\xf3\x7f\xd3sc\x98[\x1a\xac6V\x1f\xad0)\xd0\x978\xd1\x02\xe6\xfbH\x149\xdc).\xb5\x92\xf6\x91A\x1b\xcd\xb8`B\xc6\x04\x83L\xc0\xb8\xafN+\x81\xed\xec?;\x1f\xab1\xc1^J\xffO\x1e\x01\x87H\x0f.ZD\x06\xf0\xbak\xaagVH]\x17\xe6I.B\x14a2\xc1;\xd1+\xea.\xe4\x92\x15\x93\xe9\'E\xd0(\xcd\x90\xfb\x10'),
+]
+
+class ErlangTestCase(unittest.TestCase):
+ def testDecode(self):
+ for python, expected_type, erlang in erlang_term_binaries:
+ decoded = erlang_decode(erlang)
+ self.failUnlessEqual(python, decoded)
+ self.failUnless(isinstance(decoded, expected_type))
+
+ def testEncode(self):
+ for python, expected_type, erlang in erlang_term_binaries:
+ encoded = erlang_encode(python)
+ self.failUnlessEqual(erlang, encoded)
+
+if __name__ == '__main__':
+ unittest.main()

0 comments on commit 668685b

Please sign in to comment.
Something went wrong with that request. Please try again.