Comparing version 0.10.0-beta.5 to 0.10.0-beta.6
@@ -31,3 +31,2 @@ 'use strict'; | ||
app = new fixture.App(); | ||
fixture.Message = app.bindTo(fixture.Message); | ||
app.messageStore.setContextName('local-context'); | ||
@@ -105,5 +104,4 @@ }); | ||
var app = new Application(); | ||
var WrappedComponent = app.bindTo(Component); | ||
return app.renderToString(React.createElement(WrappedComponent, null)).then(loadDOM); | ||
return app.renderToString(React.createElement(Component, null)).then(loadDOM); | ||
}); | ||
@@ -110,0 +108,0 @@ |
@@ -50,3 +50,3 @@ 'use strict'; | ||
message: function message() { | ||
return this.messageStore.getMessage('Child'); | ||
return this.app.messageStore.getMessage('Child'); | ||
} | ||
@@ -77,3 +77,3 @@ } | ||
message: function message() { | ||
return this.messageStore.getMessage('Parent'); | ||
return this.app.messageStore.getMessage('Parent'); | ||
} | ||
@@ -80,0 +80,0 @@ } |
@@ -11,6 +11,4 @@ 'use strict'; | ||
var sinon = require('sinon'); | ||
var React = require('react'); | ||
var expect = require('chai').expect; | ||
var buildMarty = require('../../../test/lib/buildMarty'); | ||
var TestUtils = require('react/addons').addons.TestUtils; | ||
@@ -182,50 +180,2 @@ describe('Application', function () { | ||
describe('#bindTo(InnerComponent)', function () { | ||
beforeEach(function () { | ||
application = new Marty.Application(); | ||
}); | ||
describe('when you dont pass in a component', function () { | ||
it('should throw an error', function () { | ||
expect(bindToNull).to['throw'](Error); | ||
function bindToNull() { | ||
application.bindTo(); | ||
} | ||
}); | ||
}); | ||
describe('when you pass in a react component', function () { | ||
var actualApplication, actualProps, expectedProps; | ||
beforeEach(function () { | ||
application = new Marty.Application(); | ||
var InnerComponent = React.createClass({ | ||
displayName: 'InnerComponent', | ||
contextTypes: Marty.contextTypes, | ||
render: function render() { | ||
actualProps = this.props; | ||
actualApplication = this.context.app; | ||
return React.createElement('div', null); | ||
} | ||
}); | ||
expectedProps = { foo: 'bar' }; | ||
var ContainerComponent = application.bindTo(InnerComponent); | ||
TestUtils.renderIntoDocument(React.createElement(ContainerComponent, expectedProps)); | ||
}); | ||
it('should pass the props through to the inner component', function () { | ||
expect(actualProps).to.eql(expectedProps); | ||
}); | ||
it('should pass the application down through the context', function () { | ||
expect(actualApplication).to.equal(application); | ||
}); | ||
}); | ||
}); | ||
describe('#fetch(callback)', function () { | ||
@@ -232,0 +182,0 @@ describe('when stores make requests to fetch data', function () { |
'use strict'; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
@@ -11,2 +9,3 @@ | ||
var log = require('../core/logger'); | ||
var invariant = require('invariant'); | ||
var timeout = require('../core/utils/timeout'); | ||
@@ -22,4 +21,2 @@ var deferred = require('../core/utils/deferred'); | ||
module.exports = function (React) { | ||
var ApplicationContainer = require('./applicationContainer')(React); | ||
var Application = (function () { | ||
@@ -55,35 +52,2 @@ function Application(options) { | ||
_createClass(Application, [{ | ||
key: 'render', | ||
value: function render(element, container, callback) { | ||
React.render(React.createElement( | ||
ApplicationContainer, | ||
{ app: this }, | ||
element | ||
), container, callback); | ||
} | ||
}, { | ||
key: 'bindTo', | ||
value: function bindTo(InnerComponent) { | ||
var app = this; | ||
if (!InnerComponent) { | ||
throw new Error('Must specify an inner component'); | ||
} | ||
return React.createClass({ | ||
childContextTypes: { | ||
app: React.PropTypes.object | ||
}, | ||
getChildContext: function getChildContext() { | ||
return { app: app }; | ||
}, | ||
getInnerComponent: function getInnerComponent() { | ||
return this.refs.innerComponent; | ||
}, | ||
render: function render() { | ||
return React.createElement(InnerComponent, _extends({ ref: 'innerComponent', app: app }, this.props)); | ||
} | ||
}); | ||
} | ||
}, { | ||
key: 'getAll', | ||
@@ -302,3 +266,7 @@ value: function getAll(type) { | ||
value: function renderToString(element, options) { | ||
return _renderToString(this, React.renderToString, element, options); | ||
var _this3 = this; | ||
return _renderToString(this, React.renderToString, function () { | ||
return elementWithApp(element, _this3); | ||
}, options); | ||
} | ||
@@ -308,3 +276,7 @@ }, { | ||
value: function renderToStaticMarkup(element, options) { | ||
return _renderToString(this, React.renderToStaticMarkup, element, options); | ||
var _this4 = this; | ||
return _renderToString(this, React.renderToStaticMarkup, function () { | ||
return elementWithApp(element, _this4); | ||
}, options); | ||
} | ||
@@ -341,3 +313,11 @@ }], [{ | ||
function elementWithApp(element, app) { | ||
invariant(element && (typeof element.type === 'function' || typeof element.type === 'string'), 'Must pass in a React component'); | ||
return React.cloneElement(element, { | ||
app: app | ||
}); | ||
} | ||
return Application; | ||
}; |
'use strict'; | ||
var invariant = require('invariant'); | ||
var findApp = require('../core/findApp'); | ||
@@ -8,2 +8,3 @@ var _require = require('../mindash'); | ||
var isArray = _require.isArray; | ||
var extend = _require.extend; | ||
@@ -17,11 +18,4 @@ module.exports = function (React) { | ||
}, | ||
propTypes: { | ||
app: React.PropTypes.object | ||
}, | ||
getChildContext: function getChildContext() { | ||
invariant(this.props.app, 'Must specify the application'); | ||
return { | ||
app: this.props.app | ||
}; | ||
return { app: findApp(this) }; | ||
}, | ||
@@ -35,12 +29,16 @@ render: function render() { | ||
if (isArray(children)) { | ||
return React.Children.map(children, cloneElementWithApp); | ||
return React.createElement( | ||
'span', | ||
null, | ||
React.Children.map(children, cloneWithApp) | ||
); | ||
} else { | ||
return cloneElementWithApp(children); | ||
return cloneWithApp(children); | ||
} | ||
} | ||
function cloneElementWithApp(element) { | ||
return React.addons.cloneWithProps(element, { | ||
function cloneWithApp(element) { | ||
return React.createElement(element.type, extend({ | ||
app: app | ||
}); | ||
}, element.props)); | ||
} | ||
@@ -47,0 +45,0 @@ } |
@@ -5,7 +5,6 @@ 'use strict'; | ||
var Application = require('./application')(React); | ||
var ApplicationContainer = require('./applicationContainer')(React); | ||
marty.ApplicationContainer = require('./applicationContainer')(React); | ||
marty.createApplication = require('./createApplication')(Application); | ||
marty.Application = Application; | ||
marty.ApplicationContainer = ApplicationContainer; | ||
marty.contextTypes = { | ||
@@ -12,0 +11,0 @@ app: React.PropTypes.instanceOf(Application) |
@@ -5,4 +5,5 @@ 'use strict'; | ||
var MAX_NUMBER_OF_ITERATIONS = 10; | ||
var invariant = require('invariant'); | ||
function renderToString(app, render, element, options) { | ||
function renderToString(app, render, createElement, options) { | ||
options = _.defaults(options || {}, { | ||
@@ -12,2 +13,6 @@ maxNumberOfIterations: MAX_NUMBER_OF_ITERATIONS | ||
invariant(app, 'Must specify the application'); | ||
invariant(render, 'Must specify the render function'); | ||
invariant(_.isFunction(createElement), 'Must specify the element factory'); | ||
var totalIterations = 0; | ||
@@ -17,2 +22,4 @@ var fetchOptions = { timeout: options.timeout }; | ||
return new Promise(function (resolve, reject) { | ||
var element = createElement(); | ||
resolveFetches().then(dehydrateAndRenderHtml); | ||
@@ -19,0 +26,0 @@ |
'use strict'; | ||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
@@ -16,9 +18,6 @@ | ||
var _fetch = require('../../store/fetch'); | ||
var buildMarty = require('../../../test/lib/buildMarty'); | ||
var _require = require('../../test-utils'); | ||
var renderIntoDocument = require('react/addons').addons.TestUtils.renderIntoDocument; | ||
var renderIntoDocument = _require.renderIntoDocument; | ||
var buildMarty = require('../../../test/lib/buildMarty'); | ||
describe('Container', function () { | ||
@@ -87,81 +86,2 @@ var Marty, InnerComponent, ContainerComponent, expectedProps, element, context, app; | ||
describe('#inject', function () { | ||
var containerFunctionContext; | ||
beforeEach(function () { | ||
app.register('dep1', Marty.Store); | ||
app.register('dep2', Marty.Store); | ||
}); | ||
describe('when I inject in a dependency', function () { | ||
beforeEach(function () { | ||
var Component = Marty.createContainer(InnerComponent, { | ||
inject: ['dep1', 'dep2'], | ||
fetch: { | ||
foo: function foo() { | ||
containerFunctionContext = this; | ||
return {}; | ||
} | ||
} | ||
}); | ||
renderIntoDocument(React.createElement(Component, null), app); | ||
}); | ||
it('should make it available in the container component', function () { | ||
expect(deps(containerFunctionContext)).to.eql(deps(app)); | ||
}); | ||
it('should make it available in the inner component', function () { | ||
expect(deps(innerFunctionContext)).to.eql(deps(app)); | ||
}); | ||
}); | ||
describe('when I inject a dependency to a component that have contextTypes', function () { | ||
beforeEach(function () { | ||
var Component = (function (_React$Component) { | ||
function Component() { | ||
_classCallCheck(this, Component); | ||
if (_React$Component != null) { | ||
_React$Component.apply(this, arguments); | ||
} | ||
} | ||
_inherits(Component, _React$Component); | ||
_createClass(Component, [{ | ||
key: 'render', | ||
value: function render() { | ||
innerFunctionContext = this; | ||
return false; | ||
} | ||
}]); | ||
return Component; | ||
})(React.Component); | ||
var ComponentContainer = Marty.createContainer(Component, { | ||
inject: ['dep1', 'dep2'], | ||
fetch: { | ||
foo: function foo() { | ||
containerFunctionContext = this; | ||
return {}; | ||
} | ||
} | ||
}); | ||
renderIntoDocument(React.createElement(ComponentContainer, null), app); | ||
}); | ||
it('should make it available in the container component', function () { | ||
expect(deps(containerFunctionContext)).to.eql(deps(app)); | ||
}); | ||
it('should make it available in the inner component', function () { | ||
expect(deps(innerFunctionContext)).to.eql(deps(app)); | ||
}); | ||
}); | ||
}); | ||
describe('component lifestyle', function () { | ||
@@ -210,3 +130,3 @@ var ParentComponent; | ||
element = renderIntoDocument(React.createElement(ParentComponent, null)); | ||
element = renderIntoDocument(React.createElement(ParentComponent, { app: app })); | ||
@@ -247,16 +167,15 @@ element.setState({ | ||
var actualApplication = undefined; | ||
var exectedApplication = undefined; | ||
beforeEach(function () { | ||
exectedApplication = new Marty.Application(); | ||
app = new Marty.Application(); | ||
var TestComponent = (function (_React$Component2) { | ||
function TestComponent(props) { | ||
var TestComponent = (function (_React$Component) { | ||
function TestComponent(props, context) { | ||
_classCallCheck(this, TestComponent); | ||
_get(Object.getPrototypeOf(TestComponent.prototype), 'constructor', this).call(this, props); | ||
_get(Object.getPrototypeOf(TestComponent.prototype), 'constructor', this).call(this, props, context); | ||
actualApplication = props.app; | ||
} | ||
_inherits(TestComponent, _React$Component2); | ||
_inherits(TestComponent, _React$Component); | ||
@@ -275,7 +194,7 @@ _createClass(TestComponent, [{ | ||
renderIntoDocument(React.createElement(WrappedComponent, null), app); | ||
renderIntoDocument(React.createElement(WrappedComponent, { app: app })); | ||
}); | ||
it('should pass the app down through the props', function () { | ||
expect(actualApplication).to.equal(exectedApplication); | ||
expect(actualApplication).to.equal(app); | ||
}); | ||
@@ -298,16 +217,16 @@ }); | ||
it('should set the display name on classical React components', function () { | ||
expect(render(ContainerComponent).refs.subject.constructor.displayName).to.eql('InnerComponentContainer'); | ||
expect(render(ContainerComponent).constructor.displayName).to.eql('InnerComponentContainer'); | ||
}); | ||
it('should set the display name on ES6 React components', function () { | ||
var ES6InnerComponent = (function (_React$Component3) { | ||
var ES6InnerComponent = (function (_React$Component2) { | ||
function ES6InnerComponent() { | ||
_classCallCheck(this, ES6InnerComponent); | ||
if (_React$Component3 != null) { | ||
_React$Component3.apply(this, arguments); | ||
if (_React$Component2 != null) { | ||
_React$Component2.apply(this, arguments); | ||
} | ||
} | ||
_inherits(ES6InnerComponent, _React$Component3); | ||
_inherits(ES6InnerComponent, _React$Component2); | ||
@@ -324,4 +243,5 @@ _createClass(ES6InnerComponent, [{ | ||
var ContainerES6Component = Marty.createContainer(ES6InnerComponent); | ||
expect(render(ContainerES6Component).refs.subject.constructor.displayName).to.eql('ES6InnerComponentContainer'); | ||
var ContainerES6Component = wrap(ES6InnerComponent); | ||
expect(render(ContainerES6Component).constructor.displayName).to.eql('ES6InnerComponentContainer'); | ||
}); | ||
@@ -359,3 +279,3 @@ }); | ||
}); | ||
element = renderIntoDocument(React.createElement(ContainerComponent, null)); | ||
element = renderIntoDocument(React.createElement(ContainerComponent, { app: app })); | ||
}); | ||
@@ -444,3 +364,3 @@ | ||
var element = renderIntoDocument(React.createElement(ParentComponent, null)); | ||
var element = renderIntoDocument(React.createElement(ParentComponent, { app: app })); | ||
@@ -548,3 +468,3 @@ element.replaceState({ | ||
bar: function bar() { | ||
return this.barStore.getBar(expectedId); | ||
return this.app.barStore.getBar(expectedId); | ||
} | ||
@@ -554,3 +474,3 @@ } | ||
element = renderIntoDocument(React.createElement(ContainerComponent, null), app); | ||
element = renderIntoDocument(React.createElement(ContainerComponent, { app: app })); | ||
@@ -577,3 +497,3 @@ finishQuery(); | ||
element = renderIntoDocument(React.createElement(ContainerComponent, null)); | ||
element = renderIntoDocument(React.createElement(ContainerComponent, { app: app })); | ||
}); | ||
@@ -587,6 +507,6 @@ | ||
describe('when the component is bound to an application', function () { | ||
var application, actualApplication; | ||
var actualApplication; | ||
beforeEach(function () { | ||
application = new Marty.Application(); | ||
app = new Marty.Application(); | ||
ContainerComponent = wrap(InnerComponent, { | ||
@@ -602,7 +522,7 @@ fetch: { | ||
element = renderIntoDocument(React.createElement(ContainerComponent, null), application); | ||
element = renderIntoDocument(React.createElement(ContainerComponent, { app: app })); | ||
}); | ||
it('should make the application accessible on `this.app`', function () { | ||
expect(actualApplication).to.equal(application); | ||
expect(actualApplication).to.equal(app); | ||
}); | ||
@@ -732,3 +652,3 @@ }); | ||
beforeEach(function () { | ||
var app = new Marty.Application(); | ||
app = new Marty.Application(); | ||
@@ -752,3 +672,3 @@ app.register('fooStore', Marty.createStore({ | ||
foo: function foo() { | ||
return this.fooStore.getFoo(123); | ||
return this.app.fooStore.getFoo(123); | ||
} | ||
@@ -777,3 +697,3 @@ } | ||
foo: function foo() { | ||
return this.store.getFoo(123); | ||
return this.app.store.getFoo(123); | ||
} | ||
@@ -822,6 +742,2 @@ } | ||
function deps(obj) { | ||
return _.pick(obj, 'dep1', 'dep2'); | ||
} | ||
function withoutApp(props) { | ||
@@ -836,14 +752,4 @@ return _.omit(props, 'app'); | ||
function render(Component, props) { | ||
var ContextContainer = React.createClass({ | ||
displayName: 'ContextContainer', | ||
render: function render() { | ||
var innerProps = _.extend({}, this.props, props, { ref: 'subject' }); | ||
return React.createElement(Component, innerProps); | ||
} | ||
}); | ||
return renderIntoDocument(React.createElement(ContextContainer, null), app); | ||
return renderIntoDocument(React.createElement(Component, _extends({ app: app }, props))); | ||
} | ||
}); |
@@ -6,6 +6,7 @@ 'use strict'; | ||
var _ = require('../mindash'); | ||
var inject = require('../core/inject'); | ||
var findApp = require('../core/findApp'); | ||
var uuid = require('../core/utils/uuid'); | ||
var getFetchResult = require('./getFetchResult'); | ||
var appProperty = require('../core/appProperty'); | ||
var StoreObserver = require('../core/storeObserver'); | ||
var getFetchResult = require('./getFetchResult'); | ||
var getClassName = require('../core/utils/getClassName'); | ||
@@ -32,6 +33,10 @@ | ||
inject(InnerComponent.prototype, config); | ||
appProperty(InnerComponent.prototype); | ||
var Container = React.createClass(_.extend({ | ||
contextTypes: contextTypes, | ||
childContextTypes: DEFAULT_CONTEXT_TYPES, | ||
getChildContext: function getChildContext() { | ||
return { app: findApp(this) }; | ||
}, | ||
componentDidMount: function componentDidMount() { | ||
@@ -90,3 +95,3 @@ var component = { | ||
getInitialState: function getInitialState() { | ||
inject(this, config); | ||
appProperty(this); | ||
return this.getState(); | ||
@@ -93,0 +98,0 @@ }, |
@@ -13,3 +13,3 @@ 'use strict'; | ||
accept: 'application/html', | ||
success: function (data, textStatus, jqXHR) { | ||
success: function success(data, textStatus, jqXHR) { | ||
var $div = _$('<div />', { | ||
@@ -16,0 +16,0 @@ id: 'server-html' + uuid() |
'use strict'; | ||
var _ = require('lodash'); | ||
var React = require('react'); | ||
@@ -10,10 +9,6 @@ var sinon = require('sinon'); | ||
var ActionPayload = require('../../core/actionPayload'); | ||
var buildMarty = require('../../../test/lib/buildMarty'); | ||
var _require = require('../../test-utils'); | ||
var renderIntoDocument = require('react/addons').addons.TestUtils.renderIntoDocument; | ||
var renderIntoDocument = _require.renderIntoDocument; | ||
var buildMarty = require('../../../test/lib/buildMarty'); | ||
var TestUtils = require('react/addons').addons.TestUtils; | ||
describe('StateMixin', function () { | ||
@@ -43,36 +38,2 @@ var element, sandbox, mixin, initialState, Marty, app, state, componentFunctionContext; | ||
it('should throw an error if you dont pass in an object literal', function () { | ||
expect(function () { | ||
Marty.createStateMixin(); | ||
}).to['throw'](Error); | ||
}); | ||
describe('#inject', function () { | ||
var mixinFunctionContext; | ||
beforeEach(function () { | ||
app.register('fooActions', Marty.ActionCreators); | ||
app.register('barActions', Marty.ActionCreators); | ||
renderClassWithMixin(Marty.createStateMixin({ | ||
inject: ['fooActions', 'barActions'], | ||
getInitialState: function getInitialState() { | ||
mixinFunctionContext = this; | ||
return {}; | ||
} | ||
})); | ||
}); | ||
it('should make it available in the container component', function () { | ||
expect(deps(componentFunctionContext)).to.eql(deps(app)); | ||
}); | ||
it('should make it available in the inner component', function () { | ||
expect(deps(mixinFunctionContext)).to.eql(deps(app)); | ||
}); | ||
function deps(obj) { | ||
return _.pick(obj, 'fooActions', 'barActions'); | ||
} | ||
}); | ||
describe('when a store changes', function () { | ||
@@ -122,5 +83,2 @@ var expectedState, expectedId, action, log; | ||
app.register('unmountStore', Marty.createStore({ | ||
getState: function getState() { | ||
return {}; | ||
}, | ||
getInitialState: function getInitialState() { | ||
@@ -182,3 +140,3 @@ return {}; | ||
element = TestUtils.renderIntoDocument(React.createElement(parent)); | ||
element = renderIntoDocument(React.createElement(parent)); | ||
@@ -258,3 +216,3 @@ element.setState({ | ||
getState: function getState() { | ||
return this.store1.getState(); | ||
return this.app.store1.getState(); | ||
} | ||
@@ -283,4 +241,4 @@ }); | ||
return { | ||
store1: this.store1.getState(), | ||
store2: this.store2.getState() | ||
store1: this.app.store1.getState(), | ||
store2: this.app.store2.getState() | ||
}; | ||
@@ -313,3 +271,3 @@ } | ||
function renderClassWithMixin(mixin, render) { | ||
var element = React.createElement(React.createClass({ | ||
var Component = React.createClass({ | ||
mixins: [mixin], | ||
@@ -322,8 +280,6 @@ displayName: mixin.displayName, | ||
} | ||
})); | ||
}); | ||
var component = renderIntoDocument(element, app); | ||
return component.refs.innerComponent; | ||
return renderIntoDocument(React.createElement(Component, { app: app })); | ||
} | ||
}); |
'use strict'; | ||
var _ = require('../mindash'); | ||
var inject = require('../core/inject'); | ||
var findApp = require('../core/findApp'); | ||
var uuid = require('../core/utils/uuid'); | ||
var appProperty = require('../core/appProperty'); | ||
var StoreObserver = require('../core/storeObserver'); | ||
@@ -11,11 +12,15 @@ var reservedKeys = ['listenTo', 'getState', 'getInitialState']; | ||
return function createStateMixin(options) { | ||
if (!options) { | ||
throw new Error('The state mixin is expecting some options'); | ||
} | ||
options = options || {}; | ||
var instanceMethods = _.omit(options, reservedKeys); | ||
var contextTypes = { | ||
app: React.PropTypes.object | ||
}; | ||
var mixin = _.extend({ | ||
contextTypes: { | ||
app: React.PropTypes.object | ||
contextTypes: contextTypes, | ||
childContextTypes: contextTypes, | ||
getChildContext: function getChildContext() { | ||
return { app: findApp(this) }; | ||
}, | ||
@@ -28,5 +33,5 @@ componentDidMount: function componentDidMount() { | ||
this.__observer = new StoreObserver({ | ||
app: this.app, | ||
component: component, | ||
app: this.context.app, | ||
stores: options.listenTo, | ||
stores: options.listenTo || [], | ||
onStoreChanged: this.onStoreChanged | ||
@@ -56,3 +61,3 @@ }); | ||
getInitialState: function getInitialState() { | ||
inject(this, options); | ||
appProperty(this); | ||
@@ -59,0 +64,0 @@ var el = this._currentElement; |
@@ -8,4 +8,3 @@ 'use strict'; | ||
createApplication: require('./createApplication'), | ||
renderIntoDocument: require('./renderIntoDocument'), | ||
getDispatchedActionsWithType: require('./getDispatchedActionsWithType') | ||
}; |
{ | ||
"name": "marty-lib", | ||
"version": "0.10.0-beta.5", | ||
"version": "0.10.0-beta.6", | ||
"description": "A Javascript library for state management in React applications", | ||
@@ -28,9 +28,7 @@ "scripts": { | ||
"body-parser": "^1.9.3", | ||
"browserify": "^9.0.0", | ||
"browserify-shim": "^3.7.0", | ||
"browserify": "^10.0.0", | ||
"bundle-collapser": "^1.0.0", | ||
"chai": "^2.0.0", | ||
"chai-as-promised": "^4.1.1", | ||
"cheerio": "^0.18.0", | ||
"cookie-parser": "^1.3.3", | ||
"chai-as-promised": "^5.0.0", | ||
"cheerio": "^0.19.0", | ||
"es6-promise": "^2.0.0", | ||
@@ -42,3 +40,3 @@ "esprima-fb": "^12001.1.0-dev-harmony-fb", | ||
"jscs": "^1.11.3", | ||
"jsxhint": "^0.12.0", | ||
"jsxhint": "^0.15.0", | ||
"karma": "^0.12.24", | ||
@@ -51,11 +49,11 @@ "karma-browserify": "^4.1.2", | ||
"karma-sauce-launcher": "^0.2.10", | ||
"karma-spec-reporter": "0.0.13", | ||
"mocha": "^1.21.4", | ||
"karma-spec-reporter": "0.0.19", | ||
"mocha": "^2.2.5", | ||
"react": "^0.13.0", | ||
"semver": "^4.2.0", | ||
"shelljs": "^0.4.0", | ||
"shelljs": "^0.5.0", | ||
"sinon": "^1.10.3", | ||
"sinon-chai": "^2.5.0", | ||
"uglify-js": "^2.4.15", | ||
"isomorphic-fetch": "1.6.0" | ||
"isomorphic-fetch": "2.1.0" | ||
}, | ||
@@ -62,0 +60,0 @@ "author": "James Hollingworth", |
@@ -29,3 +29,2 @@ var React = require('react'); | ||
app = new fixture.App(); | ||
fixture.Message = app.bindTo(fixture.Message); | ||
app.messageStore.setContextName('local-context'); | ||
@@ -100,5 +99,4 @@ }); | ||
var app = new Application(); | ||
var WrappedComponent = app.bindTo(Component); | ||
return app.renderToString(<WrappedComponent/>).then(loadDOM); | ||
return app.renderToString(<Component/>).then(loadDOM); | ||
}); | ||
@@ -105,0 +103,0 @@ |
@@ -40,3 +40,3 @@ var React = require('react'); | ||
message() { | ||
return this.messageStore.getMessage('Child'); | ||
return this.app.messageStore.getMessage('Child'); | ||
} | ||
@@ -61,3 +61,3 @@ } | ||
message() { | ||
return this.messageStore.getMessage('Parent'); | ||
return this.app.messageStore.getMessage('Parent'); | ||
} | ||
@@ -64,0 +64,0 @@ } |
var _ = require('lodash'); | ||
var sinon = require('sinon'); | ||
var React = require('react'); | ||
var expect = require('chai').expect; | ||
var buildMarty = require('../../../test/lib/buildMarty'); | ||
var TestUtils = require('react/addons').addons.TestUtils; | ||
@@ -160,48 +158,2 @@ describe('Application', () => { | ||
describe('#bindTo(InnerComponent)', () => { | ||
beforeEach(() => { | ||
application = new Marty.Application(); | ||
}); | ||
describe('when you dont pass in a component', () => { | ||
it('should throw an error', () => { | ||
expect(bindToNull).to.throw(Error); | ||
function bindToNull() { | ||
application.bindTo(); | ||
} | ||
}); | ||
}); | ||
describe('when you pass in a react component', () => { | ||
var actualApplication, actualProps, expectedProps; | ||
beforeEach(() => { | ||
application = new Marty.Application(); | ||
var InnerComponent = React.createClass({ | ||
contextTypes: Marty.contextTypes, | ||
render() { | ||
actualProps = this.props; | ||
actualApplication = this.context.app; | ||
return <div/>; | ||
} | ||
}); | ||
expectedProps = { foo: 'bar' }; | ||
var ContainerComponent = application.bindTo(InnerComponent); | ||
TestUtils.renderIntoDocument(<ContainerComponent {...expectedProps} />); | ||
}); | ||
it('should pass the props through to the inner component', () => { | ||
expect(actualProps).to.eql(expectedProps); | ||
}); | ||
it('should pass the application down through the context', () => { | ||
expect(actualApplication).to.equal(application); | ||
}); | ||
}); | ||
}); | ||
describe('#fetch(callback)', function () { | ||
@@ -208,0 +160,0 @@ describe('when stores make requests to fetch data', function () { |
let _ = require('../mindash'); | ||
let log = require('../core/logger'); | ||
let invariant = require('invariant'); | ||
let timeout = require('../core/utils/timeout'); | ||
@@ -13,4 +14,2 @@ let deferred = require('../core/utils/deferred'); | ||
module.exports = function (React) { | ||
let ApplicationContainer = require('./applicationContainer')(React); | ||
class Application { | ||
@@ -47,33 +46,2 @@ constructor(options) { | ||
render(element, container, callback) { | ||
React.render(( | ||
<ApplicationContainer app={this}> | ||
{element} | ||
</ApplicationContainer> | ||
), container, callback); | ||
} | ||
bindTo(InnerComponent) { | ||
let app = this; | ||
if (!InnerComponent) { | ||
throw new Error('Must specify an inner component'); | ||
} | ||
return React.createClass({ | ||
childContextTypes: { | ||
app: React.PropTypes.object | ||
}, | ||
getChildContext() { | ||
return { app }; | ||
}, | ||
getInnerComponent() { | ||
return this.refs.innerComponent; | ||
}, | ||
render() { | ||
return <InnerComponent ref="innerComponent" app={app} {...this.props} />; | ||
} | ||
}); | ||
} | ||
getAll(type) { | ||
@@ -281,3 +249,3 @@ return this.__types[type] || {}; | ||
React.renderToString, | ||
element, | ||
() => elementWithApp(element, this), | ||
options | ||
@@ -291,3 +259,3 @@ ); | ||
React.renderToStaticMarkup, | ||
element, | ||
() => elementWithApp(element, this), | ||
options | ||
@@ -316,3 +284,15 @@ ); | ||
function elementWithApp(element, app) { | ||
invariant( | ||
element && | ||
(typeof element.type === 'function' || typeof element.type === 'string'), | ||
'Must pass in a React component' | ||
); | ||
return React.cloneElement(element, { | ||
app: app | ||
}); | ||
} | ||
return Application; | ||
}; |
@@ -1,18 +0,11 @@ | ||
var invariant = require('invariant'); | ||
var { isArray } = require('../mindash'); | ||
let findApp = require('../core/findApp'); | ||
let { isArray, extend } = require('../mindash'); | ||
module.exports = function (React) { | ||
var ApplicationContainer = React.createClass({ | ||
let ApplicationContainer = React.createClass({ | ||
childContextTypes: { | ||
app: React.PropTypes.object | ||
}, | ||
propTypes: { | ||
app: React.PropTypes.object | ||
}, | ||
getChildContext() { | ||
invariant(this.props.app, 'Must specify the application'); | ||
return { | ||
app: this.props.app | ||
}; | ||
return { app: findApp(this) }; | ||
}, | ||
@@ -24,12 +17,12 @@ render() { | ||
if (isArray(children)) { | ||
return React.Children.map(children, cloneElementWithApp); | ||
return <span>{React.Children.map(children, cloneWithApp)}</span>; | ||
} else { | ||
return cloneElementWithApp(children); | ||
return cloneWithApp(children); | ||
} | ||
} | ||
function cloneElementWithApp(element) { | ||
return React.addons.cloneWithProps(element, { | ||
function cloneWithApp(element) { | ||
return React.createElement(element.type, extend({ | ||
app: app | ||
}); | ||
}, element.props)); | ||
} | ||
@@ -36,0 +29,0 @@ } |
module.exports = function (marty, React) { | ||
let Application = require('./application')(React); | ||
let ApplicationContainer = require('./applicationContainer')(React); | ||
marty.ApplicationContainer = require('./applicationContainer')(React); | ||
marty.createApplication = require('./createApplication')(Application); | ||
marty.Application = Application; | ||
marty.ApplicationContainer = ApplicationContainer; | ||
marty.contextTypes = { | ||
@@ -9,0 +8,0 @@ app: React.PropTypes.instanceOf(Application) |
let _ = require('../mindash'); | ||
let MAX_NUMBER_OF_ITERATIONS = 10; | ||
let invariant = require('invariant'); | ||
function renderToString(app, render, element, options) { | ||
function renderToString(app, render, createElement, options) { | ||
options = _.defaults(options || {}, { | ||
@@ -9,2 +10,6 @@ maxNumberOfIterations: MAX_NUMBER_OF_ITERATIONS | ||
invariant(app, 'Must specify the application'); | ||
invariant(render, 'Must specify the render function'); | ||
invariant(_.isFunction(createElement), 'Must specify the element factory'); | ||
let totalIterations = 0; | ||
@@ -14,2 +19,4 @@ let fetchOptions = { timeout: options.timeout }; | ||
return new Promise(function (resolve, reject) { | ||
let element = createElement(); | ||
resolveFetches().then(dehydrateAndRenderHtml); | ||
@@ -16,0 +23,0 @@ |
@@ -6,4 +6,4 @@ var React = require('react'); | ||
var fetch = require('../../store/fetch'); | ||
var { renderIntoDocument } = require('../../test-utils'); | ||
var buildMarty = require('../../../test/lib/buildMarty'); | ||
var { renderIntoDocument } = require('react/addons').addons.TestUtils; | ||
@@ -71,66 +71,2 @@ describe('Container', () => { | ||
describe('#inject', () => { | ||
var containerFunctionContext; | ||
beforeEach(() => { | ||
app.register('dep1', Marty.Store); | ||
app.register('dep2', Marty.Store); | ||
}); | ||
describe('when I inject in a dependency', () => { | ||
beforeEach(function () { | ||
var Component = Marty.createContainer(InnerComponent, { | ||
inject: ['dep1', 'dep2'], | ||
fetch: { | ||
foo() { | ||
containerFunctionContext = this; | ||
return {}; | ||
} | ||
} | ||
}); | ||
renderIntoDocument(<Component />, app); | ||
}); | ||
it('should make it available in the container component', () => { | ||
expect(deps(containerFunctionContext)).to.eql(deps(app)); | ||
}); | ||
it('should make it available in the inner component', () => { | ||
expect(deps(innerFunctionContext)).to.eql(deps(app)); | ||
}); | ||
}); | ||
describe('when I inject a dependency to a component that have contextTypes', () => { | ||
beforeEach(function () { | ||
class Component extends React.Component { | ||
render() { | ||
innerFunctionContext = this; | ||
return false; | ||
} | ||
} | ||
var ComponentContainer = Marty.createContainer(Component, { | ||
inject: ['dep1', 'dep2'], | ||
fetch: { | ||
foo() { | ||
containerFunctionContext = this; | ||
return {}; | ||
} | ||
} | ||
}); | ||
renderIntoDocument(<ComponentContainer />, app); | ||
}); | ||
it('should make it available in the container component', () => { | ||
expect(deps(containerFunctionContext)).to.eql(deps(app)); | ||
}); | ||
it('should make it available in the inner component', () => { | ||
expect(deps(innerFunctionContext)).to.eql(deps(app)); | ||
}); | ||
}); | ||
}); | ||
describe('component lifestyle', () => { | ||
@@ -173,3 +109,3 @@ var ParentComponent; | ||
element = renderIntoDocument(<ParentComponent />); | ||
element = renderIntoDocument(<ParentComponent app={app} />); | ||
@@ -210,10 +146,9 @@ element.setState({ | ||
let actualApplication; | ||
let exectedApplication; | ||
beforeEach(() => { | ||
exectedApplication = new Marty.Application(); | ||
app = new Marty.Application(); | ||
class TestComponent extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
constructor(props, context) { | ||
super(props, context); | ||
actualApplication = props.app; | ||
@@ -228,7 +163,7 @@ } | ||
renderIntoDocument(<WrappedComponent />, app); | ||
renderIntoDocument(<WrappedComponent app={app} />); | ||
}); | ||
it('should pass the app down through the props', () => { | ||
expect(actualApplication).to.equal(exectedApplication); | ||
expect(actualApplication).to.equal(app); | ||
}); | ||
@@ -251,3 +186,3 @@ }); | ||
it('should set the display name on classical React components', () => { | ||
expect(render(ContainerComponent).refs.subject.constructor.displayName).to.eql('InnerComponentContainer'); | ||
expect(render(ContainerComponent).constructor.displayName).to.eql('InnerComponentContainer'); | ||
}); | ||
@@ -262,4 +197,5 @@ | ||
let ContainerES6Component = Marty.createContainer(ES6InnerComponent); | ||
expect(render(ContainerES6Component).refs.subject.constructor.displayName).to.eql('ES6InnerComponentContainer'); | ||
let ContainerES6Component = wrap(ES6InnerComponent); | ||
expect(render(ContainerES6Component).constructor.displayName).to.eql('ES6InnerComponentContainer'); | ||
}); | ||
@@ -297,3 +233,3 @@ }); | ||
}); | ||
element = renderIntoDocument(<ContainerComponent />); | ||
element = renderIntoDocument(<ContainerComponent app={app} />); | ||
}); | ||
@@ -376,3 +312,3 @@ | ||
var element = renderIntoDocument(<ParentComponent />); | ||
var element = renderIntoDocument(<ParentComponent app={app} />); | ||
@@ -480,3 +416,3 @@ element.replaceState({ | ||
bar() { | ||
return this.barStore.getBar(expectedId); | ||
return this.app.barStore.getBar(expectedId); | ||
} | ||
@@ -486,3 +422,3 @@ } | ||
element = renderIntoDocument(<ContainerComponent />, app); | ||
element = renderIntoDocument(<ContainerComponent app={app} />); | ||
@@ -509,3 +445,3 @@ finishQuery(); | ||
element = renderIntoDocument(<ContainerComponent />); | ||
element = renderIntoDocument(<ContainerComponent app={app} />); | ||
}); | ||
@@ -519,6 +455,6 @@ | ||
describe('when the component is bound to an application', () => { | ||
var application, actualApplication; | ||
var actualApplication; | ||
beforeEach(() => { | ||
application = new Marty.Application(); | ||
app = new Marty.Application(); | ||
ContainerComponent = wrap(InnerComponent, { | ||
@@ -534,7 +470,7 @@ fetch: { | ||
element = renderIntoDocument(<ContainerComponent />, application); | ||
element = renderIntoDocument(<ContainerComponent app={app} />); | ||
}); | ||
it('should make the application accessible on `this.app`', () => { | ||
expect(actualApplication).to.equal(application); | ||
expect(actualApplication).to.equal(app); | ||
}); | ||
@@ -664,3 +600,3 @@ }); | ||
beforeEach(() => { | ||
var app = new Marty.Application(); | ||
app = new Marty.Application(); | ||
@@ -684,3 +620,3 @@ app.register('fooStore', Marty.createStore({ | ||
foo() { | ||
return this.fooStore.getFoo(123); | ||
return this.app.fooStore.getFoo(123); | ||
} | ||
@@ -709,3 +645,3 @@ } | ||
foo() { | ||
return this.store.getFoo(123); | ||
return this.app.store.getFoo(123); | ||
} | ||
@@ -754,6 +690,2 @@ } | ||
function deps(obj) { | ||
return _.pick(obj, 'dep1', 'dep2'); | ||
} | ||
function withoutApp(props) { | ||
@@ -768,12 +700,4 @@ return _.omit(props, 'app'); | ||
function render(Component, props) { | ||
var ContextContainer = React.createClass({ | ||
render: function () { | ||
var innerProps = _.extend({}, this.props, props, { ref: 'subject' }); | ||
return <Component {...innerProps} />; | ||
} | ||
}); | ||
return renderIntoDocument(<ContextContainer />, app); | ||
return renderIntoDocument(<Component app={app} {...props} />); | ||
} | ||
}); |
let _ = require('../mindash'); | ||
let inject = require('../core/inject'); | ||
let findApp = require('../core/findApp'); | ||
let uuid = require('../core/utils/uuid'); | ||
let getFetchResult = require('./getFetchResult'); | ||
let appProperty = require('../core/appProperty'); | ||
let StoreObserver = require('../core/storeObserver'); | ||
let getFetchResult = require('./getFetchResult'); | ||
let getClassName = require('../core/utils/getClassName'); | ||
@@ -44,6 +45,10 @@ | ||
inject(InnerComponent.prototype, config); | ||
appProperty(InnerComponent.prototype); | ||
let Container = React.createClass(_.extend({ | ||
contextTypes: contextTypes, | ||
childContextTypes: DEFAULT_CONTEXT_TYPES, | ||
getChildContext() { | ||
return { app: findApp(this) }; | ||
}, | ||
componentDidMount() { | ||
@@ -102,3 +107,3 @@ let component = { | ||
getInitialState() { | ||
inject(this, config); | ||
appProperty(this); | ||
return this.getState(); | ||
@@ -105,0 +110,0 @@ }, |
let log = require('./logger'); | ||
let _ = require('../mindash'); | ||
class StoreObserver { | ||
@@ -5,0 +6,0 @@ constructor(options) { |
@@ -1,2 +0,1 @@ | ||
var _ = require('lodash'); | ||
var React = require('react'); | ||
@@ -8,5 +7,4 @@ var sinon = require('sinon'); | ||
var ActionPayload = require('../../core/actionPayload'); | ||
var { renderIntoDocument } = require('../../test-utils'); | ||
var buildMarty = require('../../../test/lib/buildMarty'); | ||
var TestUtils = require('react/addons').addons.TestUtils; | ||
var { renderIntoDocument } = require('react/addons').addons.TestUtils; | ||
@@ -37,34 +35,2 @@ describe('StateMixin', function () { | ||
it('should throw an error if you dont pass in an object literal', function () { | ||
expect(function () { Marty.createStateMixin(); }).to.throw(Error); | ||
}); | ||
describe('#inject', function () { | ||
var mixinFunctionContext; | ||
beforeEach(function () { | ||
app.register('fooActions', Marty.ActionCreators); | ||
app.register('barActions', Marty.ActionCreators); | ||
renderClassWithMixin(Marty.createStateMixin({ | ||
inject: ['fooActions', 'barActions'], | ||
getInitialState() { | ||
mixinFunctionContext = this; | ||
return {}; | ||
} | ||
})); | ||
}); | ||
it('should make it available in the container component', () => { | ||
expect(deps(componentFunctionContext)).to.eql(deps(app)); | ||
}); | ||
it('should make it available in the inner component', () => { | ||
expect(deps(mixinFunctionContext)).to.eql(deps(app)); | ||
}); | ||
function deps(obj) { | ||
return _.pick(obj, 'fooActions', 'barActions'); | ||
} | ||
}); | ||
describe('when a store changes', function () { | ||
@@ -113,5 +79,2 @@ var expectedState, expectedId, action, log; | ||
app.register('unmountStore', Marty.createStore({ | ||
getState: function () { | ||
return {}; | ||
}, | ||
getInitialState: function () { | ||
@@ -169,3 +132,3 @@ return {}; | ||
element = TestUtils.renderIntoDocument(React.createElement(parent)); | ||
element = renderIntoDocument(React.createElement(parent)); | ||
@@ -245,3 +208,3 @@ element.setState({ | ||
getState: function () { | ||
return this.store1.getState(); | ||
return this.app.store1.getState(); | ||
} | ||
@@ -270,4 +233,4 @@ }); | ||
return { | ||
store1: this.store1.getState(), | ||
store2: this.store2.getState() | ||
store1: this.app.store1.getState(), | ||
store2: this.app.store2.getState() | ||
}; | ||
@@ -300,3 +263,3 @@ } | ||
function renderClassWithMixin(mixin, render) { | ||
var element = React.createElement(React.createClass({ | ||
var Component = React.createClass({ | ||
mixins: [mixin], | ||
@@ -309,8 +272,6 @@ displayName: mixin.displayName, | ||
} | ||
})); | ||
}); | ||
var component = renderIntoDocument(element, app); | ||
return component.refs.innerComponent; | ||
return renderIntoDocument(<Component app={app} />); | ||
} | ||
}); |
let _ = require('../mindash'); | ||
let inject = require('../core/inject'); | ||
let findApp = require('../core/findApp'); | ||
let uuid = require('../core/utils/uuid'); | ||
let appProperty = require('../core/appProperty'); | ||
let StoreObserver = require('../core/storeObserver'); | ||
@@ -9,11 +10,15 @@ let reservedKeys = ['listenTo', 'getState', 'getInitialState']; | ||
return function createStateMixin(options) { | ||
if (!options) { | ||
throw new Error('The state mixin is expecting some options'); | ||
} | ||
options = options || {}; | ||
let instanceMethods = _.omit(options, reservedKeys); | ||
let contextTypes = { | ||
app: React.PropTypes.object | ||
}; | ||
let mixin = _.extend({ | ||
contextTypes: { | ||
app: React.PropTypes.object | ||
contextTypes: contextTypes, | ||
childContextTypes: contextTypes, | ||
getChildContext() { | ||
return { app: findApp(this) }; | ||
}, | ||
@@ -27,5 +32,5 @@ componentDidMount: function () { | ||
this.__observer = new StoreObserver({ | ||
app: this.app, | ||
component: component, | ||
app: this.context.app, | ||
stores: options.listenTo, | ||
stores: options.listenTo || [], | ||
onStoreChanged: this.onStoreChanged | ||
@@ -55,3 +60,3 @@ }); | ||
getInitialState: function () { | ||
inject(this, options); | ||
appProperty(this); | ||
@@ -58,0 +63,0 @@ let el = this._currentElement; |
@@ -6,4 +6,3 @@ module.exports = { | ||
createApplication: require('./createApplication'), | ||
renderIntoDocument: require('./renderIntoDocument'), | ||
getDispatchedActionsWithType: require('./getDispatchedActionsWithType') | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
584475
31
255
15682