From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../src/common/internal/query/parseQuery.ts | 155 +++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 dom/webgpu/tests/cts/checkout/src/common/internal/query/parseQuery.ts (limited to 'dom/webgpu/tests/cts/checkout/src/common/internal/query/parseQuery.ts') diff --git a/dom/webgpu/tests/cts/checkout/src/common/internal/query/parseQuery.ts b/dom/webgpu/tests/cts/checkout/src/common/internal/query/parseQuery.ts new file mode 100644 index 0000000000..996835b0ec --- /dev/null +++ b/dom/webgpu/tests/cts/checkout/src/common/internal/query/parseQuery.ts @@ -0,0 +1,155 @@ +import { assert } from '../../util/util.js'; +import { + TestParamsRW, + JSONWithUndefined, + badParamValueChars, + paramKeyIsPublic, +} from '../params_utils.js'; + +import { parseParamValue } from './json_param_value.js'; +import { + TestQuery, + TestQueryMultiFile, + TestQueryMultiTest, + TestQueryMultiCase, + TestQuerySingleCase, +} from './query.js'; +import { kBigSeparator, kWildcard, kPathSeparator, kParamSeparator } from './separators.js'; +import { validQueryPart } from './validQueryPart.js'; + +export function parseQuery(s: string): TestQuery { + try { + return parseQueryImpl(s); + } catch (ex) { + if (ex instanceof Error) { + ex.message += '\n on: ' + s; + } + throw ex; + } +} + +function parseQueryImpl(s: string): TestQuery { + // Undo encodeURIComponentSelectively + s = decodeURIComponent(s); + + // bigParts are: suite, file, test, params (note kBigSeparator could appear in params) + let suite: string; + let fileString: string | undefined; + let testString: string | undefined; + let paramsString: string | undefined; + { + const i1 = s.indexOf(kBigSeparator); + assert(i1 !== -1, `query string must have at least one ${kBigSeparator}`); + suite = s.substring(0, i1); + const i2 = s.indexOf(kBigSeparator, i1 + 1); + if (i2 === -1) { + fileString = s.substring(i1 + 1); + } else { + fileString = s.substring(i1 + 1, i2); + const i3 = s.indexOf(kBigSeparator, i2 + 1); + if (i3 === -1) { + testString = s.substring(i2 + 1); + } else { + testString = s.substring(i2 + 1, i3); + paramsString = s.substring(i3 + 1); + } + } + } + + const { parts: file, wildcard: filePathHasWildcard } = parseBigPart(fileString, kPathSeparator); + + if (testString === undefined) { + // Query is file-level + assert( + filePathHasWildcard, + `File-level query without wildcard ${kWildcard}. Did you want a file-level query \ +(append ${kPathSeparator}${kWildcard}) or test-level query (append ${kBigSeparator}${kWildcard})?` + ); + return new TestQueryMultiFile(suite, file); + } + assert(!filePathHasWildcard, `Wildcard ${kWildcard} must be at the end of the query string`); + + const { parts: test, wildcard: testPathHasWildcard } = parseBigPart(testString, kPathSeparator); + + if (paramsString === undefined) { + // Query is test-level + assert( + testPathHasWildcard, + `Test-level query without wildcard ${kWildcard}; did you want a test-level query \ +(append ${kPathSeparator}${kWildcard}) or case-level query (append ${kBigSeparator}${kWildcard})?` + ); + assert(file.length > 0, 'File part of test-level query was empty (::)'); + return new TestQueryMultiTest(suite, file, test); + } + + // Query is case-level + assert(!testPathHasWildcard, `Wildcard ${kWildcard} must be at the end of the query string`); + + const { parts: paramsParts, wildcard: paramsHasWildcard } = parseBigPart( + paramsString, + kParamSeparator + ); + + assert(test.length > 0, 'Test part of case-level query was empty (::)'); + + const params: TestParamsRW = {}; + for (const paramPart of paramsParts) { + const [k, v] = parseSingleParam(paramPart); + assert(validQueryPart.test(k), `param key names must match ${validQueryPart}`); + params[k] = v; + } + if (paramsHasWildcard) { + return new TestQueryMultiCase(suite, file, test, params); + } else { + return new TestQuerySingleCase(suite, file, test, params); + } +} + +// webgpu:a,b,* or webgpu:a,b,c:* +const kExampleQueries = `\ +webgpu${kBigSeparator}a${kPathSeparator}b${kPathSeparator}${kWildcard} or \ +webgpu${kBigSeparator}a${kPathSeparator}b${kPathSeparator}c${kBigSeparator}${kWildcard}`; + +function parseBigPart( + s: string, + separator: typeof kParamSeparator | typeof kPathSeparator +): { parts: string[]; wildcard: boolean } { + if (s === '') { + return { parts: [], wildcard: false }; + } + const parts = s.split(separator); + + let endsWithWildcard = false; + for (const [i, part] of parts.entries()) { + if (i === parts.length - 1) { + endsWithWildcard = part === kWildcard; + } + assert( + part.indexOf(kWildcard) === -1 || endsWithWildcard, + `Wildcard ${kWildcard} must be complete last part of a path (e.g. ${kExampleQueries})` + ); + } + if (endsWithWildcard) { + // Remove the last element of the array (which is just the wildcard). + parts.length = parts.length - 1; + } + return { parts, wildcard: endsWithWildcard }; +} + +function parseSingleParam(paramSubstring: string): [string, JSONWithUndefined] { + assert(paramSubstring !== '', 'Param in a query must not be blank (is there a trailing comma?)'); + const i = paramSubstring.indexOf('='); + assert(i !== -1, 'Param in a query must be of form key=value'); + const k = paramSubstring.substring(0, i); + assert(paramKeyIsPublic(k), 'Param in a query must not be private (start with _)'); + const v = paramSubstring.substring(i + 1); + return [k, parseSingleParamValue(v)]; +} + +function parseSingleParamValue(s: string): JSONWithUndefined { + assert( + !badParamValueChars.test(s), + `param value must not match ${badParamValueChars} - was ${s}` + ); + return parseParamValue(s); +} -- cgit v1.2.3