Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-component-tree",
"version": "0.1.2",
"version": "0.2.0",
"description": "Serialize and reproduce the state of an entire tree of React components",
"main": "build/bundle.js",
"repository": {
Expand Down
3 changes: 1 addition & 2 deletions src/load-child-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ var React = require('react'),

class LoadChildComponent extends React.Component {
loadChild(childName, a, b, c, d, e, f) {
return loadChild.loadChild(
this.children, childName, a, b, c, d, e, f);
return loadChild.loadChild(this, childName, a, b, c, d, e, f);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/load-child-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ var loadChild = require('./load-child.js');

module.exports = {
loadChild: function(childName, a, b, c, d, e, f) {
return loadChild.loadChild(
this.children, childName, a, b, c, d, e, f);
return loadChild.loadChild(this, childName, a, b, c, d, e, f);
}
};
21 changes: 11 additions & 10 deletions src/load-child.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
var _ = require('lodash'),
React = require('react');

exports.loadChild = function(childTemplates, childName, a, b, c, d, e, f) {
exports.loadChild = function(component, childName, a, b, c, d, e, f) {
/**
* Create a React element for a specific child type.
*
* The component class and props of the child are returned together by a
* corresponding function from the childTemplates object. The functions are
* corresponding function from the .children object. The functions are
* mapped with the name of the child as the key.
*
* https://facebook.github.io/react/docs/top-level-api.html#react.createelement
*
* @param {Object} childTemplates Map of functions that generate child
* component params (component+props)
* @param {Object} component Parent component
* @param {Object} component.children Map of functions that generate child
* component params (component+props)
* @param {String} name Key that corresponds to the child component we want
* to get the params for
* @param {...*} [arguments] Optional extra arguments get passed to the
* component template function
* component .children function
*
* @returns {ReactElement} Created React element
*
Expand All @@ -39,7 +40,7 @@ exports.loadChild = function(childTemplates, childName, a, b, c, d, e, f) {
* });
*/
var params = getChildParams.call(
this, childTemplates, childName, a, b, c, d, e, f);
this, component, childName, a, b, c, d, e, f);

// One child with bad params shouldn't block the entire app
try {
Expand All @@ -50,11 +51,11 @@ exports.loadChild = function(childTemplates, childName, a, b, c, d, e, f) {
}
};

var getChildParams = function(childTemplates, childName, a, b, c, d, e, f) {
var params = childTemplates[childName].call(this, a, b, c, d, e, f);
var getChildParams = function(component, childName, a, b, c, d, e, f) {
var params = component.children[childName].call(component, a, b, c, d, e, f);

// Default the child ref to its key name if the template doesn't return a
// value
// Default the child ref to its key name if the child template doesn't return
// a value
if (!params.ref) {
params.ref = childName;
}
Expand Down
5 changes: 2 additions & 3 deletions tests/load-child-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ var _ = require('lodash'),

describe('Load child component', function() {
var fakeReactElement = {},
children = {},
myComponent;

class MyComponent extends LoadChildComponent {
constructor(props) {
super(props);
this.children = children;
this.children = {};
}
render() {
return React.DOM.span();
Expand All @@ -33,7 +32,7 @@ describe('Load child component', function() {
myComponent.loadChild('myChild', 5, 10, true);

var args = loadChild.loadChild.lastCall.args;
expect(args[0]).to.equal(children);
expect(args[0]).to.equal(myComponent);
expect(args[1]).to.equal('myChild');
expect(args[2]).to.equal(5);
expect(args[3]).to.equal(10);
Expand Down
5 changes: 2 additions & 3 deletions tests/load-child-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ var _ = require('lodash'),

describe('Load child mixin', function() {
var fakeReactElement = {},
children = {},
myComponent;

var MyComponent = React.createClass({
mixins: [LoadChildMixin],
children: children,
children: {},

render: function() {
return React.DOM.span();
Expand All @@ -32,7 +31,7 @@ describe('Load child mixin', function() {
myComponent.loadChild('myChild', 5, 10, true);

var args = loadChild.loadChild.lastCall.args;
expect(args[0]).to.equal(children);
expect(args[0]).to.equal(myComponent);
expect(args[1]).to.equal('myChild');
expect(args[2]).to.equal(5);
expect(args[3]).to.equal(10);
Expand Down
57 changes: 33 additions & 24 deletions tests/load-child.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ var React = require('react'),
describe('Load child', function() {
var FirstComponent = {},
SecondComponent = {},
childTemplates;
component;

beforeEach(function() {
childTemplates = {
defaultRef: sinon.spy(function() {
return {
component: FirstComponent,
alwaysTrue: true
};
}),
customRef: sinon.spy(function() {
return {
component: SecondComponent,
ref: 'fooChild'
};
})
component = {
children: {
defaultRef: sinon.spy(function() {
return {
component: FirstComponent,
alwaysTrue: true
};
}),
customRef: sinon.spy(function() {
return {
component: SecondComponent,
ref: 'fooChild'
};
})
}
};

sinon.stub(React, 'createElement');
Expand All @@ -29,40 +31,47 @@ describe('Load child', function() {
React.createElement.restore();
});

it('should call corresponding template function', function() {
loadChild(childTemplates, 'defaultRef');
it('should call .children function', function() {
loadChild(component, 'defaultRef');

expect(childTemplates.defaultRef).to.have.been.called;
expect(component.children.defaultRef).to.have.been.called;
});

it('should call corresponding template function with extra args', function() {
loadChild(childTemplates, 'customRef', 'first', 'second');
it('should call .children function with component context', function() {
loadChild(component, 'defaultRef');

expect(childTemplates.customRef).to.have.been.calledWith('first', 'second');
expect(component.children.defaultRef).to.have.been.calledOn(component);
});

it('should call .children function with extra args', function() {
loadChild(component, 'customRef', 'first', 'second');

expect(component.children.customRef)
.to.have.been.calledWith('first', 'second');
});

it('should create element using returned component class', function() {
loadChild(childTemplates, 'defaultRef');
loadChild(component, 'defaultRef');

expect(React.createElement.lastCall.args[0]).to.equal(FirstComponent);
});

it('should create element using returned props', function() {
loadChild(childTemplates, 'defaultRef');
loadChild(component, 'defaultRef');

var props = React.createElement.lastCall.args[1];
expect(props.alwaysTrue).to.equal(true);
});

it('should use child name as ref if omitted', function() {
loadChild(childTemplates, 'defaultRef');
loadChild(component, 'defaultRef');

var props = React.createElement.lastCall.args[1];
expect(props.ref).to.equal('defaultRef');
});

it('should use returned ref when present', function() {
loadChild(childTemplates, 'customRef');
loadChild(component, 'customRef');

var props = React.createElement.lastCall.args[1];
expect(props.ref).to.equal('fooChild');
Expand Down
14 changes: 8 additions & 6 deletions tests/load-missing-child.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ var React = require('react'),
loadChild = require('../src/load-child.js').loadChild;

describe('Load missing child', function() {
var childTemplates;
var component;

beforeEach(function() {
childTemplates = {
missingChild: function() {
return {};
component = {
children: {
missingChild: function() {
return {};
}
}
};

Expand All @@ -26,12 +28,12 @@ describe('Load missing child', function() {

it('should handle exception', function() {
expect(function whereAreYouSon() {
loadChild(childTemplates, 'missingChild');
loadChild(component, 'missingChild');
}).to.not.throw();
});

it('should log error', function() {
loadChild(childTemplates, 'missingChild');
loadChild(component, 'missingChild');

expect(console.error.lastCall.args[0]).to.be.an.instanceof(Error);
});
Expand Down
3 changes: 2 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ module.exports = {
}]
},
output: {
libraryTarget: 'commonjs2',
libraryTarget: 'umd',
library: 'ComponentTree',
path: path.join(__dirname, 'build'),
filename: 'bundle.js'
}
Expand Down