test_script.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import sys
  2. from unittest import mock
  3. import pytest
  4. from qrcode.console_scripts import commas, main
  5. def bad_read():
  6. raise UnicodeDecodeError("utf-8", b"0x80", 0, 1, "invalid start byte")
  7. @mock.patch("os.isatty", lambda *args: True)
  8. @mock.patch("qrcode.main.QRCode.print_ascii")
  9. def test_isatty(mock_print_ascii):
  10. main(["testtext"])
  11. mock_print_ascii.assert_called_with(tty=True)
  12. @mock.patch("os.isatty", lambda *args: False)
  13. def test_piped():
  14. pytest.importorskip("PIL", reason="Requires PIL")
  15. main(["testtext"])
  16. @mock.patch("os.isatty", lambda *args: True)
  17. def test_stdin():
  18. with mock.patch("qrcode.main.QRCode.print_ascii") as mock_print_ascii:
  19. with mock.patch("sys.stdin") as mock_stdin:
  20. mock_stdin.buffer.read.return_value = "testtext"
  21. main([])
  22. assert mock_stdin.buffer.read.called
  23. mock_print_ascii.assert_called_with(tty=True)
  24. @mock.patch("os.isatty", lambda *args: True)
  25. def test_stdin_py3_unicodedecodeerror():
  26. with mock.patch("qrcode.main.QRCode.print_ascii") as mock_print_ascii:
  27. with mock.patch("sys.stdin") as mock_stdin:
  28. mock_stdin.buffer.read.return_value = "testtext"
  29. mock_stdin.read.side_effect = bad_read
  30. # sys.stdin.read() will raise an error...
  31. with pytest.raises(UnicodeDecodeError):
  32. sys.stdin.read()
  33. # ... but it won't be used now.
  34. main([])
  35. mock_print_ascii.assert_called_with(tty=True)
  36. def test_optimize():
  37. pytest.importorskip("PIL", reason="Requires PIL")
  38. main("testtext --optimize 0".split())
  39. def test_factory():
  40. main(["testtext", "--factory", "svg"])
  41. def test_bad_factory():
  42. with pytest.raises(SystemExit):
  43. main(["testtext", "--factory", "nope"])
  44. @mock.patch.object(sys, "argv", "qr testtext output".split())
  45. def test_sys_argv():
  46. pytest.importorskip("PIL", reason="Requires PIL")
  47. main()
  48. def test_output(tmp_path):
  49. pytest.importorskip("PIL", reason="Requires PIL")
  50. main(["testtext", "--output", str(tmp_path / "test.png")])
  51. def test_factory_drawer_none(capsys):
  52. pytest.importorskip("PIL", reason="Requires PIL")
  53. with pytest.raises(SystemExit):
  54. main("testtext --factory pil --factory-drawer nope".split())
  55. assert "The selected factory has no drawer aliases" in capsys.readouterr()[1]
  56. def test_factory_drawer_bad(capsys):
  57. with pytest.raises(SystemExit):
  58. main("testtext --factory svg --factory-drawer sobad".split())
  59. assert "sobad factory drawer not found" in capsys.readouterr()[1]
  60. def test_factory_drawer(capsys):
  61. main("testtext --factory svg --factory-drawer circle".split())
  62. def test_commas():
  63. assert commas([]) == ""
  64. assert commas(["A"]) == "A"
  65. assert commas("AB") == "A or B"
  66. assert commas("ABC") == "A, B or C"
  67. assert commas("ABC", joiner="and") == "A, B and C"