Skip to content

Commit c175ebc

Browse files
Add test coverage for --recursive option (#6)
* Add comprehensive tests for --recursive option - Add test_recursive_option_with_nested_directory: verifies files in subdirectories are processed - Add test_non_recursive_option_ignores_subdirectories: confirms non-recursive mode only processes top-level files - Add test_recursive_with_match_pattern: tests recursive with pattern matching - Add test_recursive_preserves_directory_structure: ensures directory structure is preserved in output Closes #5 Co-authored-by: kompre <kompre@users.noreply.github.com> * Create test.yml --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: kompre <kompre@users.noreply.github.com>
1 parent 933100a commit c175ebc

2 files changed

Lines changed: 148 additions & 3 deletions

File tree

.github/workflows/test.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Run Tests
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version-file: ".python-version"
21+
22+
- name: Install uv
23+
uses: astral-sh/setup-uv@v6
24+
with:
25+
version: "latest"
26+
27+
- name: Install Quarto
28+
uses: quarto-dev/quarto-actions/setup@v2
29+
with:
30+
version: latest
31+
32+
- name: Install dependencies
33+
run: uv sync --locked --all-extras --dev
34+
35+
- name: Run tests
36+
run: uv run pytest tests -v

tests/test_quarto_batch_convert.py

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,120 @@ def test_output_path(setup_teardown_test_env):
180180
runner = CliRunner()
181181
test_dir = setup_teardown_test_env
182182
output_dir = os.path.join(test_dir, "output")
183-
183+
184184
input_file = os.path.join(test_dir, "notebooks/_test_1.ipynb")
185185
result = runner.invoke(convert_files, [input_file, "-o", output_dir])
186-
186+
187187
file_name, _ = os.path.splitext(os.path.basename(input_file))
188-
188+
189189
assert result.exit_code == 0
190190
assert os.path.exists(os.path.join(output_dir, os.path.dirname(input_file), file_name + ".qmd"))
191+
192+
def test_recursive_option_with_nested_directory():
193+
"""Test that the --recursive option processes files in subdirectories."""
194+
runner = CliRunner()
195+
test_dir = "tests/assets"
196+
output_dir = "temp_recursive_test_output"
197+
198+
# Clean up output directory before test
199+
shutil.rmtree(output_dir, ignore_errors=True)
200+
201+
try:
202+
# Run with recursive flag
203+
result = runner.invoke(convert_files, [test_dir, "-r", "-o", output_dir])
204+
205+
assert result.exit_code == 0
206+
207+
# Check that files from root directory were converted
208+
assert os.path.exists(os.path.join(output_dir, test_dir, "__test.qmd"))
209+
210+
# Check that files from nested directory were converted
211+
assert os.path.exists(os.path.join(output_dir, test_dir, "nested", "__test3.qmd"))
212+
213+
# Verify multiple files were found and converted
214+
assert "Found" in result.output
215+
# Should find __test.ipynb and nested/__test3.ipynb (2 files)
216+
assert "2 file(s)" in result.output or "files" in result.output
217+
finally:
218+
# Cleanup
219+
shutil.rmtree(output_dir, ignore_errors=True)
220+
221+
def test_non_recursive_option_ignores_subdirectories():
222+
"""Test that without --recursive option, subdirectories are ignored."""
223+
runner = CliRunner()
224+
test_dir = "tests/assets"
225+
output_dir = "temp_non_recursive_test_output"
226+
227+
# Clean up output directory before test
228+
shutil.rmtree(output_dir, ignore_errors=True)
229+
230+
try:
231+
# Run WITHOUT recursive flag
232+
result = runner.invoke(convert_files, [test_dir, "-o", output_dir])
233+
234+
assert result.exit_code == 0
235+
236+
# Check that file from root directory was converted
237+
assert os.path.exists(os.path.join(output_dir, test_dir, "__test.qmd"))
238+
239+
# Check that files from nested directory were NOT converted
240+
assert not os.path.exists(os.path.join(output_dir, test_dir, "nested", "__test3.qmd"))
241+
242+
# Should only find __test.ipynb (1 file)
243+
assert "1 file(s)" in result.output or "file" in result.output
244+
finally:
245+
# Cleanup
246+
shutil.rmtree(output_dir, ignore_errors=True)
247+
248+
def test_recursive_with_match_pattern():
249+
"""Test that --recursive works correctly with match patterns."""
250+
runner = CliRunner()
251+
test_dir = "tests/assets"
252+
output_dir = "temp_recursive_match_test_output"
253+
254+
# Clean up output directory before test
255+
shutil.rmtree(output_dir, ignore_errors=True)
256+
257+
try:
258+
# Run with recursive flag and match pattern
259+
result = runner.invoke(convert_files, [test_dir, "-r", "-o", output_dir, "-m", "__test3"])
260+
261+
assert result.exit_code == 0
262+
263+
# Only __test3.ipynb from nested directory should match
264+
assert os.path.exists(os.path.join(output_dir, test_dir, "nested", "__test3.qmd"))
265+
266+
# __test.ipynb from root should NOT be converted (doesn't match pattern)
267+
assert not os.path.exists(os.path.join(output_dir, test_dir, "__test.qmd"))
268+
269+
# Should only find 1 file matching the pattern
270+
assert "1 file(s)" in result.output
271+
finally:
272+
# Cleanup
273+
shutil.rmtree(output_dir, ignore_errors=True)
274+
275+
def test_recursive_preserves_directory_structure():
276+
"""Test that --recursive option preserves the directory structure in output."""
277+
runner = CliRunner()
278+
test_dir = "tests/assets"
279+
output_dir = "temp_recursive_structure_test_output"
280+
281+
# Clean up output directory before test
282+
shutil.rmtree(output_dir, ignore_errors=True)
283+
284+
try:
285+
# Run with recursive flag
286+
result = runner.invoke(convert_files, [test_dir, "-r", "-o", output_dir])
287+
288+
assert result.exit_code == 0
289+
290+
# Verify directory structure is preserved
291+
assert os.path.isdir(os.path.join(output_dir, test_dir))
292+
assert os.path.isdir(os.path.join(output_dir, test_dir, "nested"))
293+
294+
# Check files are in correct locations
295+
assert os.path.exists(os.path.join(output_dir, test_dir, "__test.qmd"))
296+
assert os.path.exists(os.path.join(output_dir, test_dir, "nested", "__test3.qmd"))
297+
finally:
298+
# Cleanup
299+
shutil.rmtree(output_dir, ignore_errors=True)

0 commit comments

Comments
 (0)