diff --git a/src/common/framework/params_utils.ts b/src/common/framework/params_utils.ts index e8c9f4cedda5..8292e4533edf 100644 --- a/src/common/framework/params_utils.ts +++ b/src/common/framework/params_utils.ts @@ -2,10 +2,20 @@ import { comparePublicParamsPaths, Ordering } from './query/compare.js'; import { kWildcard, kParamSeparator, kParamKVSeparator } from './query/separators.js'; // Consider adding more types here if needed -export type ParamArgument = void | undefined | number | string | boolean | number[]; -export interface CaseParams { +// +// TODO: This type isn't actually used to constrain what you're allowed to do in `.params()`, so +// it's not really serving its purpose. Figure out how to fix that? +export type ParamArgument = + | undefined + | null + | number + | string + | boolean + | number[] + | { readonly [k: string]: undefined | null | number | string | boolean }; +export type CaseParams = { readonly [k: string]: ParamArgument; -} +}; export interface CaseParamsRW { [k: string]: ParamArgument; } diff --git a/src/common/framework/query/encode_selectively.ts b/src/common/framework/query/encode_selectively.ts index 38bbaf02a81e..ab1997b6e458 100644 --- a/src/common/framework/query/encode_selectively.ts +++ b/src/common/framework/query/encode_selectively.ts @@ -16,6 +16,8 @@ export function encodeURIComponentSelectively(s: string): string { ret = ret.replace(/%3D/g, '='); // for params (k=v) ret = ret.replace(/%5B/g, '['); // for JSON arrays ret = ret.replace(/%5D/g, ']'); // for JSON arrays + ret = ret.replace(/%7B/g, '{'); // for JSON objects + ret = ret.replace(/%7D/g, '}'); // for JSON objects ret = ret.replace(/%E2%9C%97/g, '✗'); // for jsUndefinedMagicValue return ret; } diff --git a/src/common/framework/query/parseQuery.ts b/src/common/framework/query/parseQuery.ts index b8834421dd33..bcbb23e86b8e 100644 --- a/src/common/framework/query/parseQuery.ts +++ b/src/common/framework/query/parseQuery.ts @@ -30,9 +30,29 @@ function parseQueryImpl(s: string): TestQuery { // Undo encodeURIComponentSelectively s = decodeURIComponent(s); - // bigParts are: suite, group, test, params (note kBigSeparator could appear in params) - const [suite, fileString, testString, paramsString] = s.split(kBigSeparator, 4); - assert(fileString !== undefined, `filter string must have at least one ${kBigSeparator}`); + // 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); diff --git a/src/demo/json.spec.ts b/src/demo/json.spec.ts new file mode 100644 index 000000000000..84cbf0c8054b --- /dev/null +++ b/src/demo/json.spec.ts @@ -0,0 +1,10 @@ +export const description = 'Description for a.spec.ts'; + +import { makeTestGroup } from '../common/framework/test_group.js'; +import { UnitTest } from '../unittests/unit_test.js'; + +export const g = makeTestGroup(UnitTest); + +g.test('json') + .params([{ p: { x: 1, y: 'two' } }]) + .fn(() => {}); diff --git a/src/unittests/url_query.spec.ts b/src/unittests/url_query.spec.ts index 1a9e8fc3aaf5..c3908596cf8d 100644 --- a/src/unittests/url_query.spec.ts +++ b/src/unittests/url_query.spec.ts @@ -27,10 +27,20 @@ g.test('stringifyQuery,single_case').fn(t => { new TestQuerySingleCase('a', ['b_1', '2_c'], ['d_3', '4_e'], { f: 'g', _pri1: 0, - a: 3, + x: 3, _pri2: 1, }), - 'a:b_1,2_c:d_3,4_e:f="g";a=3' + 'a:b_1,2_c:d_3,4_e:f="g";x=3' + ); +}); + +g.test('stringifyQuery,single_case,json').fn(t => { + t.expectQueryString( + new TestQuerySingleCase('a', ['b_1', '2_c'], ['d_3', '4_e'], { + f: 'g', + x: { p: 2, q: 'Q' }, + }), + 'a:b_1,2_c:d_3,4_e:f="g";x={"p":2,"q":"Q"}' ); });