Skip to content

Instantly share code, notes, and snippets.

@BlancosWay
Forked from iammerrick/README.md
Created January 2, 2016 02:24
Show Gist options
  • Save BlancosWay/c398ec366034dc9eef97 to your computer and use it in GitHub Desktop.
Save BlancosWay/c398ec366034dc9eef97 to your computer and use it in GitHub Desktop.

Redux Chaos Monkey

This is a proof of concept which allows you to replay system events in a random order each time to make sure your UI can tolerate variable states.

I'm not sure if this is worthy of its on open source project with additional features like changing play back time, whitelisting/blacklisting actions etc but figured I'd put this out there to see if it piques anyones interest.

See a video of this in action here: [https://www.youtube.com/watch?v=wkoukONfwmA](Video on YouTube).

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, compose } from 'redux';
import { connect, Provider} from 'react-redux';
import { createDevTools, ActionCreators } from 'redux-devtools';
const { reset, performAction } = ActionCreators;
/**
* Developer Tools
*/
const Havoc = connect((state) => state, {
reset,
performAction
})(class extends React.Component {
constructor(){
super(...arguments);
this.havoc = this.havoc.bind(this);
}
havoc() {
const goHam = (list) => {
const keys = Object.keys(list);
const random = keys[Math.floor(Math.random() * keys.length)];
if (keys.length === 0) return null;
if (list[random].action.type !== '@@INIT') {
this.props.performAction(list[random].action);
}
const remaining = keys.reduce((acc, key) => {
if (key === random) return acc;
acc[key] = list[key];
return acc;
}, {});
setTimeout(() => goHam(remaining), 500);
};
this.props.reset();
goHam(this.props.actionsById);
}
render() {
return (
<div style={{ backgroundColor: '#eee' }}>
<button onClick={this.havoc}>Wreak Chaos</button>
{Object.keys(this.props.actionsById).map((action) => {
return <div key={action}>{this.props.actionsById[action].action.type}</div>;
})}
</div>
);
}
});
Havoc.update = () => {};
const DeveloperTools = createDevTools(<Havoc />);
const finalCreateStore = compose(
DeveloperTools.instrument()
)(createStore);
/**
* Constants
*/
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
/**
* Store
*/
const store = finalCreateStore((state = { count: 0 }, action) => {
switch (action.type) {
case INCREMENT:
return { count: state.count + 1 };
case DECREMENT:
return { count: state.count - 1 };
default:
return state;
}
});
/**
* Actions
*/
const increment = () => {
return {
type: INCREMENT
};
};
const decrement = () => {
return {
type: DECREMENT
};
};
/**
* Selectors
*/
const selectCount = (state) => {
return state.count;
};
/**
* Components
*/
const Counter = connect((state) => ({
count: selectCount(state)
}), {
increment,
decrement
})(class extends React.Component {
render() {
return (
<div>
<button onClick={this.props.increment}>+</button>
<button onClick={this.props.decrement}>-</button>
{this.props.count}
</div>
);
}
});
ReactDOM.render(
<Provider store={store}>
<div>
<Counter />
<DeveloperTools />
</div>
</Provider>
, document.getElementById('viewport'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment