Updates
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
UNICODE_TEXT = "\u03b1\u03b2\u03b3"
|
||||
WHITE = (255, 255, 255)
|
||||
BLACK = (0, 0, 0)
|
||||
RED = (255, 0, 0)
|
||||
@@ -0,0 +1,13 @@
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
from qrcode import run_example
|
||||
|
||||
pytest.importorskip("PIL", reason="Requires PIL")
|
||||
|
||||
|
||||
@mock.patch("PIL.Image.Image.show")
|
||||
def test_example(mock_show):
|
||||
run_example()
|
||||
mock_show.assert_called_with()
|
||||
@@ -0,0 +1,271 @@
|
||||
import io
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
import qrcode
|
||||
import qrcode.util
|
||||
from qrcode.exceptions import DataOverflowError
|
||||
from qrcode.image.base import BaseImage
|
||||
from qrcode.tests.consts import UNICODE_TEXT
|
||||
from qrcode.util import MODE_8BIT_BYTE, MODE_ALPHA_NUM, MODE_NUMBER, QRData
|
||||
|
||||
|
||||
def test_basic():
|
||||
qr = qrcode.QRCode(version=1)
|
||||
qr.add_data("a")
|
||||
qr.make(fit=False)
|
||||
|
||||
|
||||
def test_large():
|
||||
qr = qrcode.QRCode(version=27)
|
||||
qr.add_data("a")
|
||||
qr.make(fit=False)
|
||||
|
||||
|
||||
def test_invalid_version():
|
||||
with pytest.raises(ValueError):
|
||||
qrcode.QRCode(version=42)
|
||||
|
||||
|
||||
def test_invalid_border():
|
||||
with pytest.raises(ValueError):
|
||||
qrcode.QRCode(border=-1)
|
||||
|
||||
|
||||
def test_overflow():
|
||||
qr = qrcode.QRCode(version=1)
|
||||
qr.add_data("abcdefghijklmno")
|
||||
with pytest.raises(DataOverflowError):
|
||||
qr.make(fit=False)
|
||||
|
||||
|
||||
def test_add_qrdata():
|
||||
qr = qrcode.QRCode(version=1)
|
||||
data = QRData("a")
|
||||
qr.add_data(data)
|
||||
qr.make(fit=False)
|
||||
|
||||
|
||||
def test_fit():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data("a")
|
||||
qr.make()
|
||||
assert qr.version == 1
|
||||
qr.add_data("bcdefghijklmno")
|
||||
qr.make()
|
||||
assert qr.version == 2
|
||||
|
||||
|
||||
def test_mode_number():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data("1234567890123456789012345678901234", optimize=0)
|
||||
qr.make()
|
||||
assert qr.version == 1
|
||||
assert qr.data_list[0].mode == MODE_NUMBER
|
||||
|
||||
|
||||
def test_mode_alpha():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data("ABCDEFGHIJ1234567890", optimize=0)
|
||||
qr.make()
|
||||
assert qr.version == 1
|
||||
assert qr.data_list[0].mode == MODE_ALPHA_NUM
|
||||
|
||||
|
||||
def test_regression_mode_comma():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(",", optimize=0)
|
||||
qr.make()
|
||||
assert qr.data_list[0].mode == MODE_8BIT_BYTE
|
||||
|
||||
|
||||
def test_mode_8bit():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data("abcABC" + UNICODE_TEXT, optimize=0)
|
||||
qr.make()
|
||||
assert qr.version == 1
|
||||
assert qr.data_list[0].mode == MODE_8BIT_BYTE
|
||||
|
||||
|
||||
def test_mode_8bit_newline():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data("ABCDEFGHIJ1234567890\n", optimize=0)
|
||||
qr.make()
|
||||
assert qr.data_list[0].mode == MODE_8BIT_BYTE
|
||||
|
||||
|
||||
def test_make_image_with_wrong_pattern():
|
||||
with pytest.raises(TypeError):
|
||||
qrcode.QRCode(mask_pattern="string pattern")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
qrcode.QRCode(mask_pattern=-1)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
qrcode.QRCode(mask_pattern=42)
|
||||
|
||||
|
||||
def test_mask_pattern_setter():
|
||||
qr = qrcode.QRCode()
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
qr.mask_pattern = "string pattern"
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
qr.mask_pattern = -1
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
qr.mask_pattern = 8
|
||||
|
||||
|
||||
def test_qrcode_bad_factory():
|
||||
with pytest.raises(TypeError):
|
||||
qrcode.QRCode(image_factory="not_BaseImage") # type: ignore
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
qrcode.QRCode(image_factory=dict) # type: ignore
|
||||
|
||||
|
||||
def test_qrcode_factory():
|
||||
class MockFactory(BaseImage):
|
||||
drawrect = mock.Mock()
|
||||
new_image = mock.Mock()
|
||||
|
||||
qr = qrcode.QRCode(image_factory=MockFactory)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
qr.make_image()
|
||||
assert MockFactory.new_image.called
|
||||
assert MockFactory.drawrect.called
|
||||
|
||||
|
||||
def test_optimize():
|
||||
qr = qrcode.QRCode()
|
||||
text = "A1abc12345def1HELLOa"
|
||||
qr.add_data(text, optimize=4)
|
||||
qr.make()
|
||||
assert [d.mode for d in qr.data_list] == [
|
||||
MODE_8BIT_BYTE,
|
||||
MODE_NUMBER,
|
||||
MODE_8BIT_BYTE,
|
||||
MODE_ALPHA_NUM,
|
||||
MODE_8BIT_BYTE,
|
||||
]
|
||||
assert qr.version == 2
|
||||
|
||||
|
||||
def test_optimize_short():
|
||||
qr = qrcode.QRCode()
|
||||
text = "A1abc1234567def1HELLOa"
|
||||
qr.add_data(text, optimize=7)
|
||||
qr.make()
|
||||
assert len(qr.data_list) == 3
|
||||
assert [d.mode for d in qr.data_list] == [
|
||||
MODE_8BIT_BYTE,
|
||||
MODE_NUMBER,
|
||||
MODE_8BIT_BYTE,
|
||||
]
|
||||
assert qr.version == 2
|
||||
|
||||
|
||||
def test_optimize_longer_than_data():
|
||||
qr = qrcode.QRCode()
|
||||
text = "ABCDEFGHIJK"
|
||||
qr.add_data(text, optimize=12)
|
||||
assert len(qr.data_list) == 1
|
||||
assert qr.data_list[0].mode == MODE_ALPHA_NUM
|
||||
|
||||
|
||||
def test_optimize_size():
|
||||
text = "A1abc12345123451234512345def1HELLOHELLOHELLOHELLOa" * 5
|
||||
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(text)
|
||||
qr.make()
|
||||
assert qr.version == 10
|
||||
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(text, optimize=0)
|
||||
qr.make()
|
||||
assert qr.version == 11
|
||||
|
||||
|
||||
def test_qrdata_repr():
|
||||
data = b"hello"
|
||||
data_obj = qrcode.util.QRData(data)
|
||||
assert repr(data_obj) == repr(data)
|
||||
|
||||
|
||||
def test_print_ascii_stdout():
|
||||
qr = qrcode.QRCode()
|
||||
with mock.patch("sys.stdout") as fake_stdout:
|
||||
fake_stdout.isatty.return_value = None
|
||||
with pytest.raises(OSError):
|
||||
qr.print_ascii(tty=True)
|
||||
assert fake_stdout.isatty.called
|
||||
|
||||
|
||||
def test_print_ascii():
|
||||
qr = qrcode.QRCode(border=0)
|
||||
f = io.StringIO()
|
||||
qr.print_ascii(out=f)
|
||||
printed = f.getvalue()
|
||||
f.close()
|
||||
expected = "\u2588\u2580\u2580\u2580\u2580\u2580\u2588"
|
||||
assert printed[: len(expected)] == expected
|
||||
|
||||
f = io.StringIO()
|
||||
f.isatty = lambda: True
|
||||
qr.print_ascii(out=f, tty=True)
|
||||
printed = f.getvalue()
|
||||
f.close()
|
||||
expected = "\x1b[48;5;232m\x1b[38;5;255m" + "\xa0\u2584\u2584\u2584\u2584\u2584\xa0"
|
||||
assert printed[: len(expected)] == expected
|
||||
|
||||
|
||||
def test_print_tty_stdout():
|
||||
qr = qrcode.QRCode()
|
||||
with mock.patch("sys.stdout") as fake_stdout:
|
||||
fake_stdout.isatty.return_value = None
|
||||
pytest.raises(OSError, qr.print_tty)
|
||||
assert fake_stdout.isatty.called
|
||||
|
||||
|
||||
def test_print_tty():
|
||||
qr = qrcode.QRCode()
|
||||
f = io.StringIO()
|
||||
f.isatty = lambda: True
|
||||
qr.print_tty(out=f)
|
||||
printed = f.getvalue()
|
||||
f.close()
|
||||
BOLD_WHITE_BG = "\x1b[1;47m"
|
||||
BLACK_BG = "\x1b[40m"
|
||||
WHITE_BLOCK = BOLD_WHITE_BG + " " + BLACK_BG
|
||||
EOL = "\x1b[0m\n"
|
||||
expected = BOLD_WHITE_BG + " " * 23 + EOL + WHITE_BLOCK + " " * 7 + WHITE_BLOCK
|
||||
assert printed[: len(expected)] == expected
|
||||
|
||||
|
||||
def test_get_matrix():
|
||||
qr = qrcode.QRCode(border=0)
|
||||
qr.add_data("1")
|
||||
assert qr.get_matrix() == qr.modules
|
||||
|
||||
|
||||
def test_get_matrix_border():
|
||||
qr = qrcode.QRCode(border=1)
|
||||
qr.add_data("1")
|
||||
matrix = [row[1:-1] for row in qr.get_matrix()[1:-1]]
|
||||
assert matrix == qr.modules
|
||||
|
||||
|
||||
def test_negative_size_at_construction():
|
||||
with pytest.raises(ValueError):
|
||||
qrcode.QRCode(box_size=-1)
|
||||
|
||||
|
||||
def test_negative_size_at_usage():
|
||||
qr = qrcode.QRCode()
|
||||
qr.box_size = -1
|
||||
with pytest.raises(ValueError):
|
||||
qr.make_image()
|
||||
@@ -0,0 +1,157 @@
|
||||
import io
|
||||
|
||||
import pytest
|
||||
|
||||
import qrcode
|
||||
import qrcode.util
|
||||
from qrcode.tests.consts import BLACK, RED, UNICODE_TEXT, WHITE
|
||||
|
||||
Image = pytest.importorskip("PIL.Image", reason="PIL is not installed")
|
||||
|
||||
if Image:
|
||||
from qrcode.image.styledpil import StyledPilImage
|
||||
from qrcode.image.styles import colormasks, moduledrawers
|
||||
|
||||
|
||||
def test_render_pil():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image()
|
||||
img.save(io.BytesIO())
|
||||
assert isinstance(img.get_image(), Image.Image)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("back_color", ["TransParent", "red", (255, 195, 235)])
|
||||
def test_render_pil_background(back_color):
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(back_color="TransParent")
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_render_pil_with_rgb_color_tuples():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(back_color=(255, 195, 235), fill_color=(55, 95, 35))
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_render_with_pattern():
|
||||
qr = qrcode.QRCode(mask_pattern=3)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image()
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_render_styled_Image():
|
||||
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_L)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=StyledPilImage)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_render_styled_with_embedded_image():
|
||||
embedded_img = Image.new("RGB", (10, 10), color="red")
|
||||
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_H)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=StyledPilImage, embedded_image=embedded_img)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_render_styled_with_embedded_image_path(tmp_path):
|
||||
tmpfile = str(tmp_path / "test.png")
|
||||
embedded_img = Image.new("RGB", (10, 10), color="red")
|
||||
embedded_img.save(tmpfile)
|
||||
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_H)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=StyledPilImage, embedded_image_path=tmpfile)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"drawer",
|
||||
[
|
||||
moduledrawers.CircleModuleDrawer,
|
||||
moduledrawers.GappedSquareModuleDrawer,
|
||||
moduledrawers.HorizontalBarsDrawer,
|
||||
moduledrawers.RoundedModuleDrawer,
|
||||
moduledrawers.SquareModuleDrawer,
|
||||
moduledrawers.VerticalBarsDrawer,
|
||||
],
|
||||
)
|
||||
def test_render_styled_with_drawer(drawer):
|
||||
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_L)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(
|
||||
image_factory=StyledPilImage,
|
||||
module_drawer=drawer(),
|
||||
)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mask",
|
||||
[
|
||||
colormasks.SolidFillColorMask(),
|
||||
colormasks.SolidFillColorMask(back_color=WHITE, front_color=RED),
|
||||
colormasks.SolidFillColorMask(back_color=(255, 0, 255, 255), front_color=RED),
|
||||
colormasks.RadialGradiantColorMask(
|
||||
back_color=WHITE, center_color=BLACK, edge_color=RED
|
||||
),
|
||||
colormasks.SquareGradiantColorMask(
|
||||
back_color=WHITE, center_color=BLACK, edge_color=RED
|
||||
),
|
||||
colormasks.HorizontalGradiantColorMask(
|
||||
back_color=WHITE, left_color=RED, right_color=BLACK
|
||||
),
|
||||
colormasks.VerticalGradiantColorMask(
|
||||
back_color=WHITE, top_color=RED, bottom_color=BLACK
|
||||
),
|
||||
colormasks.ImageColorMask(
|
||||
back_color=WHITE, color_mask_image=Image.new("RGB", (10, 10), color="red")
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_render_styled_with_mask(mask):
|
||||
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_L)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=StyledPilImage, color_mask=mask)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_embedded_image_and_error_correction(tmp_path):
|
||||
"If an embedded image is specified, error correction must be the highest so the QR code is readable"
|
||||
tmpfile = str(tmp_path / "test.png")
|
||||
embedded_img = Image.new("RGB", (10, 10), color="red")
|
||||
embedded_img.save(tmpfile)
|
||||
|
||||
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_L)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
with pytest.raises(ValueError):
|
||||
qr.make_image(embedded_image_path=tmpfile)
|
||||
with pytest.raises(ValueError):
|
||||
qr.make_image(embedded_image=embedded_img)
|
||||
|
||||
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_M)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
with pytest.raises(ValueError):
|
||||
qr.make_image(embedded_image_path=tmpfile)
|
||||
with pytest.raises(ValueError):
|
||||
qr.make_image(embedded_image=embedded_img)
|
||||
|
||||
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_Q)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
with pytest.raises(ValueError):
|
||||
qr.make_image(embedded_image_path=tmpfile)
|
||||
with pytest.raises(ValueError):
|
||||
qr.make_image(embedded_image=embedded_img)
|
||||
|
||||
# The only accepted correction level when an embedded image is provided
|
||||
qr = qrcode.QRCode(error_correction=qrcode.ERROR_CORRECT_H)
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
qr.make_image(embedded_image_path=tmpfile)
|
||||
qr.make_image(embedded_image=embedded_img)
|
||||
|
||||
|
||||
def test_shortcut():
|
||||
qrcode.make("image")
|
||||
@@ -0,0 +1,35 @@
|
||||
import io
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
import qrcode
|
||||
import qrcode.util
|
||||
from qrcode.image.pure import PyPNGImage
|
||||
from qrcode.tests.consts import UNICODE_TEXT
|
||||
|
||||
png = pytest.importorskip("png", reason="png is not installed")
|
||||
|
||||
|
||||
def test_render_pypng():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=PyPNGImage)
|
||||
assert isinstance(img.get_image(), png.Writer)
|
||||
|
||||
print(img.width, img.box_size, img.border)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_render_pypng_to_str():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=PyPNGImage)
|
||||
assert isinstance(img.get_image(), png.Writer)
|
||||
|
||||
mock_open = mock.mock_open()
|
||||
with mock.patch("qrcode.image.pure.open", mock_open, create=True):
|
||||
img.save("test_file.png")
|
||||
mock_open.assert_called_once_with("test_file.png", "wb")
|
||||
mock_open("test_file.png", "wb").write.assert_called()
|
||||
@@ -0,0 +1,54 @@
|
||||
import io
|
||||
|
||||
import qrcode
|
||||
from qrcode.image import svg
|
||||
from qrcode.tests.consts import UNICODE_TEXT
|
||||
|
||||
|
||||
class SvgImageWhite(svg.SvgImage):
|
||||
background = "white"
|
||||
|
||||
|
||||
def test_render_svg():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=svg.SvgImage)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_render_svg_path():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=svg.SvgPathImage)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_render_svg_fragment():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=svg.SvgFragmentImage)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_svg_string():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=svg.SvgFragmentImage)
|
||||
file_like = io.BytesIO()
|
||||
img.save(file_like)
|
||||
file_like.seek(0)
|
||||
assert file_like.read() in img.to_string()
|
||||
|
||||
|
||||
def test_render_svg_with_background():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=SvgImageWhite)
|
||||
img.save(io.BytesIO())
|
||||
|
||||
|
||||
def test_svg_circle_drawer():
|
||||
qr = qrcode.QRCode()
|
||||
qr.add_data(UNICODE_TEXT)
|
||||
img = qr.make_image(image_factory=svg.SvgPathImage, module_drawer="circle")
|
||||
img.save(io.BytesIO())
|
||||
@@ -0,0 +1,43 @@
|
||||
import builtins
|
||||
import datetime
|
||||
import re
|
||||
from unittest import mock
|
||||
|
||||
from qrcode.release import update_manpage
|
||||
|
||||
OPEN = f"{builtins.__name__}.open"
|
||||
DATA = 'test\n.TH "date" "version" "description"\nthis'
|
||||
|
||||
|
||||
@mock.patch(OPEN, new_callable=mock.mock_open, read_data=".TH invalid")
|
||||
def test_invalid_data(mock_file):
|
||||
update_manpage({"name": "qrcode", "new_version": "1.23"})
|
||||
mock_file.assert_called()
|
||||
mock_file().write.assert_not_called()
|
||||
|
||||
|
||||
@mock.patch(OPEN, new_callable=mock.mock_open, read_data=DATA)
|
||||
def test_not_qrcode(mock_file):
|
||||
update_manpage({"name": "not-qrcode"})
|
||||
mock_file.assert_not_called()
|
||||
|
||||
|
||||
@mock.patch(OPEN, new_callable=mock.mock_open, read_data=DATA)
|
||||
def test_no_change(mock_file):
|
||||
update_manpage({"name": "qrcode", "new_version": "version"})
|
||||
mock_file.assert_called()
|
||||
mock_file().write.assert_not_called()
|
||||
|
||||
|
||||
@mock.patch(OPEN, new_callable=mock.mock_open, read_data=DATA)
|
||||
def test_change(mock_file):
|
||||
update_manpage({"name": "qrcode", "new_version": "3.11"})
|
||||
expected = re.split(r"([^\n]*(?:\n|$))", DATA)[1::2]
|
||||
expected[1] = (
|
||||
expected[1]
|
||||
.replace("version", "3.11")
|
||||
.replace("date", datetime.datetime.now().strftime("%-d %b %Y"))
|
||||
)
|
||||
mock_file().write.assert_has_calls(
|
||||
[mock.call(line) for line in expected if line != ""], any_order=True
|
||||
)
|
||||
@@ -0,0 +1,97 @@
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
from qrcode.console_scripts import commas, main
|
||||
|
||||
|
||||
def bad_read():
|
||||
raise UnicodeDecodeError("utf-8", b"0x80", 0, 1, "invalid start byte")
|
||||
|
||||
|
||||
@mock.patch("os.isatty", lambda *args: True)
|
||||
@mock.patch("qrcode.main.QRCode.print_ascii")
|
||||
def test_isatty(mock_print_ascii):
|
||||
main(["testtext"])
|
||||
mock_print_ascii.assert_called_with(tty=True)
|
||||
|
||||
|
||||
@mock.patch("os.isatty", lambda *args: False)
|
||||
def test_piped():
|
||||
pytest.importorskip("PIL", reason="Requires PIL")
|
||||
main(["testtext"])
|
||||
|
||||
|
||||
@mock.patch("os.isatty", lambda *args: True)
|
||||
def test_stdin():
|
||||
with mock.patch("qrcode.main.QRCode.print_ascii") as mock_print_ascii:
|
||||
with mock.patch("sys.stdin") as mock_stdin:
|
||||
mock_stdin.buffer.read.return_value = "testtext"
|
||||
main([])
|
||||
assert mock_stdin.buffer.read.called
|
||||
mock_print_ascii.assert_called_with(tty=True)
|
||||
|
||||
|
||||
@mock.patch("os.isatty", lambda *args: True)
|
||||
def test_stdin_py3_unicodedecodeerror():
|
||||
with mock.patch("qrcode.main.QRCode.print_ascii") as mock_print_ascii:
|
||||
with mock.patch("sys.stdin") as mock_stdin:
|
||||
mock_stdin.buffer.read.return_value = "testtext"
|
||||
mock_stdin.read.side_effect = bad_read
|
||||
# sys.stdin.read() will raise an error...
|
||||
with pytest.raises(UnicodeDecodeError):
|
||||
sys.stdin.read()
|
||||
# ... but it won't be used now.
|
||||
main([])
|
||||
mock_print_ascii.assert_called_with(tty=True)
|
||||
|
||||
|
||||
def test_optimize():
|
||||
pytest.importorskip("PIL", reason="Requires PIL")
|
||||
main("testtext --optimize 0".split())
|
||||
|
||||
|
||||
def test_factory():
|
||||
main(["testtext", "--factory", "svg"])
|
||||
|
||||
|
||||
def test_bad_factory():
|
||||
with pytest.raises(SystemExit):
|
||||
main(["testtext", "--factory", "nope"])
|
||||
|
||||
|
||||
@mock.patch.object(sys, "argv", "qr testtext output".split())
|
||||
def test_sys_argv():
|
||||
pytest.importorskip("PIL", reason="Requires PIL")
|
||||
main()
|
||||
|
||||
|
||||
def test_output(tmp_path):
|
||||
pytest.importorskip("PIL", reason="Requires PIL")
|
||||
main(["testtext", "--output", str(tmp_path / "test.png")])
|
||||
|
||||
|
||||
def test_factory_drawer_none(capsys):
|
||||
pytest.importorskip("PIL", reason="Requires PIL")
|
||||
with pytest.raises(SystemExit):
|
||||
main("testtext --factory pil --factory-drawer nope".split())
|
||||
assert "The selected factory has no drawer aliases" in capsys.readouterr()[1]
|
||||
|
||||
|
||||
def test_factory_drawer_bad(capsys):
|
||||
with pytest.raises(SystemExit):
|
||||
main("testtext --factory svg --factory-drawer sobad".split())
|
||||
assert "sobad factory drawer not found" in capsys.readouterr()[1]
|
||||
|
||||
|
||||
def test_factory_drawer(capsys):
|
||||
main("testtext --factory svg --factory-drawer circle".split())
|
||||
|
||||
|
||||
def test_commas():
|
||||
assert commas([]) == ""
|
||||
assert commas(["A"]) == "A"
|
||||
assert commas("AB") == "A or B"
|
||||
assert commas("ABC") == "A, B or C"
|
||||
assert commas("ABC", joiner="and") == "A, B and C"
|
||||
@@ -0,0 +1,11 @@
|
||||
import pytest
|
||||
|
||||
from qrcode import util
|
||||
|
||||
|
||||
def test_check_wrong_version():
|
||||
with pytest.raises(ValueError):
|
||||
util.check_version(0)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
util.check_version(41)
|
||||
Reference in New Issue
Block a user