import os import sys if os.environ.get("SDL_VIDEODRIVER") == "dummy": __tags__ = ("ignore", "subprocess_ignore") import unittest from pygame.tests.test_utils import trunk_relative_path import pygame from pygame import scrap class ScrapModuleTest(unittest.TestCase): @classmethod def setUpClass(cls): pygame.display.init() pygame.display.set_mode((1, 1)) scrap.init() @classmethod def tearDownClass(cls): # scrap.quit() # Does not exist! pygame.display.quit() def test_init(self): """Ensures scrap module still initialized after multiple init calls.""" scrap.init() scrap.init() self.assertTrue(scrap.get_init()) def test_init__reinit(self): """Ensures reinitializing the scrap module doesn't clear its data.""" data_type = pygame.SCRAP_TEXT expected_data = b"test_init__reinit" scrap.put(data_type, expected_data) scrap.init() self.assertEqual(scrap.get(data_type), expected_data) def test_get_init(self): """Ensures get_init gets the init state.""" self.assertTrue(scrap.get_init()) def todo_test_contains(self): """Ensures contains works as expected.""" self.fail() def todo_test_get(self): """Ensures get works as expected.""" self.fail() def test_get__owned_empty_type(self): """Ensures get works when there is no data of the requested type in the clipboard and the clipboard is owned by the pygame application. """ # Use a unique data type identifier to ensure there is no preexisting # data. DATA_TYPE = "test_get__owned_empty_type" if scrap.lost(): # Try to acquire the clipboard. scrap.put(pygame.SCRAP_TEXT, b"text to clipboard") if scrap.lost(): self.skipTest("requires the pygame application to own the clipboard") data = scrap.get(DATA_TYPE) self.assertIsNone(data) def todo_test_get_types(self): """Ensures get_types works as expected.""" self.fail() def todo_test_lost(self): """Ensures lost works as expected.""" self.fail() def test_set_mode(self): """Ensures set_mode works as expected.""" scrap.set_mode(pygame.SCRAP_SELECTION) scrap.set_mode(pygame.SCRAP_CLIPBOARD) self.assertRaises(ValueError, scrap.set_mode, 1099) def test_put__text(self): """Ensures put can place text into the clipboard.""" scrap.put(pygame.SCRAP_TEXT, b"Hello world") self.assertEqual(scrap.get(pygame.SCRAP_TEXT), b"Hello world") scrap.put(pygame.SCRAP_TEXT, b"Another String") self.assertEqual(scrap.get(pygame.SCRAP_TEXT), b"Another String") @unittest.skipIf("pygame.image" not in sys.modules, "requires pygame.image module") def test_put__bmp_image(self): """Ensures put can place a BMP image into the clipboard.""" sf = pygame.image.load(trunk_relative_path("examples/data/asprite.bmp")) expected_string = pygame.image.tostring(sf, "RGBA") scrap.put(pygame.SCRAP_BMP, expected_string) self.assertEqual(scrap.get(pygame.SCRAP_BMP), expected_string) def test_put(self): """Ensures put can place data into the clipboard when using a user defined type identifier. """ DATA_TYPE = "arbitrary buffer" scrap.put(DATA_TYPE, b"buf") r = scrap.get(DATA_TYPE) self.assertEqual(r, b"buf") class ScrapModuleClipboardNotOwnedTest(unittest.TestCase): """Test the scrap module's functionality when the pygame application is not the current owner of the clipboard. A separate class is used to prevent tests that acquire the clipboard from interfering with these tests. """ @classmethod def setUpClass(cls): pygame.display.init() pygame.display.set_mode((1, 1)) scrap.init() @classmethod def tearDownClass(cls): # scrap.quit() # Does not exist! pygame.quit() pygame.display.quit() def _skip_if_clipboard_owned(self): # Skip test if the pygame application owns the clipboard. Currently, # there is no way to give up ownership. if not scrap.lost(): self.skipTest("requires the pygame application to not own the clipboard") def test_get__not_owned(self): """Ensures get works when there is no data of the requested type in the clipboard and the clipboard is not owned by the pygame application. """ self._skip_if_clipboard_owned() # Use a unique data type identifier to ensure there is no preexisting # data. DATA_TYPE = "test_get__not_owned" data = scrap.get(DATA_TYPE) self.assertIsNone(data) def test_get_types__not_owned(self): """Ensures get_types works when the clipboard is not owned by the pygame application. """ self._skip_if_clipboard_owned() data_types = scrap.get_types() self.assertIsInstance(data_types, list) def test_contains__not_owned(self): """Ensures contains works when the clipboard is not owned by the pygame application. """ self._skip_if_clipboard_owned() # Use a unique data type identifier to ensure there is no preexisting # data. DATA_TYPE = "test_contains__not_owned" contains = scrap.contains(DATA_TYPE) self.assertFalse(contains) def test_lost__not_owned(self): """Ensures lost works when the clipboard is not owned by the pygame application. """ self._skip_if_clipboard_owned() lost = scrap.lost() self.assertTrue(lost) class X11InteractiveTest(unittest.TestCase): __tags__ = ["ignore", "subprocess_ignore"] try: pygame.display.init() except Exception: pass else: if pygame.display.get_driver() == "x11": __tags__ = ["interactive"] pygame.display.quit() def test_issue_208(self): """PATCH: pygame.scrap on X11, fix copying into PRIMARY selection Copying into theX11 PRIMARY selection (mouse copy/paste) would not work due to a confusion between content type and clipboard type. """ from pygame import display, event, freetype from pygame.locals import SCRAP_SELECTION, SCRAP_TEXT from pygame.locals import KEYDOWN, K_y, QUIT success = False freetype.init() font = freetype.Font(None, 24) display.init() display.set_caption("Interactive X11 Paste Test") screen = display.set_mode((600, 200)) screen.fill(pygame.Color("white")) text = "Scrap put() succeeded." msg = ( "Some text has been placed into the X11 clipboard." " Please click the center mouse button in an open" " text window to retrieve it." '\n\nDid you get "{}"? (y/n)' ).format(text) word_wrap(screen, msg, font, 6) display.flip() event.pump() scrap.init() scrap.set_mode(SCRAP_SELECTION) scrap.put(SCRAP_TEXT, text.encode("UTF-8")) while True: e = event.wait() if e.type == QUIT: break if e.type == KEYDOWN: success = e.key == K_y break pygame.display.quit() self.assertTrue(success) def word_wrap(surf, text, font, margin=0, color=(0, 0, 0)): font.origin = True surf_width, surf_height = surf.get_size() width = surf_width - 2 * margin height = surf_height - 2 * margin line_spacing = int(1.25 * font.get_sized_height()) x, y = margin, margin + line_spacing space = font.get_rect(" ") for word in iwords(text): if word == "\n": x, y = margin, y + line_spacing else: bounds = font.get_rect(word) if x + bounds.width + bounds.x >= width: x, y = margin, y + line_spacing if x + bounds.width + bounds.x >= width: raise ValueError("word too wide for the surface") if y + bounds.height - bounds.y >= height: raise ValueError("text to long for the surface") font.render_to(surf, (x, y), None, color) x += bounds.width + space.width return x, y def iwords(text): # r"\n|[^ ]+" # head = 0 tail = head end = len(text) while head < end: if text[head] == " ": head += 1 tail = head + 1 elif text[head] == "\n": head += 1 yield "\n" tail = head + 1 elif tail == end: yield text[head:] head = end elif text[tail] == "\n": yield text[head:tail] head = tail elif text[tail] == " ": yield text[head:tail] head = tail else: tail += 1 if __name__ == "__main__": unittest.main()