Skip to content

Commit

Permalink
v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
MicheleBertoli committed Oct 13, 2016
1 parent e4f012d commit 0479ae0
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 81 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"extends": "airbnb",

"env": {
"mocha": true
},

"rules": {
"semi": [2, "never"],
"no-param-reassign": 0,
"prefer-rest-params": 0,
"react/prefer-es6-class": 0,
"react/prefer-stateless-function": 0,
"react/no-multi-comp": 0
Expand Down
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

# react-poop

react-poop wraps your stateless functions and the render method of your components
into a try/catch block and renders a 💩 when something goes wrong.
`react-poop` wraps your stateless functions and the render method of your components into a try/catch block.

When something goes wrong, it shows a 💩 (or the custom handler you provided) so that the tree can still be rendered.

## Installation

Expand All @@ -18,7 +19,15 @@ import React from 'react'
import { render } from 'react-dom'
import poop from 'react-poop'

const App = poop(() => <div>Hello react-poop</div>)
// default

const App = poop()(() => <div>Hello react-poop</div>)

// or
// with a custom handler

const Handler = ({ message }) => <div>{message}</div>
const App = poop(Handler)(() => <div>Hello react-poop</div>)

render(<App />, document.getElementById('app'))
```
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "react-poop",
"version": "0.2.0",
"version": "1.0.0",
"description": "The ultimate error handler for React",
"main": "dist/index.js",
"files": [
"dist"
],
"scripts": {
"test": "mocha --compilers js:babel-register --reporter=emoji-reporter ./src/**/*.spec.js",
"test": "mocha --compilers js:babel-register --reporter emoji-reporter",
"build": "babel ./src --out-dir ./dist --ignore *.spec.js",
"prepublish": "npm run build"
},
Expand Down Expand Up @@ -37,6 +37,7 @@
"eslint-plugin-import": "^1.9.2",
"eslint-plugin-jsx-a11y": "^1.5.3",
"eslint-plugin-react": "^5.2.2",
"jsdom": "^9.6.0",
"mocha": "^2.5.3",
"react": "^15.1.0",
"react-addons-test-utils": "^15.1.0",
Expand Down
20 changes: 10 additions & 10 deletions src/poop.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import React from 'react'

const isStateless = component => !(component.prototype && component.prototype.isReactComponent)
const isStateless = Component => !(Component.prototype && Component.prototype.isReactComponent)

const createClass = component => React.createClass({
render() {
return component(this.props)
},
})

const wrap = (Target, Handler) => {
const originalRender = Target.prototype.render
const wrap = (Component, Handler) => {
const originalRender = Component.prototype.render

Target.prototype.render = function render(...args) {
Component.prototype.render = function render(...args) {
try {
return originalRender.apply(this, args)
} catch (error) {
return <Handler error={error} />
}
}

return Target
return Component
}

export default handler => component => {
const Component = isStateless(component) ? createClass(component) : component
const Poop = error => <div title={error}>💩</div>
const Handler = handler || Poop
const Poop = error => <div title={error}>💩</div>

return wrap(Component, Handler)
export default Handler => Component => {
const Target = isStateless(Component) ? createClass(Component) : Component

return wrap(Target, Handler || Poop)
}
65 changes: 0 additions & 65 deletions src/poop.spec.js

This file was deleted.

81 changes: 81 additions & 0 deletions test/poop.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import assert from 'assert'
import { shallow, mount } from 'enzyme'
import React from 'react'

import poop from '../src'

describe('poop', () => {
const Handler = () => <div>Handler</div>

describe('class', () => {
let NiceClass
let EvilClass

beforeEach(() => {
NiceClass = React.createClass({
render() {
return <div>Dummy</div>
},
})

EvilClass = React.createClass({
render() {
return <div>{this.does.not.exist}</div>
},
})
})

it('renders the component when everything is fine', () => {
const Dummy = poop()(NiceClass)
const wrapper = shallow(<Dummy />)

assert(wrapper.contains('Dummy'))
})

it('renders the handler when something goes wrong', () => {
const Dummy = poop(Handler)(EvilClass)
const wrapper = mount(<Dummy />)

assert.equal(wrapper.find('Handler').length, 1)
})

it('renders the poop when something goes wrong', () => {
const Dummy = poop()(EvilClass)
const wrapper = mount(<Dummy />)

assert.equal(wrapper.find('Poop').length, 1)
})
})

describe('stateless', () => {
let NiceStateless
let EvilStateless

beforeEach(() => {
NiceStateless = () => <div>Dummy</div>

EvilStateless = () => <div>{this.does.not.exist}</div>
})

it('renders the component when everything is fine', () => {
const Dummy = poop()(NiceStateless)
const wrapper = shallow(<Dummy />)

assert(wrapper.contains('Dummy'))
})

it('renders the handler when something goes wrong', () => {
const Dummy = poop(Handler)(EvilStateless)
const wrapper = mount(<Dummy />)

assert.equal(wrapper.find('Handler').length, 1)
})

it('renders the poop when something goes wrong', () => {
const Dummy = poop()(EvilStateless)
const wrapper = mount(<Dummy />)

assert.equal(wrapper.find('Poop').length, 1)
})
})
})
13 changes: 13 additions & 0 deletions test/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { jsdom } from 'jsdom'

global.document = jsdom('')
global.window = document.defaultView
Object.keys(document.defaultView).forEach((property) => {
if (typeof global[property] === 'undefined') {
global[property] = document.defaultView[property]
}
})

global.navigator = {
userAgent: 'node.js',
}

0 comments on commit 0479ae0

Please sign in to comment.