mirror of
https://github.com/cyclotruc/gitingest.git
synced 2026-04-28 11:19:31 +00:00
* feat: add optional --include-submodules flag to CLI and ingestion - Adds --include-submodules CLI flag to control submodule analysis - Propagates include_submodules through ingestion, schemas, and clone logic - Updates tests to cover submodule inclusion - Adds a helper function (_checkout_partial_clone) to avoid repetition - Adds include_submodules example in README.md - Web UI for this option is not implemented for now (https://github.com/cyclotruc/gitingest/pull/313#issuecomment-3019912523) --------- Co-authored-by: Filip Christiansen <22807962+filipchristiansen@users.noreply.github.com>
99 lines
3.5 KiB
Python
99 lines
3.5 KiB
Python
"""Tests for the Gitingest CLI."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from inspect import signature
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from click.testing import CliRunner, Result
|
|
|
|
from gitingest.cli import main
|
|
from gitingest.config import MAX_FILE_SIZE, OUTPUT_FILE_NAME
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("cli_args", "expect_file"),
|
|
[
|
|
pytest.param(["./"], True, id="default-options"),
|
|
pytest.param(
|
|
[
|
|
"./",
|
|
"--output",
|
|
str(OUTPUT_FILE_NAME),
|
|
"--max-size",
|
|
str(MAX_FILE_SIZE),
|
|
"--exclude-pattern",
|
|
"tests/",
|
|
"--include-pattern",
|
|
"src/",
|
|
"--include-submodules",
|
|
],
|
|
True,
|
|
id="custom-options",
|
|
),
|
|
],
|
|
)
|
|
def test_cli_writes_file(
|
|
tmp_path: Path,
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
*,
|
|
cli_args: list[str],
|
|
expect_file: bool,
|
|
) -> None:
|
|
"""Run the CLI and verify that the SARIF file is created (or not)."""
|
|
expectes_exit_code = 0
|
|
# Work inside an isolated temp directory
|
|
monkeypatch.chdir(tmp_path)
|
|
|
|
result = _invoke_isolated_cli_runner(cli_args)
|
|
|
|
assert result.exit_code == expectes_exit_code, result.stderr
|
|
|
|
# Summary line should be on STDOUT
|
|
stdout_lines = result.stdout.splitlines()
|
|
assert f"Analysis complete! Output written to: {OUTPUT_FILE_NAME}" in stdout_lines
|
|
|
|
# File side-effect
|
|
sarif_file = tmp_path / OUTPUT_FILE_NAME
|
|
assert sarif_file.exists() is expect_file, f"{OUTPUT_FILE_NAME} existence did not match expectation"
|
|
|
|
|
|
def test_cli_with_stdout_output() -> None:
|
|
"""Test CLI invocation with output directed to STDOUT."""
|
|
output_file = Path(OUTPUT_FILE_NAME)
|
|
# Clean up any existing digest.txt file before test
|
|
if output_file.exists():
|
|
output_file.unlink()
|
|
|
|
try:
|
|
result = _invoke_isolated_cli_runner(["./", "--output", "-", "--exclude-pattern", "tests/"])
|
|
|
|
# ─── core expectations (stdout) ────────────────────────────────────-
|
|
assert result.exit_code == 0, f"CLI exited with code {result.exit_code}, stderr: {result.stderr}"
|
|
assert "---" in result.stdout, "Expected file separator '---' not found in STDOUT"
|
|
assert "src/gitingest/cli.py" in result.stdout, (
|
|
"Expected content (e.g., src/gitingest/cli.py) not found in STDOUT"
|
|
)
|
|
assert not output_file.exists(), f"Output file {output_file} was unexpectedly created."
|
|
|
|
# ─── the summary must *not* pollute STDOUT, must appear on STDERR ───
|
|
summary = "Analysis complete! Output sent to stdout."
|
|
stdout_lines = result.stdout.splitlines()
|
|
stderr_lines = result.stderr.splitlines()
|
|
assert summary not in stdout_lines, "Unexpected summary message found in STDOUT"
|
|
assert summary in stderr_lines, "Expected summary message not found in STDERR"
|
|
assert f"Output written to: {output_file.name}" not in stderr_lines
|
|
finally:
|
|
# Clean up any digest.txt file that might have been created during test
|
|
if output_file.exists():
|
|
output_file.unlink()
|
|
|
|
|
|
def _invoke_isolated_cli_runner(args: list[str]) -> Result:
|
|
"""Return a ``CliRunner`` that keeps ``stderr`` separate on Click 8.0-8.1."""
|
|
kwargs = {}
|
|
if "mix_stderr" in signature(CliRunner.__init__).parameters:
|
|
kwargs["mix_stderr"] = False # Click 8.0-8.1
|
|
runner = CliRunner(**kwargs)
|
|
return runner.invoke(main, args)
|