Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions .github/scripts/__tests__/agents-pr-meta-update-body.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ test('extractBlock returns empty string if markers not found', () => {

// ========== stripPrTemplateContent tests ==========

test('stripPrTemplateContent removes content before pr-preamble marker', () => {
test('stripPrTemplateContent preserves checkbox-bearing content before pr-preamble marker', () => {
const body = `# Summary

One sentence.
Expand All @@ -356,9 +356,7 @@ Add labels.

const result = stripPrTemplateContent(body);

assert.ok(result.startsWith('<!-- pr-preamble:start -->'));
assert.ok(!result.includes('# Summary'));
assert.ok(!result.includes('Checklist'));
assert.equal(result, body);
});

test('stripPrTemplateContent removes content before auto-status-summary if no preamble', () => {
Expand Down Expand Up @@ -1598,3 +1596,41 @@ test('upsertBlock preserves triple newlines in single-pair case (no duplicates)'
assert.ok(result.includes('After'));
assert.ok(result.includes('\n\n\n'), 'should preserve existing triple newlines when no duplicates removed');
});


test('metadata regeneration preserves outside task lines before and after the summary', () => {
const before = '## Reviewer tasks\n- [ ] Exercise the error path\n and retain its output.\n\n';
const after = '\n\n## More acceptance\n- [ ] Verify the packaged command';
const oldSummary = '<!-- auto-status-summary:start -->\n## Tasks\n- [x] Source task\n<!-- auto-status-summary:end -->';
const newSummary = '<!-- auto-status-summary:start -->\n## Tasks\n- [x] Refreshed source task\n<!-- auto-status-summary:end -->';
const preamble = '<!-- pr-preamble:start -->\nCloses #3441\n<!-- pr-preamble:end -->';
const refresh = (body) => upsertBlock(upsertBlock(stripPrTemplateContent(body), 'pr-preamble', preamble), 'auto-status-summary', newSummary);
const result = refresh(before + oldSummary + after);
assert.ok(result.startsWith(before));
assert.ok(result.includes(after));
assert.ok(result.includes(newSummary));
assert.equal(refresh(result), result);
});

for (const templatePath of ['../../../.github/PULL_REQUEST_TEMPLATE.md', '../../../templates/consumer-repo/.github/PULL_REQUEST_TEMPLATE.md']) {
test(`metadata refresh removes template controls and retains genuine reviewer tasks (${templatePath})`, () => {
const template = require('fs').readFileSync(require('path').resolve(__dirname, templatePath), 'utf8');
const summary = '<!-- auto-status-summary:start -->\n## Tasks\n- [x] Source task\n<!-- auto-status-summary:end -->';
assert.equal(stripPrTemplateContent(template + summary), summary);
const reviewer = '## Review tasks\n> - [ ] Check the error path\n> and its diagnostic.\n';
const cleaned = stripPrTemplateContent(template + reviewer + summary);
assert.ok(cleaned.includes(reviewer));
assert.doesNotMatch(cleaned, /\[[ xX]\] (?:GitHub issue|Direct PR|Verifier should|Keepalive may)/);
assert.equal(stripPrTemplateContent(cleaned), cleaned);
// A genuine task in Notes within Workflow Source must also survive.
const notes = template.replace('Notes:', 'Notes:\n- [ ] Verify the provenance record');
assert.match(stripPrTemplateContent(notes + summary), /- \[ \] Verify the provenance record/);
});
}

for (const hidden of ['<!--\n- [ ] Hidden comment\n-->\n', '```markdown\n- [ ] Fenced example\n```\n', '> ```markdown\n> - [ ] Quoted fenced example\n> ```\n']) {
test(`metadata refresh ignores hidden checkbox prefix: ${hidden.split('\n')[0]}`, () => {
const summary = '<!-- auto-status-summary:start -->\n## Tasks\n- [x] Source task\n<!-- auto-status-summary:end -->';
assert.equal(stripPrTemplateContent('## Stale template\n' + hidden + summary), summary);
});
}
56 changes: 56 additions & 0 deletions .github/scripts/__tests__/issue_scope_parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,64 @@ const {
parseScopeTasksAcceptanceSections,
analyzeSectionPresence,
hasNonPlaceholderScopeTasksAcceptanceContent,
visibleChecklistContent,
} = require('../issue_scope_parser');

for (const parserPath of ['../issue_scope_parser', '../../../templates/consumer-repo/.github/scripts/issue_scope_parser']) {
const parser = require(parserPath);
for (const fence of ['```', '~~~']) {
for (const quote of ['', '> ', '> > ']) {
test(`template controls preserve fenced examples (${parserPath}, ${fence}, ${quote})`, () => {
const example = [
`${fence}markdown`, '## Workflow Source', 'Started from:',
'- [ ] GitHub issue: #123', ` ${fence}`,
'Automation intent:', '- [ ] Keepalive may manage this PR',
`${fence}not-a-closing-fence`, '- [ ] Direct PR / remote GitHub work', fence,
].map((line) => quote + line).join('\n');
const actualControls = [
'## Workflow Source', 'Started from:', '- [ ] GitHub issue: #456',
'Automation intent:', '- [ ] Keepalive may manage this PR',
'Notes:', '- [ ] Retain reviewer work',
].join('\n');
assert.equal(parser.stripPrTemplateControls(`${example}\n${actualControls}`),
`${example}\n## Workflow Source\nNotes:\n- [ ] Retain reviewer work`);
assert.doesNotMatch(parser.visibleChecklistContent(example), /\[ \]/);
});
}
}
}

test('visible checklist scan handles nested quotes without counting their fenced examples', () => {
const body = [
'> > - [ ] Visible nested task',
'> > with a continuation.',
'> > ```markdown',
'> > - [ ] Example only',
'> > ```',
'>> - [x] Completed nested task',
].join('\n');
const visible = visibleChecklistContent(body);
assert.match(visible, /^- \[ \] Visible nested task\n with a continuation\./);
assert.match(visible, /- \[x\] Completed nested task/);
assert.doesNotMatch(visible, /Example only|>/);
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

for (const fence of ['```', '~~~']) {
test(`visible checklist scan keeps fence and comment state separate (${fence})`, () => {
const body = [
'<!-- hidden comment', fence, '- [ ] Hidden task', '-->',
`${fence}markdown`, '<!-- literal comment opener',
` ${fence}`, '- [ ] Indented fence is still an example',
`${fence}not-a-closing-fence`, '- [ ] Still an example', fence,
'- [ ] Real task <!-- inline comment --> remains visible',
'-->',
].join('\n');
const visible = visibleChecklistContent(body);
assert.match(visible, /- \[ \] Real task remains visible/);
assert.doesNotMatch(visible, /Hidden task|example|literal comment/);
});
}

test('extracts sections inside auto-status markers', () => {
const issue = [
'Intro text',
Expand Down
Loading
Loading