|
| 1 | +package parser |
| 2 | + |
| 3 | +import ( |
| 4 | + "strings" |
| 5 | + "testing" |
| 6 | +) |
| 7 | + |
| 8 | +func TestChunkOversizedLeavesSplits(t *testing.T) { |
| 9 | + // 12 words per "sentence", 5 sentences ~ 60-65 words, ~360 chars; we want |
| 10 | + // >2400 chars so build it from a longer paragraph + a colon-terminated header. |
| 11 | + header := "Securities registered pursuant to Section 12(b) of the Act: " |
| 12 | + long := strings.Repeat("alpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu ", 60) |
| 13 | + content := header + long |
| 14 | + if len(content) <= leafChunkThreshold { |
| 15 | + t.Fatalf("test setup: content must exceed threshold; got %d", len(content)) |
| 16 | + } |
| 17 | + in := []Section{{Level: 1, Title: "3M COMPANY", Content: content}} |
| 18 | + |
| 19 | + out := chunkOversizedLeaves(in) |
| 20 | + if len(out) != 1 { |
| 21 | + t.Fatalf("expected 1 top-level section, got %d", len(out)) |
| 22 | + } |
| 23 | + parent := out[0] |
| 24 | + if parent.Title != "3M COMPANY" { |
| 25 | + t.Errorf("parent title should be preserved, got %q", parent.Title) |
| 26 | + } |
| 27 | + if parent.Content != "" { |
| 28 | + t.Errorf("parent content should be cleared after splitting, got %d chars", len(parent.Content)) |
| 29 | + } |
| 30 | + if len(parent.Children) < 2 { |
| 31 | + t.Fatalf("expected multiple chunks, got %d", len(parent.Children)) |
| 32 | + } |
| 33 | + // First chunk's title should use the colon-terminated header. |
| 34 | + if !strings.HasPrefix(parent.Children[0].Title, "Securities registered pursuant to Section 12(b)") { |
| 35 | + t.Errorf("first chunk title should come from the colon header, got %q", parent.Children[0].Title) |
| 36 | + } |
| 37 | + // Every chunk's content should be non-empty and well below the original. |
| 38 | + for i, c := range parent.Children { |
| 39 | + if c.Content == "" { |
| 40 | + t.Errorf("chunk %d has empty content", i) |
| 41 | + } |
| 42 | + if len(c.Content) > leafChunkTarget*2 { |
| 43 | + t.Errorf("chunk %d larger than expected: %d chars", i, len(c.Content)) |
| 44 | + } |
| 45 | + } |
| 46 | +} |
| 47 | + |
| 48 | +func TestChunkOversizedLeavesLeavesSmallSectionsAlone(t *testing.T) { |
| 49 | + in := []Section{ |
| 50 | + {Level: 1, Title: "Intro", Content: strings.Repeat("a b c d e f ", 50)}, // ~600 chars |
| 51 | + {Level: 1, Title: "Methods", Content: strings.Repeat("x y z ", 200)}, // ~1200 chars |
| 52 | + } |
| 53 | + out := chunkOversizedLeaves(in) |
| 54 | + if len(out) != 2 { |
| 55 | + t.Fatalf("expected 2 sections preserved, got %d", len(out)) |
| 56 | + } |
| 57 | + for i, s := range out { |
| 58 | + if len(s.Children) != 0 { |
| 59 | + t.Errorf("section %d was unexpectedly split into %d children", i, len(s.Children)) |
| 60 | + } |
| 61 | + } |
| 62 | +} |
| 63 | + |
| 64 | +func TestChunkOversizedLeavesRecursesIntoInternals(t *testing.T) { |
| 65 | + bigLeaf := Section{Level: 2, Title: "Detail", Content: strings.Repeat("the quick brown fox jumps over the lazy dog ", 100)} |
| 66 | + parent := Section{Level: 1, Title: "Parent", Children: []Section{bigLeaf}} |
| 67 | + out := chunkOversizedLeaves([]Section{parent}) |
| 68 | + if len(out) != 1 || len(out[0].Children) == 0 { |
| 69 | + t.Fatalf("parent should be retained with chunked children, got %+v", out) |
| 70 | + } |
| 71 | + leaf := out[0].Children[0] |
| 72 | + if leaf.Title != "Detail" { |
| 73 | + t.Errorf("inner leaf title should be preserved, got %q", leaf.Title) |
| 74 | + } |
| 75 | + if len(leaf.Children) < 2 { |
| 76 | + t.Errorf("inner leaf should have been chunked, has %d children", len(leaf.Children)) |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +func TestDeriveChunkTitleColonHeader(t *testing.T) { |
| 81 | + got := deriveChunkTitle("Securities registered pursuant to Section 12(b) of the Act: Title of each class ...", "fallback") |
| 82 | + want := "Securities registered pursuant to Section 12(b) of the Act" |
| 83 | + if got != want { |
| 84 | + t.Errorf("colon-header title: got %q want %q", got, want) |
| 85 | + } |
| 86 | +} |
| 87 | + |
| 88 | +func TestDeriveChunkTitleFallback(t *testing.T) { |
| 89 | + if got := deriveChunkTitle("", "fb"); got != "fb" { |
| 90 | + t.Errorf("empty chunk should fall back, got %q", got) |
| 91 | + } |
| 92 | +} |
0 commit comments