Skip to content

Instantly share code, notes, and snippets.

@sam-rad
Created March 15, 2017 01:10
Show Gist options
  • Save sam-rad/1778fa0dd87ea07aa320287d3c185f25 to your computer and use it in GitHub Desktop.
Save sam-rad/1778fa0dd87ea07aa320287d3c185f25 to your computer and use it in GitHub Desktop.
nrl
<div id="app"></div>
// States
const NOT_STARTED = 'NOT_STARTED';
const FINISHED = 'FINISHED';
const RUNNING = 'RUNNING';
const PASSED = 'PASSED';
const FAILED = 'FAILED';
// Actions
const ADD_TEST = 'ADD_TEST';
const UPDATE_TEST = 'UPDATE_TEST';
// State ordering
const priority = {
RUNNING: 1,
PASSED: 2,
FAILED: 3
};
// Comparator fn
const compareTests = (a, b) => priority[a.state] > priority[b.state];
function generateDummyTest() {
var delay = 7000 + Math.random() * 7000;
var testPassed = Math.random() > 0.5;
return function(callback) {
setTimeout(function() {
callback(testPassed);
}, delay);
};
}
var tests = [
{ description: "commas are rotated properly", run: generateDummyTest() },
{ description: "exclamation points stand up straight", run: generateDummyTest() },
{ description: "run-on sentences don't run forever", run: generateDummyTest() },
{ description: "question marks curl down, not up", run: generateDummyTest() },
{ description: "semicolons are adequately waterproof", run: generateDummyTest() },
{ description: "capital letters can do yoga", run: generateDummyTest() }
];
const addTest = test => ({
type: ADD_TEST,
data: { ...test }
});
const updateTest = (description, state) => ({
type: UPDATE_TEST,
data: {
description: description,
state: state
}
});
const testReducer = (tests = [], action) => {
switch (action.type) {
case UPDATE_TEST:
return tests.map(t => {
console.log(action.data);
return t.description === action.data.description
? (console.log({ ...t, state: action.data.state }), { ...t, state: action.data.state })
: t;
})
default:
return tests;
}
};
const reducer = (state, action) => {
switch (action.type) {
case ADD_TEST: {
return { ...state, tests: [ ...state.tests, action.data ] };
}
case UPDATE_TEST:
return { ...state, tests: testReducer(state.tests, action) };
default:
return state;
}
};
const Test = ({ description, state }) => {
const colorClass = state === RUNNING
? 'blue'
: state === PASSED
? 'green'
: state === FAILED
? 'red'
: 'gray';
return (
<div>{ description }: <span className={ `label ${colorClass}` }>{ state }</span> </div>
);
};
const App = React.createClass({
getInitialState() {
return {
session_state: NOT_STARTED,
tests: []
}
},
componentDidMount() {
this.props.tests.map(_ => this.setState(s => reducer(s, addTest({
description: _.description,
state: NOT_STARTED
}))));
},
start () {
this.props.tests.map(_ => {
this.update(_.description, RUNNING);
_.run(result => result
? this.update(_.description, PASSED)
: this.update(_.description, FAILED));
});
},
update (description, state) {
this.setState(s => reducer(s, updateTest(description, state)));
},
add () {
this.props.tests.map(_ => this.setState(s => reducer(s, addTest({ description: _.description }))));
},
isSessionFinished (tests) {
return tests.reduce((acc, curr) => {
return curr.state === RUNNING || curr.state === NOT_STARTED
? (acc = false, acc)
: acc;
}, true);
},
render() {
const sortedTests = this.state.tests.sort(compareTests);
const finished = this.isSessionFinished(sortedTests);
return (
<div>
Session state: <span className="label gray"> { finished ? 'FINISHED' : '...' } </span>
<br /> <br />
{ sortedTests.map((t, i) => <Test key={i} { ...t } />) }
<br /> <br />
<button onClick= { () => this.start() }> Start Tests </button>
</div>
);
}
});
ReactDOM.render(<App tests={ tests }/>, document.querySelector('#app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js"></script>
body {
background-color: whitesmoke;
font-family: monospace;
}
.label {
border-radius: 2px;
padding: 0px 10px;
color: whitesmoke;
font-size: smaller;
}
.green {
background-color: #19a974;
}
.red {
background-color: #ff4136;
}
.blue {
background-color: #357edd;
}
.gray {
background-color: darkgray;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment