Skip to content

Commit 744869f

Browse files
author
Philipp Alferov
committed
Implement ability to specify custom properties
1 parent be737ad commit 744869f

File tree

4 files changed

+78
-14
lines changed

4 files changed

+78
-14
lines changed

index.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22
var util = require('util');
33

4-
function createTree(list, rootNodes) {
4+
function createTree(list, rootNodes, customID) {
55
var tree = [];
66

77
for (var prop in rootNodes) {
@@ -10,9 +10,10 @@ function createTree(list, rootNodes) {
1010
}
1111

1212
var node = rootNodes[prop];
13+
var listItem = list[node[customID]];
1314

14-
if (list[node.id]) {
15-
node.children = createTree(list, list[node.id]);
15+
if (listItem) {
16+
node.children = createTree(list, listItem, customID);
1617
}
1718

1819
tree.push(node);
@@ -21,11 +22,12 @@ function createTree(list, rootNodes) {
2122
return tree;
2223
}
2324

24-
function orderByParents(list) {
25+
function orderByParents(list, config) {
2526
var parents = {};
27+
var parentProperty = config.parentProperty;
2628

2729
list.forEach(function(item) {
28-
var parentID = item.parent_id || 0;
30+
var parentID = item[parentProperty] || 0;
2931
parents[parentID] = parents[parentID] || [];
3032
parents[parentID].push(item);
3133
});
@@ -34,14 +36,19 @@ function orderByParents(list) {
3436
}
3537

3638
module.exports = function(options) {
37-
var config = util._extend({ parentProperty: 'parent_id', data: [] }, options);
39+
var config = util._extend({
40+
parentProperty: 'parent_id',
41+
data: [],
42+
customID: 'id'
43+
}, options);
44+
3845
var data = config.data;
3946

4047
if (!util.isArray(data)) {
4148
throw new Error('Expected an object but got an invalid argument');
4249
}
4350

4451
var cloned = data.slice();
45-
var ordered = orderByParents(cloned);
46-
return createTree(ordered, ordered[0]);
52+
var ordered = orderByParents(cloned, config);
53+
return createTree(ordered, ordered[0], config.customID);
4754
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports = [{
2+
_id: 1,
3+
parent: null,
4+
children: [{
5+
_id: 2,
6+
parent: 1,
7+
children: [{
8+
_id: 3,
9+
parent: 2
10+
}]
11+
}]
12+
}, {
13+
_id: 4,
14+
parent: null
15+
}];
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = [{
2+
_id: 1,
3+
parent: null
4+
}, {
5+
_id: 2,
6+
parent: 1
7+
}, {
8+
_id: 3,
9+
parent: 2
10+
}, {
11+
_id: 4,
12+
parent: null
13+
}];

test/test.js

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ var chai = require('chai');
33
var expect = chai.expect;
44
var toTree = require('../index.js');
55
var expected = require('./fixtures/expected.fixture.js');
6+
var customExpected = require('./fixtures/expected-custom.fixture.js');
7+
var customInitial = require('./fixtures/initial-custom.fixture.js');
68
var initial = require('./fixtures/initial.fixture.js');
79
var current;
810

9-
describe('parent pointer array to tree', function() {
10-
describe('expected behavior', function() {
11+
describe('array-to-tree', function() {
12+
describe('with valid arguments', function() {
1113

1214
before(function() {
1315
current = toTree({ data: initial });
@@ -39,18 +41,45 @@ describe('parent pointer array to tree', function() {
3941
it('should return an expected value', function() {
4042
expect(current).to.be.deep.equal(expected);
4143
});
42-
4344
});
4445

45-
describe('with incorrect arguments', function() {
46+
describe('with invalid arguments', function() {
4647
it('should return an empty array if the empty array passed', function() {
4748
expect(toTree({ data: [] })).to.be.deep.equal([]);
4849
});
4950

5051
it('should throw an error if wrong arguments passed', function() {
51-
expect(toTree.bind(null, { data: 'string' })).to.throw(/invalid argument/);
52-
expect(toTree.bind(null, { data: {} })).to.throw(/invalid argument/);
52+
expect(toTree.bind(null, { data: 'string' }))
53+
.to.throw(/invalid argument/);
54+
55+
expect(toTree.bind(null, { data: {} }))
56+
.to.throw(/invalid argument/);
57+
});
58+
59+
it('should return the same array if there is no pointer to parent', function() {
60+
61+
var modified = initial.map(function(item) {
62+
delete item.parent_id;
63+
return item;
64+
});
65+
66+
expect(toTree({ data: modified }))
67+
.to.be.deep.equal(modified);
5368
});
5469

5570
})
71+
72+
describe('with different options', function() {
73+
it('should work with custom link to parent', function() {
74+
75+
var current = toTree({
76+
data: customInitial,
77+
parentProperty: 'parent',
78+
customID: '_id'
79+
});
80+
81+
expect(current)
82+
.to.be.deep.equal(customExpected);
83+
});
84+
});
5685
});

0 commit comments

Comments
 (0)