From a2b73afe238cec13a301346b318ad8b494100f3c Mon Sep 17 00:00:00 2001 From: Jason Dent Date: Sat, 14 Aug 2021 17:22:32 +0200 Subject: [PATCH] fix: do not return forbidden words in suggestions --- .../SpellingDictionaryCollection.test.ts | 70 ++++++++++++++++++- .../SpellingDictionaryCollection.ts | 8 ++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/packages/cspell-lib/src/SpellingDictionary/SpellingDictionaryCollection.test.ts b/packages/cspell-lib/src/SpellingDictionary/SpellingDictionaryCollection.test.ts index 175b6a4387c..5c21ec9542e 100644 --- a/packages/cspell-lib/src/SpellingDictionary/SpellingDictionaryCollection.test.ts +++ b/packages/cspell-lib/src/SpellingDictionary/SpellingDictionaryCollection.test.ts @@ -22,7 +22,8 @@ describe('Verify using multiple dictionaries', () => { ]; const wordsB = ['ape', 'lion', 'tiger', 'elephant', 'monkey', 'gazelle', 'antelope', 'aardvark', 'hyena']; const wordsC = ['ant', 'snail', 'beetle', 'worm', 'stink bug', 'centipede', 'millipede', 'flea', 'fly']; - const wordsD = ['red*', 'green*', 'blue*', 'pink*', 'black*', '*berry', '+-fruit']; + const wordsD = ['red*', 'green*', 'blue*', 'pink*', 'black*', '*berry', '+-fruit', '*bug', 'pinkie']; + const wordsF = ['!pink*', '+berry', '+bug', '!stinkbug']; test('checks for existence', async () => { const dicts = await Promise.all([ createSpellingDictionary(wordsA, 'wordsA', 'test'), @@ -113,6 +114,73 @@ describe('Verify using multiple dictionaries', () => { expect(sugs).toContain('apple mango'); }); + test.each` + word | expected + ${'redberry'} | ${true} + ${'pink'} | ${true} + ${'bug'} | ${true} + ${'blackberry'} | ${true} + ${'pinkbug'} | ${true} + `('checks has word: "$word"', ({ word, expected }) => { + const dicts = [ + createSpellingDictionary(wordsA, 'wordsA', 'test'), + createSpellingDictionary(wordsB, 'wordsB', 'test'), + createSpellingDictionary(wordsC, 'wordsC', 'test'), + createSpellingDictionary(wordsD, 'wordsD', 'test'), + createSpellingDictionary(wordsF, 'wordsF', 'test'), + ]; + + const dictCollection = createCollection(dicts, 'test', ['Avocado']); + expect(dictCollection.has(word)).toEqual(expected); + }); + + // cspell:ignore pinkbug redberry + // Note: `pinkbug` is not forbidden because compound forbidden words is not yet supported. + test.each` + word | expected + ${'redberry'} | ${false} + ${'pink'} | ${true} + ${'bug'} | ${false} + ${'blackberry'} | ${false} + ${'stinkbug'} | ${true} + ${'pinkbug'} | ${false} + `('checks forbid word: "$word"', ({ word, expected }) => { + const dicts = [ + createSpellingDictionary(wordsA, 'wordsA', 'test'), + createSpellingDictionary(wordsB, 'wordsB', 'test'), + createSpellingDictionary(wordsC, 'wordsC', 'test'), + createSpellingDictionary(wordsD, 'wordsD', 'test'), + createSpellingDictionary(wordsF, 'wordsF', 'test'), + ]; + + const dictCollection = createCollection(dicts, 'test', ['Avocado']); + expect(dictCollection.isForbidden(word)).toEqual(expected); + }); + + function sr(word: string, cost: number) { + return { word, cost }; + } + + test.each` + word | expected + ${'redberry'} | ${[sr('redberry', 0), sr('red berry', 105)]} + ${'pink'} | ${[sr('pinkie', 189)]} + ${'bug'} | ${[sr('bug', 5)]} + ${'blackberry'} | ${[sr('blackberry', 0), sr('black berry', 98)]} + ${'stinkbug'} | ${[sr('stink bug', 103), sr('pinkbug', 198)]} + `('checks suggestions word: "$word"', ({ word, expected }) => { + const dicts = [ + createSpellingDictionary(wordsA, 'wordsA', 'test'), + createSpellingDictionary(wordsB, 'wordsB', 'test'), + createSpellingDictionary(wordsC, 'wordsC', 'test'), + createSpellingDictionary(wordsD, 'wordsD', 'test'), + createSpellingDictionary(wordsF, 'wordsF', 'test'), + ]; + + const dictCollection = createCollection(dicts, 'test', ['Avocado']); + expect(dictCollection.suggest(word, 2)).toEqual(expected); + }); + test('checks for suggestions with flagged words', async () => { const dicts = await Promise.all([ createSpellingDictionary(wordsA, 'wordsA', 'test'), diff --git a/packages/cspell-lib/src/SpellingDictionary/SpellingDictionaryCollection.ts b/packages/cspell-lib/src/SpellingDictionary/SpellingDictionaryCollection.ts index 1f4231b6c89..c5b3c4275a6 100644 --- a/packages/cspell-lib/src/SpellingDictionary/SpellingDictionaryCollection.ts +++ b/packages/cspell-lib/src/SpellingDictionary/SpellingDictionaryCollection.ts @@ -73,8 +73,12 @@ export class SpellingDictionaryCollection implements SpellingDictionary { } = suggestOptions; _suggestOptions.compoundMethod = this.options.useCompounds ? CompoundWordsMethod.JOIN_WORDS : compoundMethod; const prefixNoCase = CASE_INSENSITIVE_PREFIX; - const filter = (word: string) => { - return !this.wordsToFlag.has(word.toLowerCase()) && (ignoreCase || word[0] !== prefixNoCase); + const filter = (word: string, _cost: number) => { + return ( + !this.wordsToFlag.has(word.toLowerCase()) && + (ignoreCase || word[0] !== prefixNoCase) && + !this.isForbidden(word) + ); }; const collector = suggestionCollector(word, { numSuggestions,