Merge branch 'feature/support-telnet' into develop
This commit is contained in:
commit
83162be149
@ -70,6 +70,7 @@ class MpdSession(network.LineProtocol):
|
||||
|
||||
terminator = protocol.LINE_TERMINATOR
|
||||
encoding = protocol.ENCODING
|
||||
delimeter = r'\r?\n'
|
||||
|
||||
def __init__(self, connection):
|
||||
super(MpdSession, self).__init__(connection)
|
||||
|
||||
@ -278,9 +278,13 @@ class LineProtocol(ThreadingActor):
|
||||
then splitting data along line boundaries.
|
||||
"""
|
||||
|
||||
#: What terminator to use to split lines.
|
||||
#: Line terminator to use for outputed lines.
|
||||
terminator = '\n'
|
||||
|
||||
#: Regex to use for spliting 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'
|
||||
|
||||
@ -289,6 +293,11 @@ class LineProtocol(ThreadingActor):
|
||||
self.prevent_timeout = False
|
||||
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
|
||||
@ -315,7 +324,8 @@ class LineProtocol(ThreadingActor):
|
||||
|
||||
for line in self.parse_lines():
|
||||
line = self.decode(line)
|
||||
self.on_line_received(line)
|
||||
if line is not None:
|
||||
self.on_line_received(line)
|
||||
|
||||
if not self.prevent_timeout:
|
||||
self.connection.enable_timeout()
|
||||
@ -327,7 +337,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
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#encoding: utf-8
|
||||
|
||||
import re
|
||||
import unittest
|
||||
|
||||
from mopidy.utils import network
|
||||
@ -9,16 +10,27 @@ from mock import sentinel, Mock
|
||||
class LineProtocolTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.mock = Mock(spec=network.LineProtocol)
|
||||
|
||||
self.mock.terminator = network.LineProtocol.terminator
|
||||
self.mock.encoding = network.LineProtocol.encoding
|
||||
self.mock.delimeter = network.LineProtocol.delimeter
|
||||
self.mock.prevent_timeout = False
|
||||
|
||||
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)
|
||||
self.assertFalse(self.mock.prevent_timeout)
|
||||
|
||||
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)
|
||||
self.mock.recv_buffer = ''
|
||||
@ -75,6 +87,15 @@ class LineProtocolTest(unittest.TestCase):
|
||||
network.LineProtocol.on_receive(self.mock, {'received': 'data\n'})
|
||||
self.mock.on_line_received.assert_called_once_with(sentinel.decoded)
|
||||
|
||||
def test_on_receive_with_new_line_with_failed_decode(self):
|
||||
self.mock.connection = Mock(spec=network.Connection)
|
||||
self.mock.recv_buffer = ''
|
||||
self.mock.parse_lines.return_value = [sentinel.line]
|
||||
self.mock.decode.return_value = None
|
||||
|
||||
network.LineProtocol.on_receive(self.mock, {'received': 'data\n'})
|
||||
self.assertEqual(0, self.mock.on_line_received.call_count)
|
||||
|
||||
def test_on_receive_with_new_lines_calls_on_recieve(self):
|
||||
self.mock.connection = Mock(spec=network.Connection)
|
||||
self.mock.recv_buffer = ''
|
||||
@ -86,18 +107,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)
|
||||
@ -105,7 +129,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)
|
||||
@ -114,6 +148,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)
|
||||
@ -122,6 +157,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)
|
||||
@ -130,6 +166,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)
|
||||
@ -140,6 +177,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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user