def test_resize_shifts_horizontal(self): # If the current display is thinner than the requested size... s = screen((2,2)) s.display = ["bo", "sh"] # New columns should get added to the right. s.resize((2,3)) self.assertEqual(s.display, ["bo ", "sh "]) # If the current display is wider than the requested size... s = screen((2,2)) s.display = ["bo", "sh"] # Columns should be removed from the right... s.resize((2, 1)) self.assertEqual(s.display, ["b", "s"])
def __init__(self, **kwargs): self._stream = vt102.stream() self._screen = vt102.screen((ROWS, COLS)) self._screen.attach(self._stream) self._need_inventory = True self._has_more = False self._command = None self.messages = collections.deque(maxlen=1000) self.stats = {} self.inventory = {} self.spells = {} opts = dict(character=random.choice('bar pri ran val wiz'.split()), gender=random.choice('mal fem'.split()), race=random.choice('elf hum'.split()), align=random.choice('cha neu'.split())) opts.update(kwargs) handle = tempfile.NamedTemporaryFile() handle.write(self.OPTIONS.format(**opts).encode('utf-8')) handle.flush() os.environ['NETHACKOPTIONS'] = '@' + handle.name
def test_resize_shifts_vertical(self): # If the current display is shorter than the requested screen size... s = screen((2,2)) s.display = ["bo", "sh"] # New rows should get added on the bottom... s.resize((3,2)) self.assertEqual(s.display, ["bo", "sh", " "]) # If the current display is taller than the requested screen size... s = screen((2,2)) s.display = ["bo", "sh"] # Rows should be removed from the top... s.resize((1,2)) self.assertEqual(s.display, ["sh"])
def test_remove_non_existant_attribute(self): s = screen((2,2)) assert s.attributes == [[s.default_attributes, s.default_attributes]] * 2 s._remove_text_attr("underline") assert s.attributes == [[s.default_attributes, s.default_attributes]] * 2
def test_home(self): s = screen((10, 10)) s.x = 5 s.y = 5 s._home() self.assertEqual(s.x, 0) self.assertEqual(s.y, 0)
def test_restore_cursor_with_none_saved(self): s = screen((10, 10)) s.x = 5 s.y = 5 s._restore_cursor() self.assertEqual(s.x, 5) self.assertEqual(s.y, 5)
def test_backspace(self): s = screen((2,2)) self.assertEqual(s.x, 0) s._backspace() self.assertEqual(s.x, 0) s.x = 1 s._backspace() self.assertEqual(s.x, 0)
def test_multi_attribs(self): s = screen((2,2)) assert s.attributes == [[s.default_attributes, s.default_attributes]] * 2 s._select_graphic_rendition(1) # Bold s._select_graphic_rendition(5) # Blink assert s.cursor_attributes == (("bold", "blink"), "default", "default") or \ s.cursor_attributes == (("blink", "bold"), "default", "default")
def test_reset_resets_colors(self): s = screen((2,2)) assert s.attributes == [[s.default_attributes, s.default_attributes]] * 2 s._select_graphic_rendition(30) # black foreground s._select_graphic_rendition(40) # black background self.assertEqual(s.cursor_attributes, ((), "black", "black")) s._select_graphic_rendition(0) self.assertEqual(s.cursor_attributes, s.default_attributes)
def test_line_feed(self): # Line feeds are the same as indexes, except they move the cursor to # the first character on the created/next line s = screen((2,2)) s.display = ["bo", "sh"] s.x = 1; s.y = 0 s._linefeed() self.assertEqual(s.x, 0) self.assertEqual(s.y, 1)
def test_print(self): s = screen((3,3)) s._print("s") self.assertEqual(s.display, ["s ", " ", " "]) self.assertEqual(s.cursor(), (1, 0)) s.x = 1; s.y = 1 s._print("a") self.assertEqual(s.display, ["s ", " a ", " "])
def test_resize(self): s = screen((2,2)) assert s.display == [" ", " "] assert s.attributes == [[s.default_attributes, s.default_attributes]] * 2 s.resize((3,3)) self.assertEqual(s.display, [" ", " ", " "]) assert s.attributes == [[s.default_attributes, s.default_attributes, s.default_attributes]] * 3
def test_delete_characters(self): s = screen((3,3)) s.display = ["sam", "is ", "foo"] s.x = 0 s.y = 0 s._delete_character(2) self.assertEqual(s.display, ["m ", "is ", "foo"]) s.y = 2 s.x = 2 s._delete_character(1) self.assertEqual(s.display, ["m ", "is ", "fo "])
def __init__(self, toggle_help="\t", toggle_map="`"): self.options = parse_options() if self.options.save: self.save_file = os.path.join(self.noobhack_dir, "save-%s" % self.options.save) else: self.save_file = os.path.join(self.noobhack_dir, "save") self.toggle_help = toggle_help self.toggle_map = toggle_map self.mode = "game" self.playing = False self.reloading = False self.last_input = time() self.pending_input = [] if not os.path.exists(self.noobhack_dir): os.makedirs(self.noobhack_dir, 0755) self.nethack = self.connect_to_game() self.output_proxy = proxy.Output(self.nethack) self.input_proxy = proxy.Input(self.nethack) # Create an in-memory terminal screen and register it's stream # processor with the output proxy. self.stream = vt102.stream() # For some reason that I can't assertain: curses freaks out and crashes # when you use exactly the number of rows that are available on the # terminal. It seems easiest just to subtract one from the rows and # deal with it rather than hunt forever trying to figure out what I'm # doing wrong with curses. rows, cols = size() self.term = vt102.screen((rows, cols), self.options.encoding) self.term.attach(self.stream) self.output_proxy.register(self.stream.process) self.game = Game(self.term) self.output_proxy.register(self._restore_game_checker) self.output_proxy.register(self._game_started_checker) self.output_proxy.register(self._quit_or_died_checker) # Register the `toggle` key to open up the interactive nooback # assistant. self.input_proxy.register(self._toggle)
def test_attributes(self): s = screen((2,2)) assert s.attributes == [[s.default_attributes, s.default_attributes]] * 2 s._select_graphic_rendition(1) # Bold # Still default, since we haven't written anything. assert s.attributes == [[s.default_attributes, s.default_attributes]] * 2 self.assertEqual(s.cursor_attributes, (("bold",), "default", "default")) s._print("f") assert s.attributes == [ [(("bold",), "default", "default"), s.default_attributes], [s.default_attributes, s.default_attributes] ]
def test_tabstops(self): s = screen((10,10)) s.x = 1 s._set_tab_stop() s.x = 8 s._set_tab_stop() s.x = 0 s._tab() self.assertEqual(s.x, 1) s._tab() self.assertEqual(s.x, 8) s._tab() self.assertEqual(s.x, 9) s._tab() self.assertEqual(s.x, 9)
def test_reverse_index(self): s = screen((2,2)) s.display = ["bo", "sh"] s.x = 1 s._reverse_index() # Reverse indexing on the first row should push rows down and create a # new row at the top. self.assertEqual(s.y, 0 ) self.assertEqual(s.x, 1) self.assertEqual(s.display, [" ", "bo"]) s.y = 1 s._reverse_index() self.assertEqual(s.display, [" ", "bo"]) self.assertEqual(s.y, 0 )
def test_index(self): s = screen((2,2)) s.display = ["bo", "sh"] s.x = 1 s._index() # Indexing on a row that isn't the last should just move the cursor # down. self.assertEqual(s.y, 1) self.assertEqual(s.x, 1) s._index() # Indexing on the last row should push everything up and create a new # row at the bottom. self.assertEqual(s.display, ["sh", " "]) self.assertEqual(s.y, 1)
def test_cursor_forward(self): s = screen((10, 10)) # Moving the cursor right at the margin doesn't do anything s.x = 9 s._cursor_forward(1) self.assertEqual(s.x, 9 ) # Moving the cursor past the right margin moves it to the right margin s.x = 8 s._cursor_forward(10) self.assertEqual(s.x, 9) # Can move the cursor more than one forward. s.x = 5 s._cursor_forward(3) self.assertEqual(s.x, 8 )
def test_cursor_up(self): s = screen((10, 10)) # Moving the cursor up at the top doesn't do anything s._cursor_up(1) self.assertEqual(s.y, 0) s.y = 1 # Moving the cursor past the top moves it to the top s._cursor_up(10) self.assertEqual(s.y, 0) s.y = 5 # Can move the cursor more than one up. s._cursor_up(3) self.assertEqual(s.y, 2)
def test_insert_line(self): s = screen((3,3)) s.display = ["sam", "is ", " "] self.assertEqual(s.x, 0) self.assertEqual(s.y, 0) s._insert_line(1) self.assertEqual(s.display, ["sam", " ", "is "]) self.assertEqual(s.x, 0) self.assertEqual(s.y, 0) s.display = ["sam", "is ", "foo"] s._insert_line(2) self.assertEqual(s.display, ["sam", " ", " "])
def test_cursor_position(self): s = screen((10, 10)) # Rows/columns are backwards of x/y and are 1-indexed instead of 0-indexed s._cursor_position(5, 10) self.assertEqual(s.x, 9) self.assertEqual(s.y, 4) # Confusingly enough, however, 0-inputs are acceptable and should be # the same a 1 s._cursor_position(0, 10) self.assertEqual(s.x, 9) self.assertEqual(s.y, 0) # Moving outside the margins constrains to within the margins. s._cursor_position(20, 20) self.assertEqual(s.x, 9) self.assertEqual(s.y, 9)
def test_cursor_back(self): s = screen((10, 10)) # Moving the cursor left at the margin doesn't do anything s.x = 0 s._cursor_back(1) self.assertEqual(s.x, 0) s.x = 3 # Moving the cursor past the left margin moves it to the left margin s._cursor_back(10) self.assertEqual(s.x, 0 ) s.x = 5 # Can move the cursor more than one back. s._cursor_back(3) self.assertEqual(s.x, 2)
def test_cursor_down(self): s = screen((10, 10)) # Moving the cursor down at the bottom doesn't do anything s.y = 9 s._cursor_down(1) self.assertEqual(s.y, 9) s.y = 8 # Moving the cursor past the bottom moves it to the bottom s._cursor_down(10) self.assertEqual(s.y, 9 ) s.y = 5 # Can move the cursor more than one down. s._cursor_down(3) self.assertEqual(s.y, 8)
def test_save_cursor(self): s = screen((10, 10)) s._save_cursor() s.x = 3 s.y = 5 s._save_cursor() s.x = 4 s.y = 4 s._restore_cursor() self.assertEqual(s.x, 3) self.assertEqual(s.y, 5) s._restore_cursor() self.assertEqual(s.x, 0) self.assertEqual(s.y, 0)
def test_save_cursor(self): s = screen((10,10)) s._save_cursor() s.x = 3 s.y = 5 s._save_cursor() s.x = 4 s.y = 4 s._restore_cursor() self.assertEqual(s.x, 3) self.assertEqual(s.y, 5) s._restore_cursor() self.assertEqual(s.x, 0) self.assertEqual(s.y, 0)
def test_erase_in_line(self): s = screen((5,5)) s.display = ["sam i", "s foo", "but a", "re yo", "u? "] s.x = 2 s.y = 0 # Erase from cursor to the end of line s._erase_in_line(0) assert s.display == ["sa ", "s foo", "but a", "re yo", "u? "] # Erase from the beginning of the line to the cursor s.display = ["sam i", "s foo", "but a", "re yo", "u? "] s._erase_in_line(1) assert s.display == [" i", "s foo", "but a", "re yo", "u? "] s.y = 1 # Erase the entire line s.display = ["sam i", "s foo", "but a", "re yo", "u? "] s._erase_in_line(2) assert s.display == ["sam i", " ", "but a", "re yo", "u? "]
def test_clear_tabstops(self): s = screen((10, 10)) s.x = 1 s._set_tab_stop() s._clear_tab_stop(0x30) self.assertEqual(len(s.tabstops), 0) s._set_tab_stop() s.x = 5 s._set_tab_stop() s.x = 9 s._set_tab_stop() self.assertEqual(len(s.tabstops), 3) s._clear_tab_stop(0x33) self.assertEqual(len(s.tabstops), 0)
def test_attributes_reset(self): s = screen((2,2)) assert s.attributes == [[s.default_attributes, s.default_attributes]] * 2 s._select_graphic_rendition(1) # Bold s._print("f") s._print("o") s._print("o") assert s.attributes == [ [(("bold",), "default", "default"), (("bold",), "default", "default")], [(("bold",), "default", "default"), s.default_attributes], ] s._home() s._select_graphic_rendition(0) # Reset s._print("f") assert s.attributes == [ [s.default_attributes, (("bold",), "default", "default")], [(("bold",), "default", "default"), s.default_attributes], ]
def test_erase_in_line(self): s = screen((5, 5)) s.display = ["sam i", "s foo", "but a", "re yo", "u? "] s.x = 2 s.y = 0 # Erase from cursor to the end of line s._erase_in_line(0) assert s.display == ["sa ", "s foo", "but a", "re yo", "u? "] # Erase from the beginning of the line to the cursor s.display = ["sam i", "s foo", "but a", "re yo", "u? "] s._erase_in_line(1) assert s.display == [" i", "s foo", "but a", "re yo", "u? "] s.y = 1 # Erase the entire line s.display = ["sam i", "s foo", "but a", "re yo", "u? "] s._erase_in_line(2) assert s.display == ["sam i", " ", "but a", "re yo", "u? "]
def test_attributes_reset(self): s = screen((2, 2)) assert s.attributes == [[s.default_attributes, s.default_attributes] ] * 2 s._select_graphic_rendition(1) # Bold s._print("f") s._print("o") s._print("o") assert s.attributes == [ [(("bold", ), "default", "default"), (("bold", ), "default", "default")], [(("bold", ), "default", "default"), s.default_attributes], ] s._home() s._select_graphic_rendition(0) # Reset s._print("f") assert s.attributes == [ [s.default_attributes, (("bold", ), "default", "default")], [(("bold", ), "default", "default"), s.default_attributes], ]
def test_erase_in_display(self): s = screen((5,5)) s.display = ["sam i", "s foo", "but a", "re yo", "u? "] s.y = 2 # Erase from the cursor to the end of the display. s._erase_in_display(0) assert s.display == ["sam i", "s foo", " ", " ", " "] # Erase from cursor to the beginning of the display. s.display = ["sam i", "s foo", "but a", "re yo", "u? "] s._erase_in_display(1) assert s.display == [" ", " ", " ", "re yo", "u? "] s.y = 1 # Erase the entire screen s._erase_in_display(2) assert s.display == [" ", " ", " ", " ", " "]
def _run(self, win): curses.nonl() curses.curs_set(1) self._win = win self._win.nodelay(1) self._win.scrollok(0) self._win.idlok(1) self._vt_stream = vt102.stream() self._vt_screen = vt102.screen(self._win.getmaxyx()) self._vt_screen.attach(self._vt_stream) self._buffered_output = u'' self._vt_stream.process(ConsoleServer.banner) server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind(('127.0.0.1', 6809)) server_socket.listen() server_socket.setblocking(False) self._selector.register(server_socket, selectors.EVENT_READ, self._accept) while True: events = self._selector.select(timeout=0.1) if self._want_exit: return for key, mask in events: callback = key.data callback(key.fileobj, mask) self._update() if len(self._buffered_input) > 0: if self._connection is not None: self._connection.send( self._buffered_input.encode('latin-1')) self._buffered_input = u''
logging.debug("Sending '%s' to child"%key) child.send(key) s = termcheck(child) logging.debug("Sending child.before text to vt102 stream") stream.process(child.before) logging.debug("vt102 screen dump") logging.debug(screen) # START LOGGING logging.basicConfig(filename='menu_demo.log',level=logging.DEBUG) # SETUP VT102 EMULATOR #rows, columns = os.popen('stty size', 'r').read().split() rows, columns = (50,120) stream=vt102.stream() screen=vt102.screen((int(rows), int(columns))) screen.attach(stream) logging.debug("Setup vt102 with %d %d"%(int(rows),int(columns))) logging.debug("Starting demo2.py child process...") child = pexpect.spawn('./demo2.py', maxread=65536, dimensions=(int(rows),int(columns))) s = termcheck(child) logging.debug("Sending child.before (len=%d) text to vt102 stream"%len(child.before)) stream.process(child.before) logging.debug("vt102 screen dump") logging.debug(screen) termkey(child, stream, screen, "a") termkey(child, stream, screen, "1")
def test_carriage_return(self): s = screen((3, 3)) s.x = 2 s._carriage_return() self.assertEqual(s.x, 0)