Files
files-to-prompt/tests/test_files_to_prompt.py
Nick Powell acbe107f49 --ignore patterns now include directory names unless --ignore-files-only (#30)
* Option to --include-directories otherwise ignored by an ignore pattern
* --include-directories renamed to --ignore-files-only

Refs https://github.com/simonw/files-to-prompt/pull/30/#issuecomment-2658177542

---------

Co-authored-by: Simon Willison <swillison@gmail.com>
2025-02-13 19:28:32 -08:00

325 lines
12 KiB
Python

import os
import pytest
from click.testing import CliRunner
from files_to_prompt.cli import cli
def test_basic_functionality(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/file1.txt", "w") as f:
f.write("Contents of file1")
with open("test_dir/file2.txt", "w") as f:
f.write("Contents of file2")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
assert "test_dir/file1.txt" in result.output
assert "Contents of file1" in result.output
assert "test_dir/file2.txt" in result.output
assert "Contents of file2" in result.output
def test_include_hidden(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/.hidden.txt", "w") as f:
f.write("Contents of hidden file")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
assert "test_dir/.hidden.txt" not in result.output
result = runner.invoke(cli, ["test_dir", "--include-hidden"])
assert result.exit_code == 0
assert "test_dir/.hidden.txt" in result.output
assert "Contents of hidden file" in result.output
def test_ignore_gitignore(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/.gitignore", "w") as f:
f.write("ignored.txt")
with open("test_dir/ignored.txt", "w") as f:
f.write("This file should be ignored")
with open("test_dir/included.txt", "w") as f:
f.write("This file should be included")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
assert "test_dir/ignored.txt" not in result.output
assert "test_dir/included.txt" in result.output
result = runner.invoke(cli, ["test_dir", "--ignore-gitignore"])
assert result.exit_code == 0
assert "test_dir/ignored.txt" in result.output
assert "This file should be ignored" in result.output
assert "test_dir/included.txt" in result.output
def test_multiple_paths(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir1")
with open("test_dir1/file1.txt", "w") as f:
f.write("Contents of file1")
os.makedirs("test_dir2")
with open("test_dir2/file2.txt", "w") as f:
f.write("Contents of file2")
with open("single_file.txt", "w") as f:
f.write("Contents of single file")
result = runner.invoke(cli, ["test_dir1", "test_dir2", "single_file.txt"])
assert result.exit_code == 0
assert "test_dir1/file1.txt" in result.output
assert "Contents of file1" in result.output
assert "test_dir2/file2.txt" in result.output
assert "Contents of file2" in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
def test_ignore_patterns(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir", exist_ok=True)
with open("test_dir/file_to_ignore.txt", "w") as f:
f.write("This file should be ignored due to ignore patterns")
with open("test_dir/file_to_include.txt", "w") as f:
f.write("This file should be included")
result = runner.invoke(cli, ["test_dir", "--ignore", "*.txt"])
assert result.exit_code == 0
assert "test_dir/file_to_ignore.txt" not in result.output
assert "This file should be ignored due to ignore patterns" not in result.output
assert "test_dir/file_to_include.txt" not in result.output
os.makedirs("test_dir/test_subdir", exist_ok=True)
with open("test_dir/test_subdir/any_file.txt", "w") as f:
f.write("This entire subdirectory should be ignored due to ignore patterns")
result = runner.invoke(cli, ["test_dir", "--ignore", "*subdir*"])
assert result.exit_code == 0
assert "test_dir/test_subdir/any_file.txt" not in result.output
assert (
"This entire subdirectory should be ignored due to ignore patterns"
not in result.output
)
assert "test_dir/file_to_include.txt" in result.output
assert "This file should be included" in result.output
assert "This file should be included" in result.output
result = runner.invoke(
cli, ["test_dir", "--ignore", "*subdir*", "--ignore-files-only"]
)
assert result.exit_code == 0
assert "test_dir/test_subdir/any_file.txt" in result.output
result = runner.invoke(cli, ["test_dir", "--ignore", ""])
def test_specific_extensions(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
# Write one.txt one.py two/two.txt two/two.py three.md
os.makedirs("test_dir/two")
with open("test_dir/one.txt", "w") as f:
f.write("This is one.txt")
with open("test_dir/one.py", "w") as f:
f.write("This is one.py")
with open("test_dir/two/two.txt", "w") as f:
f.write("This is two/two.txt")
with open("test_dir/two/two.py", "w") as f:
f.write("This is two/two.py")
with open("test_dir/three.md", "w") as f:
f.write("This is three.md")
# Try with -e py -e md
result = runner.invoke(cli, ["test_dir", "-e", "py", "-e", "md"])
assert result.exit_code == 0
assert ".txt" not in result.output
assert "test_dir/one.py" in result.output
assert "test_dir/two/two.py" in result.output
assert "test_dir/three.md" in result.output
def test_mixed_paths_with_options(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/.gitignore", "w") as f:
f.write("ignored_in_gitignore.txt\n.hidden_ignored_in_gitignore.txt")
with open("test_dir/ignored_in_gitignore.txt", "w") as f:
f.write("This file should be ignored by .gitignore")
with open("test_dir/.hidden_ignored_in_gitignore.txt", "w") as f:
f.write("This hidden file should be ignored by .gitignore")
with open("test_dir/included.txt", "w") as f:
f.write("This file should be included")
with open("test_dir/.hidden_included.txt", "w") as f:
f.write("This hidden file should be included")
with open("single_file.txt", "w") as f:
f.write("Contents of single file")
result = runner.invoke(cli, ["test_dir", "single_file.txt"])
assert result.exit_code == 0
assert "test_dir/ignored_in_gitignore.txt" not in result.output
assert "test_dir/.hidden_ignored_in_gitignore.txt" not in result.output
assert "test_dir/included.txt" in result.output
assert "test_dir/.hidden_included.txt" not in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
result = runner.invoke(cli, ["test_dir", "single_file.txt", "--include-hidden"])
assert result.exit_code == 0
assert "test_dir/ignored_in_gitignore.txt" not in result.output
assert "test_dir/.hidden_ignored_in_gitignore.txt" not in result.output
assert "test_dir/included.txt" in result.output
assert "test_dir/.hidden_included.txt" in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
result = runner.invoke(
cli, ["test_dir", "single_file.txt", "--ignore-gitignore"]
)
assert result.exit_code == 0
assert "test_dir/ignored_in_gitignore.txt" in result.output
assert "test_dir/.hidden_ignored_in_gitignore.txt" not in result.output
assert "test_dir/included.txt" in result.output
assert "test_dir/.hidden_included.txt" not in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
result = runner.invoke(
cli,
["test_dir", "single_file.txt", "--ignore-gitignore", "--include-hidden"],
)
assert result.exit_code == 0
assert "test_dir/ignored_in_gitignore.txt" in result.output
assert "test_dir/.hidden_ignored_in_gitignore.txt" in result.output
assert "test_dir/included.txt" in result.output
assert "test_dir/.hidden_included.txt" in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
def test_binary_file_warning(tmpdir):
runner = CliRunner(mix_stderr=False)
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/binary_file.bin", "wb") as f:
f.write(b"\xff")
with open("test_dir/text_file.txt", "w") as f:
f.write("This is a text file")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
stdout = result.stdout
stderr = result.stderr
assert "test_dir/text_file.txt" in stdout
assert "This is a text file" in stdout
assert "\ntest_dir/binary_file.bin" not in stdout
assert (
"Warning: Skipping file test_dir/binary_file.bin due to UnicodeDecodeError"
in stderr
)
@pytest.mark.parametrize(
"args", (["test_dir"], ["test_dir/file1.txt", "test_dir/file2.txt"])
)
def test_xml_format_dir(tmpdir, args):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/file1.txt", "w") as f:
f.write("Contents of file1.txt")
with open("test_dir/file2.txt", "w") as f:
f.write("Contents of file2.txt")
result = runner.invoke(cli, args + ["--cxml"])
assert result.exit_code == 0
actual = result.output
expected = """
<documents>
<document index="1">
<source>test_dir/file1.txt</source>
<document_content>
Contents of file1.txt
</document_content>
</document>
<document index="2">
<source>test_dir/file2.txt</source>
<document_content>
Contents of file2.txt
</document_content>
</document>
</documents>
"""
assert expected.strip() == actual.strip()
@pytest.mark.parametrize("arg", ("-o", "--output"))
def test_output_option(tmpdir, arg):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/file1.txt", "w") as f:
f.write("Contents of file1.txt")
with open("test_dir/file2.txt", "w") as f:
f.write("Contents of file2.txt")
output_file = "output.txt"
result = runner.invoke(
cli, ["test_dir", arg, output_file], catch_exceptions=False
)
assert result.exit_code == 0
assert not result.output
with open(output_file, "r") as f:
actual = f.read()
expected = """
test_dir/file1.txt
---
Contents of file1.txt
---
test_dir/file2.txt
---
Contents of file2.txt
---
"""
assert expected.strip() == actual.strip()
def test_line_numbers(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
test_content = "First line\nSecond line\nThird line\nFourth line\n"
with open("test_dir/multiline.txt", "w") as f:
f.write(test_content)
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
assert "1 First line" not in result.output
assert test_content in result.output
result = runner.invoke(cli, ["test_dir", "-n"])
assert result.exit_code == 0
assert "1 First line" in result.output
assert "2 Second line" in result.output
assert "3 Third line" in result.output
assert "4 Fourth line" in result.output
result = runner.invoke(cli, ["test_dir", "--line-numbers"])
assert result.exit_code == 0
assert "1 First line" in result.output
assert "2 Second line" in result.output
assert "3 Third line" in result.output
assert "4 Fourth line" in result.output