1from RLTest import Env
2from includes import *
3from common import waitForIndex
4
5
6def testDictAdd():
7    env = Env()
8    env.expect('ft.dictadd', 'dict', 'term1', 'term2', 'term3').equal(3)
9    env.expect('ft.dictadd', 'dict', 'term1', 'term2', 'term4').equal(1)
10
11
12def testDictAddWrongArity():
13    env = Env()
14    env.expect('ft.dictadd', 'dict').raiseError()
15
16
17def testDictDelete():
18    env = Env()
19    env.expect('ft.dictadd', 'dict', 'term1', 'term2', 'term3').equal(3)
20    env.expect('ft.dictdel', 'dict', 'term1', 'term2', 'term4').equal(2)
21    env.expect('ft.dictdel', 'dict', 'term3').equal(1)
22    env.expect('keys', '*').equal([])
23
24def testDictDeleteOnFlush():
25    env = Env()
26    env.expect('ft.dictadd', 'dict', 'term1', 'term2', 'term3').equal(3)
27    env.expect('FLUSHALL').equal(True)
28    env.expect('ft.dictdump', 'dict').error().contains('could not open dict')
29    env.expect('ft.dictadd', 'dict', 'term4', 'term5', 'term6').equal(3)
30    env.expect('ft.dictdump', 'dict').equal(['term4', 'term5', 'term6'])
31
32def testDictDeleteWrongArity():
33    env = Env()
34    env.expect('ft.dictdel', 'dict').raiseError()
35
36
37def testDictDeleteOnNoneExistingKey():
38    env = Env()
39    env.expect('ft.dictdel', 'dict', 'term1').equal(0)
40
41
42def testDictDump():
43    env = Env()
44    env.expect('ft.dictadd', 'dict', 'term1', 'term2', 'term3').equal(3)
45    env.expect('ft.dictdump', 'dict').equal(['term1', 'term2', 'term3'])
46
47
48def testDictDumpWrongArity():
49    env = Env()
50    env.expect('ft.dictdump').raiseError()
51
52
53def testDictDumpOnNoneExistingKey():
54    env = Env()
55    env.expect('ft.dictdump', 'dict').raiseError()
56
57
58def testBasicSpellCheck():
59    env = Env()
60    env.cmd('ft.create', 'idx', 'ON', 'HASH', 'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
61    waitForIndex(env, 'idx')
62    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'name1', 'body', 'body1')
63    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'name2', 'body', 'body2')
64    env.cmd('ft.add', 'idx', 'doc3', 1.0, 'FIELDS', 'name', 'name2', 'body', 'name2')
65    env.expect('ft.spellcheck', 'idx', 'name').equal([['TERM', 'name',
66                                                     [['0.66666666666666663', 'name2'], ['0.33333333333333331', 'name1']]]])
67    if not env.isCluster():
68        env.expect('ft.spellcheck', 'idx', '@body:name').equal([['TERM', 'name', [['0.66666666666666663', 'name2']]]])
69
70
71def testBasicSpellCheckWithNoResult():
72    env = Env()
73    env.cmd('ft.create', 'idx', 'ON', 'HASH', 'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
74    waitForIndex(env, 'idx')
75    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'name1', 'body', 'body1')
76    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'name2', 'body', 'body2')
77    env.cmd('ft.add', 'idx', 'doc3', 1.0, 'FIELDS', 'name', 'name2', 'body', 'name2')
78    env.expect('ft.spellcheck', 'idx', 'somenotexiststext').equal([['TERM', 'somenotexiststext', []]])
79
80
81def testSpellCheckOnExistingTerm():
82    env = Env()
83    env.cmd('ft.create', 'idx', 'ON', 'HASH', 'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
84    waitForIndex(env, 'idx')
85    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'name', 'body', 'body1')
86    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'name2', 'body', 'body2')
87    env.cmd('ft.add', 'idx', 'doc3', 1.0, 'FIELDS', 'name', 'name2', 'body', 'name2')
88    env.expect('ft.spellcheck', 'idx', 'name').equal([])
89
90
91def testSpellCheckWithIncludeDict():
92    env = Env()
93    env.cmd('ft.dictadd', 'dict', 'name3', 'name4', 'name5')
94    env.cmd('ft.create', 'idx', 'ON', 'HASH', 'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
95    waitForIndex(env, 'idx')
96    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'name1', 'body', 'body1')
97    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'name2', 'body', 'body2')
98    env.cmd('ft.add', 'idx', 'doc3', 1.0, 'FIELDS', 'name', 'name2', 'body', 'name2')
99    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'INCLUDE', 'dict').equal([['TERM', 'name',
100                                                                                   [['0.66666666666666663', 'name2'],
101                                                                                    ['0.33333333333333331', 'name1'],
102                                                                                    ['0', 'name3'], ['0', 'name4'],
103                                                                                    ['0', 'name5']]]])
104    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'include', 'dict').equal([['TERM', 'name',
105                                                                                   [['0.66666666666666663', 'name2'],
106                                                                                    ['0.33333333333333331', 'name1'],
107                                                                                    ['0', 'name3'], ['0', 'name4'],
108                                                                                    ['0', 'name5']]]])
109
110
111def testSpellCheckWithDuplications():
112    env = Env()
113    env.cmd('ft.dictadd', 'dict', 'name1', 'name4', 'name5')
114    env.cmd('ft.create', 'idx', 'ON', 'HASH', 'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
115    waitForIndex(env, 'idx')
116    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'name1', 'body', 'body1')
117    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'name2', 'body', 'body2')
118    env.cmd('ft.add', 'idx', 'doc3', 1.0, 'FIELDS', 'name', 'name2', 'body', 'name2')
119    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'INCLUDE', 'dict').equal([['TERM', 'name',
120                                                                                   [['0.66666666666666663', 'name2'],
121                                                                                    ['0.33333333333333331', 'name1'],
122                                                                                    ['0', 'name4'], ['0', 'name5']]]])
123
124
125def testSpellCheckExcludeDict():
126    env = Env()
127    env.cmd('ft.dictadd', 'dict', 'name')
128    env.cmd('ft.create', 'idx', 'ON', 'HASH', 'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
129    waitForIndex(env, 'idx')
130    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'name1', 'body', 'body1')
131    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'name2', 'body', 'body2')
132    env.cmd('ft.add', 'idx', 'doc3', 1.0, 'FIELDS', 'name', 'name2', 'body', 'name2')
133    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'EXCLUDE', 'dict').equal([])
134    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'exclude', 'dict').equal([])
135
136
137def testSpellCheckNoneExistingIndex():
138    env = Env()
139    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'EXCLUDE', 'dict').raiseError()
140
141
142def testSpellCheckWrongArity():
143    env = Env()
144    env.cmd('ft.dictadd', 'dict', 'name')
145    env.cmd('ft.create', 'idx', 'ON', 'HASH', 'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
146    waitForIndex(env, 'idx')
147    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'name1', 'body', 'body1')
148    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'name2', 'body', 'body2')
149    env.cmd('ft.add', 'idx', 'doc3', 1.0, 'FIELDS', 'name', 'name2', 'body', 'name2')
150    env.expect('ft.spellcheck', 'idx').raiseError()
151    env.expect('ft.spellcheck', 'idx').raiseError()
152
153
154def testSpellCheckBadFormat():
155    env = Env()
156    env.cmd('ft.dictadd', 'dict', 'name')
157    env.cmd('ft.create', 'idx', 'ON', 'HASH', 'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
158    waitForIndex(env, 'idx')
159    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'name1', 'body', 'body1')
160    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'name2', 'body', 'body2')
161    env.cmd('ft.add', 'idx', 'doc3', 1.0, 'FIELDS', 'name', 'name2', 'body', 'name2')
162    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS').raiseError()
163    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'INCLUDE').raiseError()
164    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'EXCLUDE').raiseError()
165    env.expect('ft.spellcheck', 'idx', 'name', 'DISTANCE').raiseError()
166    env.expect('ft.spellcheck', 'idx', 'name', 'DISTANCE', 0).raiseError()
167    env.expect('ft.spellcheck', 'idx', 'name', 'DISTANCE', -1).raiseError()
168    env.expect('ft.spellcheck', 'idx', 'name', 'DISTANCE', 101).raiseError()
169
170
171def testSpellCheckNoneExistingDicts():
172    env = Env()
173    env.cmd('ft.create', 'idx', 'ON', 'HASH',
174            'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
175    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'name1', 'body', 'body1')
176    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'name2', 'body', 'body2')
177    env.cmd('ft.add', 'idx', 'doc3', 1.0, 'FIELDS', 'name', 'name2', 'body', 'name2')
178    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'INCLUDE', 'dict').raiseError()
179    env.expect('ft.spellcheck', 'idx', 'name', 'TERMS', 'EXCLUDE', 'dict').raiseError()
180
181
182def testSpellCheckResultsOrder():
183    env = Env()
184    env.cmd('ft.dictadd', 'dict', 'name')
185    env.cmd('ft.create', 'idx', 'ON', 'HASH', 'SCHEMA', 'name', 'TEXT', 'body', 'TEXT')
186    waitForIndex(env, 'idx')
187    env.cmd('ft.add', 'idx', 'doc1', 1.0, 'FIELDS', 'name', 'Elior', 'body', 'body1')
188    env.cmd('ft.add', 'idx', 'doc2', 1.0, 'FIELDS', 'name', 'Hila', 'body', 'body2')
189    env.expect('ft.spellcheck', 'idx', 'Elioh Hilh').equal([['TERM', 'elioh', [['0.5', 'elior']]], ['TERM', 'hilh', [['0.5', 'hila']]]])
190
191def testSpellCheckDictReleadRDB():
192    env = Env()
193    env.expect('FT.DICTADD test 1 2 3').equal(3L)
194    for _ in env.retry_with_rdb_reload():
195        env.expect('FT.DICTDUMP test').equal(['1', '2', '3'])
196
197def testSpellCheckIssue437():
198    env = Env()
199    env.cmd('ft.create', 'incidents', 'ON', 'HASH', 'SCHEMA', 'report', 'text')
200    env.cmd('FT.DICTADD', 'slang', 'timmies', 'toque', 'toonie', 'serviette', 'kerfuffle', 'chesterfield')
201    env.expect('FT.SPELLCHECK', 'incidents',
202               'Tooni toque kerfuffle', 'TERMS',
203               'EXCLUDE', 'slang', 'TERMS',
204               'INCLUDE', 'slang').equal([['TERM', 'tooni', [['0', 'toonie']]]])
205