-
Notifications
You must be signed in to change notification settings - Fork 0
test: ✅ mocking of basic app functionality #155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
caf43bc
fix: 🐛 Correctly add root keys
joelostblom 27119aa
test: ✅ Test fundamental app logic
joelostblom de44805
test: ✅ Test help output format
joelostblom 9c84926
test: ✅ Reformat comments
joelostblom daf506d
Apply suggestions from code review
joelostblom 5235dd2
docs: 📝 Remove leading = for section comments as per Lukes request
joelostblom 3ef568a
feat: ✨ Add function to generate help test strings
joelostblom eee5717
chore(pre-commit): :pencil2: automatic fixes
pre-commit-ci[bot] bbd38f5
fix: 🐛 Simplify docstring and printing
joelostblom 1d11e38
fix: 🐛 Restore test cases
joelostblom 1a46c90
chore(pre-commit): :pencil2: automatic fixes
pre-commit-ci[bot] 1e56fc4
refactor: ♻️ Functionalize outdated check
joelostblom File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,50 +1,170 @@ | ||
| """These are integration tests for the CLI commands.""" | ||
| """Tests for the CLI commands.""" | ||
|
|
||
| import json | ||
| from pathlib import Path | ||
| from textwrap import dedent | ||
|
|
||
| from pytest import fixture, mark | ||
| import pytest | ||
|
|
||
| from seedcase_flower.cli import build, view | ||
| from seedcase_flower.cli import app, view | ||
| from seedcase_flower.internals import BuildStyle | ||
|
|
||
| _DATAPACKAGE_DATA = { | ||
| "name": "placeholder", | ||
| "created": "2026-02-12T11:25:49+01:00", | ||
| "description": "Placeholder", | ||
| "id": "Placeholder", | ||
| "licenses": [{"name": "Placeholder"}], | ||
| "title": "Placeholder", | ||
| "version": "0.0.0", | ||
| } | ||
|
|
||
| # Create a file at tmp_path that is automatically cleaned up after tests finish | ||
| @fixture | ||
| def datapackage_path(tmp_path): | ||
| data = { | ||
| "name": "placeholder", | ||
| "created": "2026-02-12T11:25:49+01:00", | ||
| "description": "Placeholder", | ||
| "id": "Placeholder", | ||
| "licenses": [{"name": "Placeholder"}], | ||
| "title": "Placeholder", | ||
| "version": "0.0.0", | ||
| } | ||
|
|
||
| @pytest.fixture | ||
| def datapackage_path(tmp_path): | ||
| """Create a temporary datapackage.json and return its path as a string.""" | ||
| file_path = tmp_path / "datapackage.json" | ||
| file_path.write_text(json.dumps(data)) | ||
|
|
||
| # Since `build` expects a str as the URI | ||
| file_path.write_text(json.dumps(_DATAPACKAGE_DATA)) | ||
| return str(file_path) | ||
|
|
||
|
|
||
| @mark.parametrize( | ||
| "style, expected", | ||
| [ | ||
| (BuildStyle.quarto_one_page, None), | ||
| ], | ||
| ) | ||
| def test_build( | ||
| datapackage_path: str, | ||
| style: BuildStyle, | ||
| expected: None, | ||
| ) -> None: | ||
| """Test the build CLI function.""" | ||
| result = build(datapackage_path, style=style) | ||
| assert result == expected | ||
| @pytest.fixture | ||
| def mock_resolve_uri(mocker): | ||
| """Mock _resolve_uri to isolate CLI tests from filesystem resolution.""" | ||
| return mocker.patch("seedcase_flower.cli._resolve_uri") | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def mock_read_properties(mocker): | ||
joelostblom marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """Mock _read_properties to isolate CLI tests from file I/O.""" | ||
| return mocker.patch("seedcase_flower.cli._read_properties") | ||
|
|
||
|
|
||
| # === Testing CLI invocation === | ||
lwjohnst86 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| def test_build_with_mocked_internals(mock_resolve_uri, mock_read_properties): | ||
| """Isolate CLI behaviour by mocking internal helpers.""" | ||
| fake_path = Path("datapackage.json") | ||
| mock_resolve_uri.return_value = fake_path | ||
| # Simulate running the app from the command line (but without calling sys.exit()) | ||
| app(["build", "datapackage.json"], result_action="return_value") | ||
|
|
||
| # Checking that the correct values were passed to the internal functions | ||
| mock_resolve_uri.assert_called_once_with("datapackage.json") | ||
| mock_read_properties.assert_called_once_with(fake_path) | ||
|
|
||
|
|
||
| # === Checking stdout === | ||
|
|
||
|
|
||
| def test_build_verbose_prints_output(capsys, datapackage_path): | ||
joelostblom marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """--verbose should print output_dir, properties, template_dir, and style.""" | ||
| app( | ||
| ["build", datapackage_path, "--verbose"], | ||
| result_action="return_value", | ||
| ) | ||
| expected = f"docs {_DATAPACKAGE_DATA} None BuildStyle.quarto_one_page\n" | ||
| assert capsys.readouterr().out == expected | ||
|
|
||
|
|
||
| def test_build_no_verbose_produces_no_output(capsys, datapackage_path): | ||
| """Without --verbose, build should produce no stdout.""" | ||
| app(["build", datapackage_path], result_action="return_value") | ||
| assert capsys.readouterr().out == "" | ||
|
|
||
|
|
||
| # === File-based config === | ||
|
|
||
|
|
||
| def test_build_reads_uri_from_flower_toml(tmp_path, monkeypatch): | ||
| """Build args specified in .flower.toml should overwrite the default values.""" | ||
| toml_path = tmp_path / ".flower.toml" | ||
| toml_path.write_text( | ||
| 'uri = "custom.json"\n' | ||
| 'style = "quarto_resource_listing"\n' | ||
| 'template_dir = "my-templates/"\n' | ||
| 'output_dir = "my-docs/"\n' | ||
| "verbose = true\n" | ||
| ) | ||
|
|
||
| monkeypatch.chdir(tmp_path) | ||
|
|
||
| _, bound, _ = app.parse_args(["build"]) | ||
| assert bound.arguments["uri"] == "custom.json" | ||
| assert bound.arguments["style"] == BuildStyle.quarto_resource_listing | ||
| assert bound.arguments["template_dir"] == Path("my-templates/") | ||
| assert bound.arguments["output_dir"] == Path("my-docs/") | ||
| assert bound.arguments["verbose"] is True | ||
|
|
||
|
|
||
| # === Help output === | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def console(): | ||
| from rich.console import Console | ||
|
|
||
| return Console( | ||
| width=90, | ||
| force_terminal=True, | ||
| highlight=False, | ||
| color_system=None, | ||
| legacy_windows=False, | ||
| ) | ||
|
|
||
|
|
||
| def test_help_page(capsys, console): | ||
| """Top-level --help should match expected output.""" | ||
| with pytest.raises(SystemExit): | ||
| app(["--help"], console=console) | ||
| assert capsys.readouterr().out == dedent( | ||
| """\ | ||
| Usage: seedcase-flower COMMAND | ||
|
|
||
| Flower generates human-readable documentation from Data Packages. | ||
|
|
||
| ╭─ Commands ─────────────────────────────────────────────────────────────────────────────╮ | ||
| │ build Build human-readable documentation from a datapackage.json file. │ | ||
| │ --help (-h) Display this message and exit. │ | ||
| │ --version Display application version. │ | ||
| ╰────────────────────────────────────────────────────────────────────────────────────────╯ | ||
| """ # noqa | ||
lwjohnst86 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ) | ||
|
|
||
|
|
||
| def test_build_help_page(capsys, console): | ||
| """build --help should document all parameters with defaults and choices.""" | ||
| with pytest.raises(SystemExit): | ||
| app(["build", "--help"], console=console) | ||
| assert capsys.readouterr().out == dedent( | ||
| """\ | ||
lwjohnst86 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Usage: seedcase-flower build [ARGS] | ||
|
|
||
| Build human-readable documentation from a datapackage.json file. | ||
|
|
||
| ╭─ Parameters ───────────────────────────────────────────────────────────────────────────╮ | ||
| │ URI --uri The URI to a datapackage.json file. [default: │ | ||
| │ datapackage.json] │ | ||
| │ STYLE --style The style used to structure the output. If a template │ | ||
| │ directory is given, this parameter will be ignored. │ | ||
| │ [choices: quarto-one-page, quarto-resource-listing, │ | ||
| │ quarto-resource-tables] [default: quarto-one-page] │ | ||
| │ TEMPLATE-DIR --template-dir The directory that contains the Jinja template files and │ | ||
| │ sections.toml. When set, it will override any built-in │ | ||
| │ style given by the style parameter. │ | ||
| │ OUTPUT-DIR --output-dir The directory to save the generated files in. [default: │ | ||
| │ docs] │ | ||
| │ VERBOSE --verbose If True, prints additional information to the console. │ | ||
| │ [default: False] │ | ||
| ╰────────────────────────────────────────────────────────────────────────────────────────╯ | ||
| """ # noqa | ||
| ) | ||
|
|
||
|
|
||
| # === view (placeholder) === | ||
|
|
||
|
|
||
| def test_view() -> None: | ||
| """Test the view CLI function.""" | ||
| result = view() | ||
| assert result == "" | ||
| """view returns an empty string.""" | ||
| assert view() == "" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.