@@ -5,8 +5,12 @@ import WebWorker from "./"
5
5
6
6
afterEach ( cleanup )
7
7
8
- const worker = { postMessage : jest . fn ( ) , terminate : jest . fn ( ) }
8
+ const worker = { onmessage : null , postMessage : jest . fn ( ) , terminate : jest . fn ( ) }
9
+ const serviceWorker = { postMessage : jest . fn ( ) }
10
+ const messageChannel = { port1 : { } , port2 : jest . fn ( ) }
9
11
window . Worker = jest . fn ( ) . mockImplementation ( ( ) => worker )
12
+ window . ServiceWorker = jest . fn ( ) . mockImplementation ( ( ) => serviceWorker )
13
+ window . MessageChannel = jest . fn ( ) . mockImplementation ( ( ) => messageChannel )
10
14
11
15
test ( "initializes a Worker on mount" , ( ) => {
12
16
const options = { }
@@ -15,31 +19,35 @@ test("initializes a Worker on mount", () => {
15
19
} )
16
20
17
21
test ( "passes received messages to children as render prop" , async ( ) => {
18
- const { getByText } = render ( < WebWorker > { ( { messages } ) => messages . map ( m => m . data ) . join ( ) } </ WebWorker > )
22
+ const { getByText } = render (
23
+ < WebWorker url = "/worker.js" > { ( { messages } ) => messages . map ( m => m . data ) . join ( ) } </ WebWorker >
24
+ )
19
25
worker . onmessage ( { data : "foo" } )
20
26
worker . onmessage ( { data : "bar" } )
21
27
worker . onmessage ( { data : "baz" } )
22
28
await waitForElement ( ( ) => getByText ( "foo,bar,baz" ) )
23
29
} )
24
30
25
31
test ( "passes data of last received message to children as render prop" , async ( ) => {
26
- const { getByText } = render ( < WebWorker > { ( { data } ) => data } </ WebWorker > )
32
+ const { getByText } = render ( < WebWorker url = "/worker.js" > { ( { data } ) => data } </ WebWorker > )
27
33
worker . onmessage ( { data : "foo" } )
28
34
worker . onmessage ( { data : "bar" } )
29
35
worker . onmessage ( { data : "baz" } )
30
36
await waitForElement ( ( ) => getByText ( "baz" ) )
31
37
} )
32
38
33
39
test ( "passes received errors to children as render prop" , async ( ) => {
34
- const { getByText } = render ( < WebWorker > { ( { errors } ) => errors . map ( e => e . error ) . join ( ) } </ WebWorker > )
40
+ const { getByText } = render (
41
+ < WebWorker url = "/worker.js" > { ( { errors } ) => errors . map ( e => e . error ) . join ( ) } </ WebWorker >
42
+ )
35
43
worker . onerror ( { error : "foo" } )
36
44
worker . onerror ( { error : "bar" } )
37
45
worker . onerror ( { error : "baz" } )
38
46
await waitForElement ( ( ) => getByText ( "foo,bar,baz" ) )
39
47
} )
40
48
41
49
test ( "passes last received error to children as render prop" , async ( ) => {
42
- const { getByText } = render ( < WebWorker > { ( { error } ) => error } </ WebWorker > )
50
+ const { getByText } = render ( < WebWorker url = "/worker.js" > { ( { error } ) => error } </ WebWorker > )
43
51
worker . onerror ( { error : "foo" } )
44
52
worker . onerror ( { error : "bar" } )
45
53
worker . onerror ( { error : "baz" } )
@@ -49,7 +57,9 @@ test("passes last received error to children as render prop", async () => {
49
57
test ( "passes updatedAt date when a message is received" , async ( ) => {
50
58
const date = new Date ( ) . toISOString ( ) . substr ( 0 , 10 )
51
59
const { getByText, queryByText } = render (
52
- < WebWorker > { ( { updatedAt } ) => ( updatedAt ? updatedAt . toISOString ( ) . substr ( 0 , 10 ) : null ) } </ WebWorker >
60
+ < WebWorker url = "/worker.js" >
61
+ { ( { updatedAt } ) => ( updatedAt ? updatedAt . toISOString ( ) . substr ( 0 , 10 ) : null ) }
62
+ </ WebWorker >
53
63
)
54
64
expect ( queryByText ( date ) ) . toBeNull ( )
55
65
worker . onmessage ( { data : "foo" } )
@@ -59,7 +69,9 @@ test("passes updatedAt date when a message is received", async () => {
59
69
test ( "passes updatedAt date when an error is received" , async ( ) => {
60
70
const date = new Date ( ) . toISOString ( ) . substr ( 0 , 10 )
61
71
const { getByText, queryByText } = render (
62
- < WebWorker > { ( { updatedAt } ) => ( updatedAt ? updatedAt . toISOString ( ) . substr ( 0 , 10 ) : null ) } </ WebWorker >
72
+ < WebWorker url = "/worker.js" >
73
+ { ( { updatedAt } ) => ( updatedAt ? updatedAt . toISOString ( ) . substr ( 0 , 10 ) : null ) }
74
+ </ WebWorker >
63
75
)
64
76
expect ( queryByText ( date ) ) . toBeNull ( )
65
77
worker . onerror ( { error : "foo" } )
@@ -68,29 +80,31 @@ test("passes updatedAt date when an error is received", async () => {
68
80
69
81
test ( "invokes onMessage callback with message data when a message is received" , async ( ) => {
70
82
const onMessage = jest . fn ( )
71
- render ( < WebWorker onMessage = { onMessage } /> )
83
+ render ( < WebWorker url = "/worker.js" onMessage = { onMessage } /> )
72
84
worker . onmessage ( { data : "foo" } )
73
85
expect ( onMessage ) . toHaveBeenCalledWith ( "foo" )
74
86
} )
75
87
76
88
test ( "invokes onError callback with error when a error is received" , async ( ) => {
77
89
const onError = jest . fn ( )
78
- render ( < WebWorker onError = { onError } /> )
90
+ render ( < WebWorker url = "/worker.js" onError = { onError } /> )
79
91
worker . onerror ( { error : "foo" } )
80
92
expect ( onError ) . toHaveBeenCalledWith ( "foo" )
81
93
} )
82
94
83
95
test ( "terminates the worker when unmounted" , async ( ) => {
84
96
worker . terminate . mockClear ( )
85
- const { unmount } = render ( < WebWorker /> )
97
+ const { unmount } = render ( < WebWorker url = "/worker.js" /> )
86
98
unmount ( )
87
99
expect ( worker . terminate ) . toHaveBeenCalled ( )
88
100
} )
89
101
90
102
test ( "postMessage sends messages to the worker" , async ( ) => {
91
103
worker . postMessage . mockClear ( )
92
104
const { getByText } = render (
93
- < WebWorker > { ( { postMessage } ) => < button onClick = { ( ) => postMessage ( "hello" ) } > go</ button > } </ WebWorker >
105
+ < WebWorker url = "/worker.js" >
106
+ { ( { postMessage } ) => < button onClick = { ( ) => postMessage ( "hello" ) } > go</ button > }
107
+ </ WebWorker >
94
108
)
95
109
expect ( worker . postMessage ) . not . toHaveBeenCalled ( )
96
110
fireEvent . click ( getByText ( "go" ) )
@@ -99,7 +113,7 @@ test("postMessage sends messages to the worker", async () => {
99
113
100
114
test ( "calling postMessage before having setup a worker will throw" , async ( ) => {
101
115
render (
102
- < WebWorker >
116
+ < WebWorker url = "/worker.js" >
103
117
{ ( { postMessage } ) => {
104
118
expect ( ( ) => postMessage ( "hello" ) ) . toThrow ( new Error ( "Worker not initialized" ) )
105
119
} }
@@ -110,7 +124,7 @@ test("calling postMessage before having setup a worker will throw", async () =>
110
124
test ( "serializer will prepare messages before sending them to the worker" , async ( ) => {
111
125
worker . postMessage . mockClear ( )
112
126
const { getByText } = render (
113
- < WebWorker serializer = { JSON . stringify } >
127
+ < WebWorker url = "/worker.js" serializer = { JSON . stringify } >
114
128
{ ( { postMessage } ) => < button onClick = { ( ) => postMessage ( { foo : "bar" } ) } > go</ button > }
115
129
</ WebWorker >
116
130
)
@@ -122,7 +136,7 @@ test("serializer will prepare messages before sending them to the worker", async
122
136
test ( "parser will deserialize messages received from the worker" , async ( ) => {
123
137
const onMessage = jest . fn ( )
124
138
const { getByText } = render (
125
- < WebWorker parser = { JSON . parse } onMessage = { onMessage } >
139
+ < WebWorker url = "/worker.js" parser = { JSON . parse } onMessage = { onMessage } >
126
140
{ ( { data } ) => data && data . foo }
127
141
</ WebWorker >
128
142
)
@@ -133,7 +147,7 @@ test("parser will deserialize messages received from the worker", async () => {
133
147
134
148
test ( "supports passing a custom Worker instance" , ( ) => {
135
149
const onMessage = jest . fn ( )
136
- const customWorker = { postMessage : jest . fn ( ) }
150
+ const customWorker = { onmessage : null , postMessage : jest . fn ( ) }
137
151
const { getByText } = render (
138
152
< WebWorker worker = { customWorker } onMessage = { onMessage } >
139
153
{ ( { postMessage } ) => < button onClick = { ( ) => postMessage ( "hello" ) } > go</ button > }
@@ -153,9 +167,22 @@ test("custom workers don't terminate on unmount", async () => {
153
167
expect ( customWorker . terminate ) . not . toHaveBeenCalled ( )
154
168
} )
155
169
170
+ test ( "supports Service Workers" , ( ) => {
171
+ const onMessage = jest . fn ( )
172
+ const customWorker = window . ServiceWorker ( )
173
+ const { getByText } = render (
174
+ < WebWorker worker = { customWorker } onMessage = { onMessage } >
175
+ { ( { postMessage } ) => < button onClick = { ( ) => postMessage ( "hello" ) } > go</ button > }
176
+ </ WebWorker >
177
+ )
178
+ expect ( customWorker . postMessage ) . not . toHaveBeenCalled ( )
179
+ fireEvent . click ( getByText ( "go" ) )
180
+ expect ( customWorker . postMessage ) . toHaveBeenCalledWith ( "hello" , [ messageChannel . port2 ] )
181
+ } )
182
+
156
183
test ( "WebWorker.Data renders with last message data only when a message has been received" , async ( ) => {
157
184
const { getByText, queryByText } = render (
158
- < WebWorker >
185
+ < WebWorker url = "/worker.js" >
159
186
< WebWorker . Data > { data => data } </ WebWorker . Data >
160
187
</ WebWorker >
161
188
)
@@ -170,7 +197,7 @@ test("WebWorker.Data renders with last message data only when a message has been
170
197
171
198
test ( "WebWorker.Error renders with last error only when an error has been received" , async ( ) => {
172
199
const { getByText, queryByText } = render (
173
- < WebWorker >
200
+ < WebWorker url = "/worker.js" >
174
201
< WebWorker . Error > { error => error } </ WebWorker . Error >
175
202
</ WebWorker >
176
203
)
@@ -185,7 +212,7 @@ test("WebWorker.Error renders with last error only when an error has been receiv
185
212
186
213
test ( "WebWorker.Pending renders only when no message has been received yet" , async ( ) => {
187
214
const { getByText, queryByText } = render (
188
- < WebWorker >
215
+ < WebWorker url = "/worker.js" >
189
216
< WebWorker . Pending > pending</ WebWorker . Pending >
190
217
</ WebWorker >
191
218
)
@@ -196,7 +223,7 @@ test("WebWorker.Pending renders only when no message has been received yet", asy
196
223
197
224
test ( "WebWorker.Pending renders only when no error has been received yet" , async ( ) => {
198
225
const { getByText, queryByText } = render (
199
- < WebWorker >
226
+ < WebWorker url = "/worker.js" >
200
227
< WebWorker . Pending > pending</ WebWorker . Pending >
201
228
</ WebWorker >
202
229
)
@@ -209,7 +236,7 @@ test("An unrelated change in props does not update the Context", async () => {
209
236
let one
210
237
let two
211
238
const { rerender } = render (
212
- < WebWorker >
239
+ < WebWorker url = "/worker.js" >
213
240
< WebWorker . Pending >
214
241
{ value => {
215
242
one = value
@@ -218,7 +245,7 @@ test("An unrelated change in props does not update the Context", async () => {
218
245
</ WebWorker >
219
246
)
220
247
rerender (
221
- < WebWorker someProp >
248
+ < WebWorker url = "/worker.js" someProp >
222
249
< WebWorker . Pending >
223
250
{ value => {
224
251
two = value
0 commit comments