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

Commit

Permalink
Add support for expression test
Browse files Browse the repository at this point in the history
Fix polygon within algorithm
Add Unit tests

Fix incorrect metrics folder for ios-render-test-runner job
  • Loading branch information
zmiao committed Feb 11, 2020
1 parent bb32c29 commit e9c6eba
Show file tree
Hide file tree
Showing 16 changed files with 357 additions and 1,867 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ add_library(
${PROJECT_SOURCE_DIR}/include/mbgl/style/expression/step.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/style/expression/type.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/style/expression/value.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/style/expression/within.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/style/filter.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/style/image.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/style/layer.hpp
Expand Down Expand Up @@ -578,6 +579,7 @@ add_library(
${PROJECT_SOURCE_DIR}/src/mbgl/style/expression/util.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/style/expression/util.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/style/expression/value.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/style/expression/within.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/style/filter.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/style/image.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/style/image_impl.cpp
Expand Down
30 changes: 26 additions & 4 deletions expression-test/expression_test_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include <args.hxx>

#include <regex>

using namespace mbgl;
using namespace mbgl::style;
using namespace mbgl::style::conversion;
Expand Down Expand Up @@ -254,6 +256,19 @@ bool parseInputs(const JSValue& inputsValue, TestData& data) {
heatmapDensity = evaluationContext["heatmapDensity"].GetDouble();
}

// Parse canonicalID
optional<CanonicalTileID> canonical;
if (evaluationContext.HasMember("canonicalID")) {
assert(evaluationContext["canonicalID"].IsObject());
assert(
evaluationContext["canonicalID"].HasMember("z") && evaluationContext["canonicalID"]["z"].IsNumber() &&
evaluationContext["canonicalID"].HasMember("x") && evaluationContext["canonicalID"]["x"].IsNumber() &&
evaluationContext["canonicalID"].HasMember("y") && evaluationContext["canonicalID"]["y"].IsNumber());
canonical = CanonicalTileID(evaluationContext["canonicalID"]["z"].GetUint(),
evaluationContext["canonicalID"]["x"].GetUint(),
evaluationContext["canonicalID"]["y"].GetUint());
}

// Parse availableImages
std::set<std::string> availableImages;
if (evaluationContext.HasMember("availableImages")) {
Expand Down Expand Up @@ -282,8 +297,11 @@ bool parseInputs(const JSValue& inputsValue, TestData& data) {
feature.id = mapbox::geojson::convert<mapbox::feature::identifier>(featureObject["id"]);
}

data.inputs.emplace_back(
std::move(zoom), std::move(heatmapDensity), std::move(availableImages), std::move(feature));
data.inputs.emplace_back(std::move(zoom),
std::move(heatmapDensity),
std::move(canonical),
std::move(availableImages),
std::move(feature));
}
return true;
}
Expand All @@ -294,11 +312,11 @@ std::tuple<filesystem::path, std::vector<filesystem::path>, bool, uint32_t> pars
args::ArgumentParser argumentParser("Mapbox GL Expression Test Runner");

args::HelpFlag helpFlag(argumentParser, "help", "Display this help menu", { 'h', "help" });
args::Flag shuffleFlag(argumentParser, "shuffle", "Toggle shuffling the tests order",
{ 's', "shuffle" });
args::Flag shuffleFlag(argumentParser, "shuffle", "Toggle shuffling the tests order", {'s', "shuffle"});
args::ValueFlag<uint32_t> seedValue(argumentParser, "seed", "Shuffle seed (default: random)",
{ "seed" });
args::PositionalList<std::string> testNameValues(argumentParser, "URL", "Test name(s)");
args::ValueFlag<std::string> testFilterValue(argumentParser, "filter", "Test filter regex", {'f', "filter"});

try {
argumentParser.ParseCLI(argc, argv);
Expand Down Expand Up @@ -336,6 +354,7 @@ std::tuple<filesystem::path, std::vector<filesystem::path>, bool, uint32_t> pars
paths.emplace_back(rootPath);
}

auto testFilter = testFilterValue ? args::get(testFilterValue) : std::string{};
// Recursively traverse through the test paths and collect test directories containing "test.json".
std::vector<filesystem::path> testPaths;
testPaths.reserve(paths.size());
Expand All @@ -346,6 +365,9 @@ std::tuple<filesystem::path, std::vector<filesystem::path>, bool, uint32_t> pars
}

for (auto& testPath : filesystem::recursive_directory_iterator(path)) {
if (!testFilter.empty() && !std::regex_search(testPath.path().string(), std::regex(testFilter))) {
continue;
}
if (testPath.path().filename() == "test.json") {
testPaths.emplace_back(testPath.path());
}
Expand Down
3 changes: 3 additions & 0 deletions expression-test/expression_test_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ using namespace mbgl;
struct Input {
Input(optional<float> zoom_,
optional<double> heatmapDensity_,
optional<CanonicalTileID> canonical_,
std::set<std::string> availableImages_,
Feature feature_)
: zoom(std::move(zoom_)),
heatmapDensity(std::move(heatmapDensity_)),
canonical(std::move(canonical_)),
availableImages(std::move(availableImages_)),
feature(std::move(feature_)) {}
optional<float> zoom;
optional<double> heatmapDensity;
optional<CanonicalTileID> canonical;
std::set<std::string> availableImages;
Feature feature;
};
Expand Down
10 changes: 8 additions & 2 deletions expression-test/expression_test_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,14 @@ TestRunOutput runExpressionTest(TestData& data, const std::string& rootPath, con
std::vector<Value> outputs;
if (!data.inputs.empty()) {
for (const auto& input : data.inputs) {
auto evaluationResult =
expression->evaluate(input.zoom, input.feature, input.heatmapDensity, input.availableImages);
mbgl::style::expression::EvaluationResult evaluationResult;
if (input.canonical) {
evaluationResult = expression->evaluate(
input.zoom, input.feature, input.heatmapDensity, input.availableImages, *input.canonical);
} else {
evaluationResult =
expression->evaluate(input.zoom, input.feature, input.heatmapDensity, input.availableImages);
}
if (!evaluationResult) {
std::unordered_map<std::string, Value> error{{"error", Value{evaluationResult.error().message}}};
outputs.emplace_back(Value{std::move(error)});
Expand Down
5 changes: 5 additions & 0 deletions include/mbgl/style/expression/expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ class Expression {
const Feature& feature,
optional<double> colorRampParameter,
const std::set<std::string>& availableImages) const;
EvaluationResult evaluate(optional<float> zoom,
const Feature& feature,
optional<double> colorRampParameter,
const std::set<std::string>& availableImages,
const CanonicalTileID& canonical) const;
EvaluationResult evaluate(optional<mbgl::Value> accumulated, const Feature& feature) const;

/**
Expand Down
4 changes: 2 additions & 2 deletions include/mbgl/style/expression/within.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ class Within final : public Expression {
return false;
}

std::vector<optional<Value>> possibleOutputs() const override { return {{false}}; }
std::vector<optional<Value>> possibleOutputs() const override { return {{true}, {false}}; }

mbgl::Value serialize() const override;
std::string getOperator() const override { return "Within"; }
std::string getOperator() const override { return "within"; }

private:
GeoJSON geoJSONSource;
Expand Down
Loading

0 comments on commit e9c6eba

Please sign in to comment.