class InitiatorSelectTestCase(NetworkTestCase):
    """Base class for XMPP initiator streams tests, using the
    `SelectMainLoop`.
    
    :Ivariables:
        - `stream`: The stream tested (to be created by a test method)
        - `transport`: TCPTransport used by the stream
        - `loop`: the main loop
    :Types:
        - `transport`: `TCPTransport`
        - `loop`: `MainLoop`
    """
    def setUp(self):
        super(InitiatorSelectTestCase, self).setUp()
        self.stream = None
        self.transport = None
        self.loop = None

    def start_transport(self, handlers):
        """Initialize a transport and a main loop with the provided handlers"""
        self.transport = TCPTransport()
        self.make_loop(handlers + [self.transport])

    def connect_transport(self):
        """Start a test server and connect the transport to it."""
        addr, port = self.start_server()
        self.transport.connect(addr, port)

    def make_loop(self, handlers):
        """Return a main loop object for use with this test suite."""
        self.loop = SelectMainLoop(None, handlers)

    def tearDown(self):
        super(InitiatorSelectTestCase, self).tearDown()
        self.loop = None
        self.stream = None
        if self.transport:
            self.transport.close()
        self.transport = None

    def wait(self, timeout = TIMEOUT, expect = None):
        """Wait until the main loop finishes, `timeout` seconds passes
        or current server input matches `expect`."""
        timeout = time.time() + timeout
        while not self.loop.finished:
            self.loop.loop_iteration(0.1)
            if expect:
                match = expect.match(self.server.rdata)
                if match:
                    return match.group(1)
            if time.time() > timeout:
                break

    def wait_short(self, timeout = 0.1):
        """Run a single main loop iteration."""
        self.loop.loop_iteration(timeout)
class ReceiverSelectTestCase(NetworkTestCase):
    """Base class for XMPP receiver streams tests, using the
    `SelectMainLoop`"""
    def setUp(self):
        super(ReceiverSelectTestCase, self).setUp()
        self.stream = None
        self.transport = None
        self.loop = None
        self.addr = None

    def start_transport(self, handlers):
        """Create a listening socket for the tested stream, 
        a transport a main loop and create a client connectiong to the
        socket."""
        sock = self.make_listening_socket()
        self.addr = sock.getsockname()
        self.start_client(self.addr)
        self.transport = TCPTransport(sock = sock.accept()[0])
        sock.close()
        self.make_loop(handlers + [self.transport])

    def make_loop(self, handlers):
        """Create the main loop object."""
        self.loop = SelectMainLoop(None, handlers)

    def wait(self, timeout = TIMEOUT, expect = None):
        """Wait until the main loop finishes, `timeout` seconds passes
        or current server input matches `expect`."""
        timeout = time.time() + timeout
        while not self.loop.finished:
            self.loop.loop_iteration(0.1)
            if expect:
                match = expect.match(self.client.rdata)
                if match:
                    return match.group(1)
            if time.time() > timeout:
                break

    def wait_short(self, timeout = 0.1):
        """Run a single main loop iteration."""
        self.loop.loop_iteration(timeout)

    def tearDown(self):
        self.loop = None
        self.stream = None
        if self.transport:
            self.transport.close()
        self.transport = None
        super(ReceiverSelectTestCase, self).tearDown()