Ejemplo n.º 1
0
    def test__render_line_bg_colors(self):
        cell_width = 8
        screen_line = {
            0: anim.CharacterCell('A', 'black', 'red'),
            1: anim.CharacterCell('A', 'black', 'red'),
            3: anim.CharacterCell('A', 'black', 'red'),
            4: anim.CharacterCell('A', 'black', 'blue'),
            6: anim.CharacterCell('A', 'black', 'blue'),
            7: anim.CharacterCell('A', 'black', 'blue'),
            8: anim.CharacterCell('A', 'black', 'green'),
            9: anim.CharacterCell('A', 'black', 'red'),
            10: anim.CharacterCell('A', 'black', 'red'),
            99: anim.CharacterCell('A', 'black', 'black'),
        }

        rectangles = anim._render_line_bg_colors(screen_line=screen_line,
                                                 height=0,
                                                 line_height=1,
                                                 cell_width=cell_width,
                                                 background_color='black')
        rect_0, rect_3, rect_4, rect_6, rect_8, rect_9 = sorted(
            rectangles, key=lambda r: r.attribs['x'])

        self.assertEqual(rect_0.attribs['x'], 0)
        self.assertEqual(rect_0.attribs['width'], 16)
        self.assertEqual(rect_0.attribs['fill'], 'red')
        self.assertEqual(rect_3.attribs['x'], 24)
        self.assertEqual(rect_3.attribs['width'], 8)
        self.assertEqual(rect_4.attribs['x'], 32)
        self.assertEqual(rect_6.attribs['x'], 48)
        self.assertEqual(rect_6.attribs['width'], 16)
        self.assertEqual(rect_6.attribs['fill'], 'blue')
        self.assertEqual(rect_8.attribs['x'], 64)
        self.assertEqual(rect_8.attribs['fill'], 'green')
        self.assertEqual(rect_9.attribs['x'], 72)
Ejemplo n.º 2
0
    def test_screen_events_empty_groups(self):
        """screen_events should never return an empty group of events"""
        records = [
            AsciiCastV2Header(version=2, width=80, height=24, theme=THEME),
            AsciiCastV2Event(0, 'o', 'i', None),
            AsciiCastV2Event(1, 'o', '', None),
            AsciiCastV2Event(2, 'o', '', None),
            AsciiCastV2Event(3, 'o', '', None),
        ]
        expected_events = [
            term.Configuration(80, 24),
            [
                term.DisplayLine(0, {
                    0: anim.CharacterCell('i'),
                    1: CURSOR_CHAR
                }, 0),
            ],
            [
                term.DisplayLine(0, {
                    0: anim.CharacterCell('i'),
                    1: CURSOR_CHAR
                }, 0, 4000),
            ]
        ]

        events = term.screen_events(records, 1, None, last_frame_dur=1000)

        list_events = [next(events)]
        list_events.extend([le for le in events])

        z = itertools.zip_longest(expected_events, list_events)
        for count, (expected_item, item) in enumerate(z):
            with self.subTest(case='No empty group - item #{}'.format(count)):
Ejemplo n.º 3
0
    def test_screen_events_simple_events(self):
        records = [AsciiCastV2Header(version=2, width=80, height=24, theme=THEME)] + \
                  [AsciiCastV2Event(time=i,
                                    event_type='o',
                                    event_data='{}\r\n'.format(i),
                                    duration=None)
                   for i in range(0, 2)]
        events = term.screen_events(records, 1, None, 42)
        list_events = [next(events)]
        list_events.extend([list(le) for le in events])

        expected_events = [
            term.Configuration(80, 24),
            [
                term.DisplayLine(0, {0: anim.CharacterCell('0')}, 0),
                term.DisplayLine(1, {0: CURSOR_CHAR}, 0),
            ],
            [
                term.DisplayLine(1, {0: CURSOR_CHAR}, 0, 1000),
                term.DisplayLine(1, {0: anim.CharacterCell('1')}, 1000),
                term.DisplayLine(2, {0: CURSOR_CHAR}, 1000),
            ],
            [
                term.DisplayLine(0, {0: anim.CharacterCell('0')}, 0, 1042),
                term.DisplayLine(1, {0: anim.CharacterCell('1')}, 1000, 42),
                term.DisplayLine(2, {0: CURSOR_CHAR}, 1000, 42),
            ],
        ]

        z = itertools.zip_longest(expected_events, list_events)
        for count, (expected_item, item) in enumerate(z):
            with self.subTest(case='Simple events - item #{}'.format(count)):
Ejemplo n.º 4
0
 def line(i):
     chars = []
     for c in 'line{}'.format(i):
         chars.append(
             anim.CharacterCell(c, '#123456', '#789012', False, False,
                                False, False))
     return dict(enumerate(chars))
Ejemplo n.º 5
0
    def test__render_characters(self):
        screen_line = {
            0: anim.CharacterCell('A', 'red', 'white'),
            1: anim.CharacterCell('B', 'blue', 'white'),
            2: anim.CharacterCell('C', 'blue', 'white'),
            7: anim.CharacterCell('D', 'green', 'white'),
            8: anim.CharacterCell('E', 'green', 'white'),
            9: anim.CharacterCell('F', 'green', 'white'),
            10: anim.CharacterCell('G', 'green', 'white'),
            11: anim.CharacterCell('H', 'red', 'white'),
            20: anim.CharacterCell(' ', 'black', 'black')
        }

        with self.subTest(case='Content'):
Ejemplo n.º 6
0
    def test_from_pyte(self):
        pyte_chars = [
            # Simple mapping
            pyte.screens.Char('A', 'red', 'blue'),
            # Reverse colors
            pyte.screens.Char('B', 'red', 'blue', reverse=True),
            # Bold for foreground -> bright colors
            pyte.screens.Char('C', 'red', 'blue', bold=True),
            # Bold and reverse
            pyte.screens.Char('D', 'red', 'blue', bold=True, reverse=True),
            # Defaults
            pyte.screens.Char('E', 'default', 'default'),
            # Hexadecimal
            pyte.screens.Char('F', '008700', 'ABCDEF'),
            # Bright and bold
            pyte.screens.Char('G', 'brightgreen', 'ABCDEF', bold=True),
        ]

        char_cells = [
            anim.CharacterCell('A', 'color1', 'color4', False),
            anim.CharacterCell('B', 'color4', 'color1', False),
            anim.CharacterCell('C', 'color9', 'color4', True),
            anim.CharacterCell('D', 'color4', 'color9', True),
            anim.CharacterCell('E', 'foreground', 'background', False),
            anim.CharacterCell('F', '#008700', '#ABCDEF', False),
            anim.CharacterCell('G', 'color10', '#ABCDEF', True),
        ]

        for pyte_char, cell_char in zip(pyte_chars, char_cells):
            with self.subTest(case=pyte_char):
                self.assertEqual(anim.CharacterCell.from_pyte(pyte_char), cell_char)
Ejemplo n.º 7
0
    def test_timed_frames_simple_events(self):
        records = [AsciiCastV2Header(version=2, width=80, height=24, theme=THEME)] + \
                  [AsciiCastV2Event(time=i,
                                    event_type='o',
                                    event_data='{}\r\n'.format(i),
                                    duration=None)
                   for i in range(0, 2)]
        geometry, frames = term.timed_frames(records, 1, None, 42)

        self.assertEqual(geometry, (80, 24))

        expected_frames = [
            term.TimedFrame(0, 1000, {
                0: {
                    0: anim.CharacterCell('0')
                },
                1: {
                    0: CURSOR_CHAR
                },
            }),
            term.TimedFrame(
                1000, 42, {
                    0: {
                        0: anim.CharacterCell('0')
                    },
                    1: {
                        0: anim.CharacterCell('1')
                    },
                    2: {
                        0: CURSOR_CHAR
                    },
                })
        ]

        z = itertools.zip_longest(expected_frames, frames)
        for (expected_frame, frame) in z:
            self.assertEqual(expected_frame.time, frame.time)
            self.assertEqual(expected_frame.duration, frame.duration)
            for row in frame.buffer:
                if row in expected_frame.buffer:
                    self.assertEqual(expected_frame.buffer[row],
                                     frame.buffer[row])
                else:
                    self.assertEqual({}, frame.buffer[row])
Ejemplo n.º 8
0
    def test_from_pyte(self):
        pyte_chars = [
            # Simple mapping
            pyte.screens.Char('A', 'red', 'blue'),
            # Reverse colors
            pyte.screens.Char('B', 'red', 'blue', reverse=True),
            # Bold for foreground -> bright colors
            pyte.screens.Char('C', 'red', 'blue', bold=True),
            # Bold and reverse
            pyte.screens.Char('D', 'red', 'blue', bold=True, reverse=True),
            # Bold with no matching bright color
            pyte.screens.Char('E', 'blue', 'blue', bold=True),
            # Defaults
            pyte.screens.Char('F', 'default', 'default'),
            # Hexadecimal
            pyte.screens.Char('G', '008700', 'ABCDEF'),
            # Bright and bold
            pyte.screens.Char('H', 'brightgreen', 'ABCDEF', bold=True),
            # Bright but not in the palette --> fallback to the non bright color
            # for compatibility with an 8-color palette (issue #1)
            pyte.screens.Char('I', 'brown', 'ABCDEF', bold=True),
        ]

        char_cells = [
            anim.CharacterCell('A', 'color1', 'color4'),
            anim.CharacterCell('B', 'color4', 'color1'),
            anim.CharacterCell('C', 'color9', 'color4'),
            anim.CharacterCell('D', 'color4', 'color9'),
            anim.CharacterCell('E', 'color12', 'color4'),
            anim.CharacterCell('F', 'foreground', 'background'),
            anim.CharacterCell('G', '#008700', '#ABCDEF'),
            anim.CharacterCell('H', 'color10', '#ABCDEF'),
            anim.CharacterCell('I', 'color3', '#ABCDEF'),
        ]

        palette = {
            'foreground': 'foreground',
            'background': 'background',
            1: 'color1',
            3: 'color3',
            4: 'color4',
            9: 'color9',
            10: 'color10',
            12: 'color12',
        }
        for pyte_char, cell_char in zip(pyte_chars, char_cells):
            with self.subTest(case=pyte_char):
                self.assertEqual(
Ejemplo n.º 9
0
    def test__render_line_bg_colors_xml(self):
        cell_width = 8
        screen_line = {
            0: anim.CharacterCell('A', 'black', 'red'),
            1: anim.CharacterCell('A', 'black', 'red'),
            3: anim.CharacterCell('A', 'black', 'red'),
            4: anim.CharacterCell('A', 'black', 'blue'),
            6: anim.CharacterCell('A', 'black', 'blue'),
            7: anim.CharacterCell('A', 'black', 'blue'),
            8: anim.CharacterCell('A', 'black', 'green'),
            9: anim.CharacterCell('A', 'black', 'red'),
            10: anim.CharacterCell('A', 'black', 'red'),
            11: anim.CharacterCell('A', 'black', '#123456'),
        }

        rectangles = anim._render_line_bg_colors(screen_line=screen_line,
                                                 height=0,
                                                 cell_height=1,
                                                 cell_width=cell_width)

        def key(r):
            return r.attrib['x']

        rect_0, rect_3, rect_4, rect_6, rect_8, rect_9, rect_11 = sorted(
            rectangles, key=key)

        self.assertEqual(rect_0.attrib['x'], '0')
        self.assertEqual(rect_0.attrib['width'], '16')
        self.assertEqual(rect_0.attrib['height'], '1')
        self.assertEqual(rect_0.attrib['class'], 'red')
        self.assertEqual(rect_3.attrib['x'], '24')
        self.assertEqual(rect_3.attrib['width'], '8')
        self.assertEqual(rect_4.attrib['x'], '32')
        self.assertEqual(rect_6.attrib['x'], '48')
        self.assertEqual(rect_6.attrib['width'], '16')
        self.assertEqual(rect_6.attrib['class'], 'blue')
        self.assertEqual(rect_8.attrib['x'], '64')
        self.assertEqual(rect_8.attrib['class'], 'green')
        self.assertEqual(rect_9.attrib['x'], '72')
        self.assertEqual(rect_11.attrib['fill'], '#123456')
Ejemplo n.º 10
0
    def test__feed(self):
        redraw_buffers = [{
            0: {
                0: anim.CharacterCell('1')
            },
            1: {
                0: CURSOR_CHAR
            },
        }, {
            1: {
                0: anim.CharacterCell('2')
            },
            2: {
                0: CURSOR_CHAR
            },
        }]

        all_expected_events = [[
            term.DisplayLine(0, {0: anim.CharacterCell('1')}, 0),
            term.DisplayLine(1, {0: CURSOR_CHAR}, 0),
        ],
                               [
                                   term.DisplayLine(1, {0: CURSOR_CHAR}, 0,
                                                    1000),
                                   term.DisplayLine(
                                       1, {0: anim.CharacterCell('2')}, 1000),
                                   term.DisplayLine(2, {0: CURSOR_CHAR}, 1000),
                               ]]

        display_events = {}
        time = 0
        z = itertools.zip_longest(redraw_buffers, all_expected_events)
        for buffer, expected_events in z:
            display_events, events = term._feed(buffer, display_events, time)
            with self.subTest(time=time):
                self.assertEqual(expected_events, events)
            time += 1000
Ejemplo n.º 11
0
 def line(s):
     return dict(enumerate([anim.CharacterCell(c) for c in s]))
Ejemplo n.º 12
0
    def test__render_characters(self):
        screen_line = {
            0: anim.CharacterCell('A', 'red', 'white'),
            1: anim.CharacterCell('B', 'blue', 'white'),
            2: anim.CharacterCell('C', 'blue', 'white'),
            7: anim.CharacterCell('D', '#00FF00', 'white'),
            8: anim.CharacterCell('E', '#00FF00', 'white'),
            9: anim.CharacterCell('F', '#00FF00', 'white'),
            10: anim.CharacterCell('G', '#00FF00', 'white'),
            20: anim.CharacterCell('H', 'black', 'black', bold=True),
            30: anim.CharacterCell('I', 'black', 'black', italics=True),
            40: anim.CharacterCell('J', 'black', 'black', underscore=True),
            50: anim.CharacterCell('K', 'black', 'black', strikethrough=True),
            60: anim.CharacterCell('L', 'black', 'black', underscore=True, strikethrough=True),
        }

        with self.subTest(case='Content'):
Ejemplo n.º 13
0
 def line(i):
     chars = [
         anim.CharacterCell(c, '#123456', '#789012')
         for c in 'line{}'.format(i)
     ]
     return dict(enumerate(chars))
Ejemplo n.º 14
0
class TestTerm(unittest.TestCase):
    def test__record(self):
        fd_in_read, fd_in_write = os.pipe()
        fd_out_read, fd_out_write = os.pipe()

        lines = 24
        columns = 80

        pid = os.fork()
        if pid == 0:
            # Child process
            for line in commands:
                os.write(fd_in_write, line.encode('utf-8'))
                time.sleep(0.060)
            os._exit(0)

        # Parent process
        with term.TerminalMode(fd_in_read):
            for _ in term._record(['sh'], columns, lines, fd_in_read,
                                  fd_out_write):
                pass

        os.waitpid(pid, 0)
        for fd in fd_in_read, fd_in_write, fd_out_read, fd_out_write:
            os.close(fd)

    def test_record(self):
        # Use pipes in lieu of stdin and stdout
        fd_in_read, fd_in_write = os.pipe()
        fd_out_read, fd_out_write = os.pipe()

        lines = 24
        columns = 80

        pid = os.fork()
        if pid == 0:
            # Child process
            for line in commands:
                os.write(fd_in_write, line.encode('utf-8'))
                time.sleep(0.060)
            os._exit(0)

        # Parent process
        with term.TerminalMode(fd_in_read):
            for _ in term.record(['sh'], columns, lines, fd_in_read,
                                 fd_out_write):
                pass

        os.waitpid(pid, 0)
        for fd in fd_in_read, fd_in_write, fd_out_read, fd_out_write:
            os.close(fd)

    def test__buffer_simple_events(self):
        escape_sequences = ['{}\r\n'.format(i) for i in range(5)]

        screen = pyte.Screen(80, 24)
        stream = pyte.Stream(screen)
        for count, escape_sequence in enumerate(escape_sequences):
            with self.subTest(case='Simple events (record #{})'.format(count)):
                stream.feed(escape_sequence)
                buffer = term._screen_buffer(screen)
                expected_buffer = {}
                for i in range(screen.lines):
                    if i <= count:
                        expected_buffer[i] = {0: anim.CharacterCell(str(i))}
                    elif i == count + 1:
                        expected_buffer[i] = {0: CURSOR_CHAR}
                    else:
                        expected_buffer[i] = {}

                self.assertEqual(expected_buffer, buffer)
Ejemplo n.º 15
0
import unittest
from unittest.mock import MagicMock, patch

import pyte

import termtosvg.anim as anim
from termtosvg import term
from termtosvg.asciicast import AsciiCastV2Event, AsciiCastV2Header, AsciiCastV2Theme

commands = [
    'echo $SHELL && sleep 0.1;\r\n', 'date && sleep 0.1;\r\n',
    'uname && sleep 0.1;\r\n', 'w', 'h', 'o', 'a', 'm', 'i\r\n', 'exit;\r\n'
]

THEME = AsciiCastV2Theme('#000000', '#FFFFFF', ':'.join(['#123456'] * 16))
CURSOR_CHAR = anim.CharacterCell(' ', 'background', 'foreground')

unittest.TestCase.maxDiff = None


class TestTerm(unittest.TestCase):
    def test__record(self):
        fd_in_read, fd_in_write = os.pipe()
        fd_out_read, fd_out_write = os.pipe()

        lines = 24
        columns = 80

        pid = os.fork()
        if pid == 0:
            # Child process