Skip to content

Commit

Permalink
Add command suggestion tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mfridman committed Dec 27, 2024
1 parent c5cb6c4 commit 7cabe13
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 7 deletions.
11 changes: 4 additions & 7 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"flag"
"fmt"
"slices"
"sort"
"strings"
)

Expand Down Expand Up @@ -291,13 +292,9 @@ func (c *Command) getSuggestions(unknownCmd string) []string {
}
}
// Sort suggestions by score (highest first)
for i := 0; i < len(suggestions)-1; i++ {
for j := i + 1; j < len(suggestions); j++ {
if suggestions[j].score > suggestions[i].score {
suggestions[i], suggestions[j] = suggestions[j], suggestions[i]
}
}
}
sort.Slice(suggestions, func(i, j int) bool {
return suggestions[i].score > suggestions[j].score
})
// Get top 3 suggestions
maxSuggestions := 3
result := make([]string, 0, maxSuggestions)
Expand Down
184 changes: 184 additions & 0 deletions command_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package cli

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestCalculateSimilarity(t *testing.T) {
tests := []struct {
name string
a string
b string
expected float64
}{
{
name: "perfect match",
a: "hello",
b: "hello",
expected: 1.0,
},
{
name: "perfect match with different case",
a: "Hello",
b: "hello",
expected: 1.0,
},
{
name: "prefix match",
a: "hel",
b: "hello",
expected: 0.9,
},
{
name: "one character difference",
a: "hello",
b: "hello1",
expected: 0.9, // prefix match case
},
{
name: "completely different strings",
a: "hello",
b: "world",
expected: 0.2, // Based on Levenshtein distance of 4 with max length 5
},
{
name: "empty strings",
a: "",
b: "",
expected: 1.0,
},
{
name: "one empty string",
a: "hello",
b: "",
expected: 0.0,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := calculateSimilarity(tt.a, tt.b)
assert.InDelta(t, tt.expected, result, 0.001, "similarity mismatch for %q and %q", tt.a, tt.b)
})
}
}

func TestLevenshteinDistance(t *testing.T) {
tests := []struct {
name string
a string
b string
expected int
}{
{
name: "identical strings",
a: "hello",
b: "hello",
expected: 0,
},
{
name: "one character difference",
a: "hello",
b: "hallo",
expected: 1,
},
{
name: "addition",
a: "hello",
b: "hello1",
expected: 1,
},
{
name: "deletion",
a: "hello",
b: "hell",
expected: 1,
},
{
name: "empty first string",
a: "",
b: "hello",
expected: 5,
},
{
name: "empty second string",
a: "hello",
b: "",
expected: 5,
},
{
name: "both empty strings",
a: "",
b: "",
expected: 0,
},
{
name: "completely different strings",
a: "hello",
b: "world",
expected: 4,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := levenshteinDistance(tt.a, tt.b)
assert.Equal(t, tt.expected, result, "distance mismatch for %q and %q", tt.a, tt.b)
})
}
}

func TestWrapText(t *testing.T) {
tests := []struct {
name string
text string
width int
expected []string
}{
{
name: "simple wrap",
text: "hello world",
width: 5,
expected: []string{"hello", "world"},
},
{
name: "no wrap needed",
text: "hello",
width: 10,
expected: []string{"hello"},
},
{
name: "multiple wraps",
text: "this is a long text that needs wrapping",
width: 10,
expected: []string{"this is a", "long text", "that needs", "wrapping"},
},
{
name: "empty string",
text: "",
width: 10,
expected: nil,
},
{
name: "single word longer than width",
text: "supercalifragilistic",
width: 10,
expected: []string{"supercalifragilistic"},
},
{
name: "multiple spaces",
text: "hello world",
width: 20,
expected: []string{"hello world"},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := wrapText(tt.text, tt.width)
assert.EqualValues(t, tt.expected, result, "wrapped text mismatch for input %q with width %d", tt.text, tt.width)
})
}
}

0 comments on commit 7cabe13

Please sign in to comment.