Skip to content

Commit

Permalink
fix: fix allowCompoundWords find in case aware dictionaries. (#1549)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason3S authored Aug 18, 2021
1 parent 657db95 commit 769de0b
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 27 deletions.
75 changes: 51 additions & 24 deletions packages/cspell-trie-lib/src/lib/find.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { findWord, PartialFindOptions, FindFullResult, __testing__ } from './find';
import {
createFindOptions,
FindFullResult,
findLegacyCompound,
findWord,
PartialFindOptions,
__testing__,
} from './find';
import { parseDictionary } from './SimpleDictionaryParser';
import { Trie } from './trie';

Expand Down Expand Up @@ -87,34 +94,54 @@ describe('Validate findWord', () => {
});

describe('Validate Legacy Compound lookup', () => {
test('compound words', () => {
// cspell:ignore talkinglift joywalk jwalk awalk jayjay jayi
// cspell:ignore talkinglift joywalk jwalk awalk jayjay jayi
// cspell:ignore walkin walkjay walkedge
test.each`
word | compoundLen | expected
${'talkinglift'} | ${true} | ${true}
${'joywalk'} | ${true} | ${true}
${'jaywalk'} | ${true} | ${true}
${'jwalk'} | ${true} | ${false}
${'awalk'} | ${true} | ${false}
${'jayjay'} | ${true} | ${true}
${'jayjay'} | ${4} | ${false}
${'jayi'} | ${3} | ${false}
${'toto'} | ${true} | ${false}
${'toto'} | ${2} | ${true}
${'toto'} | ${1} | ${true}
${'iif'} | ${1} | ${true}
${'uplift'} | ${true} | ${false}
${'endless'} | ${true} | ${true}
${'joywalk'} | ${999} | ${false}
${'walked'} | ${true} | ${true}
${'walkin'} | ${true} | ${false}
${'walkup'} | ${true} | ${false}
${'walkjay'} | ${true} | ${true}
${'walkjay'} | ${4} | ${false}
${'walkedge'} | ${4} | ${true}
`('compound words no case "$word" compoundLen: $compoundLen', ({ word, compoundLen, expected }) => {
const trie = Trie.create(sampleWords);
function has(word: string, compoundLen: true | number): boolean {
const len = compoundLen === true ? 3 : compoundLen;
return !!findLegacyCompoundWord([trie.root], word, len).found;
}
expect(has('talkinglift', true)).toBe(true);
expect(has('joywalk', true)).toBe(true);
expect(has('jaywalk', true)).toBe(true);
expect(has('jwalk', true)).toBe(false);
expect(has('awalk', true)).toBe(false);
expect(has('jayjay', true)).toBe(true);
expect(has('jayjay', 4)).toBe(false);
expect(has('jayi', 3)).toBe(false);
expect(has('toto', true)).toBe(false);
expect(has('toto', 2)).toBe(true);
expect(has('toto', 1)).toBe(true);
expect(has('iif', 1)).toBe(true);
expect(has('uplift', true)).toBe(false);
expect(has('endless', true)).toBe(true);
expect(has('joywalk', 999)).toBe(false);
expect(has('walked', true)).toBe(true);
expect(has('walkin', true)).toBe(false); // cspell:disable-line
expect(has('walkup', true)).toBe(false); // cspell:disable-line
expect(has('walkjay', true)).toBe(true); // cspell:disable-line
expect(has('walkjay', 4)).toBe(false); // cspell:disable-line
expect(has('walkedge', 4)).toBe(true); // cspell:disable-line
expect(has(word, compoundLen)).toBe(expected);
});

// cspell:ignore cafecode codecafe
test.each`
word | compoundLen | expected
${'codecafe'} | ${true} | ${true}
${'codeerrors'} | ${true} | ${true}
${'cafecode'} | ${true} | ${true}
`('compound words "$word" compoundLen: $compoundLen', ({ word, compoundLen, expected }) => {
const trie = dictionary();
function has(word: string, minLegacyCompoundLength: true | number): boolean {
const len = minLegacyCompoundLength !== true ? minLegacyCompoundLength : 3;
const findOptions = createFindOptions({ legacyMinCompoundLength: len });
return !!findLegacyCompound(trie.root, word, findOptions).found;
}
expect(has(word, compoundLen)).toBe(expected);
});
});

Expand Down
12 changes: 9 additions & 3 deletions packages/cspell-trie-lib/src/lib/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ function findLegacyCompoundNode(
];

const w = word;
const wLen = w.length;
let compoundUsed = false;
let caseMatched = true;
let i = 0;
Expand All @@ -296,7 +297,7 @@ function findLegacyCompoundNode(
const h = w[i++];
const n = s.cr || s.n;
const c = n?.c?.get(h);
if (c && i < word.length) {
if (c && i < wLen) {
// Go deeper.
stack[i] = {
n: c,
Expand All @@ -310,7 +311,12 @@ function findLegacyCompoundNode(
// We did not find the word backup and take the first unused compound branch
while (--i > 0) {
const s = stack[i];
if (s.usedRoots < numRoots && s.n?.f && s.subLength >= minCompoundLength) {
if (
s.usedRoots < numRoots &&
s.n?.f &&
(s.subLength >= minCompoundLength || !s.subLength) &&
wLen - i >= minCompoundLength
) {
break;
}
}
Expand All @@ -319,7 +325,7 @@ function findLegacyCompoundNode(
const s = stack[i];
s.cr = roots[s.usedRoots++];
s.subLength = 0;
s.isCompound = i > 0;
s.isCompound = compoundUsed;
s.caseMatched = s.caseMatched && s.usedRoots <= 1;
} else {
break;
Expand Down

0 comments on commit 769de0b

Please sign in to comment.