summaryrefslogtreecommitdiff
path: root/test/spellfix.test
blob: 21383c2d336df3a5319dcb3579bda40bcf1defd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# 2012 July 12
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix spellfix

ifcapable !vtab { finish_test ; return }

load_static_extension db spellfix nextchar

set vocab {
rabbi rabbit rabbits rabble rabid rabies raccoon raccoons race raced racer
racers races racetrack racial racially racing rack racked racket racketeer
racketeering racketeers rackets racking racks radar radars radial radially
radian radiance radiant radiantly radiate radiated radiates radiating radiation
radiations radiator radiators radical radically radicals radices radii radio
radioactive radioastronomy radioed radiography radioing radiology radios radish
radishes radium radius radix radon raft rafter rafters rafts rag rage raged
rages ragged raggedly raggedness raging rags ragweed raid raided raider raiders
raiding raids rail railed railer railers railing railroad railroaded railroader
railroaders railroading railroads rails railway railways raiment rain rainbow
raincoat raincoats raindrop raindrops rained rainfall rainier rainiest raining
rains rainstorm rainy raise raised raiser raisers raises raisin raising rake
raked rakes raking rallied rallies rally rallying ram ramble rambler rambles
rambling ramblings ramification ramifications ramp rampage rampant rampart
ramps ramrod rams ran ranch ranched rancher ranchers ranches ranching rancid
random randomization randomize randomized randomizes randomly randomness randy
rang range ranged rangeland ranger rangers ranges ranging rangy rank ranked
ranker rankers rankest ranking rankings rankle rankly rankness ranks ransack
ransacked ransacking ransacks ransom ransomer ransoming ransoms rant ranted
ranter ranters ranting rants rap rapacious rape raped raper rapes rapid
rapidity rapidly rapids rapier raping rapport rapprochement raps rapt raptly
rapture raptures rapturous rare rarely rareness rarer rarest rarity rascal
rascally rascals rash rasher rashly rashness rasp raspberry rasped rasping
rasps raster rat rate rated rater raters rates rather ratification ratified
ratifies ratify ratifying rating ratings ratio ration rational rationale
rationales rationalities rationality rationalization rationalizations
rationalize rationalized rationalizes rationalizing rationally rationals
rationing rations ratios rats rattle rattled rattler rattlers rattles
rattlesnake rattlesnakes rattling raucous ravage ravaged ravager ravagers
ravages ravaging rave raved raven ravening ravenous ravenously ravens raves
ravine ravines raving ravings raw rawer rawest rawly rawness ray rays raze
razor razors re reabbreviate reabbreviated reabbreviates reabbreviating reach
reachability reachable reachably reached reacher reaches reaching reacquired
react reacted reacting reaction reactionaries reactionary reactions reactivate
reactivated reactivates reactivating reactivation reactive reactively
reactivity reactor reactors reacts read readability readable reader readers
readied readier readies readiest readily readiness reading readings readjusted
readout readouts reads ready readying real realest realign realigned realigning
realigns realism realist realistic realistically realists realities reality
}

do_test 1.1 {
  execsql { CREATE VIRTUAL TABLE t1 USING spellfix1 }
  foreach word $vocab {
    execsql { INSERT INTO t1(word) VALUES($word) }
  }
} {}

foreach {tn word res} {
  1   raxpi*     {rasping 5 rasped 5 ragweed 5 raspberry 6 rasp 4}
  2   ril*       {rail 4 railed 4 railer 4 railers 4 railing 4}
  3   rilis*     {realism 6 realist 6 realistic 6 realistically 6 realists 6}
  4   reail*     {real 3 realest 3 realign 3 realigned 3 realigning 3}
  5   ras*       {rascal 3 rascally 3 rascals 3 rash 3 rasher 3}
  6   realistss* {realists 8 realigns 8 realistic 9 realistically 9 realest 7}
  7   realistss  {realists 8 realist 7 realigns 8 realistic 9 realest 7}
  8   rllation*  {realities 9 reality 7 rallied 7 railed 4}
  9   renstom*   {rainstorm 8 ransom 6 ransomer 6 ransoming 6 ransoms 6}
} {
  do_execsql_test 1.2.$tn {
    SELECT word, matchlen FROM t1 WHERE word MATCH $word 
     ORDER BY score, word LIMIT 5
  } $res
}

# Tests of the next_char function.
#
do_test 1.10 {
  db eval {
    CREATE TABLE vocab(w TEXT PRIMARY KEY);
    INSERT INTO vocab SELECT word FROM t1;
  }
} {}
do_execsql_test 1.11 {
  SELECT next_char('re','vocab','w');
} {a}
do_execsql_test 1.11sub {
  SELECT next_char('re','(SELECT w AS x FROM vocab)','x');
} {a}
do_execsql_test 1.12 {
  SELECT next_char('r','vocab','w');
} {ae}
do_execsql_test 1.13 {
  SELECT next_char('','vocab','w');
} {r}
do_test 1.14 {
  catchsql {SELECT next_char('','xyzzy','a')}
} {1 {no such table: xyzzy}}

do_execsql_test 1.20 {
  CREATE TABLE vocab2(w TEXT);
  CREATE INDEX vocab2w ON vocab2(w COLLATE nocase);
  INSERT INTO vocab2 VALUES('abc'), ('ABD'), ('aBe'), ('AbF');
  SELECT next_char('ab', 'vocab2', 'w', null, 'nocase');
} {cDeF}
do_execsql_test 1.21 {
  SELECT next_char('ab','vocab2','w',null,null);
} {c}
do_execsql_test 1.22 {
  SELECT next_char('AB','vocab2','w',null,'NOCASE');
} {cDeF}
do_execsql_test 1.23 {
  SELECT next_char('ab','vocab2','w',null,'binary');
} {c}

do_execsql_test 2.1 {
  CREATE VIRTUAL TABLE t2 USING spellfix1;
  INSERT INTO t2 (word, soundslike) VALUES('school', 'skuul');
  INSERT INTO t2 (word, soundslike) VALUES('psalm', 'sarm');
  SELECT word, matchlen FROM t2 WHERE word MATCH 'sar*' LIMIT 5;
} {psalm 4}

do_execsql_test 2.2 {
  SELECT word, matchlen FROM t2 WHERE word MATCH 'skol*' LIMIT 5;
} {school 6}

set vocab {
kangaroo kanji kappa karate keel keeled keeling keels keen keener keenest
keenly keenness keep keeper keepers keeping keeps ken kennel kennels kept
kerchief kerchiefs kern kernel kernels kerosene ketchup kettle
kettles key keyboard keyboards keyed keyhole keying keynote keypad keypads keys
keystroke keystrokes keyword keywords kick kicked kicker kickers kicking
kickoff kicks kid kidded kiddie kidding kidnap kidnapper kidnappers kidnapping
kidnappings kidnaps kidney kidneys kids kill killed killer killers killing
killingly killings killjoy kills kilobit kilobits kiloblock kilobyte kilobytes
kilogram kilograms kilohertz kilohm kilojoule kilometer kilometers kiloton
kilovolt kilowatt kiloword kimono kin kind kinder kindergarten kindest
kindhearted kindle kindled kindles kindling kindly kindness kindred kinds
kinetic king kingdom kingdoms kingly kingpin kings kink kinky kinship kinsman
kiosk kiss kissed kisser kissers kisses kissing kit kitchen kitchenette
kitchens kite kited kites kiting kits kitten kittenish kittens kitty klaxon
kludge kludges klystron knack knapsack knapsacks knave knaves knead kneads knee
kneecap kneed kneeing kneel kneeled kneeling kneels knees knell knells knelt
knew knife knifed knifes knifing knight knighted knighthood knighting knightly
knights knit knits knives knob knobs knock knockdown knocked knocker knockers
knocking knockout knocks knoll knolls knot knots knotted knotting know knowable
knower knowhow knowing knowingly knowledge knowledgeable known knows knuckle
knuckled knuckles koala kosher kudo
}

do_execsql_test 3.1 {
  CREATE TABLE costs(iLang, cFrom, cTo, iCost);
  INSERT INTO costs VALUES(0, 'a', 'e', 1);
  INSERT INTO costs VALUES(0, 'e', 'i', 1);
  INSERT INTO costs VALUES(0, 'i', 'o', 1);
  INSERT INTO costs VALUES(0, 'o', 'u', 1);
  INSERT INTO costs VALUES(0, 'u', 'a', 1);
  CREATE VIRTUAL TABLE t3 USING spellfix1(edit_cost_table=costs);
}

do_test 3.2 {
  foreach w $vocab {
    execsql { INSERT INTO t3(word) VALUES($w) }
  }
} {}

foreach {tn word res} {
  1   kos*     {kosher 3 kiosk 4 kudo 2 kiss 3 kissed 3}
  2   kellj*   {killjoy 5 kill 4 killed 4 killer 4 killers 4}
  3   kellj    {kill 4 kills 5 killjoy 7 keel 4 killed 6}
} {
  do_execsql_test 3.2.$tn {
    SELECT word, matchlen FROM t3 WHERE word MATCH $word
     ORDER BY score, word LIMIT 5
  } $res
}

do_execsql_test 4.0 {
  INSERT INTO t3(command) VALUES('edit_cost_table=NULL');
}
foreach {tn word res} {
  1   kosher     {kosher 0 kisser 51 kissers 76 kissed 126 kisses 126}
  2   kellj      {keels 60 killjoy 68 kills 80 keel 120 kill 125}
  3   kashar     {kosher 80 kisser 91 kissers 116 kissed 166 kisses 166}
} {
  do_execsql_test 4.1.$tn {
    SELECT word, distance FROM t3 WHERE word MATCH $word
     ORDER BY score, word LIMIT 5
  } $res
}
do_execsql_test 5.0 {
  CREATE TABLE costs2(iLang, cFrom, cTo, iCost);
  INSERT INTO costs2 VALUES(0, 'a', 'o', 1);
  INSERT INTO costs2 VALUES(0, 'e', 'o', 4);
  INSERT INTO costs2 VALUES(0, 'i', 'o', 8);
  INSERT INTO costs2 VALUES(0, 'u', 'o', 16);
  INSERT INTO t3(command) VALUES('edit_cost_table="costs2"');
}

foreach {tn word res} {
  1   kasher     {kosher 1}
  2   kesher     {kosher 4}
  3   kisher     {kosher 8}
  4   kosher     {kosher 0}
  5   kusher     {kosher 16}
} {
  do_execsql_test 5.1.$tn {
    SELECT word, distance FROM t3 WHERE word MATCH $word
     ORDER BY score, word LIMIT 1
  } $res
}

#-------------------------------------------------------------------------
# Try some queries by rowid.
#
do_execsql_test 6.1.1 {
  SELECT word FROM t3 WHERE rowid = 10;
} {keener}
do_execsql_test 6.1.2 {
  SELECT word, distance FROM t3 WHERE rowid = 10;
} {keener {}}
do_execsql_test 6.1.3 {
  SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
} {keener 300}

ifcapable trace {
  proc trace_callback {sql} {
    if {[string range $sql 0 2] == "-- "} {
      lappend ::trace [string range $sql 3 end]
    }
  }
  
  proc do_tracesql_test {tn sql {res {}}} {
    set ::trace [list]
    uplevel [list do_test $tn [subst -nocommands {
      set vals [execsql {$sql}]
      concat [set vals] [set ::trace]
    }] [list {*}$res]]
  }
  
  db trace trace_callback
  do_tracesql_test 6.2.1 {
    SELECT word FROM t3 WHERE rowid = 10;
  } {keener
    {SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
  }
  do_tracesql_test 6.2.2 {
    SELECT word, distance FROM t3 WHERE rowid = 10;
  } {keener {}
    {SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
  }
  do_tracesql_test 6.2.3 {
    SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
  } {keener 300
    {SELECT id, word, rank, k1  FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
  }
}




finish_test