Last active
February 21, 2016 18:00
-
-
Save AdamBrodzinski/aeb5b669a74259da8af8 to your computer and use it in GitHub Desktop.
Karma React Setup (drop these in /tests/karma/ )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = function(config) { | |
config.set({ | |
basePath: '../../', | |
frameworks: ['jasmine', 'jquery-2.1.0'], | |
plugins: [ | |
'karma-babel-preprocessor', | |
'karma-jquery', | |
'karma-jasmine', | |
'karma-mocha-reporter', | |
], | |
autoWatch: true, | |
reporters: ['mocha'], | |
// import your files the same as Meteor would, you'll need to tweak these | |
files: [ | |
'tests/karma/mocks.js', | |
'tests/karma/node_modules/react/dist/react-with-addons.js', | |
'both/lib/namespaces.js', | |
'tests/karma/spec_helper.js', | |
'**/*Mixin.jsx', | |
'both/components/**/*.jsx', | |
'both/pages/**/*.jsx', | |
'**/*_spec.js', | |
], | |
preprocessors: { | |
'**/*.jsx': ['babel'], | |
'**/*_spec.js': ['babel'] | |
}, | |
babelPreprocessor: { | |
options: { | |
sourceMap: 'inline', | |
whitelist: [ | |
"react", | |
"flow", | |
'es3.propertyLiterals', | |
'es3.memberExpressionLiterals', | |
'es6.arrowFunctions', | |
'es6.templateLiterals', | |
'es6.classes', | |
'es6.blockScoping', | |
"es6.properties.shorthand", | |
"es6.properties.computed", | |
"es6.parameters.rest", | |
"es6.parameters.default", | |
"es6.spread", | |
"es6.destructuring", | |
"es6.constants", | |
"es7.objectRestSpread", | |
'es7.trailingFunctionCommas', | |
] | |
}, | |
filename: function (file) { | |
return file.originalPath.replace(/\.js$/, '.es5.js'); | |
}, | |
sourceFileName: function (file) { | |
return file.originalPath; | |
} | |
} | |
}); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ReactMeteor = { | |
Mixin: {} | |
}; | |
Meteor = { | |
_reload: { | |
onMigrate: function() { } | |
} | |
} | |
FlowRouter = { | |
route: function() { | |
} | |
}; | |
log = function() {}; | |
ReactMeteorData = {}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "karma-unit-tests", | |
"version": "1.0.0", | |
"description": "Tests for React", | |
"scripts": { | |
"test": "./node_modules/karma/bin/karma start" | |
}, | |
"devDependencies": { | |
"jasmine-core": "^2.3.4", | |
"karma": "^0.12.36", | |
"karma-babel-preprocessor": "^5.2.1", | |
"karma-chrome-launcher": "^0.1.12", | |
"karma-jasmine": "^0.3.5", | |
"karma-jquery": "^0.1.0", | |
"karma-mocha-reporter": "^1.0.2", | |
"react": "^0.13.3" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# typing reactunit + tab will scaffold out this: | |
snippet reactunit "React Unit Test" !b | |
/*global $1, renderComponent */ | |
describe("$1 Component", function() { | |
var defProps, renderWithProps, component, el, $el; | |
beforeEach(() => { | |
defProps = { | |
label: 'Check me', | |
}; | |
renderWithProps = function(props) { | |
component = renderComponent($1, props); | |
el = React.findDOMNode(component); | |
$el = $(el); | |
}; | |
renderWithProps(defProps); | |
}); | |
it("should be mounted in DOM", () => { | |
expect($el.length).toEqual(1); | |
}); | |
}); | |
endsnippet |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TestUtils = React.addons.TestUtils; | |
Simulate = TestUtils.Simulate; | |
renderComponent = function (comp, props) { | |
return TestUtils.renderIntoDocument( | |
React.createElement(comp, props) | |
); | |
}; | |
simulateClickOn = function(selector) { | |
var button = this.$el.find(selector)[0]; | |
console.log(button); | |
React.addons.TestUtils.Simulate.click(button); | |
} | |
var spies = [], | |
componentStubs = [], | |
renderedComponents = []; | |
jasmineReact = { | |
render: function(component, container, callback){ | |
if(typeof container === "undefined"){ | |
container = this.getDefaultContainer(); | |
} | |
var comp = (typeof callback === "undefined") ? | |
React.render(component, container) : | |
React.render(component, container, callback); | |
// keep track of the components we render, so we can unmount them later | |
renderedComponents.push(comp); | |
return comp; | |
}, | |
spyOnClass: function(klass, methodName){ | |
var klassProto = this.classPrototype(klass), | |
original = klassProto[methodName], | |
jasmineSpy = spyOn(klassProto, methodName); | |
// keep track of the spies, so we can clean up the __reactAutoBindMap later | |
// (Jasmine 2.1) | |
spies.push({ | |
spy: jasmineSpy, | |
baseObj: klassProto, | |
methodName: methodName, | |
originalValue: original | |
}); | |
// react.js will autobind `this` to the correct value and it caches that | |
// result on a __reactAutoBindMap for performance reasons. | |
if(klassProto.__reactAutoBindMap){ | |
klassProto.__reactAutoBindMap[methodName] = jasmineSpy; | |
} | |
return jasmineSpy; | |
}, | |
classComponentConstructor: function(klass){ | |
return klass.type || // React 0.11.1 | |
klass.componentConstructor; // React 0.8.0 | |
}, | |
classPrototype: function(klass){ | |
var componentConstructor = this.classComponentConstructor(klass); | |
if(typeof componentConstructor === "undefined"){ | |
throw("A component constructor could not be found for this class. Are you sure you passed in a the component definition for a React component?"); | |
} | |
return componentConstructor.prototype; | |
}, | |
createStubComponent: function(obj, propertyName){ | |
// keep track of the components we stub, so we can swap them back later | |
componentStubs.push({obj: obj, propertyName: propertyName, originalValue: obj[propertyName]}); | |
return obj[propertyName] = React.createClass({ | |
render: function(){ | |
return React.DOM.div(); | |
} | |
}); | |
}, | |
addMethodToClass: function(klass, methodName, methodDefinition){ | |
if(typeof methodDefinition === "undefined"){ | |
methodDefinition = function(){}; | |
} | |
this.classPrototype(klass)[methodName] = methodDefinition; | |
return klass; | |
}, | |
resetComponentStubs: function(){ | |
for (var i = 0; i < componentStubs.length; i++) { | |
var stub = componentStubs[i]; | |
stub.obj[stub.propertyName] = stub.originalValue; | |
} | |
componentStubs = []; | |
}, | |
removeAllSpies: function(){ | |
for (var i = 0; i < spies.length; i++) { | |
var spy = spies[i]; | |
if(spy.baseObj.__reactAutoBindMap){ | |
spy.baseObj.__reactAutoBindMap[spy.methodName] = spy.originalValue; | |
} | |
spy.baseObj[spy.methodName] = spy.originalValue; | |
} | |
spies = []; | |
}, | |
unmountAllRenderedComponents: function(){ | |
for (var i = 0; i < renderedComponents.length; i++) { | |
var renderedComponent = renderedComponents[i]; | |
this.unmountComponent(renderedComponent); | |
} | |
renderedComponents = []; | |
}, | |
unmountComponent: function(component){ | |
if(component.isMounted()){ | |
return React.unmountComponentAtNode(component.getDOMNode().parentNode); | |
} else { | |
return false; | |
} | |
}, | |
getDefaultContainer: function(){ | |
return document.getElementById("jasmine_content"); | |
} | |
}; | |
// backwards compatability for React < 0.12 | |
jasmineReact.renderComponent = jasmineReact.render; | |
// TODO: this has no automated test coverage. Add some integration tests for coverage. | |
afterEach(function(){ | |
jasmineReact.removeAllSpies(); | |
jasmineReact.resetComponentStubs(); | |
jasmineReact.unmountAllRenderedComponents(); | |
}); | |
beforeEach(function() { | |
jasmine.addMatchers({ | |
// jQuery selector element exists | |
toExist: function () { | |
return { | |
compare: function (actual) { | |
return { pass: $(actual).length }; | |
} | |
}; | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment