""" Test running an Imaginary world """ import os import fcntl import pty import tty import struct import termios from axiom.store import Store from twisted.trial.unittest import TestCase from twisted.internet.defer import Deferred from twisted.test.proto_helpers import StringTransport from twisted.conch.insults.insults import ServerProtocol from imaginary.world import ImaginaryWorld from imaginary.wiring.player import Player from imaginary.__main__ import withSavedTerminalSettings from imaginary.__main__ import CLEAR_SCREEN from imaginary.__main__ import getTerminalSize, ConsoleTextServer def makeTerminal(testCase): """ Create a terminal for a given test case. """ leader, follower = pty.openpty() testCase.addCleanup(os.close, leader) testCase.addCleanup(os.close, follower) return leader, follower def setTerminalSize(terminalFD, ws_row=25, ws_col=80, ws_xpixel=0, ws_ypixel=0): """ Set the size of the given PTY leader file descriptor. """ structformat = '4H' data = struct.pack(structformat, ws_row, ws_col, ws_xpixel, ws_ypixel) fcntl.ioctl(terminalFD, tty.TIOCSWINSZ, data) class WindowSizing(TestCase): """ Tests for getting the size of a terminal window. """ def test_getTerminalSize(self): """ L{getWindowSize} gets the size of a terminal file descriptor. """ leader, follower = makeTerminal(self) ws_row, ws_col, ws_xpixel, ws_ypixel = 123, 456, 789, 912 setTerminalSize(leader, ws_row, ws_col, ws_xpixel, ws_ypixel) self.assertEqual(getTerminalSize(follower), (ws_row, ws_col)) def test_consoleTextServer(self): """ L{ConsoleTextServer.connectionMade} sets the protocol of its player to itself. """ leader, follower = makeTerminal(self) store = Store() world = ImaginaryWorld(store=store) actor = world.create(u"player") setTerminalSize(leader, 234, 567) player = Player(actor) textServer = ConsoleTextServer(player, follower) terminalProtocol = ServerProtocol(lambda: textServer) self.assertIdentical(player.proto, None) terminalProtocol.makeConnection(StringTransport()) self.assertIdentical(player.proto, textServer) self.assertEqual(textServer.width, 567) self.assertEqual(textServer.height, 234) def test_withSavedTerminalSettings(self): """ L{withSavedTerminalSettings} saves and then restores the settings for the terminal that it is given. """ CFLAG = 2 LFLAG = 3 leader, follower = makeTerminal(self) def attributesEqual(a, b): # lflags seem to change randomly, and I'm not sure why, so let's # exclude them from the test (we never change them in mangle() # anyway). a[LFLAG] = 0 b[LFLAG] = 0 self.assertEqual(a, b) attrs = termios.tcgetattr(follower) chattrs = attrs[:] # Change one flag, just to change it. chattrs[CFLAG] ^= termios.INLCR def mangle(): os.write(follower, b"HELLO") termios.tcsetattr(follower, termios.TCSANOW, chattrs) mangle.attrs = termios.tcgetattr(follower) mangle.run = True mangle.run = False withSavedTerminalSettings(follower, mangle) self.assertEqual(mangle.run, True) # Sanity check: did the attributes change in the first place? attributesEqual(mangle.attrs, chattrs) newattrs = termios.tcgetattr(follower) attributesEqual(newattrs, attrs) self.assertEqual(os.read(leader, 1024), b"HELLO" + CLEAR_SCREEN)