Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import re
import subprocess
from pathlib import Path

Expand Down Expand Up @@ -73,6 +74,10 @@ def private_test_repo():
# Fixture containing everything needed to access private github repo.
# GIT2CPP_TEST_PRIVATE_TOKEN is the fine-grained Personal Access Token for private test repo.
# If this is not available as an environment variable, tests that use this fixture are skipped.

if GIT2CPP_TEST_WASM:
pytest.skip("Use of credentials in wasm not yet implemented")

token = os.getenv("GIT2CPP_TEST_PRIVATE_TOKEN")
if token is None or len(token) == 0:
pytest.skip("No token for private test repo GIT2CPP_TEST_PRIVATE_TOKEN")
Expand All @@ -84,3 +89,11 @@ def private_test_repo():
"https_url": f"https://github.com/{org_name}/{repo_name}",
"token": token,
}


# Functions not fixtures below here.


def strip_ansi_colours(text):
# Strip ansi colour code sequences from a string.
return re.sub(r"\x1b\[[^m]*m", "", text)
58 changes: 44 additions & 14 deletions test/conftest_wasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ def pytest_ignore_collect(collection_path: pathlib.Path) -> bool:
"test_clone.py",
"test_commit.py",
"test_config.py",
"test_diff.py",
"test_fetch.py",
"test_fixtures.py",
"test_git.py",
"test_init.py",
"test_log.py",
"test_merge.py",
"test_mv.py",
"test_push.py",
"test_rebase.py",
"test_remote.py",
"test_reset.py",
Expand All @@ -33,6 +36,7 @@ def pytest_ignore_collect(collection_path: pathlib.Path) -> bool:
"test_rm.py",
"test_stash.py",
"test_status.py",
"test_tag.py",
]


Expand All @@ -54,18 +58,6 @@ def load_page(page: Page):
page.locator("#loaded").wait_for()


def os_chdir(dir: str):
subprocess.run(["cd", str(dir)], capture_output=True, check=True, text=True)


def os_getcwd():
return subprocess.run(["pwd"], capture_output=True, check=True, text=True).stdout.strip()


def os_remove(file: str):
return subprocess.run(["rm", str(file)], capture_output=True, check=True, text=True)


class MockPath(pathlib.Path):
def __init__(self, path: str = ""):
super().__init__(path)
Expand Down Expand Up @@ -95,26 +87,62 @@ def mkdir(self, *, parents=False):
args.append("-p")
subprocess.run(["mkdir"] + args, capture_output=True, text=True, check=True)

def read_bytes(self) -> bytes:
raise RuntimeError("Not implemented")

def read_text(self) -> str:
p = subprocess.run(["cat", str(self)], capture_output=True, text=True, check=True)
text = p.stdout
if text.endswith("\n"):
text = text[:-1]
return text

def write_bytes(self, data: bytes):
# Convert binary data to a string where each element is backslash-escaped so that we can
# write to file in cockle using `echo -e <backslash-escaped data>`.
encoded_string = "".join(map(lambda d: f"\\x{d:02x}", data))
cmd = ["echo", "-e", encoded_string, ">", str(self)]
subprocess.run(cmd, capture_output=True, text=True, check=True)
return len(data)

def write_text(self, data: str):
# Note that in general it is not valid to direct output of a subprocess.run call to a file,
# but we get away with it here as the command arguments are passed straight through to
# cockle without being checked.
p = subprocess.run(["echo", data, ">", str(self)], capture_output=True, text=True)
assert p.returncode == 0
if data.endswith("\n"):
data = data[:-1]
cmd = ["echo", data, ">", str(self)]
subprocess.run(cmd, capture_output=True, text=True, check=True)
return len(data)

def __truediv__(self, other):
if isinstance(other, str):
return MockPath(f"{self}/{other}")
raise RuntimeError("MockPath.__truediv__ only supports strings")


def os_chdir(dir: str):
subprocess.run(["cd", str(dir)], capture_output=True, check=True, text=True)


def os_getcwd():
return subprocess.run(["pwd"], capture_output=True, check=True, text=True).stdout.strip()


def os_remove(file: str):
return subprocess.run(["rm", str(file)], capture_output=True, check=True, text=True)


def os_rename(src: str | MockPath, dst: str | MockPath):
return subprocess.run(["mv", str(src), str(dst)], capture_output=True, check=True, text=True)


def os_symlink(src: str | MockPath, dst: str | MockPath):
return subprocess.run(
["ln", "-s", str(src), str(dst)], capture_output=True, check=True, text=True
)


def subprocess_run(
page: Page,
cmd: list[str],
Expand Down Expand Up @@ -192,3 +220,5 @@ def mock_subprocess_run(page: Page, monkeypatch):
monkeypatch.setattr(os, "chdir", os_chdir)
monkeypatch.setattr(os, "getcwd", os_getcwd)
monkeypatch.setattr(os, "remove", os_remove)
monkeypatch.setattr(os, "rename", os_rename)
monkeypatch.setattr(os, "symlink", os_symlink)
3 changes: 3 additions & 0 deletions test/test_checkout.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import pytest

from .conftest import strip_ansi_colours


def test_checkout(repo_init_with_commit, git2cpp_path, tmp_path):
assert (tmp_path / "initial.txt").exists()
Expand Down Expand Up @@ -103,6 +105,7 @@ def test_checkout_with_unstaged_changes(repo_init_with_commit, git2cpp_path, tmp

# Should succeed and show status
assert p_checkout.returncode == 0
p_checkout.stdout = strip_ansi_colours(p_checkout.stdout)
assert " M initial.txt" in p_checkout.stdout
assert "Switched to branch 'newbranch'" in p_checkout.stdout

Expand Down
10 changes: 8 additions & 2 deletions test/test_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import pytest

from .conftest import strip_ansi_colours


def test_diff_nogit(git2cpp_path, tmp_path):
cmd = [git2cpp_path, "diff"]
Expand Down Expand Up @@ -84,6 +86,8 @@ def test_diff_stat(repo_init_with_commit, git2cpp_path, tmp_path):
cmd = [git2cpp_path, "diff", "--stat"]
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
assert p.returncode == 0

p.stdout = strip_ansi_colours(p.stdout)
assert "initial.txt" in p.stdout
assert "1 file changed, 1 insertion(+)" in p.stdout
assert "Modified content" not in p.stdout
Expand Down Expand Up @@ -132,6 +136,7 @@ def test_diff_summary(repo_init_with_commit, git2cpp_path, tmp_path):
cmd = [git2cpp_path, "diff", "--cached", "--summary"]
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
assert p.returncode == 0
p.stdout = strip_ansi_colours(p.stdout)
assert "newfile.txt" in p.stdout
assert "+" not in p.stdout

Expand All @@ -146,6 +151,7 @@ def test_diff_name_only(repo_init_with_commit, git2cpp_path, tmp_path):
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)

assert p.returncode == 0
p.stdout = strip_ansi_colours(p.stdout)
assert p.stdout == "initial.txt\n"
assert "+" not in p.stdout

Expand All @@ -159,6 +165,7 @@ def test_diff_name_status(repo_init_with_commit, git2cpp_path, tmp_path):
cmd = [git2cpp_path, "diff", "--name-status"]
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
assert p.returncode == 0
p.stdout = strip_ansi_colours(p.stdout)
assert p.stdout == "M\tinitial.txt\n"


Expand All @@ -172,6 +179,7 @@ def test_diff_raw(repo_init_with_commit, git2cpp_path, tmp_path):
cmd = [git2cpp_path, "diff", "--raw"]
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
assert p.returncode == 0
p.stdout = strip_ansi_colours(p.stdout)
assert "M\tinitial.txt" in p.stdout
assert bool(re.search(":[0-9]*", p.stdout))

Expand Down Expand Up @@ -635,7 +643,6 @@ def test_diff_find_copies_harder(
[git2cpp_path, "commit", "-m", "add original file"],
cwd=tmp_path,
check=True,
env=commit_env_config,
)

# Create identical copy
Expand Down Expand Up @@ -669,7 +676,6 @@ def test_diff_find_copies_with_threshold(
[git2cpp_path, "commit", "-m", "add original file"],
cwd=tmp_path,
check=True,
env=commit_env_config,
)

# Create a partial copy (60% similar)
Expand Down
8 changes: 5 additions & 3 deletions test/test_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import pytest

from .conftest import strip_ansi_colours


@pytest.mark.parametrize("format_flag", ["", "--format=full", "--format=fuller"])
def test_log(commit_env_config, git2cpp_path, tmp_path, format_flag):
Expand Down Expand Up @@ -101,7 +103,7 @@ def test_log_with_head_reference(repo_init_with_commit, commit_env_config, git2c
assert p_log.returncode == 0

# Check that HEAD reference is shown
assert "HEAD ->" in p_log.stdout
assert "HEAD ->" in strip_ansi_colours(p_log.stdout)
assert "master" in p_log.stdout or "main" in p_log.stdout


Expand Down Expand Up @@ -253,7 +255,7 @@ def test_log_commit_without_references(commit_env_config, git2cpp_path, tmp_path
assert p_log.returncode == 0

# First commit line should have references
lines = p_log.stdout.split("\n")
lines = strip_ansi_colours(p_log.stdout).split("\n")
first_commit_line = [line for line in lines if line.startswith("commit")][0]
assert "(" in first_commit_line # Has references

Expand Down Expand Up @@ -286,7 +288,7 @@ def test_log_abbrev_commit_flags(
p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
assert p.returncode == 0

m = re.search(r"^commit\s+([0-9a-fA-F]+)", p.stdout, flags=re.MULTILINE)
m = re.search(r"^commit\s+([0-9a-fA-F]+)", strip_ansi_colours(p.stdout), flags=re.MULTILINE)
if abbrev_commit_flag in ["", "--no-abbrev-commit"]:
assert len(m.group(1)) == 40
else:
Expand Down
4 changes: 4 additions & 0 deletions test/test_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import pytest

from .conftest import strip_ansi_colours


@pytest.mark.parametrize("short_flag", ["", "-s", "--short"])
@pytest.mark.parametrize("long_flag", ["", "--long"])
Expand Down Expand Up @@ -185,6 +187,8 @@ def test_status_mixed_changes(repo_init_with_commit, git2cpp_path, tmp_path, sho
p = subprocess.run(cmd_status, capture_output=True, cwd=tmp_path, text=True)

assert p.returncode == 0

p.stdout = strip_ansi_colours(p.stdout)
if short_flag == "-s":
assert "A staged.txt" in p.stdout
assert "D to_delete.txt" in p.stdout
Expand Down
5 changes: 5 additions & 0 deletions test/test_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import pytest

from .conftest import GIT2CPP_TEST_WASM


def test_tag_list_empty(repo_init_with_commit, git2cpp_path, tmp_path):
"""Test listing tags when there are no tags."""
Expand Down Expand Up @@ -235,6 +237,9 @@ def test_tag_annotated_no_message(repo_init_with_commit, commit_env_config, git2
commit_cmd = [git2cpp_path, "commit", "-m", "my specific commit message"]
subprocess.run(commit_cmd, cwd=tmp_path, check=True)

if GIT2CPP_TEST_WASM:
pytest.skip("Not possible to pass empty argument to wasm")

# Create tag with empty message (should create lightweight tag)
create_cmd = [git2cpp_path, "tag", "-m", "", "v1.0.0"]
subprocess.run(create_cmd, capture_output=True, cwd=tmp_path, check=True)
Expand Down
Loading