Skip to content

Commit

Permalink
fix: Fix issue with suggestions. (#1507)
Browse files Browse the repository at this point in the history
* fix: Fix issue with suggestions.
  Case sensitive suggestions were not getting properly processed.
* Create issues-lock.yml

Note: cspell-trie-lib api changed in this diff. Since it is an internal library, it is not marked as breaking.
  • Loading branch information
Jason3S committed Aug 13, 2021
1 parent 6163424 commit 6a44e26
Show file tree
Hide file tree
Showing 15 changed files with 245 additions and 51 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/issues-lock.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: "Lock closed issues"

on:
schedule:
- cron: "30 5 * * *"
workflow_dispatch:

jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: dessant/[email protected]
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
issue-lock-comment: "This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs."
issue-lock-inactive-days: 30
process-only: "issues"
# cspell:ignore dessant
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"bootstrap": "lerna bootstrap --no-ci",
"lint": "eslint . --fix && prettier -w \"**/*.{md,yaml,yml,json}\"",
"lint-ci": "eslint . && prettier -c \"**/*.{md,yaml,yml,json}\"",
"prepare-cspell-action": "cd test-packages/yarn2 && npm i",
"prepare-cspell-action": "npm i",
"pub-lerna": "lerna publish from-git",
"pub-version": "lerna version --conventional-commits",
"pub-version-pre": "lerna version --conventional-commits --conventional-prerelease",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,13 @@ export class SpellingDictionaryCollection implements SpellingDictionary {
const filter = (word: string) => {
return !this.wordsToFlag.has(word.toLowerCase()) && (ignoreCase || word[0] !== prefixNoCase);
};
const collector = suggestionCollector(word, numSuggestions, filter, numChanges);
const collector = suggestionCollector(word, {
numSuggestions,
filter,
changeLimit: numChanges,
includeTies: true,
ignoreCase,
});
this.genSuggestions(collector, suggestOptions);
return collector.suggestions.map((r) => ({ ...r, word: r.word }));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@ export class SpellingDictionaryFromTrie implements SpellingDictionary {
function filter(_word: string): boolean {
return true;
}
const collector = suggestionCollector(word, numSuggestions, filter, numChanges, undefined, ignoreCase);
const collector = suggestionCollector(word, {
numSuggestions,
filter,
changeLimit: numChanges,
includeTies: true,
ignoreCase,
});
this.genSuggestions(collector, suggestOptions);
return collector.suggestions.map((r) => ({ ...r, word: r.word }));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function impersonateCollector(collector: SuggestionCollector, word: strin
get maxNumSuggestions() {
return collector.maxNumSuggestions;
},
includesTies: false,
includesTies: collector.includesTies,
ignoreCase: collector.ignoreCase,
};
}
Expand Down
22 changes: 22 additions & 0 deletions packages/cspell-lib/src/__snapshots__/validator.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@ Array [
"few's",
"fe's",
"feal",
"fear",
"feat",
"feck",
"feds",
"feed",
"feel",
"feer",
"fees",
"feet",
"fell",
"felt",
"feme",
"fend",
"fens",
"fern",
"fess",
"fest",
"feta",
"fete",
"feud",
"flews",
],
"text": "feww",
},
Expand All @@ -53,6 +74,7 @@ Array [
"mistaken",
"mistaker",
"mistake's",
"mistakers",
],
"text": "mistaks",
},
Expand Down
5 changes: 5 additions & 0 deletions packages/cspell-trie-lib/cspell.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"import": [
"@cspell/dict-es-es/cspell-ext.json"
]
}
6 changes: 3 additions & 3 deletions packages/cspell-trie-lib/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/cspell-trie-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
},
"devDependencies": {
"@cspell/dict-en_us": "^1.2.45",
"@cspell/dict-es-es": "^1.0.28",
"@cspell/dict-es-es": "^2.0.0",
"@types/fs-extra": "^9.0.12",
"@types/node": "^16.6.0",
"jest": "^27.0.6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('Validate SimpleDictionaryParser', () => {
${'BeginEn'} | ${false} | ${false} | ${['BeginEnd', 'Begin']}
${'BeginMidleEnd'} | ${false} | ${false} | ${['BeginMiddleEnd', 'BeginEnd']}
${'beginmidleend'} | ${true} | ${false} | ${[toL('BeginMiddleEnd'), 'BeginMiddleEnd', toL('BeginEnd'), 'BeginEnd']}
${'BeginmidleEnd'} | ${true} | ${false} | ${['BeginMiddleEnd', toL('BeginMiddleEnd'), 'BeginEnd', toL('BeginEnd')]}
${'BeginmidleEnd'} | ${true} | ${false} | ${['BeginMiddleEnd', toL('BeginMiddleEnd'), toL('BeginEnd'), 'BeginEnd']}
${'cafe'} | ${false} | ${false} | ${['Café']}
${'cafe'} | ${true} | ${true} | ${['cafe', 'café', 'Café']}
${'cafë'} | ${true} | ${false} | ${['cafe', 'café', 'Café']}
Expand Down
38 changes: 30 additions & 8 deletions packages/cspell-trie-lib/src/lib/suggest-en.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { genCompoundableSuggestions, suggestionCollector, suggest, SuggestionResult } from './suggest';
import {
genCompoundableSuggestions,
suggestionCollector,
suggest,
SuggestionResult,
SuggestionCollectorOptions,
} from './suggest';
import { CompoundWordsMethod } from './walker';
import { readTrie } from './dictionaries.test.helper';

Expand Down Expand Up @@ -37,7 +43,7 @@ describe('Validate English Suggestions', () => {
'Tests suggestions "joyful"',
async () => {
const trie = await getTrie();
const collector = suggestionCollector('joyful', 8, undefined, 1);
const collector = suggestionCollector('joyful', opts(8, undefined, 1));
collector.collect(genCompoundableSuggestions(trie.root, collector.word, CompoundWordsMethod.NONE));
const results = collector.suggestions;
const suggestions = results.map((s) => s.word);
Expand All @@ -52,7 +58,7 @@ describe('Validate English Suggestions', () => {
async () => {
const trie = await getTrie();
// cspell:ignore joyfull
const collector = suggestionCollector('joyfull', 8);
const collector = suggestionCollector('joyfull', opts(8));
collector.collect(
genCompoundableSuggestions(trie.root, collector.word, CompoundWordsMethod.SEPARATE_WORDS)
);
Expand All @@ -71,7 +77,7 @@ describe('Validate English Suggestions', () => {
async () => {
const trie = await getTrie();
// cspell:ignore onetwothreefour
const collector = suggestionCollector('onetwothreefour', 8, undefined, 3.3);
const collector = suggestionCollector('onetwothreefour', opts(8, undefined, 3.3));
collector.collect(
genCompoundableSuggestions(trie.root, collector.word, CompoundWordsMethod.SEPARATE_WORDS)
);
Expand All @@ -89,7 +95,7 @@ describe('Validate English Suggestions', () => {
async () => {
const trie = await getTrie();
// cspell:ignore onetwothrefour
const collector = suggestionCollector('onetwothreefour', 8, undefined, 3);
const collector = suggestionCollector('onetwothreefour', opts(8, undefined, 3));
collector.collect(genCompoundableSuggestions(trie.root, collector.word, CompoundWordsMethod.JOIN_WORDS));
const results = collector.suggestions;
const suggestions = results.map((s) => s.word);
Expand All @@ -104,7 +110,7 @@ describe('Validate English Suggestions', () => {
async () => {
const trie = await getTrie();
// cspell:ignore onetwothrefour
const collector = suggestionCollector('onetwothreefour', 8, undefined, 3);
const collector = suggestionCollector('onetwothreefour', opts(8, undefined, 3));
collector.collect(genCompoundableSuggestions(trie.root, collector.word, CompoundWordsMethod.JOIN_WORDS));
const results = collector.suggestions;
const suggestions = results.map((s) => s.word);
Expand All @@ -120,7 +126,7 @@ describe('Validate English Suggestions', () => {
async () => {
const trie = await getTrie();
// cspell:ignore testscomputesuggestions
const collector = suggestionCollector('testscomputesuggestions', 2, undefined, 3, true);
const collector = suggestionCollector('testscomputesuggestions', opts(2, undefined, 3, true));
collector.collect(
genCompoundableSuggestions(trie.root, collector.word, CompoundWordsMethod.SEPARATE_WORDS)
);
Expand All @@ -139,7 +145,7 @@ describe('Validate English Suggestions', () => {
async () => {
const trie = await getTrie();
// cspell:ignore testscompundsuggestions
const collector = suggestionCollector('testscompundsuggestions', 1, undefined, 3);
const collector = suggestionCollector('testscompundsuggestions', opts(1, undefined, 3));
collector.collect(
genCompoundableSuggestions(trie.root, collector.word, CompoundWordsMethod.SEPARATE_WORDS)
);
Expand All @@ -153,6 +159,22 @@ describe('Validate English Suggestions', () => {
);
});

function opts(
numSuggestions: number,
filter?: SuggestionCollectorOptions['filter'],
changeLimit?: number,
includeTies?: boolean,
ignoreCase?: boolean
): SuggestionCollectorOptions {
return {
numSuggestions,
filter,
changeLimit,
includeTies,
ignoreCase,
};
}

function sr(...sugs: (string | ExpectedSuggestion)[]): ExpectedSuggestion[] {
return sugs.map((s) => {
if (typeof s === 'string') return { word: s };
Expand Down
54 changes: 48 additions & 6 deletions packages/cspell-trie-lib/src/lib/suggest-es.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,59 @@
import { readTrie } from './dictionaries.test.helper';
import { parseLinesToDictionary } from './SimpleDictionaryParser';

function getTrie() {
return readTrie('@cspell/dict-es-es/cspell-ext.json');
}

describe('Validate Spanish Suggestions', () => {
test('Tests suggestions', async () => {
// cspell:locale en,es
// cspell:ignore Carmjen
test.each`
word | ignoreCase | expectedWords
${'carmjen'} | ${false} | ${['carmen', 'carmene', 'carmena', 'carmená', 'carmené', 'carmeno', 'carmenó', 'carmenen']}
${'carmjen'} | ${true} | ${['carmen', 'carmene', 'carmena', 'carmená', 'carmené', 'carmeno', 'carmenó', 'carmenen']}
${'carmen'} | ${true} | ${['carmen', 'carmene', 'carmena', 'carmená', 'carmené', 'carmeno', 'carmenó']}
${'carmen'} | ${false} | ${['carmen', 'carmene', 'carmena', 'carmená', 'carmené', 'carmeno', 'carmenó']}
${'cafe'} | ${false} | ${['café', 'cafés', 'cafre', 'cabe', 'cace', 'cale', 'cañe', 'cape', 'case', 'cate', 'cave']}
${'niño'} | ${false} | ${['niño', 'niños', 'niña', 'niñeo']}
${'nino'} | ${false} | ${['niño', 'ninfo', 'niños', 'nido', 'niña', 'nito', 'niñeo']}
${'barcelona'} | ${false} | ${['Barcelona', 'Bárcena', 'parcelan', 'abretona']}
${'Mexico'} | ${false} | ${['México', 'mexica', 'medico', 'medicó', 'médico']}
`('Tests suggestions "$word" ignoreCase: $ignoreCase', async ({ word, ignoreCase, expectedWords }) => {
jest.setTimeout(5000);
const trie = await getTrie();
// cspell:ignore Carmjen
const results = trie.suggestWithCost('carmjen', 10);
const suggestions = results.map((s) => s.word);
expect(suggestions).toEqual(expect.arrayContaining(['carmen']));
expect(suggestions[0]).toBe('carmen');
const suggestions = trie.suggest(word, 4, undefined, undefined, ignoreCase);
expect(suggestions).toEqual(expectedWords);
});

test.each`
word | ignoreCase | expectedWords
${'niño'} | ${false} | ${[c('niño', 0), c('niños', 95), c('niña', 96), c('niñeo', 96)]}
${'nino'} | ${false} | ${[c('niño', 1), c('ninfo', 96), c('niños', 96), c('nido', 97), c('niña', 97), c('nito', 97), c('niñeo', 97)]}
`('Tests suggestions "$word" ignoreCase: $ignoreCase', async ({ word, ignoreCase, expectedWords }) => {
jest.setTimeout(5000);
const trie = await getTrie();
const results = trie.suggestWithCost(word, 4, undefined, undefined, ignoreCase);
expect(results).toEqual(expectedWords);
});

test.each`
word | ignoreCase | expectedWords
${'niño'} | ${false} | ${[c('niño', 0), c('niños', 95), c('niña', 96), c('niñeo', 96), c('nido', 97), c('dino', 100)]}
${'nino'} | ${false} | ${[c('niño', 1), c('niños', 96), c('nido', 97), c('niña', 97), c('niñeo', 97), c('dino', 99)]}
`('Tests suggestions "$word" ignoreCase: $ignoreCase', ({ word, ignoreCase, expectedWords }) => {
const trie = trieSimple();
const results = trie.suggestWithCost(word, 10, undefined, undefined, ignoreCase);
expect(results).toEqual(expectedWords);
});
});

function c(word: string, cost: number) {
return { word, cost };
}

const sampleWords = ['niño', 'niños', 'niña', 'niñeo', 'dino', 'nido'];

function trieSimple() {
return parseLinesToDictionary(sampleWords);
}
Loading

0 comments on commit 6a44e26

Please sign in to comment.