Skip to content

Commit e67859b

Browse files
committed
add a test, remove proptypes from prod
1 parent 7c7fbfa commit e67859b

File tree

8 files changed

+251
-44
lines changed

8 files changed

+251
-44
lines changed

karma.conf.js

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
const path = require('path')
2+
const webpack = require('webpack')
3+
4+
module.exports = (config) => {
5+
const customLaunchers = {
6+
BS_Chrome: {
7+
base: 'BrowserStack',
8+
os: 'Windows',
9+
os_version: '10',
10+
browser: 'chrome',
11+
browser_version: '47.0'
12+
},
13+
BS_Firefox: {
14+
base: 'BrowserStack',
15+
os: 'Windows',
16+
os_version: '10',
17+
browser: 'firefox',
18+
browser_version: '43.0'
19+
},
20+
BS_Safari: {
21+
base: 'BrowserStack',
22+
os: 'OS X',
23+
os_version: 'El Capitan',
24+
browser: 'safari',
25+
browser_version: '9.0'
26+
},
27+
BS_MobileSafari8: {
28+
base: 'BrowserStack',
29+
os: 'ios',
30+
os_version: '8.3',
31+
browser: 'iphone',
32+
real_mobile: false
33+
},
34+
BS_MobileSafari9: {
35+
base: 'BrowserStack',
36+
os: 'ios',
37+
os_version: '9.1',
38+
browser: 'iphone',
39+
real_mobile: false
40+
},
41+
BS_InternetExplorer10: {
42+
base: 'BrowserStack',
43+
os: 'Windows',
44+
os_version: '8',
45+
browser: 'ie',
46+
browser_version: '10.0'
47+
},
48+
BS_InternetExplorer11: {
49+
base: 'BrowserStack',
50+
os: 'Windows',
51+
os_version: '10',
52+
browser: 'ie',
53+
browser_version: '11.0'
54+
}
55+
}
56+
57+
config.set({
58+
customLaunchers: customLaunchers,
59+
60+
browsers: [ 'Chrome' ],
61+
frameworks: [ 'mocha' ],
62+
reporters: [ 'mocha' ],
63+
64+
files: [
65+
'tests.webpack.js'
66+
],
67+
68+
preprocessors: {
69+
'tests.webpack.js': [ 'webpack', 'sourcemap' ]
70+
},
71+
72+
webpack: {
73+
devtool: 'inline-source-map',
74+
module: {
75+
loaders: [
76+
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel' }
77+
]
78+
},
79+
plugins: [
80+
new webpack.DefinePlugin({
81+
'process.env.NODE_ENV': JSON.stringify('test')
82+
})
83+
]
84+
},
85+
86+
webpackServer: {
87+
noInfo: true
88+
}
89+
})
90+
91+
if (process.env.USE_CLOUD) {
92+
config.browsers = Object.keys(customLaunchers)
93+
config.reporters = [ 'dots' ]
94+
config.browserDisconnectTimeout = 10000
95+
config.browserDisconnectTolerance = 3
96+
config.browserNoActivityTimeout = 30000
97+
config.captureTimeout = 120000
98+
99+
if (process.env.TRAVIS) {
100+
const buildLabel = 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')'
101+
102+
config.browserStack = {
103+
username: process.env.BROWSER_STACK_USERNAME,
104+
accessKey: process.env.BROWSER_STACK_ACCESS_KEY,
105+
pollingTimeout: 10000,
106+
startTunnel: true,
107+
project: 'react-router',
108+
build: buildLabel,
109+
name: process.env.TRAVIS_JOB_NUMBER
110+
}
111+
112+
config.singleRun = true
113+
} else {
114+
config.browserStack = {
115+
username: process.env.BROWSER_STACK_USERNAME,
116+
accessKey: process.env.BROWSER_STACK_ACCESS_KEY,
117+
pollingTimeout: 10000,
118+
startTunnel: true
119+
}
120+
}
121+
}
122+
}
123+

modules/Broadcast.js

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import invariant from 'invariant'
22
import React, { PropTypes } from 'react'
3-
import {
4-
broadcasts as broadcastsType
5-
} from './PropTypes'
63

74
const createBroadcast = (initialValue) => {
85
let listeners = []
@@ -36,19 +33,15 @@ const createBroadcast = (initialValue) => {
3633
*/
3734
class Broadcast extends React.Component {
3835
static contextTypes = {
39-
broadcasts: broadcastsType
40-
}
41-
42-
static propTypes = {
43-
channel: PropTypes.string.isRequired,
44-
children: PropTypes.node.isRequired,
45-
value: PropTypes.any
36+
broadcasts: PropTypes.object
4637
}
4738

4839
static childContextTypes = {
49-
broadcasts: broadcastsType.isRequired
40+
broadcasts: PropTypes.object.isRequired
5041
}
5142

43+
broadcast = createBroadcast(this.props.value)
44+
5245
getBroadcastsContext() {
5346
const { channel } = this.props
5447
const { broadcasts } = this.context
@@ -65,10 +58,6 @@ class Broadcast extends React.Component {
6558
}
6659
}
6760

68-
componentWillMount() {
69-
this.broadcast = createBroadcast(this.props.value)
70-
}
71-
7261
componentWillReceiveProps(nextProps) {
7362
invariant(
7463
this.props.channel === nextProps.channel,
@@ -84,4 +73,12 @@ class Broadcast extends React.Component {
8473
}
8574
}
8675

76+
if (__DEV__) {
77+
Broadcast.propTypes = {
78+
channel: PropTypes.string.isRequired,
79+
children: PropTypes.node.isRequired,
80+
value: PropTypes.any
81+
}
82+
}
83+
8784
export default Broadcast

modules/PropTypes.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

modules/Subscriber.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
11
import invariant from 'invariant'
22
import React, { PropTypes } from 'react'
3-
import {
4-
broadcasts as broadcastsType
5-
} from './PropTypes'
63

74
/**
85
* A <Subscriber> pulls the value for a channel off of context.broadcasts
96
* and passes it to its children function.
107
*/
118
class Subscriber extends React.Component {
129
static contextTypes = {
13-
broadcasts: broadcastsType.isRequired
14-
}
15-
16-
static propTypes = {
17-
channel: PropTypes.string.isRequired,
18-
children: PropTypes.func.isRequired
10+
broadcasts: React.PropTypes.object
1911
}
2012

2113
state = {
@@ -48,4 +40,11 @@ class Subscriber extends React.Component {
4840
}
4941
}
5042

43+
if (__DEV__) {
44+
Subscriber.propTypes = {
45+
channel: PropTypes.string.isRequired,
46+
children: PropTypes.func.isRequired
47+
}
48+
}
49+
5150
export default Subscriber

modules/__tests__/integration-test.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*eslint-env mocha*/
2+
/*eslint react/prop-types: 0*/
3+
import React from 'react'
4+
import { render } from 'react-dom'
5+
import expect from 'expect'
6+
import { EventEmitter } from 'events'
7+
import { Subscriber, Broadcast } from '../index'
8+
9+
it('works', (done) => {
10+
11+
const steps = []
12+
const execNextStep = () => steps.shift()()
13+
const div = document.createElement('div')
14+
15+
// so we can trigger rerenders in ComponentWithStateForDescendants
16+
const emitter = new EventEmitter()
17+
18+
// A component has some state it wants to make available to descendants
19+
// 1. We create our Emitter and Subscriber components
20+
const CheeseEmitter = ({ cheese, children }) =>
21+
<Broadcast channel="cheese" value={cheese} children={children}/>
22+
const CheeseSubscriber = ({ children }) =>
23+
<Subscriber channel="cheese">{(value) => children(value)}</Subscriber>
24+
25+
class ComponentWithStateForDescendants extends React.Component {
26+
constructor() {
27+
super()
28+
this.state = { cheese: 'cheddar' }
29+
emitter.on('CHEESE', (cheese) => {
30+
this.setState({ cheese })
31+
})
32+
}
33+
34+
componentDidMount = execNextStep
35+
36+
componentDidUpdate = execNextStep
37+
38+
render() {
39+
// 2. render the Emitter in the component w/ state and pass
40+
// it the value we want accessible through context as a prop
41+
// by the same name as when the Emitter was created
42+
return (
43+
<CheeseEmitter cheese={this.state.cheese}>
44+
{this.props.children}
45+
</CheeseEmitter>
46+
)
47+
}
48+
}
49+
50+
let actualCheese = null
51+
52+
steps.push(
53+
() => {
54+
expect(actualCheese).toBe('cheddar')
55+
emitter.emit('CHEESE', 'gouda')
56+
},
57+
() => {
58+
expect(actualCheese).toBe('gouda')
59+
done()
60+
}
61+
)
62+
63+
// 3. Render a <Subscriber> that calls back when the Emitter
64+
// gets a new value in its prop
65+
render((
66+
<ComponentWithStateForDescendants>
67+
<CheeseSubscriber>
68+
{(cheese) => {
69+
actualCheese = cheese
70+
return null
71+
}}
72+
</CheeseSubscriber>
73+
</ComponentWithStateForDescendants>
74+
), div)
75+
})
76+

modules/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
export Broadcast from './Broadcast'
22
export Subscriber from './Subscriber'
33

4-
export * as PropTypes from './PropTypes'

package.json

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
"name": "react-broadcast",
33
"version": "0.0.3",
44
"description": "Broadcast state changes to React components deep in the hierarchy",
5-
"author": "Michael Jackson",
5+
"authors": [
6+
"Michael Jackson",
7+
"Ryan Florence"
8+
],
69
"license": "MIT",
710
"scripts": {
811
"build": "node ./scripts/build.js",
@@ -11,7 +14,7 @@
1114
"build-min": "webpack -p modules/index.js umd/react-broadcast.min.js",
1215
"prepublish": "node ./scripts/build.js",
1316
"release": "node ./scripts/release.js",
14-
"test": "npm run lint",
17+
"test": "npm run lint && karma start",
1518
"lint": "eslint modules"
1619
},
1720
"dependencies": {
@@ -21,22 +24,32 @@
2124
"react": "15.x"
2225
},
2326
"devDependencies": {
24-
"babel-cli": "^6.16.0",
25-
"babel-core": "^6.16.0",
26-
"babel-eslint": "^7.0.0",
27-
"babel-loader": "^6.2.5",
28-
"babel-plugin-dev-expression": "^0.2.1",
29-
"babel-preset-es2015": "^6.16.0",
30-
"babel-preset-es2015-loose": "^8.0.0",
31-
"babel-preset-react": "^6.16.0",
32-
"babel-preset-stage-1": "^6.16.0",
33-
"eslint": "^3.7.0",
34-
"eslint-plugin-import": "^2.0.0",
35-
"eslint-plugin-react": "^6.3.0",
27+
"babel-cli": "^6.10.1",
28+
"babel-core": "^6.9.1",
29+
"babel-eslint": "^6.0.4",
30+
"babel-loader": "^6.2.4",
31+
"babel-preset-es2015": "^6.9.0",
32+
"babel-preset-es2015-loose": "^7.0.0",
33+
"babel-preset-react": "^6.5.0",
34+
"babel-preset-stage-1": "^6.5.0",
35+
"eslint": "^3.3.1",
36+
"eslint-plugin-import": "^1.8.1",
37+
"eslint-plugin-react": "^6.1.2",
38+
"expect": "^1.20.1",
3639
"gzip-size": "^3.0.0",
3740
"in-publish": "^2.0.0",
38-
"pretty-bytes": "^4.0.2",
41+
"karma": "^1.2.0",
42+
"karma-browserstack-launcher": "^1.0.1",
43+
"karma-chrome-launcher": "^1.0.1",
44+
"karma-mocha": "^1.0.1",
45+
"karma-mocha-reporter": "^2.0.4",
46+
"karma-sourcemap-loader": "^0.3.7",
47+
"karma-webpack": "^1.7.0",
48+
"mocha": "^3.0.2",
49+
"pretty-bytes": "^4.0.0",
50+
"react": "^15.3.0",
51+
"react-dom": "^15.3.0",
3952
"readline-sync": "^1.4.4",
40-
"webpack": "^1.13.2"
53+
"webpack": "1.13.1"
4154
}
4255
}

tests.webpack.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const context = require.context('./modules', true, /-test\.js$/)
2+
context.keys().forEach(context)
3+

0 commit comments

Comments
 (0)