<commit_before>from stanczyk import consoleFunctions
from stanczyk.console import LineKillingConsoleManhole, Protocol, _extractArgs
from twisted.conch.insults.helper import TerminalBuffer
from twisted.trial.unittest import SynchronousTestCase


class TerminalSetUp(object):
    """Set-up for in-memory terminal testing.


    """
    protocolClass = None

    def setUp(self):
        self.transport = TerminalBuffer()
        self.protocol = self.protocolClass()
        self.protocol.makeConnection(self.transport)


class LineKillingTests(TerminalSetUp, SynchronousTestCase):
    """Tests for the colored manhole with line killing support.

    """
    protocolClass = LineKillingConsoleManhole

    def test_killLine(self):
        """Receiving a vertical tab (C-k, "\v") kills the rest of the line on
        the terminal, as well as trimming the line buffer.

        """
        for x in list("abcdef") + [self.transport.LEFT_ARROW] * 3:
            self.protocol.keystrokeReceived(x, None)

        self.assertEqual(self.protocol.currentLineBuffer(), ("abc", "def"))

        self.protocol.keystrokeReceived("\v", None)

        self.assertEqual(self.protocol.currentLineBuffer(), ("abc", ""))

        restOfLine = self.transport.lines[self.transport.y][self.transport.x:]
        self.assertTrue(all(c is self.transport.void for (c, _) in restOfLine))



class ProtocolLineKillingTests(LineKillingTests):
    """Tests for the protocol.

    By inheriting from ``LineKillingTests``, we assert that line
    killing also works for the protocol.

    """
    protocolClass = Protocol

    def test_sessionStarted(self):
        """On start-up, the terminal is cleared, cursor put in the home
        position, MOTD printed, and the input line drawn.

        """
        self.assertEqual(str(self.transport), expectedSession)


    def test_consoleFunctions(self):
        """The manhole's namespace contains itself, under the ``"manhole"``
        name, as well as all of the console functions under their own
        names, partially applied with the manhole's namespace.

        """
        expectedKwargs = {"namespace": self.protocol.namespace}
        gotFuncs = set()
        for name, obj in self.protocol.namespace.iteritems():
            if name == "manhole":
                self.assertEqual(obj, self.protocol)
            else:
                self.assertEqual(obj.__name__, name)
                self.assertEqual(obj.keywords, expectedKwargs)
                gotFuncs.add(obj.func)

        self.assertEqual(gotFuncs, set(consoleFunctions))



expectedSession = """
Welcome to the Crypto 101 console client!


The following commands are available:
+--------------------------------------+--------------------------------------+
|               Command                |             Description              |
+======================================+======================================+
| connect()                            | Connects to the Crypto 101 exercise  |
|                                      | server.                              |
+--------------------------------------+--------------------------------------+
| getExercises(solved=False)           | Gets some exercises that are         |
|                                      | currently avaialble to you.          |
+--------------------------------------+--------------------------------------+
| getExerciseDetails(identifier)       | Shows the detailed description of a  |
|                                      | particular excerise.                 |
+--------------------------------------+--------------------------------------+
| connectProxy(identifier)             | Start listening on some free local   |
|                                      | port; connections will be proxied to |<commit_msg>Tests for killLine<commit_after>from stanczyk import consoleFunctions
from stanczyk.console import LineKillingConsoleManhole, Protocol, _extractArgs
from twisted.conch.insults.helper import TerminalBuffer
from twisted.trial.unittest import SynchronousTestCase


class TerminalSetUp(object):
    """Set-up for in-memory terminal testing.


    """
    protocolClass = None

    def setUp(self):
        self.transport = TerminalBuffer()
        self.protocol = self.protocolClass()
        self.protocol.makeConnection(self.transport)


class LineKillingTests(TerminalSetUp, SynchronousTestCase):
    """Tests for the colored manhole with line killing support.

    """
    protocolClass = LineKillingConsoleManhole

    def test_killLine(self):
        """Receiving a vertical tab (C-k, "\v") kills the rest of the line on
        the terminal, as well as trimming the line buffer.

        """
        for x in list("abcdef") + [self.transport.LEFT_ARROW] * 3:
            self.protocol.keystrokeReceived(x, None)

        self.assertEqual(self.protocol.currentLineBuffer(), ("abc", "def"))

        self.protocol.keystrokeReceived("\v", None)

        self.assertEqual(self.protocol.currentLineBuffer(), ("abc", ""))

        restOfLine = self.transport.lines[self.transport.y][self.transport.x:]
        self.assertTrue(isEmpty(restOfLine))



def isEmpty(line):
    """Checks if part of a TerminalBuffer line is empty.

    """
    return all(c is TerminalBuffer.void for (c, _) in line)



class ProtocolLineKillingTests(LineKillingTests):
    """Tests for the protocol.

    By inheriting from ``LineKillingTests``, we assert that line
    killing also works for the protocol.

    """
    protocolClass = Protocol

    def test_sessionStarted(self):
        """On start-up, the terminal is cleared, cursor put in the home
        position, MOTD printed, and the input line drawn.

        """
        self.assertEqual(str(self.transport), expectedSession)


    def test_consoleFunctions(self):
        """The manhole's namespace contains itself, under the ``"manhole"``
        name, as well as all of the console functions under their own
        names, partially applied with the manhole's namespace.

        """
        expectedKwargs = {"namespace": self.protocol.namespace}
        gotFuncs = set()
        for name, obj in self.protocol.namespace.iteritems():
            if name == "manhole":
                self.assertEqual(obj, self.protocol)
            else:
                self.assertEqual(obj.__name__, name)
                self.assertEqual(obj.keywords, expectedKwargs)
                gotFuncs.add(obj.func)

        self.assertEqual(gotFuncs, set(consoleFunctions))


    def test_killLine(self):
        """The killLine method finds the current cursor position, moves to
        the start of that line, and then erases the rest of the line.

        """
        for char in "abcdef":
            self.protocol.keystrokeReceived(char, None)

        currentLine = self.transport.lines[self.transport.y]
        self.assertFalse(isEmpty(currentLine))

        oldCoords = self.transport.x, self.transport.y
        self.protocol.killLine()
        self.assertEqual(self.transport.x, 0)
        self.assertEqual(self.transport.y, oldCoords[1])

        currentLine = self.transport.lines[self.transport.y]
        self.assertTrue(isEmpty(currentLine))



expectedSession = """
Welcome to the Crypto 101 console client!


The following commands are available:
+--------------------------------------+--------------------------------------+
|               Command                |             Description              |
+======================================+======================================+
| connect()                            | Connects to the Crypto 101 exercise  |
|                                      | server.                              |
+--------------------------------------+--------------------------------------+
| getExercises(solved=False)           | Gets some exercises that are         |
|                                      | currently avaialble to you.          |
+--------------------------------------+--------------------------------------+
| getExerciseDetails(identifier)       | Shows the detailed description of a  |
|                                      | particular excerise.                 |
+--------------------------------------+--------------------------------------+
| connectProxy(identifier)             | Start listening on some free local   |
|                                      | port; connections will be proxied to |
{'fraction_non_alphanumeric': 0.17523197715917202, 'fraction_numerical': 0.0019034023316678564, 'mean_word_length': 1.8277833837874202, 'pattern_counts': {'":': 5, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '641293', 'n_tokens_mistral': 2061, 'n_tokens_neox': 1920, 'n_words': 556}