Skip to content

Commit 8d35b71

Browse files
committed
Lock down and document the unimplemented case in expandObjectPaths
1 parent b612ac3 commit 8d35b71

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

src/lib/index.js

+36-3
Original file line numberDiff line numberDiff line change
@@ -589,9 +589,25 @@ lib.objectFromPath = function(path, value) {
589589
/**
590590
* Iterate through an object in-place, converting dotted properties to objects.
591591
*
592-
* @example
593-
* lib.expandObjectPaths({'nested.test.path': 'value'});
594-
* // returns { nested: { test: {path: 'value'}}}
592+
* Examples:
593+
*
594+
* lib.expandObjectPaths({'nested.test.path': 'value'});
595+
* => { nested: { test: {path: 'value'}}}
596+
*
597+
* It also handles array notation, e.g.:
598+
*
599+
* lib.expandObjectPaths({'foo[1].bar': 'value'});
600+
* => { foo: [null, {bar: value}] }
601+
*
602+
* It handles merges the results when two properties are specified in parallel:
603+
*
604+
* lib.expandObjectPaths({'foo[1].bar': 10, 'foo[0].bar': 20});
605+
* => { foo: [{bar: 10}, {bar: 20}] }
606+
*
607+
* It does NOT, however, merge mulitple mutliply-nested arrays::
608+
*
609+
* lib.expandObjectPaths({'marker[1].range[1]': 5, 'marker[1].range[0]': 4})
610+
* => { marker: [null, {range: 4}] }
595611
*/
596612

597613
// Store this to avoid recompiling regex on *every* prop since this may happen many
@@ -624,10 +640,27 @@ lib.expandObjectPaths = function(data) {
624640
data[prop] = data[prop] || [];
625641

626642
if(match[3] === '.') {
643+
// This is the case where theere are subsequent properties into which
644+
// we must recurse, e.g. transforms[0].value
627645
trailingPath = match[4];
628646
dest = data[prop][idx] = data[prop][idx] || {};
647+
648+
// NB: Extend deep no arrays prevents this from working on multiple
649+
// nested properties in the same object, e.g.
650+
//
651+
// {
652+
// foo[0].bar[1].range
653+
// foo[0].bar[0].range
654+
// }
655+
//
656+
// In this case, the extendDeepNoArrays will overwrite one array with
657+
// the other, so that both properties *will not* be present in the
658+
// result. Fixing this would require a more intelligent tracking
659+
// of changes and merging than extendDeepNoArrays currently accomplishes.
629660
lib.extendDeepNoArrays(dest, lib.objectFromPath(trailingPath, lib.expandObjectPaths(datum)));
630661
} else {
662+
// This is the case where this property is the end of the line,
663+
// e.g. xaxis.range[0]
631664
data[prop][idx] = lib.expandObjectPaths(datum);
632665
}
633666
} else {

test/jasmine/tests/lib_test.js

+15
Original file line numberDiff line numberDiff line change
@@ -579,12 +579,27 @@ describe('Test lib.js:', function() {
579579
expect(computed).toEqual(expected);
580580
});
581581

582+
it('combines changes with single array nesting', function() {
583+
var input = {'marker[1].foo': 5, 'marker[0].foo': 4};
584+
var expected = {marker: [{foo: 4}, {foo: 5}]};
585+
var computed = Lib.expandObjectPaths(input);
586+
expect(computed).toEqual(expected);
587+
});
588+
589+
// TODO: This test is unimplemented since it's a currently-unused corner case.
590+
// Getting the test to pass requires some extension (pun?) to extendDeepNoArrays
591+
// that's intelligent enough to only selectively merge *some* arrays, in particular
592+
// not data arrays but yes on arrays that were previously expanded. This is a bit
593+
// tricky to get to work just right and currently doesn't have any known use since
594+
// container arrays are not multiply nested.
595+
/*
582596
it('combines changes', function() {
583597
var input = {'marker[1].range[1]': 5, 'marker[1].range[0]': 4};
584598
var expected = {marker: [undefined, {range: [4, 5]}]};
585599
var computed = Lib.expandObjectPaths(input);
586600
expect(computed).toEqual(expected);
587601
});
602+
*/
588603
});
589604

590605
describe('coerce', function() {

0 commit comments

Comments
 (0)