Skip to content

Instantly share code, notes, and snippets.

@MalucoMarinero
Created July 5, 2014 23:51
Show Gist options
  • Save MalucoMarinero/85349e9fff4134f63397 to your computer and use it in GitHub Desktop.
Save MalucoMarinero/85349e9fff4134f63397 to your computer and use it in GitHub Desktop.
Testing React with Generative Testing
///<reference path="../typedefs/node.d.ts"/>
///<reference path="../typedefs/bluebird.d.ts"/>
///<reference path="../typedefs/lodash.d.ts"/>
declare var describe, it, before; // Mocha injections.
import SwiftCheck = require('../src/SwiftCheck');
var domino = require('domino');
// DOM must be created prior to including React
global.window = domino.createWindow("<html><head></head><body></body></html>");
global.document = window.document;
global.navigator = window.navigator;
var React = require("react/addons");
var TUtils = React.addons.TestUtils;
var DOM = React.DOM;
var Prop = SwiftCheck.Prop;
var Gen = SwiftCheck.Gen;
var Counter = React.createClass({
getInitialState: function() {
return {count: this.props.initial || 0}
},
increment: function() { this.setState({count: this.state.count + 1}); },
decrement: function() { this.setState({count: this.state.count - 1}); },
render: function() {
var contClasses = {
'counter': true,
'red': this.state.count < 0,
'blue': this.state.count > 10
};
return DOM.div({className: React.addons.classSet(contClasses)},
DOM.span({className: 'display'}, this.state.count),
DOM.a({className: 'up', onClick: this.increment}, "Up"),
DOM.a({className: 'down', onClick: this.decrement}, "Down")
);
},
});
function callbackOnUpdate(component, callback) {
if (!component.componentDidUpdate) {
component.componentDidUpdate = function(prevProps, prevState) {
callback(prevProps, prevState);
component.componentDidUpdate = null;
};
} else {
var originalFunc = component.componentDidUpdate;
component.componentDidUpdate = function(prevProps, prevState) {
callback(prevProps, prevState);
component.componentDidUpdate = originalFunc;
};
};
};
describe("React Counter Component", () => {
before((done) => {
done();
});
it("render count correctly", () => {
var prop = Prop.forAll(Gen.Values.tinyInt(), (num) => {
var counter = TUtils.renderIntoDocument(Counter({initial: num}));
var display = TUtils.findRenderedDOMComponentWithClass(counter, 'display');
return display.getDOMNode().textContent == num.toString();
}).check();
});
it("use blue class when count above ten", () => {
var prop = Prop.forAll(Gen.Values.tinyInt(), function(num) {
this.implies(num > 10);
var counter = TUtils.renderIntoDocument(Counter({initial: num}));
return counter.getDOMNode().classList.contains('blue');
}).check();
});
it("use red class when count below zero", () => {
var prop = Prop.forAll(Gen.Values.tinyInt(), function(num) {
this.implies(num < 0);
var counter = TUtils.renderIntoDocument(Counter({initial: num}));
return counter.getDOMNode().classList.contains('red');
}).check();
});
it("holds good on state test", (done) => {
var prop = Prop.commands(function() {
this.initialSUT(() => {
return TUtils.renderIntoDocument(Counter({initial: 0}));
});
this.initialState(() => 0);
this.promised(true);
this.invariant((state, sut) => {
var display = TUtils.findRenderedDOMComponentWithClass(sut, 'display');
return display.getDOMNode().textContent == state.toString();
});
this.addCommand("Add", (system, done) => {
var up = TUtils.findRenderedDOMComponentWithClass(system, 'up');
callbackOnUpdate(system, () => { done(system); });
TUtils.Simulate.click(up.getDOMNode());
}, (s) => s + 1);
this.addCommand("Sub", (system, done) => {
var down = TUtils.findRenderedDOMComponentWithClass(system, 'down');
callbackOnUpdate(system, () => { done(system); });
TUtils.Simulate.click(down.getDOMNode());
}, (s) => s - 1);
}).check().then((result) => {
done();
}).catch(done);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment