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
41 changes: 41 additions & 0 deletions internal/truncate/fallback.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package truncate

import (
"strings"
)

// FallbackLanguage provides line-based truncation for unknown or unsupported languages.
// It treats the entire file as a single block and provides no import detection.
// This ensures graceful degradation when language-specific parsing is unavailable.
type FallbackLanguage struct{}

// DetectImportEnd returns 0 for fallback as there's no language-specific import detection.
// The fallback treats the entire file uniformly without distinguishing imports.
func (f FallbackLanguage) DetectImportEnd(lines []string) int {
return 0
}

// DetectBlocks returns the entire content as a single block.
// Since we don't understand the language structure, we treat everything as one unit.
// This allows line-based truncation while maintaining the Block interface contract.
func (f FallbackLanguage) DetectBlocks(content string) []Block {
if content == "" {
return []Block{}
}

lines := strings.Split(content, "\n")
return []Block{
{
Type: "block",
Name: "",
StartLine: 0,
EndLine: len(lines) - 1,
},
}
}

// CommentSyntax returns no comment syntax for fallback.
// Truncation indicators will use plaintext format without comment markers.
func (f FallbackLanguage) CommentSyntax() (single string, multiOpen string, multiClose string) {
return "", "", ""
}
143 changes: 143 additions & 0 deletions internal/truncate/fallback_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package truncate

import (
"testing"
)

func TestFallbackLanguage_DetectImportEnd(t *testing.T) {
fb := FallbackLanguage{}

tests := []struct {
name string
lines []string
want int
}{
{
name: "empty file",
lines: []string{},
want: 0,
},
{
name: "single line",
lines: []string{"line1"},
want: 0,
},
{
name: "multiple lines",
lines: []string{
"import something",
"",
"code here",
},
want: 0,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := fb.DetectImportEnd(tt.lines)
if got != tt.want {
t.Errorf("DetectImportEnd() = %d, want %d", got, tt.want)
}
})
}
}

func TestFallbackLanguage_DetectBlocks(t *testing.T) {
fb := FallbackLanguage{}

tests := []struct {
name string
content string
want []Block
}{
{
name: "empty content",
content: "",
want: []Block{},
},
{
name: "single line",
content: "single line",
want: []Block{
{
Type: "block",
Name: "",
StartLine: 0,
EndLine: 0,
},
},
},
{
name: "multiple lines",
content: "line1\nline2\nline3",
want: []Block{
{
Type: "block",
Name: "",
StartLine: 0,
EndLine: 2,
},
},
},
{
name: "content with trailing newline",
content: "line1\nline2\n",
want: []Block{
{
Type: "block",
Name: "",
StartLine: 0,
EndLine: 2,
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := fb.DetectBlocks(tt.content)

if len(got) != len(tt.want) {
t.Errorf("DetectBlocks() returned %d blocks, want %d", len(got), len(tt.want))
return
}

for i := range got {
if got[i].Type != tt.want[i].Type {
t.Errorf("block[%d].Type = %q, want %q", i, got[i].Type, tt.want[i].Type)
}
if got[i].Name != tt.want[i].Name {
t.Errorf("block[%d].Name = %q, want %q", i, got[i].Name, tt.want[i].Name)
}
if got[i].StartLine != tt.want[i].StartLine {
t.Errorf("block[%d].StartLine = %d, want %d", i, got[i].StartLine, tt.want[i].StartLine)
}
if got[i].EndLine != tt.want[i].EndLine {
t.Errorf("block[%d].EndLine = %d, want %d", i, got[i].EndLine, tt.want[i].EndLine)
}
}
})
}
}

func TestFallbackLanguage_CommentSyntax(t *testing.T) {
fb := FallbackLanguage{}

single, multiOpen, multiClose := fb.CommentSyntax()

if single != "" {
t.Errorf("CommentSyntax() single = %q, want empty string", single)
}
if multiOpen != "" {
t.Errorf("CommentSyntax() multiOpen = %q, want empty string", multiOpen)
}
if multiClose != "" {
t.Errorf("CommentSyntax() multiClose = %q, want empty string", multiClose)
}
}

func TestFallbackLanguage_ImplementsInterface(t *testing.T) {
// Compile-time check that FallbackLanguage implements Language
var _ Language = FallbackLanguage{}
}
Loading
Loading