Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/test/base/validate.ts
13388 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
export type KeywordPredicate =
6
| string
7
| { anyOf: readonly KeywordPredicate[] }
8
| { allOf: readonly KeywordPredicate[] }
9
| { not: readonly KeywordPredicate[] }
10
;
11
12
export function validate(answer: string, predicate: readonly KeywordPredicate[] | object): string | undefined {
13
const predicates = Array.isArray(predicate) ? predicate : Object.entries(predicate).map(([key, value]) => ({ [key]: value }));
14
const errors = predicates.map(pred => validatePredicate(answer, pred)).filter(err => !!err);
15
if (errors.length) {
16
return `Failed checks:\n${errors.join('\n')}`;
17
}
18
return undefined;
19
}
20
21
function validatePredicate(answer: string, predicate: KeywordPredicate): string | undefined {
22
if (typeof predicate === 'string') {
23
const startsWithWordChar = /^\w/.test(predicate);
24
const endsWithWordChar = /\w$/.test(predicate);
25
// Use word boundaries to prevent matching inside words
26
if (!new RegExp((startsWithWordChar ? '\\b' : '') + escapeRegExpCharacters(predicate) + (endsWithWordChar ? '\\b' : ''), 'i').test(answer)) {
27
return `Missing keyword: ${predicate}`;
28
}
29
return;
30
} else {
31
if ('anyOf' in predicate) {
32
const errors = (predicate.anyOf as readonly KeywordPredicate[])
33
.map(pred => validatePredicate(answer, pred));
34
35
if (!errors.some(err => typeof err === 'undefined')) {
36
return `All anyOf checks failed:\n${errors.join('\n')}`;
37
}
38
}
39
40
if ('allOf' in predicate) {
41
const result = validate(answer, predicate.allOf);
42
if (result?.length) {
43
return result;
44
}
45
}
46
47
if ('not' in predicate) {
48
const result = validate(answer, predicate.not);
49
if (!result?.length) {
50
return 'Expected not';
51
}
52
}
53
54
return;
55
}
56
}
57
58
/**
59
* Escapes regular expression characters in a given string
60
*/
61
function escapeRegExpCharacters(value: string): string {
62
return value.replace(/[\\\{\}\*\+\?\|\^\$\.\[\]\(\)]/g, '\\$&');
63
}
64