1package closestmatch
2
3import (
4	"fmt"
5	"io/ioutil"
6	"strings"
7	"testing"
8
9	"github.com/schollz/closestmatch/test"
10)
11
12func BenchmarkNew(b *testing.B) {
13	for i := 0; i < b.N; i++ {
14		New(test.WordsToTest, []int{3})
15	}
16}
17
18func BenchmarkSplitOne(b *testing.B) {
19	cm := New(test.WordsToTest, []int{3})
20	searchWord := test.SearchWords[0]
21	b.ResetTimer()
22	for i := 0; i < b.N; i++ {
23		cm.splitWord(searchWord)
24	}
25}
26
27func BenchmarkClosestOne(b *testing.B) {
28	bText, _ := ioutil.ReadFile("test/books.list")
29	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
30	cm := New(wordsToTest, []int{3})
31	searchWord := test.SearchWords[0]
32	b.ResetTimer()
33	for i := 0; i < b.N; i++ {
34		cm.Closest(searchWord)
35	}
36}
37
38func BenchmarkClosest3(b *testing.B) {
39	bText, _ := ioutil.ReadFile("test/books.list")
40	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
41	cm := New(wordsToTest, []int{3})
42	searchWord := test.SearchWords[0]
43	b.ResetTimer()
44	for i := 0; i < b.N; i++ {
45		cm.ClosestN(searchWord, 3)
46	}
47}
48
49func BenchmarkClosest30(b *testing.B) {
50	bText, _ := ioutil.ReadFile("test/books.list")
51	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
52	cm := New(wordsToTest, []int{3})
53	searchWord := test.SearchWords[0]
54	b.ResetTimer()
55	for i := 0; i < b.N; i++ {
56		cm.ClosestN(searchWord, 30)
57	}
58}
59
60func BenchmarkFileLoad(b *testing.B) {
61	bText, _ := ioutil.ReadFile("test/books.list")
62	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
63	cm := New(wordsToTest, []int{3, 4})
64	cm.Save("test/books.list.cm.gz")
65	b.ResetTimer()
66	for i := 0; i < b.N; i++ {
67		Load("test/books.list.cm.gz")
68	}
69}
70
71func BenchmarkFileSave(b *testing.B) {
72	bText, _ := ioutil.ReadFile("test/books.list")
73	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
74	cm := New(wordsToTest, []int{3, 4})
75	b.ResetTimer()
76	for i := 0; i < b.N; i++ {
77		cm.Save("test/books.list.cm.gz")
78	}
79}
80
81func ExampleMatchingSmall() {
82	cm := New([]string{"love", "loving", "cat", "kit", "cats"}, []int{4})
83	fmt.Println(cm.splitWord("love"))
84	fmt.Println(cm.splitWord("kit"))
85	fmt.Println(cm.Closest("kit"))
86	// Output:
87	// map[love:{}]
88	// map[kit:{}]
89	// kit
90
91}
92
93func ExampleMatchingSimple() {
94	cm := New(test.WordsToTest, []int{3})
95	for _, searchWord := range test.SearchWords {
96		fmt.Printf("'%s' matched '%s'\n", searchWord, cm.Closest(searchWord))
97	}
98	// Output:
99	// 'cervantes don quixote' matched 'don quixote by miguel de cervantes saavedra'
100	// 'mysterious afur at styles by christie' matched 'the mysterious affair at styles by agatha christie'
101	// 'hard times by charles dickens' matched 'hard times by charles dickens'
102	// 'complete william shakespeare' matched 'the complete works of william shakespeare by william shakespeare'
103	// 'war by hg wells' matched 'the war of the worlds by h. g. wells'
104
105}
106
107func ExampleMatchingN() {
108	cm := New(test.WordsToTest, []int{4})
109	fmt.Println(cm.ClosestN("war h.g. wells", 3))
110	// Output:
111	// [the war of the worlds by h. g. wells the time machine by h. g. wells war and peace by graf leo tolstoy]
112}
113
114func ExampleMatchingBigList() {
115	bText, _ := ioutil.ReadFile("test/books.list")
116	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
117	cm := New(wordsToTest, []int{3})
118	searchWord := "island of a thod mirrors"
119	fmt.Println(cm.Closest(searchWord))
120	// Output:
121	// island of a thousand mirrors by nayomi munaweera
122}
123
124func ExampleMatchingCatcher() {
125	bText, _ := ioutil.ReadFile("test/catcher.txt")
126	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
127	cm := New(wordsToTest, []int{5})
128	searchWord := "catcher in the rye by jd salinger"
129	for i, match := range cm.ClosestN(searchWord, 3) {
130		if i == 2 {
131			fmt.Println(match)
132		}
133	}
134	// Output:
135	// the catcher in the rye by j.d. salinger
136}
137
138func ExampleMatchingPotter() {
139	bText, _ := ioutil.ReadFile("test/potter.txt")
140	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
141	cm := New(wordsToTest, []int{5})
142	searchWord := "harry potter and the half blood prince by j.k. rowling"
143	for i, match := range cm.ClosestN(searchWord, 3) {
144		if i == 1 {
145			fmt.Println(match)
146		}
147	}
148	// Output:
149	//  harry potter and the order of the phoenix (harry potter, #5, part 1) by j.k. rowling
150}
151
152func TestAccuracyBookWords(t *testing.T) {
153	bText, _ := ioutil.ReadFile("test/books.list")
154	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
155	cm := New(wordsToTest, []int{4, 5})
156	accuracy := cm.AccuracyMutatingWords()
157	fmt.Printf("Accuracy with mutating words in book list:\t%2.1f%%\n", accuracy)
158}
159
160func TestAccuracyBookLetters(t *testing.T) {
161	bText, _ := ioutil.ReadFile("test/books.list")
162	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
163	cm := New(wordsToTest, []int{5})
164	accuracy := cm.AccuracyMutatingLetters()
165	fmt.Printf("Accuracy with mutating letters in book list:\t%2.1f%%\n", accuracy)
166}
167
168func TestAccuracyDictionaryLetters(t *testing.T) {
169	bText, _ := ioutil.ReadFile("test/popular.txt")
170	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
171	cm := New(wordsToTest, []int{2, 3, 4})
172	accuracy := cm.AccuracyMutatingWords()
173	fmt.Printf("Accuracy with mutating letters in dictionary:\t%2.1f%%\n", accuracy)
174}
175
176func TestSaveLoad(t *testing.T) {
177	bText, _ := ioutil.ReadFile("test/books.list")
178	wordsToTest := strings.Split(strings.ToLower(string(bText)), "\n")
179	type TestStruct struct {
180		cm *ClosestMatch
181	}
182	tst := new(TestStruct)
183	tst.cm = New(wordsToTest, []int{5})
184	err := tst.cm.Save("test.gob")
185	if err != nil {
186		t.Error(err)
187	}
188
189	tst2 := new(TestStruct)
190	tst2.cm, err = Load("test.gob")
191	if err != nil {
192		t.Error(err)
193	}
194	answer2 := tst2.cm.Closest("war of the worlds by hg wells")
195	answer1 := tst.cm.Closest("war of the worlds by hg wells")
196	if answer1 != answer2 {
197		t.Errorf("Differing answers: '%s' '%s'", answer1, answer2)
198	}
199}
200