Add concept of delimeter to complemend terminator in LineProtocol

This commit is contained in:
Thomas Adamcik 2011-07-25 00:50:41 +02:00
parent 2a0646cc43
commit 4049b23c3f
2 changed files with 39 additions and 2 deletions

View File

@ -278,9 +278,13 @@ class LineProtocol(ThreadingActor):
then splitting data along line boundaries.
"""
#: What terminator to use to split lines.
#: Line terinator to use for outputed lines.
terminator = '\n'
#: Regex to use for splitings lines, will be set compiled version of its
#: own value, or to `terminator`s value if it is not set itself.
delimeter = None
#: What encoding to expect incomming data to be in, can be :class:`None`.
encoding = 'utf-8'
@ -288,6 +292,11 @@ class LineProtocol(ThreadingActor):
self.connection = connection
self.recv_buffer = ''
if self.delimeter:
self.delimeter = re.compile(self.delimeter)
else:
self.delimeter = re.compile(self.terminator)
@property
def host(self):
return self.connection.host
@ -325,7 +334,7 @@ class LineProtocol(ThreadingActor):
def parse_lines(self):
"""Consume new data and yield any lines found."""
while re.search(self.terminator, self.recv_buffer):
line, self.recv_buffer = re.split(self.terminator,
line, self.recv_buffer = self.delimeter.split(
self.recv_buffer, 1)
yield line

View File

@ -1,5 +1,6 @@
#encoding: utf-8
import re
import unittest
from mopidy.utils import network
@ -11,11 +12,21 @@ class LineProtocolTest(unittest.TestCase):
self.mock = Mock(spec=network.LineProtocol)
self.mock.terminator = network.LineProtocol.terminator
self.mock.encoding = network.LineProtocol.encoding
self.mock.delimeter = network.LineProtocol.delimeter
def test_init_stores_values_in_attributes(self):
delimeter = re.compile(network.LineProtocol.terminator)
network.LineProtocol.__init__(self.mock, sentinel.connection)
self.assertEqual(sentinel.connection, self.mock.connection)
self.assertEqual('', self.mock.recv_buffer)
self.assertEqual(delimeter, self.mock.delimeter)
def test_init_compiles_delimeter(self):
self.mock.delimeter = '\r?\n'
delimeter = re.compile('\r?\n')
network.LineProtocol.__init__(self.mock, sentinel.connection)
self.assertEqual(delimeter, self.mock.delimeter)
def test_on_receive_no_new_lines_adds_to_recv_buffer(self):
self.mock.connection = Mock(spec=network.Connection)
@ -74,18 +85,21 @@ class LineProtocolTest(unittest.TestCase):
self.assertEqual(2, self.mock.on_line_received.call_count)
def test_parse_lines_emtpy_buffer(self):
self.mock.delimeter = re.compile(r'\n')
self.mock.recv_buffer = ''
lines = network.LineProtocol.parse_lines(self.mock)
self.assertRaises(StopIteration, lines.next)
def test_parse_lines_no_terminator(self):
self.mock.delimeter = re.compile(r'\n')
self.mock.recv_buffer = 'data'
lines = network.LineProtocol.parse_lines(self.mock)
self.assertRaises(StopIteration, lines.next)
def test_parse_lines_termintor(self):
self.mock.delimeter = re.compile(r'\n')
self.mock.recv_buffer = 'data\n'
lines = network.LineProtocol.parse_lines(self.mock)
@ -93,7 +107,17 @@ class LineProtocolTest(unittest.TestCase):
self.assertRaises(StopIteration, lines.next)
self.assertEqual('', self.mock.recv_buffer)
def test_parse_lines_termintor_with_carriage_return(self):
self.mock.delimeter = re.compile(r'\r?\n')
self.mock.recv_buffer = 'data\r\n'
lines = network.LineProtocol.parse_lines(self.mock)
self.assertEqual('data', lines.next())
self.assertRaises(StopIteration, lines.next)
self.assertEqual('', self.mock.recv_buffer)
def test_parse_lines_no_data_before_terminator(self):
self.mock.delimeter = re.compile(r'\n')
self.mock.recv_buffer = '\n'
lines = network.LineProtocol.parse_lines(self.mock)
@ -102,6 +126,7 @@ class LineProtocolTest(unittest.TestCase):
self.assertEqual('', self.mock.recv_buffer)
def test_parse_lines_extra_data_after_terminator(self):
self.mock.delimeter = re.compile(r'\n')
self.mock.recv_buffer = 'data1\ndata2'
lines = network.LineProtocol.parse_lines(self.mock)
@ -110,6 +135,7 @@ class LineProtocolTest(unittest.TestCase):
self.assertEqual('data2', self.mock.recv_buffer)
def test_parse_lines_unicode(self):
self.mock.delimeter = re.compile(r'\n')
self.mock.recv_buffer = u'æøå\n'.encode('utf-8')
lines = network.LineProtocol.parse_lines(self.mock)
@ -118,6 +144,7 @@ class LineProtocolTest(unittest.TestCase):
self.assertEqual('', self.mock.recv_buffer)
def test_parse_lines_multiple_lines(self):
self.mock.delimeter = re.compile(r'\n')
self.mock.recv_buffer = 'abc\ndef\nghi\njkl'
lines = network.LineProtocol.parse_lines(self.mock)
@ -128,6 +155,7 @@ class LineProtocolTest(unittest.TestCase):
self.assertEqual('jkl', self.mock.recv_buffer)
def test_parse_lines_multiple_calls(self):
self.mock.delimeter = re.compile(r'\n')
self.mock.recv_buffer = 'data1'
lines = network.LineProtocol.parse_lines(self.mock)