一键导入
tag-tests-with-issues
Identify likely GitHub issues connected to test cases. Use when asked to tag tests with issues or get started with qcthat.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Identify likely GitHub issues connected to test cases. Use when asked to tag tests with issues or get started with qcthat.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Creates GitHub issues for the package repository. Use when asked to create, file, or open a GitHub issue, or when planning new features or functions that need to be tracked.
Document package functions. Use when asked to document functions.
Implements a GitHub issue end-to-end. Use when asked to implement, work on, or fix a specific issue number.
Guide for writing R code in qcthat. Use when writing new functions, designing APIs, or reviewing/modifying existing R code.
Test-driven development workflow for qcthat. Use when writing any R code (writing new features, fixing bugs, refactoring, or reviewing tests).
Search and rewrite R source code by syntax using astgrepr. Use when asked to find patterns in code, search for function calls, identify usage of specific arguments, locate structural patterns across R files, or perform find-and-replace on code structure.
| name | tag-tests-with-issues |
| description | Identify likely GitHub issues connected to test cases. Use when asked to tag tests with issues or get started with qcthat. |
Add issue references (e.g., (#123)) to test descriptions to connect tests to features/bugs they address.
Pre-compute issue-commit mappings once with MapLongIssueCommits() and pass to MapTestFilesToPotentialIssues(). Do not skip this—its output is used in PrepareTestIssueContext(), your sole source of context for remaining steps.
Pass lglUseCoverage = TRUE to MapTestFilesToPotentialIssues() to augment test-file blame with source-line coverage from covr. Omit lglUseCoverage (defaults to FALSE) if the user tells you to "skip R source checks".
library(qcthat)
dfFileTests <- ExtractTestsFromFiles()
dfIssueCommitsLong <- MapLongIssueCommits()
# If timeout, split: split(dfFileTests, dfFileTests$File) and process per file
dfPotentialIssues <- MapTestFilesToPotentialIssues(
dfFileTests, lglUseCoverage = TRUE, dfIssueCommitsLong = dfIssueCommitsLong
)
dfTestIssueContext <- PrepareTestIssueContext(dfPotentialIssues)
PrepareTestIssueContext() returns tibble with Test (chr), File (chr), LineStart/LineEnd (int), Issues (list of int vecs, already-tagged), PotentialIssueDetails (list of tibbles with Issue, Title, Body), TestCode (list of chr vecs).
For each test, compare code/description against PotentialIssueDetails. Do not use git blame, gh, or other tools. Matches must come only from PotentialIssueDetails for that test. Most tests match one issue; some zero; few >1.
For every test with non-empty PotentialIssueDetails:
TestCode (ground truth over descriptions). Extract: primary function called, expect_*() assertions, edge cases.Body of each potential issue (titles are often misleading). Note whether it names the tested function, describes the specific behavior, and its purpose (feature, bugfix, or unrelated).ValidateCardNumber() rejects expired cards matches "add validation for expired card numbers" but NOT "Payment processing" discussing order workflows.Issues column for existing tags. Don't re-add.Do NOT match on: keyword overlap in title only; feature-area proximity without behavioral match; body contradicting title (trust body); incidental file changes from infrastructure/cleanup; description when TestCode shows different behavior.
intIssue in ExpectUserAccepts() calls: Tag with that issue number unless obviously test data (1, 12, 123).Issues looks correct, skip. When adding, preserve existing tags, sort ascending.test <- dfTestIssueContext[5, ]
test$Test # '"ProcessPayment handles declined cards"'
test$TestCode # calls ProcessPayment(), expects error-payment_declined
test$PotentialIssueDetails[[1]]
# Issue Title Body
# 42 "Payment system overhaul" "Refactor payment module architecture..."
# 87 "Payment processing error handling" "Implement ProcessPayment() to handle declined cards..."
# 104 "Add logging to payment module" "Add debug logging throughout payment..."
# 42: refactoring, not implementing → NO
# 87: explicitly mentions ProcessPayment() + declined cards → YES
# 104: logging, unrelated → NO
# Decision: Tag #87
Format: test_that("does something (#123)", { ... }) or (#123, #456) for multiple.
Rules: Only edit the parenthetical issue tags in test_that() descriptions. Preserve existing tags; sort ascending. Batch edits per file; preserve style.
Use astgrepr find-and-replace to rewrite test descriptions. Process one file at a time: find all test_that() calls, match against your tagging decisions, and replace descriptions with tagged versions.
library(astgrepr)
# For each file with tests to tag:
root <- tree_root(tree_new(file = test$File))
# Find test_that() calls by their exact description string
fixes <- root |>
node_find_all(
ast_rule(id = "t1", pattern = 'test_that("ProcessPayment handles declined cards", µBODY)')
) |>
node_replace_all(t1 = 'test_that("ProcessPayment handles declined cards (#87)", ~~BODY~~)')
# Preview, then write
tree_rewrite(root, fixes)
writeLines(tree_rewrite(root, fixes), con = test$File)
When tagging multiple tests in the same file, add multiple ast_rule()s to a single node_find_all() call and corresponding replacements to node_replace_all().
Keep a running log in pkgdown/assets/test_tag_reasons.qmd (renders to HTML). Table per file: "Test", "Issue" (absolute GitHub link), "Reason" (1–2 sentences). Update as you work, not at the end.
After tagging: run devtools::test(reporter = "check") (only descriptions should change, snapshots may update), re-run ExtractTestsFromFiles() to confirm Issues contains tagged numbers, render test_tag_reasons.qmd.