From 2f33aa8182c92bf56d49ec3184e6b20f0c0c1e1e Mon Sep 17 00:00:00 2001 From: kodai3 Date: Tue, 9 Mar 2021 23:00:21 +0900 Subject: [PATCH 1/5] fix: use window inside useEffect --- src/useOrientation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/useOrientation.ts b/src/useOrientation.ts index cb315218b6..fb6aad7731 100644 --- a/src/useOrientation.ts +++ b/src/useOrientation.ts @@ -12,10 +12,10 @@ const defaultState: OrientationState = { }; const useOrientation = (initialState: OrientationState = defaultState) => { - const screen = window.screen; const [state, setState] = useState(initialState); useEffect(() => { + const screen = window.screen; let mounted = true; const onChange = () => { From 793b0539f0305e2512e7022c45a5c33b842d24d5 Mon Sep 17 00:00:00 2001 From: Edwin Joseph Date: Tue, 13 Oct 2020 13:55:39 +0100 Subject: [PATCH 2/5] fix(useOrientation): handle orientation being 0 --- src/useOrientation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/useOrientation.ts b/src/useOrientation.ts index fb6aad7731..b5365af90f 100644 --- a/src/useOrientation.ts +++ b/src/useOrientation.ts @@ -25,7 +25,7 @@ const useOrientation = (initialState: OrientationState = defaultState) => { if (orientation) { const { angle, type } = orientation; setState({ angle, type }); - } else if (window.orientation) { + } else if (window.orientation !== undefined) { setState({ angle: typeof window.orientation === 'number' ? window.orientation : 0, type: '', From f45cb707b52363f1cb1b32a0ebf2fdbdae79b322 Mon Sep 17 00:00:00 2001 From: Edwin Joseph Date: Tue, 13 Oct 2020 11:37:26 +0100 Subject: [PATCH 3/5] feat(useOrientation): add tests --- tests/useOrientation.test.ts | 68 ++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/useOrientation.test.ts diff --git a/tests/useOrientation.test.ts b/tests/useOrientation.test.ts new file mode 100644 index 0000000000..aa1d28a568 --- /dev/null +++ b/tests/useOrientation.test.ts @@ -0,0 +1,68 @@ +import { act, renderHook } from '@testing-library/react-hooks'; +import { replaceRaf } from 'raf-stub'; +import useOrientation from '../src/useOrientation'; +import { isClient } from '../src/util'; + +declare var requestAnimationFrame: { + reset: () => void; + step: (steps?: number, duration?: number) => void; +}; + +describe('useOrientation', () => { + beforeAll(() => { + replaceRaf(); + (window.screen.orientation as object) = { + type: 'landscape-primary', + angle: 0, + }; + }); + + afterEach(() => { + requestAnimationFrame.reset(); + }); + + it('should be defined', () => { + expect(useOrientation).toBeDefined(); + }); + + function getHook(...args) { + return renderHook(() => useOrientation(...args)); + } + + function triggerOrientation(type: string, angle: number) { + (window.screen.orientation.type as string) = type; + (window.screen.orientation.angle as number) = angle; + + window.dispatchEvent(new Event('orientationchange')); + } + + it('should return current window orientation', () => { + const hook = getHook(); + + expect(typeof hook.result.current).toBe('object'); + expect(typeof hook.result.current.type).toBe('string'); + expect(typeof hook.result.current.angle).toBe('number'); + }); + + it('should use passed parameters as initial values in case of non-browser use', () => { + const hook = getHook({ + angle: 90, + type: 'portrait-primary' + }); + + expect(hook.result.current.type).toBe(isClient ? window.screen.orientation.type : 'portrait-primary'); + expect(hook.result.current.angle).toBe(isClient ? window.screen.orientation.angle : 90); + }); + + it('should re-render after orientation change on closest RAF', () => { + const hook = getHook(); + + act(() => { + triggerOrientation('portrait-secondary', 180); + requestAnimationFrame.step(); + }); + + expect(hook.result.current.type).toBe('portrait-secondary'); + expect(hook.result.current.angle).toBe(180); + }); +}); From f9c743fa8375ef726d33f85285d4a5af608f9a42 Mon Sep 17 00:00:00 2001 From: Edwin Joseph Date: Tue, 13 Oct 2020 13:56:06 +0100 Subject: [PATCH 4/5] fix(useOrientation): update tests to increase coverage --- tests/useOrientation.test.ts | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/useOrientation.test.ts b/tests/useOrientation.test.ts index aa1d28a568..6bbee1951e 100644 --- a/tests/useOrientation.test.ts +++ b/tests/useOrientation.test.ts @@ -11,11 +11,15 @@ declare var requestAnimationFrame: { describe('useOrientation', () => { beforeAll(() => { replaceRaf(); + }); + + beforeEach(() => { (window.screen.orientation as object) = { type: 'landscape-primary', angle: 0, }; - }); + (window.orientation as number) = 0; + }) afterEach(() => { requestAnimationFrame.reset(); @@ -44,6 +48,13 @@ describe('useOrientation', () => { expect(typeof hook.result.current.angle).toBe('number'); }); + it('should use initial values in case of no parameters', () => { + const hook = getHook(); + + expect(hook.result.current.type).toBe('landscape-primary'); + expect(hook.result.current.angle).toBe(0); + }); + it('should use passed parameters as initial values in case of non-browser use', () => { const hook = getHook({ angle: 90, @@ -65,4 +76,23 @@ describe('useOrientation', () => { expect(hook.result.current.type).toBe('portrait-secondary'); expect(hook.result.current.angle).toBe(180); }); + + it('should return window.orientation number if window.screen.orientation is missing', () => { + (window.screen.orientation as unknown) = undefined; + + const hook = getHook(); + + expect(hook.result.current.type).toBe(''); + expect(hook.result.current.angle).toBe(0); + }); + + it('should return 0 if window.orientation is not a number and if window.screen.orientation is missing', () => { + (window.screen.orientation as unknown) = undefined; + (window.orientation as unknown) = null; + + const hook = getHook(); + + expect(hook.result.current.type).toBe(''); + expect(hook.result.current.angle).toBe(0); + }) }); From 72f4cb9b405b3729975bca3acb06658ca467d15b Mon Sep 17 00:00:00 2001 From: kodai3 Date: Tue, 9 Mar 2021 23:18:34 +0900 Subject: [PATCH 5/5] fix: delete isClient --- tests/useOrientation.test.ts | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/tests/useOrientation.test.ts b/tests/useOrientation.test.ts index 6bbee1951e..58a8392f2b 100644 --- a/tests/useOrientation.test.ts +++ b/tests/useOrientation.test.ts @@ -1,7 +1,6 @@ -import { act, renderHook } from '@testing-library/react-hooks'; -import { replaceRaf } from 'raf-stub'; -import useOrientation from '../src/useOrientation'; -import { isClient } from '../src/util'; +import { act, renderHook } from "@testing-library/react-hooks"; +import { replaceRaf } from "raf-stub"; +import useOrientation from "../src/useOrientation"; declare var requestAnimationFrame: { reset: () => void; @@ -55,17 +54,7 @@ describe('useOrientation', () => { expect(hook.result.current.angle).toBe(0); }); - it('should use passed parameters as initial values in case of non-browser use', () => { - const hook = getHook({ - angle: 90, - type: 'portrait-primary' - }); - - expect(hook.result.current.type).toBe(isClient ? window.screen.orientation.type : 'portrait-primary'); - expect(hook.result.current.angle).toBe(isClient ? window.screen.orientation.angle : 90); - }); - - it('should re-render after orientation change on closest RAF', () => { + it("should re-render after orientation change on closest RAF", () => { const hook = getHook(); act(() => {