Skip to content

Commit

Permalink
Support JSON objects in param values (#270)
Browse files Browse the repository at this point in the history
This was mostly supported before, but parsed incorrectly in query strings.
  • Loading branch information
kainino0x authored Aug 19, 2020
1 parent d72562e commit e956025
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 8 deletions.
16 changes: 13 additions & 3 deletions src/common/framework/params_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/common/framework/query/encode_selectively.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
26 changes: 23 additions & 3 deletions src/common/framework/query/parseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
10 changes: 10 additions & 0 deletions src/demo/json.spec.ts
Original file line number Diff line number Diff line change
@@ -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(() => {});
14 changes: 12 additions & 2 deletions src/unittests/url_query.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"}'
);
});

Expand Down

0 comments on commit e956025

Please sign in to comment.