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

import subprocess

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."""
    assert (tmp_path / "initial.txt").exists()

    cmd = [git2cpp_path, "tag"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert p.stdout == ""


def test_tag_create_lightweight(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    """Test creating a lightweight tag."""
    assert (tmp_path / "initial.txt").exists()

    # Create a lightweight tag
    create_cmd = [git2cpp_path, "tag", "v1.0.0"]
    subprocess.run(create_cmd, capture_output=True, cwd=tmp_path, text=True, check=True)

    # List tags to verify it was created
    list_cmd = [git2cpp_path, "tag"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "v1.0.0" in p_list.stdout


def test_tag_create_annotated(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    """Test creating an annotated tag."""
    assert (tmp_path / "initial.txt").exists()

    # Create an annotated tag
    create_cmd = [git2cpp_path, "tag", "-m", "Release version 1.0", "v1.0.0"]
    subprocess.run(create_cmd, capture_output=True, cwd=tmp_path, text=True, check=True)

    # List tags to verify it was created
    list_cmd = [git2cpp_path, "tag", "-n", "1"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "v1.0.0" in p_list.stdout
    assert "Release version 1.0" in p_list.stdout


def test_tag_create_on_specific_commit(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path
):
    """Test creating a tag on a specific commit."""
    assert (tmp_path / "initial.txt").exists()

    # Get the commit SHA before creating new commit
    old_head_cmd = [git2cpp_path, "rev-parse", "HEAD"]
    p_old_head = subprocess.run(old_head_cmd, capture_output=True, cwd=tmp_path, text=True)
    old_head_sha = p_old_head.stdout.strip()

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

    add_cmd = [git2cpp_path, "add", "test_file.txt"]
    subprocess.run(add_cmd, cwd=tmp_path, check=True)

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

    # Get new HEAD commit SHA
    new_head_cmd = [git2cpp_path, "rev-parse", "HEAD"]
    p_new_head = subprocess.run(new_head_cmd, capture_output=True, cwd=tmp_path, text=True)
    new_head_sha = p_new_head.stdout.strip()

    # Verify we actually created a new commit
    assert old_head_sha != new_head_sha

    # Create tag on HEAD
    tag_cmd = [git2cpp_path, "tag", "v1.0.0", "HEAD"]
    subprocess.run(tag_cmd, capture_output=True, cwd=tmp_path, check=True)

    # Verify tag exists
    list_cmd = [git2cpp_path, "tag"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "v1.0.0" in p_list.stdout

    # Get commit SHA that the tag points to
    tag_sha_cmd = [git2cpp_path, "rev-parse", "v1.0.0^{commit}"]
    p_tag_sha = subprocess.run(tag_sha_cmd, capture_output=True, cwd=tmp_path, text=True)
    tag_sha = p_tag_sha.stdout.strip()

    # Verify tag points to new HEAD, not old HEAD
    assert tag_sha == new_head_sha
    assert tag_sha != old_head_sha


def test_tag_delete(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    """Test deleting a tag."""
    assert (tmp_path / "initial.txt").exists()

    # Create a tag
    create_cmd = [git2cpp_path, "tag", "v1.0.0"]
    subprocess.run(create_cmd, capture_output=True, cwd=tmp_path, text=True, check=True)

    # Delete the tag
    delete_cmd = [git2cpp_path, "tag", "-d", "v1.0.0"]
    p_delete = subprocess.run(delete_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_delete.returncode == 0
    assert "Deleted tag 'v1.0.0'" in p_delete.stdout

    # Verify tag is gone
    list_cmd = [git2cpp_path, "tag"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "v1.0.0" not in p_list.stdout


def test_tag_delete_nonexistent(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test deleting a tag that doesn't exist."""
    assert (tmp_path / "initial.txt").exists()

    # Try to delete non-existent tag
    delete_cmd = [git2cpp_path, "tag", "-d", "nonexistent"]
    p_delete = subprocess.run(delete_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_delete.returncode != 0
    assert "not found" in p_delete.stderr


@pytest.mark.parametrize("list_flag", ["", "-l", "--list"])
def test_tag_list(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path, list_flag):
    """Test listing tags with -l or --list flag."""
    assert (tmp_path / "initial.txt").exists()

    # Create a tag
    tag_cmd = [git2cpp_path, "tag", "v1.0.0"]
    subprocess.run(tag_cmd, capture_output=True, cwd=tmp_path, text=True)

    # List tags
    list_cmd = [git2cpp_path, "tag", list_flag]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "v1.0.0" in p_list.stdout


def test_tag_list_with_pattern(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    """Test listing tags with a pattern."""
    assert (tmp_path / "initial.txt").exists()

    # Create tags with different prefixes
    tag_cmd_1 = [git2cpp_path, "tag", "v1.0.0"]
    subprocess.run(tag_cmd_1, capture_output=True, cwd=tmp_path, text=True)

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

    tag_cmd_3 = [git2cpp_path, "tag", "release-1.0"]
    subprocess.run(tag_cmd_3, capture_output=True, cwd=tmp_path, text=True)

    # List only tags matching pattern
    list_cmd = [git2cpp_path, "tag", "-l", "v1.0*"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "v1.0.0" in p_list.stdout
    assert "v1.0.1" in p_list.stdout
    assert "release-1.0" not in p_list.stdout


def test_tag_list_with_message_lines(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path
):
    """Test listing tags with message lines (-n flag)."""
    assert (tmp_path / "initial.txt").exists()

    # Create an annotated tag with a message
    create_cmd = [
        git2cpp_path,
        "tag",
        "-m",
        "First line\nSecond line\nThird line\nForth line",
        "v1.0.0",
    ]
    p_create = subprocess.run(create_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_create.returncode == 0

    # List tags with message lines
    list_cmd = [git2cpp_path, "tag", "-n", "3", "-l"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "v1.0.0" in p_list.stdout
    assert "First line" in p_list.stdout
    assert "Second line" in p_list.stdout
    assert "Third line" in p_list.stdout
    assert "Forth line" not in p_list.stdout


@pytest.mark.parametrize("force_flag", ["-f", "--force"])
def test_tag_force_replace(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path, force_flag
):
    """Test replacing an existing tag with -f or --force flag."""
    assert (tmp_path / "initial.txt").exists()

    # Create initial tag
    create_cmd_1 = [git2cpp_path, "tag", "v1.0.0"]
    subprocess.run(create_cmd_1, capture_output=True, cwd=tmp_path, text=True, check=True)

    # Try to create same tag without force (should fail)
    create_cmd_2 = [git2cpp_path, "tag", "v1.0.0"]
    p_create_2 = subprocess.run(create_cmd_2, capture_output=True, cwd=tmp_path)
    assert p_create_2.returncode != 0

    # Create same tag with force (should succeed)
    create_cmd_3 = [git2cpp_path, "tag", force_flag, "v1.0.0"]
    p_create_3 = subprocess.run(create_cmd_3, capture_output=True, cwd=tmp_path, text=True)
    assert p_create_3.returncode == 0


def test_tag_nogit(git2cpp_path, tmp_path):
    """Test tag command outside a git repository."""
    cmd = [git2cpp_path, "tag"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode != 0


def test_tag_annotated_no_message(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    """Test creating an annotated tag without a message should fail."""
    assert (tmp_path / "initial.txt").exists()

    # Create a commit with a known message
    file_path = tmp_path / "test_file.txt"
    file_path.write_text("test content")

    add_cmd = [git2cpp_path, "add", "test_file.txt"]
    subprocess.run(add_cmd, cwd=tmp_path, check=True)

    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)

    # List tag with messages - lightweight tag shows commit message
    list_cmd = [git2cpp_path, "tag", "-n", "1"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "v1.0.0" in p_list.stdout
    # Lightweight tag shows the commit message, not a tag message
    assert "my specific commit message" in p_list.stdout


def test_tag_multiple_create_and_list(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path
):
    """Test creating multiple tags and listing them."""
    assert (tmp_path / "initial.txt").exists()

    # Create multiple tags
    tags = ["v1.0.0", "v1.0.1", "v1.1.0", "v2.0.0"]
    for tag in tags:
        create_cmd = [git2cpp_path, "tag", tag]
        subprocess.run(create_cmd, capture_output=True, cwd=tmp_path, check=True)

    # List all tags
    list_cmd = [git2cpp_path, "tag"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0

    # Verify all tags are in the list
    for tag in tags:
        assert tag in p_list.stdout


def test_tag_on_new_commit(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    """Test creating tags on new commits."""
    assert (tmp_path / "initial.txt").exists()

    # Tag the current commit
    tag_cmd_1 = [git2cpp_path, "tag", "before-change"]
    subprocess.run(tag_cmd_1, cwd=tmp_path, check=True)

    # Make a new commit
    file_path = tmp_path / "new_file.txt"
    file_path.write_text("new content")

    add_cmd = [git2cpp_path, "add", "new_file.txt"]
    subprocess.run(add_cmd, cwd=tmp_path, check=True)

    commit_cmd = [git2cpp_path, "commit", "-m", "new commit"]
    subprocess.run(commit_cmd, cwd=tmp_path, check=True)

    # Tag the new commit
    tag_cmd_2 = [git2cpp_path, "tag", "after-change"]
    subprocess.run(tag_cmd_2, cwd=tmp_path, check=True)

    # List tags
    list_cmd = [git2cpp_path, "tag"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "before-change" in p_list.stdout
    assert "after-change" in p_list.stdout


def test_tag_create_annotated_with_a_flag(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path
):
    """Test creating an annotated tag using -a flag."""
    assert (tmp_path / "initial.txt").exists()

    # Create an annotated tag using -a and -m
    create_cmd = [git2cpp_path, "tag", "-a", "-m", "Release version 1.0", "v1.0.0"]
    subprocess.run(create_cmd, capture_output=True, cwd=tmp_path, text=True, check=True)

    # List tags with message lines to verify it was created as an annotated tag
    list_cmd = [git2cpp_path, "tag", "-n", "1"]
    p_list = subprocess.run(list_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_list.returncode == 0
    assert "v1.0.0" in p_list.stdout
    assert "Release version 1.0" in p_list.stdout


def test_tag_annotate_flag_requires_message(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path
):
    """Test that -a/--annotate without -m fails."""
    assert (tmp_path / "initial.txt").exists()

    create_cmd = [git2cpp_path, "tag", "-a", "v1.0.0"]
    p = subprocess.run(create_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode != 0
    assert "requires -m" in p.stderr


def test_tag_errors(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    assert (tmp_path / "initial.txt").exists()

    # Test that -a/--annotate without -m fails.
    create_cmd = [git2cpp_path, "tag", "-a", "v1.0.0"]
    p_create = subprocess.run(create_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_create.returncode != 0
    assert "requires -m" in p_create.stderr

    # Test that command fails when no message
    del_cmd = [git2cpp_path, "tag", "-d"]
    p_del = subprocess.run(del_cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p_del.returncode != 0

Web Proxy Viewer  |  New URL  |  Original Page