zclsyntax: "Did you mean ...?" helper function
This commit is contained in:
parent
31caa36b9a
commit
8437058b60
24
zcl/zclsyntax/didyoumean.go
Normal file
24
zcl/zclsyntax/didyoumean.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package zclsyntax
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/agext/levenshtein"
|
||||||
|
)
|
||||||
|
|
||||||
|
// nameSuggestion tries to find a name from the given slice of suggested names
|
||||||
|
// that is close to the given name and returns it if found. If no suggestion
|
||||||
|
// is close enough, returns the empty string.
|
||||||
|
//
|
||||||
|
// The suggestions are tried in order, so earlier suggestions take precedence
|
||||||
|
// if the given string is similar to two or more suggestions.
|
||||||
|
//
|
||||||
|
// This function is intended to be used with a relatively-small number of
|
||||||
|
// suggestions. It's not optimized for hundreds or thousands of them.
|
||||||
|
func nameSuggestion(given string, suggestions []string) string {
|
||||||
|
for _, suggestion := range suggestions {
|
||||||
|
dist := levenshtein.Distance(given, suggestion, nil)
|
||||||
|
if dist < 3 { // threshold determined experimentally
|
||||||
|
return suggestion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
51
zcl/zclsyntax/didyoumean_test.go
Normal file
51
zcl/zclsyntax/didyoumean_test.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package zclsyntax
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestNameSuggestion(t *testing.T) {
|
||||||
|
var keywords = []string{"false", "true", "null"}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
Input, Want string
|
||||||
|
}{
|
||||||
|
{"true", "true"},
|
||||||
|
{"false", "false"},
|
||||||
|
{"null", "null"},
|
||||||
|
{"bananas", ""},
|
||||||
|
{"NaN", ""},
|
||||||
|
{"Inf", ""},
|
||||||
|
{"Infinity", ""},
|
||||||
|
{"void", ""},
|
||||||
|
{"undefined", ""},
|
||||||
|
|
||||||
|
{"ture", "true"},
|
||||||
|
{"tru", "true"},
|
||||||
|
{"tre", "true"},
|
||||||
|
{"treu", "true"},
|
||||||
|
{"rtue", "true"},
|
||||||
|
|
||||||
|
{"flase", "false"},
|
||||||
|
{"fales", "false"},
|
||||||
|
{"flse", "false"},
|
||||||
|
{"fasle", "false"},
|
||||||
|
{"fasel", "false"},
|
||||||
|
{"flue", "false"},
|
||||||
|
|
||||||
|
{"nil", "null"},
|
||||||
|
{"nul", "null"},
|
||||||
|
{"unll", "null"},
|
||||||
|
{"nll", "null"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.Input, func(t *testing.T) {
|
||||||
|
got := nameSuggestion(test.Input, keywords)
|
||||||
|
if got != test.Want {
|
||||||
|
t.Errorf(
|
||||||
|
"wrong result\ninput: %q\ngot: %q\nwant: %q",
|
||||||
|
test.Input, got, test.Want,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user