Skip to content

Commit

Permalink
Materialize configuration options parameters that are functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaime del Palacio committed Nov 16, 2017
1 parent 8084faa commit fa1df30
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
10 changes: 8 additions & 2 deletions src/documentation/config/config.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#### **config** : {<%= type %>} (Core)

The Contour configuration object is a set of configuration options.
The Contour configuration object is a set of configuration options.

Each set of options can be added:

Expand All @@ -21,7 +21,7 @@ Each set of options can be added:
})
.cartesian()
.column(data, { columnWidth: 30 } )
.column(otherData, { columnWidth: 20} )
.column(otherData, { columnWidth: () => 20 } )
.render()

Each configuration option can be:
Expand All @@ -38,6 +38,12 @@ Each configuration option can be:

columnWidth: function() { return this.rangeBand/3 * 2; }

__Note__ In general, function parameters will be invoked just before the render cycle happens except when:
* the function expects 1 or more parameters (ie. `function (d) { return d.x; }`) or
* the parameter path matches or is in the `options.skip` array. The `options.skip` array can have string with a full path to skip or a RegExp to match a path. For example `['line.marker.enable', /formatter$/i]

This allows functions to be used for things like formatters that need to be called for each point in the data set.

<% if(notes) { %><%= notes %><% } %>

<% if(defaultValue !== "[object Object]") { %>*default: <%= defaultValue %>* <% }%>
Expand Down
24 changes: 22 additions & 2 deletions src/scripts/core/contour-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,20 @@
return name || '';
},

materialize: function (object, ctx) {
materialize: function (object, ctx, options, curPath) {
var isDom = function (obj) { return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.style === 'object' && typeof obj.ownerDocument === 'object'; };
var skipList = (options || {}).skip || [];

var shouldSkip = function (path) {
return skipList.some(function (e) {
if (typeof e === 'object' && e instanceof RegExp) {
return e.test(path);
}

return e.toString() === path;
});
};

if ( object == null ) {
return object;
} else if (Array.isArray(object)) {
Expand All @@ -34,7 +46,15 @@
return generalHelpers.getValue(object, null, ctx);
} else if (typeof object === 'object') {
return Object.keys(object).reduce(function (prev, key) {
prev[key] = generalHelpers.materialize(object[key], ctx);
var curKeyPath = curPath ? curPath + '.' + key : key;
var expectsParam = (typeof object[key] === 'function' && !!object[key].length);
var shouldMaterialize = !shouldSkip(curKeyPath) && !expectsParam;

if (shouldMaterialize) {
prev[key] = generalHelpers.materialize(object[key], ctx, options, curKeyPath);
} else {
prev[key] = object[key];
}
return prev;
}, {});
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/core/contour.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@
_.each(this._extraOptions, mergeExtraOptions);
_.each(this._visualizations, mergeDefaults);

var opt = _.extend({}, this.originalOptions);
var opt = _.nw.materialize(this.originalOptions, this, { skipMatch: /formatter/ });

// compose the final list of options right before start rendering
this.options = _.merge(opt, _.merge({}, allDefaults, opt));
Expand Down
33 changes: 29 additions & 4 deletions tests/specs/contour-utils-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,18 +456,30 @@ describe('utils', function () {
var res;
var passCtx;
var expectedContext = {};
var input;
beforeEach(function () {
res = mat({
input = {
a: 1,
b: 'hello',
c: function () { return 2; },
x: function () { return 'keep'; },
d: {
a: 11,
b: 'hello world',
c: function () { return true; },
d: function () { passCtx = this; return 'do'; }
d: function () { passCtx = this; return 'do'; },
x: function () { return 'keep'; },
zzz: function () { return 'keep'; },
other: function (d) {
return d.x;
}
}
}, expectedContext);
};


res = mat(input, expectedContext, {
skip: ['x', 'd.x', /zzz/],
});
});

it('should materialize all props that are functions', function () {
Expand All @@ -486,6 +498,19 @@ describe('utils', function () {
it('should pass the correct context to the functions', function () {
expect(passCtx).toBe(expectedContext);
});
})

it('should skip the skip list', function () {
expect(res.x).toEqual(input.x);
expect(res.d.x).toEqual(input.d.x);
});

it('should skip the skipMatch', function () {
expect(res.d.zzz).toEqual(input.d.zzz);
});

it('should skip functions that expect parameters', function () {
expect(res.d.other).toEqual(input.d.other);
});
});
});
});

0 comments on commit fa1df30

Please sign in to comment.