Skip to content

Commit 269744e

Browse files
authored
Merge pull request #262 from retyui/add-use-device-orientation-test
Add useDeviceOrientation tests
2 parents 5c8506a + 3feeff1 commit 269744e

File tree

2 files changed

+75
-26
lines changed

2 files changed

+75
-26
lines changed

src/useDeviceOrientation.test.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import {useDeviceOrientation} from './useDeviceOrientation'
2+
import {act, renderHook} from '@testing-library/react-hooks'
3+
4+
// @ts-expect-error - untyped implementation
5+
import RCTDeviceEventEmitter from 'react-native/Libraries/EventEmitter/RCTDeviceEventEmitter'
6+
import {Dimensions} from 'react-native'
7+
8+
describe('useDeviceOrientation', () => {
9+
const emitChangeDimensions = (screen = {width: 0, height: 0}) =>
10+
RCTDeviceEventEmitter.emit('didUpdateDimensions', {screen})
11+
12+
const rotatePortrait = () => emitChangeDimensions({height: 200, width: 100})
13+
const rotateLandscape = () => emitChangeDimensions({height: 100, width: 200})
14+
15+
it('should return portrait orientation', () => {
16+
const {result} = renderHook(() => useDeviceOrientation())
17+
18+
act(() => rotatePortrait())
19+
20+
expect(result.current).toEqual({
21+
landscape: false,
22+
portrait: true,
23+
})
24+
})
25+
26+
it('should return landscape orientation', () => {
27+
const {result} = renderHook(() => useDeviceOrientation())
28+
29+
act(() => rotateLandscape())
30+
31+
expect(result.current).toEqual({
32+
landscape: true,
33+
portrait: false,
34+
})
35+
})
36+
37+
it('should return landscape & portrait orientations when window is square', () => {
38+
const {result} = renderHook(() => useDeviceOrientation())
39+
40+
act(() => emitChangeDimensions({width: 100, height: 100}))
41+
42+
expect(result.current).toEqual({
43+
landscape: true,
44+
portrait: true,
45+
})
46+
})
47+
48+
it('should use latest screen size for orientation state initialization', () => {
49+
Dimensions.get('screen')
50+
51+
rotateLandscape()
52+
53+
const {result} = renderHook(() => useDeviceOrientation())
54+
55+
expect(result.current).toEqual({
56+
landscape: true,
57+
portrait: false,
58+
})
59+
})
60+
})

src/useDeviceOrientation.ts

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,32 @@
1-
import {useEffect, useState, useCallback} from 'react'
1+
import {useEffect, useState} from 'react'
22
import {Dimensions, ScaledSize} from 'react-native'
33

4-
const screen = Dimensions.get('screen')
4+
const isOrientationPortrait = ({width, height}: ScaledSize) => height >= width
5+
const isOrientationLandscape = ({width, height}: ScaledSize) => width >= height
56

67
export function useDeviceOrientation() {
7-
const isOrientationPortrait = ({
8-
width,
9-
height,
10-
}: {
11-
width: number
12-
height: number
13-
}) => height >= width
14-
const isOrientationLandscape = ({
15-
width,
16-
height,
17-
}: {
18-
width: number
19-
height: number
20-
}) => width >= height
21-
22-
const [orientation, setOrientation] = useState({
8+
const screen = Dimensions.get('screen')
9+
const initialState = {
2310
portrait: isOrientationPortrait(screen),
2411
landscape: isOrientationLandscape(screen),
25-
})
12+
}
2613

27-
const onChange = useCallback(({screen: scr}: {screen: ScaledSize}) => {
28-
setOrientation({
29-
portrait: isOrientationPortrait(scr),
30-
landscape: isOrientationLandscape(scr),
31-
})
32-
}, [])
14+
const [orientation, setOrientation] = useState(initialState)
3315

3416
useEffect(() => {
17+
const onChange = ({screen}: {screen: ScaledSize}) => {
18+
setOrientation({
19+
portrait: isOrientationPortrait(screen),
20+
landscape: isOrientationLandscape(screen),
21+
})
22+
}
23+
3524
Dimensions.addEventListener('change', onChange)
3625

3726
return () => {
3827
Dimensions.removeEventListener('change', onChange)
3928
}
40-
}, [orientation.portrait, orientation.landscape, onChange])
29+
}, [])
4130

4231
return orientation
4332
}

0 commit comments

Comments
 (0)