Skip to content

Commit

Permalink
Add validation for 'zoom' expression usage
Browse files Browse the repository at this point in the history
  • Loading branch information
Anand Thakker committed Jun 22, 2017
1 parent 3d2a76d commit dd09152
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
23 changes: 17 additions & 6 deletions src/style-spec/function/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ module.exports = parseExpression;
function parseExpression(
definitions: {[string]: Definition},
expr: mixed,
path: Array<number> = []
path: Array<number> = [],
parentExpressionName?: string
) /*: TypedExpression | ParseError */ {
const key = path.join('.');
if (expr === null || typeof expr === 'undefined') return {
Expand Down Expand Up @@ -92,14 +93,24 @@ function parseExpression(
};
}

// special case validation for `zoom`
if (op === 'zoom') {
if (parentExpressionName !== 'curve' || path.length > 1) {
return {
key,
error: 'The "zoom" expression may only be used as the input to a top-level "curve" expression.'
};
}
}

// special case parsing for `match`
if (op === 'match') {
if (expr.length < 3) return {
key,
error: `Expected at least 2 arguments, but found only ${expr.length - 1}.`
};

const inputExpression = parseExpression(definitions, expr[1], path.concat(1));
const inputExpression = parseExpression(definitions, expr[1], path.concat(1), op);
if (inputExpression.error) return inputExpression;

// parse input/output pairs.
Expand All @@ -116,7 +127,7 @@ function parseExpression(

const parsedInputGroup = [];
for (let j = 0; j < inputGroup.length; j++) {
const parsedValue = parseExpression(definitions, inputGroup[j], path.concat(i, j));
const parsedValue = parseExpression(definitions, inputGroup[j], path.concat(i, j), op);
if (parsedValue.error) return parsedValue;
if (!parsedValue.literal) return {
key: `${key}.${i}.${j}`,
Expand All @@ -126,12 +137,12 @@ function parseExpression(
}
matchInputs.push(parsedInputGroup);

const output = parseExpression(definitions, expr[i + 1], path.concat(i));
const output = parseExpression(definitions, expr[i + 1], path.concat(i), op);
if (output.error) return output;
outputExpressions.push(output);
}

const otherwise = parseExpression(definitions, expr[expr.length - 1], path.concat(expr.length - 1));
const otherwise = parseExpression(definitions, expr[expr.length - 1], path.concat(expr.length - 1), op);
if (otherwise.error) return otherwise;
outputExpressions.push(otherwise);

Expand All @@ -147,7 +158,7 @@ function parseExpression(

const args = [];
for (const arg of expr.slice(1)) {
const parsedArg = parseExpression(definitions, arg, path.concat(1 + args.length));
const parsedArg = parseExpression(definitions, arg, path.concat(1 + args.length), op);
if (parsedArg.error) return parsedArg;
args.push(parsedArg);
}
Expand Down
12 changes: 11 additions & 1 deletion test/integration/expression-tests/zoom/basic/test.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
{
"expression": [
"zoom"
"curve",
[
"linear"
],
[
"zoom"
],
0,
0,
30,
30
],
"evaluate": [
[
Expand Down
34 changes: 34 additions & 0 deletions test/integration/expression-tests/zoom/too-deep/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"expression": [
"curve",
[
"step"
],
1,
0,
[
"curve",
[
"linear"
],
[
"zoom"
],
0,
0,
22,
22
]
],
"expected": {
"compileResult": {
"result": "error",
"errors": [
{
"key": "4.2",
"error": "The \"zoom\" expression may only be used as the input to a top-level \"curve\" expression."
}
]
}
}
}

0 comments on commit dd09152

Please sign in to comment.