/
niceSOFT
/
python3-installer
Обзор
Документация
Войти
/
niceSOFT
/
python3-installer
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
tests/test_records.py
303 строки
9 KB
Bartosz Sokorski
Introduce more ruff rules (#230)
02 ноя 2024, 03:44
Не верифицирован
02 ноя 2024, 03:44
22619e6
Код
Авторство
О чём код?
from io import BytesIO from pathlib import Path import pytest from installer.records import Hash, InvalidRecordEntry, RecordEntry, parse_record_file # # pytest fixture witchcraft # @pytest.fixture() def record_simple_list(): return [ "file.py,sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI,3144", "distribution-1.0.dist-info/RECORD,,", ] @pytest.fixture() def record_simple_iter(record_simple_list): return iter(record_simple_list) @pytest.fixture() def record_simple_file(tmpdir, record_simple_list): p = tmpdir.join("RECORD") p.write("\n".join(record_simple_list)) with Path(p).open() as f: yield f @pytest.fixture() def record_input(request): return request.getfixturevalue(request.param) SAMPLE_RECORDS = [ ( "purelib", ("test1.py", "sha256=Y0sCextp4SQtQNU-MSs7SsdxD1W-gfKJtUlEbvZ3i-4", 6), b"test1\n", True, ), ( "purelib", ("test2.py", "sha256=fW_Xd08Nh2JNptzxbQ09EEwxkedx--LznIau1LK_Gg8", 6), b"test2\n", True, ), ( "purelib", ("test3.py", "sha256=qwPDTx7OCCEf4qgDn9ZCQZmz9de1X_E7ETSzZHdsRcU", 6), b"test3\n", True, ), ( "purelib", ( "test4.py", "sha256=Y0sCextp4SQtQNU-MSs7SsdxD1W-gfKJtUlEbvZ3i-4", None, ), b"test1\n", True, ), ("purelib", ("test5.py", None, None), b"test1\n", True), ("purelib", ("test6.py", None, 6), b"test1\n", True), ( "purelib", ("test7.py", "sha256=Y0sCextp4SQtQNU-MSs7SsdxD1W-gfKJtUlEbvZ3i-4", 7), b"test1\n", False, ), ( "purelib", ("test7.py", "sha256=Y0sCextp4SQtQNU-MSs7SsdxD1W-gfKJtUlEbvZ3i-4", None), b"not-test1\n", False, ), ("purelib", ("test8.py", None, 10), b"test1\n", False), ] # # Actual Tests # class TestRecordEntry: @pytest.mark.parametrize( "path, hash_, size, caused_by", [ ("", "", "", ["path"]), ("", "", "non-int", ["path", "size"]), ("a.py", "", "non-int", ["size"]), # Notice that we're explicitly allowing non-compliant hash values ("a.py", "some-random-value", "non-int", ["size"]), ], ) def test_invalid_elements(self, path, hash_, size, caused_by): with pytest.raises(InvalidRecordEntry) as exc_info: RecordEntry.from_elements(path, hash_, size) assert exc_info.value.elements == (path, hash_, size) for word in caused_by: assert word in str(exc_info.value) @pytest.mark.parametrize( "path, hash_, size", [ ("a.py", "", ""), ("a.py", "", "3144"), ("a.py", "sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI", ""), ("a.py", "sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI", "3144"), ], ) def test_valid_elements(self, path, hash_, size): RecordEntry.from_elements(path, hash_, size) @pytest.mark.parametrize( ("scheme", "elements", "data", "passes_validation"), SAMPLE_RECORDS ) def test_populates_attributes_correctly( self, scheme, elements, data, passes_validation ): path, hash_string, size = elements record = RecordEntry.from_elements(path, hash_string, size) assert record.path == path assert record.size == size if record.hash_ is not None: assert isinstance(record.hash_, Hash) assert record.hash_.name == "sha256" assert record.hash_.value == hash_string[len("sha256=") :] @pytest.mark.parametrize( ("scheme", "elements", "data", "passes_validation"), SAMPLE_RECORDS ) def test_validation(self, scheme, elements, data, passes_validation): record = RecordEntry.from_elements(*elements) assert record.validate(data) == passes_validation @pytest.mark.parametrize( ("scheme", "elements", "data", "passes_validation"), SAMPLE_RECORDS ) def test_validate_stream(self, scheme, elements, data, passes_validation): record = RecordEntry.from_elements(*elements) assert record.validate_stream(BytesIO(data)) == passes_validation @pytest.mark.parametrize( ("scheme", "elements", "data", "passes_validation"), SAMPLE_RECORDS ) def test_string_representation(self, scheme, elements, data, passes_validation): record = RecordEntry.from_elements(*elements) expected_row = tuple( [(str(elem) if elem is not None else "") for elem in elements] ) assert record.to_row() == expected_row @pytest.mark.parametrize( ("scheme", "elements", "data", "passes_validation"), SAMPLE_RECORDS ) def test_string_representation_with_prefix( self, scheme, elements, data, passes_validation ): record = RecordEntry.from_elements(*elements) expected_row = tuple( [ (str(elem) if elem is not None else "") for elem in ("prefix/" + elements[0], elements[1], elements[2]) ] ) assert record.to_row("prefix/") == expected_row def test_equality(self): record = RecordEntry.from_elements( "file.py", "sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI", "3144", ) record_same = RecordEntry.from_elements( "file.py", "sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI", "3144", ) record_different_name = RecordEntry.from_elements( "file2.py", "sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI", "3144", ) record_different_hash_name = RecordEntry.from_elements( "file.py", "md5=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI", "3144", ) record_different_hash_value = RecordEntry.from_elements( "file.py", "sha256=qwertyuiodfdsflkgshdlkjghrefawrwerwffsdfflk29", "3144", ) record_different_size = RecordEntry.from_elements( "file.py", "sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI", "10", ) assert record == record_same assert record != "random string" assert record != record_different_name assert record != record_different_hash_name assert record != record_different_hash_value assert record != record_different_size # Ensure equality is based on current state record_same.hash_ = None assert record != record_same class TestParseRecordFile: def test_accepts_empty_iterable(self): list(parse_record_file([])) @pytest.mark.parametrize( "record_input", ["record_simple_list", "record_simple_iter", "record_simple_file"], indirect=True, ) def test_accepts_all_kinds_of_iterables(self, record_input): """Should accepts any iterable, e.g. container, iterator, or file object.""" records = list(parse_record_file(record_input)) assert len(records) == 2 assert records == [ ( "file.py", "sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI", "3144", ), ("distribution-1.0.dist-info/RECORD", "", ""), ] @pytest.mark.parametrize( "line, element_count", [ pytest.param( "file.py,sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI,3144,", 4, id="four", ), pytest.param( "distribution-1.0.dist-info/RECORD,,,,", 5, id="five", ), ], ) def test_rejects_wrong_element_count(self, line, element_count): with pytest.raises(InvalidRecordEntry) as exc_info: list(parse_record_file([line])) message = f"expected 3 elements, got {element_count}" assert message in str(exc_info.value) def test_shows_correct_row_number(self): record_lines = [ "file1.py,sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI,3144", "file2.py,sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI,3144", "file3.py,sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI,3144", "distribution-1.0.dist-info/RECORD,,,,", ] with pytest.raises(InvalidRecordEntry) as exc_info: list(parse_record_file(record_lines)) assert "Row Index 3" in str(exc_info.value) def test_parse_record_entry_with_comma(self): record_lines = [ '"file1,file2.txt",sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI,3144', "distribution-1.0.dist-info/RECORD,,", ] records = list(parse_record_file(record_lines)) assert records == [ ( "file1,file2.txt", "sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI", "3144", ), ("distribution-1.0.dist-info/RECORD", "", ""), ] def test_parse_record_entry_with_backslash_path(self): record_lines = [ "distribution-1.0.dist-info\\RECORD,,", ] records = list(parse_record_file(record_lines)) assert records == [ ("distribution-1.0.dist-info/RECORD", "", ""), ]