From 75c1c7b9112737e4b63142d5ecb42461d0becf58 Mon Sep 17 00:00:00 2001 From: altair823 Date: Wed, 20 May 2026 14:40:37 +0000 Subject: [PATCH] test(p10-2-followup): cover tier2_shared oversize fallback with >200-line k8s ConfigMap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spec p10-2 risks section calls out "거대 ConfigMap" but no test exercised the line-window split branch of tier2_shared::push_chunks_with_oversize. This adds a 256-line ConfigMap fixture (generated inline) and asserts: - ≥2 chunks emitted (split happened), - all chunks share symbol `ConfigMap/prod/big`, - chunk_ids all distinct (id_for_chunk's #L{k} suffix disambiguation), - line ranges form a contiguous partition (prev.line_end + 1 == next.line_start). Reviewer nit #1 (PR #153 code-reviewer). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../tests/k8s_manifest_resource_v1.rs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/crates/kebab-chunk/tests/k8s_manifest_resource_v1.rs b/crates/kebab-chunk/tests/k8s_manifest_resource_v1.rs index 42625a0..d3234d7 100644 --- a/crates/kebab-chunk/tests/k8s_manifest_resource_v1.rs +++ b/crates/kebab-chunk/tests/k8s_manifest_resource_v1.rs @@ -203,3 +203,75 @@ rules: other => panic!("expected Code span, got {other:?}"), } } + +/// 200+ line resource exercises `tier2_shared::push_chunks_with_oversize`'s +/// line-window split branch. All chunks must share the same symbol +/// (`//`); their line ranges must form a contiguous +/// partition; chunk_ids must all differ (the `#L{k}` suffix on `id_for_chunk` +/// ensures uniqueness across windows). Spec p10-2 risks section explicitly +/// flags "거대 ConfigMap" — this test covers that path. +#[test] +fn k8s_oversize_splits_into_line_windows_sharing_symbol() { + // ConfigMap with 250 data keys → ~256 total lines, > AST_CHUNK_MAX_LINES (200). + let mut yaml = String::from( + "apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: big\n namespace: prod\ndata:\n", + ); + for i in 0..250 { + yaml.push_str(&format!(" key{i}: value{i}\n")); + } + + let doc = yaml_doc(&yaml); + let chunks = K8sManifestResourceV1Chunker + .chunk(&doc, &policy()) + .expect("chunk"); + + assert!( + chunks.len() >= 2, + "expected ≥2 chunks for oversize resource, got {}", + chunks.len() + ); + + // Every chunk must share the same symbol + lang. + let expected_symbol = "ConfigMap/prod/big"; + for (i, c) in chunks.iter().enumerate() { + match &c.source_spans[0] { + SourceSpan::Code { symbol, lang, .. } => { + assert_eq!( + symbol.as_deref(), + Some(expected_symbol), + "chunk[{i}] symbol must equal `{expected_symbol}`" + ); + assert_eq!(lang.as_deref(), Some("yaml")); + } + other => panic!("chunk[{i}]: expected Code span, got {other:?}"), + } + } + + // chunk_ids must all be distinct (oversize fallback's #L{k} suffix). + let ids: std::collections::HashSet<_> = chunks.iter().map(|c| c.chunk_id.clone()).collect(); + assert_eq!( + ids.len(), + chunks.len(), + "oversize chunks must have distinct chunk_ids (the #L{{k}} suffix should disambiguate)" + ); + + // Line ranges must form a contiguous partition: chunk[i].line_end + 1 == chunk[i+1].line_start. + let ranges: Vec<(u32, u32)> = chunks + .iter() + .map(|c| match &c.source_spans[0] { + SourceSpan::Code { line_start, line_end, .. } => (*line_start, *line_end), + other => panic!("expected Code span, got {other:?}"), + }) + .collect(); + for w in ranges.windows(2) { + let (_, prev_end) = w[0]; + let (next_start, _) = w[1]; + assert_eq!( + prev_end + 1, + next_start, + "line ranges must be contiguous: {} → {} (got gap or overlap)", + prev_end, + next_start + ); + } +}