Skip to content

Commit f18c7ae

Browse files
committed
test(commit): refactor preview tests with mock prompt app
1 parent 48fa2fb commit f18c7ae

File tree

2 files changed

+25
-41
lines changed

2 files changed

+25
-41
lines changed

tests/commands/test_commit_command.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ def test_commit_message_length_cli_zero_disables_limit(
405405
success_mock.assert_called_once()
406406

407407

408-
@pytest.mark.usefixtures("staging_is_clean")
408+
@pytest.mark.usefixtures("staging_is_clean", "commit_mock")
409409
def test_commit_preview_enhances_questions_passed_to_questionary_prompt(
410410
config, mocker: MockFixture
411411
):
@@ -428,9 +428,6 @@ def prompt_side_effect(questions_to_ask, style=None):
428428
return prompt_return
429429

430430
prompt_mock = mocker.patch("questionary.prompt", side_effect=prompt_side_effect)
431-
mocker.patch(
432-
"commitizen.git.commit", return_value=cmd.Command("success", "", b"", b"", 0)
433-
)
434431

435432
commit_cmd = commands.Commit(config, {"preview": True, "message_length_limit": 0})
436433
message = commit_cmd._get_message_by_prompt_commit_questions()

tests/test_preview_questions.py

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from collections.abc import Mapping
1010

1111
import pytest
12+
from pytest_mock import MockerFixture
1213

1314
from commitizen.question import CzQuestion
1415

@@ -38,6 +39,13 @@ def info(self) -> str:
3839
return ""
3940

4041

42+
def _make_fake_prompt_app(mocker: MockerFixture, buffer_text: str):
43+
"""Object graph for get_app().layout.current_buffer.text (prompt_toolkit)."""
44+
app = mocker.Mock()
45+
app.layout.current_buffer.text = buffer_text
46+
return app
47+
48+
4149
def test_build_preview_questions_disabled_returns_original_list(config):
4250
cz = PreviewCz(config)
4351
questions: list[CzQuestion] = [
@@ -50,22 +58,14 @@ def test_build_preview_questions_disabled_returns_original_list(config):
5058

5159
def test_build_preview_questions_wraps_filter_and_updates_answers_state(
5260
monkeypatch: pytest.MonkeyPatch,
61+
mocker: MockerFixture,
5362
config,
5463
):
5564
cz = PreviewCz(config)
5665

5766
def original_filter(raw: str) -> str:
5867
return raw.strip().upper()
5968

60-
class DummyBuffer:
61-
text = " hello "
62-
63-
class DummyLayout:
64-
current_buffer = DummyBuffer()
65-
66-
class DummyApp:
67-
layout = DummyLayout()
68-
6969
questions: list[CzQuestion] = [
7070
{
7171
"type": "input",
@@ -78,13 +78,12 @@ class DummyApp:
7878
enhanced = build_preview_questions(cz, questions, enabled=True, max_length=50)
7979
q = enhanced[0]
8080
assert q["filter"] is not original_filter
81-
82-
# First update state via filter wrapper
8381
assert q["filter"](" hello ") == "HELLO"
8482

85-
# Then call toolbar which uses subject_builder -> cz.message() using answers_state
86-
# and the current buffer text for the active field.
87-
monkeypatch.setattr("commitizen.preview_questions.get_app", lambda: DummyApp())
83+
monkeypatch.setattr(
84+
"commitizen.preview_questions.get_app",
85+
lambda: _make_fake_prompt_app(mocker, " hello "),
86+
)
8887
toolbar_text = q["bottom_toolbar"]()
8988
assert "HELLO" in toolbar_text
9089
assert cz.calls, "cz.message should be called by toolbar rendering"
@@ -121,28 +120,22 @@ def test_build_preview_questions_adds_validate_only_for_supported_types(config):
121120

122121
def test_toolbar_uses_current_buffer_text_and_subject_builder(
123122
monkeypatch: pytest.MonkeyPatch,
123+
mocker: MockerFixture,
124124
config,
125125
):
126126
cz = PreviewCz(config)
127127

128-
class DummyBuffer:
129-
text = "buffered"
130-
131-
class DummyLayout:
132-
current_buffer = DummyBuffer()
133-
134-
class DummyApp:
135-
layout = DummyLayout()
136-
137-
monkeypatch.setattr("commitizen.preview_questions.get_app", lambda: DummyApp())
128+
monkeypatch.setattr(
129+
"commitizen.preview_questions.get_app",
130+
lambda: _make_fake_prompt_app(mocker, "buffered"),
131+
)
138132

139133
questions: list[CzQuestion] = [
140134
{"type": "input", "name": "subject", "message": "Subject"},
141135
]
142136
enhanced = build_preview_questions(cz, questions, enabled=True, max_length=50)
143137
toolbar_text = enhanced[0]["bottom_toolbar"]()
144138

145-
# DummyCz.message uses subject from current buffer text via subject_builder
146139
assert "buffered" in toolbar_text
147140

148141

@@ -165,6 +158,7 @@ def test_get_current_buffer_text_on_get_app_exception_returns_empty(
165158

166159
def test_subject_builder_applies_field_filter_and_handles_filter_exception(
167160
monkeypatch: pytest.MonkeyPatch,
161+
mocker: MockerFixture,
168162
config,
169163
):
170164
cz = PreviewCz(config)
@@ -175,15 +169,6 @@ def ok_filter(raw: str) -> str:
175169
def boom_filter(_raw: str) -> str:
176170
raise RuntimeError("boom")
177171

178-
class DummyBuffer:
179-
text = " SCOPE "
180-
181-
class DummyLayout:
182-
current_buffer = DummyBuffer()
183-
184-
class DummyApp:
185-
layout = DummyLayout()
186-
187172
questions: list[CzQuestion] = [
188173
{"type": "input", "name": "subject", "message": "Subject", "filter": ok_filter},
189174
{"type": "input", "name": "scope", "message": "Scope", "filter": boom_filter},
@@ -194,7 +179,10 @@ class DummyApp:
194179
enhanced[0]["filter"](" hi ")
195180
# When rendering toolbar for current field 'scope', subject_builder will apply the
196181
# field filter to the current buffer text; filter exceptions must fallback to raw.
197-
monkeypatch.setattr("commitizen.preview_questions.get_app", lambda: DummyApp())
182+
monkeypatch.setattr(
183+
"commitizen.preview_questions.get_app",
184+
lambda: _make_fake_prompt_app(mocker, " SCOPE "),
185+
)
198186

199187
# Render toolbar for scope and ensure it still includes subject, and scope raw is used
200188
toolbar_text = enhanced[1]["bottom_toolbar"]()
@@ -205,7 +193,7 @@ class DummyApp:
205193
def test_subject_builder_handles_cz_message_exception_returns_empty(
206194
monkeypatch: pytest.MonkeyPatch,
207195
config,
208-
mocker,
196+
mocker: MockerFixture,
209197
):
210198
class BoomCz(PreviewCz):
211199
def message(self, _answers: Mapping[str, Any]) -> str:
@@ -218,7 +206,6 @@ def message(self, _answers: Mapping[str, Any]) -> str:
218206
]
219207
enhanced = build_preview_questions(cz, questions, enabled=True, max_length=50)
220208

221-
# Force deterministic terminal width to avoid wrap dependence
222209
monkeypatch.setattr(
223210
"commitizen.interactive_preview.get_terminal_size",
224211
lambda: mocker.Mock(columns=80),

0 commit comments

Comments
 (0)