Merge pull request #370 from mapbox/style-parser-test
Malformed stylesheet tests
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,3 +17,4 @@
|
||||
/src/shader/shaders_gles2.cpp
|
||||
/bin/style.bin.js
|
||||
/test/fixtures/styles/index.html
|
||||
/test/fixtures/style_parser/styles
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('./mkdirp');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
try { var glsl = require('mapbox-glsl-optimizer'); } catch(err) {}
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
|
||||
|
||||
function mkdirP (p, opts, f, made) {
|
||||
if (typeof opts === 'function') {
|
||||
f = opts;
|
||||
opts = {};
|
||||
}
|
||||
else if (!opts || typeof opts !== 'object') {
|
||||
opts = { mode: opts };
|
||||
}
|
||||
|
||||
var mode = opts.mode;
|
||||
var xfs = opts.fs || fs;
|
||||
|
||||
if (mode === undefined) {
|
||||
mode = 0777 & (~process.umask());
|
||||
}
|
||||
if (!made) made = null;
|
||||
|
||||
var cb = f || function () {};
|
||||
p = path.resolve(p);
|
||||
|
||||
xfs.mkdir(p, mode, function (er) {
|
||||
if (!er) {
|
||||
made = made || p;
|
||||
return cb(null, made);
|
||||
}
|
||||
switch (er.code) {
|
||||
case 'ENOENT':
|
||||
mkdirP(path.dirname(p), opts, function (er, made) {
|
||||
if (er) cb(er, made);
|
||||
else mkdirP(p, opts, cb, made);
|
||||
});
|
||||
break;
|
||||
|
||||
// In the case of any other error, just see if there's a dir
|
||||
// there already. If so, then hooray! If not, then something
|
||||
// is borked.
|
||||
default:
|
||||
xfs.stat(p, function (er2, stat) {
|
||||
// if the stat fails, then that's super weird.
|
||||
// let the original error be the failure reason.
|
||||
if (er2 || !stat.isDirectory()) cb(er, made)
|
||||
else cb(null, made);
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mkdirP.sync = function sync (p, opts, made) {
|
||||
if (!opts || typeof opts !== 'object') {
|
||||
opts = { mode: opts };
|
||||
}
|
||||
|
||||
var mode = opts.mode;
|
||||
var xfs = opts.fs || fs;
|
||||
|
||||
if (mode === undefined) {
|
||||
mode = 0777 & (~process.umask());
|
||||
}
|
||||
if (!made) made = null;
|
||||
|
||||
p = path.resolve(p);
|
||||
|
||||
try {
|
||||
xfs.mkdirSync(p, mode);
|
||||
made = made || p;
|
||||
}
|
||||
catch (err0) {
|
||||
switch (err0.code) {
|
||||
case 'ENOENT' :
|
||||
made = sync(path.dirname(p), opts, made);
|
||||
sync(p, opts, made);
|
||||
break;
|
||||
|
||||
// In the case of any other error, just see if there's a dir
|
||||
// there already. If so, then hooray! If not, then something
|
||||
// is borked.
|
||||
default:
|
||||
var stat;
|
||||
try {
|
||||
stat = xfs.statSync(p);
|
||||
}
|
||||
catch (err1) {
|
||||
throw err0;
|
||||
}
|
||||
if (!stat.isDirectory()) throw err0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return made;
|
||||
};
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "mbgl-native",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"mapbox-glsl-optimizer": "~0.1.0"
|
||||
}
|
||||
"name": "mbgl-native",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"mapbox-glsl-optimizer": "~0.1.0",
|
||||
"mkdirp": "^0.5.0"
|
||||
}
|
||||
}
|
||||
|
||||
9
configure
vendored
9
configure
vendored
@@ -22,6 +22,11 @@ parser.add_option("--node",
|
||||
dest="node",
|
||||
help="Name of the node executable (defaults to node)")
|
||||
|
||||
parser.add_option("--npm",
|
||||
action="store",
|
||||
dest="npm",
|
||||
help="Name of the npm executable (defaults to npm)")
|
||||
|
||||
parser.add_option("--pkg-config-root",
|
||||
action="store",
|
||||
dest="pkgconfig_root",
|
||||
@@ -59,6 +64,10 @@ def configure_mbgl(o):
|
||||
o['variables']['node'] = options.node
|
||||
else:
|
||||
o['variables']['node'] = 'node'
|
||||
if options.npm:
|
||||
o['variables']['npm'] = options.npm
|
||||
else:
|
||||
o['variables']['npm'] = 'npm'
|
||||
o['target_defaults']['default_configuration'] = 'Debug' if options.debug else 'Release'
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
|
||||
public:
|
||||
Style();
|
||||
~Style();
|
||||
|
||||
void loadJSON(const uint8_t *const data);
|
||||
|
||||
|
||||
40
mapboxgl.gyp
40
mapboxgl.gyp
@@ -8,6 +8,9 @@
|
||||
'target_name': 'shaders',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'npm_install'
|
||||
],
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Build Shaders',
|
||||
@@ -33,6 +36,23 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'target_name': 'npm_install',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'npm install',
|
||||
'inputs': [
|
||||
'bin/package.json',
|
||||
],
|
||||
'outputs': [
|
||||
'bin/node_modules',
|
||||
],
|
||||
'action': ['./scripts/npm_install.sh', '<@(npm)']
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'touch_styles',
|
||||
'type': 'none',
|
||||
@@ -65,6 +85,20 @@
|
||||
'destination': '<(PRODUCT_DIR)'
|
||||
}],
|
||||
},
|
||||
{
|
||||
'target_name': 'copy_fixtures',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'bundle_styles'
|
||||
],
|
||||
'copies': [
|
||||
{
|
||||
'files': [ 'styles' ],
|
||||
'destination': 'test/fixtures/style_parser'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'copy_certificate_bundle',
|
||||
'type': 'none',
|
||||
@@ -90,7 +124,7 @@
|
||||
'<!@(find include -name "*.hpp")',
|
||||
'<!@(find include -name "*.h")',
|
||||
'<!@(find src -name "*.glsl")',
|
||||
'bin/style.js'
|
||||
'bin/style.json'
|
||||
],
|
||||
'xcode_settings': {
|
||||
'SDKROOT': 'macosx',
|
||||
@@ -157,7 +191,7 @@
|
||||
'<!@(find include -name "*.hpp")',
|
||||
'<!@(find include -name "*.h")',
|
||||
'<!@(find src -name "*.glsl")',
|
||||
'bin/style.js'
|
||||
'bin/style.json'
|
||||
],
|
||||
'xcode_settings': {
|
||||
'SDKROOT': 'iphoneos',
|
||||
@@ -213,4 +247,4 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
8
scripts/npm_install.sh
Executable file
8
scripts/npm_install.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
cd bin
|
||||
$1 install --clang=1
|
||||
cd ../
|
||||
@@ -40,6 +40,9 @@ if [[ $MISSING_DEPS != "" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NODE=`which node`
|
||||
NPM=`which npm`
|
||||
|
||||
if [ ! -d 'mapnik-packaging/.git' ]; then
|
||||
git clone --depth=1 https://github.com/mapnik/mapnik-packaging.git
|
||||
fi
|
||||
@@ -92,7 +95,8 @@ cd ../../
|
||||
./configure \
|
||||
--pkg-config-root=`pwd`/mapnik-packaging/osx/out/build-cpp11-libcpp-universal/lib/pkgconfig \
|
||||
--boost=`pwd`/mapnik-packaging/osx/out/build-cpp11-libcpp-universal \
|
||||
--node=`which node`
|
||||
--npm=$NPM \
|
||||
--node=$NODE
|
||||
|
||||
elif [ ${UNAME} = 'Linux' ]; then
|
||||
|
||||
@@ -122,5 +126,6 @@ cd ../../
|
||||
./configure \
|
||||
--pkg-config-root=`pwd`/mapnik-packaging/osx/out/build-cpp11-libstdcpp-gcc-x86_64-linux/lib/pkgconfig \
|
||||
--boost=`pwd`/mapnik-packaging/osx/out/build-cpp11-libstdcpp-gcc-x86_64-linux \
|
||||
--node=`which node`
|
||||
--npm=$NPM \
|
||||
--node=$NODE
|
||||
fi
|
||||
|
||||
@@ -19,6 +19,11 @@ Style::Style()
|
||||
: mtx(std::make_unique<uv::rwlock>()) {
|
||||
}
|
||||
|
||||
// Note: This constructor is seemingly empty, but we need to declare it anyway
|
||||
// because this file includes uv_detail.hpp, which has the declarations necessary
|
||||
// for deleting the std::unique_ptr<uv::rwlock>.
|
||||
Style::~Style() {}
|
||||
|
||||
void Style::updateProperties(float z, timestamp now) {
|
||||
uv::writelock lock(mtx);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ void StyleParser::parseConstants(JSVal value) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw Style::exception("constants must be an object");
|
||||
Log::Warning(Event::ParseStyle, "constants must be an object");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ template<> bool StyleParser::parseRenderProperty(JSVal value, std::string &targe
|
||||
target = { property.GetString(), property.GetStringLength() };
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] '%s' must be a string\n", name);
|
||||
Log::Warning(Event::ParseStyle, "'%s' must be a string", name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -97,7 +97,7 @@ template<> bool StyleParser::parseRenderProperty(JSVal value, float &target, con
|
||||
target = property.GetDouble();
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] '%s' must be a number\n", name);
|
||||
Log::Warning(Event::ParseStyle, "'%s' must be a number", name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -109,14 +109,14 @@ template<> bool StyleParser::parseRenderProperty(JSVal value, uint16_t &target,
|
||||
if (property.IsUint()) {
|
||||
unsigned int value = property.GetUint();
|
||||
if (value > std::numeric_limits<uint16_t>::max()) {
|
||||
fprintf(stderr, "[WARNING] values for %s that are larger than %d are not supported\n", name, std::numeric_limits<uint16_t>::max());
|
||||
Log::Warning(Event::ParseStyle, "values for %s that are larger than %d are not supported", name, std::numeric_limits<uint16_t>::max());
|
||||
return false;
|
||||
}
|
||||
|
||||
target = value;
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] %s must be an unsigned integer\n", name);
|
||||
Log::Warning(Event::ParseStyle, "%s must be an unsigned integer", name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -129,7 +129,7 @@ template<> bool StyleParser::parseRenderProperty(JSVal value, int32_t &target, c
|
||||
target = property.GetInt();
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] %s must be an integer\n", name);
|
||||
Log::Warning(Event::ParseStyle, "%s must be an integer", name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -144,10 +144,10 @@ template<> bool StyleParser::parseRenderProperty(JSVal value, vec2<float> &targe
|
||||
target.y = property[(rapidjson::SizeType)1].GetDouble();
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] %s must have at least two members\n", name);
|
||||
Log::Warning(Event::ParseStyle, "%s must have at least two members", name);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] %s must be a n array of numbers\n", name);
|
||||
Log::Warning(Event::ParseStyle, "%s must be an array of numbers", name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -161,7 +161,7 @@ bool StyleParser::parseRenderProperty(JSVal value, T &target, const char *name)
|
||||
target = Parser({ property.GetString(), property.GetStringLength() });
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] %s must have one of the enum values\n", name);
|
||||
Log::Warning(Event::ParseStyle, "%s must have one of the enum values", name);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -192,7 +192,7 @@ void StyleParser::parseSources(JSVal value) {
|
||||
sources.emplace(std::move(name), std::make_shared<StyleSource>(SourceInfo { type, url, tile_size, min_zoom, max_zoom }));
|
||||
}
|
||||
} else {
|
||||
throw Style::exception("sources must be an object");
|
||||
Log::Warning(Event::ParseStyle, "sources must be an object");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ void StyleParser::parseSources(JSVal value) {
|
||||
|
||||
Color parseColor(JSVal value) {
|
||||
if (!value.IsString()) {
|
||||
fprintf(stderr, "[WARNING] color value must be a string\n");
|
||||
Log::Warning(Event::ParseStyle, "color value must be a string");
|
||||
return Color{{ 0, 0, 0, 0 }};
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ bool StyleParser::parseFunctionArgument(JSVal value) {
|
||||
} else if (rvalue.IsNumber()) {
|
||||
return rvalue.GetDouble();
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] function argument must be a boolean or numeric value");
|
||||
Log::Warning(Event::ParseStyle, "function argument must be a boolean or numeric value");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -234,7 +234,7 @@ float StyleParser::parseFunctionArgument(JSVal value) {
|
||||
if (rvalue.IsNumber()) {
|
||||
return rvalue.GetDouble();
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] function argument must be a numeric value");
|
||||
Log::Warning(Event::ParseStyle, "function argument must be a numeric value");
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
@@ -251,7 +251,7 @@ template <> inline float defaultBaseValue<Color>() { return 1.0; }
|
||||
template <typename T>
|
||||
std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value) {
|
||||
if (!value.HasMember("stops")) {
|
||||
fprintf(stderr, "[WARNING] stops function must specify a stops array\n");
|
||||
Log::Warning(Event::ParseStyle, "function must specify a function type");
|
||||
return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
|
||||
}
|
||||
|
||||
@@ -262,13 +262,13 @@ std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value) {
|
||||
if (value_base.IsNumber()) {
|
||||
base = value_base.GetDouble();
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] base must be numeric\n");
|
||||
Log::Warning(Event::ParseStyle, "base must be numeric");
|
||||
}
|
||||
}
|
||||
|
||||
JSVal value_stops = value["stops"];
|
||||
if (!value_stops.IsArray()) {
|
||||
fprintf(stderr, "[WARNING] stops function must specify a stops array\n");
|
||||
Log::Warning(Event::ParseStyle, "stops function must specify a stops array");
|
||||
return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
|
||||
}
|
||||
|
||||
@@ -277,19 +277,19 @@ std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value) {
|
||||
JSVal stop = value_stops[i];
|
||||
if (stop.IsArray()) {
|
||||
if (stop.Size() != 2) {
|
||||
fprintf(stderr, "[WARNING] stop must have zoom level and value specification\n");
|
||||
Log::Warning(Event::ParseStyle, "stop must have zoom level and value specification");
|
||||
return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
|
||||
}
|
||||
|
||||
JSVal z = stop[rapidjson::SizeType(0)];
|
||||
if (!z.IsNumber()) {
|
||||
fprintf(stderr, "[WARNING] zoom level in stop must be a number\n");
|
||||
Log::Warning(Event::ParseStyle, "zoom level in stop must be a number");
|
||||
return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
|
||||
}
|
||||
|
||||
stops.emplace_back(z.GetDouble(), parseFunctionArgument<T>(stop[rapidjson::SizeType(1)]));
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] function argument must be a numeric value\n");
|
||||
Log::Warning(Event::ParseStyle, "function argument must be a numeric value");
|
||||
return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) };
|
||||
}
|
||||
}
|
||||
@@ -352,7 +352,7 @@ bool StyleParser::parseOptionalProperty(const char *property_name, T &target, JS
|
||||
|
||||
template<> std::tuple<bool, std::string> StyleParser::parseProperty(JSVal value, const char *property_name) {
|
||||
if (!value.IsString()) {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a string\n", property_name);
|
||||
Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
|
||||
return std::tuple<bool, std::string> { false, std::string() };
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ template<> std::tuple<bool, std::string> StyleParser::parseProperty(JSVal value,
|
||||
|
||||
template<> std::tuple<bool, TranslateAnchorType> StyleParser::parseProperty(JSVal value, const char *property_name) {
|
||||
if (!value.IsString()) {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a string\n", property_name);
|
||||
Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
|
||||
return std::tuple<bool, TranslateAnchorType> { false, TranslateAnchorType::Map };
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ template<> std::tuple<bool, TranslateAnchorType> StyleParser::parseProperty(JSVa
|
||||
|
||||
template<> std::tuple<bool, RotateAnchorType> StyleParser::parseProperty<RotateAnchorType>(JSVal value, const char *property_name) {
|
||||
if (!value.IsString()) {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a string\n", property_name);
|
||||
Log::Warning(Event::ParseStyle, "value of '%s' must be a string", property_name);
|
||||
return std::tuple<bool, RotateAnchorType> { false, RotateAnchorType::Map };
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ template<> std::tuple<bool, Function<bool>> StyleParser::parseProperty(JSVal val
|
||||
} else if (value.IsBool()) {
|
||||
return std::tuple<bool, Function<bool>> { true, ConstantFunction<bool>(value.GetBool()) };
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be convertible to boolean, or a boolean function\n", property_name);
|
||||
Log::Warning(Event::ParseStyle, "value of '%s' must be convertible to boolean, or a boolean function", property_name);
|
||||
return std::tuple<bool, Function<bool>> { false, ConstantFunction<bool>(false) };
|
||||
}
|
||||
}
|
||||
@@ -416,7 +416,7 @@ template<> std::tuple<bool, Function<float>> StyleParser::parseProperty(JSVal va
|
||||
} else if (value.IsBool()) {
|
||||
return std::tuple<bool, Function<float>> { true, ConstantFunction<float>(value.GetBool()) };
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a number, or a number function\n", property_name);
|
||||
Log::Warning(Event::ParseStyle, "value of '%s' must be a number, or a number function", property_name);
|
||||
return std::tuple<bool, Function<float>> { false, ConstantFunction<float>(0) };
|
||||
}
|
||||
}
|
||||
@@ -427,7 +427,7 @@ template<> std::tuple<bool, Function<Color>> StyleParser::parseProperty(JSVal va
|
||||
} else if (value.IsString()) {
|
||||
return std::tuple<bool, Function<Color>> { true, ConstantFunction<Color>(parseColor(value)) };
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a color, or a color function\n", property_name);
|
||||
Log::Warning(Event::ParseStyle, "value of '%s' must be a color, or a color function", property_name);
|
||||
return std::tuple<bool, Function<Color>> { false, ConstantFunction<Color>(Color {{ 0, 0, 0, 0 }}) };
|
||||
}
|
||||
}
|
||||
@@ -437,11 +437,11 @@ bool StyleParser::parseOptionalProperty(const char *property_name, const std::ve
|
||||
if (value.HasMember(property_name)) {
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (!rvalue.IsArray()) {
|
||||
throw Style::exception("array value must be an array");
|
||||
Log::Warning(Event::ParseStyle, "array value must be an array");
|
||||
}
|
||||
|
||||
if (rvalue.Size() != keys.size()) {
|
||||
throw Style::exception("array value has unexpected number of elements");
|
||||
Log::Warning(Event::ParseStyle, "array value has unexpected number of elements");
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < keys.size(); i++) {
|
||||
@@ -464,27 +464,27 @@ std::unique_ptr<StyleLayerGroup> StyleParser::createLayers(JSVal value) {
|
||||
}
|
||||
return group;
|
||||
} else {
|
||||
throw Style::exception("layers must be an array");
|
||||
Log::Warning(Event::ParseStyle, "layers must be an array");
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<StyleLayer> StyleParser::createLayer(JSVal value) {
|
||||
if (value.IsObject()) {
|
||||
if (!value.HasMember("id")) {
|
||||
fprintf(stderr, "[WARNING] layer must have an id\n");
|
||||
Log::Warning(Event::ParseStyle, "layer must have an id");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSVal id = value["id"];
|
||||
if (!id.IsString()) {
|
||||
fprintf(stderr, "[WARNING] layer id must be a string\n");
|
||||
Log::Warning(Event::ParseStyle, "layer id must be a string");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::string layer_id = { id.GetString(), id.GetStringLength() };
|
||||
|
||||
if (layers.find(layer_id) != layers.end()) {
|
||||
fprintf(stderr, "[WARNING] duplicate layer id %s\n", layer_id.c_str());
|
||||
Log::Warning(Event::ParseStyle, "duplicate layer id %s", layer_id.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ std::shared_ptr<StyleLayer> StyleParser::createLayer(JSVal value) {
|
||||
|
||||
return layer;
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] layer must be an object\n");
|
||||
Log::Warning(Event::ParseStyle, "layer must be an object");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -533,7 +533,7 @@ void StyleParser::parseLayer(std::pair<JSVal, std::shared_ptr<StyleLayer>> &pair
|
||||
if (value.HasMember("type")) {
|
||||
JSVal type = value["type"];
|
||||
if (!type.IsString()) {
|
||||
fprintf(stderr, "[WARNING] layer type of '%s' must be a string\n", layer->id.c_str());
|
||||
Log::Warning(Event::ParseStyle, "layer type of '%s' must be a string", layer->id.c_str());
|
||||
} else {
|
||||
layer->type = StyleLayerTypeClass(std::string { type.GetString(), type.GetStringLength() });
|
||||
}
|
||||
@@ -541,7 +541,7 @@ void StyleParser::parseLayer(std::pair<JSVal, std::shared_ptr<StyleLayer>> &pair
|
||||
|
||||
// Make sure we have not previously attempted to parse this layer.
|
||||
if (std::find(stack.begin(), stack.end(), layer.get()) != stack.end()) {
|
||||
fprintf(stderr, "[WARNING] layer reference of '%s' is circular\n", layer->id.c_str());
|
||||
Log::Warning(Event::ParseStyle, "layer reference of '%s' is circular", layer->id.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -670,13 +670,13 @@ std::unique_ptr<RasterizeProperties> StyleParser::parseRasterize(JSVal value) {
|
||||
|
||||
void StyleParser::parseReference(JSVal value, std::shared_ptr<StyleLayer> &layer) {
|
||||
if (!value.IsString()) {
|
||||
fprintf(stderr, "[WARNING] layer ref of '%s' must be a string\n", layer->id.c_str());
|
||||
Log::Warning(Event::ParseStyle, "layer ref of '%s' must be a string", layer->id.c_str());
|
||||
return;
|
||||
}
|
||||
const std::string ref { value.GetString(), value.GetStringLength() };
|
||||
auto it = layers.find(ref);
|
||||
if (it == layers.end()) {
|
||||
fprintf(stderr, "[WARNING] layer '%s' references unknown layer %s\n", layer->id.c_str(), ref.c_str());
|
||||
Log::Warning(Event::ParseStyle, "layer '%s' references unknown layer %s", layer->id.c_str(), ref.c_str());
|
||||
// We cannot parse this layer further.
|
||||
return;
|
||||
}
|
||||
@@ -692,7 +692,7 @@ void StyleParser::parseReference(JSVal value, std::shared_ptr<StyleLayer> &layer
|
||||
layer->type = reference->type;
|
||||
|
||||
if (reference->layers) {
|
||||
fprintf(stderr, "[WARNING] layer '%s' references composite layer\n", layer->id.c_str());
|
||||
Log::Warning(Event::ParseStyle, "layer '%s' references composite layer", layer->id.c_str());
|
||||
// We cannot parse this layer further.
|
||||
return;
|
||||
} else {
|
||||
@@ -716,11 +716,10 @@ void StyleParser::parseBucket(JSVal value, std::shared_ptr<StyleLayer> &layer) {
|
||||
if (source_it != sources.end()) {
|
||||
layer->bucket->style_source = source_it->second;
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] can't find source '%s' required for layer '%s'\n",
|
||||
source_name.c_str(), layer->id.c_str());
|
||||
Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", source_name.c_str(), layer->id.c_str());
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] source of layer '%s' must be a string\n", layer->id.c_str());
|
||||
Log::Warning(Event::ParseStyle, "source of layer '%s' must be a string", layer->id.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,7 +728,7 @@ void StyleParser::parseBucket(JSVal value, std::shared_ptr<StyleLayer> &layer) {
|
||||
if (value_source_layer.IsString()) {
|
||||
layer->bucket->source_layer = { value_source_layer.GetString(), value_source_layer.GetStringLength() };
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] source-layer of layer '%s' must be a string\n", layer->id.c_str());
|
||||
Log::Warning(Event::ParseStyle, "source-layer of layer '%s' must be a string", layer->id.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,7 +808,7 @@ FilterExpression StyleParser::parseFilter(JSVal value, FilterExpression::Operato
|
||||
expression.add(parseFilter(replaceConstant(value[i])));
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] expression must be either an array or an object\n");
|
||||
Log::Warning(Event::ParseStyle, "expression must be either an array or an object");
|
||||
}
|
||||
|
||||
return expression;
|
||||
@@ -851,7 +850,7 @@ std::vector<Value> StyleParser::parseValues(JSVal value) {
|
||||
|
||||
void StyleParser::parseRender(JSVal value, std::shared_ptr<StyleLayer> &layer) {
|
||||
if (!value.IsObject()) {
|
||||
fprintf(stderr, "[WARNING] render property of layer '%s' must be an object\n", layer->id.c_str());
|
||||
Log::Warning(Event::ParseStyle, "render property of layer '%s' must be an object", layer->id.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
2
test/fixtures/fixture_log.cpp
vendored
2
test/fixtures/fixture_log.cpp
vendored
@@ -44,4 +44,4 @@ std::vector<FixtureLogBackend::LogMessage> FixtureLogBackend::unchecked() const
|
||||
return os << "]" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
6
test/fixtures/style_parser/colors.info.json
vendored
Normal file
6
test/fixtures/style_parser/colors.info.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"default": {
|
||||
"log": [
|
||||
]
|
||||
}
|
||||
}
|
||||
40
test/fixtures/style_parser/colors.style.json
vendored
Normal file
40
test/fixtures/style_parser/colors.style.json
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "vector",
|
||||
"url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
|
||||
"maxZoom": 14
|
||||
}
|
||||
},
|
||||
"constants": {
|
||||
"@land":"r44,239,225)",
|
||||
"@snow":"f4f8foNGbjf#",
|
||||
"@crop":"#eerLznieed4"
|
||||
},
|
||||
"layers": [{
|
||||
"id": "background",
|
||||
"type": "background",
|
||||
"style": {
|
||||
"background-color": "@land"
|
||||
}
|
||||
}, {
|
||||
"id": "landcover_snow",
|
||||
"source": "mapbox",
|
||||
"source-layer": "landcover",
|
||||
"filter": { "class": "snow" },
|
||||
"type": "fill",
|
||||
"style": {
|
||||
"fill-color": "@snow"
|
||||
}
|
||||
}, {
|
||||
"id": "landcover_crop",
|
||||
"source": "mapbox",
|
||||
"source-layer": "landcover",
|
||||
"filter": { "class": "crop" },
|
||||
"type": "fill",
|
||||
"style": {
|
||||
"fill-color": "@crop"
|
||||
}
|
||||
}]
|
||||
}
|
||||
6
test/fixtures/style_parser/default.info.json
vendored
Normal file
6
test/fixtures/style_parser/default.info.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"default": {
|
||||
"log": [
|
||||
]
|
||||
}
|
||||
}
|
||||
2244
test/fixtures/style_parser/default.style.json
vendored
Executable file
2244
test/fixtures/style_parser/default.style.json
vendored
Executable file
File diff suppressed because it is too large
Load Diff
7
test/fixtures/style_parser/function-numeric.info.json
vendored
Normal file
7
test/fixtures/style_parser/function-numeric.info.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"default": {
|
||||
"log": [
|
||||
[1, "WARNING", "ParseStyle", "function argument must be a numeric value"]
|
||||
]
|
||||
}
|
||||
}
|
||||
22
test/fixtures/style_parser/function-numeric.style.json
vendored
Normal file
22
test/fixtures/style_parser/function-numeric.style.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "vector",
|
||||
"url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
|
||||
"maxZoom": 14
|
||||
}
|
||||
},
|
||||
"layers": [{
|
||||
"id": "waterway_river_canal",
|
||||
"source": "mapbox",
|
||||
"source-layer": "waterway",
|
||||
"filter": { "type": ["river", "canal"] },
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-width": {
|
||||
"stops": [0]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
7
test/fixtures/style_parser/function-type.info.json
vendored
Normal file
7
test/fixtures/style_parser/function-type.info.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"default": {
|
||||
"log": [
|
||||
[1, "WARNING", "ParseStyle", "function must specify a function type"]
|
||||
]
|
||||
}
|
||||
}
|
||||
20
test/fixtures/style_parser/function-type.style.json
vendored
Normal file
20
test/fixtures/style_parser/function-type.style.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "vector",
|
||||
"url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
|
||||
"maxZoom": 14
|
||||
}
|
||||
},
|
||||
"layers": [{
|
||||
"id": "waterway_river_canal",
|
||||
"source": "mapbox",
|
||||
"source-layer": "waterway",
|
||||
"filter": { "type": ["river", "canal"] },
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-width": {}
|
||||
}
|
||||
}]
|
||||
}
|
||||
7
test/fixtures/style_parser/line-opacity.info.json
vendored
Normal file
7
test/fixtures/style_parser/line-opacity.info.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"default": {
|
||||
"log": [
|
||||
[1, "WARNING", "ParseStyle", "value of 'line-opacity' must be a number, or a number function"]
|
||||
]
|
||||
}
|
||||
}
|
||||
22
test/fixtures/style_parser/line-opacity.style.json
vendored
Normal file
22
test/fixtures/style_parser/line-opacity.style.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "vector",
|
||||
"url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
|
||||
"maxZoom": 14
|
||||
}
|
||||
},
|
||||
"layers": [{
|
||||
"id": "contour_line_loud",
|
||||
"source": "mapbox",
|
||||
"source-layer": "contour",
|
||||
"filter": { "index": 5 },
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-color": "#008",
|
||||
"line-width": 0.9,
|
||||
"line-opacity": null
|
||||
}
|
||||
}]
|
||||
}
|
||||
7
test/fixtures/style_parser/line-width.info.json
vendored
Normal file
7
test/fixtures/style_parser/line-width.info.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"default": {
|
||||
"log": [
|
||||
[1, "WARNING", "ParseStyle", "value of 'line-width' must be a number, or a number function"]
|
||||
]
|
||||
}
|
||||
}
|
||||
20
test/fixtures/style_parser/line-width.style.json
vendored
Normal file
20
test/fixtures/style_parser/line-width.style.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "vector",
|
||||
"url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
|
||||
"maxZoom": 14
|
||||
}
|
||||
},
|
||||
"layers": [{
|
||||
"id": "waterway_river_canal",
|
||||
"source": "mapbox",
|
||||
"source-layer": "waterway",
|
||||
"filter": { "type": ["river", "canal"] },
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-width": null
|
||||
}
|
||||
}]
|
||||
}
|
||||
7
test/fixtures/style_parser/stop-zoom-value.info.json
vendored
Normal file
7
test/fixtures/style_parser/stop-zoom-value.info.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"default": {
|
||||
"log": [
|
||||
[1, "WARNING", "ParseStyle", "stop must have zoom level and value specification"]
|
||||
]
|
||||
}
|
||||
}
|
||||
45
test/fixtures/style_parser/stop-zoom-value.style.json
vendored
Normal file
45
test/fixtures/style_parser/stop-zoom-value.style.json
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "vector",
|
||||
"url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
|
||||
"maxZoom": 14
|
||||
}
|
||||
},
|
||||
"layers": [{
|
||||
"id": "landcover_grass",
|
||||
"source": "mapbox",
|
||||
"source-layer": "landcover",
|
||||
"filter": { "class": "grass" },
|
||||
"type": "fill",
|
||||
"style": {
|
||||
"fill-opacity": {
|
||||
"stops": []
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "landcover_scrub",
|
||||
"source": "mapbox",
|
||||
"source-layer": "landcover",
|
||||
"filter": { "class": "scrub" },
|
||||
"type": "fill",
|
||||
"style": {
|
||||
"fill-opacity": {
|
||||
"stops": [[12]]
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"id": "landcover_wood",
|
||||
"source": "mapbox",
|
||||
"source-layer": "landcover",
|
||||
"filter": { "class": "wood" },
|
||||
"type": "fill",
|
||||
"style": {
|
||||
"fill-color": "@wood",
|
||||
"fill-opacity": {
|
||||
"stops": [[12, 1], [13, 0.8], [16, 0.2]]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
7
test/fixtures/style_parser/stops-array.info.json
vendored
Normal file
7
test/fixtures/style_parser/stops-array.info.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"default": {
|
||||
"log": [
|
||||
[1, "WARNING", "ParseStyle", "stops function must specify a stops array"]
|
||||
]
|
||||
}
|
||||
}
|
||||
22
test/fixtures/style_parser/stops-array.style.json
vendored
Normal file
22
test/fixtures/style_parser/stops-array.style.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "vector",
|
||||
"url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
|
||||
"maxZoom": 14
|
||||
}
|
||||
},
|
||||
"layers": [{
|
||||
"id": "waterway_river_canal",
|
||||
"source": "mapbox",
|
||||
"source-layer": "waterway",
|
||||
"filter": { "type": ["river", "canal"] },
|
||||
"type": "line",
|
||||
"style": {
|
||||
"line-width": {
|
||||
"stops": null
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
7
test/fixtures/style_parser/text-size.info.json
vendored
Normal file
7
test/fixtures/style_parser/text-size.info.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"default": {
|
||||
"log": [
|
||||
[1, "WARNING", "ParseStyle", "value of 'text-size' must be a number, or a number function"]
|
||||
]
|
||||
}
|
||||
}
|
||||
20
test/fixtures/style_parser/text-size.style.json
vendored
Normal file
20
test/fixtures/style_parser/text-size.style.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": {
|
||||
"mapbox": {
|
||||
"type": "vector",
|
||||
"url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
|
||||
"maxZoom": 14
|
||||
}
|
||||
},
|
||||
"layers": [{
|
||||
"id": "country_label",
|
||||
"source": "mapbox",
|
||||
"source-layer": "country_label",
|
||||
"filter": { "$type": "Point" },
|
||||
"type": "text",
|
||||
"style": {
|
||||
"text-size": null
|
||||
}
|
||||
}]
|
||||
}
|
||||
101
test/style_parser.cpp
Normal file
101
test/style_parser.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
#include "./fixtures/fixture_log.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
const std::string base_directory = []{
|
||||
std::string fn = __FILE__;
|
||||
fn.erase(fn.find_last_of("/"));
|
||||
return fn + "/fixtures/style_parser";
|
||||
}();
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
typedef std::pair<uint32_t, std::string> Message;
|
||||
typedef std::vector<Message> Messages;
|
||||
|
||||
class StyleParserTest : public ::testing::TestWithParam<std::string> {};
|
||||
|
||||
TEST_P(StyleParserTest, ParseStyle) {
|
||||
const std::string &base = base_directory + "/" + GetParam();
|
||||
|
||||
const std::string style_path = base + ".style.json";
|
||||
const std::string info = util::read_file(base + ".info.json");
|
||||
|
||||
// Parse settings.
|
||||
rapidjson::Document doc;
|
||||
doc.Parse<0>((const char *const)info.c_str());
|
||||
ASSERT_EQ(false, doc.HasParseError());
|
||||
ASSERT_EQ(true, doc.IsObject());
|
||||
|
||||
std::ifstream stylefile(style_path);
|
||||
ASSERT_TRUE(stylefile.good());
|
||||
std::stringstream stylejson;
|
||||
stylejson << stylefile.rdbuf();
|
||||
|
||||
const FixtureLogBackend &log = Log::Set<FixtureLogBackend>();
|
||||
|
||||
Style style;
|
||||
style.loadJSON((const uint8_t *)stylejson.str().c_str());
|
||||
|
||||
for (auto it = doc.MemberBegin(), end = doc.MemberEnd(); it != end; it++) {
|
||||
const std::string name { it->name.GetString(), it->name.GetStringLength() };
|
||||
const rapidjson::Value &value = it->value;
|
||||
ASSERT_EQ(true, value.IsObject());
|
||||
|
||||
if (value.HasMember("log")) {
|
||||
const rapidjson::Value &js_log = value["log"];
|
||||
ASSERT_EQ(true, js_log.IsArray());
|
||||
for (rapidjson::SizeType i = 0; i < js_log.Size(); i++) {
|
||||
const rapidjson::Value &js_entry = js_log[i];
|
||||
ASSERT_EQ(true, js_entry.IsArray());
|
||||
|
||||
const uint32_t count = js_entry[rapidjson::SizeType(0)].GetUint();
|
||||
const FixtureLogBackend::LogMessage message {
|
||||
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
|
||||
EventClass(js_entry[rapidjson::SizeType(2)].GetString()),
|
||||
js_entry[rapidjson::SizeType(3)].GetString()
|
||||
};
|
||||
|
||||
EXPECT_EQ(count, log.count(message)) << "Message: " << message << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
const auto &unchecked = log.unchecked();
|
||||
if (unchecked.size()) {
|
||||
std::cerr << "Unchecked Log Messages (" << base << "/" << name << "): " << std::endl << unchecked;
|
||||
}
|
||||
|
||||
ASSERT_EQ(0, unchecked.size());
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(StyleParser, StyleParserTest, ::testing::ValuesIn([] {
|
||||
std::vector<std::string> names;
|
||||
const std::string ending = ".info.json";
|
||||
|
||||
DIR *dir = opendir(base_directory.c_str());
|
||||
if (dir == nullptr) {
|
||||
return names;
|
||||
}
|
||||
|
||||
for (dirent *dp = nullptr; (dp = readdir(dir)) != nullptr;) {
|
||||
const std::string name = dp->d_name;
|
||||
if (name.length() >= ending.length() && name.compare(name.length() - ending.length(), ending.length(), ending) == 0) {
|
||||
names.push_back(name.substr(0, name.length() - ending.length()));
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return names;
|
||||
}()));
|
||||
@@ -71,7 +71,7 @@
|
||||
],
|
||||
"dependencies": [
|
||||
"../deps/gtest/gtest.gyp:gtest",
|
||||
"../mapboxgl.gyp:mapboxgl"
|
||||
"../mapboxgl.gyp:mapboxgl",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -87,7 +87,7 @@
|
||||
],
|
||||
"dependencies": [
|
||||
"../deps/gtest/gtest.gyp:gtest",
|
||||
"../mapboxgl.gyp:mapboxgl"
|
||||
"../mapboxgl.gyp:mapboxgl",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -103,7 +103,26 @@
|
||||
],
|
||||
"dependencies": [
|
||||
"../deps/gtest/gtest.gyp:gtest",
|
||||
"../mapboxgl.gyp:mapboxgl"
|
||||
"../mapboxgl.gyp:mapboxgl",
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_name": "style_parser",
|
||||
"product_name": "test_style_parser",
|
||||
"type": "executable",
|
||||
"libraries": [
|
||||
"-lpthread",
|
||||
],
|
||||
"sources": [
|
||||
"./main.cpp",
|
||||
"./style_parser.cpp",
|
||||
"./fixtures/fixture_log.hpp",
|
||||
"./fixtures/fixture_log.cpp",
|
||||
],
|
||||
"dependencies": [
|
||||
"../deps/gtest/gtest.gyp:gtest",
|
||||
"../mapboxgl.gyp:mapboxgl",
|
||||
"../mapboxgl.gyp:copy_fixtures",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -119,7 +138,7 @@
|
||||
],
|
||||
"dependencies": [
|
||||
"../deps/gtest/gtest.gyp:gtest",
|
||||
"../mapboxgl.gyp:mapboxgl"
|
||||
"../mapboxgl.gyp:mapboxgl",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -135,7 +154,7 @@
|
||||
],
|
||||
"dependencies": [
|
||||
"../deps/gtest/gtest.gyp:gtest",
|
||||
"../mapboxgl.gyp:mapboxgl"
|
||||
"../mapboxgl.gyp:mapboxgl",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -151,7 +170,7 @@
|
||||
],
|
||||
"dependencies": [
|
||||
"../deps/gtest/gtest.gyp:gtest",
|
||||
"../mapboxgl.gyp:mapboxgl"
|
||||
"../mapboxgl.gyp:mapboxgl",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -167,7 +186,7 @@
|
||||
],
|
||||
"dependencies": [
|
||||
"../deps/gtest/gtest.gyp:gtest",
|
||||
"../mapboxgl.gyp:mapboxgl"
|
||||
"../mapboxgl.gyp:mapboxgl",
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -203,6 +222,7 @@
|
||||
"tile",
|
||||
"functions",
|
||||
"headless",
|
||||
"style_parser",
|
||||
"comparisons",
|
||||
],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user