mirror of
https://github.com/divkit/divkit.git
synced 2026-05-07 20:02:32 +00:00
Integration tests
commit_hash:951943346e70aea6a4cc69b5a69e9f466a314812
This commit is contained in:
@@ -494,25 +494,22 @@ function evalCallExpression(ctx: EvalContext, expr: CallExpression): EvalValue {
|
||||
function logFunctionMatchError(funcName: string, args: EvalValue[], findRes: FuncMatchError): never {
|
||||
const argsType = args.map(arg => typeToString(arg.type)).join(', ');
|
||||
const prefix = `${funcName}(${argsToStr(args)})`;
|
||||
const funcList = funcs.get(funcName) || [];
|
||||
const firstFunc = funcList[0];
|
||||
const hasOverloads = funcList.length > 1;
|
||||
|
||||
if (findRes.type === 'few' && args.length === 0 && hasOverloads) {
|
||||
if (findRes.type === 'few' && args.length === 0 && findRes.hasOverloads) {
|
||||
evalError(prefix, 'Function requires non empty argument list.');
|
||||
} else if (firstFunc && (findRes.type === 'many' || findRes.type === 'few' || findRes.type === 'mismatch')) {
|
||||
if (hasOverloads) {
|
||||
} else if (findRes.type === 'many' || findRes.type === 'few' || findRes.type === 'mismatch') {
|
||||
if (findRes.hasOverloads) {
|
||||
evalError(prefix, `Function has no matching overload for given argument types: ${argsType}.`);
|
||||
} else {
|
||||
// eslint-disable-next-line no-lonely-if
|
||||
if (findRes.type === 'many' || findRes.type === 'few') {
|
||||
if (firstFunc.args.some(arg => typeof arg === 'object' && arg.isVararg)) {
|
||||
evalError(prefix, `At least ${firstFunc.args.length} argument(s) expected.`);
|
||||
if (findRes.def.args.some(arg => typeof arg === 'object' && arg.isVararg)) {
|
||||
evalError(prefix, `At least ${findRes.def.args.length} argument(s) expected.`);
|
||||
} else {
|
||||
evalError(prefix, `Exactly ${firstFunc.args.length} argument(s) expected.`);
|
||||
evalError(prefix, `Exactly ${findRes.def.args.length} argument(s) expected.`);
|
||||
}
|
||||
} else {
|
||||
const expectedArgs = firstFunc.args.map(arg => typeToString(typeof arg === 'string' ? arg : arg.type)).join(', ');
|
||||
const expectedArgs = findRes.def.args.map(arg => typeToString(typeof arg === 'string' ? arg : arg.type)).join(', ');
|
||||
evalError(prefix, `Invalid argument type: expected ${expectedArgs}, got ${argsType}.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,14 +22,20 @@ export type FuncMatchError = {
|
||||
type: 'mismatch';
|
||||
expected: EvalTypes;
|
||||
found: EvalTypes;
|
||||
def: Func;
|
||||
hasOverloads: boolean;
|
||||
} | {
|
||||
type: 'few';
|
||||
expected: number;
|
||||
found: number;
|
||||
def: Func;
|
||||
hasOverloads: boolean;
|
||||
} | {
|
||||
type: 'many';
|
||||
expected: number;
|
||||
found: number;
|
||||
def: Func;
|
||||
hasOverloads: boolean;
|
||||
} | {
|
||||
type: 'missing';
|
||||
};
|
||||
@@ -191,7 +197,7 @@ export function registerMethod(
|
||||
methodByArgs.set(funcKey, desc);
|
||||
}
|
||||
|
||||
function matchFuncArgs(func: Func, args: EvalValue[]): {
|
||||
function matchFuncArgs(func: Func, args: EvalValue[], hasOverloads: boolean): {
|
||||
type: 'match';
|
||||
conversions: number;
|
||||
} | FuncMatchError {
|
||||
@@ -208,13 +214,17 @@ function matchFuncArgs(func: Func, args: EvalValue[]): {
|
||||
return {
|
||||
type: 'few',
|
||||
expected: minArgs,
|
||||
found: args.length
|
||||
found: args.length,
|
||||
def: func,
|
||||
hasOverloads
|
||||
};
|
||||
} else if (args.length > maxArgs) {
|
||||
return {
|
||||
type: 'many',
|
||||
expected: maxArgs,
|
||||
found: args.length
|
||||
found: args.length,
|
||||
def: func,
|
||||
hasOverloads
|
||||
};
|
||||
}
|
||||
|
||||
@@ -235,7 +245,9 @@ function matchFuncArgs(func: Func, args: EvalValue[]): {
|
||||
return {
|
||||
type: 'mismatch',
|
||||
expected: funcArg.type,
|
||||
found: args[i].type
|
||||
found: args[i].type,
|
||||
def: func,
|
||||
hasOverloads
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -260,7 +272,7 @@ export function findBestMatchedFunc(map: Map<string, Func[]>, funcName: string,
|
||||
conversions: number;
|
||||
} | null = null;
|
||||
for (let i = 0; i < list.length; ++i) {
|
||||
const match = matchFuncArgs(list[i], args);
|
||||
const match = matchFuncArgs(list[i], args, list.length > 1);
|
||||
if (match.type === 'match') {
|
||||
if (!bestFunc || bestFunc.conversions > match.conversions) {
|
||||
bestFunc = {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
module.exports = async function(jsonPath, params = {}) {
|
||||
await this.yaOpenExample('client/web/divkit/tests/hermione/static/index.html', {
|
||||
query: {
|
||||
...params,
|
||||
crossplatform_json: jsonPath
|
||||
}
|
||||
});
|
||||
|
||||
@@ -70,6 +70,79 @@ function createInteractiveTestCase(testCase, testPath) {
|
||||
});
|
||||
}
|
||||
|
||||
function createIntegrationTestCase(testCase, testPath) {
|
||||
const { description, div_data, cases } = JSON.parse(fs.readFileSync(path.join(path.resolve(__dirname, '../../..'), testPath), 'utf8'));
|
||||
|
||||
for (let i = 0; i < cases.length; ++i) {
|
||||
const item = cases[i];
|
||||
const resultType = item.expected.find(it => it.type === 'variable' && it.variable_name === 'result')?.value?.type;
|
||||
|
||||
if (item.platforms && !item.platforms.includes('web')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
describe(description, () => {
|
||||
it(`Case [${i}]`, async function() {
|
||||
await this.browser.yaOpenCrossplatformJson(testPath, {
|
||||
result_type: resultType
|
||||
});
|
||||
|
||||
for (let j = 0; j < item.div_actions.length; j++) {
|
||||
const action = item.div_actions[j];
|
||||
|
||||
await this.browser.execute(action => {
|
||||
window.divkitRoot.execAction(action);
|
||||
}, action);
|
||||
}
|
||||
|
||||
for (let j = 0; j < item.expected.length; j++) {
|
||||
const expected = item.expected[j];
|
||||
|
||||
if (expected.type === 'variable') {
|
||||
const result = await this.browser.execute(variableName => {
|
||||
const inst = window.divkitRoot.getDebugAllVariables().get(variableName);
|
||||
const type = inst.getType();
|
||||
let value = inst.getValue();
|
||||
|
||||
if (typeof value === 'bigint') {
|
||||
value = Number(value);
|
||||
} else if (type === 'boolean') {
|
||||
value = Boolean(value);
|
||||
}
|
||||
|
||||
return {
|
||||
type,
|
||||
value
|
||||
};
|
||||
}, expected.variable_name);
|
||||
|
||||
result.type.should.equal(expected.value.type);
|
||||
result.value.should.equal(expected.value.value);
|
||||
} else if (expected.type === 'error') {
|
||||
const errors = await this.browser.execute(() => {
|
||||
if (!window.errors) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return window.errors.map(it => {
|
||||
return {
|
||||
message: it.message,
|
||||
additionalMessage: it.additional ? it.additional.message : undefined
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
errors.length.should.equal(1);
|
||||
errors[0].additionalMessage.should.equal(expected.value);
|
||||
} else {
|
||||
throw new Error('Unsupported expected type ' + expected.type);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const crossplatformPath = '../../../../../../test_data';
|
||||
describe('crossplatform', () => {
|
||||
describe('samples', () => {
|
||||
@@ -87,6 +160,11 @@ describe('crossplatform', () => {
|
||||
read(`${crossplatformPath}/interactive_snapshot_test_data/`, createInteractiveTestCase, skipTests);
|
||||
});
|
||||
|
||||
describe('integration', () => {
|
||||
const skipTests = [];
|
||||
read(`${crossplatformPath}/integration_test_data/`, createIntegrationTestCase, skipTests);
|
||||
});
|
||||
|
||||
describe('unit', () => {
|
||||
const skipTests = [
|
||||
'patches',
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
const params = new URLSearchParams(location.search);
|
||||
const json = params.get('json');
|
||||
const crossplatformJson = params.get('crossplatform_json');
|
||||
const resultType = params.get('result_type');
|
||||
|
||||
function getJson(json) {
|
||||
return fetch(json)
|
||||
@@ -149,24 +150,50 @@
|
||||
.then(() => fn())
|
||||
.then(json => {
|
||||
const root = document.querySelector('#root');
|
||||
window.divkitRoot = Ya.Divkit.render({
|
||||
|
||||
let globalVariablesController;
|
||||
if (resultType) {
|
||||
globalVariablesController = Ya.DivKit.createGlobalVariablesController();
|
||||
|
||||
let value = '';
|
||||
if (resultType === 'integer' || resultType === 'number') {
|
||||
value = 0;
|
||||
} else if (resultType === 'boolean') {
|
||||
value = false;
|
||||
} else if (resultType === 'color') {
|
||||
value = '#000';
|
||||
} else if (resultType === 'dict') {
|
||||
value = {};
|
||||
} else if (resultType === 'array') {
|
||||
value = [];
|
||||
}
|
||||
|
||||
window.result = Ya.DivKit.createVariable('result', resultType, value);
|
||||
globalVariablesController.setVariable(window.result);
|
||||
}
|
||||
|
||||
window.divkitRoot = Ya.DivKit.render({
|
||||
id: 'test',
|
||||
target: root,
|
||||
json,
|
||||
platform: 'touch',
|
||||
direction: json.configuration && json.configuration.layout_direction === 'rtl' ? 'rtl' : 'ltr',
|
||||
globalVariablesController,
|
||||
onStat(arg) {
|
||||
window.divkitLogs.push(arg);
|
||||
},
|
||||
onError(err) {
|
||||
if (err && err.error && err.error.level === 'warn') {
|
||||
onError(event) {
|
||||
if (event && event.error && event.error.level === 'warn') {
|
||||
return;
|
||||
}
|
||||
|
||||
const elem = document.createElement('p');
|
||||
elem.className = 'log-item';
|
||||
elem.textContent = String(err && err.error || '<unknown>');
|
||||
elem.textContent = String(event && event.error || '<unknown>');
|
||||
root.appendChild(elem);
|
||||
|
||||
window.errors = window.errors || [];
|
||||
window.errors.push(event.error);
|
||||
},
|
||||
onComponent(details) {
|
||||
if (details.type === 'mount' && details.json.id) {
|
||||
|
||||
@@ -94,7 +94,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -115,7 +116,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -72,7 +72,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -64,11 +64,13 @@
|
||||
"variable_name": "result",
|
||||
"value": {
|
||||
"type": "color",
|
||||
"value": "#AABBCC"
|
||||
"value": "#FFAABBCC"
|
||||
}
|
||||
}
|
||||
],
|
||||
"platforms": []
|
||||
"platforms": [
|
||||
"web"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -78,7 +78,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -95,7 +95,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -116,7 +117,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -129,10 +131,13 @@
|
||||
"expected": [
|
||||
{
|
||||
"type": "error",
|
||||
"value": "Failed to evaluate [[123,123.45].increment(2)]. Unknown method name: increment."
|
||||
"value": "Failed to evaluate [increment(2)]. Unknown method name: increment."
|
||||
}
|
||||
],
|
||||
"platforms": []
|
||||
"platforms": [
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -94,7 +94,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -115,7 +116,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -128,10 +130,12 @@
|
||||
"expected": [
|
||||
{
|
||||
"type": "error",
|
||||
"value": "Function captureFunction() returned integer, but string was expected."
|
||||
"value": "Failed to evaluate [captureFunction('test')]. Exactly 0 argument(s) expected."
|
||||
}
|
||||
],
|
||||
"platforms": []
|
||||
"platforms": [
|
||||
"web"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user