Skip to content

Commit

Permalink
Add abs, round, floor, ceil operators (#6496)
Browse files Browse the repository at this point in the history
Refs #5853

* Add abs, round, floor, ceil operators

* Round away from 0

* Add entries to v8.json

* Test non-integer abs

* Edits from review
  • Loading branch information
anandthakker authored Apr 11, 2018
1 parent a48c14c commit 6b96d69
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 2 deletions.
26 changes: 26 additions & 0 deletions src/style-spec/expression/definitions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,32 @@ CompoundExpression.register(expressions, {
varargs(NumberType),
(ctx, args) => Math.max(...args.map(arg => arg.evaluate(ctx)))
],
'abs': [
NumberType,
[NumberType],
(ctx, [n]) => Math.abs(n.evaluate(ctx))
],
'round': [
NumberType,
[NumberType],
(ctx, [n]) => {
const v = n.evaluate(ctx);
// Javascript's Math.round() rounds towards +Infinity for halfway
// values, even when they're negative. It's more common to round
// away from 0 (e.g., this is what python and C++ do)
return v < 0 ? -Math.round(-v) : Math.round(v);
}
],
'floor': [
NumberType,
[NumberType],
(ctx, [n]) => Math.floor(n.evaluate(ctx))
],
'ceil': [
NumberType,
[NumberType],
(ctx, [n]) => Math.ceil(n.evaluate(ctx))
],
'filter-==': [
BooleanType,
[StringType, ValueType],
Expand Down
36 changes: 36 additions & 0 deletions src/style-spec/reference/v8.json
Original file line number Diff line number Diff line change
Expand Up @@ -2490,6 +2490,42 @@
}
}
},
"round": {
"doc": "Rounds the input to the nearest integer. Halfway values are rounded away from zero. For example, `[\"round\", -1.5]` evaluates to -2.",
"group": "Math",
"sdk-support": {
"basic functionality": {
"js": "0.45.0"
}
}
},
"abs": {
"doc": "Returns the absolute value of the input.",
"group": "Math",
"sdk-support": {
"basic functionality": {
"js": "0.45.0"
}
}
},
"ceil": {
"doc": "Returns the smallest integer that is greater than or equal to the input.",
"group": "Math",
"sdk-support": {
"basic functionality": {
"js": "0.45.0"
}
}
},
"floor": {
"doc": "Returns the largest integer that is less than or equal to the input.",
"group": "Math",
"sdk-support": {
"basic functionality": {
"js": "0.45.0"
}
}
},
"==": {
"doc": "Returns `true` if the input values are equal, `false` otherwise. Equality is strictly typed: values of different types are always considered not equal.",
"group": "Decision",
Expand Down
18 changes: 18 additions & 0 deletions test/integration/expression-tests/abs/basic/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"expression": ["abs", ["get", "x"]],
"inputs": [
[{}, {"properties": {"x": -2}}],
[{}, {"properties": {"x": 2}}],
[{}, {"properties": {"x": -1.1}}]
],
"expected": {
"compiled": {
"result": "success",
"isFeatureConstant": false,
"isZoomConstant": true,
"type": "number"
},
"outputs": [2, 2, 1.1],
"serialized": ["abs", ["number", ["get", "x"]]]
}
}
23 changes: 23 additions & 0 deletions test/integration/expression-tests/ceil/basic/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"expression": ["ceil", ["get", "x"]],
"inputs": [
[{}, {"properties": {"x": -2.6}}],
[{}, {"properties": {"x": -2.5}}],
[{}, {"properties": {"x": -2.4}}],
[{}, {"properties": {"x": -2}}],
[{}, {"properties": {"x": 2.6}}],
[{}, {"properties": {"x": 2.5}}],
[{}, {"properties": {"x": 2.4}}],
[{}, {"properties": {"x": 2}}]
],
"expected": {
"compiled": {
"result": "success",
"isFeatureConstant": false,
"isZoomConstant": true,
"type": "number"
},
"outputs": [ -2, -2, -2, -2, 3, 3, 3, 2 ],
"serialized": ["ceil", ["number", ["get", "x"]]]
}
}
23 changes: 23 additions & 0 deletions test/integration/expression-tests/floor/basic/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"expression": ["floor", ["get", "x"]],
"inputs": [
[{}, {"properties": {"x": -2.6}}],
[{}, {"properties": {"x": -2.5}}],
[{}, {"properties": {"x": -2.4}}],
[{}, {"properties": {"x": -2}}],
[{}, {"properties": {"x": 2.6}}],
[{}, {"properties": {"x": 2.5}}],
[{}, {"properties": {"x": 2.4}}],
[{}, {"properties": {"x": 2}}]
],
"expected": {
"compiled": {
"result": "success",
"isFeatureConstant": false,
"isZoomConstant": true,
"type": "number"
},
"outputs": [ -3, -3, -3, -2, 2, 2, 2, 2 ],
"serialized": ["floor", ["number", ["get", "x"]]]
}
}
23 changes: 23 additions & 0 deletions test/integration/expression-tests/round/basic/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"expression": ["round", ["get", "x"]],
"inputs": [
[{}, {"properties": {"x": -2.6}}],
[{}, {"properties": {"x": -2.5}}],
[{}, {"properties": {"x": -2.4}}],
[{}, {"properties": {"x": -2}}],
[{}, {"properties": {"x": 2.6}}],
[{}, {"properties": {"x": 2.5}}],
[{}, {"properties": {"x": 2.4}}],
[{}, {"properties": {"x": 2}}]
],
"expected": {
"compiled": {
"result": "success",
"isFeatureConstant": false,
"isZoomConstant": true,
"type": "number"
},
"outputs": [ -3, -3, -2, -2, 3, 3, 2, 2 ],
"serialized": ["round", ["number", ["get", "x"]]]
}
}
9 changes: 7 additions & 2 deletions test/integration/lib/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,16 @@ exports.run = function (implementation, options, runExpressionTest) {
.filter(Boolean)
.join('\n');
};

if (compileOk && !evalOk) {
diffOutputs(result.outputs);
const differences = diffOutputs(result.outputs);
diffOutput.text += differences;
diffOutput.html += differences;
}
if (recompileOk && !roundTripOk) {
diffOutputs(result.roundTripOutputs);
const differences = diffOutputs(result.roundTripOutputs);
diffOutput.text += differences;
diffOutput.html += differences;
}

params.difference = diffOutput.html;
Expand Down

0 comments on commit 6b96d69

Please sign in to comment.