mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
193 lines
3.7 KiB
Go
193 lines
3.7 KiB
Go
package levenshtein_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/coder/coder/v2/cli/cliutil/levenshtein"
|
|
)
|
|
|
|
func Test_Levenshtein_Matches(t *testing.T) {
|
|
t.Parallel()
|
|
for _, tt := range []struct {
|
|
Name string
|
|
Needle string
|
|
MaxDistance int
|
|
Haystack []string
|
|
Expected []string
|
|
}{
|
|
{
|
|
Name: "empty",
|
|
Needle: "",
|
|
MaxDistance: 0,
|
|
Haystack: []string{},
|
|
Expected: []string{},
|
|
},
|
|
{
|
|
Name: "empty haystack",
|
|
Needle: "foo",
|
|
MaxDistance: 0,
|
|
Haystack: []string{},
|
|
Expected: []string{},
|
|
},
|
|
{
|
|
Name: "empty needle",
|
|
Needle: "",
|
|
MaxDistance: 0,
|
|
Haystack: []string{"foo"},
|
|
Expected: []string{},
|
|
},
|
|
{
|
|
Name: "exact match distance 0",
|
|
Needle: "foo",
|
|
MaxDistance: 0,
|
|
Haystack: []string{"foo", "fob"},
|
|
Expected: []string{"foo"},
|
|
},
|
|
{
|
|
Name: "exact match distance 1",
|
|
Needle: "foo",
|
|
MaxDistance: 1,
|
|
Haystack: []string{"foo", "bar"},
|
|
Expected: []string{"foo"},
|
|
},
|
|
{
|
|
Name: "not found",
|
|
Needle: "foo",
|
|
MaxDistance: 1,
|
|
Haystack: []string{"bar"},
|
|
Expected: []string{},
|
|
},
|
|
{
|
|
Name: "1 deletion",
|
|
Needle: "foo",
|
|
MaxDistance: 1,
|
|
Haystack: []string{"bar", "fo"},
|
|
Expected: []string{"fo"},
|
|
},
|
|
{
|
|
Name: "one deletion, two matches",
|
|
Needle: "foo",
|
|
MaxDistance: 1,
|
|
Haystack: []string{"bar", "fo", "fou"},
|
|
Expected: []string{"fo", "fou"},
|
|
},
|
|
{
|
|
Name: "one deletion, one addition",
|
|
Needle: "foo",
|
|
MaxDistance: 1,
|
|
Haystack: []string{"bar", "fo", "fou", "f"},
|
|
Expected: []string{"fo", "fou"},
|
|
},
|
|
{
|
|
Name: "distance 2",
|
|
Needle: "foo",
|
|
MaxDistance: 2,
|
|
Haystack: []string{"bar", "boo", "boof"},
|
|
Expected: []string{"boo", "boof"},
|
|
},
|
|
{
|
|
Name: "longer input",
|
|
Needle: "kuberenetes",
|
|
MaxDistance: 5,
|
|
Haystack: []string{"kubernetes", "kubeconfig", "kubectl", "kube"},
|
|
Expected: []string{"kubernetes"},
|
|
},
|
|
} {
|
|
t.Run(tt.Name, func(t *testing.T) {
|
|
t.Parallel()
|
|
actual := levenshtein.Matches(tt.Needle, tt.MaxDistance, tt.Haystack...)
|
|
require.ElementsMatch(t, tt.Expected, actual)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_Levenshtein_Distance(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
for _, tt := range []struct {
|
|
Name string
|
|
A string
|
|
B string
|
|
MaxDist int
|
|
Expected int
|
|
Error string
|
|
}{
|
|
{
|
|
Name: "empty",
|
|
A: "",
|
|
B: "",
|
|
MaxDist: -1,
|
|
Expected: 0,
|
|
},
|
|
{
|
|
Name: "a empty",
|
|
A: "",
|
|
B: "foo",
|
|
MaxDist: -1,
|
|
Expected: 3,
|
|
},
|
|
{
|
|
Name: "b empty",
|
|
A: "foo",
|
|
B: "",
|
|
MaxDist: -1,
|
|
Expected: 3,
|
|
},
|
|
{
|
|
Name: "a is b",
|
|
A: "foo",
|
|
B: "foo",
|
|
MaxDist: -1,
|
|
Expected: 0,
|
|
},
|
|
{
|
|
Name: "one addition",
|
|
A: "foo",
|
|
B: "fooo",
|
|
MaxDist: -1,
|
|
Expected: 1,
|
|
},
|
|
{
|
|
Name: "one deletion",
|
|
A: "fooo",
|
|
B: "foo",
|
|
MaxDist: -1,
|
|
Expected: 1,
|
|
},
|
|
{
|
|
Name: "one substitution",
|
|
A: "foo",
|
|
B: "fou",
|
|
MaxDist: -1,
|
|
Expected: 1,
|
|
},
|
|
{
|
|
Name: "different strings entirely",
|
|
A: "foo",
|
|
B: "bar",
|
|
MaxDist: -1,
|
|
Expected: 3,
|
|
},
|
|
{
|
|
Name: "different strings, max distance 2",
|
|
A: "foo",
|
|
B: "bar",
|
|
MaxDist: 2,
|
|
Error: levenshtein.ErrMaxDist.Error(),
|
|
},
|
|
} {
|
|
t.Run(tt.Name, func(t *testing.T) {
|
|
t.Parallel()
|
|
actual, err := levenshtein.Distance(tt.A, tt.B, tt.MaxDist)
|
|
if tt.Error == "" {
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.Expected, actual)
|
|
} else {
|
|
require.EqualError(t, err, tt.Error)
|
|
}
|
|
})
|
|
}
|
|
}
|