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 from pygame.compat import as_bytes 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_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, as_bytes("Hello world")) self.assertEqual(scrap.get(pygame.SCRAP_TEXT), as_bytes("Hello world")) scrap.put(pygame.SCRAP_TEXT, as_bytes("Another String")) self.assertEqual(scrap.get(pygame.SCRAP_TEXT), as_bytes("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, as_bytes('buf')) r = scrap.get(DATA_TYPE) self.assertEqual(r, as_bytes('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()