Skip to content

Commit 2373613

Browse files
d10cCopilot
andcommitted
Support --learn for inline expectations via learnEdits
`codeql test run --learn` could previously only rewrite `.expected` files; inline expectations (the `// $ Alert` comments checked by `InlineExpectationsTest`) had to be fixed by hand. This teaches the shared test library to compute those source edits so the test runner can apply them. The `test-postprocess` query exposes a `learnEdits` relation (`file, line, operation, startColumn, endColumn, text`) describing the minimal source rewrite that makes the inline expectations match the actual query results. Replace edits use 1-based half-open `[startColumn, endColumn)` ranges. Equal boundaries represent insertion, and an end column of zero denotes replacement through the end of the line. Same-line inclusive CodeQL location ends convert to exclusive boundaries; locations ending on the following line use the to-EOL form. The relation covers: - appending a fresh comment carrying every tag learned for a line that has an unexpected result and no existing comment to merge into; - rewriting an existing expectation comment as a whole so it matches the current results: dropping fixed-spurious tags, promoting a `MISSING:` expectation that now fires, clearing a stale `SPURIOUS:` annotation, and merging in freshly learned tags, re-rendering the remaining expectations (or deleting the comment when none remain); - preserving expectations this test does not own -- e.g. a tag annotated with a different query's id that shares the source file -- and any trailing regular note (`// $ Alert // note`); - recording any unexpected result, not just `Alert`. The comment syntax comes from the `getStartCommentMarker` / `getEndCommentMarker` markers added to `InputSig` in the previous commit, so `LearnEditsImpl` renders each edit in the target file's own syntax and stays language-agnostic. The Actions postprocessor supplies `#` for `.yml` and `.yaml` sources when implementing the same signature. Edits are emitted as a query predicate rather than applied here: the engine consumes `learnEdits` only under `--learn` and ignores it otherwise, so ordinary `test run` output is unchanged. The supporting predicates are wrapped in a `private module LearnEditsImpl` so only the `query predicate learnEdits` is re-exposed. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1adfa307-c48e-43f5-94e3-8286e4a8c083
1 parent ec736b4 commit 2373613

5 files changed

Lines changed: 482 additions & 0 deletions

File tree

‎actions/ql/lib/codeql/actions/test/internal/InlineExpectationsTestImpl.qll‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,10 @@ module Impl implements InlineExpectationsTestSig {
2121
":" + endColumn
2222
)
2323
}
24+
25+
bindingset[relativePath]
26+
string getStartCommentMarker(string relativePath) {
27+
relativePath.regexpMatch(".*\\.ya?ml") and
28+
result = "#"
29+
}
2430
}

‎actions/ql/test/utils/ActionsInlineExpectationsTestQuery.ql‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ private module Impl implements T::InlineExpectationsTestSig {
2020
)
2121
}
2222

23+
bindingset[relativePath]
24+
string getStartCommentMarker(string relativePath) {
25+
relativePath.regexpMatch(".*\\.ya?ml") and
26+
result = "#"
27+
}
28+
2329
class ExpectationComment extends Yaml::YamlComment {
2430
string getContents() { result = this.getText() }
2531
}

‎java/ql/test-kotlin1/TestUtilities/internal/InlineExpectationsTestImpl.qll‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,10 @@ module Impl implements InlineExpectationsTestSig {
4242
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
4343
)
4444
}
45+
46+
bindingset[relativePath]
47+
string getStartCommentMarker(string relativePath) {
48+
relativePath.matches(["%.java", "%.kt"]) and
49+
result = "//"
50+
}
4551
}

‎java/ql/test-kotlin2/TestUtilities/internal/InlineExpectationsTestImpl.qll‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,10 @@ module Impl implements InlineExpectationsTestSig {
4242
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
4343
)
4444
}
45+
46+
bindingset[relativePath]
47+
string getStartCommentMarker(string relativePath) {
48+
relativePath.matches(["%.java", "%.kt"]) and
49+
result = "//"
50+
}
4551
}

0 commit comments

Comments
 (0)