text: import logging
  import sys
  import unittest
  from unittest import mock
  
  from engineio import exceptions as engineio_exceptions
  from engineio import json
  from engineio import packet as engineio_packet
  import pytest
  
  from socketio import asyncio_namespace
  from socketio import client
  from socketio import exceptions
  from socketio import msgpack_packet
  from socketio import namespace
  from socketio import packet
  
  
  class TestClient(unittest.TestCase):
      def test_is_asyncio_based(self):
          c = client.Client()
          assert not c.is_asyncio_based()
  
      @mock.patch('socketio.client.Client._engineio_client_class')
      def test_create(self, engineio_client_class):
          c = client.Client(
              reconnection=False,
              reconnection_attempts=123,
              reconnection_delay=5,
              reconnection_delay_max=10,
              randomization_factor=0.2,
              handle_sigint=False,
              foo='bar',
          )
          assert not c.reconnection
          assert c.reconnection_attempts == 123
          assert c.reconnection_delay == 5
          assert c.reconnection_delay_max == 10
          assert c.randomization_factor == 0.2
          assert not c.handle_sigint
          engineio_client_class().assert_called_once_with(
              foo='bar', handle_sigint=False)
          assert c.connection_url is None
          assert c.connection_headers is None
          assert c.connection_transports is None
          assert c.connection_namespaces == []
          assert c.socketio_path is None
          assert c.sid is None
  
          assert c.namespaces == {}
          assert c.handlers == {}
          assert c.namespace_handlers == {}
          assert c.callbacks == {}
          assert c._binary_packet is None
          assert c._reconnect_task is None
          assert c.packet_class == packet.Packet
  
      def test_msgpack(self):
          c = client.Client(serializer='msgpack')
          assert c.packet_class == msgpack_packet.MsgPackPacket
  
      def test_custom_serializer(self):
          class CustomPacket(packet.Packet):
              pass
  
          c = client.Client(serializer=CustomPacket)
          assert c.packet_class == CustomPacket
  
      def test_custom_json(self):
          client.Client()
          assert packet.Packet.json == json
          assert engineio_packet.Packet.json == json
          client.Client(json='foo')
          assert packet.Packet.json == 'foo'
          assert engineio_packet.Packet.json == 'foo'
          packet.Packet.json = json
  
      def test_logger(self):
          c = client.Client(logger=False)
          assert c.logger.getEffectiveLevel() == logging.ERROR
          c.logger.setLevel(logging.NOTSET)
          c = client.Client(logger=True)
          assert c.logger.getEffectiveLevel() == logging.INFO
          c.logger.setLevel(logging.WARNING)
          c = client.Client(logger=True)
          assert c.logger.getEffectiveLevel() == logging.WARNING
          c.logger.setLevel(logging.NOTSET)
          my_logger = logging.Logger('foo')
          c = client.Client(logger=my_logger)
          assert c.logger == my_logger
  
      @mock.patch('socketio.client.Client._engineio_client_class')
      def test_engineio_logger(self, engineio_client_class):
          client.Client(engineio_logger='foo')
          engineio_client_class().assert_called_once_with(
              handle_sigint=True, logger='foo')
  
      def test_on_event(self):
          c = client.Client()
  
          @c.on('connect')
          def foo():
              pass
  
          def bar():
              pass
  
          c.on('disconnect', bar)
          c.on('disconnect', bar, namespace='/foo')
  
          assert c.handlers['/']['connect'] == foo
          assert c.handlers['/']['disconnect'] == bar
          assert c.handlers['/foo']['disconnect'] == bar
  
      def test_event(self):
          c = client.Client()
  
          @c.event
          def connect():
              pass
  
          @c.event
          def foo():
              pass
  
          @c.event
          def bar():
              pass
  
          @c.event(namespace='/foo')
          def disconnect():
              pass
  
          assert c.handlers['/']['connect'] == connect
          assert c.handlers['/']['foo'] == foo
          assert c.handlers['/']['bar'] == bar
          assert c.handlers['/foo']['disconnect'] == disconnect
  
      def test_namespace_handler(self):
          class MyNamespace(namespace.ClientNamespace):
              pass
  
          c = client.Client()
          n = MyNamespace('/foo')
          c.register_namespace(n)
          assert c.namespace_handlers['/foo'] == n
  
      def test_namespace_handler_wrong_class(self):
          class MyNamespace(object):
              def __init__(self, n):
                  pass
  
          c = client.Client()
          n = MyNamespace('/foo')
          with pytest.raises(ValueError):
              c.register_namespace(n)
  
      @unittest.skipIf(sys.version_info < (3, 0), 'only for Python 3')
      def test_namespace_handler_wrong_async(self):
          class MyNamespace(asyncio_namespace.AsyncClientNamespace):
              pass
  
          c = client.Client()
          n = MyNamespace('/foo')
          with pytest.raises(ValueError):
              c.register_namespace(n)
  
      def test_connect(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock()
          c.connect(
              'url',
              headers='headers',
              auth='auth',
              transports='transports',
              namespaces=['/foo', '/', '/bar'],
              socketio_path='path',
              wait=False,
          )
          assert c.connection_url == 'url'
          assert c.connection_headers == 'headers'
          assert c.connection_auth == 'auth'
          assert c.connection_transports == 'transports'
          assert c.connection_namespaces == ['/foo', '/', '/bar']
          assert c.socketio_path == 'path'
          c.eio.connect.assert_called_once_with(
              'url',
              headers='headers',
              transports='transports',
              engineio_path='path',
          )
  
      def test_connect_functions(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock()
          c.connect(
              lambda: 'url',
              headers=lambda: 'headers',
              auth='auth',
              transports='transports',
              namespaces=['/foo', '/', '/bar'],
              socketio_path='path',
              wait=False,
          )
          c.eio.connect.assert_called_once_with(
              'url',
              headers='headers',
              transports='transports',
              engineio_path='path',
          )
  
      def test_connect_one_namespace(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock()
          c.connect(
              'url',
              headers='headers',
              transports='transports',
              namespaces='/foo',
              socketio_path='path',
              wait=False,
          )
          assert c.connection_url == 'url'
          assert c.connection_headers == 'headers'
          assert c.connection_transports == 'transports'
          assert c.connection_namespaces == ['/foo']
          assert c.socketio_path == 'path'
          c.eio.connect.assert_called_once_with(
              'url',
              headers='headers',
              transports='transports',
              engineio_path='path',
          )
  
      def test_connect_default_namespaces(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock()
          c.on('foo', mock.MagicMock(), namespace='/foo')
          c.on('bar', mock.MagicMock(), namespace='/')
          c.connect(
              'url',
              headers='headers',
              transports='transports',
              socketio_path='path',
              wait=False,
          )
          assert c.connection_url == 'url'
          assert c.connection_headers == 'headers'
          assert c.connection_transports == 'transports'
          assert c.connection_namespaces == ['/foo', '/'] or \
              c.connection_namespaces == ['/', '/foo']
          assert c.socketio_path == 'path'
          c.eio.connect.assert_called_once_with(
              'url',
              headers='headers',
              transports='transports',
              engineio_path='path',
          )
  
      def test_connect_no_namespaces(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock()
          c.connect(
              'url',
              headers='headers',
              transports='transports',
              socketio_path='path',
              wait=False,
          )
          assert c.connection_url == 'url'
          assert c.connection_headers == 'headers'
          assert c.connection_transports == 'transports'
          assert c.connection_namespaces == ['/']
          assert c.socketio_path == 'path'
          c.eio.connect.assert_called_once_with(
              'url',
              headers='headers',
              transports='transports',
              engineio_path='path',
          )
  
      def test_connect_error(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock(
              side_effect=engineio_exceptions.ConnectionError('foo')
          )
          c.on('foo', mock.MagicMock(), namespace='/foo')
          c.on('bar', mock.MagicMock(), namespace='/')
          with pytest.raises(exceptions.ConnectionError):
              c.connect(
                  'url',
                  headers='headers',
                  transports='transports',
                  socketio_path='path',
                  wait=False,
              )
  
      def test_connect_twice(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock()
          c.connect(
              'url',
              wait=False,
          )
          with pytest.raises(exceptions.ConnectionError):
              c.connect(
                  'url',
                  wait=False,
              )
  
      def test_connect_wait_single_namespace(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock()
          c._connect_event = mock.MagicMock()
  
          def mock_connect(timeout):
              assert timeout == 0.01
              c.namespaces = {'/': '123'}
              return True
  
          c._connect_event.wait = mock_connect
          c.connect(
              'url',
              wait=True,
              wait_timeout=0.01,
          )
          assert c.connected is True
  
      def test_connect_wait_two_namespaces(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock()
          c._connect_event = mock.MagicMock()
  
          def mock_connect(timeout):
              assert timeout == 0.01
              if c.namespaces == {}:
                  c.namespaces = {'/bar': '123'}
                  return True
              elif c.namespaces == {'/bar': '123'}:
                  c.namespaces = {'/bar': '123', '/foo': '456'}
                  return True
              return False
  
          c._connect_event.wait = mock_connect
          c.connect(
              'url',
              namespaces=['/foo', '/bar'],
              wait=True,
              wait_timeout=0.01,
          )
          assert c.connected is True
          assert c.namespaces == {'/bar': '123', '/foo': '456'}
  
      def test_connect_timeout(self):
          c = client.Client()
          c.eio.connect = mock.MagicMock()
          c.disconnect = mock.MagicMock()
          with pytest.raises(exceptions.ConnectionError):
              c.connect(
                  'url',
                  wait=True,
                  wait_timeout=0.01,
              )
          c.disconnect.assert_called_once_with()
  
      def test_wait_no_reconnect(self):
          c = client.Client()
          c.eio.wait = mock.MagicMock()
          c.sleep = mock.MagicMock()
          c._reconnect_task = None
          c.wait()
          c.eio.wait.assert_called_once_with()
          c.sleep.assert_called_once_with(1)
  
      def test_wait_reconnect_failed(self):
          c = client.Client()
          c.eio.wait = mock.MagicMock()
          c.sleep = mock.MagicMock()
          c._reconnect_task = mock.MagicMock()
          states = ['disconnected']
  
          def fake_join():
              c.eio.state = states.pop(0)
  
          c._reconnect_task.join = fake_join
          c.wait()
          c.eio.wait.assert_called_once_with()
          c.sleep.assert_called_once_with(1)
  
      def test_wait_reconnect_successful(self):
          c = client.Client()
          c.eio.wait = mock.MagicMock()
          c.sleep = mock.MagicMock()
          c._reconnect_task = mock.MagicMock()
          states = ['connected', 'disconnected']
  
          def fake_join():
              c.eio.state = states.pop(0)
  
          c._reconnect_task.join = fake_join
          c.wait()
          assert c.eio.wait.call_count == 2
          assert c.sleep.call_count == 2
  
      def test_get_sid(self):
          c = client.Client()
          c.namespaces = {'/': '1', '/foo': '2'}
          assert c.get_sid() == '1'
          assert c.get_sid('/') == '1'
          assert c.get_sid('/foo') == '2'
          assert c.get_sid('/bar') is None
  
      def test_emit_no_arguments(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
          c._send_packet = mock.MagicMock()
          c.emit('foo')
          expected_packet = packet.Packet(
              packet.EVENT, namespace='/', data=['foo'], id=None)
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_emit_one_argument(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
          c._send_packet = mock.MagicMock()
          c.emit('foo', 'bar')
          expected_packet = packet.Packet(
              packet.EVENT,
              namespace='/',
              data=['foo', 'bar'],
              id=None,
          )
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_emit_one_argument_list(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
          c._send_packet = mock.MagicMock()
          c.emit('foo', ['bar', 'baz'])
          expected_packet = packet.Packet(
              packet.EVENT,
              namespace='/',
              data=['foo', ['bar', 'baz']],
              id=None,
          )
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_emit_two_arguments(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
          c._send_packet = mock.MagicMock()
          c.emit('foo', ('bar', 'baz'))
          expected_packet = packet.Packet(
              packet.EVENT,
              namespace='/',
              data=['foo', 'bar', 'baz'],
              id=None,
          )
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_emit_namespace(self):
          c = client.Client()
          c.namespaces = ['/foo']
          c._send_packet = mock.MagicMock()
          c.emit('foo', namespace='/foo')
          expected_packet = packet.Packet(
              packet.EVENT, namespace='/foo', data=['foo'], id=None)
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_emit_unknown_namespace(self):
          c = client.Client()
          c.namespaces = ['/foo']
          with pytest.raises(exceptions.BadNamespaceError):
              c.emit('foo', namespace='/bar')
  
      def test_emit_with_callback(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
          c._send_packet = mock.MagicMock()
          c._generate_ack_id = mock.MagicMock(return_value=123)
          c.emit('foo', callback='cb')
          expected_packet = packet.Packet(
              packet.EVENT, namespace='/', data=['foo'], id=123)
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
          c._generate_ack_id.assert_called_once_with('/', 'cb')
  
      def test_emit_namespace_with_callback(self):
          c = client.Client()
          c.namespaces = {'/foo': '1'}
          c._send_packet = mock.MagicMock()
          c._generate_ack_id = mock.MagicMock(return_value=123)
          c.emit('foo', namespace='/foo', callback='cb')
          expected_packet = packet.Packet(
              packet.EVENT, namespace='/foo', data=['foo'], id=123)
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
          c._generate_ack_id.assert_called_once_with('/foo', 'cb')
  
      def test_emit_binary(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
          c._send_packet = mock.MagicMock()
          c.emit('foo', b'bar')
          expected_packet = packet.Packet(
              packet.EVENT,
              namespace='/',
              data=['foo', b'bar'],
              id=None,
          )
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_emit_not_binary(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
          c._send_packet = mock.MagicMock()
          c.emit('foo', 'bar')
          expected_packet = packet.Packet(
              packet.EVENT,
              namespace='/',
              data=['foo', 'bar'],
              id=None,
          )
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_send(self):
          c = client.Client()
          c.emit = mock.MagicMock()
          c.send('data', 'namespace', 'callback')
          c.emit.assert_called_once_with(
              'message', data='data', namespace='namespace', callback='callback'
          )
  
      def test_send_with_defaults(self):
          c = client.Client()
          c.emit = mock.MagicMock()
          c.send('data')
          c.emit.assert_called_once_with(
              'message', data='data', namespace=None, callback=None
          )
  
      def test_call(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
  
          def fake_event_wait(timeout=None):
              assert timeout == 60
              c._generate_ack_id.call_args_list[0][0][1]('foo', 321)
              return True
  
          c._send_packet = mock.MagicMock()
          c._generate_ack_id = mock.MagicMock(return_value=123)
          c.eio = mock.MagicMock()
          c.eio.create_event.return_value.wait = fake_event_wait
          assert c.call('foo') == ('foo', 321)
          expected_packet = packet.Packet(
              packet.EVENT, namespace='/', data=['foo'], id=123)
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_call_with_timeout(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
  
          def fake_event_wait(timeout=None):
              assert timeout == 12
              return False
  
          c._send_packet = mock.MagicMock()
          c._generate_ack_id = mock.MagicMock(return_value=123)
          c.eio = mock.MagicMock()
          c.eio.create_event.return_value.wait = fake_event_wait
          with pytest.raises(exceptions.TimeoutError):
              c.call('foo', timeout=12)
          expected_packet = packet.Packet(
              packet.EVENT, namespace='/', data=['foo'], id=123)
          assert c._send_packet.call_count == 1
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_disconnect(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/': '1'}
          c._trigger_event = mock.MagicMock()
          c._send_packet = mock.MagicMock()
          c.eio = mock.MagicMock()
          c.eio.state = 'connected'
          c.disconnect()
          assert c.connected
          assert c._trigger_event.call_count == 0
          assert c._send_packet.call_count == 1
          expected_packet = packet.Packet(packet.DISCONNECT, namespace='/')
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
          c.eio.disconnect.assert_called_once_with(abort=True)
  
      def test_disconnect_namespaces(self):
          c = client.Client()
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._trigger_event = mock.MagicMock()
          c._send_packet = mock.MagicMock()
          c.eio = mock.MagicMock()
          c.eio.state = 'connected'
          c.disconnect()
          assert c._trigger_event.call_count == 0
          assert c._send_packet.call_count == 2
          expected_packet = packet.Packet(packet.DISCONNECT, namespace='/foo')
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
          expected_packet = packet.Packet(packet.DISCONNECT, namespace='/bar')
          assert (
              c._send_packet.call_args_list[1][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_transport(self):
          c = client.Client()
          c.eio.transport = mock.MagicMock(return_value='foo')
          assert c.transport() == 'foo'
          c.eio.transport.assert_called_once_with()
  
      def test_start_background_task(self):
          c = client.Client()
          c.eio.start_background_task = mock.MagicMock(return_value='foo')
          assert c.start_background_task('foo', 'bar', baz='baz') == 'foo'
          c.eio.start_background_task.assert_called_once_with(
              'foo', 'bar', baz='baz'
          )
  
      def test_sleep(self):
          c = client.Client()
          c.eio.sleep = mock.MagicMock()
          c.sleep(1.23)
          c.eio.sleep.assert_called_once_with(1.23)
  
      def test_send_packet(self):
          c = client.Client()
          c.eio.send = mock.MagicMock()
          c._send_packet(packet.Packet(packet.EVENT, 'foo'))
          c.eio.send.assert_called_once_with('2"foo"')
  
      def test_send_packet_binary(self):
          c = client.Client()
          c.eio.send = mock.MagicMock()
          c._send_packet(packet.Packet(packet.EVENT, b'foo'))
          assert c.eio.send.call_args_list == [
              mock.call('51-{"_placeholder":true,"num":0}'),
              mock.call(b'foo'),
          ] or c.eio.send.call_args_list == [
              mock.call('51-{"num":0,"_placeholder":true}'),
              mock.call(b'foo'),
          ]
  
      def test_send_packet_default_binary(self):
          c = client.Client()
          c.eio.send = mock.MagicMock()
          c._send_packet(packet.Packet(packet.EVENT, 'foo'))
          c.eio.send.assert_called_once_with('2"foo"')
  
      def test_generate_ack_id(self):
          c = client.Client()
          assert c._generate_ack_id('/', 'cb') == 1
          assert c._generate_ack_id('/', 'cb') == 2
          assert c._generate_ack_id('/', 'cb') == 3
          assert c._generate_ack_id('/foo', 'cb') == 1
          assert c._generate_ack_id('/bar', 'cb') == 1
          assert c._generate_ack_id('/', 'cb') == 4
          assert c._generate_ack_id('/bar', 'cb') == 2
  
      def test_handle_connect(self):
          c = client.Client()
          c._connect_event = mock.MagicMock()
          c._trigger_event = mock.MagicMock()
          c._send_packet = mock.MagicMock()
          c._handle_connect('/', {'sid': '123'})
          assert c.namespaces == {'/': '123'}
          c._connect_event.set.assert_called_once_with()
          c._trigger_event.assert_called_once_with('connect', namespace='/')
          c._send_packet.assert_not_called()
  
      def test_handle_connect_with_namespaces(self):
          c = client.Client()
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._connect_event = mock.MagicMock()
          c._trigger_event = mock.MagicMock()
          c._send_packet = mock.MagicMock()
          c._handle_connect('/', {'sid': '3'})
          c._connect_event.set.assert_called_once_with()
          c._trigger_event.assert_called_once_with('connect', namespace='/')
          assert c.namespaces == {'/': '3', '/foo': '1', '/bar': '2'}
  
      def test_handle_connect_namespace(self):
          c = client.Client()
          c.namespaces = {'/foo': '1'}
          c._connect_event = mock.MagicMock()
          c._trigger_event = mock.MagicMock()
          c._send_packet = mock.MagicMock()
          c._handle_connect('/foo', {'sid': '123'})
          c._handle_connect('/bar', {'sid': '2'})
          assert c._trigger_event.call_count == 1
          c._connect_event.set.assert_called_once_with()
          c._trigger_event.assert_called_once_with('connect', namespace='/bar')
          assert c.namespaces == {'/foo': '1', '/bar': '2'}
  
      def test_handle_disconnect(self):
          c = client.Client()
          c.namespace = {'/': '1'}
          c.connected = True
          c._trigger_event = mock.MagicMock()
          c._handle_disconnect('/')
          c._trigger_event.assert_called_once_with('disconnect', namespace='/')
          assert not c.connected
          c._handle_disconnect('/')
          assert c._trigger_event.call_count == 1
  
      def test_handle_disconnect_namespace(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._trigger_event = mock.MagicMock()
          c._handle_disconnect('/foo')
          c._trigger_event.assert_called_once_with(
              'disconnect', namespace='/foo'
          )
          assert c.namespaces == {'/bar': '2'}
          assert c.connected
          c._handle_disconnect('/bar')
          c._trigger_event.assert_called_with(
              'disconnect', namespace='/bar'
          )
          assert c.namespaces == {}
          assert not c.connected
  
      def test_handle_disconnect_unknown_namespace(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._trigger_event = mock.MagicMock()
          c._handle_disconnect('/baz')
          c._trigger_event.assert_called_once_with(
              'disconnect', namespace='/baz'
          )
          assert c.namespaces == {'/foo': '1', '/bar': '2'}
          assert c.connected
  
      def test_handle_disconnect_default_namespace(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._trigger_event = mock.MagicMock()
          c._handle_disconnect('/')
          c._trigger_event.assert_called_with('disconnect', namespace='/')
          assert c.namespaces == {'/foo': '1', '/bar': '2'}
          assert c.connected
  
      def test_handle_event(self):
          c = client.Client()
          c._trigger_event = mock.MagicMock()
          c._handle_event('/', None, ['foo', ('bar', 'baz')])
          c._trigger_event.assert_called_once_with('foo', '/', ('bar', 'baz'))
  
      def test_handle_event_with_id_no_arguments(self):
          c = client.Client()
          c._trigger_event = mock.MagicMock(return_value=None)
          c._send_packet = mock.MagicMock()
          c._handle_event('/', 123, ['foo', ('bar', 'baz')])
          c._trigger_event.assert_called_once_with('foo', '/', ('bar', 'baz'))
          assert c._send_packet.call_count == 1
          expected_packet = packet.Packet(
              packet.ACK, namespace='/', id=123, data=[])
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_handle_event_with_id_one_argument(self):
          c = client.Client()
          c._trigger_event = mock.MagicMock(return_value='ret')
          c._send_packet = mock.MagicMock()
          c._handle_event('/', 123, ['foo', ('bar', 'baz')])
          c._trigger_event.assert_called_once_with('foo', '/', ('bar', 'baz'))
          assert c._send_packet.call_count == 1
          expected_packet = packet.Packet(
              packet.ACK, namespace='/', id=123, data=['ret'])
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_handle_event_with_id_one_list_argument(self):
          c = client.Client()
          c._trigger_event = mock.MagicMock(return_value=['a', 'b'])
          c._send_packet = mock.MagicMock()
          c._handle_event('/', 123, ['foo', ('bar', 'baz')])
          c._trigger_event.assert_called_once_with('foo', '/', ('bar', 'baz'))
          assert c._send_packet.call_count == 1
          expected_packet = packet.Packet(
              packet.ACK, namespace='/', id=123, data=[['a', 'b']])
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_handle_event_with_id_two_arguments(self):
          c = client.Client()
          c._trigger_event = mock.MagicMock(return_value=('a', 'b'))
          c._send_packet = mock.MagicMock()
          c._handle_event('/', 123, ['foo', ('bar', 'baz')])
          c._trigger_event.assert_called_once_with('foo', '/', ('bar', 'baz'))
          assert c._send_packet.call_count == 1
          expected_packet = packet.Packet(
              packet.ACK, namespace='/', id=123, data=['a', 'b'])
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_handle_ack(self):
          c = client.Client()
          mock_cb = mock.MagicMock()
          c.callbacks['/foo'] = {123: mock_cb}
          c._handle_ack('/foo', 123, ['bar', 'baz'])
          mock_cb.assert_called_once_with('bar', 'baz')
          assert 123 not in c.callbacks['/foo']
  
      def test_handle_ack_not_found(self):
          c = client.Client()
          mock_cb = mock.MagicMock()
          c.callbacks['/foo'] = {123: mock_cb}
          c._handle_ack('/foo', 124, ['bar', 'baz'])
          mock_cb.assert_not_called()
          assert 123 in c.callbacks['/foo']
  
      def test_handle_error(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._connect_event = mock.MagicMock()
          c._trigger_event = mock.MagicMock()
          c._handle_error('/', 'error')
          assert c.namespaces == {}
          assert not c.connected
          c._connect_event.set.assert_called_once_with()
          c._trigger_event.assert_called_once_with('connect_error', '/', 'error')
  
      def test_handle_error_with_no_arguments(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._connect_event = mock.MagicMock()
          c._trigger_event = mock.MagicMock()
          c._handle_error('/', None)
          assert c.namespaces == {}
          assert not c.connected
          c._connect_event.set.assert_called_once_with()
          c._trigger_event.assert_called_once_with('connect_error', '/')
  
      def test_handle_error_namespace(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._connect_event = mock.MagicMock()
          c._trigger_event = mock.MagicMock()
          c._handle_error('/bar', ['error', 'message'])
          assert c.namespaces == {'/foo': '1'}
          assert c.connected
          c._connect_event.set.assert_called_once_with()
          c._trigger_event.assert_called_once_with(
              'connect_error', '/bar', 'error', 'message'
          )
  
      def test_handle_error_namespace_with_no_arguments(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._connect_event = mock.MagicMock()
          c._trigger_event = mock.MagicMock()
          c._handle_error('/bar', None)
          assert c.namespaces == {'/foo': '1'}
          assert c.connected
          c._connect_event.set.assert_called_once_with()
          c._trigger_event.assert_called_once_with('connect_error', '/bar')
  
      def test_handle_error_unknown_namespace(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/foo': '1', '/bar': '2'}
          c._connect_event = mock.MagicMock()
          c._handle_error('/baz', 'error')
          assert c.namespaces == {'/foo': '1', '/bar': '2'}
          assert c.connected
          c._connect_event.set.assert_called_once_with()
  
      def test_trigger_event(self):
          c = client.Client()
          handler = mock.MagicMock()
          catchall_handler = mock.MagicMock()
          c.on('foo', handler)
          c.on('*', catchall_handler)
          c._trigger_event('foo', '/', 1, '2')
          c._trigger_event('bar', '/', 1, '2', 3)
          handler.assert_called_once_with(1, '2')
          catchall_handler.assert_called_once_with('bar', 1, '2', 3)
  
      def test_trigger_event_namespace(self):
          c = client.Client()
          handler = mock.MagicMock()
          catchall_handler = mock.MagicMock()
          c.on('foo', handler, namespace='/bar')
          c.on('*', catchall_handler, namespace='/bar')
          c._trigger_event('foo', '/bar', 1, '2')
          c._trigger_event('bar', '/bar', 1, '2', 3)
          handler.assert_called_once_with(1, '2')
          catchall_handler.assert_called_once_with('bar', 1, '2', 3)
  
      def test_trigger_event_class_namespace(self):
          c = client.Client()
          result = []
  
          class MyNamespace(namespace.ClientNamespace):
              def on_foo(self, a, b):
                  result.append(a)
                  result.append(b)
  
          c.register_namespace(MyNamespace('/'))
          c._trigger_event('foo', '/', 1, '2')
          assert result == [1, '2']
  
      def test_trigger_event_unknown_namespace(self):
          c = client.Client()
          result = []
  
          class MyNamespace(namespace.ClientNamespace):
              def on_foo(self, a, b):
                  result.append(a)
                  result.append(b)
  
          c.register_namespace(MyNamespace('/'))
          c._trigger_event('foo', '/bar', 1, '2')
          assert result == []
  
      @mock.patch('socketio.client.random.random', side_effect=[1, 0, 0.5])
      def test_handle_reconnect(self, random):
          c = client.Client()
          c._reconnect_task = 'foo'
          c._reconnect_abort = c.eio.create_event()
          c._reconnect_abort.wait = mock.MagicMock(return_value=False)
          c.connect = mock.MagicMock(
              side_effect=[ValueError, exceptions.ConnectionError, None]
          )
          c._handle_reconnect()
          assert c._reconnect_abort.wait.call_count == 3
          assert c._reconnect_abort.wait.call_args_list == [
              mock.call(1.5),
              mock.call(1.5),
              mock.call(4.0),
          ]
          assert c._reconnect_task is None
  
      @mock.patch('socketio.client.random.random', side_effect=[1, 0, 0.5])
      def test_handle_reconnect_max_delay(self, random):
          c = client.Client(reconnection_delay_max=3)
          c._reconnect_task = 'foo'
          c._reconnect_abort = c.eio.create_event()
          c._reconnect_abort.wait = mock.MagicMock(return_value=False)
          c.connect = mock.MagicMock(
              side_effect=[ValueError, exceptions.ConnectionError, None]
          )
          c._handle_reconnect()
          assert c._reconnect_abort.wait.call_count == 3
          assert c._reconnect_abort.wait.call_args_list == [
              mock.call(1.5),
              mock.call(1.5),
              mock.call(3.0),
          ]
          assert c._reconnect_task is None
  
      @mock.patch('socketio.client.random.random', side_effect=[1, 0, 0.5])
      def test_handle_reconnect_max_attempts(self, random):
          c = client.Client(reconnection_attempts=2)
          c._reconnect_task = 'foo'
          c._reconnect_abort = c.eio.create_event()
          c._reconnect_abort.wait = mock.MagicMock(return_value=False)
          c.connect = mock.MagicMock(
              side_effect=[ValueError, exceptions.ConnectionError, None]
          )
          c._handle_reconnect()
          assert c._reconnect_abort.wait.call_count == 2
          assert c._reconnect_abort.wait.call_args_list == [
              mock.call(1.5),
              mock.call(1.5),
          ]
          assert c._reconnect_task == 'foo'
  
      @mock.patch('socketio.client.random.random', side_effect=[1, 0, 0.5])
      def test_handle_reconnect_aborted(self, random):
          c = client.Client()
          c._reconnect_task = 'foo'
          c._reconnect_abort = c.eio.create_event()
          c._reconnect_abort.wait = mock.MagicMock(side_effect=[False, True])
          c.connect = mock.MagicMock(side_effect=exceptions.ConnectionError)
          c._handle_reconnect()
          assert c._reconnect_abort.wait.call_count == 2
          assert c._reconnect_abort.wait.call_args_list == [
              mock.call(1.5),
              mock.call(1.5),
          ]
          assert c._reconnect_task == 'foo'
  
      def test_handle_eio_connect(self):
          c = client.Client()
          c.connection_namespaces = ['/', '/foo']
          c.connection_auth = 'auth'
          c._send_packet = mock.MagicMock()
          c.eio.sid = 'foo'
          assert c.sid is None
          c._handle_eio_connect()
          assert c.sid == 'foo'
          assert c._send_packet.call_count == 2
          expected_packet = packet.Packet(
              packet.CONNECT, data='auth', namespace='/')
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
          expected_packet = packet.Packet(
              packet.CONNECT, data='auth', namespace='/foo')
          assert (
              c._send_packet.call_args_list[1][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_handle_eio_connect_function(self):
          c = client.Client()
          c.connection_namespaces = ['/', '/foo']
          c.connection_auth = lambda: 'auth'
          c._send_packet = mock.MagicMock()
          c.eio.sid = 'foo'
          assert c.sid is None
          c._handle_eio_connect()
          assert c.sid == 'foo'
          assert c._send_packet.call_count == 2
          expected_packet = packet.Packet(
              packet.CONNECT, data='auth', namespace='/')
          assert (
              c._send_packet.call_args_list[0][0][0].encode()
              == expected_packet.encode()
          )
          expected_packet = packet.Packet(
              packet.CONNECT, data='auth', namespace='/foo')
          assert (
              c._send_packet.call_args_list[1][0][0].encode()
              == expected_packet.encode()
          )
  
      def test_handle_eio_message(self):
          c = client.Client()
          c._handle_connect = mock.MagicMock()
          c._handle_disconnect = mock.MagicMock()
          c._handle_event = mock.MagicMock()
          c._handle_ack = mock.MagicMock()
          c._handle_error = mock.MagicMock()
  
          c._handle_eio_message('0{"sid":"123"}')
          c._handle_connect.assert_called_with(None, {'sid': '123'})
          c._handle_eio_message('0/foo,{"sid":"123"}')
          c._handle_connect.assert_called_with('/foo', {'sid': '123'})
          c._handle_eio_message('1')
          c._handle_disconnect.assert_called_with(None)
          c._handle_eio_message('1/foo')
          c._handle_disconnect.assert_called_with('/foo')
          c._handle_eio_message('2["foo"]')
          c._handle_event.assert_called_with(None, None, ['foo'])
          c._handle_eio_message('3/foo,["bar"]')
          c._handle_ack.assert_called_with('/foo', None, ['bar'])
          c._handle_eio_message('4')
          c._handle_error.assert_called_with(None, None)
          c._handle_eio_message('4"foo"')
          c._handle_error.assert_called_with(None, 'foo')
          c._handle_eio_message('4["foo"]')
          c._handle_error.assert_called_with(None, ['foo'])
          c._handle_eio_message('4/foo')
          c._handle_error.assert_called_with('/foo', None)
          c._handle_eio_message('4/foo,["foo","bar"]')
          c._handle_error.assert_called_with('/foo', ['foo', 'bar'])
          c._handle_eio_message('51-{"_placeholder":true,"num":0}')
          assert c._binary_packet.packet_type == packet.BINARY_EVENT
          c._handle_eio_message(b'foo')
          c._handle_event.assert_called_with(None, None, b'foo')
          c._handle_eio_message(
              '62-/foo,{"1":{"_placeholder":true,"num":1},'
              '"2":{"_placeholder":true,"num":0}}'
          )
          assert c._binary_packet.packet_type == packet.BINARY_ACK
          c._handle_eio_message(b'bar')
          c._handle_eio_message(b'foo')
          c._handle_ack.assert_called_with(
              '/foo', None, {'1': b'foo', '2': b'bar'}
          )
          with pytest.raises(ValueError):
              c._handle_eio_message('9')
  
      def test_eio_disconnect(self):
          c = client.Client()
          c.namespaces = {'/': '1'}
          c.connected = True
          c._trigger_event = mock.MagicMock()
          c.start_background_task = mock.MagicMock()
          c.sid = 'foo'
          c.eio.state = 'connected'
          c._handle_eio_disconnect()
          c._trigger_event.assert_called_once_with('disconnect', namespace='/')
          assert c.sid is None
          assert not c.connected
  
      def test_eio_disconnect_namespaces(self):
          c = client.Client()
          c.connected = True
          c.namespaces = {'/': '1', '/foo': '2', '/bar': '3'}
          c._trigger_event = mock.MagicMock()
          c.start_background_task = mock.MagicMock()
          c.sid = 'foo'
          c.eio.state = 'connected'
          c._handle_eio_disconnect()
          c._trigger_event.assert_any_call('disconnect', namespace='/foo')
          c._trigger_event.assert_any_call('disconnect', namespace='/bar')
          c._trigger_event.assert_any_call('disconnect', namespace='/')
          assert c.sid is None
          assert not c.connected
  
      def test_eio_disconnect_reconnect(self):
          c = client.Client(reconnection=True)
          c.start_background_task = mock.MagicMock()
          c.eio.state = 'connected'
          c._handle_eio_disconnect()
          c.start_background_task.assert_called_once_with(c._handle_reconnect)
  
      def test_eio_disconnect_self_disconnect(self):
          c = client.Client(reconnection=True)
          c.start_background_task = mock.MagicMock()
          c.eio.state = 'disconnected'
          c._handle_eio_disconnect()
          c.start_background_task.assert_not_called()
  
      def test_eio_disconnect_no_reconnect(self):
          c = client.Client(reconnection=False)
          c.start_background_task = mock.MagicMock()
          c.eio.state = 'connected'
          c._handle_eio_disconnect()
          c.start_background_task.assert_not_called()
  