[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/QuantStack/git2cpp/main/test/test_log.py [Back]  [Original]

import re
import subprocess

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):
    cmd_init = [git2cpp_path, "init", "."]
    p_init = subprocess.run(cmd_init, capture_output=True, cwd=tmp_path)
    assert p_init.returncode == 0

    p = tmp_path / "mook_file.txt"
    p.write_text("")

    cmd_add = [git2cpp_path, "add", "mook_file.txt"]
    p_add = subprocess.run(cmd_add, cwd=tmp_path, text=True)
    assert p_add.returncode == 0

    cmd_commit = [git2cpp_path, "commit", "-m", "test commit"]
    p_commit = subprocess.run(cmd_commit, cwd=tmp_path, text=True)
    assert p_commit.returncode == 0

    cmd_log = [git2cpp_path, "log"]
    if format_flag != "":
        cmd_log.append(format_flag)
    p_log = subprocess.run(cmd_log, capture_output=True, cwd=tmp_path, text=True)
    assert p_log.returncode == 0
    assert "Jane Doe" in p_log.stdout
    assert "test commit" in p_log.stdout

    if format_flag == "":
        assert "Commit" not in p_log.stdout
    else:
        assert "Commit" in p_log.stdout
        if format_flag == "--format=full":
            assert "Date" not in p_log.stdout
        else:
            assert "CommitDate" in p_log.stdout


def test_log_nogit(commit_env_config, git2cpp_path, tmp_path):
    cmd_log = [git2cpp_path, "log"]
    p_log = subprocess.run(cmd_log, capture_output=True, cwd=tmp_path, text=True)
    assert p_log.returncode != 0
    assert "error: could not find repository at" in p_log.stderr


@pytest.mark.parametrize("max_count_flag", ["", "-n", "--max-count"])
def test_max_count(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path, max_count_flag
):
    assert (tmp_path / "initial.txt").exists()

    p2 = tmp_path / "second.txt"
    p2.write_text("second file")

    cmd_add2 = [git2cpp_path, "add", "second.txt"]
    subprocess.run(cmd_add2, capture_output=True, cwd=tmp_path, text=True, check=True)

    cmd_commit2 = [git2cpp_path, "commit", "-m", "Second commit"]
    subprocess.run(cmd_commit2, capture_output=True, cwd=tmp_path, text=True, check=True)

    p3 = tmp_path / "third.txt"
    p3.write_text("third file")

    cmd_add3 = [git2cpp_path, "add", "third.txt"]
    subprocess.run(cmd_add3, capture_output=True, cwd=tmp_path, text=True, check=True)

    cmd_commit3 = [git2cpp_path, "commit", "-m", "Third commit"]
    subprocess.run(cmd_commit3, capture_output=True, cwd=tmp_path, text=True, check=True)

    cmd_log = [git2cpp_path, "log"]
    if max_count_flag != "":
        cmd_log.append(max_count_flag)
        cmd_log.append("2")
    p_log = subprocess.run(cmd_log, capture_output=True, cwd=tmp_path, text=True)
    assert p_log.returncode == 0

    if max_count_flag == "":
        assert p_log.stdout.count("Author") > 2
    else:
        assert p_log.stdout.count("Author") == 2


def test_log_with_head_reference(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    """Test that HEAD reference is shown on the latest commit."""
    assert (tmp_path / "initial.txt").exists()

    # Create a new commit
    p = tmp_path / "test_file.txt"
    p.write_text("test content")

    subprocess.run([git2cpp_path, "add", "test_file.txt"], cwd=tmp_path, check=True)
    subprocess.run([git2cpp_path, "commit", "-m", "test commit"], cwd=tmp_path, check=True)

    # Run log with max count 1 to get only the latest commit
    p_log = subprocess.run(
        [git2cpp_path, "log", "-n", "1"], capture_output=True, cwd=tmp_path, text=True
    )
    assert p_log.returncode == 0

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


def test_log_with_tag(commit_env_config, git2cpp_path, tmp_path):
    """Test that tags are shown in log output."""
    cmd_init = [git2cpp_path, "init", "."]
    p_init = subprocess.run(cmd_init, capture_output=True, cwd=tmp_path)
    assert p_init.returncode == 0

    # Create a commit and tag it
    p = tmp_path / "tagged_file.txt"
    p.write_text("tagged content")

    subprocess.run([git2cpp_path, "add", "tagged_file.txt"], cwd=tmp_path, check=True)
    subprocess.run([git2cpp_path, "commit", "-m", "tagged commit"], cwd=tmp_path, check=True)

    # Create a tag (using git command since git2cpp might not have tag creation yet)
    subprocess.run([git2cpp_path, "tag", "v1.0.0"], cwd=tmp_path, check=True)

    # Run log
    p_log = subprocess.run(
        [git2cpp_path, "log", "-n", "1"], capture_output=True, cwd=tmp_path, text=True
    )
    assert p_log.returncode == 0

    # Check that tag is shown
    assert "tag: v1.0.0" in p_log.stdout


def test_log_with_multiple_tags(commit_env_config, git2cpp_path, tmp_path):
    """Test that multiple tags on the same commit are all shown."""
    cmd_init = [git2cpp_path, "init", "."]
    p_init = subprocess.run(cmd_init, capture_output=True, cwd=tmp_path)
    assert p_init.returncode == 0

    # Create a commit
    p = tmp_path / "multi_tag_file.txt"
    p.write_text("content")

    subprocess.run([git2cpp_path, "add", "multi_tag_file.txt"], cwd=tmp_path, check=True)
    subprocess.run([git2cpp_path, "commit", "-m", "multi tag commit"], cwd=tmp_path, check=True)

    # Create multiple tags
    subprocess.run([git2cpp_path, "tag", "v1.0.0"], cwd=tmp_path, check=True)
    subprocess.run([git2cpp_path, "tag", "stable"], cwd=tmp_path, check=True)
    subprocess.run([git2cpp_path, "tag", "latest"], cwd=tmp_path, check=True)

    # Run log
    p_log = subprocess.run(
        [git2cpp_path, "log", "-n", "1"], capture_output=True, cwd=tmp_path, text=True
    )
    assert p_log.returncode == 0

    # Check that all tags are shown
    assert "tag: v1.0.0" in p_log.stdout
    assert "tag: stable" in p_log.stdout
    assert "tag: latest" in p_log.stdout


def test_log_with_annotated_tag(commit_env_config, git2cpp_path, tmp_path):
    """Test that annotated tags are shown in log output."""
    cmd_init = [git2cpp_path, "init", "."]
    p_init = subprocess.run(cmd_init, capture_output=True, cwd=tmp_path)
    assert p_init.returncode == 0

    # Create a commit
    p = tmp_path / "annotated_tag_file.txt"
    p.write_text("content")

    subprocess.run([git2cpp_path, "add", "annotated_tag_file.txt"], cwd=tmp_path, check=True)
    subprocess.run([git2cpp_path, "commit", "-m", "annotated tag commit"], cwd=tmp_path, check=True)

    # Create an annotated tag
    subprocess.run(
        [git2cpp_path, "tag", "-a", "v2.0.0", "-m", "Version 2.0.0"],
        cwd=tmp_path,
        check=True,
    )

    # Run log
    p_log = subprocess.run(
        [git2cpp_path, "log", "-n", "1"], capture_output=True, cwd=tmp_path, text=True
    )
    assert p_log.returncode == 0

    # Check that annotated tag is shown
    assert "tag: v2.0.0" in p_log.stdout


def test_log_with_branch(commit_env_config, git2cpp_path, tmp_path):
    """Test that branches are shown in log output."""
    cmd_init = [git2cpp_path, "init", "."]
    p_init = subprocess.run(cmd_init, capture_output=True, cwd=tmp_path)
    assert p_init.returncode == 0

    # Create a commit
    p = tmp_path / "branch_file.txt"
    p.write_text("content")

    subprocess.run([git2cpp_path, "add", "branch_file.txt"], cwd=tmp_path, check=True)
    subprocess.run([git2cpp_path, "commit", "-m", "branch commit"], cwd=tmp_path, check=True)

    # Create a new branch pointing to HEAD
    subprocess.run([git2cpp_path, "branch", "feature-branch"], cwd=tmp_path, check=True)

    # Run log
    p_log = subprocess.run(
        [git2cpp_path, "log", "-n", "1"], capture_output=True, cwd=tmp_path, text=True
    )
    assert p_log.returncode == 0

    # Check that both branches are shown (HEAD -> master/main and feature-branch)
    assert "feature-branch" in p_log.stdout


def test_log_with_remote_branches(xtl_clone, commit_env_config, git2cpp_path, tmp_path):
    """Test that remote branches are shown in log output."""
    assert (tmp_path / "xtl").exists()
    xtl_path = tmp_path / "xtl"

    # The xtl_clone fixture already has remote branches (origin/master, etc.)
    # Run log to check they appear
    p_log = subprocess.run(
        [git2cpp_path, "log", "-n", "1"], capture_output=True, cwd=xtl_path, text=True
    )
    assert p_log.returncode == 0

    # Check that origin remote branches are shown
    assert "origin/master" in p_log.stdout


def test_log_commit_without_references(commit_env_config, git2cpp_path, tmp_path):
    """Test that commits without any references don't show empty parentheses."""
    cmd_init = [git2cpp_path, "init", "."]
    p_init = subprocess.run(cmd_init, capture_output=True, cwd=tmp_path)
    assert p_init.returncode == 0

    # Create two commits - the second one will have refs, the first won't
    for i in range(2):
        p = tmp_path / f"file_{i}.txt"
        p.write_text(f"content {i}")
        subprocess.run([git2cpp_path, "add", f"file_{i}.txt"], cwd=tmp_path, check=True)
        subprocess.run([git2cpp_path, "commit", "-m", f"commit {i}"], cwd=tmp_path, check=True)

    # Run log with 2 commits
    p_log = subprocess.run(
        [git2cpp_path, "log", "-n", "2"], capture_output=True, cwd=tmp_path, text=True
    )
    assert p_log.returncode == 0

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

    # Second commit (older one) should not have empty parentheses
    second_commit_line = [line for line in lines if line.startswith("commit")][1]
    # Should either have no parentheses or have actual references
    if "(" in second_commit_line:
        # If it has parentheses, they shouldn't be empty
        assert "()" not in second_commit_line


@pytest.mark.parametrize("abbrev_commit_flag", ["", "--abbrev-commit", "--no-abbrev-commit"])
@pytest.mark.parametrize("abbrev_flag", ["", "--abbrev=10"])
def test_log_abbrev_commit_flags(
    repo_init_with_commit,
    commit_env_config,
    git2cpp_path,
    tmp_path,
    abbrev_commit_flag,
    abbrev_flag,
):
    """Test for --abbrev-commit, --abbrev= (only applies when --abbrev-commit is set) and --no-abbrev-commit"""
    assert (tmp_path / "initial.txt").exists()

    cmd = [git2cpp_path, "log", "-n", "1"]
    if abbrev_commit_flag != "":
        cmd.append(abbrev_commit_flag)
    if abbrev_flag != "":
        cmd.append(abbrev_flag)
    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]+)", strip_ansi_colours(p.stdout), flags=re.MULTILINE)
    if abbrev_commit_flag in ["", "--no-abbrev-commit"]:
        assert len(m.group(1)) == 40
    else:
        if abbrev_flag == "--abbrev=10":
            assert len(m.group(1)) == 10
        else:
            assert len(m.group(1)) == 7


def test_log_format_oneline(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test --format=oneline prints the full sha"""
    assert (tmp_path / "initial.txt").exists()

    p = subprocess.run(
        [git2cpp_path, "rev-parse", "HEAD"],
        cwd=tmp_path,
        capture_output=True,
        text=True,
    )
    assert p.returncode == 0
    full_sha = p.stdout.strip()

    p = subprocess.run(
        [git2cpp_path, "log", "--format=oneline", "-n", "1"],
        cwd=tmp_path,
        capture_output=True,
        text=True,
    )
    assert p.returncode == 0

    # assert: should contain full 40-hex sha and subject
    assert full_sha in p.stdout
    assert "Initial commit" in p.stdout


def test_log_oneline(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test --oneline prints the default length sha (i.e 7)"""
    assert (tmp_path / "initial.txt").exists()

    p = subprocess.run(
        [git2cpp_path, "rev-parse", "HEAD"],
        cwd=tmp_path,
        capture_output=True,
        text=True,
    )
    assert p.returncode == 0
    full_sha = str(p.stdout.strip())
    abbrev7 = full_sha[:7]

    subprocess.run([git2cpp_path, "tag", "v1"], capture_output=True, cwd=tmp_path, check=True)

    p = subprocess.run(
        [git2cpp_path, "log", "--oneline", "-n", "1"],
        cwd=tmp_path,
        capture_output=True,
        text=True,
    )
    assert p.returncode == 0

    assert abbrev7 in p.stdout
    assert full_sha not in p.stdout
    assert "tag: v1" in p.stdout
    assert "Initial commit" in p.stdout


def test_log_oneline_no_abbrev_commit(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test --oneline prints prints the full sha when using --no-abbrev-commit"""
    assert (tmp_path / "initial.txt").exists()

    p = subprocess.run(
        [git2cpp_path, "rev-parse", "HEAD"],
        cwd=tmp_path,
        capture_output=True,
        text=True,
    )
    assert p.returncode == 0
    full_sha = str(p.stdout.strip())

    p = subprocess.run(
        [git2cpp_path, "log", "--oneline", "--no-abbrev-commit", "-n", "1"],
        cwd=tmp_path,
        capture_output=True,
        text=True,
    )
    assert p.returncode == 0

    assert full_sha in p.stdout
    assert "Initial commit" in p.stdout

Web Proxy Viewer  |  New URL  |  Original Page