123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- 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()
|