Skip to content

Commit fbc7439

Browse files
committed
Fixed arg parsing and added tests
1 parent 0f2241a commit fbc7439

File tree

2 files changed

+86
-7
lines changed

2 files changed

+86
-7
lines changed

process.go

+15-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package fuzzy
22

33
import (
44
"errors"
5+
"fmt"
56
"sort"
67
)
78

@@ -65,7 +66,11 @@ func ExtractWithoutOrder(query string, choices []string, args ...interface{}) (M
6566
}
6667
scoreCutoff := 0
6768

68-
opts, _ := parseArgs(args)
69+
opts, err := parseArgs(args...)
70+
if err != nil {
71+
return nil, err
72+
}
73+
6974
if opts.scorerSet {
7075
scorer = opts.scorer
7176
}
@@ -103,14 +108,16 @@ func parseArgs(args ...interface{}) (*optionalArgs, error) {
103108
processorSet, scorerSet, cutoffSet := false, false, false
104109

105110
for _, arg := range args {
106-
switch arg.(type) {
111+
switch v := arg.(type) {
112+
default:
113+
return nil, fmt.Errorf("not expecting optional argument of type %T", v)
107114
case func(string) string:
108115
if processorSet {
109116
return nil, errors.New("expecting only one processing function of the form f(string)->string")
110117
}
111118
processor = arg.(func(string) string)
112119
processorSet = true
113-
case func(string) int:
120+
case func(string, string) int:
114121
if scorerSet {
115122
return nil, errors.New("expecting only one scoring function of the form f(string,string)->int")
116123
}
@@ -121,7 +128,9 @@ func parseArgs(args ...interface{}) (*optionalArgs, error) {
121128
return nil, errors.New("expecting only one integer scoring cutoff")
122129
}
123130
scoreCutoff = arg.(int)
131+
cutoffSet = true
124132
}
133+
125134
}
126135
opts := new(optionalArgs)
127136
opts.processor = processor
@@ -134,7 +143,7 @@ func parseArgs(args ...interface{}) (*optionalArgs, error) {
134143
}
135144

136145
func Extract(query string, choices []string, limit int, args ...interface{}) (MatchPairs, error) {
137-
pairs, err := ExtractWithoutOrder(query, choices, args)
146+
pairs, err := ExtractWithoutOrder(query, choices, args...)
138147
if err != nil {
139148
return nil, err
140149
}
@@ -143,7 +152,7 @@ func Extract(query string, choices []string, limit int, args ...interface{}) (Ma
143152
}
144153

145154
func ExtractOne(query string, choices []string, args ...interface{}) (*MatchPair, error) {
146-
matches, err := ExtractWithoutOrder(query, choices, args)
155+
matches, err := ExtractWithoutOrder(query, choices, args...)
147156
if err != nil {
148157
return nil, err
149158
}
@@ -203,7 +212,7 @@ func Dedupe(sliceWithDupes []string, args ...interface{}) ([]string, error) {
203212
case 1:
204213
s, err := arg.(func(string, string) int)
205214
if err {
206-
return nil, errors.New("Expected second optional argument to be a function of the form f(string,string)->int")
215+
return nil, errors.New("expected second optional argument to be a function of the form f(string,string)->int")
207216
}
208217
scorer = s
209218
}

process_test.go

+71-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,23 @@ var baseballStrings = []string{
1111
"braves vs mets",
1212
}
1313

14+
var moreBaseballStrings = []string{
15+
"new york mets vs chicago cubs",
16+
"chicago cubs at new york mets",
17+
"atlanta braves vs pittsbugh pirates",
18+
"new york yankees vs boston red sox",
19+
}
20+
21+
var someEmptyStrings = []string{
22+
"",
23+
"new york mets vs chicago cubs",
24+
"new york yankees vs boston red sox",
25+
"",
26+
"",
27+
}
28+
29+
var someNullStrings = []string{}
30+
1431
func TestExtractOne(t *testing.T) {
1532
query1 := "new york mets at atlanta braves"
1633
best1, _ := ExtractOne(query1, baseballStrings)
@@ -37,10 +54,63 @@ func TestExtractOne(t *testing.T) {
3754
}
3855
best6, _ := ExtractOne(query5, baseballStrings, customScorer)
3956
assertMatch(t, query5, baseballStrings[0], best6.Match)
57+
58+
query7 := "los angeles dodgers vs san francisco giants"
59+
scoreCutoff := 50
60+
best7, _ := ExtractOne(query7, moreBaseballStrings, scoreCutoff)
61+
if best7 != nil {
62+
t.Error("expecting to find no matches")
63+
}
64+
65+
query8 := "new york mets vs chicago cubs"
66+
scoreCutoff = 100
67+
best8, _ := ExtractOne(query8, moreBaseballStrings, scoreCutoff)
68+
if best8 == nil {
69+
t.Error("expecting to find a match")
70+
}
71+
72+
query9 := "new york mets at chicago cubs"
73+
best9, _ := ExtractOne(query9, someEmptyStrings)
74+
assertMatch(t, query9, someEmptyStrings[1], best9.Match)
75+
76+
query10 := "a, b"
77+
choices := []string{query10}
78+
expectedResult := new(MatchPair)
79+
expectedResult.Match = query10
80+
expectedResult.Score = 100
81+
customScorer = func(s1, s2 string) int {
82+
return Ratio(s1, s2)
83+
}
84+
partialScorer := func(s1, s2 string) int {
85+
return PartialRatio(s1, s2)
86+
}
87+
88+
res, _ := ExtractOne(query10, choices, customScorer)
89+
partialRes, _ := ExtractOne(query10, choices, partialScorer)
90+
if *res != *expectedResult {
91+
t.Error("simple match failed")
92+
}
93+
if *partialRes != *expectedResult {
94+
t.Error("simple partial match failed")
95+
}
96+
}
97+
98+
func TestDedupe(t *testing.T) {
99+
sliceWithDupes := []string{"Frodo Baggins", "Tom Sawyer", "Bilbo Baggin", "Samuel L. Jackson", "F. Baggins", "Frody Baggins", "Bilbo Baggins"}
100+
res, _ := Dedupe(sliceWithDupes)
101+
if len(res) >= len(sliceWithDupes) {
102+
t.Error("expecting Dedupe to remove at least one string from slice")
103+
}
104+
105+
sliceWithoutDupes := []string{"Tom", "Dick", "Harry"}
106+
res2, _ := Dedupe(sliceWithoutDupes)
107+
if len(res2) != len(sliceWithoutDupes) {
108+
t.Error("not expecting Dedupe to remove any strings from slice")
109+
}
40110
}
41111

42112
func assertMatch(t *testing.T, query, expectedMatch, actualMatch string) {
43113
if expectedMatch != actualMatch {
44-
t.Errorf("Expecting [%v] to find match of [%v]. Actual match: [%v]", query, expectedMatch, actualMatch)
114+
t.Errorf("expecting [%v] to find match of [%v], actual match was [%v]", query, expectedMatch, actualMatch)
45115
}
46116
}

0 commit comments

Comments
 (0)