Skip to content

Commit 5a89b02

Browse files
zhujian0805claude
andcommitted
test(prompts): add 20 new tests for prompts_commands CLI
Add comprehensive tests for uncovered functions: - list_prompts (empty and with prompts) - view_prompt (success and not found) - create_prompt (from file and empty content) - update_prompt (success and not found) - delete_prompt (success and not found) - set_default_prompt (success and not found) - clear_default_prompt - generate_prompt_id - _parse_app_list (all, comma-separated, invalid) - unsync_prompt (success and file not found) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b818008 commit 5a89b02

1 file changed

Lines changed: 329 additions & 0 deletions

File tree

tests/unit/test_prompts_cli.py

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,332 @@ def test_sync_default_prompt(cli_manager, tmp_path, monkeypatch):
228228
stored = cli_manager.get("test")
229229
assert stored.is_default is True
230230
assert any("synced" in msg.lower() for msg in outputs)
231+
232+
233+
# Additional tests for uncovered functions
234+
235+
236+
def test_list_prompts_empty(cli_manager, monkeypatch):
237+
"""list_prompts shows message when no prompts exist."""
238+
outputs = []
239+
monkeypatch.setattr(
240+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
241+
)
242+
243+
prompts_commands.list_prompts()
244+
245+
combined = "\n".join(outputs)
246+
assert "No prompts found" in combined
247+
248+
249+
def test_list_prompts_with_prompts(cli_manager, monkeypatch):
250+
"""list_prompts shows all prompts with their status."""
251+
prompt1 = Prompt(id="p1", name="Prompt One", content="content 1")
252+
prompt2 = Prompt(
253+
id="p2", name="Prompt Two", content="content 2", description="A description"
254+
)
255+
cli_manager.create(prompt1)
256+
cli_manager.create(prompt2)
257+
cli_manager.set_default("p1")
258+
259+
outputs = []
260+
monkeypatch.setattr(
261+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
262+
)
263+
264+
prompts_commands.list_prompts()
265+
266+
combined = "\n".join(outputs)
267+
assert "Prompt One" in combined
268+
assert "Prompt Two" in combined
269+
assert "default" in combined
270+
assert "p1" in combined
271+
assert "p2" in combined
272+
assert "A description" in combined
273+
274+
275+
def test_view_prompt_success(cli_manager, monkeypatch):
276+
"""view_prompt displays prompt content."""
277+
prompt = Prompt(
278+
id="test",
279+
name="Test Prompt",
280+
content="This is the content",
281+
description="A test description",
282+
)
283+
cli_manager.create(prompt)
284+
285+
outputs = []
286+
monkeypatch.setattr(
287+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
288+
)
289+
290+
prompts_commands.view_prompt("test")
291+
292+
combined = "\n".join(outputs)
293+
assert "Test Prompt" in combined
294+
assert "This is the content" in combined
295+
assert "A test description" in combined
296+
297+
298+
def test_view_prompt_not_found(cli_manager, monkeypatch):
299+
"""view_prompt raises exit when prompt not found."""
300+
outputs = []
301+
monkeypatch.setattr(
302+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
303+
)
304+
305+
with pytest.raises(prompts_commands.typer.Exit):
306+
prompts_commands.view_prompt("nonexistent")
307+
308+
combined = "\n".join(outputs)
309+
assert "not found" in combined
310+
311+
312+
def test_create_prompt_from_file(cli_manager, tmp_path, monkeypatch):
313+
"""create_prompt reads content from file."""
314+
content_file = tmp_path / "content.md"
315+
content_file.write_text("File content")
316+
317+
outputs = []
318+
monkeypatch.setattr(
319+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
320+
)
321+
322+
prompts_commands.create_prompt(
323+
prompt_id="new-prompt",
324+
name="New Prompt",
325+
description="From file",
326+
file=content_file,
327+
)
328+
329+
prompt = cli_manager.get("new-prompt")
330+
assert prompt is not None
331+
assert prompt.content == "File content"
332+
assert prompt.name == "New Prompt"
333+
assert prompt.description == "From file"
334+
335+
336+
def test_create_prompt_empty_content(cli_manager, tmp_path, monkeypatch):
337+
"""create_prompt fails with empty content."""
338+
content_file = tmp_path / "empty.md"
339+
content_file.write_text("")
340+
341+
outputs = []
342+
monkeypatch.setattr(
343+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
344+
)
345+
346+
with pytest.raises(prompts_commands.typer.Exit):
347+
prompts_commands.create_prompt(
348+
prompt_id="empty-prompt",
349+
name="Empty Prompt",
350+
description=None,
351+
file=content_file,
352+
)
353+
354+
combined = "\n".join(outputs)
355+
assert "cannot be empty" in combined
356+
357+
358+
def test_update_prompt_success(cli_manager, tmp_path, monkeypatch):
359+
"""update_prompt updates existing prompt."""
360+
prompt = Prompt(id="upd", name="Original", content="original content")
361+
cli_manager.create(prompt)
362+
363+
new_content_file = tmp_path / "new_content.md"
364+
new_content_file.write_text("updated content")
365+
366+
outputs = []
367+
monkeypatch.setattr(
368+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
369+
)
370+
371+
prompts_commands.update_prompt(
372+
prompt_id="upd",
373+
name="Updated Name",
374+
description="Updated desc",
375+
file=new_content_file,
376+
)
377+
378+
updated = cli_manager.get("upd")
379+
assert updated.name == "Updated Name"
380+
assert updated.description == "Updated desc"
381+
assert updated.content == "updated content"
382+
assert any("updated" in msg.lower() for msg in outputs)
383+
384+
385+
def test_update_prompt_not_found(cli_manager, monkeypatch):
386+
"""update_prompt fails when prompt not found."""
387+
outputs = []
388+
monkeypatch.setattr(
389+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
390+
)
391+
392+
with pytest.raises(prompts_commands.typer.Exit):
393+
prompts_commands.update_prompt(
394+
prompt_id="nonexistent",
395+
name="New Name",
396+
description=None,
397+
file=None,
398+
)
399+
400+
combined = "\n".join(outputs)
401+
assert "not found" in combined
402+
403+
404+
def test_delete_prompt_success(cli_manager, monkeypatch):
405+
"""delete_prompt removes prompt with force flag."""
406+
prompt = Prompt(id="del", name="To Delete", content="content")
407+
cli_manager.create(prompt)
408+
409+
outputs = []
410+
monkeypatch.setattr(
411+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
412+
)
413+
414+
prompts_commands.delete_prompt(prompt_id="del", force=True)
415+
416+
assert cli_manager.get("del") is None
417+
assert any("deleted" in msg.lower() for msg in outputs)
418+
419+
420+
def test_delete_prompt_not_found(cli_manager, monkeypatch):
421+
"""delete_prompt fails when prompt not found."""
422+
outputs = []
423+
monkeypatch.setattr(
424+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
425+
)
426+
427+
with pytest.raises(prompts_commands.typer.Exit):
428+
prompts_commands.delete_prompt(prompt_id="nonexistent", force=True)
429+
430+
combined = "\n".join(outputs)
431+
assert "not found" in combined
432+
433+
434+
def test_set_default_prompt_success(cli_manager, monkeypatch):
435+
"""set_default_prompt sets a prompt as default."""
436+
prompt = Prompt(id="def", name="Default", content="content")
437+
cli_manager.create(prompt)
438+
439+
outputs = []
440+
monkeypatch.setattr(
441+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
442+
)
443+
444+
prompts_commands.set_default_prompt(prompt_id="def")
445+
446+
updated = cli_manager.get("def")
447+
assert updated.is_default is True
448+
assert any("default" in msg.lower() for msg in outputs)
449+
450+
451+
def test_set_default_prompt_not_found(cli_manager, monkeypatch):
452+
"""set_default_prompt fails when prompt not found."""
453+
outputs = []
454+
monkeypatch.setattr(
455+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
456+
)
457+
458+
with pytest.raises(prompts_commands.typer.Exit):
459+
prompts_commands.set_default_prompt(prompt_id="nonexistent")
460+
461+
combined = "\n".join(outputs)
462+
assert "not found" in combined
463+
464+
465+
def test_clear_default_prompt(cli_manager, monkeypatch):
466+
"""clear_default_prompt clears the default setting."""
467+
prompt = Prompt(id="def", name="Default", content="content")
468+
cli_manager.create(prompt)
469+
cli_manager.set_default("def")
470+
471+
outputs = []
472+
monkeypatch.setattr(
473+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
474+
)
475+
476+
prompts_commands.clear_default_prompt()
477+
478+
updated = cli_manager.get("def")
479+
assert updated.is_default is False
480+
assert any("cleared" in msg.lower() for msg in outputs)
481+
482+
483+
def test_generate_prompt_id():
484+
"""generate_prompt_id creates unique IDs with prefix."""
485+
id1 = prompts_commands.generate_prompt_id("test")
486+
id2 = prompts_commands.generate_prompt_id("test")
487+
488+
assert id1.startswith("test-")
489+
assert id2.startswith("test-")
490+
assert id1 != id2 # Should be unique
491+
assert len(id1) == len("test-") + 8 # 8 char hex UUID
492+
493+
494+
def test_parse_app_list_all():
495+
"""_parse_app_list returns all apps when 'all' specified."""
496+
apps = prompts_commands._parse_app_list("all")
497+
assert apps == prompts_commands.VALID_APP_TYPES
498+
499+
500+
def test_parse_app_list_comma_separated():
501+
"""_parse_app_list parses comma-separated apps."""
502+
apps = prompts_commands._parse_app_list("claude,codex")
503+
assert apps == ["claude", "codex"]
504+
505+
506+
def test_parse_app_list_invalid():
507+
"""_parse_app_list raises error for invalid apps."""
508+
with pytest.raises(prompts_commands.typer.BadParameter) as exc_info:
509+
prompts_commands._parse_app_list("invalid,claude")
510+
511+
assert "invalid" in str(exc_info.value).lower()
512+
513+
514+
def test_unsync_prompt_project_level(cli_manager, tmp_path, monkeypatch):
515+
"""unsync_prompt clears project-level prompt file content."""
516+
project_dir = tmp_path / "project"
517+
project_dir.mkdir()
518+
prompt_file = project_dir / "CLAUDE.md"
519+
prompt_file.write_text("Content to unsync")
520+
521+
outputs = []
522+
monkeypatch.setattr(
523+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
524+
)
525+
526+
prompts_commands.unsync_prompt(
527+
app_type="claude",
528+
level="project",
529+
force=True,
530+
project_dir=project_dir,
531+
)
532+
533+
# unsync clears the file content, not deletes it
534+
assert prompt_file.exists()
535+
assert prompt_file.read_text() == ""
536+
combined = "\n".join(outputs)
537+
assert "cleared" in combined.lower()
538+
539+
540+
def test_unsync_prompt_file_not_found(cli_manager, tmp_path, monkeypatch):
541+
"""unsync_prompt handles missing file gracefully."""
542+
project_dir = tmp_path / "project"
543+
project_dir.mkdir()
544+
545+
outputs = []
546+
monkeypatch.setattr(
547+
prompts_commands.typer, "echo", lambda msg="": outputs.append(str(msg))
548+
)
549+
550+
prompts_commands.unsync_prompt(
551+
app_type="claude",
552+
level="project",
553+
force=True,
554+
project_dir=project_dir,
555+
)
556+
557+
combined = "\n".join(outputs)
558+
# Should indicate file doesn't exist
559+
assert "not exist" in combined.lower() or "does not exist" in combined.lower()

0 commit comments

Comments
 (0)