1
1
import { act , renderHook } from '@testing-library/react-hooks/dom' ;
2
- import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest' ;
2
+ import { type Mock , afterEach , beforeEach , describe , expect , it , vi } from 'vitest' ;
3
3
import { useMediaQuery } from '../index.js' ;
4
4
5
+ type MatchMediaMock = MediaQueryList & {
6
+ matches : boolean ;
7
+ addEventListener : Mock ;
8
+ removeEventListener : Mock ;
9
+ dispatchEvent : Mock ;
10
+ } ;
11
+
5
12
describe ( 'useMediaQuery' , ( ) => {
6
- const matchMediaMock = vi . fn ( ( query : string ) => ( {
7
- matches : false ,
8
- media : query ,
9
- onchange : null ,
10
- addEventListener : vi . fn ( ) ,
11
- removeEventListener : vi . fn ( ) ,
12
- dispatchEvent : vi . fn ( ) ,
13
- } ) ) ;
13
+ const matchMediaMock = vi . fn (
14
+ ( query : string ) =>
15
+ ( query === '(orientation: unsupported)' ?
16
+ undefined :
17
+ {
18
+ matches : false ,
19
+ media : query ,
20
+ onchange : null ,
21
+ addEventListener : vi . fn ( ) ,
22
+ removeEventListener : vi . fn ( ) ,
23
+ dispatchEvent : vi . fn ( ) ,
24
+ } ) as unknown as MatchMediaMock ,
25
+ ) ;
14
26
15
27
vi . stubGlobal ( 'matchMedia' , matchMediaMock ) ;
16
28
@@ -30,17 +42,45 @@ describe('useMediaQuery', () => {
30
42
expect ( result . error ) . toBeUndefined ( ) ;
31
43
} ) ;
32
44
45
+ it ( 'should return undefined and not thrown on unsupported when not enabled' , ( ) => {
46
+ const spy = vi . fn ( ) ;
47
+ vi . stubGlobal ( 'console' , {
48
+ error : spy ,
49
+ } ) ;
50
+ const { result, rerender, unmount} = renderHook ( ( ) => useMediaQuery ( 'max-width : 768px' , { enabled : false } ) ) ;
51
+ const { result : result2 , rerender : rerender2 , unmount : unmount2 } = renderHook ( ( ) => useMediaQuery ( '(orientation: unsupported)' , { enabled : false } ) ) ;
52
+ expect ( spy . call . length === 0 || ! spy . mock . calls . some ( ( call : string [ ] ) => call [ 0 ] ?. includes ?.( 'error: matchMedia' ) ) ) . toBe ( true ) ;
53
+ expect ( result . error ) . toBeUndefined ( ) ;
54
+ expect ( result . current ) . toBe ( undefined ) ;
55
+ expect ( result2 . error ) . toBeUndefined ( ) ;
56
+ expect ( result2 . current ) . toBe ( undefined ) ;
57
+ rerender ( 'max-width : 768px' ) ;
58
+ rerender2 ( '(orientation: unsupported)' ) ;
59
+ expect ( spy . call . length === 0 || ! spy . mock . calls . some ( ( call : string [ ] ) => call [ 0 ] ?. includes ?.( 'error: matchMedia' ) ) ) . toBe ( true ) ;
60
+ expect ( result . error ) . toBeUndefined ( ) ;
61
+ expect ( result . current ) . toBe ( undefined ) ;
62
+ expect ( result2 . current ) . toBe ( undefined ) ;
63
+ expect ( result2 . error ) . toBeUndefined ( ) ;
64
+ unmount ( ) ;
65
+ unmount2 ( ) ;
66
+ expect ( spy . call . length === 0 || ! spy . mock . calls . some ( ( call : string [ ] ) => call [ 0 ] ?. includes ?.( 'error: matchMedia' ) ) ) . toBe ( true ) ;
67
+ expect ( result . error ) . toBeUndefined ( ) ;
68
+ expect ( result . current ) . toBe ( undefined ) ;
69
+ expect ( result2 . error ) . toBeUndefined ( ) ;
70
+ expect ( result2 . current ) . toBe ( undefined ) ;
71
+ vi . unstubAllGlobals ( ) ;
72
+ vi . stubGlobal ( 'matchMedia' , matchMediaMock ) ;
73
+ } ) ;
74
+
33
75
it ( 'should return undefined on first render, if initializeWithValue is false' , ( ) => {
34
- const { result} = renderHook ( ( ) =>
35
- useMediaQuery ( 'max-width : 768px' , { initializeWithValue : false } ) ) ;
76
+ const { result} = renderHook ( ( ) => useMediaQuery ( 'max-width : 768px' , { initializeWithValue : false } ) ) ;
36
77
expect ( result . all . length ) . toBe ( 2 ) ;
37
78
expect ( result . all [ 0 ] ) . toBe ( undefined ) ;
38
79
expect ( result . current ) . toBe ( false ) ;
39
80
} ) ;
40
81
41
82
it ( 'should return value on first render, if initializeWithValue is true' , ( ) => {
42
- const { result} = renderHook ( ( ) =>
43
- useMediaQuery ( 'max-width : 768px' , { initializeWithValue : true } ) ) ;
83
+ const { result} = renderHook ( ( ) => useMediaQuery ( 'max-width : 768px' , { initializeWithValue : true } ) ) ;
44
84
expect ( result . all . length ) . toBe ( 1 ) ;
45
85
expect ( result . current ) . toBe ( false ) ;
46
86
} ) ;
@@ -97,12 +137,9 @@ describe('useMediaQuery', () => {
97
137
it ( 'should unsubscribe from previous mql when query changed' , ( ) => {
98
138
const { result : result1 } = renderHook ( ( ) => useMediaQuery ( 'max-width : 768px' ) ) ;
99
139
const { result : result2 } = renderHook ( ( ) => useMediaQuery ( 'max-width : 768px' ) ) ;
100
- const { result : result3 , rerender : rerender3 } = renderHook (
101
- ( { query} ) => useMediaQuery ( query ) ,
102
- {
103
- initialProps : { query : 'max-width : 768px' } ,
104
- } ,
105
- ) ;
140
+ const { result : result3 , rerender : rerender3 } = renderHook ( ( { query} ) => useMediaQuery ( query ) , {
141
+ initialProps : { query : 'max-width : 768px' } ,
142
+ } ) ;
106
143
expect ( result1 . current ) . toBe ( false ) ;
107
144
expect ( result2 . current ) . toBe ( false ) ;
108
145
expect ( result3 . current ) . toBe ( false ) ;
@@ -147,4 +184,24 @@ describe('useMediaQuery', () => {
147
184
unmount1 ( ) ;
148
185
expect ( mql . removeEventListener ) . toHaveBeenCalledTimes ( 1 ) ;
149
186
} ) ;
187
+
188
+ it ( 'should not throw when media query is not supported' , ( ) => {
189
+ const spy = vi . fn ( ) ;
190
+ vi . stubGlobal ( 'console' , {
191
+ error : spy ,
192
+ } ) ;
193
+ const { result, unmount, rerender} = renderHook ( ( ) => useMediaQuery ( '(orientation: unsupported)' , { initializeWithValue : true } ) ) ;
194
+ expect ( spy ) . toHaveBeenCalled ( ) ;
195
+ expect ( spy . mock . calls . some ( ( call : string [ ] ) => call [ 0 ] ?. includes ?.( 'error: matchMedia' ) ) ) . toBe ( true ) ;
196
+ expect ( result . error ) . toBeUndefined ( ) ;
197
+ expect ( result . current ) . toBe ( undefined ) ;
198
+ rerender ( ) ;
199
+ expect ( result . error ) . toBeUndefined ( ) ;
200
+ expect ( result . current ) . toBe ( undefined ) ;
201
+ unmount ( ) ;
202
+ expect ( result . error ) . toBeUndefined ( ) ;
203
+ expect ( result . current ) . toBe ( undefined ) ;
204
+ vi . unstubAllGlobals ( ) ;
205
+ vi . stubGlobal ( 'matchMedia' , matchMediaMock ) ;
206
+ } ) ;
150
207
} ) ;
0 commit comments