Use enzyme for Image tests

This commit is contained in:
Nicolas Gallagher
2016-06-23 13:50:28 -07:00
parent 7f94c4bf06
commit 4516c72296
2 changed files with 140 additions and 120 deletions
+89 -66
View File
@@ -1,55 +1,56 @@
/* eslint-env mocha */ /* eslint-env mocha */
import * as utils from '../../../modules/specHelpers' import { mount, shallow } from 'enzyme'
import assert from 'assert' import assert from 'assert'
import React from 'react' import React from 'react'
import flattenStyle from '../../../apis/StyleSheet/flattenStyle' import StyleSheet from '../../../apis/StyleSheet'
import Image from '../' import Image from '../'
const getStyleBackgroundSize = (element) => flattenStyle(element.props.style).backgroundSize
suite('components/Image', () => { suite('components/Image', () => {
test('default accessibility', () => { test('sets correct accessibility role"', () => {
const dom = utils.renderToDOM(<Image />) const image = shallow(<Image />)
assert.equal(dom.getAttribute('role'), 'img') assert.equal(image.prop('accessibilityRole'), 'img')
}) })
test('prop "accessibilityLabel"', () => { test('prop "accessibilityLabel"', () => {
const accessibilityLabel = 'accessibilityLabel' const accessibilityLabel = 'accessibilityLabel'
const result = utils.shallowRender(<Image accessibilityLabel={accessibilityLabel} />) const image = shallow(<Image accessibilityLabel={accessibilityLabel} />)
assert.equal(result.props.accessibilityLabel, accessibilityLabel) assert.equal(image.prop('accessibilityLabel'), accessibilityLabel)
}) })
test('prop "accessible"', () => { test('prop "accessible"', () => {
const accessible = false const accessible = false
const result = utils.shallowRender(<Image accessible={accessible} />) const image = shallow(<Image accessible={accessible} />)
assert.equal(result.props.accessible, accessible) assert.equal(image.prop('accessible'), accessible)
}) })
test('prop "children"') test('prop "children"', () => {
const children = <div className='unique' />
test('prop "defaultSource"', () => { const wrapper = shallow(<Image>{children}</Image>)
const defaultSource = { uri: 'https://google.com/favicon.ico' } assert.equal(wrapper.contains(children), true)
const dom = utils.renderToDOM(<Image defaultSource={defaultSource} />)
const backgroundImage = dom.style.backgroundImage
assert(backgroundImage.indexOf(defaultSource.uri) > -1)
}) })
test('prop "defaultSource" with string value"', () => { suite('prop "defaultSource"', () => {
// emulate require-ed asset test('sets background image when value is an object', () => {
const defaultSource = 'https://google.com/favicon.ico' const defaultSource = { uri: 'https://google.com/favicon.ico' }
const dom = utils.renderToDOM(<Image defaultSource={defaultSource} />) const image = shallow(<Image defaultSource={defaultSource} />)
const backgroundImage = dom.style.backgroundImage const backgroundImage = StyleSheet.flatten(image.prop('style')).backgroundImage
assert(backgroundImage.indexOf(defaultSource) > -1) assert(backgroundImage.indexOf(defaultSource.uri) > -1)
})
test('sets background image when value is a string', () => {
// emulate require-ed asset
const defaultSource = 'https://google.com/favicon.ico'
const image = shallow(<Image defaultSource={defaultSource} />)
const backgroundImage = StyleSheet.flatten(image.prop('style')).backgroundImage
assert(backgroundImage.indexOf(defaultSource) > -1)
})
}) })
test('prop "onError"', function (done) { test('prop "onError"', function (done) {
this.timeout(5000) this.timeout(5000)
utils.render(<Image mount(<Image onError={onError} source={{ uri: 'https://google.com/favicon.icox' }} />)
onError={onError}
source={{ uri: 'https://google.com/favicon.icox' }}
/>)
function onError(e) { function onError(e) {
assert.equal(e.nativeEvent.type, 'error') assert.equal(e.nativeEvent.type, 'error')
done() done()
@@ -58,82 +59,104 @@ suite('components/Image', () => {
test('prop "onLoad"', function (done) { test('prop "onLoad"', function (done) {
this.timeout(5000) this.timeout(5000)
utils.render(<Image onLoad={onLoad} source={{ uri: 'https://google.com/favicon.ico' }} />) const image = mount(<Image onLoad={onLoad} source={{ uri: 'https://google.com/favicon.ico' }} />)
function onLoad(e) { function onLoad(e) {
assert.equal(e.nativeEvent.type, 'load') assert.equal(e.nativeEvent.type, 'load')
const backgroundImage = StyleSheet.flatten(image.ref('root').prop('style')).backgroundImage
assert.notDeepEqual(backgroundImage, undefined)
done() done()
} }
}) })
test('prop "onLoadEnd"') test('prop "onLoadEnd"', function (done) {
this.timeout(5000)
const image = mount(<Image onLoadEnd={onLoadEnd} source={{ uri: 'https://google.com/favicon.ico' }} />)
function onLoadEnd() {
assert.ok(true)
const backgroundImage = StyleSheet.flatten(image.ref('root').prop('style')).backgroundImage
assert.notDeepEqual(backgroundImage, undefined)
done()
}
})
test('prop "onLoadStart"') test('prop "onLoadStart"', function (done) {
this.timeout(5000)
mount(<Image onLoadStart={onLoadStart} source={{ uri: 'https://google.com/favicon.ico' }} />)
function onLoadStart() {
assert.ok(true)
done()
}
})
suite('prop "resizeMode"', () => { suite('prop "resizeMode"', () => {
const getBackgroundSize = (image) => StyleSheet.flatten(image.prop('style')).backgroundSize
test('value "contain"', () => { test('value "contain"', () => {
const result = utils.shallowRender(<Image resizeMode={Image.resizeMode.contain} />) const image = shallow(<Image resizeMode={Image.resizeMode.contain} />)
assert.equal(getStyleBackgroundSize(result), 'contain') assert.equal(getBackgroundSize(image), 'contain')
}) })
test('value "cover"', () => { test('value "cover"', () => {
const result = utils.shallowRender(<Image resizeMode={Image.resizeMode.cover} />) const image = shallow(<Image resizeMode={Image.resizeMode.cover} />)
assert.equal(getStyleBackgroundSize(result), 'cover') assert.equal(getBackgroundSize(image), 'cover')
}) })
test('value "none"', () => { test('value "none"', () => {
const result = utils.shallowRender(<Image resizeMode={Image.resizeMode.none} />) const image = shallow(<Image resizeMode={Image.resizeMode.none} />)
assert.equal(getStyleBackgroundSize(result), 'auto') assert.equal(getBackgroundSize(image), 'auto')
}) })
test('value "stretch"', () => { test('value "stretch"', () => {
const result = utils.shallowRender(<Image resizeMode={Image.resizeMode.stretch} />) const image = shallow(<Image resizeMode={Image.resizeMode.stretch} />)
assert.equal(getStyleBackgroundSize(result), '100% 100%') assert.equal(getBackgroundSize(image), '100% 100%')
}) })
test('no value', () => { test('no value', () => {
const result = utils.shallowRender(<Image />) const image = shallow(<Image />)
assert.equal(getStyleBackgroundSize(result), 'cover') assert.equal(getBackgroundSize(image), 'cover')
}) })
}) })
test('prop "source"', function (done) { suite('prop "source"', function () {
this.timeout(5000) this.timeout(5000)
const source = { uri: 'https://google.com/favicon.ico' }
utils.render(<Image onLoad={onLoad} source={source} />)
function onLoad(e) {
const src = e.nativeEvent.target.src
assert.equal(src, source.uri)
done()
}
})
test('prop "source" with string value', function (done) { test('sets background image when value is an object', (done) => {
this.timeout(5000) const source = { uri: 'https://google.com/favicon.ico' }
// emulate require-ed asset mount(<Image onLoad={onLoad} source={source} />)
const source = 'https://google.com/favicon.ico' function onLoad(e) {
utils.render(<Image onLoad={onLoad} source={source} />) const src = e.nativeEvent.target.src
function onLoad(e) { assert.equal(src, source.uri)
const src = e.nativeEvent.target.src done()
assert.equal(src, source) }
done() })
}
test('sets background image when value is a string', (done) => {
// emulate require-ed asset
const source = 'https://google.com/favicon.ico'
mount(<Image onLoad={onLoad} source={source} />)
function onLoad(e) {
const src = e.nativeEvent.target.src
assert.equal(src, source)
done()
}
})
}) })
suite('prop "style"', () => { suite('prop "style"', () => {
test('converts "resizeMode" property', () => { test('converts "resizeMode" property', () => {
const result = utils.shallowRender(<Image style={{ resizeMode: Image.resizeMode.contain }} />) const image = shallow(<Image style={{ resizeMode: Image.resizeMode.contain }} />)
assert.equal(getStyleBackgroundSize(result), 'contain') assert.equal(StyleSheet.flatten(image.prop('style')).backgroundSize, 'contain')
}) })
test('removes "resizeMode" property', () => { test('removes "resizeMode" property', () => {
const result = utils.shallowRender(<Image style={{ resizeMode: Image.resizeMode.contain }} />) const image = shallow(<Image style={{ resizeMode: Image.resizeMode.contain }} />)
assert.equal(flattenStyle(result.props.style).resizeMode, undefined) assert.equal(StyleSheet.flatten(image.prop('style')).resizeMode, undefined)
}) })
}) })
test('prop "testID"', () => { test('prop "testID"', () => {
const testID = 'testID' const testID = 'testID'
const result = utils.shallowRender(<Image testID={testID} />) const image = shallow(<Image testID={testID} />)
assert.equal(result.props.testID, testID) assert.equal(image.prop('testID'), testID)
}) })
}) })
+51 -54
View File
@@ -49,61 +49,7 @@ class Image extends Component {
constructor(props, context) { constructor(props, context) {
super(props, context) super(props, context)
const uri = resolveAssetSource(props.source) const uri = resolveAssetSource(props.source)
// state
this.state = { status: uri ? STATUS_PENDING : STATUS_IDLE } this.state = { status: uri ? STATUS_PENDING : STATUS_IDLE }
// autobinding
this._onError = this._onError.bind(this)
this._onLoad = this._onLoad.bind(this)
}
_createImageLoader() {
const uri = resolveAssetSource(this.props.source)
this._destroyImageLoader()
this.image = new window.Image()
this.image.onerror = this._onError
this.image.onload = this._onLoad
this.image.src = uri
this._onLoadStart()
}
_destroyImageLoader() {
if (this.image) {
this.image.onerror = null
this.image.onload = null
this.image = null
}
}
_onError(e) {
const { onError } = this.props
const event = { nativeEvent: e }
this._destroyImageLoader()
this.setState({ status: STATUS_ERRORED })
this._onLoadEnd()
if (onError) onError(event)
}
_onLoad(e) {
const { onLoad } = this.props
const event = { nativeEvent: e }
this._destroyImageLoader()
this.setState({ status: STATUS_LOADED })
if (onLoad) onLoad(event)
this._onLoadEnd()
}
_onLoadEnd() {
const { onLoadEnd } = this.props
if (onLoadEnd) onLoadEnd()
}
_onLoadStart() {
const { onLoadStart } = this.props
this.setState({ status: STATUS_LOADING })
if (onLoadStart) onLoadStart()
} }
componentDidMount() { componentDidMount() {
@@ -162,6 +108,7 @@ class Image extends Component {
accessibilityLabel={accessibilityLabel} accessibilityLabel={accessibilityLabel}
accessibilityRole='img' accessibilityRole='img'
accessible={accessible} accessible={accessible}
ref='root'
style={[ style={[
styles.initial, styles.initial,
style, style,
@@ -177,6 +124,56 @@ class Image extends Component {
</View> </View>
) )
} }
_createImageLoader() {
const uri = resolveAssetSource(this.props.source)
this._destroyImageLoader()
this.image = new window.Image()
this.image.onerror = this._onError
this.image.onload = this._onLoad
this.image.src = uri
this._onLoadStart()
}
_destroyImageLoader() {
if (this.image) {
this.image.onerror = null
this.image.onload = null
this.image = null
}
}
_onError = (e) => {
const { onError } = this.props
const event = { nativeEvent: e }
this._destroyImageLoader()
this.setState({ status: STATUS_ERRORED })
this._onLoadEnd()
if (onError) onError(event)
}
_onLoad = (e) => {
const { onLoad } = this.props
const event = { nativeEvent: e }
this._destroyImageLoader()
this.setState({ status: STATUS_LOADED })
if (onLoad) onLoad(event)
this._onLoadEnd()
}
_onLoadEnd() {
const { onLoadEnd } = this.props
if (onLoadEnd) onLoadEnd()
}
_onLoadStart() {
const { onLoadStart } = this.props
this.setState({ status: STATUS_LOADING })
if (onLoadStart) onLoadStart()
}
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({