(opts = {})
| 100 | } |
| 101 | |
| 102 | function makeGithub(opts = {}) { |
| 103 | const createReviewCalls = []; |
| 104 | const issueComments = []; |
| 105 | const updatedComments = []; |
| 106 | const listCommentsCalls = []; |
| 107 | const listReviewCommentsCalls = []; |
| 108 | const listReviewsCalls = []; |
| 109 | const listFilesCalls = []; |
| 110 | const getPullCalls = []; |
| 111 | // Interleaved log of write operations (createReview / createComment / |
| 112 | // updateComment) in call order, so tests can assert positioning invariants |
| 113 | // such as "summary created before review" without timing the calls. |
| 114 | const ops = []; |
| 115 | // Per-comment attempt counter, keyed by commentKey, so perCommentError can be |
| 116 | // attempt-aware (e.g. "429 on attempt 0, succeed on attempt 1"). |
| 117 | const perCommentAttempts = new Map(); |
| 118 | |
| 119 | function successRemaining() { |
| 120 | return opts.successRemaining != null ? String(opts.successRemaining) : "5000"; |
| 121 | } |
| 122 | |
| 123 | // Inline comment objects recorded in BATCH createReview calls only, so tests |
| 124 | // can simulate "this comment already landed on the server" without predicting |
| 125 | // the random IDs from newCommentId(). Under multi-batch (N < toSend.length) |
| 126 | // there are several batch calls (body === REVIEW_TAG), so this scans ALL batch |
| 127 | // calls — not just createReviewCalls[0]. Scoped to batch calls so batch-level |
| 128 | // landing (echoPosted) stays disjoint from per-comment landing (landedKeys, |
| 129 | // which reads per-comment calls with body === ""). |
| 130 | function batchPostedComments() { |
| 131 | const out = []; |
| 132 | for (const call of createReviewCalls) { |
| 133 | if ((call.body || "") !== REVIEW_TAG) continue; |
| 134 | for (const c of call.comments || []) { |
| 135 | const m = /<!--\s*(ocr-\d+-\d+-[a-f0-9]+)\s*-->/.exec(c.body || ""); |
| 136 | if (m) { |
| 137 | out.push({ |
| 138 | path: c.path, |
| 139 | body: c.body, |
| 140 | side: c.side || "RIGHT", |
| 141 | start_line: c.start_line, |
| 142 | line: c.line, |
| 143 | }); |
| 144 | } |
| 145 | } |
| 146 | } |
| 147 | return out; |
| 148 | } |
| 149 | |
| 150 | // Count of batch createReview calls issued so far (body === REVIEW_TAG), so a |
| 151 | // per-batch-index error spec can target e.g. "fail batch #2 but not #1". |
| 152 | function batchCallCount() { |
| 153 | let n = 0; |
| 154 | for (const call of createReviewCalls) { |
| 155 | if ((call.body || "") === REVIEW_TAG) n++; |
| 156 | } |
| 157 | return n; |
| 158 | } |
| 159 |
no test coverage detected