From b5154968097b0de943f2e5d22f488c53b14afb46 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Mon, 13 Jun 2016 12:57:46 -0700 Subject: [PATCH 1/6] Return default values for undefined feature properties in fns --- index.js | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index ca7e30f..02411a4 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ 'use strict'; -function createFunction(parameters, defaultType) { +function createFunction(parameters, defaultType, reference) { var fun; if (!isFunctionDefinition(parameters)) { @@ -45,7 +45,7 @@ function createFunction(parameters, defaultType) { featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z])]); } fun = function(zoom, feature) { - return evaluateExponentialFunction({ stops: featureFunctionStops, base: parameters.base }, zoom)(zoom, feature); + return evaluateExponentialFunction({ stops: featureFunctionStops, base: parameters.base }, zoom)(zoom, feature, reference); }; fun.isFeatureConstant = false; fun.isZoomConstant = false; @@ -58,7 +58,7 @@ function createFunction(parameters, defaultType) { fun.isZoomConstant = false; } else { fun = function(zoom, feature) { - return innerFun(parameters, feature[parameters.property]); + return innerFun(parameters, feature[parameters.property], reference); }; fun.isFeatureConstant = false; fun.isZoomConstant = true; @@ -68,7 +68,11 @@ function createFunction(parameters, defaultType) { return fun; } -function evaluateCategoricalFunction(parameters, input) { +function evaluateCategoricalFunction(parameters, input, reference) { + if (input === undefined && reference) { + return reference.default; + } + for (var i = 0; i < parameters.stops.length; i++) { if (input === parameters.stops[i][0]) { return parameters.stops[i][1]; @@ -77,14 +81,22 @@ function evaluateCategoricalFunction(parameters, input) { return parameters.stops[0][1]; } -function evaluateIntervalFunction(parameters, input) { +function evaluateIntervalFunction(parameters, input, reference) { + if (input === undefined && reference) { + return reference.default; + } + for (var i = 0; i < parameters.stops.length; i++) { if (input < parameters.stops[i][0]) break; } return parameters.stops[Math.max(i - 1, 0)][1]; } -function evaluateExponentialFunction(parameters, input) { +function evaluateExponentialFunction(parameters, input, reference) { + if (input == undefined && reference) { + return reference.default; + } + var base = parameters.base !== undefined ? parameters.base : 1; var i = 0; @@ -156,10 +168,10 @@ function isFunctionDefinition(value) { module.exports.isFunctionDefinition = isFunctionDefinition; -module.exports.interpolated = function(parameters) { - return createFunction(parameters, 'exponential'); +module.exports.interpolated = function(parameters, reference) { + return createFunction(parameters, 'exponential', reference); }; -module.exports['piecewise-constant'] = function(parameters) { - return createFunction(parameters, 'interval'); +module.exports['piecewise-constant'] = function(parameters, reference) { + return createFunction(parameters, 'interval', reference); }; From 8a4c09056663fd01ecc67c83a18cdedd7d1ff791 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Tue, 16 Aug 2016 18:35:16 -0700 Subject: [PATCH 2/6] Fix defaults behavior for zoom-and-property function, add a few tests --- index.js | 4 ++-- test/test.js | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 02411a4..73a0702 100644 --- a/index.js +++ b/index.js @@ -42,7 +42,7 @@ function createFunction(parameters, defaultType, reference) { } for (var z in featureFunctions) { - featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z])]); + featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z], type, reference)]); } fun = function(zoom, feature) { return evaluateExponentialFunction({ stops: featureFunctionStops, base: parameters.base }, zoom)(zoom, feature, reference); @@ -93,7 +93,7 @@ function evaluateIntervalFunction(parameters, input, reference) { } function evaluateExponentialFunction(parameters, input, reference) { - if (input == undefined && reference) { + if (input === undefined && reference) { return reference.default; } diff --git a/test/test.js b/test/test.js index 7989afa..b34fa47 100644 --- a/test/test.js +++ b/test/test.js @@ -5,7 +5,7 @@ var MapboxGLFunction = require('../').interpolated; test('function types', function(t) { - t.test('contant', function(t) { + t.test('constant', function(t) { t.test('range types', function(t) { @@ -107,6 +107,39 @@ test('function types', function(t) { t.end(); }); + t.test('property', function(t) { + var f = MapboxGLFunction({ + type: 'exponential', + stops: [[0, 0], [1000, 3000]], + property: 'prop' + }); + + t.equal(f(10, { prop: 0 }), 0); + t.equal(f(10, { prop: 1 }), 3); + t.equal(f(10, { prop: 100 }), 300); + t.equal(f(10, { prop: 1000 }), 3000); + t.equal(f(10, { prop: 3000 }), 3000); + t.equal(f(10, { prop: undefined }), 3000); + + t.end(); + }); + + t.test('property with reference default', function(t) { + var f = MapboxGLFunction({ + type: 'exponential', + stops: [[0, 0], [1000, 3000]], + property: 'prop' + }, { default: 10 }); + + t.equal(f(10, { prop: 0 }), 0); + t.equal(f(10, { prop: 1 }), 3); + t.equal(f(10, { prop: 100 }), 300); + t.equal(f(10, { prop: 1000 }), 3000); + t.equal(f(10, { prop: 3000 }), 3000); + t.equal(f(10, { prop: undefined }), 10); + + t.end(); + }); }); t.test('zoom + data stops', function(t) { @@ -156,6 +189,34 @@ test('function types', function(t) { t.end(); }); + t.test('default', function(t) { + var f = MapboxGLFunction({ + type: 'exponential', + property: 'prop', + base: 1, + stops: [ + [{ zoom: 15, value: 0}, 0], + [{ zoom: 15, value: 1000}, 0], + [{ zoom: 15.1, value: 0}, 0], + [{ zoom: 15.1, value: 10}, 30], + [{ zoom: 15.1, value: 1000}, 3000]] + }, { default: 3}); + + t.equal(f(15, { prop: 0 }), 0); + t.equal(f(15, { prop: 10 }), 0); + t.equal(f(15, { prop: 300 }), 0); + t.equal(f(15.2, { prop: 0 }), 0); + t.equal(f(15.2, { prop: 10 }), 30); + t.equal(f(15.2, { prop: undefined }), 3); + t.equal(f(15.2, { prop: 299 }), 897); + t.equal(f(16, { prop: 0 }), 0); + t.equal(f(16, { prop: 10 }), 30); + t.equal(f(16, { prop: undefined }), 3); + t.equal(f(16, { prop: 299 }), 897); + + t.end(); + }); + t.test('three elements', function(t) { var f = MapboxGLFunction({ type: 'exponential', From 83f0e0c52facf5ac6d9ee29e90c4a8ca0ed00199 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Wed, 17 Aug 2016 14:36:42 -0700 Subject: [PATCH 3/6] One more test --- test/test.js | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/test/test.js b/test/test.js index b34fa47..4614702 100644 --- a/test/test.js +++ b/test/test.js @@ -189,6 +189,27 @@ test('function types', function(t) { t.end(); }); + t.test('three elements', function(t) { + var f = MapboxGLFunction({ + type: 'exponential', + property: 'prop', + base: 1, + stops: [ + [{ zoom: 1, value: 0}, 0], + [{ zoom: 1, value: 2}, 4], + [{ zoom: 3, value: 0}, 0], + [{ zoom: 3, value: 2}, 12], + [{ zoom: 5, value: 0}, 0], + [{ zoom: 5, value: 2}, 20]] + }); + + t.equal(f(0, { prop: 1 }), 2); + t.equal(f(1, { prop: 1 }), 2); + t.equal(f(2, { prop: 1 }), 4); + + t.end(); + }); + t.test('default', function(t) { var f = MapboxGLFunction({ type: 'exponential', @@ -217,27 +238,6 @@ test('function types', function(t) { t.end(); }); - t.test('three elements', function(t) { - var f = MapboxGLFunction({ - type: 'exponential', - property: 'prop', - base: 1, - stops: [ - [{ zoom: 1, value: 0}, 0], - [{ zoom: 1, value: 2}, 4], - [{ zoom: 3, value: 0}, 0], - [{ zoom: 3, value: 2}, 12], - [{ zoom: 5, value: 0}, 0], - [{ zoom: 5, value: 2}, 20]] - }); - - t.equal(f(0, { prop: 1 }), 2); - t.equal(f(1, { prop: 1 }), 2); - t.equal(f(2, { prop: 1 }), 4); - - t.end(); - }); - t.test('fractional zoom', function(t) { var f = MapboxGLFunction({ type: 'exponential', @@ -369,9 +369,10 @@ test('property', function(t) { type: 'categorical', stops: [['map', 'neat'], ['box', 'swell']], property: 'mapbox' - }); + }, { default: 'cool' }); t.equal(f({}, {mapbox: 'box'}), 'swell'); + t.equal(f({}, {mapbox: undefined}), 'cool'); t.end(); }); From d8c631055e6cbb235e99aca140c9f74055e4e90f Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Fri, 19 Aug 2016 12:05:12 -0700 Subject: [PATCH 4/6] Only use reference if it has a default value (otherwise breaks e.g. fill-outline-color) --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 73a0702..1f49f35 100644 --- a/index.js +++ b/index.js @@ -69,7 +69,7 @@ function createFunction(parameters, defaultType, reference) { } function evaluateCategoricalFunction(parameters, input, reference) { - if (input === undefined && reference) { + if (input === undefined && reference && reference.default) { return reference.default; } @@ -82,7 +82,7 @@ function evaluateCategoricalFunction(parameters, input, reference) { } function evaluateIntervalFunction(parameters, input, reference) { - if (input === undefined && reference) { + if (input === undefined && reference && reference.default) { return reference.default; } @@ -93,7 +93,7 @@ function evaluateIntervalFunction(parameters, input, reference) { } function evaluateExponentialFunction(parameters, input, reference) { - if (input === undefined && reference) { + if (input === undefined && reference && reference.default) { return reference.default; } From 1999a618eaff21a4bdec935bd3eff1cb97d5211f Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Fri, 19 Aug 2016 12:58:48 -0700 Subject: [PATCH 5/6] Move from passing reference object to just passing defaults (eliminates the need to pull in color parsing) --- index.js | 34 +++++++++++++++++----------------- test/test.js | 6 +++--- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/index.js b/index.js index 1f49f35..7074cb4 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ 'use strict'; -function createFunction(parameters, defaultType, reference) { +function createFunction(parameters, defaultType, specDefault) { var fun; if (!isFunctionDefinition(parameters)) { @@ -42,10 +42,10 @@ function createFunction(parameters, defaultType, reference) { } for (var z in featureFunctions) { - featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z], type, reference)]); + featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z], type, specDefault)]); } fun = function(zoom, feature) { - return evaluateExponentialFunction({ stops: featureFunctionStops, base: parameters.base }, zoom)(zoom, feature, reference); + return evaluateExponentialFunction({ stops: featureFunctionStops, base: parameters.base }, zoom)(zoom, feature, specDefault); }; fun.isFeatureConstant = false; fun.isZoomConstant = false; @@ -58,7 +58,7 @@ function createFunction(parameters, defaultType, reference) { fun.isZoomConstant = false; } else { fun = function(zoom, feature) { - return innerFun(parameters, feature[parameters.property], reference); + return innerFun(parameters, feature[parameters.property], specDefault); }; fun.isFeatureConstant = false; fun.isZoomConstant = true; @@ -68,9 +68,9 @@ function createFunction(parameters, defaultType, reference) { return fun; } -function evaluateCategoricalFunction(parameters, input, reference) { - if (input === undefined && reference && reference.default) { - return reference.default; +function evaluateCategoricalFunction(parameters, input, specDefault) { + if (input === undefined && specDefault) { + return specDefault; } for (var i = 0; i < parameters.stops.length; i++) { @@ -81,9 +81,9 @@ function evaluateCategoricalFunction(parameters, input, reference) { return parameters.stops[0][1]; } -function evaluateIntervalFunction(parameters, input, reference) { - if (input === undefined && reference && reference.default) { - return reference.default; +function evaluateIntervalFunction(parameters, input, specDefault) { + if (input === undefined && specDefault) { + return specDefault; } for (var i = 0; i < parameters.stops.length; i++) { @@ -92,9 +92,9 @@ function evaluateIntervalFunction(parameters, input, reference) { return parameters.stops[Math.max(i - 1, 0)][1]; } -function evaluateExponentialFunction(parameters, input, reference) { - if (input === undefined && reference && reference.default) { - return reference.default; +function evaluateExponentialFunction(parameters, input, specDefault) { + if (input === undefined && specDefault) { + return specDefault; } var base = parameters.base !== undefined ? parameters.base : 1; @@ -168,10 +168,10 @@ function isFunctionDefinition(value) { module.exports.isFunctionDefinition = isFunctionDefinition; -module.exports.interpolated = function(parameters, reference) { - return createFunction(parameters, 'exponential', reference); +module.exports.interpolated = function(parameters, specDefault) { + return createFunction(parameters, 'exponential', specDefault); }; -module.exports['piecewise-constant'] = function(parameters, reference) { - return createFunction(parameters, 'interval', reference); +module.exports['piecewise-constant'] = function(parameters, specDefault) { + return createFunction(parameters, 'interval', specDefault); }; diff --git a/test/test.js b/test/test.js index 4614702..065cef1 100644 --- a/test/test.js +++ b/test/test.js @@ -129,7 +129,7 @@ test('function types', function(t) { type: 'exponential', stops: [[0, 0], [1000, 3000]], property: 'prop' - }, { default: 10 }); + }, 10); t.equal(f(10, { prop: 0 }), 0); t.equal(f(10, { prop: 1 }), 3); @@ -221,7 +221,7 @@ test('function types', function(t) { [{ zoom: 15.1, value: 0}, 0], [{ zoom: 15.1, value: 10}, 30], [{ zoom: 15.1, value: 1000}, 3000]] - }, { default: 3}); + }, 3); t.equal(f(15, { prop: 0 }), 0); t.equal(f(15, { prop: 10 }), 0); @@ -369,7 +369,7 @@ test('property', function(t) { type: 'categorical', stops: [['map', 'neat'], ['box', 'swell']], property: 'mapbox' - }, { default: 'cool' }); + }, 'cool'); t.equal(f({}, {mapbox: 'box'}), 'swell'); t.equal(f({}, {mapbox: undefined}), 'cool'); From 404d340bbb1aafea8bd74d489b35f4a0587ccfab Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Fri, 26 Aug 2016 12:54:56 -0700 Subject: [PATCH 6/6] Fix for when spec default = 0 --- index.js | 6 +++--- test/test.js | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 7074cb4..622d419 100644 --- a/index.js +++ b/index.js @@ -69,7 +69,7 @@ function createFunction(parameters, defaultType, specDefault) { } function evaluateCategoricalFunction(parameters, input, specDefault) { - if (input === undefined && specDefault) { + if (input === undefined && typeof specDefault !== 'undefined') { return specDefault; } @@ -82,7 +82,7 @@ function evaluateCategoricalFunction(parameters, input, specDefault) { } function evaluateIntervalFunction(parameters, input, specDefault) { - if (input === undefined && specDefault) { + if (input === undefined && typeof specDefault !== 'undefined') { return specDefault; } @@ -93,7 +93,7 @@ function evaluateIntervalFunction(parameters, input, specDefault) { } function evaluateExponentialFunction(parameters, input, specDefault) { - if (input === undefined && specDefault) { + if (input === undefined && typeof specDefault !== 'undefined') { return specDefault; } diff --git a/test/test.js b/test/test.js index 065cef1..6752525 100644 --- a/test/test.js +++ b/test/test.js @@ -140,6 +140,23 @@ test('function types', function(t) { t.end(); }); + + t.test('property with 0 reference default', function(t) { + var f = MapboxGLFunction({ + type: 'exponential', + stops: [[0, 0], [1000, 3000]], + property: 'prop' + }, 0); + + t.equal(f(10, { prop: 0 }), 0); + t.equal(f(10, { prop: 1 }), 3); + t.equal(f(10, { prop: 100 }), 300); + t.equal(f(10, { prop: 1000 }), 3000); + t.equal(f(10, { prop: 3000 }), 3000); + t.equal(f(10, { prop: undefined }), 0); + + t.end(); + }); }); t.test('zoom + data stops', function(t) {