mirror of
https://github.com/fluencelabs/fluence-js.git
synced 2025-05-01 04:22:14 +00:00
Add math builtins implementation (#139)
This commit is contained in:
parent
56638c8fe2
commit
f8abe728c0
@ -20,50 +20,96 @@ const oneTwoThreeFour = `[
|
|||||||
describe('Tests for default handler', () => {
|
describe('Tests for default handler', () => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
each`
|
each`
|
||||||
serviceId | fnName | args | retCode | result
|
serviceId | fnName | args | retCode | result
|
||||||
${'op'} | ${'identity'} | ${[]} | ${0} | ${{}}
|
${'op'} | ${'identity'} | ${[]} | ${0} | ${{}}
|
||||||
${'op'} | ${'identity'} | ${[1]} | ${0} | ${1}
|
${'op'} | ${'identity'} | ${[1]} | ${0} | ${1}
|
||||||
${'op'} | ${'identity'} | ${[1, 2]} | ${1} | ${'identity accepts up to 1 arguments, received 2 arguments'}
|
${'op'} | ${'identity'} | ${[1, 2]} | ${1} | ${'identity accepts up to 1 arguments, received 2 arguments'}
|
||||||
|
|
||||||
${'op'} | ${'noop'} | ${[1, 2]} | ${0} | ${{}}
|
${'op'} | ${'noop'} | ${[1, 2]} | ${0} | ${{}}
|
||||||
|
|
||||||
${'op'} | ${'array'} | ${[1, 2, 3]} | ${0} | ${[1, 2, 3]}
|
${'op'} | ${'array'} | ${[1, 2, 3]} | ${0} | ${[1, 2, 3]}
|
||||||
|
|
||||||
${'op'} | ${'array_length'} | ${[[1, 2, 3]]} | ${0} | ${3}
|
${'op'} | ${'array_length'} | ${[[1, 2, 3]]} | ${0} | ${3}
|
||||||
${'op'} | ${'array_length'} | ${[]} | ${1} | ${'array_length accepts exactly one argument, found: 0'}
|
${'op'} | ${'array_length'} | ${[]} | ${1} | ${'array_length accepts exactly one argument, found: 0'}
|
||||||
|
|
||||||
${'op'} | ${'concat'} | ${[[1, 2], [3, 4], [5, 6]]} | ${0} | ${[1, 2, 3, 4, 5, 6]}
|
${'op'} | ${'concat'} | ${[[1, 2], [3, 4], [5, 6]]} | ${0} | ${[1, 2, 3, 4, 5, 6]}
|
||||||
${'op'} | ${'concat'} | ${[[1, 2]]} | ${0} | ${[1, 2]}
|
${'op'} | ${'concat'} | ${[[1, 2]]} | ${0} | ${[1, 2]}
|
||||||
${'op'} | ${'concat'} | ${[]} | ${0} | ${[]}
|
${'op'} | ${'concat'} | ${[]} | ${0} | ${[]}
|
||||||
${'op'} | ${'concat'} | ${[1, [1, 2], 1]} | ${1} | ${"All arguments of 'concat' must be arrays: arguments 0, 2 are not"}
|
${'op'} | ${'concat'} | ${[1, [1, 2], 1]} | ${1} | ${"All arguments of 'concat' must be arrays: arguments 0, 2 are not"}
|
||||||
|
|
||||||
${'op'} | ${'string_to_b58'} | ${["test"]} | ${0} | ${"3yZe7d"}
|
${'op'} | ${'string_to_b58'} | ${["test"]} | ${0} | ${"3yZe7d"}
|
||||||
${'op'} | ${'string_to_b58'} | ${["test", 1]} | ${1} | ${"string_to_b58 accepts only one string argument"}
|
${'op'} | ${'string_to_b58'} | ${["test", 1]} | ${1} | ${"string_to_b58 accepts only one string argument"}
|
||||||
|
|
||||||
${'op'} | ${'string_from_b58'} | ${["3yZe7d"]} | ${0} | ${"test"}
|
${'op'} | ${'string_from_b58'} | ${["3yZe7d"]} | ${0} | ${"test"}
|
||||||
${'op'} | ${'string_from_b58'} | ${["3yZe7d", 1]} | ${1} | ${"string_from_b58 accepts only one string argument"}
|
${'op'} | ${'string_from_b58'} | ${["3yZe7d", 1]} | ${1} | ${"string_from_b58 accepts only one string argument"}
|
||||||
|
|
||||||
${'op'} | ${'bytes_to_b58'} | ${[[116, 101, 115, 116]]} | ${0} | ${"3yZe7d"}
|
${'op'} | ${'bytes_to_b58'} | ${[[116, 101, 115, 116]]} | ${0} | ${"3yZe7d"}
|
||||||
${'op'} | ${'bytes_to_b58'} | ${[[116, 101, 115, 116], 1]} | ${1} | ${"bytes_to_b58 accepts only single argument: array of numbers"}
|
${'op'} | ${'bytes_to_b58'} | ${[[116, 101, 115, 116], 1]} | ${1} | ${"bytes_to_b58 accepts only single argument: array of numbers"}
|
||||||
|
|
||||||
${'op'} | ${'bytes_from_b58'} | ${["3yZe7d"]} | ${0} | ${[116, 101, 115, 116]}
|
${'op'} | ${'bytes_from_b58'} | ${["3yZe7d"]} | ${0} | ${[116, 101, 115, 116]}
|
||||||
${'op'} | ${'bytes_from_b58'} | ${["3yZe7d", 1]} | ${1} | ${"bytes_from_b58 accepts only one string argument"}
|
${'op'} | ${'bytes_from_b58'} | ${["3yZe7d", 1]} | ${1} | ${"bytes_from_b58 accepts only one string argument"}
|
||||||
|
|
||||||
${'op'} | ${'sha256_string'} | ${["hello, world!"]} | ${0} | ${"QmVQ8pg6L1tpoWYeq6dpoWqnzZoSLCh7E96fCFXKvfKD3u"}
|
${'op'} | ${'sha256_string'} | ${["hello, world!"]} | ${0} | ${"QmVQ8pg6L1tpoWYeq6dpoWqnzZoSLCh7E96fCFXKvfKD3u"}
|
||||||
${'op'} | ${'sha256_string'} | ${["hello, world!", true]} | ${0} | ${"84V7ZxLW7qKsx1Qvbd63BdGaHxUc3TfT2MBPqAXM7Wyu"}
|
${'op'} | ${'sha256_string'} | ${["hello, world!", true]} | ${0} | ${"84V7ZxLW7qKsx1Qvbd63BdGaHxUc3TfT2MBPqAXM7Wyu"}
|
||||||
${'op'} | ${'sha256_string'} | ${[]} | ${1} | ${"sha256_string accepts 1-3 arguments, found: 0"}
|
${'op'} | ${'sha256_string'} | ${[]} | ${1} | ${"sha256_string accepts 1-3 arguments, found: 0"}
|
||||||
|
|
||||||
${'op'} | ${'concat_strings'} | ${[]} | ${0} | ${""}
|
${'op'} | ${'concat_strings'} | ${[]} | ${0} | ${""}
|
||||||
${'op'} | ${'concat_strings'} | ${["a", "b", "c"]} | ${0} | ${"abc"}
|
${'op'} | ${'concat_strings'} | ${["a", "b", "c"]} | ${0} | ${"abc"}
|
||||||
|
|
||||||
${'peer'} | ${'timeout'} | ${[200, []]} | ${0} | ${[]}}
|
${'peer'} | ${'timeout'} | ${[200, []]} | ${0} | ${[]}}
|
||||||
${'peer'} | ${'timeout'} | ${[200, ['test']]} | ${0} | ${['test']}}
|
${'peer'} | ${'timeout'} | ${[200, ['test']]} | ${0} | ${['test']}}
|
||||||
${'peer'} | ${'timeout'} | ${[]} | ${1} | ${'timeout accepts exactly two arguments: timeout duration in ms and a message string'}}
|
${'peer'} | ${'timeout'} | ${[]} | ${1} | ${'timeout accepts exactly two arguments: timeout duration in ms and a message string'}}
|
||||||
${'peer'} | ${'timeout'} | ${[200, 'test', 1]} | ${1} | ${'timeout accepts exactly two arguments: timeout duration in ms and a message string'}}
|
${'peer'} | ${'timeout'} | ${[200, 'test', 1]} | ${1} | ${'timeout accepts exactly two arguments: timeout duration in ms and a message string'}}
|
||||||
|
|
||||||
${'debug'} | ${'stringify'} | ${[]} | ${0} | ${'"<empty argument list>"'}}
|
${'debug'} | ${'stringify'} | ${[]} | ${0} | ${'"<empty argument list>"'}}
|
||||||
${'debug'} | ${'stringify'} | ${[{a: 10, b: 20}]} | ${0} | ${a10b20}}
|
${'debug'} | ${'stringify'} | ${[{a: 10, b: 20}]} | ${0} | ${a10b20}}
|
||||||
${'debug'} | ${'stringify'} | ${[1, 2, 3, 4]} | ${0} | ${oneTwoThreeFour}}
|
${'debug'} | ${'stringify'} | ${[1, 2, 3, 4]} | ${0} | ${oneTwoThreeFour}}
|
||||||
|
|
||||||
|
${'math'} | ${'add'}" | ${[2, 2]} | ${0} | ${4}
|
||||||
|
${'math'} | ${'add'}" | ${[2]} | ${1} | ${"Expected 2 argument(s). Got 1"}
|
||||||
|
|
||||||
|
${'math'} | ${'sub'}" | ${[2, 2]} | ${0} | ${0}
|
||||||
|
${'math'} | ${'sub'}" | ${[2, 3]} | ${0} | ${-1}
|
||||||
|
|
||||||
|
${'math'} | ${'mul'}" | ${[2, 2]} | ${0} | ${4}
|
||||||
|
${'math'} | ${'mul'}" | ${[2, 0]} | ${0} | ${0}
|
||||||
|
${'math'} | ${'mul'}" | ${[2, -1]} | ${0} | ${-2}
|
||||||
|
|
||||||
|
${'math'} | ${'fmul'}" | ${[10, 0.66]} | ${0} | ${6}
|
||||||
|
${'math'} | ${'fmul'}" | ${[0.5, 0.5]} | ${0} | ${0}
|
||||||
|
${'math'} | ${'fmul'}" | ${[100.5, 0.5]} | ${0} | ${50}
|
||||||
|
|
||||||
|
${'math'} | ${'div'}" | ${[2, 2]} | ${0} | ${1}
|
||||||
|
${'math'} | ${'div'}" | ${[2, 3]} | ${0} | ${0}
|
||||||
|
${'math'} | ${'div'}" | ${[10, 5]} | ${0} | ${2}
|
||||||
|
|
||||||
|
${'math'} | ${'rem'}" | ${[10, 3]} | ${0} | ${1}
|
||||||
|
|
||||||
|
${'math'} | ${'pow'}" | ${[2, 2]} | ${0} | ${4}
|
||||||
|
${'math'} | ${'pow'}" | ${[2, 0]} | ${0} | ${1}
|
||||||
|
|
||||||
|
${'math'} | ${'log'}" | ${[2, 2]} | ${0} | ${1}
|
||||||
|
${'math'} | ${'log'}" | ${[2, 4]} | ${0} | ${2}
|
||||||
|
|
||||||
|
${'cmp'} | ${'gt'}" | ${[2, 4]} | ${0} | ${false}
|
||||||
|
${'cmp'} | ${'gte'}" | ${[2, 4]} | ${0} | ${false}
|
||||||
|
${'cmp'} | ${'gte'}" | ${[4, 2]} | ${0} | ${true}
|
||||||
|
${'cmp'} | ${'gte'}" | ${[2, 2]} | ${0} | ${true}
|
||||||
|
|
||||||
|
${'cmp'} | ${'lt'}" | ${[2, 4]} | ${0} | ${true}
|
||||||
|
${'cmp'} | ${'lte'}" | ${[2, 4]} | ${0} | ${true}
|
||||||
|
${'cmp'} | ${'lte'}" | ${[4, 2]} | ${0} | ${false}
|
||||||
|
${'cmp'} | ${'lte'}" | ${[2, 2]} | ${0} | ${true}
|
||||||
|
|
||||||
|
${'cmp'} | ${'cmp'}" | ${[2, 4]} | ${0} | ${-1}
|
||||||
|
${'cmp'} | ${'cmp'}" | ${[2, -4]} | ${0} | ${1}
|
||||||
|
${'cmp'} | ${'cmp'}" | ${[2, 2]} | ${0} | ${0}
|
||||||
|
|
||||||
|
${'array'} | ${'sum'}" | ${[[1, 2, 3]]} | ${0} | ${6}
|
||||||
|
${'array'} | ${'dedup'}" | ${[["a", "a", "b", "c", "a", "b", "c"]]} | ${0} | ${["a", "b", "c"]}
|
||||||
|
${'array'} | ${'intersect'}" | ${[["a", "b", "c"], ["c", "b", "d"]]} | ${0} | ${["b", "c"]}
|
||||||
|
${'array'} | ${'diff'}" | ${[["a", "b", "c"], ["c", "b", "d"]]} | ${0} | ${["a"]}
|
||||||
|
${'array'} | ${'sdiff'}" | ${[["a", "b", "c"], ["c", "b", "d"]]} | ${0} | ${["a", "d"]}
|
||||||
|
|
||||||
`.test(
|
`.test(
|
||||||
//
|
//
|
||||||
|
@ -288,79 +288,183 @@ export const builtInServices = {
|
|||||||
|
|
||||||
math: {
|
math: {
|
||||||
add: (req) => {
|
add: (req) => {
|
||||||
return errorNotImpl('math.add');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(x + y);
|
||||||
},
|
},
|
||||||
|
|
||||||
sub: (req) => {
|
sub: (req) => {
|
||||||
return errorNotImpl('math.sub');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(x - y);
|
||||||
},
|
},
|
||||||
|
|
||||||
mul: (req) => {
|
mul: (req) => {
|
||||||
return errorNotImpl('math.mul');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(x * y);
|
||||||
},
|
},
|
||||||
|
|
||||||
fmul: (req) => {
|
fmul: (req) => {
|
||||||
return errorNotImpl('math.fmul');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(Math.floor(x * y));
|
||||||
},
|
},
|
||||||
|
|
||||||
div: (req) => {
|
div: (req) => {
|
||||||
return errorNotImpl('math.div');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(Math.floor(x / y));
|
||||||
},
|
},
|
||||||
|
|
||||||
rem: (req) => {
|
rem: (req) => {
|
||||||
return errorNotImpl('math.rem');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(x % y);
|
||||||
},
|
},
|
||||||
|
|
||||||
pow: (req) => {
|
pow: (req) => {
|
||||||
return errorNotImpl('math.pow');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(Math.pow(x, y));
|
||||||
},
|
},
|
||||||
|
|
||||||
log: (req) => {
|
log: (req) => {
|
||||||
return errorNotImpl('math.log');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(Math.log(y) / Math.log(x));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
cmp: {
|
cmp: {
|
||||||
gt: (req) => {
|
gt: (req) => {
|
||||||
return errorNotImpl('cmp.gt');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(x > y);
|
||||||
},
|
},
|
||||||
|
|
||||||
gte: (req) => {
|
gte: (req) => {
|
||||||
return errorNotImpl('cmp.gte');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(x >= y);
|
||||||
},
|
},
|
||||||
|
|
||||||
lt: (req) => {
|
lt: (req) => {
|
||||||
return errorNotImpl('cmp.lt');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(x < y);
|
||||||
},
|
},
|
||||||
|
|
||||||
lte: (req) => {
|
lte: (req) => {
|
||||||
return errorNotImpl('cmp.lte');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(x <= y);
|
||||||
},
|
},
|
||||||
|
|
||||||
cmp: (req) => {
|
cmp: (req) => {
|
||||||
return errorNotImpl('cmp.cmp');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [x, y] = req.args;
|
||||||
|
return success(x === y ? 0 : x > y ? 1 : -1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
array: {
|
array: {
|
||||||
sum: (req) => {
|
sum: (req) => {
|
||||||
return errorNotImpl('array.sum');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 1))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [xs] = req.args;
|
||||||
|
return success(xs.reduce((agg, cur) => agg + cur, 0));
|
||||||
},
|
},
|
||||||
|
|
||||||
dedup: (req) => {
|
dedup: (req) => {
|
||||||
return errorNotImpl('array.dedup');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 1))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [xs] = req.args;
|
||||||
|
const set = new Set(xs);
|
||||||
|
return success(Array.from(set));
|
||||||
},
|
},
|
||||||
|
|
||||||
intersect: (req) => {
|
intersect: (req) => {
|
||||||
return errorNotImpl('array.intersect');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [xs, ys] = req.args;
|
||||||
|
const intersection = xs.filter((x) => ys.includes(x));
|
||||||
|
return success(intersection);
|
||||||
},
|
},
|
||||||
|
|
||||||
diff: (req) => {
|
diff: (req) => {
|
||||||
return errorNotImpl('array.diff');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [xs, ys] = req.args;
|
||||||
|
const diff = xs.filter((x) => !ys.includes(x));
|
||||||
|
return success(diff);
|
||||||
},
|
},
|
||||||
|
|
||||||
sdiff: (req) => {
|
sdiff: (req) => {
|
||||||
return errorNotImpl('array.sdiff');
|
let err;
|
||||||
|
if ((err = checkForArgumentsCount(req, 2))) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
const [xs, ys] = req.args;
|
||||||
|
const sdiff = [
|
||||||
|
// force new line
|
||||||
|
...xs.filter((y) => !ys.includes(y)),
|
||||||
|
...ys.filter((x) => !xs.includes(x)),
|
||||||
|
];
|
||||||
|
return success(sdiff);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const checkForArgumentsCount = (req, count: number) => {
|
||||||
|
if (req.args.length !== count) {
|
||||||
|
return error(`Expected ${count} argument(s). Got ${req.args.length}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user