|
9 | 9 | import unittest |
10 | 10 | from itertools import chain |
11 | 11 | from pathlib import Path |
12 | | -from unittest.mock import patch |
| 12 | +from unittest.mock import Mock, patch |
13 | 13 |
|
14 | 14 | import pytest |
15 | 15 |
|
|
24 | 24 | Head, |
25 | 25 | Reference, |
26 | 26 | RefLog, |
| 27 | + Remote, |
| 28 | + RemoteProgress, |
27 | 29 | RemoteReference, |
28 | 30 | SymbolicReference, |
29 | 31 | TagReference, |
|
37 | 39 | from test.lib.fixtures import fixture_repo, read_only_fixture, writable_fixture |
38 | 40 |
|
39 | 41 |
|
| 42 | +@pytest.mark.parametrize("object_format", ["sha1", "sha256"]) |
| 43 | +def test_reference_names_preserve_unicode_line_separators(object_format): |
| 44 | + names = [ |
| 45 | + before + separator + after |
| 46 | + for separator in ("\x85", "\u2028", "\u2029") |
| 47 | + for before, after in (("", "after"), ("before", "after"), ("before", "")) |
| 48 | + ] |
| 49 | + with fixture_repo("ref-line-separators.sh", object_format) as repo: |
| 50 | + expected = { |
| 51 | + f"{prefix}/{name}" for prefix in ("refs/heads", "refs/tags", "refs/remotes/origin") for name in names |
| 52 | + } | {"refs/heads/main"} |
| 53 | + assert set(repo.git.for_each_ref("--format=%(refname)").split("\n")) == expected |
| 54 | + assert {ref.path for ref in repo.references} == expected |
| 55 | + assert {head.name for head in repo.heads} == set(names) | {"main"} |
| 56 | + assert {tag.name for tag in repo.tags} == set(names) |
| 57 | + assert {ref.remote_head for ref in RemoteReference.iter_items(repo, remote="origin")} == set(names) |
| 58 | + for ref in repo.references: |
| 59 | + assert ref.commit == repo.head.commit |
| 60 | + |
| 61 | + |
| 62 | +@pytest.mark.parametrize("separator", ["\x85", "\u2028", "\u2029"]) |
| 63 | +@pytest.mark.parametrize("before,after", [("", "after"), ("before", "after"), ("before", "")]) |
| 64 | +@pytest.mark.parametrize("as_bytes", [False, True]) |
| 65 | +def test_fetch_resolves_unicode_line_separator_names_from_inventory(separator, before, after, as_bytes): |
| 66 | + name = before + separator + after |
| 67 | + with fixture_repo("ref-line-separators.sh", "sha1") as repo: |
| 68 | + progress = RemoteProgress() |
| 69 | + line = f" * [new branch] {name} -> origin/{name}" |
| 70 | + progress.new_message_handler()((line + "\n").encode() if as_bytes else line + "\n") |
| 71 | + assert progress.other_lines == [line] |
| 72 | + with patch("git.remote.handle_process_output"): |
| 73 | + result = Remote(repo, "inventory")._get_fetch_info_from_stderr(Mock(), progress) |
| 74 | + assert len(result) == 1 |
| 75 | + assert result[0].ref.path == f"refs/remotes/origin/{name}" |
| 76 | + assert result[0].remote_ref_path == name |
| 77 | + |
| 78 | + |
| 79 | +def test_remote_urls_preserve_unicode_line_separators(): |
| 80 | + with fixture_repo("ref-line-separators.sh", "sha1") as repo: |
| 81 | + assert list(repo.remote("unicode").urls) == [ |
| 82 | + f"https://example.invalid/before{separator}after" for separator in ("\x85", "\u2028", "\u2029") |
| 83 | + ] |
| 84 | + with patch.object(Git, "_call_process_safe", return_value=""): |
| 85 | + assert list(Remote(repo, "empty").urls) == [] |
| 86 | + |
| 87 | + |
| 88 | +def test_stale_refs_preserve_unicode_line_separators(): |
| 89 | + with fixture_repo("ref-line-separators.sh", "sha1") as repo: |
| 90 | + origin = repo.remote("origin") |
| 91 | + assert {ref.path for ref in origin.stale_refs} == {ref.path for ref in origin.refs} |
| 92 | + |
| 93 | + |
40 | 94 | @pytest.mark.parametrize("object_format", ["sha1", "sha256"]) |
41 | 95 | def test_non_utf8_tag_names_preserve_bytes(object_format): |
42 | 96 | with fixture_repo("legacy-refs.sh", object_format) as repo: |
|
0 commit comments