Skip to content
This repository has been archived by the owner on Apr 10, 2018. It is now read-only.

Commit

Permalink
Add has and !has operators
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas Wojciechowski committed Feb 22, 2016
1 parent 12c2e1f commit 2c5d620
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 33 deletions.
81 changes: 52 additions & 29 deletions lib/validate/validate_filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ module.exports = function validateFilter(options) {
var value = options.value;
var key = options.key;
var styleSpec = options.styleSpec;
var type;

var errors = [];

Expand Down Expand Up @@ -37,54 +36,78 @@ module.exports = function validateFilter(options) {
if (value.length >= 2 && value[1] == '$type') {
errors.push(new ValidationError(key, value, '"$type" cannot be use with operator "%s"', value[0]));
}
/* falls through */
if (value.length != 3) {
errors.push(new ValidationError(key, value, 'filter array for operator "%s" must have 3 elements', value[0]));
}
return errors.concat(validateSimpleFilter(options));

case '==':
case '!=':
if (value.length != 3) {
errors.push(new ValidationError(key, value, 'filter array for operator "%s" must have 3 elements', value[0]));
}
/* falls through */
return errors.concat(validateSimpleFilter(options));

case 'in':
case '!in':
if (value.length >= 2) {
type = getType(value[1]);
if (type !== 'string') {
errors.push(new ValidationError(key + '[1]', value[1], 'string expected, %s found', type));
} else if (value[1][0] === '@') {
errors.push(new ValidationError(key + '[1]', value[1], 'filter key cannot be a constant'));
}
}
for (var i = 2; i < value.length; i++) {
type = getType(value[i]);
if (value[1] == '$type') {
errors = errors.concat(validateEnum({
key: key + '[' + i + ']',
value: value[i],
valueSpec: styleSpec.geometry_type,
style: options.style,
styleSpec: options.styleSpec
}));
} else if (type === 'string' && value[i][0] === '@') {
errors.push(new ValidationError(key + '[' + i + ']', value[i], 'filter value cannot be a constant'));
} else if (type !== 'string' && type !== 'number' && type !== 'boolean' && value[i] !== null) {
errors.push(new ValidationError(key + '[' + i + ']', value[i], 'string, number, boolean, or null expected, %s found', type));
}
return errors.concat(validateSimpleFilter(options));

case 'has':
case '!has':
if (value.length != 2) {
errors.push(new ValidationError(key, value, '"has" filter must have exactly 1 operand'));
}
break;
return errors.concat(validateSimpleFilter(options));

case 'any':
case 'all':
case 'none':
for (i = 1; i < value.length; i++) {
for (var i = 1; i < value.length; i++) {
errors = errors.concat(validateFilter({
key: key + '[' + i + ']',
value: value[i],
style: options.style,
styleSpec: options.styleSpec
}));
}
break;
return errors;
}

return errors;
};

function validateSimpleFilter(options) {
var value = options.value;
var key = options.key;
var styleSpec = options.styleSpec;
var errors = [];
var type;

if (value.length >= 2) {
type = getType(value[1]);
if (type !== 'string') {
errors.push(new ValidationError(key + '[1]', value[1], 'string expected, %s found', type));
} else if (value[1][0] === '@') {
errors.push(new ValidationError(key + '[1]', value[1], 'filter key cannot be a constant'));
}
}

for (var i = 2; i < value.length; i++) {
type = getType(value[i]);
if (value[1] == '$type') {
errors = errors.concat(validateEnum({
key: key + '[' + i + ']',
value: value[i],
valueSpec: styleSpec.geometry_type,
style: options.style,
styleSpec: options.styleSpec
}));
} else if (type === 'string' && value[i][0] === '@') {
errors.push(new ValidationError(key + '[' + i + ']', value[i], 'filter value cannot be a constant'));
} else if (type !== 'string' && type !== 'number' && type !== 'boolean' && value[i] !== null) {
errors.push(new ValidationError(key + '[' + i + ']', value[i], 'string, number, boolean, or null expected, %s found', type));
}
}

return errors;
}
4 changes: 3 additions & 1 deletion reference/v8.json
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,9 @@
"!in",
"all",
"any",
"none"
"none",
"has",
"!has"
],
"doc": "The filter operator."
},
Expand Down
2 changes: 1 addition & 1 deletion reference/v8.min.json

Large diffs are not rendered by default.

52 changes: 51 additions & 1 deletion test/fixture/filters.input.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": 7,
"version": 8,
"sources": {
"source": {
"type": "vector",
Expand Down Expand Up @@ -135,6 +135,56 @@
"mapbox",
null
]
},
{
"id": "has",
"type": "line",
"source": "source",
"source-layer": "source-layer",
"filter": [
"has",
"mapbox"
]
},
{
"id": "!has",
"type": "line",
"source": "source",
"source-layer": "source-layer",
"filter": [
"!has",
"mapbox"
]
},
{
"id": "has-extra-argument",
"type": "line",
"source": "source",
"source-layer": "source-layer",
"filter": [
"has",
"mapbox",
"boxmap"
]
},
{
"id": "has-invalid-key",
"type": "line",
"source": "source",
"source-layer": "source-layer",
"filter": [
"has",
5
]
},
{
"id": "has-missing-key",
"type": "line",
"source": "source",
"source-layer": "source-layer",
"filter": [
"has"
]
}
]
}
14 changes: 13 additions & 1 deletion test/fixture/filters.output.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"line": 22
},
{
"message": "layers[2].filter[0]: expected one of [==, !=, >, >=, <, <=, in, !in, all, any, none], = found",
"message": "layers[2].filter[0]: expected one of [==, !=, >, >=, <, <=, in, !in, all, any, none, has, !has], = found",
"line": 30
},
{
Expand Down Expand Up @@ -50,5 +50,17 @@
{
"message": "layers[11].filter[1]: filter array must have at least 1 element",
"line": 125
},
{
"message": "layers[15].filter: \"has\" filter must have exactly 1 operand",
"line": 164
},
{
"message": "layers[16].filter[1]: string expected, number found",
"line": 177
},
{
"message": "layers[17].filter: \"has\" filter must have exactly 1 operand",
"line": 185
}
]

0 comments on commit 2c5d620

Please sign in to comment.