mirror of
https://github.com/turbot/steampipe.git
synced 2026-03-21 16:00:13 -04:00
240 lines
4.6 KiB
Go
240 lines
4.6 KiB
Go
package interactive
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/alecthomas/chroma/formatters"
|
|
"github.com/alecthomas/chroma/lexers"
|
|
"github.com/alecthomas/chroma/styles"
|
|
"github.com/c-bata/go-prompt"
|
|
)
|
|
|
|
// TestNewHighlighter tests highlighter creation
|
|
func TestNewHighlighter(t *testing.T) {
|
|
lexer := lexers.Get("sql")
|
|
formatter := formatters.Get("terminal256")
|
|
style := styles.Native
|
|
|
|
h := newHighlighter(lexer, formatter, style)
|
|
|
|
if h == nil {
|
|
t.Fatal("newHighlighter returned nil")
|
|
}
|
|
|
|
if h.lexer == nil {
|
|
t.Error("highlighter lexer is nil")
|
|
}
|
|
|
|
if h.formatter == nil {
|
|
t.Error("highlighter formatter is nil")
|
|
}
|
|
|
|
if h.style == nil {
|
|
t.Error("highlighter style is nil")
|
|
}
|
|
}
|
|
|
|
// TestHighlighterHighlight tests the Highlight function
|
|
func TestHighlighterHighlight(t *testing.T) {
|
|
h := newHighlighter(
|
|
lexers.Get("sql"),
|
|
formatters.Get("terminal256"),
|
|
styles.Native,
|
|
)
|
|
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "simple select",
|
|
input: "SELECT * FROM users",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "empty string",
|
|
input: "",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "multiline query",
|
|
input: "SELECT *\nFROM users\nWHERE id = 1",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "unicode characters",
|
|
input: "SELECT '你好世界'",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "emoji",
|
|
input: "SELECT '🔥💥✨'",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "null bytes",
|
|
input: "SELECT '\x00'",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "control characters",
|
|
input: "SELECT '\n\r\t'",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "very long query",
|
|
input: "SELECT " + strings.Repeat("a, ", 1000) + "* FROM users",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "SQL injection attempt",
|
|
input: "'; DROP TABLE users; --",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "malformed SQL",
|
|
input: "SELECT FROM WHERE",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "special characters",
|
|
input: "SELECT '\\', '/', '\"', '`'",
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
doc := prompt.Document{
|
|
Text: tt.input,
|
|
}
|
|
|
|
result, err := h.Highlight(doc)
|
|
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("Highlight() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
|
|
if !tt.wantErr && result == nil {
|
|
t.Error("Highlight() returned nil result without error")
|
|
}
|
|
|
|
// Verify result is not empty for non-empty input
|
|
if !tt.wantErr && tt.input != "" && len(result) == 0 {
|
|
t.Error("Highlight() returned empty result for non-empty input")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestGetHighlighter tests the getHighlighter function
|
|
func TestGetHighlighter(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
theme string
|
|
}{
|
|
{
|
|
name: "default theme",
|
|
theme: "",
|
|
},
|
|
{
|
|
name: "dark theme",
|
|
theme: "dark",
|
|
},
|
|
{
|
|
name: "light theme",
|
|
theme: "light",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
h := getHighlighter(tt.theme)
|
|
|
|
if h == nil {
|
|
t.Fatal("getHighlighter returned nil")
|
|
}
|
|
|
|
if h.lexer == nil {
|
|
t.Error("highlighter lexer is nil")
|
|
}
|
|
|
|
if h.formatter == nil {
|
|
t.Error("highlighter formatter is nil")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestHighlighterConcurrency tests concurrent highlighting
|
|
func TestHighlighterConcurrency(t *testing.T) {
|
|
h := newHighlighter(
|
|
lexers.Get("sql"),
|
|
formatters.Get("terminal256"),
|
|
styles.Native,
|
|
)
|
|
|
|
queries := []string{
|
|
"SELECT * FROM users",
|
|
"SELECT id FROM posts",
|
|
"SELECT name FROM companies",
|
|
}
|
|
|
|
done := make(chan bool)
|
|
|
|
for i := 0; i < 10; i++ {
|
|
go func(idx int) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Errorf("Concurrent Highlight panicked: %v", r)
|
|
}
|
|
done <- true
|
|
}()
|
|
|
|
doc := prompt.Document{
|
|
Text: queries[idx%len(queries)],
|
|
}
|
|
|
|
_, err := h.Highlight(doc)
|
|
if err != nil {
|
|
t.Errorf("Concurrent Highlight error: %v", err)
|
|
}
|
|
}(i)
|
|
}
|
|
|
|
// Wait for all goroutines
|
|
for i := 0; i < 10; i++ {
|
|
<-done
|
|
}
|
|
}
|
|
|
|
// TestHighlighterMemoryLeak tests for memory leaks with repeated highlighting
|
|
func TestHighlighterMemoryLeak(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping memory leak test in short mode")
|
|
}
|
|
|
|
h := newHighlighter(
|
|
lexers.Get("sql"),
|
|
formatters.Get("terminal256"),
|
|
styles.Native,
|
|
)
|
|
|
|
// Highlight the same query many times to check for memory leaks
|
|
doc := prompt.Document{
|
|
Text: "SELECT * FROM users WHERE id = 1",
|
|
}
|
|
|
|
for i := 0; i < 10000; i++ {
|
|
_, err := h.Highlight(doc)
|
|
if err != nil {
|
|
t.Fatalf("Highlight failed at iteration %d: %v", i, err)
|
|
}
|
|
}
|
|
|
|
// If we get here without OOM, the test passes
|
|
}
|