Advertisement

← refacto-feature-scout

tests/test_prompts.py

3.7 KB Download file
"""The prompts have to work for somebody else's project, not just the one they grew up on."""
from scout import build, scan
from scout.projects import Project

PLAIN = Project(
    key="mealplan", name="Meal Planner", folder="/tmp/mealplan",
    what_it_is="A web app that turns a weekly shopping list into meals.",
    who_uses_it="Home cooks who plan a week at a time.",
    audience="home cooks who plan their week",
    test_command="pytest -q",
)

IDEA = {"id": 7, "title": "Leftovers view", "summary": "Shows what to do with what's left.",
        "user_value": "People throw food away.", "spec": "Add a page."}


def render_scan(project=PLAIN):
    return scan.build_prompt(project, "(docs)", "(signals)", "(none yet)", count=3)


def render_build(project=PLAIN):
    return build.build_prompt(project, IDEA, "scout/7-leftovers-view")


def test_a_plain_project_gets_a_prompt_with_nothing_left_over():
    for rendered in (render_scan(), render_build()):
        assert "$" not in rendered, "a slot was left unfilled"
        assert "{" not in rendered.split("## Output")[0].split("## Final answer")[0]


def test_nothing_of_the_first_project_leaks_into_someone_elses():
    for rendered in (render_scan().lower(), render_build().lower()):
        for word in ("polymarket", "kalshi", "prediction market", "refacto", "terminal",
                     "npm", "decisions.md", "/core", "trading"):
            assert word not in rendered, word


def test_a_project_that_covers_one_thing_is_not_asked_to_tag_ideas():
    assert '"venue"' not in render_scan()
    tagged = render_scan(Project(key="k", name="K", folder="/tmp/k", areas=["Web", "Phone"]))
    assert '"venue": "web" | "phone" | "both"' in tagged


def test_a_project_with_plans_has_each_idea_placed_in_one():
    assert '"plan"' not in render_scan()
    with_plans = render_scan(Project(key="k", name="K", folder="/tmp/k", plans=["Free", "Pro"]))
    assert '"plan": "free" | "pro"' in with_plans and '"plan_reason"' in with_plans
    assert "$" not in with_plans


def test_the_projects_own_test_command_is_what_it_is_told_to_run():
    rendered = render_build()
    assert "`pytest -q`" in rendered and "npm" not in rendered


def test_extra_checks_are_asked_for_when_a_project_has_them():
    p = Project(key="k", name="K", folder="/tmp/k", test_command="make test",
                extra_checks=["make lint", "make types"])
    rendered = render_build(p)
    assert "`make test` and `make lint` and `make types`" in rendered


def test_a_project_with_no_tests_yet_is_asked_to_start_one():
    rendered = render_build(Project(key="k", name="K", folder="/tmp/k"))
    assert "no test command yet" in rendered
    assert "put the command you used in your report" in rendered


def test_house_rules_reach_the_builder_in_the_owners_own_words():
    p = Project(key="k", name="K", folder="/tmp/k", house_rules="- Never touch the billing code.")
    assert "Never touch the billing code." in render_build(p)


def test_a_project_with_nowhere_to_look_still_gets_useful_instructions():
    rendered = render_scan(Project(key="k", name="K", folder="/tmp/k"))
    assert "Competing and adjacent tools" in rendered
    assert "the people who use it" in rendered


def test_search_terms_are_handed_to_the_researcher():
    p = Project(key="k", name="K", folder="/tmp/k",
                sources={"search_terms": ["meal planning app", "grocery list tool"]})
    assert 'Search for: "meal planning app", "grocery list tool".' in render_scan(p)


def test_the_categories_a_project_cares_about_are_the_ones_offered():
    p = Project(key="k", name="K", folder="/tmp/k", categories=["bug", "polish"])
    assert '"category": "bug" | "polish"' in render_scan(p)