From 2e2ca0f3b21b2957bacb1c5ac27fd48e3136a609 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Thu, 18 May 2023 22:41:15 +0300 Subject: [PATCH] chore: allow different partial keywords for multiple searches --- src/data/search/index.ts | 292 +++++++++--------- src/data/search/split.ts | 139 ++++----- src/types/search.ts | 6 +- tests/search/split-keyword-entry-test.ts | 370 +++++++++++------------ tests/search/split-keyword-test.ts | 37 ++- 5 files changed, 400 insertions(+), 444 deletions(-) diff --git a/src/data/search/index.ts b/src/data/search/index.ts index 4b65db7..2104f23 100644 --- a/src/data/search/index.ts +++ b/src/data/search/index.ts @@ -41,28 +41,6 @@ export function search( return; } - // Check for partial - const partial = keywords.partial; - let partialKeywords: string[] | undefined; - let isFirstKeywordExact = true; - - if (partial) { - // Get all partial keyword matches - const cache = getPartialKeywords(partial, true, data); - const exists = data.keywords[partial]; - if (!cache || !cache.length) { - // No partial matches: check if keyword exists - if (!exists) { - return; - } - partialKeywords = [partial]; - } else { - // Partial keywords exist - isFirstKeywordExact = !!exists; - partialKeywords = exists ? [partial].concat(cache) : cache.slice(0); - } - } - // Get prefixes const basePrefixes = filterSearchPrefixes(data, iconSets, fullParams); @@ -92,139 +70,130 @@ export function search( }; const limit = params.limit; - // Run all searches - const check = (isExact: boolean, partial?: string) => { - for (let searchIndex = 0; searchIndex < keywords.searches.length; searchIndex++) { - // Add prefixes cache to avoid re-calculating it for every partial keyword - interface ExtendedSearchKeywordsEntry extends SearchKeywordsEntry { - filteredPrefixes?: Readonly; + interface ExtendedSearchKeywordsEntry extends SearchKeywordsEntry { + // Add prefixes cache to avoid re-calculating it for every partial keyword + filteredPrefixes?: Readonly; + } + const runSearch = (search: ExtendedSearchKeywordsEntry, isExact: boolean, partial?: string) => { + // Filter prefixes (or get it from cache) + let filteredPrefixes: Readonly; + if (search.filteredPrefixes) { + filteredPrefixes = search.filteredPrefixes; + } else { + filteredPrefixes = search.prefixes ? filterSearchPrefixesList(basePrefixes, search.prefixes) : basePrefixes; + + // Filter by required keywords + for (let i = 0; i < search.keywords.length; i++) { + filteredPrefixes = filteredPrefixes.filter((prefix) => data.keywords[search.keywords[i]]?.has(prefix)); } - const search = keywords.searches[searchIndex] as ExtendedSearchKeywordsEntry; - // Filter prefixes (or get it from cache) - let filteredPrefixes: Readonly; - if (search.filteredPrefixes) { - filteredPrefixes = search.filteredPrefixes; - } else { - filteredPrefixes = search.prefixes - ? filterSearchPrefixesList(basePrefixes, search.prefixes) - : basePrefixes; + search.filteredPrefixes = filteredPrefixes; + } + if (!filteredPrefixes.length) { + return; + } - // Filter by required keywords - for (let i = 0; i < search.keywords.length; i++) { - filteredPrefixes = filteredPrefixes.filter((prefix) => - data.keywords[search.keywords[i]].has(prefix) - ); - } + // Get keywords + const testKeywords = partial ? search.keywords.concat([partial]) : search.keywords; + const testMatches = search.test ? search.test.concat(testKeywords) : testKeywords; - search.filteredPrefixes = filteredPrefixes; - } - if (!filteredPrefixes.length) { + // Check for partial keyword if testing for exact match + if (partial) { + filteredPrefixes = filteredPrefixes.filter((prefix) => data.keywords[partial]?.has(prefix)); + } + + // Check icons + for (let prefixIndex = 0; prefixIndex < filteredPrefixes.length; prefixIndex++) { + const prefix = filteredPrefixes[prefixIndex]; + const prefixAddedIcons = addedIcons[prefix] || (addedIcons[prefix] = new Set()); + const iconSet = iconSets[prefix].item; + const iconSetIcons = iconSet.icons; + const iconSetKeywords = iconSetIcons.keywords; + if (!iconSetKeywords) { + // This should not happen! continue; } - // Get keywords - const testKeywords = partial ? search.keywords.concat([partial]) : search.keywords; - const testMatches = search.test ? search.test.concat(testKeywords) : testKeywords; + // Check icons in current prefix + let matches: IconSetIconNames[] | undefined; + let failed = false; + for (let keywordIndex = 0; keywordIndex < testKeywords.length && !failed; keywordIndex++) { + const keyword = testKeywords[keywordIndex]; + const keywordMatches = iconSetKeywords[keyword]; + if (!keywordMatches) { + failed = true; + break; + } - // Check for partial keyword if testing for exact match - if (partial) { - filteredPrefixes = filteredPrefixes.filter((prefix) => data.keywords[partial].has(prefix)); + if (!matches) { + // Copy all matches + matches = Array.from(keywordMatches); + } else { + // Match previous set + matches = matches.filter((item) => keywordMatches.has(item)); + } } - // Check icons - for (let prefixIndex = 0; prefixIndex < filteredPrefixes.length; prefixIndex++) { - const prefix = filteredPrefixes[prefixIndex]; - const prefixAddedIcons = addedIcons[prefix] || (addedIcons[prefix] = new Set()); - const iconSet = iconSets[prefix].item; - const iconSetIcons = iconSet.icons; - const iconSetKeywords = iconSetIcons.keywords; - if (!iconSetKeywords) { - // This should not happen! - continue; - } - - // Check icons in current prefix - let matches: IconSetIconNames[] | undefined; - let failed = false; - for (let keywordIndex = 0; keywordIndex < testKeywords.length && !failed; keywordIndex++) { - const keyword = testKeywords[keywordIndex]; - const keywordMatches = iconSetKeywords[keyword]; - if (!keywordMatches) { - failed = true; - break; + // Test matched icons + if (!failed && matches) { + for (let matchIndex = 0; matchIndex < matches.length; matchIndex++) { + const item = matches[matchIndex]; + if (prefixAddedIcons.has(item)) { + // Already added + continue; } - if (!matches) { - // Copy all matches - matches = Array.from(keywordMatches); - } else { - // Match previous set - matches = matches.filter((item) => keywordMatches.has(item)); + // Check style + if ( + // Style is set + fullParams.style && + // Enabled in config + appConfig.allowFilterIconsByStyle && + // Icon set has mixed style (so it is assigned to icons) -> check icon + iconSetIcons.iconStyle === 'mixed' && + item._is !== fullParams.style + ) { + // Different icon style + continue; } - } - // Test matched icons - if (!failed && matches) { - for (let matchIndex = 0; matchIndex < matches.length; matchIndex++) { - const item = matches[matchIndex]; - if (prefixAddedIcons.has(item)) { - // Already added - continue; - } + // Find icon name that matches all keywords + let length: number | undefined; + const name = item.find((name, index) => { + for (let i = 0; i < testMatches.length; i++) { + if (name.indexOf(testMatches[i]) === -1) { + return false; + } - // Check style - if ( - // Style is set - fullParams.style && - // Enabled in config - appConfig.allowFilterIconsByStyle && - // Icon set has mixed style (so it is assigned to icons) -> check icon - iconSetIcons.iconStyle === 'mixed' && - item._is !== fullParams.style - ) { - // Different icon style - continue; - } - - // Find icon name that matches all keywords - let length: number | undefined; - const name = item.find((name, index) => { - for (let i = 0; i < testMatches.length; i++) { - if (name.indexOf(testMatches[i]) === -1) { - return false; - } - - // Get length - if (!index) { - // First item sets `_l`, unless it didn't match any prefixes/suffixes - length = item._l || name.length; - } else if (iconSet.themeParts) { - // Alias: calculate length - const themeParts = iconSet.themeParts; - for (let partIndex = 0; partIndex < themeParts.length; partIndex++) { - const part = themeParts[partIndex]; - if (name.startsWith(part + '-') || name.endsWith('-' + part)) { - length = name.length - part.length - 1; - break; - } + // Get length + if (!index) { + // First item sets `_l`, unless it didn't match any prefixes/suffixes + length = item._l || name.length; + } else if (iconSet.themeParts) { + // Alias: calculate length + const themeParts = iconSet.themeParts; + for (let partIndex = 0; partIndex < themeParts.length; partIndex++) { + const part = themeParts[partIndex]; + if (name.startsWith(part + '-') || name.endsWith('-' + part)) { + length = name.length - part.length - 1; + break; } } } - return true; - }); - if (name) { - // Add icon - prefixAddedIcons.add(item); + } + return true; + }); + if (name) { + // Add icon + prefixAddedIcons.add(item); - const list = getMatchResult(length || name.length, !isExact); - list.names.push(prefix + ':' + name); - allMatchesLength++; + const list = getMatchResult(length || name.length, !isExact); + list.names.push(prefix + ':' + name); + allMatchesLength++; - if (!isExact && allMatchesLength >= limit) { - // Return only if checking for partials and limit reached - return; - } + if (!isExact && allMatchesLength >= limit) { + // Return only if checking for partials and limit reached + return; } } } @@ -232,20 +201,51 @@ export function search( } }; - // Check all keywords - if (!partialKeywords) { - check(true); - } else { - let partial: string | undefined; - while ((partial = partialKeywords.shift())) { - check(isFirstKeywordExact, partial); - if (allMatchesLength >= limit) { - break; + const runAllSearches = (isExact: boolean) => { + for (let searchIndex = 0; searchIndex < keywords.searches.length; searchIndex++) { + const search = keywords.searches[searchIndex]; + const partial = search.partial; + if (partial) { + // Has partial + if (isExact) { + if (data.keywords[partial]) { + runSearch(search, true, partial); + } + } else { + // Get all partial matches + const keywords = getPartialKeywords(partial, true, data); + if (keywords) { + for (let keywordIndex = 0; keywordIndex < keywords.length; keywordIndex++) { + runSearch(search, false, keywords[keywordIndex]); + } + } + } + } else { + // No partial for this search + if (!isExact) { + continue; + } + + // Exact match + runSearch(search, true); } - // Next check will be for partial keyword - isFirstKeywordExact = false; + // Check limit + if (!isExact && allMatchesLength >= limit) { + return; + } } + }; + + // Check all keywords + try { + runAllSearches(true); + if (allMatchesLength < limit) { + runAllSearches(false); + } + } catch (err) { + console.warn('Got exception when searching for:', params); + console.error(err); } // Generate results diff --git a/src/data/search/split.ts b/src/data/search/split.ts index c0b4fe9..246c7d2 100644 --- a/src/data/search/split.ts +++ b/src/data/search/split.ts @@ -21,20 +21,15 @@ interface SplitResultItem { // Strings to test icon name test?: string[]; -} -interface SplitResult { - searches: SplitResultItem[]; - - // Partial keyword. It is last chunk of last keyword, which cannot be treated - // as prefix, so it is identical to all searches + // Partial keyword. It is last chunk of last keyword, which cannot be treated as prefix partial?: string; } +type SplitResult = SplitResultItem[]; + export function splitKeywordEntries(values: string[], options: SplitOptions): SplitResult | undefined { - const results: SplitResult = { - searches: [], - }; + const results: SplitResult = []; let invalid = false; // Split each entry into arrays @@ -83,8 +78,14 @@ export function splitKeywordEntries(values: string[], options: SplitOptions): Sp return (items[0].empty ? '-' : '') + items.map((item) => item.value).join('-'); } + interface ResultsSet { + keywords: Set; + test: Set; + partial?: string; + } + // Function to add item - function add(items: Entry[], keywords: Set, test: Set, checkPartial: boolean) { + function addToSet(items: Entry[], set: ResultsSet, allowPartial: boolean) { let partial: string | undefined; // Add keywords @@ -92,10 +93,10 @@ export function splitKeywordEntries(values: string[], options: SplitOptions): Sp for (let i = 0; i <= max; i++) { const value = items[i]; if (!value.empty) { - if (i === max && checkPartial && value.value.length >= minPartialKeywordLength) { + if (i === max && allowPartial && value.value.length >= minPartialKeywordLength) { partial = value.value; } else { - keywords.add(value.value); + set.keywords.add(value.value); } } } @@ -103,20 +104,30 @@ export function splitKeywordEntries(values: string[], options: SplitOptions): Sp // Get test value const testValue = valuesToString(items); if (testValue) { - test.add(testValue); + set.test.add(testValue); } - // Validate partial - if (checkPartial) { - if (results.searches.length) { - if (results.partial !== partial) { - // Partial should be identical for all searches. Something went wrong !!! - console.error('Mismatches partials when splitting keywords:', values); - delete results.partial; - } - } else { - results.partial = partial; + // Add partial + if (allowPartial && partial) { + if (set.partial && set.partial !== partial) { + console.error('Different partial keywords. This should not be happening!'); } + set.partial = partial; + } + } + + // Add results set to result + function addToResult(set: ResultsSet, prefix?: string) { + if (set.keywords.size || set.partial) { + const item: SplitResultItem = { + keywords: Array.from(set.keywords), + prefix, + partial: set.partial, + }; + if (set.test.size) { + item.test = Array.from(set.test); + } + results.push(item); } } @@ -134,22 +145,14 @@ export function splitKeywordEntries(values: string[], options: SplitOptions): Sp const prefix = firstItem.length > 1 ? valuesToString(firstItem) : firstItem[0].value; if (prefix) { // Valid prefix - const keywords: Set = new Set(); - const test: Set = new Set(); + const set: ResultsSet = { + keywords: new Set(), + test: new Set(), + }; for (let i = 1; i <= lastIndex; i++) { - add(splitValues[i], keywords, test, options.partial && i === lastIndex); - } - - if (keywords.size || results.partial) { - const item: SplitResultItem = { - keywords: Array.from(keywords), - prefix, - }; - if (test.size) { - item.test = Array.from(test); - } - results.searches.push(item); + addToSet(splitValues[i], set, options.partial && i === lastIndex); } + addToResult(set, prefix); } } } @@ -159,41 +162,26 @@ export function splitKeywordEntries(values: string[], options: SplitOptions): Sp if (maxFirstItemIndex && !firstItem[0].empty && !firstItem[1].empty) { const modifiedFirstItem = firstItem.slice(0); const prefix = modifiedFirstItem.shift()!.value; - const keywords: Set = new Set(); - const test: Set = new Set(); + const set: ResultsSet = { + keywords: new Set(), + test: new Set(), + }; for (let i = 0; i <= lastIndex; i++) { - add(i ? splitValues[i] : modifiedFirstItem, keywords, test, options.partial && i === lastIndex); - } - - if (keywords.size || results.partial) { - const item: SplitResultItem = { - keywords: Array.from(keywords), - prefix, - }; - if (test.size) { - item.test = Array.from(test); - } - results.searches.push(item); + addToSet(i ? splitValues[i] : modifiedFirstItem, set, options.partial && i === lastIndex); } + addToResult(set, prefix); } } // Add as is - const keywords: Set = new Set(); - const test: Set = new Set(); + const set: ResultsSet = { + keywords: new Set(), + test: new Set(), + }; for (let i = 0; i <= lastIndex; i++) { - add(splitValues[i], keywords, test, options.partial && i === lastIndex); - } - if (keywords.size || results.partial) { - // Add item - const item: SplitResultItem = { - keywords: Array.from(keywords), - }; - if (test.size) { - item.test = Array.from(test); - } - results.searches.push(item); + addToSet(splitValues[i], set, options.partial && i === lastIndex); } + addToResult(set); // Merge values if (splitValues.length > 1) { @@ -233,22 +221,14 @@ export function splitKeywordEntries(values: string[], options: SplitOptions): Sp ...splitValues.slice(endIndex + 1), ]; const newLastIndex = newSplitValues.length - 1; - const keywords: Set = new Set(); - const test: Set = new Set(); + const set: ResultsSet = { + keywords: new Set(), + test: new Set(), + }; for (let i = 0; i <= newLastIndex; i++) { - add(newSplitValues[i], keywords, test, false); - } - - if (keywords.size || results.partial) { - // Add item - const item: SplitResultItem = { - keywords: Array.from(keywords), - }; - if (test.size) { - item.test = Array.from(test); - } - results.searches.push(item); + addToSet(newSplitValues[i], set, options.partial && i === newLastIndex); } + addToResult(set); } } } @@ -484,7 +464,7 @@ export function splitKeyword(keyword: string, allowPartial = true): SearchKeywor return; } - const searches: SearchKeywordsEntry[] = entries.searches.map((item) => { + const searches: SearchKeywordsEntry[] = entries.map((item) => { return { ...item, prefixes: item.prefix @@ -505,6 +485,5 @@ export function splitKeyword(keyword: string, allowPartial = true): SearchKeywor return { searches, params, - partial: entries.partial, }; } diff --git a/src/types/search.ts b/src/types/search.ts index 46b4537..caa1d4e 100644 --- a/src/types/search.ts +++ b/src/types/search.ts @@ -67,6 +67,9 @@ export interface SearchKeywordsEntry { // Strings to test icon value test?: string[]; + + // Partial keyword + partial?: string; } /** @@ -76,9 +79,6 @@ export interface SearchKeywords { // List of searches searches: SearchKeywordsEntry[]; - // Partial keyword, used in all matches - partial?: string; - // Params extracted from keywords params: Partial; } diff --git a/tests/search/split-keyword-entry-test.ts b/tests/search/split-keyword-entry-test.ts index a2ccb15..d7272cc 100644 --- a/tests/search/split-keyword-entry-test.ts +++ b/tests/search/split-keyword-entry-test.ts @@ -37,40 +37,34 @@ describe('Splitting keywords', () => { prefix: false, partial: false, }) - ).toEqual({ - searches: [ - { - keywords: ['home'], - }, - ], - }); + ).toEqual([ + { + keywords: ['home'], + }, + ]); expect( splitKeywordEntries(['home'], { prefix: true, partial: false, }) - ).toEqual({ - searches: [ - { - keywords: ['home'], - }, - ], - }); + ).toEqual([ + { + keywords: ['home'], + }, + ]); expect( splitKeywordEntries(['home'], { prefix: true, partial: true, }) - ).toEqual({ - searches: [ - { - keywords: [], - }, - ], - partial: 'home', - }); + ).toEqual([ + { + keywords: [], + partial: 'home', + }, + ]); }); test('Multiple simple entries', () => { @@ -79,79 +73,73 @@ describe('Splitting keywords', () => { prefix: false, partial: false, }) - ).toEqual({ - searches: [ - { - keywords: ['mdi', 'home'], - }, - { - keywords: ['mdihome'], - }, - ], - }); + ).toEqual([ + { + keywords: ['mdi', 'home'], + }, + { + keywords: ['mdihome'], + }, + ]); expect( splitKeywordEntries(['mdi', 'home', 'outline'], { prefix: false, partial: false, }) - ).toEqual({ - searches: [ - { - keywords: ['mdi', 'home', 'outline'], - }, - { - keywords: ['mdihome', 'outline'], - }, - { - keywords: ['mdihomeoutline'], - }, - { - keywords: ['mdi', 'homeoutline'], - }, - ], - }); + ).toEqual([ + { + keywords: ['mdi', 'home', 'outline'], + }, + { + keywords: ['mdihome', 'outline'], + }, + { + keywords: ['mdihomeoutline'], + }, + { + keywords: ['mdi', 'homeoutline'], + }, + ]); expect( splitKeywordEntries(['mdi', 'home'], { prefix: true, partial: false, }) - ).toEqual({ - searches: [ - { - prefix: 'mdi', - keywords: ['home'], - }, - { - keywords: ['mdi', 'home'], - }, - { - keywords: ['mdihome'], - }, - ], - }); + ).toEqual([ + { + prefix: 'mdi', + keywords: ['home'], + }, + { + keywords: ['mdi', 'home'], + }, + { + keywords: ['mdihome'], + }, + ]); expect( splitKeywordEntries(['mdi', 'home'], { prefix: true, partial: true, }) - ).toEqual({ - searches: [ - { - prefix: 'mdi', - keywords: [], - }, - { - keywords: ['mdi'], - }, - { - keywords: ['mdihome'], - }, - ], - partial: 'home', - }); + ).toEqual([ + { + prefix: 'mdi', + keywords: [], + partial: 'home', + }, + { + keywords: ['mdi'], + partial: 'home', + }, + { + keywords: [], + partial: 'mdihome', + }, + ]); }); test('Incomplete prefix', () => { @@ -160,51 +148,46 @@ describe('Splitting keywords', () => { prefix: false, partial: false, }) - ).toEqual({ - searches: [ - { - keywords: ['mdi', 'home'], - test: ['mdi-'], - }, - ], - }); + ).toEqual([ + { + keywords: ['mdi', 'home'], + test: ['mdi-'], + }, + ]); expect( splitKeywordEntries(['mdi-', 'home'], { prefix: true, partial: false, }) - ).toEqual({ - searches: [ - { - prefix: 'mdi-', - keywords: ['home'], - }, - { - keywords: ['mdi', 'home'], - test: ['mdi-'], - }, - ], - }); + ).toEqual([ + { + prefix: 'mdi-', + keywords: ['home'], + }, + { + keywords: ['mdi', 'home'], + test: ['mdi-'], + }, + ]); expect( splitKeywordEntries(['mdi-', 'home'], { prefix: true, partial: true, }) - ).toEqual({ - searches: [ - { - prefix: 'mdi-', - keywords: [], - }, - { - keywords: ['mdi'], - test: ['mdi-'], - }, - ], - partial: 'home', - }); + ).toEqual([ + { + prefix: 'mdi-', + keywords: [], + partial: 'home', + }, + { + keywords: ['mdi'], + partial: 'home', + test: ['mdi-'], + }, + ]); }); test('Long entry', () => { @@ -213,53 +196,48 @@ describe('Splitting keywords', () => { prefix: false, partial: false, }) - ).toEqual({ - searches: [ - { - keywords: ['mdi', 'home', 'outline'], - test: ['mdi-home-outline'], - }, - ], - }); + ).toEqual([ + { + keywords: ['mdi', 'home', 'outline'], + test: ['mdi-home-outline'], + }, + ]); expect( splitKeywordEntries(['mdi-home-outline'], { prefix: true, partial: false, }) - ).toEqual({ - searches: [ - { - prefix: 'mdi', - keywords: ['home', 'outline'], - test: ['home-outline'], - }, - { - keywords: ['mdi', 'home', 'outline'], - test: ['mdi-home-outline'], - }, - ], - }); + ).toEqual([ + { + prefix: 'mdi', + keywords: ['home', 'outline'], + test: ['home-outline'], + }, + { + keywords: ['mdi', 'home', 'outline'], + test: ['mdi-home-outline'], + }, + ]); expect( splitKeywordEntries(['mdi-home-outline'], { prefix: true, partial: true, }) - ).toEqual({ - searches: [ - { - prefix: 'mdi', - keywords: ['home'], - test: ['home-outline'], - }, - { - keywords: ['mdi', 'home'], - test: ['mdi-home-outline'], - }, - ], - partial: 'outline', - }); + ).toEqual([ + { + prefix: 'mdi', + keywords: ['home'], + partial: 'outline', + test: ['home-outline'], + }, + { + keywords: ['mdi', 'home'], + partial: 'outline', + test: ['mdi-home-outline'], + }, + ]); }); test('Complex entries', () => { @@ -268,77 +246,71 @@ describe('Splitting keywords', () => { prefix: false, partial: false, }) - ).toEqual({ - searches: [ - { - keywords: ['mdi', 'light', 'arrow', 'left'], - test: ['mdi-light', 'arrow-left'], - }, - ], - }); + ).toEqual([ + { + keywords: ['mdi', 'light', 'arrow', 'left'], + test: ['mdi-light', 'arrow-left'], + }, + ]); expect( splitKeywordEntries(['mdi-light', 'arrow-left'], { prefix: true, partial: false, }) - ).toEqual({ - searches: [ - { - prefix: 'mdi-light', - keywords: ['arrow', 'left'], - test: ['arrow-left'], - }, - { - prefix: 'mdi', - keywords: ['light', 'arrow', 'left'], - test: ['arrow-left'], - }, - { - keywords: ['mdi', 'light', 'arrow', 'left'], - test: ['mdi-light', 'arrow-left'], - }, - ], - }); + ).toEqual([ + { + prefix: 'mdi-light', + keywords: ['arrow', 'left'], + test: ['arrow-left'], + }, + { + prefix: 'mdi', + keywords: ['light', 'arrow', 'left'], + test: ['arrow-left'], + }, + { + keywords: ['mdi', 'light', 'arrow', 'left'], + test: ['mdi-light', 'arrow-left'], + }, + ]); expect( splitKeywordEntries(['mdi-light', 'arrow-left'], { prefix: false, partial: true, }) - ).toEqual({ - searches: [ - { - keywords: ['mdi', 'light', 'arrow'], - test: ['mdi-light', 'arrow-left'], - }, - ], - partial: 'left', - }); + ).toEqual([ + { + keywords: ['mdi', 'light', 'arrow'], + partial: 'left', + test: ['mdi-light', 'arrow-left'], + }, + ]); expect( splitKeywordEntries(['mdi-light', 'arrow-left'], { prefix: true, partial: true, }) - ).toEqual({ - searches: [ - { - prefix: 'mdi-light', - keywords: ['arrow'], - test: ['arrow-left'], - }, - { - prefix: 'mdi', - keywords: ['light', 'arrow'], - test: ['arrow-left'], - }, - { - keywords: ['mdi', 'light', 'arrow'], - test: ['mdi-light', 'arrow-left'], - }, - ], - partial: 'left', - }); + ).toEqual([ + { + prefix: 'mdi-light', + keywords: ['arrow'], + partial: 'left', + test: ['arrow-left'], + }, + { + prefix: 'mdi', + keywords: ['light', 'arrow'], + partial: 'left', + test: ['arrow-left'], + }, + { + keywords: ['mdi', 'light', 'arrow'], + partial: 'left', + test: ['mdi-light', 'arrow-left'], + }, + ]); }); }); diff --git a/tests/search/split-keyword-test.ts b/tests/search/split-keyword-test.ts index 5bddfd5..99fcb97 100644 --- a/tests/search/split-keyword-test.ts +++ b/tests/search/split-keyword-test.ts @@ -20,13 +20,14 @@ describe('Splitting keywords', () => { prefixes: ['mdi'], prefix: 'mdi', // leftover from internal function keywords: [], + partial: 'home', }, { keywords: ['mdi'], + partial: 'home', test: ['mdi-home'], }, ], - partial: 'home', params: {}, }); expect(splitKeyword('mdi-home', false)).toEqual({ @@ -50,9 +51,9 @@ describe('Splitting keywords', () => { { prefixes: ['mdi'], keywords: [], + partial: 'home', }, ], - partial: 'home', params: {}, }); expect(splitKeyword('mdi:home', false)).toEqual({ @@ -71,9 +72,9 @@ describe('Splitting keywords', () => { { prefixes: ['mdi'], keywords: [], + partial: 'home', }, ], - partial: 'home', params: {}, }); expect(splitKeyword('prefix:mdi home', false)).toEqual({ @@ -92,9 +93,9 @@ describe('Splitting keywords', () => { { prefixes: ['mdi'], keywords: [], + partial: 'home', }, ], - partial: 'home', params: {}, }); expect(splitKeyword('prefix=mdi home', false)).toEqual({ @@ -113,9 +114,9 @@ describe('Splitting keywords', () => { { prefixes: ['mdi'], keywords: [], + partial: 'home', }, ], - partial: 'home', params: {}, }); expect(splitKeyword('prefixes:mdi home', false)).toEqual({ @@ -134,9 +135,9 @@ describe('Splitting keywords', () => { { prefixes: ['fa6-', 'mdi-'], keywords: [], + partial: 'home', }, ], - partial: 'home', params: {}, }); expect(splitKeyword('prefixes:fa6-,mdi- home', false)).toEqual({ @@ -155,9 +156,9 @@ describe('Splitting keywords', () => { { prefixes: ['mdi', 'mdi-'], keywords: [], + partial: 'home', }, ], - partial: 'home', params: {}, }); expect(splitKeyword('prefixes=mdi* home', false)).toEqual({ @@ -177,18 +178,20 @@ describe('Splitting keywords', () => { prefixes: ['mdi-light'], prefix: 'mdi-light', keywords: [], + partial: 'home', }, { prefixes: ['mdi'], prefix: 'mdi', keywords: ['light'], + partial: 'home', }, { keywords: ['mdi', 'light'], test: ['mdi-light'], + partial: 'home', }, ], - partial: 'home', params: {}, }); expect(splitKeyword('mdi-light home', false)).toEqual({ @@ -218,20 +221,22 @@ describe('Splitting keywords', () => { prefixes: ['mdi-light'], prefix: 'mdi-light', keywords: ['home'], + partial: 'outline', test: ['home-outline'], }, { prefixes: ['mdi'], prefix: 'mdi', keywords: ['light', 'home'], + partial: 'outline', test: ['home-outline'], }, { keywords: ['mdi', 'light', 'home'], + partial: 'outline', test: ['mdi-light', 'home-outline'], }, ], - partial: 'outline', params: {}, }); expect(splitKeyword('mdi-light home-outline', false)).toEqual({ @@ -262,9 +267,9 @@ describe('Splitting keywords', () => { searches: [ { keywords: [], + partial: 'home', }, ], - partial: 'home', params: { palette: true, }, @@ -274,9 +279,9 @@ describe('Splitting keywords', () => { searches: [ { keywords: [], + partial: 'home', }, ], - partial: 'home', params: { palette: false, }, @@ -287,9 +292,9 @@ describe('Splitting keywords', () => { { prefixes: ['mdi', 'mdi-', 'fa6-'], keywords: [], + partial: 'home', }, ], - partial: 'home', params: {}, }); @@ -309,9 +314,9 @@ describe('Splitting keywords', () => { searches: [ { keywords: [], + partial: 'home', }, ], - partial: 'home', params: { style: 'fill', }, @@ -321,9 +326,9 @@ describe('Splitting keywords', () => { searches: [ { keywords: [], + partial: 'home', }, ], - partial: 'home', params: { style: 'stroke', }, @@ -333,9 +338,9 @@ describe('Splitting keywords', () => { searches: [ { keywords: [], + partial: 'home', }, ], - partial: 'home', params: { style: 'fill', }, @@ -345,9 +350,9 @@ describe('Splitting keywords', () => { searches: [ { keywords: [], + partial: 'home', }, ], - partial: 'home', params: { style: 'stroke', },