mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
Fixed integer calculations
This commit is contained in:
@@ -12331,6 +12331,7 @@
|
||||
"client/web/divkit/tests/bundles/client.test.ts":"divkit/public/client/web/divkit/tests/bundles/client.test.ts",
|
||||
"client/web/divkit/tests/bundles/package.json":"divkit/public/client/web/divkit/tests/bundles/package.json",
|
||||
"client/web/divkit/tests/bundles/server.test.ts":"divkit/public/client/web/divkit/tests/bundles/server.test.ts",
|
||||
"client/web/divkit/tests/expressions/expressions-integers.test.ts":"divkit/public/client/web/divkit/tests/expressions/expressions-integers.test.ts",
|
||||
"client/web/divkit/tests/expressions/expressions-with-out-bigint.test.ts":"divkit/public/client/web/divkit/tests/expressions/expressions-with-out-bigint.test.ts",
|
||||
"client/web/divkit/tests/expressions/expressions.test.ts":"divkit/public/client/web/divkit/tests/expressions/expressions.test.ts",
|
||||
"client/web/divkit/tests/expressions/nobigint/functions_arithmetic_integer.json":"divkit/public/client/web/divkit/tests/expressions/nobigint/functions_arithmetic_integer.json",
|
||||
|
||||
@@ -33,6 +33,7 @@ function arrayGetter(jsType: string, runtimeType: string) {
|
||||
throw new Error('Cannot convert value to integer.');
|
||||
}
|
||||
checkIntegerOverflow(ctx, val);
|
||||
val = toBigInt(val);
|
||||
}
|
||||
if (jsType === 'string' && runtimeType === 'color') {
|
||||
val = transformColorValue(val as string);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { toBigInt } from '../bigint';
|
||||
import { BOOLEAN, COLOR, DICT, INTEGER, NUMBER, STRING, URL } from '../const';
|
||||
import { BooleanValue, DictValue, EvalContext, EvalTypes, EvalValue, IntegerValue, NumberValue, StringValue } from '../eval';
|
||||
import { checkIntegerOverflow, transformColorValue } from '../utils';
|
||||
@@ -42,6 +43,7 @@ function dictGetter(jsType: string, runtimeType: string) {
|
||||
throw new Error('Cannot convert value to integer.');
|
||||
}
|
||||
checkIntegerOverflow(ctx, val);
|
||||
val = toBigInt(val);
|
||||
}
|
||||
if (jsType === 'string' && runtimeType === 'color') {
|
||||
val = transformColorValue(val as string);
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { EvalContext, EvalValue, IntegerValue, NumberValue } from '../eval'
|
||||
import { registerFunc } from './funcs';
|
||||
import { INTEGER, MAX_NUMBER, MIN_NUMBER, NUMBER } from '../const';
|
||||
import { checkIntegerOverflow, roundInteger } from '../utils';
|
||||
import { absBigInt, bigIntZero, signBigInt, MAX_INT, MIN_INT } from '../bigint';
|
||||
import { absBigInt, bigIntZero, signBigInt, MAX_INT, MIN_INT, toBigInt } from '../bigint';
|
||||
|
||||
function divInteger(ctx: EvalContext, arg0: IntegerValue, arg1: IntegerValue): EvalValue {
|
||||
if (arg1.value === bigIntZero) {
|
||||
@@ -297,7 +297,7 @@ function copySignInteger(ctx: EvalContext, arg0: IntegerValue, arg1: IntegerValu
|
||||
if (arg1.value === bigIntZero) {
|
||||
res = arg0.value;
|
||||
} else if (arg0.value === bigIntZero) {
|
||||
res = 0;
|
||||
res = toBigInt(0);
|
||||
} else {
|
||||
const sign = signBigInt(arg1.value);
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import { evalExpression, EvalResult } from '../../src/expressions/eval';
|
||||
import { valToString } from '../../src/expressions/utils';
|
||||
import { parse } from '../../src/expressions/expressions';
|
||||
import { createVariable } from '../../src/expressions/variable';
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const dir = path.resolve(__filename, '../../../../../../test_data/expression_test_data');
|
||||
|
||||
const tests = fs.readdirSync(dir);
|
||||
|
||||
function convertVals(val: EvalResult) {
|
||||
if (val.type === 'boolean') {
|
||||
return {
|
||||
type: 'boolean',
|
||||
value: val.value ? 1 : 0
|
||||
};
|
||||
} else if (val.type === 'integer') {
|
||||
return {
|
||||
type: 'integer',
|
||||
// values in json is out of range already
|
||||
value: Number(val.value)
|
||||
};
|
||||
} else if (val.type === 'datetime' && val.value instanceof Date) {
|
||||
return {
|
||||
type: 'datetime',
|
||||
value: valToString(val)
|
||||
};
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
function runCase(item: any) {
|
||||
const vars = new Map();
|
||||
if (item.variables) {
|
||||
for (const variable of item.variables) {
|
||||
vars.set(variable.name, createVariable(variable.name, variable.type, variable.value));
|
||||
}
|
||||
}
|
||||
let ast;
|
||||
try {
|
||||
ast = parse(item.expression, {
|
||||
startRule: 'JsonStringContents'
|
||||
});
|
||||
} catch (err: any) {
|
||||
if (item.expected.value) {
|
||||
expect({
|
||||
type: 'error',
|
||||
value: err.message
|
||||
}).toEqual(item.expected);
|
||||
} else {
|
||||
expect('error').toEqual(item.expected.type);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const res = evalExpression(vars, ast);
|
||||
expect(typeof res.result.value).toEqual('bigint');
|
||||
}
|
||||
|
||||
describe('expressions-integers', () => {
|
||||
for (const file of tests) {
|
||||
const name = file.replace('.json', '');
|
||||
const contents = require(path.resolve(dir, file));
|
||||
|
||||
if (contents.cases) {
|
||||
const counter: Record<string, number> = {};
|
||||
|
||||
describe(name, () => {
|
||||
for (const item of contents.cases) {
|
||||
if (item.platforms.includes('web') && item.expected?.type === 'integer') {
|
||||
let name = item.name;
|
||||
|
||||
if (!counter[name]) {
|
||||
counter[name] = 0;
|
||||
}
|
||||
|
||||
name += ` : ${counter[name]++}`;
|
||||
|
||||
it(name, () => {
|
||||
runCase(item);
|
||||
});
|
||||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('skip', file, name, item.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user