chore: allow different partial keywords for multiple searches

This commit is contained in:
Vjacheslav Trushkin 2023-05-18 22:41:15 +03:00
parent bdd286b32d
commit 2e2ca0f3b2
5 changed files with 400 additions and 444 deletions

View File

@ -41,28 +41,6 @@ export function search(
return; 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 // Get prefixes
const basePrefixes = filterSearchPrefixes(data, iconSets, fullParams); const basePrefixes = filterSearchPrefixes(data, iconSets, fullParams);
@ -92,139 +70,130 @@ export function search(
}; };
const limit = params.limit; const limit = params.limit;
// Run all searches interface ExtendedSearchKeywordsEntry extends SearchKeywordsEntry {
const check = (isExact: boolean, partial?: string) => { // Add prefixes cache to avoid re-calculating it for every partial keyword
for (let searchIndex = 0; searchIndex < keywords.searches.length; searchIndex++) { filteredPrefixes?: Readonly<string[]>;
// Add prefixes cache to avoid re-calculating it for every partial keyword }
interface ExtendedSearchKeywordsEntry extends SearchKeywordsEntry { const runSearch = (search: ExtendedSearchKeywordsEntry, isExact: boolean, partial?: string) => {
filteredPrefixes?: Readonly<string[]>; // Filter prefixes (or get it from cache)
let filteredPrefixes: Readonly<string[]>;
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) search.filteredPrefixes = filteredPrefixes;
let filteredPrefixes: Readonly<string[]>; }
if (search.filteredPrefixes) { if (!filteredPrefixes.length) {
filteredPrefixes = search.filteredPrefixes; return;
} else { }
filteredPrefixes = search.prefixes
? filterSearchPrefixesList(basePrefixes, search.prefixes)
: basePrefixes;
// Filter by required keywords // Get keywords
for (let i = 0; i < search.keywords.length; i++) { const testKeywords = partial ? search.keywords.concat([partial]) : search.keywords;
filteredPrefixes = filteredPrefixes.filter((prefix) => const testMatches = search.test ? search.test.concat(testKeywords) : testKeywords;
data.keywords[search.keywords[i]].has(prefix)
);
}
search.filteredPrefixes = filteredPrefixes; // Check for partial keyword if testing for exact match
} if (partial) {
if (!filteredPrefixes.length) { 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; continue;
} }
// Get keywords // Check icons in current prefix
const testKeywords = partial ? search.keywords.concat([partial]) : search.keywords; let matches: IconSetIconNames[] | undefined;
const testMatches = search.test ? search.test.concat(testKeywords) : testKeywords; 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 (!matches) {
if (partial) { // Copy all matches
filteredPrefixes = filteredPrefixes.filter((prefix) => data.keywords[partial].has(prefix)); matches = Array.from(keywordMatches);
} else {
// Match previous set
matches = matches.filter((item) => keywordMatches.has(item));
}
} }
// Check icons // Test matched icons
for (let prefixIndex = 0; prefixIndex < filteredPrefixes.length; prefixIndex++) { if (!failed && matches) {
const prefix = filteredPrefixes[prefixIndex]; for (let matchIndex = 0; matchIndex < matches.length; matchIndex++) {
const prefixAddedIcons = addedIcons[prefix] || (addedIcons[prefix] = new Set()); const item = matches[matchIndex];
const iconSet = iconSets[prefix].item; if (prefixAddedIcons.has(item)) {
const iconSetIcons = iconSet.icons; // Already added
const iconSetKeywords = iconSetIcons.keywords; continue;
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;
} }
if (!matches) { // Check style
// Copy all matches if (
matches = Array.from(keywordMatches); // Style is set
} else { fullParams.style &&
// Match previous set // Enabled in config
matches = matches.filter((item) => keywordMatches.has(item)); 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 // Find icon name that matches all keywords
if (!failed && matches) { let length: number | undefined;
for (let matchIndex = 0; matchIndex < matches.length; matchIndex++) { const name = item.find((name, index) => {
const item = matches[matchIndex]; for (let i = 0; i < testMatches.length; i++) {
if (prefixAddedIcons.has(item)) { if (name.indexOf(testMatches[i]) === -1) {
// Already added return false;
continue; }
}
// Check style // Get length
if ( if (!index) {
// Style is set // First item sets `_l`, unless it didn't match any prefixes/suffixes
fullParams.style && length = item._l || name.length;
// Enabled in config } else if (iconSet.themeParts) {
appConfig.allowFilterIconsByStyle && // Alias: calculate length
// Icon set has mixed style (so it is assigned to icons) -> check icon const themeParts = iconSet.themeParts;
iconSetIcons.iconStyle === 'mixed' && for (let partIndex = 0; partIndex < themeParts.length; partIndex++) {
item._is !== fullParams.style const part = themeParts[partIndex];
) { if (name.startsWith(part + '-') || name.endsWith('-' + part)) {
// Different icon style length = name.length - part.length - 1;
continue; break;
}
// 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;
}
} }
} }
} }
return true; }
}); return true;
if (name) { });
// Add icon if (name) {
prefixAddedIcons.add(item); // Add icon
prefixAddedIcons.add(item);
const list = getMatchResult(length || name.length, !isExact); const list = getMatchResult(length || name.length, !isExact);
list.names.push(prefix + ':' + name); list.names.push(prefix + ':' + name);
allMatchesLength++; allMatchesLength++;
if (!isExact && allMatchesLength >= limit) { if (!isExact && allMatchesLength >= limit) {
// Return only if checking for partials and limit reached // Return only if checking for partials and limit reached
return; return;
}
} }
} }
} }
@ -232,20 +201,51 @@ export function search(
} }
}; };
// Check all keywords const runAllSearches = (isExact: boolean) => {
if (!partialKeywords) { for (let searchIndex = 0; searchIndex < keywords.searches.length; searchIndex++) {
check(true); const search = keywords.searches[searchIndex];
} else { const partial = search.partial;
let partial: string | undefined; if (partial) {
while ((partial = partialKeywords.shift())) { // Has partial
check(isFirstKeywordExact, partial); if (isExact) {
if (allMatchesLength >= limit) { if (data.keywords[partial]) {
break; 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 // Check limit
isFirstKeywordExact = false; 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 // Generate results

View File

@ -21,20 +21,15 @@ interface SplitResultItem {
// Strings to test icon name // Strings to test icon name
test?: string[]; test?: string[];
}
interface SplitResult { // Partial keyword. It is last chunk of last keyword, which cannot be treated as prefix
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?: string; partial?: string;
} }
type SplitResult = SplitResultItem[];
export function splitKeywordEntries(values: string[], options: SplitOptions): SplitResult | undefined { export function splitKeywordEntries(values: string[], options: SplitOptions): SplitResult | undefined {
const results: SplitResult = { const results: SplitResult = [];
searches: [],
};
let invalid = false; let invalid = false;
// Split each entry into arrays // 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('-'); return (items[0].empty ? '-' : '') + items.map((item) => item.value).join('-');
} }
interface ResultsSet {
keywords: Set<string>;
test: Set<string>;
partial?: string;
}
// Function to add item // Function to add item
function add(items: Entry[], keywords: Set<string>, test: Set<string>, checkPartial: boolean) { function addToSet(items: Entry[], set: ResultsSet, allowPartial: boolean) {
let partial: string | undefined; let partial: string | undefined;
// Add keywords // Add keywords
@ -92,10 +93,10 @@ export function splitKeywordEntries(values: string[], options: SplitOptions): Sp
for (let i = 0; i <= max; i++) { for (let i = 0; i <= max; i++) {
const value = items[i]; const value = items[i];
if (!value.empty) { if (!value.empty) {
if (i === max && checkPartial && value.value.length >= minPartialKeywordLength) { if (i === max && allowPartial && value.value.length >= minPartialKeywordLength) {
partial = value.value; partial = value.value;
} else { } 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 // Get test value
const testValue = valuesToString(items); const testValue = valuesToString(items);
if (testValue) { if (testValue) {
test.add(testValue); set.test.add(testValue);
} }
// Validate partial // Add partial
if (checkPartial) { if (allowPartial && partial) {
if (results.searches.length) { if (set.partial && set.partial !== partial) {
if (results.partial !== partial) { console.error('Different partial keywords. This should not be happening!');
// 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;
} }
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; const prefix = firstItem.length > 1 ? valuesToString(firstItem) : firstItem[0].value;
if (prefix) { if (prefix) {
// Valid prefix // Valid prefix
const keywords: Set<string> = new Set(); const set: ResultsSet = {
const test: Set<string> = new Set(); keywords: new Set(),
test: new Set(),
};
for (let i = 1; i <= lastIndex; i++) { for (let i = 1; i <= lastIndex; i++) {
add(splitValues[i], keywords, test, options.partial && i === lastIndex); addToSet(splitValues[i], set, 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);
} }
addToResult(set, prefix);
} }
} }
} }
@ -159,41 +162,26 @@ export function splitKeywordEntries(values: string[], options: SplitOptions): Sp
if (maxFirstItemIndex && !firstItem[0].empty && !firstItem[1].empty) { if (maxFirstItemIndex && !firstItem[0].empty && !firstItem[1].empty) {
const modifiedFirstItem = firstItem.slice(0); const modifiedFirstItem = firstItem.slice(0);
const prefix = modifiedFirstItem.shift()!.value; const prefix = modifiedFirstItem.shift()!.value;
const keywords: Set<string> = new Set(); const set: ResultsSet = {
const test: Set<string> = new Set(); keywords: new Set(),
test: new Set(),
};
for (let i = 0; i <= lastIndex; i++) { for (let i = 0; i <= lastIndex; i++) {
add(i ? splitValues[i] : modifiedFirstItem, keywords, test, options.partial && i === lastIndex); addToSet(i ? splitValues[i] : modifiedFirstItem, set, 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);
} }
addToResult(set, prefix);
} }
} }
// Add as is // Add as is
const keywords: Set<string> = new Set(); const set: ResultsSet = {
const test: Set<string> = new Set(); keywords: new Set(),
test: new Set(),
};
for (let i = 0; i <= lastIndex; i++) { for (let i = 0; i <= lastIndex; i++) {
add(splitValues[i], keywords, test, options.partial && i === lastIndex); addToSet(splitValues[i], set, 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);
} }
addToResult(set);
// Merge values // Merge values
if (splitValues.length > 1) { if (splitValues.length > 1) {
@ -233,22 +221,14 @@ export function splitKeywordEntries(values: string[], options: SplitOptions): Sp
...splitValues.slice(endIndex + 1), ...splitValues.slice(endIndex + 1),
]; ];
const newLastIndex = newSplitValues.length - 1; const newLastIndex = newSplitValues.length - 1;
const keywords: Set<string> = new Set(); const set: ResultsSet = {
const test: Set<string> = new Set(); keywords: new Set(),
test: new Set(),
};
for (let i = 0; i <= newLastIndex; i++) { for (let i = 0; i <= newLastIndex; i++) {
add(newSplitValues[i], keywords, test, false); addToSet(newSplitValues[i], set, options.partial && i === newLastIndex);
}
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);
} }
addToResult(set);
} }
} }
} }
@ -484,7 +464,7 @@ export function splitKeyword(keyword: string, allowPartial = true): SearchKeywor
return; return;
} }
const searches: SearchKeywordsEntry[] = entries.searches.map((item) => { const searches: SearchKeywordsEntry[] = entries.map((item) => {
return { return {
...item, ...item,
prefixes: item.prefix prefixes: item.prefix
@ -505,6 +485,5 @@ export function splitKeyword(keyword: string, allowPartial = true): SearchKeywor
return { return {
searches, searches,
params, params,
partial: entries.partial,
}; };
} }

View File

@ -67,6 +67,9 @@ export interface SearchKeywordsEntry {
// Strings to test icon value // Strings to test icon value
test?: string[]; test?: string[];
// Partial keyword
partial?: string;
} }
/** /**
@ -76,9 +79,6 @@ export interface SearchKeywords {
// List of searches // List of searches
searches: SearchKeywordsEntry[]; searches: SearchKeywordsEntry[];
// Partial keyword, used in all matches
partial?: string;
// Params extracted from keywords // Params extracted from keywords
params: Partial<SearchParams>; params: Partial<SearchParams>;
} }

View File

@ -37,40 +37,34 @@ describe('Splitting keywords', () => {
prefix: false, prefix: false,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ keywords: ['home'],
keywords: ['home'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['home'], { splitKeywordEntries(['home'], {
prefix: true, prefix: true,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ keywords: ['home'],
keywords: ['home'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['home'], { splitKeywordEntries(['home'], {
prefix: true, prefix: true,
partial: true, partial: true,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ keywords: [],
keywords: [], partial: 'home',
}, },
], ]);
partial: 'home',
});
}); });
test('Multiple simple entries', () => { test('Multiple simple entries', () => {
@ -79,79 +73,73 @@ describe('Splitting keywords', () => {
prefix: false, prefix: false,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ keywords: ['mdi', 'home'],
keywords: ['mdi', 'home'], },
}, {
{ keywords: ['mdihome'],
keywords: ['mdihome'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['mdi', 'home', 'outline'], { splitKeywordEntries(['mdi', 'home', 'outline'], {
prefix: false, prefix: false,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ keywords: ['mdi', 'home', 'outline'],
keywords: ['mdi', 'home', 'outline'], },
}, {
{ keywords: ['mdihome', 'outline'],
keywords: ['mdihome', 'outline'], },
}, {
{ keywords: ['mdihomeoutline'],
keywords: ['mdihomeoutline'], },
}, {
{ keywords: ['mdi', 'homeoutline'],
keywords: ['mdi', 'homeoutline'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['mdi', 'home'], { splitKeywordEntries(['mdi', 'home'], {
prefix: true, prefix: true,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ prefix: 'mdi',
prefix: 'mdi', keywords: ['home'],
keywords: ['home'], },
}, {
{ keywords: ['mdi', 'home'],
keywords: ['mdi', 'home'], },
}, {
{ keywords: ['mdihome'],
keywords: ['mdihome'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['mdi', 'home'], { splitKeywordEntries(['mdi', 'home'], {
prefix: true, prefix: true,
partial: true, partial: true,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ prefix: 'mdi',
prefix: 'mdi', keywords: [],
keywords: [], partial: 'home',
}, },
{ {
keywords: ['mdi'], keywords: ['mdi'],
}, partial: 'home',
{ },
keywords: ['mdihome'], {
}, keywords: [],
], partial: 'mdihome',
partial: 'home', },
}); ]);
}); });
test('Incomplete prefix', () => { test('Incomplete prefix', () => {
@ -160,51 +148,46 @@ describe('Splitting keywords', () => {
prefix: false, prefix: false,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ keywords: ['mdi', 'home'],
keywords: ['mdi', 'home'], test: ['mdi-'],
test: ['mdi-'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['mdi-', 'home'], { splitKeywordEntries(['mdi-', 'home'], {
prefix: true, prefix: true,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ prefix: 'mdi-',
prefix: 'mdi-', keywords: ['home'],
keywords: ['home'], },
}, {
{ keywords: ['mdi', 'home'],
keywords: ['mdi', 'home'], test: ['mdi-'],
test: ['mdi-'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['mdi-', 'home'], { splitKeywordEntries(['mdi-', 'home'], {
prefix: true, prefix: true,
partial: true, partial: true,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ prefix: 'mdi-',
prefix: 'mdi-', keywords: [],
keywords: [], partial: 'home',
}, },
{ {
keywords: ['mdi'], keywords: ['mdi'],
test: ['mdi-'], partial: 'home',
}, test: ['mdi-'],
], },
partial: 'home', ]);
});
}); });
test('Long entry', () => { test('Long entry', () => {
@ -213,53 +196,48 @@ describe('Splitting keywords', () => {
prefix: false, prefix: false,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ keywords: ['mdi', 'home', 'outline'],
keywords: ['mdi', 'home', 'outline'], test: ['mdi-home-outline'],
test: ['mdi-home-outline'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['mdi-home-outline'], { splitKeywordEntries(['mdi-home-outline'], {
prefix: true, prefix: true,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ prefix: 'mdi',
prefix: 'mdi', keywords: ['home', 'outline'],
keywords: ['home', 'outline'], test: ['home-outline'],
test: ['home-outline'], },
}, {
{ keywords: ['mdi', 'home', 'outline'],
keywords: ['mdi', 'home', 'outline'], test: ['mdi-home-outline'],
test: ['mdi-home-outline'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['mdi-home-outline'], { splitKeywordEntries(['mdi-home-outline'], {
prefix: true, prefix: true,
partial: true, partial: true,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ prefix: 'mdi',
prefix: 'mdi', keywords: ['home'],
keywords: ['home'], partial: 'outline',
test: ['home-outline'], test: ['home-outline'],
}, },
{ {
keywords: ['mdi', 'home'], keywords: ['mdi', 'home'],
test: ['mdi-home-outline'], partial: 'outline',
}, test: ['mdi-home-outline'],
], },
partial: 'outline', ]);
});
}); });
test('Complex entries', () => { test('Complex entries', () => {
@ -268,77 +246,71 @@ describe('Splitting keywords', () => {
prefix: false, prefix: false,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ keywords: ['mdi', 'light', 'arrow', 'left'],
keywords: ['mdi', 'light', 'arrow', 'left'], test: ['mdi-light', 'arrow-left'],
test: ['mdi-light', 'arrow-left'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['mdi-light', 'arrow-left'], { splitKeywordEntries(['mdi-light', 'arrow-left'], {
prefix: true, prefix: true,
partial: false, partial: false,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ prefix: 'mdi-light',
prefix: 'mdi-light', keywords: ['arrow', 'left'],
keywords: ['arrow', 'left'], test: ['arrow-left'],
test: ['arrow-left'], },
}, {
{ prefix: 'mdi',
prefix: 'mdi', keywords: ['light', 'arrow', 'left'],
keywords: ['light', 'arrow', 'left'], test: ['arrow-left'],
test: ['arrow-left'], },
}, {
{ keywords: ['mdi', 'light', 'arrow', 'left'],
keywords: ['mdi', 'light', 'arrow', 'left'], test: ['mdi-light', 'arrow-left'],
test: ['mdi-light', 'arrow-left'], },
}, ]);
],
});
expect( expect(
splitKeywordEntries(['mdi-light', 'arrow-left'], { splitKeywordEntries(['mdi-light', 'arrow-left'], {
prefix: false, prefix: false,
partial: true, partial: true,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ keywords: ['mdi', 'light', 'arrow'],
keywords: ['mdi', 'light', 'arrow'], partial: 'left',
test: ['mdi-light', 'arrow-left'], test: ['mdi-light', 'arrow-left'],
}, },
], ]);
partial: 'left',
});
expect( expect(
splitKeywordEntries(['mdi-light', 'arrow-left'], { splitKeywordEntries(['mdi-light', 'arrow-left'], {
prefix: true, prefix: true,
partial: true, partial: true,
}) })
).toEqual({ ).toEqual([
searches: [ {
{ prefix: 'mdi-light',
prefix: 'mdi-light', keywords: ['arrow'],
keywords: ['arrow'], partial: 'left',
test: ['arrow-left'], test: ['arrow-left'],
}, },
{ {
prefix: 'mdi', prefix: 'mdi',
keywords: ['light', 'arrow'], keywords: ['light', 'arrow'],
test: ['arrow-left'], partial: 'left',
}, test: ['arrow-left'],
{ },
keywords: ['mdi', 'light', 'arrow'], {
test: ['mdi-light', 'arrow-left'], keywords: ['mdi', 'light', 'arrow'],
}, partial: 'left',
], test: ['mdi-light', 'arrow-left'],
partial: 'left', },
}); ]);
}); });
}); });

View File

@ -20,13 +20,14 @@ describe('Splitting keywords', () => {
prefixes: ['mdi'], prefixes: ['mdi'],
prefix: 'mdi', // leftover from internal function prefix: 'mdi', // leftover from internal function
keywords: [], keywords: [],
partial: 'home',
}, },
{ {
keywords: ['mdi'], keywords: ['mdi'],
partial: 'home',
test: ['mdi-home'], test: ['mdi-home'],
}, },
], ],
partial: 'home',
params: {}, params: {},
}); });
expect(splitKeyword('mdi-home', false)).toEqual({ expect(splitKeyword('mdi-home', false)).toEqual({
@ -50,9 +51,9 @@ describe('Splitting keywords', () => {
{ {
prefixes: ['mdi'], prefixes: ['mdi'],
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: {}, params: {},
}); });
expect(splitKeyword('mdi:home', false)).toEqual({ expect(splitKeyword('mdi:home', false)).toEqual({
@ -71,9 +72,9 @@ describe('Splitting keywords', () => {
{ {
prefixes: ['mdi'], prefixes: ['mdi'],
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: {}, params: {},
}); });
expect(splitKeyword('prefix:mdi home', false)).toEqual({ expect(splitKeyword('prefix:mdi home', false)).toEqual({
@ -92,9 +93,9 @@ describe('Splitting keywords', () => {
{ {
prefixes: ['mdi'], prefixes: ['mdi'],
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: {}, params: {},
}); });
expect(splitKeyword('prefix=mdi home', false)).toEqual({ expect(splitKeyword('prefix=mdi home', false)).toEqual({
@ -113,9 +114,9 @@ describe('Splitting keywords', () => {
{ {
prefixes: ['mdi'], prefixes: ['mdi'],
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: {}, params: {},
}); });
expect(splitKeyword('prefixes:mdi home', false)).toEqual({ expect(splitKeyword('prefixes:mdi home', false)).toEqual({
@ -134,9 +135,9 @@ describe('Splitting keywords', () => {
{ {
prefixes: ['fa6-', 'mdi-'], prefixes: ['fa6-', 'mdi-'],
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: {}, params: {},
}); });
expect(splitKeyword('prefixes:fa6-,mdi- home', false)).toEqual({ expect(splitKeyword('prefixes:fa6-,mdi- home', false)).toEqual({
@ -155,9 +156,9 @@ describe('Splitting keywords', () => {
{ {
prefixes: ['mdi', 'mdi-'], prefixes: ['mdi', 'mdi-'],
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: {}, params: {},
}); });
expect(splitKeyword('prefixes=mdi* home', false)).toEqual({ expect(splitKeyword('prefixes=mdi* home', false)).toEqual({
@ -177,18 +178,20 @@ describe('Splitting keywords', () => {
prefixes: ['mdi-light'], prefixes: ['mdi-light'],
prefix: 'mdi-light', prefix: 'mdi-light',
keywords: [], keywords: [],
partial: 'home',
}, },
{ {
prefixes: ['mdi'], prefixes: ['mdi'],
prefix: 'mdi', prefix: 'mdi',
keywords: ['light'], keywords: ['light'],
partial: 'home',
}, },
{ {
keywords: ['mdi', 'light'], keywords: ['mdi', 'light'],
test: ['mdi-light'], test: ['mdi-light'],
partial: 'home',
}, },
], ],
partial: 'home',
params: {}, params: {},
}); });
expect(splitKeyword('mdi-light home', false)).toEqual({ expect(splitKeyword('mdi-light home', false)).toEqual({
@ -218,20 +221,22 @@ describe('Splitting keywords', () => {
prefixes: ['mdi-light'], prefixes: ['mdi-light'],
prefix: 'mdi-light', prefix: 'mdi-light',
keywords: ['home'], keywords: ['home'],
partial: 'outline',
test: ['home-outline'], test: ['home-outline'],
}, },
{ {
prefixes: ['mdi'], prefixes: ['mdi'],
prefix: 'mdi', prefix: 'mdi',
keywords: ['light', 'home'], keywords: ['light', 'home'],
partial: 'outline',
test: ['home-outline'], test: ['home-outline'],
}, },
{ {
keywords: ['mdi', 'light', 'home'], keywords: ['mdi', 'light', 'home'],
partial: 'outline',
test: ['mdi-light', 'home-outline'], test: ['mdi-light', 'home-outline'],
}, },
], ],
partial: 'outline',
params: {}, params: {},
}); });
expect(splitKeyword('mdi-light home-outline', false)).toEqual({ expect(splitKeyword('mdi-light home-outline', false)).toEqual({
@ -262,9 +267,9 @@ describe('Splitting keywords', () => {
searches: [ searches: [
{ {
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: { params: {
palette: true, palette: true,
}, },
@ -274,9 +279,9 @@ describe('Splitting keywords', () => {
searches: [ searches: [
{ {
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: { params: {
palette: false, palette: false,
}, },
@ -287,9 +292,9 @@ describe('Splitting keywords', () => {
{ {
prefixes: ['mdi', 'mdi-', 'fa6-'], prefixes: ['mdi', 'mdi-', 'fa6-'],
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: {}, params: {},
}); });
@ -309,9 +314,9 @@ describe('Splitting keywords', () => {
searches: [ searches: [
{ {
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: { params: {
style: 'fill', style: 'fill',
}, },
@ -321,9 +326,9 @@ describe('Splitting keywords', () => {
searches: [ searches: [
{ {
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: { params: {
style: 'stroke', style: 'stroke',
}, },
@ -333,9 +338,9 @@ describe('Splitting keywords', () => {
searches: [ searches: [
{ {
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: { params: {
style: 'fill', style: 'fill',
}, },
@ -345,9 +350,9 @@ describe('Splitting keywords', () => {
searches: [ searches: [
{ {
keywords: [], keywords: [],
partial: 'home',
}, },
], ],
partial: 'home',
params: { params: {
style: 'stroke', style: 'stroke',
}, },