@@ -5,8 +5,12 @@ import WebWorker from "./"
55
66afterEach ( cleanup )
77
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 ( ) }
911window . Worker = jest . fn ( ) . mockImplementation ( ( ) => worker )
12+ window . ServiceWorker = jest . fn ( ) . mockImplementation ( ( ) => serviceWorker )
13+ window . MessageChannel = jest . fn ( ) . mockImplementation ( ( ) => messageChannel )
1014
1115test ( "initializes a Worker on mount" , ( ) => {
1216 const options = { }
@@ -15,31 +19,35 @@ test("initializes a Worker on mount", () => {
1519} )
1620
1721test ( "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+ )
1925 worker . onmessage ( { data : "foo" } )
2026 worker . onmessage ( { data : "bar" } )
2127 worker . onmessage ( { data : "baz" } )
2228 await waitForElement ( ( ) => getByText ( "foo,bar,baz" ) )
2329} )
2430
2531test ( "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 > )
2733 worker . onmessage ( { data : "foo" } )
2834 worker . onmessage ( { data : "bar" } )
2935 worker . onmessage ( { data : "baz" } )
3036 await waitForElement ( ( ) => getByText ( "baz" ) )
3137} )
3238
3339test ( "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+ )
3543 worker . onerror ( { error : "foo" } )
3644 worker . onerror ( { error : "bar" } )
3745 worker . onerror ( { error : "baz" } )
3846 await waitForElement ( ( ) => getByText ( "foo,bar,baz" ) )
3947} )
4048
4149test ( "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 > )
4351 worker . onerror ( { error : "foo" } )
4452 worker . onerror ( { error : "bar" } )
4553 worker . onerror ( { error : "baz" } )
@@ -49,7 +57,9 @@ test("passes last received error to children as render prop", async () => {
4957test ( "passes updatedAt date when a message is received" , async ( ) => {
5058 const date = new Date ( ) . toISOString ( ) . substr ( 0 , 10 )
5159 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 >
5363 )
5464 expect ( queryByText ( date ) ) . toBeNull ( )
5565 worker . onmessage ( { data : "foo" } )
@@ -59,7 +69,9 @@ test("passes updatedAt date when a message is received", async () => {
5969test ( "passes updatedAt date when an error is received" , async ( ) => {
6070 const date = new Date ( ) . toISOString ( ) . substr ( 0 , 10 )
6171 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 >
6375 )
6476 expect ( queryByText ( date ) ) . toBeNull ( )
6577 worker . onerror ( { error : "foo" } )
@@ -68,29 +80,31 @@ test("passes updatedAt date when an error is received", async () => {
6880
6981test ( "invokes onMessage callback with message data when a message is received" , async ( ) => {
7082 const onMessage = jest . fn ( )
71- render ( < WebWorker onMessage = { onMessage } /> )
83+ render ( < WebWorker url = "/worker.js" onMessage = { onMessage } /> )
7284 worker . onmessage ( { data : "foo" } )
7385 expect ( onMessage ) . toHaveBeenCalledWith ( "foo" )
7486} )
7587
7688test ( "invokes onError callback with error when a error is received" , async ( ) => {
7789 const onError = jest . fn ( )
78- render ( < WebWorker onError = { onError } /> )
90+ render ( < WebWorker url = "/worker.js" onError = { onError } /> )
7991 worker . onerror ( { error : "foo" } )
8092 expect ( onError ) . toHaveBeenCalledWith ( "foo" )
8193} )
8294
8395test ( "terminates the worker when unmounted" , async ( ) => {
8496 worker . terminate . mockClear ( )
85- const { unmount } = render ( < WebWorker /> )
97+ const { unmount } = render ( < WebWorker url = "/worker.js" /> )
8698 unmount ( )
8799 expect ( worker . terminate ) . toHaveBeenCalled ( )
88100} )
89101
90102test ( "postMessage sends messages to the worker" , async ( ) => {
91103 worker . postMessage . mockClear ( )
92104 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 >
94108 )
95109 expect ( worker . postMessage ) . not . toHaveBeenCalled ( )
96110 fireEvent . click ( getByText ( "go" ) )
@@ -99,7 +113,7 @@ test("postMessage sends messages to the worker", async () => {
99113
100114test ( "calling postMessage before having setup a worker will throw" , async ( ) => {
101115 render (
102- < WebWorker >
116+ < WebWorker url = "/worker.js" >
103117 { ( { postMessage } ) => {
104118 expect ( ( ) => postMessage ( "hello" ) ) . toThrow ( new Error ( "Worker not initialized" ) )
105119 } }
@@ -110,7 +124,7 @@ test("calling postMessage before having setup a worker will throw", async () =>
110124test ( "serializer will prepare messages before sending them to the worker" , async ( ) => {
111125 worker . postMessage . mockClear ( )
112126 const { getByText } = render (
113- < WebWorker serializer = { JSON . stringify } >
127+ < WebWorker url = "/worker.js" serializer = { JSON . stringify } >
114128 { ( { postMessage } ) => < button onClick = { ( ) => postMessage ( { foo : "bar" } ) } > go</ button > }
115129 </ WebWorker >
116130 )
@@ -122,7 +136,7 @@ test("serializer will prepare messages before sending them to the worker", async
122136test ( "parser will deserialize messages received from the worker" , async ( ) => {
123137 const onMessage = jest . fn ( )
124138 const { getByText } = render (
125- < WebWorker parser = { JSON . parse } onMessage = { onMessage } >
139+ < WebWorker url = "/worker.js" parser = { JSON . parse } onMessage = { onMessage } >
126140 { ( { data } ) => data && data . foo }
127141 </ WebWorker >
128142 )
@@ -133,7 +147,7 @@ test("parser will deserialize messages received from the worker", async () => {
133147
134148test ( "supports passing a custom Worker instance" , ( ) => {
135149 const onMessage = jest . fn ( )
136- const customWorker = { postMessage : jest . fn ( ) }
150+ const customWorker = { onmessage : null , postMessage : jest . fn ( ) }
137151 const { getByText } = render (
138152 < WebWorker worker = { customWorker } onMessage = { onMessage } >
139153 { ( { postMessage } ) => < button onClick = { ( ) => postMessage ( "hello" ) } > go</ button > }
@@ -153,9 +167,22 @@ test("custom workers don't terminate on unmount", async () => {
153167 expect ( customWorker . terminate ) . not . toHaveBeenCalled ( )
154168} )
155169
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+
156183test ( "WebWorker.Data renders with last message data only when a message has been received" , async ( ) => {
157184 const { getByText, queryByText } = render (
158- < WebWorker >
185+ < WebWorker url = "/worker.js" >
159186 < WebWorker . Data > { data => data } </ WebWorker . Data >
160187 </ WebWorker >
161188 )
@@ -170,7 +197,7 @@ test("WebWorker.Data renders with last message data only when a message has been
170197
171198test ( "WebWorker.Error renders with last error only when an error has been received" , async ( ) => {
172199 const { getByText, queryByText } = render (
173- < WebWorker >
200+ < WebWorker url = "/worker.js" >
174201 < WebWorker . Error > { error => error } </ WebWorker . Error >
175202 </ WebWorker >
176203 )
@@ -185,7 +212,7 @@ test("WebWorker.Error renders with last error only when an error has been receiv
185212
186213test ( "WebWorker.Pending renders only when no message has been received yet" , async ( ) => {
187214 const { getByText, queryByText } = render (
188- < WebWorker >
215+ < WebWorker url = "/worker.js" >
189216 < WebWorker . Pending > pending</ WebWorker . Pending >
190217 </ WebWorker >
191218 )
@@ -196,7 +223,7 @@ test("WebWorker.Pending renders only when no message has been received yet", asy
196223
197224test ( "WebWorker.Pending renders only when no error has been received yet" , async ( ) => {
198225 const { getByText, queryByText } = render (
199- < WebWorker >
226+ < WebWorker url = "/worker.js" >
200227 < WebWorker . Pending > pending</ WebWorker . Pending >
201228 </ WebWorker >
202229 )
@@ -209,7 +236,7 @@ test("An unrelated change in props does not update the Context", async () => {
209236 let one
210237 let two
211238 const { rerender } = render (
212- < WebWorker >
239+ < WebWorker url = "/worker.js" >
213240 < WebWorker . Pending >
214241 { value => {
215242 one = value
@@ -218,7 +245,7 @@ test("An unrelated change in props does not update the Context", async () => {
218245 </ WebWorker >
219246 )
220247 rerender (
221- < WebWorker someProp >
248+ < WebWorker url = "/worker.js" someProp >
222249 < WebWorker . Pending >
223250 { value => {
224251 two = value
0 commit comments