Skip to content

Instantly share code, notes, and snippets.

@MatthewDavidCampbell
Last active August 29, 2015 14:20
Show Gist options
  • Save MatthewDavidCampbell/aba82a69b2eef36dec86 to your computer and use it in GitHub Desktop.
Save MatthewDavidCampbell/aba82a69b2eef36dec86 to your computer and use it in GitHub Desktop.
React, Mocha, JSDom with Reflux
var fs = require('fs');
var ReactTools = require("react-tools");
require.extensions['.jsx'] = function (module, filename) {
var content;
content = fs.readFileSync(filename, 'utf8');
var compiled = ReactTools.transform(content, { harmony: true });
return module._compile(compiled, filename);
};
/** This file is engaged by compilers option pointing to the file when running Mocha */
var chai = require('chai');
var jsdom = require('jsdom');
var React;
var Target;
var Main;
var Actions;
var Store;
var Unsubscribe;
describe('Complex Component (i.e. parent to other components)', function () {
beforeEach(function () {
global.document = jsdom.jsdom('<html><body></body></html>');
global.window = global.document.defaultView;
global.navigator = global.window.navigator;
// React caches the document, thanks to Ben Alpert and Jonathan Kim
for (var i in require.cache)
delete require.cache[i];
React = require('react/addons');
Actions = require(<path to actions the component uses>);
Store = require(<path to a store the component uses>);
Target = global.document.createElement('div');
Main = require(<path to component as jsx so yes we are using a Mocha JSX compiler when running>);
});
afterEach(function () {
React.unmountComponentAtNode(Target);
if (Unsubscribe)
Unsubscribe();
});
it('Render Component and Listen to Store', function (done) {
var Factory = React.createFactory(Main);
var Component = Factory({
/* here we could set props */
});
Unsubscribe = Store.listen(function (keys, prev, curr) {
done();
});
var Element = React.render(Component, Target);
});
it('Again Render', function (done) {
var Factory = React.createFactory(Main);
var Component = Factory({
});
var Element = React.render(Component, Target);
done();
});
});
/**
* The code here is based of the Fluxy project at:
* https://github.com/jmreidy/fluxy
*
* Thanks Justin!!
*/
var Mori = require('mori');
var toArray = function (val) {
if (!Array.isArray(val)) {
val = [val];
}
return val;
};
/**
* MoriMixin
*
* @mixin MoriMixin
*/
var Mixin = {
state: Mori.toClj({}),
_updateState: function (newState) {
this.state = newState;
},
_notify: function (keys, oldState, newState) {
this.trigger(toArray(keys), oldState, newState);
},
setInitialState: function (state) {
if (Mori.isEmpty(this.state))
this.state = Mori.toClj(state);
else
this.state = Mori.merge(
this.state,
Mori.toClj(state)
);
},
/**
* Get as Clojure Script
*
* @function
* @param {Array} keys
* @returns {Object} Clojure Script
*/
get: function (keys) {
if (typeof keys === 'string') {
return Mori.get(this.state, keys);
}
return Mori.getIn(this.state, keys);
},
/**
* Get as JavaScript
*
* @function
* @param {Array} keys
* @returns {Object} JavaScript
*/
getAsJS: function (keys) {
return Mori.toJs(this.get(keys));
},
/**
* Get Hashs
*
* @function
* @param {Array} keys
* @returns {Object}
*/
getHash: function (keys) {
return Mori.hash(this.get(keys));
},
/**
* Set from Clojure Script
*
* @function
* @param {Array} keys
* @param {Object} value
* @returns {Object} JavaScript
*/
set: function (keys, value) {
var newState, oldState;
var arrKeys = toArray(keys);
if (typeof value === 'function') {
oldState = this.state;
newState = Mori.updateIn(this.state, arrKeys, value);
}
else {
oldState = this.state;
newState = Mori.assocIn(this.state, arrKeys, value);
}
this._updateState(newState);
this._notify(keys, oldState, newState);
},
/**
* Set from JavaScript
*
* @function
* @param {Array} keys
* @param {Object} value
* @returns {Object} JavaScript
*/
setFromJS: function (keys, value) {
this.set(keys, Mori.toClj(value));
}
};
module.exports = Mixin;
var Reflux = require('reflux');
/* more require statements pulling in Actions etc. */
var Store = Reflux.createStore({
mixins: [MoriMixin],
init: function () {
this.setInitialState({
/** put your store's initial state here! */
});
/** all of your Reflux listen to actions here */
this.listenTo(
<some Action>,
'onSomeAction'
);
},
onSomeAction: function() {
}
});
module.exports = Store;
@ericmasiello
Copy link

Does this assume that all your jsx components are written with a .jsx extension?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment