diff --git a/src/components/Image/__tests__/index-test.js b/src/components/Image/__tests__/index-test.js index c4831a0f..4b53b9e8 100644 --- a/src/components/Image/__tests__/index-test.js +++ b/src/components/Image/__tests__/index-test.js @@ -1,55 +1,56 @@ /* eslint-env mocha */ -import * as utils from '../../../modules/specHelpers' +import { mount, shallow } from 'enzyme' import assert from 'assert' import React from 'react' -import flattenStyle from '../../../apis/StyleSheet/flattenStyle' +import StyleSheet from '../../../apis/StyleSheet' import Image from '../' -const getStyleBackgroundSize = (element) => flattenStyle(element.props.style).backgroundSize - suite('components/Image', () => { - test('default accessibility', () => { - const dom = utils.renderToDOM() - assert.equal(dom.getAttribute('role'), 'img') + test('sets correct accessibility role"', () => { + const image = shallow() + assert.equal(image.prop('accessibilityRole'), 'img') }) test('prop "accessibilityLabel"', () => { const accessibilityLabel = 'accessibilityLabel' - const result = utils.shallowRender() - assert.equal(result.props.accessibilityLabel, accessibilityLabel) + const image = shallow() + assert.equal(image.prop('accessibilityLabel'), accessibilityLabel) }) test('prop "accessible"', () => { const accessible = false - const result = utils.shallowRender() - assert.equal(result.props.accessible, accessible) + const image = shallow() + assert.equal(image.prop('accessible'), accessible) }) - test('prop "children"') - - test('prop "defaultSource"', () => { - const defaultSource = { uri: 'https://google.com/favicon.ico' } - const dom = utils.renderToDOM() - const backgroundImage = dom.style.backgroundImage - assert(backgroundImage.indexOf(defaultSource.uri) > -1) + test('prop "children"', () => { + const children =
+ const wrapper = shallow({children}) + assert.equal(wrapper.contains(children), true) }) - test('prop "defaultSource" with string value"', () => { - // emulate require-ed asset - const defaultSource = 'https://google.com/favicon.ico' - const dom = utils.renderToDOM() - const backgroundImage = dom.style.backgroundImage - assert(backgroundImage.indexOf(defaultSource) > -1) + suite('prop "defaultSource"', () => { + test('sets background image when value is an object', () => { + const defaultSource = { uri: 'https://google.com/favicon.ico' } + const image = shallow() + const backgroundImage = StyleSheet.flatten(image.prop('style')).backgroundImage + 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() + const backgroundImage = StyleSheet.flatten(image.prop('style')).backgroundImage + assert(backgroundImage.indexOf(defaultSource) > -1) + }) }) test('prop "onError"', function (done) { this.timeout(5000) - utils.render() + mount() function onError(e) { assert.equal(e.nativeEvent.type, 'error') done() @@ -58,82 +59,104 @@ suite('components/Image', () => { test('prop "onLoad"', function (done) { this.timeout(5000) - utils.render() + const image = mount() function onLoad(e) { assert.equal(e.nativeEvent.type, 'load') + const backgroundImage = StyleSheet.flatten(image.ref('root').prop('style')).backgroundImage + assert.notDeepEqual(backgroundImage, undefined) done() } }) - test('prop "onLoadEnd"') + test('prop "onLoadEnd"', function (done) { + this.timeout(5000) + const image = mount() + 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() + function onLoadStart() { + assert.ok(true) + done() + } + }) suite('prop "resizeMode"', () => { + const getBackgroundSize = (image) => StyleSheet.flatten(image.prop('style')).backgroundSize + test('value "contain"', () => { - const result = utils.shallowRender() - assert.equal(getStyleBackgroundSize(result), 'contain') + const image = shallow() + assert.equal(getBackgroundSize(image), 'contain') }) test('value "cover"', () => { - const result = utils.shallowRender() - assert.equal(getStyleBackgroundSize(result), 'cover') + const image = shallow() + assert.equal(getBackgroundSize(image), 'cover') }) test('value "none"', () => { - const result = utils.shallowRender() - assert.equal(getStyleBackgroundSize(result), 'auto') + const image = shallow() + assert.equal(getBackgroundSize(image), 'auto') }) test('value "stretch"', () => { - const result = utils.shallowRender() - assert.equal(getStyleBackgroundSize(result), '100% 100%') + const image = shallow() + assert.equal(getBackgroundSize(image), '100% 100%') }) test('no value', () => { - const result = utils.shallowRender() - assert.equal(getStyleBackgroundSize(result), 'cover') + const image = shallow() + assert.equal(getBackgroundSize(image), 'cover') }) }) - test('prop "source"', function (done) { + suite('prop "source"', function () { this.timeout(5000) - const source = { uri: 'https://google.com/favicon.ico' } - utils.render() - function onLoad(e) { - const src = e.nativeEvent.target.src - assert.equal(src, source.uri) - done() - } - }) - test('prop "source" with string value', function (done) { - this.timeout(5000) - // emulate require-ed asset - const source = 'https://google.com/favicon.ico' - utils.render() - function onLoad(e) { - const src = e.nativeEvent.target.src - assert.equal(src, source) - done() - } + test('sets background image when value is an object', (done) => { + const source = { uri: 'https://google.com/favicon.ico' } + mount() + function onLoad(e) { + const src = e.nativeEvent.target.src + assert.equal(src, source.uri) + done() + } + }) + + test('sets background image when value is a string', (done) => { + // emulate require-ed asset + const source = 'https://google.com/favicon.ico' + mount() + function onLoad(e) { + const src = e.nativeEvent.target.src + assert.equal(src, source) + done() + } + }) }) suite('prop "style"', () => { test('converts "resizeMode" property', () => { - const result = utils.shallowRender() - assert.equal(getStyleBackgroundSize(result), 'contain') + const image = shallow() + assert.equal(StyleSheet.flatten(image.prop('style')).backgroundSize, 'contain') }) test('removes "resizeMode" property', () => { - const result = utils.shallowRender() - assert.equal(flattenStyle(result.props.style).resizeMode, undefined) + const image = shallow() + assert.equal(StyleSheet.flatten(image.prop('style')).resizeMode, undefined) }) }) test('prop "testID"', () => { const testID = 'testID' - const result = utils.shallowRender() - assert.equal(result.props.testID, testID) + const image = shallow() + assert.equal(image.prop('testID'), testID) }) }) diff --git a/src/components/Image/index.js b/src/components/Image/index.js index 66a11533..cbc70e66 100644 --- a/src/components/Image/index.js +++ b/src/components/Image/index.js @@ -49,61 +49,7 @@ class Image extends Component { constructor(props, context) { super(props, context) const uri = resolveAssetSource(props.source) - // state 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() { @@ -162,6 +108,7 @@ class Image extends Component { accessibilityLabel={accessibilityLabel} accessibilityRole='img' accessible={accessible} + ref='root' style={[ styles.initial, style, @@ -177,6 +124,56 @@ class Image extends Component { ) } + + _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({