Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
Add expression_equality test for 'in'
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin committed Feb 12, 2020
1 parent 9cb1f21 commit 3c7b29e
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 25 deletions.
3 changes: 1 addition & 2 deletions include/mbgl/style/expression/in.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ namespace expression {

class In final : public Expression {
public:
In(std::unique_ptr<Expression> needle_, std::unique_ptr<Expression> haystack_)
: Expression(Kind::In, type::Boolean), needle(std::move(needle_)), haystack(std::move(haystack_)) {}
In(std::unique_ptr<Expression> needle_, std::unique_ptr<Expression> haystack_);

static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);

Expand Down
41 changes: 18 additions & 23 deletions src/mbgl/style/expression/in.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,43 @@ namespace expression {
namespace {
bool isComparableType(type::Type type) {
return type == type::Boolean || type == type::String || type == type::Number || type == type::Null ||
type == type::Value;
type == type::Value;
}

bool isComparableRuntimeValue(type::Type type) {
bool isComparableRuntimeType(type::Type type) {
return type == type::Boolean || type == type::String || type == type::Number || type == type::Null;
}

bool isSearchableRuntimeValue(type::Type type) {
bool isSearchableRuntimeType(type::Type type) {
return type == type::String || type.is<type::Array>() || type == type::Null;
}
} // namespace

In::In(std::unique_ptr<Expression> needle_, std::unique_ptr<Expression> haystack_)
: Expression(Kind::In, type::Boolean), needle(std::move(needle_)), haystack(std::move(haystack_)) {
assert(isComparableType(needle->getType()));
assert(isSearchableRuntimeType(haystack->getType()) || haystack->getType() == type::Value);
}

EvaluationResult In::evaluate(const EvaluationContext& params) const {
const EvaluationResult evaluatedNeedle = needle->evaluate(params);
if (!evaluatedNeedle) {
return evaluatedNeedle.error();
}

const EvaluationResult evaluatedHaystack = haystack->evaluate(params);
if (!evaluatedHaystack) {
return evaluatedHaystack.error();
}

const EvaluationResult evaluatedNeedle = needle->evaluate(params);
if (!evaluatedNeedle) {
return evaluatedNeedle.error();
}

type::Type evaluatedNeedleType = typeOf(*evaluatedNeedle);
if (!isComparableRuntimeValue(evaluatedNeedleType)) {
if (!isComparableRuntimeType(evaluatedNeedleType)) {
return EvaluationError{"Expected first argument to be of type boolean, string or number, but found " +
toString(evaluatedNeedleType) + " instead."};
}

type::Type evaluatedHaystackType = typeOf(*evaluatedHaystack);
if (!isSearchableRuntimeValue(evaluatedHaystackType)) {
if (!isSearchableRuntimeType(evaluatedHaystackType)) {
return EvaluationError{"Expected second argument to be of type array or string, but found " +
toString(evaluatedHaystackType) + " instead."};
}
Expand All @@ -65,19 +71,8 @@ EvaluationResult In::evaluate(const EvaluationContext& params) const {
return EvaluationResult(haystackString.find(needleValue) != std::string::npos);
} else {
const auto haystackArray = evaluatedHaystack->get<std::vector<Value>>();

bool result = false;
if (evaluatedNeedleType == type::Boolean) {
auto needleValue = evaluatedNeedle->get<bool>();
result = find(haystackArray.begin(), haystackArray.end(), needleValue) != haystackArray.end();
} else if (evaluatedNeedleType == type::String) {
auto needleValue = evaluatedNeedle->get<std::string>();
result = find(haystackArray.begin(), haystackArray.end(), needleValue) != haystackArray.end();
} else if (evaluatedNeedleType == type::Number) {
auto needleValue = evaluatedNeedle->get<double>();
result = find(haystackArray.begin(), haystackArray.end(), needleValue) != haystackArray.end();
}
return EvaluationResult(result);
return EvaluationResult(std::find(haystackArray.begin(), haystackArray.end(), *evaluatedNeedle) !=
haystackArray.end());
}
}

Expand Down
20 changes: 20 additions & 0 deletions test/fixtures/expression_equality/in.a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
"number",
[
"in",
[
"number",
[
"get",
"i"
]
],
[
"array",
[
"get",
"arr"
]
]
]
]
20 changes: 20 additions & 0 deletions test/fixtures/expression_equality/in.b.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
"number",
[
"in",
[
"number",
[
"get",
"i"
]
],
[
"array",
[
"get",
"arr_other"
]
]
]
]

0 comments on commit 3c7b29e

Please sign in to comment.