106 lines
3.7 KiB
Python
106 lines
3.7 KiB
Python
import io
|
|
import os
|
|
import sys
|
|
import unittest
|
|
from tempfile import mkdtemp
|
|
from unittest import mock
|
|
|
|
from qrcode.compat.pil import Image
|
|
from qrcode.console_scripts import commas, main
|
|
|
|
|
|
def bad_read():
|
|
raise UnicodeDecodeError("utf-8", b"0x80", 0, 1, "invalid start byte")
|
|
|
|
|
|
class ScriptTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.tmpdir = mkdtemp()
|
|
|
|
def tearDown(self):
|
|
os.rmdir(self.tmpdir)
|
|
|
|
@mock.patch("os.isatty", lambda *args: True)
|
|
@mock.patch("qrcode.main.QRCode.print_ascii")
|
|
def test_isatty(self, mock_print_ascii):
|
|
main(["testtext"])
|
|
mock_print_ascii.assert_called_with(tty=True)
|
|
|
|
@mock.patch("os.isatty", lambda *args: False)
|
|
@mock.patch("sys.stdout")
|
|
@unittest.skipIf(not Image, "Requires PIL")
|
|
def test_piped(self, mock_stdout):
|
|
main(["testtext"])
|
|
|
|
@mock.patch("os.isatty", lambda *args: True)
|
|
@mock.patch("qrcode.main.QRCode.print_ascii")
|
|
@mock.patch("sys.stdin")
|
|
def test_stdin(self, mock_stdin, mock_print_ascii):
|
|
mock_stdin.buffer.read.return_value = "testtext"
|
|
main([])
|
|
self.assertTrue(mock_stdin.buffer.read.called)
|
|
mock_print_ascii.assert_called_with(tty=True)
|
|
|
|
@mock.patch("os.isatty", lambda *args: True)
|
|
@mock.patch("qrcode.main.QRCode.print_ascii")
|
|
def test_stdin_py3_unicodedecodeerror(self, mock_print_ascii):
|
|
mock_stdin = mock.Mock(sys.stdin)
|
|
mock_stdin.buffer.read.return_value = "testtext"
|
|
mock_stdin.read.side_effect = bad_read
|
|
with mock.patch("sys.stdin", mock_stdin):
|
|
# sys.stdin.read() will raise an error...
|
|
self.assertRaises(UnicodeDecodeError, sys.stdin.read)
|
|
# ... but it won't be used now.
|
|
main([])
|
|
mock_print_ascii.assert_called_with(tty=True)
|
|
|
|
@mock.patch("os.isatty", lambda *args: True)
|
|
@mock.patch("qrcode.main.QRCode.print_ascii")
|
|
def test_optimize(self, mock_print_ascii):
|
|
main("testtext --optimize 0".split())
|
|
|
|
@mock.patch("sys.stdout")
|
|
def test_factory(self, mock_stdout):
|
|
main("testtext --factory svg".split())
|
|
|
|
@mock.patch("sys.stderr")
|
|
def test_bad_factory(self, mock_stderr):
|
|
self.assertRaises(SystemExit, main, "testtext --factory fish".split())
|
|
|
|
@mock.patch.object(sys, "argv", "qr testtext output".split())
|
|
@unittest.skipIf(not Image, "Requires PIL")
|
|
def test_sys_argv(self):
|
|
main()
|
|
|
|
@unittest.skipIf(not Image, "Requires PIL")
|
|
def test_output(self):
|
|
tmpfile = os.path.join(self.tmpdir, "test.png")
|
|
main(["testtext", "--output", tmpfile])
|
|
os.remove(tmpfile)
|
|
|
|
@mock.patch("sys.stderr", new_callable=io.StringIO)
|
|
@unittest.skipIf(not Image, "Requires PIL")
|
|
def test_factory_drawer_none(self, mock_stderr):
|
|
with self.assertRaises(SystemExit):
|
|
main("testtext --factory pil --factory-drawer nope".split())
|
|
self.assertIn(
|
|
"The selected factory has no drawer aliases", mock_stderr.getvalue()
|
|
)
|
|
|
|
@mock.patch("sys.stderr", new_callable=io.StringIO)
|
|
def test_factory_drawer_bad(self, mock_stderr):
|
|
with self.assertRaises(SystemExit):
|
|
main("testtext --factory svg --factory-drawer sobad".split())
|
|
self.assertIn("sobad factory drawer not found", mock_stderr.getvalue())
|
|
|
|
@mock.patch("sys.stderr", new_callable=io.StringIO)
|
|
def test_factory_drawer(self, mock_stderr):
|
|
main("testtext --factory svg --factory-drawer circle".split())
|
|
|
|
def test_commas(self):
|
|
self.assertEqual(commas([]), "")
|
|
self.assertEqual(commas(["A"]), "A")
|
|
self.assertEqual(commas("AB"), "A or B")
|
|
self.assertEqual(commas("ABC"), "A, B or C")
|
|
self.assertEqual(commas("ABC", joiner="and"), "A, B and C")
|