util/config: assertOptionalStringArray '// istanbul ignore else' hides untested 'array contains non-strings' branch
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 72/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 静か
- 技術スタック
- typescript
- 領域
- testing-qa
調査の方向性
src/prompt-generators/util/config.ts の assertOptionalStringArray から始め、次に load-cli-config.test.ts の関連するケースを確認します。対象を絞ったテストとカバレッジを実行し、文字列ではない項目を含む配列のケースを追加して、正当な理由のない ignore ディレクティブを使わずに、バリデーターとカバレッジレポートでその分岐が実行されることを確認します。
索引モデルが issue の本文から書いたものです。
説明
Observed behavior
assertOptionalStringArray in src/prompt-generators/util/config.ts (lines 76-90) has an // istanbul ignore else directive immediately above its validation check:
export function assertOptionalStringArray(
value: Record<string, unknown>,
key: string,
field: string,
): void {
if (!(key in value)) {
return;
}
const array = value[key];
// istanbul ignore else
if (!Array.isArray(array) || array.some(item => typeof item !== 'string')) {
throw new Error(`${field} must be an array of strings`);
}
}
git blame traces the directive to commit 8f4d7d6 ("Push coverage to 100% using ignores"). The condition is a two-clause OR:
!Array.isArray(array)- covered by tests that pass a plain string for an array field (e.g.load-cli-config.test.ts:503,:720passcomponents: 'DOM: Workers'andlabels: 'bug').array.some(item => typeof item !== 'string')- I cannot find a single test in the repo that passes an array containing a non-string item to a field validated byassertOptionalStringArray. Searching for tests usingbugStatus,keywords,components,bugFields,bugSeverity,labels, andexcludePatternsonly turns up valid string arrays and "not even an array" failure cases.
The // istanbul ignore else is on the if statement, so strictly it suppresses the implicit "else" (no-throw) branch, not the OR's branch coverage. But it sits exactly where a branch is uncovered. Combined with the commit message, this strongly suggests the directive is silencing a real coverage gap: the array.some(...) arm of the OR has no test.
The runtime consequence is small but real: a regression that broke the per-item string check (for example, changing typeof item !== 'string' to typeof item === 'string', or accidentally removing the .some call) would not be caught by any existing test, and coverage would still report 100%.
Expected behavior
Either:
- Remove the
// istanbul ignore elsedirective and add a test that callsassertOptionalStringArray(or one of its callers, likenormalizeBugzillaTaskConfigwithbugStatus: ['OPEN', 42]) with an array containing a non-string item, so both arms of the OR are covered by an actual assertion, or - If the success path is the one that needs the suppression (because v8 is flagging it), explicitly justify that in a comment so future readers do not assume the directive is masking a different gap.
Minimal reproduction
import { assertOptionalStringArray } from './prompt-generators/util/config.js';
// Tests in the repo cover:
assertOptionalStringArray({ foo: 'bar' }, 'foo', 'test.foo'); // throws (first OR arm)
assertOptionalStringArray({ foo: ['a', 'b'] }, 'foo', 'test.foo'); // does not throw (else of if)
// Not covered anywhere:
assertOptionalStringArray({ foo: ['a', 42] }, 'foo', 'test.foo'); // throws (second OR arm)
Suggested fix
Remove the // istanbul ignore else line and add a unit test (or extend load-cli-config.test.ts) that exercises an array with at least one non-string element, e.g.:
it('should reject Bugzilla bugStatus arrays containing non-strings', async () => {
await expect(
normalizeCliConfig(
{
name: 'test',
agent: 'claude-sdk',
promptGenerator: [
'bugzilla',
{
search: { bugStatus: ['OPEN', 42] },
promptTemplate: 'Review {{id}}',
} as unknown as BugzillaTask,
],
},
join(configDir, 'config.json'),
),
).rejects.toThrow('bugzilla.search.bugStatus must be an array of strings');
});
Severity
S4 - cleanup with low behavioral risk. The validator works correctly today; the issue is that a future regression in the per-item type check would slip past both tests and the 100% coverage gate.
- 主要言語
- TypeScript
- スター
- 2
- フォーク
- 1
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
joewalker/loop-the-loop のほかの issue
-
bug S4
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
joewalker/loop-the-loop#88 ·
-
Git exec(): child killed by a signal rejects with new Error('') and loses the signal informationオープンbug S3
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
joewalker/loop-the-loop#84 ·
-
bug S3
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
joewalker/loop-the-loop#83 ·
-
bug S3
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
joewalker/loop-the-loop#82 ·
-
bug S4
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
joewalker/loop-the-loop#79 ·
joewalker/loop-the-loop の issue をすべて見る
似ている issue
-
[Bug]: Payment providers removed from config are never disabled in payment_provider対応中かも @medusa-os-bot が今日担当しました。 オープンtype: bug
難易度 2/5 半日 初心者へのやさしさ 82/100
medusajs/medusa#17544 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
software-mansion/argent#1651 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
lane:reliability
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
needs-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信