1# 2012 July 12 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# 12 13set testdir [file dirname $argv0] 14source $testdir/tester.tcl 15set testprefix spellfix 16 17ifcapable !vtab { finish_test ; return } 18 19load_static_extension db spellfix nextchar 20 21set vocab { 22rabbi rabbit rabbits rabble rabid rabies raccoon raccoons race raced racer 23racers races racetrack racial racially racing rack racked racket racketeer 24racketeering racketeers rackets racking racks radar radars radial radially 25radian radiance radiant radiantly radiate radiated radiates radiating radiation 26radiations radiator radiators radical radically radicals radices radii radio 27radioactive radioastronomy radioed radiography radioing radiology radios radish 28radishes radium radius radix radon raft rafter rafters rafts rag rage raged 29rages ragged raggedly raggedness raging rags ragweed raid raided raider raiders 30raiding raids rail railed railer railers railing railroad railroaded railroader 31railroaders railroading railroads rails railway railways raiment rain rainbow 32raincoat raincoats raindrop raindrops rained rainfall rainier rainiest raining 33rains rainstorm rainy raise raised raiser raisers raises raisin raising rake 34raked rakes raking rallied rallies rally rallying ram ramble rambler rambles 35rambling ramblings ramification ramifications ramp rampage rampant rampart 36ramps ramrod rams ran ranch ranched rancher ranchers ranches ranching rancid 37random randomization randomize randomized randomizes randomly randomness randy 38rang range ranged rangeland ranger rangers ranges ranging rangy rank ranked 39ranker rankers rankest ranking rankings rankle rankly rankness ranks ransack 40ransacked ransacking ransacks ransom ransomer ransoming ransoms rant ranted 41ranter ranters ranting rants rap rapacious rape raped raper rapes rapid 42rapidity rapidly rapids rapier raping rapport rapprochement raps rapt raptly 43rapture raptures rapturous rare rarely rareness rarer rarest rarity rascal 44rascally rascals rash rasher rashly rashness rasp raspberry rasped rasping 45rasps raster rat rate rated rater raters rates rather ratification ratified 46ratifies ratify ratifying rating ratings ratio ration rational rationale 47rationales rationalities rationality rationalization rationalizations 48rationalize rationalized rationalizes rationalizing rationally rationals 49rationing rations ratios rats rattle rattled rattler rattlers rattles 50rattlesnake rattlesnakes rattling raucous ravage ravaged ravager ravagers 51ravages ravaging rave raved raven ravening ravenous ravenously ravens raves 52ravine ravines raving ravings raw rawer rawest rawly rawness ray rays raze 53razor razors re reabbreviate reabbreviated reabbreviates reabbreviating reach 54reachability reachable reachably reached reacher reaches reaching reacquired 55react reacted reacting reaction reactionaries reactionary reactions reactivate 56reactivated reactivates reactivating reactivation reactive reactively 57reactivity reactor reactors reacts read readability readable reader readers 58readied readier readies readiest readily readiness reading readings readjusted 59readout readouts reads ready readying real realest realign realigned realigning 60realigns realism realist realistic realistically realists realities reality 61} 62 63do_test 1.1 { 64 execsql { CREATE VIRTUAL TABLE t1 USING spellfix1 } 65 foreach word $vocab { 66 execsql { INSERT INTO t1(word) VALUES($word) } 67 } 68} {} 69 70foreach {tn word res} { 71 1 raxpi* {rasping 5 rasped 5 ragweed 5 raspberry 6 rasp 4} 72 2 ril* {rail 4 railed 4 railer 4 railers 4 railing 4} 73 3 rilis* {realism 6 realist 6 realistic 6 realistically 6 realists 6} 74 4 reail* {real 3 realest 3 realign 3 realigned 3 realigning 3} 75 5 ras* {rascal 3 rascally 3 rascals 3 rash 3 rasher 3} 76 6 realistss* {realists 8 realigns 8 realistic 9 realistically 9 realest 7} 77 7 realistss {realists 8 realist 7 realigns 8 realistic 9 realest 7} 78 8 rllation* {realities 9 reality 7 rallied 7 railed 4} 79 9 renstom* {rainstorm 8 ransom 6 ransomer 6 ransoming 6 ransoms 6} 80} { 81 do_execsql_test 1.2.$tn { 82 SELECT word, matchlen FROM t1 WHERE word MATCH $word 83 ORDER BY score, word LIMIT 5 84 } $res 85} 86 87# Tests of the next_char function. 88# 89do_test 1.10 { 90 db eval { 91 CREATE TABLE vocab(w TEXT PRIMARY KEY); 92 INSERT INTO vocab SELECT word FROM t1; 93 } 94} {} 95do_execsql_test 1.11 { 96 SELECT next_char('re','vocab','w'); 97} {a} 98do_execsql_test 1.12 { 99 SELECT next_char('r','vocab','w'); 100} {ae} 101do_execsql_test 1.13 { 102 SELECT next_char('','vocab','w'); 103} {r} 104do_test 1.14 { 105 catchsql {SELECT next_char('','xyzzy','a')} 106} {1 {no such table: xyzzy}} 107 108do_execsql_test 1.20 { 109 CREATE TABLE vocab2(w TEXT); 110 CREATE INDEX vocab2w ON vocab2(w COLLATE nocase); 111 INSERT INTO vocab2 VALUES('abc'), ('ABD'), ('aBe'), ('AbF'); 112 SELECT next_char('ab', 'vocab2', 'w', null, 'nocase'); 113} {cDeF} 114do_execsql_test 1.21 { 115 SELECT next_char('ab','vocab2','w',null,null); 116} {c} 117do_execsql_test 1.22 { 118 SELECT next_char('AB','vocab2','w',null,'NOCASE'); 119} {cDeF} 120do_execsql_test 1.23 { 121 SELECT next_char('ab','vocab2','w',null,'binary'); 122} {c} 123 124do_execsql_test 2.1 { 125 CREATE VIRTUAL TABLE t2 USING spellfix1; 126 INSERT INTO t2 (word, soundslike) VALUES('school', 'skuul'); 127 INSERT INTO t2 (word, soundslike) VALUES('psalm', 'sarm'); 128 SELECT word, matchlen FROM t2 WHERE word MATCH 'sar*' LIMIT 5; 129} {psalm 4} 130 131do_execsql_test 2.2 { 132 SELECT word, matchlen FROM t2 WHERE word MATCH 'skol*' LIMIT 5; 133} {school 6} 134 135set vocab { 136kangaroo kanji kappa karate keel keeled keeling keels keen keener keenest 137keenly keenness keep keeper keepers keeping keeps ken kennel kennels kept 138kerchief kerchiefs kern kernel kernels kerosene ketchup kettle 139kettles key keyboard keyboards keyed keyhole keying keynote keypad keypads keys 140keystroke keystrokes keyword keywords kick kicked kicker kickers kicking 141kickoff kicks kid kidded kiddie kidding kidnap kidnapper kidnappers kidnapping 142kidnappings kidnaps kidney kidneys kids kill killed killer killers killing 143killingly killings killjoy kills kilobit kilobits kiloblock kilobyte kilobytes 144kilogram kilograms kilohertz kilohm kilojoule kilometer kilometers kiloton 145kilovolt kilowatt kiloword kimono kin kind kinder kindergarten kindest 146kindhearted kindle kindled kindles kindling kindly kindness kindred kinds 147kinetic king kingdom kingdoms kingly kingpin kings kink kinky kinship kinsman 148kiosk kiss kissed kisser kissers kisses kissing kit kitchen kitchenette 149kitchens kite kited kites kiting kits kitten kittenish kittens kitty klaxon 150kludge kludges klystron knack knapsack knapsacks knave knaves knead kneads knee 151kneecap kneed kneeing kneel kneeled kneeling kneels knees knell knells knelt 152knew knife knifed knifes knifing knight knighted knighthood knighting knightly 153knights knit knits knives knob knobs knock knockdown knocked knocker knockers 154knocking knockout knocks knoll knolls knot knots knotted knotting know knowable 155knower knowhow knowing knowingly knowledge knowledgeable known knows knuckle 156knuckled knuckles koala kosher kudo 157} 158 159do_execsql_test 3.1 { 160 CREATE TABLE costs(iLang, cFrom, cTo, iCost); 161 INSERT INTO costs VALUES(0, 'a', 'e', 1); 162 INSERT INTO costs VALUES(0, 'e', 'i', 1); 163 INSERT INTO costs VALUES(0, 'i', 'o', 1); 164 INSERT INTO costs VALUES(0, 'o', 'u', 1); 165 INSERT INTO costs VALUES(0, 'u', 'a', 1); 166 CREATE VIRTUAL TABLE t3 USING spellfix1(edit_cost_table=costs); 167} 168 169do_test 3.2 { 170 foreach w $vocab { 171 execsql { INSERT INTO t3(word) VALUES($w) } 172 } 173} {} 174 175foreach {tn word res} { 176 1 kos* {kosher 3 kiosk 4 kudo 2 kiss 3 kissed 3} 177 2 kellj* {killjoy 5 kill 4 killed 4 killer 4 killers 4} 178 3 kellj {kill 4 kills 5 killjoy 7 keel 4 killed 6} 179} { 180 do_execsql_test 3.2.$tn { 181 SELECT word, matchlen FROM t3 WHERE word MATCH $word 182 ORDER BY score, word LIMIT 5 183 } $res 184} 185 186do_execsql_test 4.0 { 187 INSERT INTO t3(command) VALUES('edit_cost_table=NULL'); 188} 189foreach {tn word res} { 190 1 kosher {kosher 0 kisser 51 kissers 76 kissed 126 kisses 126} 191 2 kellj {keels 60 killjoy 68 kills 80 keel 120 kill 125} 192 3 kashar {kosher 80 kisser 91 kissers 116 kissed 166 kisses 166} 193} { 194 do_execsql_test 4.1.$tn { 195 SELECT word, distance FROM t3 WHERE word MATCH $word 196 ORDER BY score, word LIMIT 5 197 } $res 198} 199do_execsql_test 5.0 { 200 CREATE TABLE costs2(iLang, cFrom, cTo, iCost); 201 INSERT INTO costs2 VALUES(0, 'a', 'o', 1); 202 INSERT INTO costs2 VALUES(0, 'e', 'o', 4); 203 INSERT INTO costs2 VALUES(0, 'i', 'o', 8); 204 INSERT INTO costs2 VALUES(0, 'u', 'o', 16); 205 INSERT INTO t3(command) VALUES('edit_cost_table="costs2"'); 206} 207 208foreach {tn word res} { 209 1 kasher {kosher 1} 210 2 kesher {kosher 4} 211 3 kisher {kosher 8} 212 4 kosher {kosher 0} 213 5 kusher {kosher 16} 214} { 215 do_execsql_test 5.1.$tn { 216 SELECT word, distance FROM t3 WHERE word MATCH $word 217 ORDER BY score, word LIMIT 1 218 } $res 219} 220 221 222 223finish_test 224