-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #177 from tkloht/react16
React16
- Loading branch information
Showing
12 changed files
with
8,229 additions
and
82 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"presets": ["stage-0", "es2015", "react"], | ||
"plugins": [ | ||
["transform-class-properties"], | ||
], | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = 'test-file-stub'; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import React from 'react'; | ||
|
||
const Intl = require.requireActual('react-intl'); | ||
|
||
// Here goes intl context injected into component, feel free to extend | ||
const intl = { | ||
formatMessage: ({defaultMessage}) => defaultMessage | ||
}; | ||
|
||
Intl.injectIntl = (Node) => { | ||
const renderWrapped = props => <Node {...props} intl={intl} />; | ||
renderWrapped.displayName = Node.displayName | ||
|| Node.name | ||
|| 'Component'; | ||
return renderWrapped; | ||
}; | ||
|
||
module.exports = Intl; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = {}; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"rules": { | ||
"max-len": 0, | ||
}, | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/* eslint-env mocha*/ | ||
import VideoCover from '../index'; | ||
import VideoCoverFallback from '../VideoCoverFallback'; | ||
|
||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
|
||
function setUserAgent(userAgent) { | ||
const originalNavigator = window.navigator; | ||
/* eslint-disable no-native-reassign, no-proto, no-underscore-dangle */ | ||
navigator = {}; | ||
navigator.__proto__ = originalNavigator; | ||
navigator.__defineGetter__('userAgent', () => userAgent); | ||
/* eslint-enable no-native-reassign, no-proto, no-underscore-dangle */ | ||
} | ||
|
||
describe('VideoCover', () => { | ||
it('should render a video tag', () => { | ||
const wrapper = shallow(<VideoCover />); | ||
const video = wrapper.find('video'); | ||
expect(video).toExist(); | ||
}); | ||
|
||
it('should not render Fallback component by default', () => { | ||
const wrapper = shallow(<VideoCover />); | ||
expect(wrapper.find(VideoCoverFallback)).not.toExist(); | ||
}); | ||
|
||
it('should set classname of <video/> according prop', () => { | ||
const className = 'WhateverClassNameYouWant EvenMultipleClassNames'; | ||
const wrapper = shallow(<VideoCover className={className} />); | ||
expect(wrapper).toHaveClassName('WhateverClassNameYouWant'); | ||
expect(wrapper).toHaveClassName('EvenMultipleClassNames'); | ||
}); | ||
|
||
it('should render Fallback component if forceFallback prop is set', () => { | ||
const wrapper = shallow(<VideoCover forceFallback />); | ||
expect(wrapper.find(VideoCoverFallback)).toExist(); | ||
}); | ||
|
||
describe('styles without fallback', () => { | ||
it('should have width and height 100% by default', () => { | ||
const wrapper = shallow(<VideoCover />); | ||
expect(wrapper).toHaveStyle('height', '100%'); | ||
expect(wrapper).toHaveStyle('width', '100%'); | ||
}); | ||
it('should have any additional styles passed in via style-prop', () => { | ||
const wrapper = shallow(<VideoCover />); | ||
expect(wrapper).not.toHaveStyle('background-color'); | ||
expect(wrapper).not.toHaveStyle('color'); | ||
expect(wrapper).not.toHaveStyle('line-height'); | ||
const nextWrapper = wrapper.setProps({ | ||
style: { | ||
backgroundColor: 'red', | ||
color: 'teal', | ||
lineHeight: 10, | ||
}, | ||
}); | ||
expect(wrapper).toHaveStyle({ | ||
backgroundColor: 'red', | ||
color: 'teal', | ||
lineHeight: 10, | ||
}); | ||
}); | ||
it('should be possible to override width and height props', () => { | ||
const wrapper = shallow(<VideoCover style={{ width: '50%', height: '50%' }} />); | ||
expect(wrapper).toHaveStyle('height', '50%'); | ||
expect(wrapper).toHaveStyle('width', '50%'); | ||
}); | ||
it('should have object-fit set to cover', () => { | ||
const wrapper = shallow(<VideoCover />); | ||
expect(wrapper).toHaveStyle('objectFit', 'cover'); | ||
}); | ||
it('should not be possible to override object-fit', () => { | ||
const wrapper = shallow(<VideoCover style={{ objectFit: 'contain' }} />); | ||
expect(wrapper).toHaveStyle('objectFit', 'cover'); | ||
}); | ||
}); | ||
|
||
// TODO: couldn't figure out how to mock the useragent with jest/jsdom | ||
// re-enable these tests when fixed (see setUserAgent()) | ||
describe.skip('UserAgent', () => { | ||
/* eslint-disable max-len */ | ||
const originalNavigator = window.navigator; | ||
const userAgents = [ | ||
{ | ||
name: 'Trident', | ||
needsFallback: true, | ||
value: `Mozilla/5.0(compatible; MSIE 10.0; | ||
WindowsNT 6.2; Win64; x64; Trident/6.0)`, | ||
}, | ||
{ | ||
name: 'Edge', | ||
needsFallback: true, | ||
value: `Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36 | ||
(KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36 Edge/12.0`, | ||
}, | ||
{ | ||
name: 'Safari', | ||
needsFallback: false, | ||
value: `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) | ||
AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17`, | ||
}, | ||
{ | ||
name: 'Chrome', | ||
needsFallback: false, | ||
value: `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) | ||
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36`, | ||
}, | ||
{ | ||
name: 'Firefox', | ||
needsFallback: false, | ||
value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:44.0) Gecko/20100101 Firefox/44.0', | ||
}, | ||
]; | ||
|
||
afterEach(() => { | ||
// reset to original navigator after each test | ||
window.navigator = originalNavigator; | ||
}); | ||
|
||
/* generate tests for some known userAgents */ | ||
userAgents.forEach(({ needsFallback, name, value }) => { | ||
it(`should ${ | ||
needsFallback ? '' : 'NOT' | ||
} render Fallback if ${name} userAgent is used`, () => { | ||
setUserAgent(value); | ||
const wrapper = shallow(<VideoCover />); | ||
if (needsFallback) { | ||
expect(wrapper.find(VideoCoverFallback)).toExist(); | ||
} else { | ||
expect(wrapper.find(VideoCoverFallback)).not.toExist(); | ||
} | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
import VideoCoverFallback from '../VideoCoverFallback'; | ||
|
||
import React from 'react'; | ||
import { shallow, mount } from 'enzyme'; | ||
|
||
describe('VideoCoverFallback', () => { | ||
it('should update container ratio when mounted', () => { | ||
const spy = jest.fn(); | ||
class WithSpy extends VideoCoverFallback { | ||
updateContainerRatio = spy; | ||
} | ||
mount(<WithSpy />); | ||
expect(spy).toBeCalled(); | ||
}); | ||
|
||
it('should call onFallbackDidMount prop when mounted', () => { | ||
const spy = jest.fn(); | ||
mount(<VideoCoverFallback onFallbackDidMount={spy} />); | ||
expect(spy).toBeCalled(); | ||
}); | ||
|
||
it('should pass this.updateContainerRatio as parameter in onFallbackWillUnmount', () => { | ||
let resizeNotifier; | ||
const wrapper = mount(<VideoCoverFallback | ||
onFallbackDidMount={result => { | ||
resizeNotifier = result; | ||
}} | ||
/>); | ||
expect(resizeNotifier).toEqual(wrapper.instance().updateContainerRatio); | ||
}); | ||
|
||
it('should initialize window-resize eventlisteners if props.remeasureOnWindowResize is set', () => { | ||
const spy = jest.fn(); | ||
class WithSpy extends VideoCoverFallback { | ||
initEventListeners = spy; | ||
} | ||
mount(<WithSpy remeasureOnWindowResize />); | ||
expect(spy).toBeCalled(); | ||
}); | ||
|
||
it('should NOT initialize window-resize eventlisteners if props.remeasureOnWindowResize is not set', () => { | ||
const spy = jest.fn(); | ||
class WithSpy extends VideoCoverFallback { | ||
initEventListeners = spy; | ||
} | ||
mount(<WithSpy />); | ||
expect(spy).not.toBeCalled(); | ||
}); | ||
|
||
it('should remove eventlisteners before unmount', () => { | ||
const spy = jest.fn(); | ||
class WithSpy extends VideoCoverFallback { | ||
removeEventListeners = spy; | ||
} | ||
const wrapper = mount(<WithSpy />); | ||
wrapper.unmount(); | ||
expect(spy).toBeCalled(); | ||
}); | ||
|
||
it('should add/remove eventlisteners if props.remeasureOnWindowResize changes', () => { | ||
const addSpy = jest.fn(); | ||
const removeSpy = jest.fn(); | ||
class WithSpy extends VideoCoverFallback { | ||
initEventListeners = addSpy; | ||
removeEventListeners = removeSpy; | ||
} | ||
const wrapper = mount(<WithSpy />); | ||
expect(addSpy).not.toBeCalled(); | ||
expect(removeSpy).not.toBeCalled(); | ||
wrapper.setProps({ remeasureOnWindowResize: true }); | ||
expect(addSpy).toBeCalled(); | ||
expect(removeSpy).not.toBeCalled(); | ||
wrapper.setProps({ remeasureOnWindowResize: false }); | ||
expect(addSpy).toBeCalled(); | ||
expect(removeSpy).toBeCalled(); | ||
}); | ||
|
||
it('should render a video tag inside a container-div', () => { | ||
const wrapper = shallow(<VideoCoverFallback />); | ||
expect(wrapper.find('div')).toExist(); | ||
expect(wrapper.find('div video')).toExist(); | ||
}); | ||
|
||
it('should pass props.className to the container-div', () => { | ||
const wrapper = shallow(<VideoCoverFallback className="some-classname" />); | ||
expect(wrapper).toHaveClassName('some-classname'); | ||
}); | ||
|
||
it('should invoke updateVideoRatio on loadedData media event', () => { | ||
const spy = jest.fn(); | ||
class WithSpy extends VideoCoverFallback { | ||
updateVideoRatio = spy; | ||
} | ||
const wrapper = shallow(<WithSpy />); | ||
const video = wrapper.find('video'); | ||
video.simulate('loadedData', { | ||
target: { | ||
videoWidth: 50, | ||
videoHeight: 50, | ||
}, | ||
}); | ||
expect(spy).toBeCalledWith(50, 50); | ||
}); | ||
|
||
it('should apply all props.videoOptions to the video tag', () => { | ||
const wrapper = shallow(<VideoCoverFallback | ||
videoOptions={{ | ||
src: 'http://some-video-url.mp4', | ||
}} | ||
/>); | ||
expect(wrapper.find('video')).toHaveProp('src', 'http://some-video-url.mp4'); | ||
}); | ||
|
||
describe('container-styles', () => { | ||
it('should apply props.style to the container-div', () => { | ||
const wrapper = shallow(<VideoCoverFallback | ||
style={{ | ||
backgroundColor: 'teal', | ||
lineHeight: '100px', | ||
}} | ||
/>); | ||
expect(wrapper).toHaveStyle('backgroundColor', 'teal'); | ||
expect(wrapper).toHaveStyle('lineHeight', '100px'); | ||
}); | ||
|
||
it('should set width and height to 100% by default', () => { | ||
const wrapper = shallow(<VideoCoverFallback />); | ||
expect(wrapper).toHaveStyle('height', '100%'); | ||
expect(wrapper).toHaveStyle('width', '100%'); | ||
}); | ||
|
||
it('should be possible to override width and height via props.style', () => { | ||
const wrapper = shallow(<VideoCoverFallback style={{ width: '50%', height: '50%' }} />); | ||
expect(wrapper).toHaveStyle('height', '50%'); | ||
expect(wrapper).toHaveStyle('width', '50%'); | ||
}); | ||
|
||
it('should set position relative and overflow: hidden', () => { | ||
const wrapper = shallow(<VideoCoverFallback />); | ||
expect(wrapper).toHaveStyle('position', 'relative'); | ||
expect(wrapper).toHaveStyle('overflow', 'hidden'); | ||
}); | ||
|
||
it('should not be possible to override position and overflow', () => { | ||
const wrapper = shallow(<VideoCoverFallback | ||
style={{ | ||
position: 'fixed', | ||
overflow: 'scroll', | ||
}} | ||
/>); | ||
expect(wrapper).toHaveStyle('position', 'relative'); | ||
expect(wrapper).toHaveStyle('overflow', 'hidden'); | ||
}); | ||
}); | ||
|
||
// todo: maybe use generated test-data for this? | ||
describe('video-styles', () => { | ||
it('should have width auto, height 100% if innerRatio > outerRatio', () => { | ||
const wrapper = shallow(<VideoCoverFallback />); | ||
wrapper.setState({ | ||
innerRatio: 5, | ||
outerRatio: 3, | ||
}); | ||
expect(wrapper.find('video')).toHaveStyle('width', 'auto'); | ||
expect(wrapper.find('video')).toHaveStyle('height', '100%'); | ||
}); | ||
it('should have width 100%, height auto if innerRatio <= outerRatio', () => { | ||
const wrapper = shallow(<VideoCoverFallback />); | ||
wrapper.setState({ | ||
innerRatio: 3, | ||
outerRatio: 5, | ||
}); | ||
expect(wrapper.find('video')).toHaveStyle('width', '100%'); | ||
expect(wrapper.find('video')).toHaveStyle('height', 'auto'); | ||
}); | ||
}); | ||
|
||
describe('updateContainerRatio()', () => { | ||
it('should set state.outerRatio to ratio of container width/height', () => { | ||
const mockRef = { | ||
getBoundingClientRect: () => { | ||
const result = { | ||
width: 4, | ||
height: 5, | ||
}; | ||
return result; | ||
}, | ||
}; | ||
class WithRef extends VideoCoverFallback { | ||
containerRef = mockRef; | ||
} | ||
const wrapper = shallow(<WithRef />); | ||
wrapper.instance().updateContainerRatio(); | ||
expect(wrapper).toHaveState('outerRatio', 4 / 5); | ||
}); | ||
}); | ||
|
||
describe('updateVideoRatio()', () => { | ||
it('should set state.innerRatio to ratio of video width/height', () => { | ||
const wrapper = shallow(<VideoCoverFallback />); | ||
expect(wrapper).toHaveState('innerRatio', undefined); | ||
wrapper.instance().updateVideoRatio(4, 5); | ||
expect(wrapper).toHaveState('innerRatio', 4 / 5); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.