mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-12 19:39:20 -05:00
63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
export type KeywordPredicate =
|
|
| string
|
|
| { anyOf: readonly KeywordPredicate[] }
|
|
| { allOf: readonly KeywordPredicate[] }
|
|
| { not: readonly KeywordPredicate[] }
|
|
;
|
|
|
|
export function validate(answer: string, predicate: readonly KeywordPredicate[] | object): string | undefined {
|
|
const predicates = Array.isArray(predicate) ? predicate : Object.entries(predicate).map(([key, value]) => ({ [key]: value }));
|
|
const errors = predicates.map(pred => validatePredicate(answer, pred)).filter(err => !!err);
|
|
if (errors.length) {
|
|
return `Failed checks:\n${errors.join('\n')}`;
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
function validatePredicate(answer: string, predicate: KeywordPredicate): string | undefined {
|
|
if (typeof predicate === 'string') {
|
|
const startsWithWordChar = /^\w/.test(predicate);
|
|
const endsWithWordChar = /\w$/.test(predicate);
|
|
// Use word boundaries to prevent matching inside words
|
|
if (!new RegExp((startsWithWordChar ? '\\b' : '') + escapeRegExpCharacters(predicate) + (endsWithWordChar ? '\\b' : ''), 'i').test(answer)) {
|
|
return `Missing keyword: ${predicate}`;
|
|
}
|
|
return;
|
|
} else {
|
|
if ('anyOf' in predicate) {
|
|
const errors = (predicate.anyOf as readonly KeywordPredicate[])
|
|
.map(pred => validatePredicate(answer, pred));
|
|
|
|
if (!errors.some(err => typeof err === 'undefined')) {
|
|
return `All anyOf checks failed:\n${errors.join('\n')}`;
|
|
}
|
|
}
|
|
|
|
if ('allOf' in predicate) {
|
|
const result = validate(answer, predicate.allOf);
|
|
if (result?.length) {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
if ('not' in predicate) {
|
|
const result = validate(answer, predicate.not);
|
|
if (!result?.length) {
|
|
return 'Expected not';
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Escapes regular expression characters in a given string
|
|
*/
|
|
function escapeRegExpCharacters(value: string): string {
|
|
return value.replace(/[\\\{\}\*\+\?\|\^\$\.\[\]\(\)]/g, '\\$&');
|
|
} |