Socket
Socket
Sign inDemoInstall

jasmine-react-helpers

Package Overview
Dependencies
0
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.2 to 0.2.0

2

package.json
{
"name": "jasmine-react-helpers",
"version": "0.1.2",
"version": "0.2.0",
"description": "a small suite of helper functions to make unit testing React.js components painless.",

@@ -5,0 +5,0 @@ "main": "src/jasmine-react.js",

@@ -133,7 +133,13 @@ *jasmine-react* is a small suite of helper functions to make unit testing React.js components painless.

When rendering a React component, this is a convenience function for React.renderComponent.
When rendering a React component, this is a convenience function for `React.renderComponent`.
It has a few helpful features:
* the container argument is optional. By default it will be: `document.getElementById("jasmine_content")
* the component is actually rendered to an attached DOM node (unlike `React.addons.TestUtils.renderIntoDocument which
renders into a detached DOM node).
* the component will be automatically unmounted after the test is complete.
NOTE: If you call React.renderComponent in a jasmine test and the component is not unmounted, that component
will pollute any subsequent tests which try to render into that container.
* the container argument is optional. By default it will be: `document.getElementById("jasmine_content"). If you
want to override this behavior, look at the documentation for `jasmineReact.getDefaultContainer`
* `React.renderComponent` will return before the rendering has occurred. `jasmineReact.renderComponent` will wait

@@ -211,14 +217,10 @@ until the async render has been performed.

## jasmineReact.getJasmineContent
## jasmineReact.getDefaultContainer
After each test, it is imperative that jasmineReact clean up after itself so that one test doesn't pollute the next.
One step in this process, is making sure that any component rendered gets unmounted. By default, in a jasmine suite
all DOM elements should be a child of the `#jasmine_content` div. If that is true for you, then you won't need to use
this function. But if you use some other div to render your jasmine DOM, then you'll want to redefine this function to
meet your specification.
The default container for jasmineReact is `document.getElementById("jasmine_content")`.
If your jasmine test page, uses `#spec-dom` as its dom node, then you'd want to define the following:
If your jasmine test page uses `#spec-dom` as its default dom node, then you'd want to define the following:
```js
jasmineReact.getJasmineContent = function(){
jasmineReact.getDefaultContainer = function(){
return document.getElementById("spec-dom");

@@ -230,5 +232,11 @@ };

To install, include the `src/jasmine-react.js` file in your jasmine spec helpers list.
```
npm install jasmine-react-helpers --save-dev
```
Bower: TODO
Script Tag: TODO
# Testing

@@ -235,0 +243,0 @@

var React = require('react');
var spies = [],
componentStubs = [],
renderedComponents = [];
var jasmineReact = {
renderComponent: function(component, container, callback){
if(typeof container === "undefined"){
container = jasmineReact.getJasmineContent();
container = this.getDefaultContainer();
}

@@ -13,2 +17,5 @@

// keep track of the components we render, so we can unmount them later
renderedComponents.push(comp);
return comp;

@@ -18,8 +25,10 @@ },

spyOnClass: function(klass, methodName){
var klassProto = jasmineReact.classPrototype(klass),
var klassProto = this.classPrototype(klass),
jasmineSpy = spyOn(klassProto, methodName);
this.jasmineReactSpies_ = this.jasmineReactSpies_ || [];
this.jasmineReactSpies_.push(jasmineSpy);
// keep track of the spies, so we can clean up the __reactAutoBindMap later
spies.push(jasmineSpy);
// react.js will autobind `this` to the correct value and it caches that
// result on a __reactAutoBindMap for performance reasons.
if(klassProto.__reactAutoBindMap){

@@ -38,3 +47,3 @@ klassProto.__reactAutoBindMap[methodName] = jasmineSpy;

classPrototype: function(klass){
var componentConstructor = jasmineReact.classComponentConstructor(klass);
var componentConstructor = this.classComponentConstructor(klass);

@@ -49,4 +58,4 @@ if(typeof componentConstructor === "undefined"){

createStubComponent: function(obj, propertyName){
this.jasmineReactComponentStubs_ = this.jasmineReactComponentStubs_ || [];
this.jasmineReactComponentStubs_.push({obj: obj, propertyName: propertyName, originalValue: 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]});

@@ -64,3 +73,3 @@ return obj[propertyName] = React.createClass({

}
jasmineReact.classPrototype(klass)[methodName] = methodDefinition;
this.classPrototype(klass)[methodName] = methodDefinition;
return klass;

@@ -70,21 +79,13 @@ },

resetComponentStubs: function(){
if(!this.jasmineReactComponentStubs_){
return;
}
for (var i = 0; i < this.jasmineReactComponentStubs_.length; i++) {
var stub = this.jasmineReactComponentStubs_[i];
for (var i = 0; i < componentStubs.length; i++) {
var stub = componentStubs[i];
stub.obj[stub.propertyName] = stub.originalValue;
}
this.jasmineReactComponentStubs_ = [];
componentStubs = [];
},
removeAllSpies: function(){
if(!this.jasmineReactSpies_){
return;
}
for (var i = 0; i < this.jasmineReactSpies_.length; i++) {
var spy = this.jasmineReactSpies_[i];
for (var i = 0; i < spies.length; i++) {
var spy = spies[i];
if(spy.baseObj.__reactAutoBindMap){

@@ -96,26 +97,23 @@ spy.baseObj.__reactAutoBindMap[spy.methodName] = spy.originalValue;

this.jasmineReactSpies_ = [];
spies = [];
},
unmountComponent: function(component){
return React.unmountComponentAtNode(component.getDOMNode().parentNode);
unmountAllRenderedComponents: function(){
for (var i = 0; i < renderedComponents.length; i++) {
var renderedComponent = renderedComponents[i];
this.unmountComponent(renderedComponent);
}
renderedComponents = [];
},
clearJasmineContent: function(){
var jasmineContentEl = jasmineReact.getJasmineContent();
if(jasmineContentEl){
React.unmountComponentAtNode(jasmineContentEl);
jasmineContentEl.innerHTML = "";
unmountComponent: function(component){
if(component.isMounted()){
return React.unmountComponentAtNode(component.getDOMNode().parentNode);
} else {
var warningMessage = "jasmineReact is unable to clear out the jasmine content element, because it could not find an " +
"element with an id of 'jasmine_content'. " +
"This may result in bugs, because a react component which isn't unmounted may pollute other tests " +
"and cause test failures/weirdness. " +
"If you'd like to override this behavior to look for a different element, then implement a method like this: " +
"jasmineReact.getJasmineContent = function(){ return document.getElementById('foo'); };"
console.warn(warningMessage);
return false;
}
},
getJasmineContent: function(){
getDefaultContainer: function(){
return document.getElementById("jasmine_content");

@@ -125,8 +123,9 @@ }

// TODO: this has no automated test coverage. Add some integration tests for coverage.
afterEach(function(){
jasmineReact.removeAllSpies();
jasmineReact.resetComponentStubs();
jasmineReact.clearJasmineContent();
jasmineReact.unmountAllRenderedComponents();
});
module.exports = jasmineReact;

@@ -10,34 +10,33 @@ describe("jasmineReact", function(){

describe("renderComponent", function(){
var fakeComponentSpy, fakeContainerSpy, fakeRenderComponentResponseSpy;
var fooKlass;
beforeEach(function(){
fakeComponentSpy = jasmine.createSpy("fakeComponent");
fakeContainerSpy = jasmine.createSpy("fakeContainer");
fooKlass = React.createClass({
render: function(){
return React.DOM.div({});
}
});
fakeRenderComponentResponseSpy = jasmine.createSpy("fakeRenderComponentResponse");
spyOn(React, "renderComponent").andReturn(fakeRenderComponentResponseSpy);
spyOn(React, "renderComponent").andCallThrough();
});
it("should call React.renderComponent", function(){
jasmineReact.renderComponent();
it("should call React.renderComponent with the passed in component", function(){
jasmineReact.renderComponent(fooKlass({foo: "bar"}), document.getElementById("jasmine_content"));
expect(React.renderComponent).toHaveBeenCalled();
});
var renderComponentArgs = React.renderComponent.mostRecentCall.args[0];
it("should call React.renderComponent with the passed in component", function(){
jasmineReact.renderComponent(fakeComponentSpy, fakeContainerSpy);
expect(React.renderComponent).toHaveBeenCalledWith(fakeComponentSpy, jasmine.any(Function));
expect(renderComponentArgs.props.foo).toBe("bar");
});
it("should call React.renderComponent with the passed in container", function(){
jasmineReact.renderComponent(fakeComponentSpy, fakeContainerSpy);
var container = document.getElementById("jasmine_content");
jasmineReact.renderComponent(fooKlass(), container);
expect(React.renderComponent).toHaveBeenCalledWith(jasmine.any(Function), fakeContainerSpy);
expect(React.renderComponent).toHaveBeenCalledWith(jasmine.any(Object), container);
});
it("should call React.renderComponent with #jasmine_content container if no container is passed in", function(){
jasmineReact.renderComponent(fakeComponentSpy);
jasmineReact.renderComponent(fooKlass());
expect(React.renderComponent).toHaveBeenCalledWith(jasmine.any(Function), document.getElementById("jasmine_content"));
expect(React.renderComponent).toHaveBeenCalledWith(jasmine.any(Object), document.getElementById("jasmine_content"));
});

@@ -48,14 +47,37 @@

jasmineReact.renderComponent(fakeComponentSpy, fakeContainerSpy, fakeCallbackSpy);
jasmineReact.renderComponent(fooKlass(), document.getElementById("jasmine_content"), fakeCallbackSpy);
expect(React.renderComponent).toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Function), fakeCallbackSpy);
expect(React.renderComponent).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Object), fakeCallbackSpy);
});
it("should return the return value of React.renderComponent", function(){
var returnValue = jasmineReact.renderComponent(fakeComponentSpy, fakeContainerSpy);
var returnValue = jasmineReact.renderComponent(fooKlass({baz: "bat"}), document.getElementById("jasmine_content"));
expect(returnValue).toBe(fakeRenderComponentResponseSpy);
expect(returnValue.props.baz).toBe("bat");
});
});
describe("renderComponent: test pollution", function(){
it("should not pollute a rendered component from one test into another test", function(){
var coolKlass = React.createClass({
render: function(){
return React.DOM.div({
id: "really-cool"
});
}
});
// lets pretend this is test #1
jasmineReact.renderComponent(coolKlass());
expect(document.getElementById("really-cool")).toBeDefined();
// this is the method in the afterEach which is needed to prevent test pollution for renderComponent
jasmineReact.unmountAllRenderedComponents();
// lets pretend this is test #1
expect(document.getElementById("really-cool")).toBeNull();
});
});
describe("spyOnClass", function(){

@@ -182,3 +204,3 @@ var fooKlass;

jasmineReact.removeAllSpies();
jasmineReact.clearJasmineContent();
jasmineReact.unmountAllRenderedComponents();

@@ -340,71 +362,55 @@ // lets pretend this is test #2

it("should unmount the component", function(){
var barComponent = jasmineReact.renderComponent(barKlass());
expect(componentWillUnmountSpy.callCount).toBe(0);
describe("the component is mounted", function(){
it("should unmount the component", function(){
var barComponent = jasmineReact.renderComponent(barKlass());
expect(componentWillUnmountSpy.callCount).toBe(0);
jasmineReact.unmountComponent(barComponent);
jasmineReact.unmountComponent(barComponent);
expect(componentWillUnmountSpy.callCount).toBe(1);
});
expect(componentWillUnmountSpy.callCount).toBe(1);
});
it("should return the return value of unmountComponentAtNode", function(){
var fakeUnmount = jasmine.createSpy("unmountComponentAtNode");
spyOn(React, "unmountComponentAtNode").andReturn(fakeUnmount);
it("should return the return value of unmountComponentAtNode", function(){
var barComponent = jasmineReact.renderComponent(barKlass({cool: "town"}));
var barComponent = jasmineReact.renderComponent(barKlass());
var returnValue = jasmineReact.unmountComponent(barComponent);
expect(jasmineReact.unmountComponent(barComponent)).toBe(fakeUnmount);
expect(returnValue).toBe(true);
});
});
});
describe("clearJasmineContent", function(){
it("should clear out the html in #jasmine_content", function(){
var barKlass = React.createClass({
render: function(){
return React.DOM.div({id: "bar-test-div"});
}
});
describe("the component is not mounted", function(){
jasmineReact.renderComponent(barKlass());
expect(document.getElementById("bar-test-div")).toBeDefined();
it("should not unmount the component", function(){
var barComponent = jasmineReact.renderComponent(barKlass());
jasmineReact.clearJasmineContent();
React.unmountComponentAtNode(barComponent.getDOMNode().parentNode);
expect(document.getElementById("bar-test-div")).toBeNull();
});
expect(componentWillUnmountSpy.callCount).toBe(1);
it("should unmount the react component in #jasmine_content", function(){
var componentWillUnmountSpy = jasmine.createSpy("componentWillUnmount");
expect(function(){
jasmineReact.unmountComponent(barComponent);
}).not.toThrow();
var barKlass = React.createClass({
render: function(){
return React.DOM.div({id: "bar-test-div"});
},
componentWillUnmount: function(){
componentWillUnmountSpy();
}
expect(componentWillUnmountSpy.callCount).toBe(1);
});
jasmineReact.renderComponent(barKlass());
expect(componentWillUnmountSpy.callCount).toBe(0);
it("should return false", function(){
var barComponent = jasmineReact.renderComponent(barKlass());
jasmineReact.clearJasmineContent();
React.unmountComponentAtNode(barComponent.getDOMNode().parentNode);
expect(componentWillUnmountSpy.callCount).toBe(1);
});
var returnValue;
it("should warn the user if a jasmine content element can't be found", function(){
spyOn(jasmineReact, "getJasmineContent").andCallFake(function(){
return document.getElementById("bogus");
expect(function(){
returnValue = jasmineReact.unmountComponent(barComponent);
}).not.toThrow();
expect(returnValue).toBe(false);
});
});
spyOn(console, "warn");
jasmineReact.clearJasmineContent();
expect(console.warn).toHaveBeenCalled();
expect(console.warn.mostRecentCall.args[0].substring(0, 63)).toBe("jasmineReact is unable to clear out the jasmine content element");
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc