Skip to content

Commit b3d57c3

Browse files
fix tests
1 parent f10e88b commit b3d57c3

File tree

3 files changed

+74
-57
lines changed

3 files changed

+74
-57
lines changed

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ repos:
4444
- id: black
4545

4646
- repo: https://github.com/asottile/pyupgrade
47-
rev: v3.19.1
47+
rev: v3.20.0
4848
hooks:
4949
- id: pyupgrade
5050
description: "Automatically upgrade syntax for newer versions."
@@ -73,7 +73,7 @@ repos:
7373
- id: djlint-reformat-jinja
7474

7575
- repo: https://github.com/igorshubovych/markdownlint-cli
76-
rev: v0.44.0
76+
rev: v0.45.0
7777
hooks:
7878
- id: markdownlint
7979
description: "Lint markdown files."
@@ -88,7 +88,7 @@ repos:
8888
files: ^src/
8989

9090
- repo: https://github.com/pycqa/pylint
91-
rev: v3.3.6
91+
rev: v3.3.7
9292
hooks:
9393
- id: pylint
9494
name: pylint for source

src/gitingest/cli.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,15 @@ async def _async_main(
163163
token=token,
164164
)
165165

166-
if output != "-":
167-
click.echo(f"Analysis complete! Output written to: {output_target}")
168-
click.echo("\nSummary:")
169-
click.echo(summary)
170-
else:
166+
if output_target == "-": # stdout
171167
click.echo("\n--- Summary ---", err=True)
172168
click.echo(summary, err=True)
173169
click.echo("--- End Summary ---", err=True)
174170
click.echo("Analysis complete! Output sent to stdout.", err=True)
171+
else: # file
172+
click.echo(f"Analysis complete! Output written to: {output_target}")
173+
click.echo("\nSummary:")
174+
click.echo(summary)
175175

176176
except Exception as exc:
177177
# Convert any exception into Click.Abort so that exit status is non-zero

tests/test_cli.py

Lines changed: 66 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,80 @@
1-
"""Tests for the gitingest cli."""
1+
"""Tests for the Gitingest CLI."""
22

33
import os
44
from inspect import signature
5+
from pathlib import Path
6+
from typing import List
57

6-
from click.testing import CliRunner
8+
import pytest
9+
from _pytest.monkeypatch import MonkeyPatch
10+
from click.testing import CliRunner, Result
711

812
from gitingest.cli import main
913
from gitingest.config import MAX_FILE_SIZE, OUTPUT_FILE_NAME
1014

1115

12-
def test_cli_with_default_options():
13-
runner = CliRunner()
14-
result = runner.invoke(main, ["./"])
15-
output_lines = result.output.strip().split("\n")
16-
assert f"Analysis complete! Output written to: {OUTPUT_FILE_NAME}" in output_lines
17-
assert os.path.exists(OUTPUT_FILE_NAME), f"Output file was not created at {OUTPUT_FILE_NAME}"
18-
19-
os.remove(OUTPUT_FILE_NAME)
20-
21-
22-
def test_cli_with_options():
23-
runner = CliRunner()
24-
result = runner.invoke(
25-
main,
26-
[
27-
"./",
28-
"--output",
29-
str(OUTPUT_FILE_NAME),
30-
"--max-size",
31-
str(MAX_FILE_SIZE),
32-
"--exclude-pattern",
33-
"tests/",
34-
"--include-pattern",
35-
"src/",
36-
],
37-
)
38-
output_lines = result.output.strip().split("\n")
39-
assert f"Analysis complete! Output written to: {OUTPUT_FILE_NAME}" in output_lines
40-
assert os.path.exists(OUTPUT_FILE_NAME), f"Output file was not created at {OUTPUT_FILE_NAME}"
41-
42-
os.remove(OUTPUT_FILE_NAME)
43-
44-
45-
def test_cli_with_stdout_output():
46-
"""Test CLI invocation with output directed to STDOUT."""
16+
@pytest.mark.parametrize(
17+
"cli_args, expect_file",
18+
[
19+
pytest.param(["./"], True, id="default-options"),
20+
pytest.param(
21+
[
22+
"./",
23+
"--output",
24+
str(OUTPUT_FILE_NAME),
25+
"--max-size",
26+
str(MAX_FILE_SIZE),
27+
"--exclude-pattern",
28+
"tests/",
29+
"--include-pattern",
30+
"src/",
31+
],
32+
True,
33+
id="custom-options",
34+
),
35+
],
36+
)
37+
def test_cli_writes_file(tmp_path: Path, monkeypatch: MonkeyPatch, cli_args: list[str], expect_file: bool) -> None:
38+
"""Run the CLI and verify that the SARIF file is created (or not)."""
39+
# Work inside an isolated temp directory
40+
monkeypatch.chdir(tmp_path)
4741

48-
kwargs = {}
49-
if "mix_stderr" in signature(CliRunner.__init__).parameters:
50-
kwargs["mix_stderr"] = (
51-
False # Click < 8.2 (https://click.palletsprojects.com/en/stable/changes/#version-8-2-0)
52-
)
42+
result = _invoke_isolated_cli_runner(cli_args)
5343

54-
runner = CliRunner(**kwargs)
55-
result = runner.invoke(main, ["./", "--output", "-", "--exclude-pattern", "tests/"])
44+
assert result.exit_code == 0, result.stderr
5645

46+
# Summary line should be on STDOUT
47+
stdout_lines = result.stdout.splitlines()
48+
assert f"Analysis complete! Output written to: {OUTPUT_FILE_NAME}" in stdout_lines
49+
50+
# File side-effect
51+
sarif_file = tmp_path / OUTPUT_FILE_NAME
52+
assert sarif_file.exists() is expect_file, f"{OUTPUT_FILE_NAME} existence did not match expectation"
53+
54+
55+
def test_cli_with_stdout_output() -> None:
56+
"""Test CLI invocation with output directed to STDOUT."""
57+
result = _invoke_isolated_cli_runner(["./", "--output", "-", "--exclude-pattern", "tests/"])
58+
59+
# ─── core expectations (stdout) ────────────────────────────────────-
5760
assert result.exit_code == 0, f"CLI exited with code {result.exit_code}, stderr: {result.stderr}"
58-
assert "---" in result.output, "Expected file separator '---' not found in STDOUT"
59-
assert "src/gitingest/cli.py" in result.output, "Expected content (e.g., src/gitingest/cli.py) not found in STDOUT"
61+
assert "---" in result.stdout, "Expected file separator '---' not found in STDOUT"
62+
assert "src/gitingest/cli.py" in result.stdout, "Expected content (e.g., src/gitingest/cli.py) not found in STDOUT"
6063
assert not os.path.exists(OUTPUT_FILE_NAME), f"Output file {OUTPUT_FILE_NAME} was unexpectedly created."
61-
assert "Analysis complete! Output sent to stdout." not in result.output
62-
assert "Analysis complete!" in result.stderr, "Expected summary message 'Analysis complete!' not found in STDERR"
63-
assert f"Output written to: {OUTPUT_FILE_NAME}" not in result.stderr
64+
65+
# ─── the summary must *not* pollute STDOUT, must appear on STDERR ───
66+
summary = "Analysis complete! Output sent to stdout."
67+
stdout_lines = result.stdout.splitlines()
68+
stderr_lines = result.stderr.splitlines()
69+
assert summary not in stdout_lines, "Unexpected summary message found in STDOUT"
70+
assert summary in stderr_lines, "Expected summary message not found in STDERR"
71+
assert f"Output written to: {OUTPUT_FILE_NAME}" not in stderr_lines
72+
73+
74+
def _invoke_isolated_cli_runner(args: List[str]) -> Result:
75+
"""Return a CliRunner that keeps stderr apart on Click 8.0-8.1."""
76+
kwargs = {}
77+
if "mix_stderr" in signature(CliRunner.__init__).parameters:
78+
kwargs["mix_stderr"] = False # Click 8.0–8.1
79+
runner = CliRunner(**kwargs)
80+
return runner.invoke(main, args)

0 commit comments

Comments
 (0)