@@ -49,34 +49,29 @@ describe('useSubscription', () => {
4949 return replaySubject ;
5050 }
5151
52- // Mimic createSubscription API to simplify testing
53- function createSubscription ( { getCurrentValue, subscribe} ) {
54- return function Subscription ( { children, source} ) {
52+ it ( 'supports basic subscription pattern' , ( ) => {
53+ function Subscription ( { source} ) {
5554 const value = useSubscription (
56- React . useMemo ( ( ) => ( { source, getCurrentValue, subscribe} ) , [ source ] ) ,
55+ ( ) => ( {
56+ getCurrentValue : ( ) => source . getValue ( ) ,
57+ subscribe : callback => {
58+ const subscription = source . subscribe ( callback ) ;
59+ return ( ) => subscription . unsubscribe ( ) ;
60+ } ,
61+ } ) ,
62+ [ source ] ,
5763 ) ;
64+ return < Child value = { value } /> ;
65+ }
5866
59- return React . createElement ( children , { value} ) ;
60- } ;
61- }
62-
63- it ( 'supports basic subscription pattern' , ( ) => {
64- const Subscription = createSubscription ( {
65- getCurrentValue : source => source . getValue ( ) ,
66- subscribe : ( source , callback ) => {
67- const subscription = source . subscribe ( callback ) ;
68- return ( ) => subscription . unsubscribe ( ) ;
69- } ,
70- } ) ;
67+ function Child ( { value = 'default' } ) {
68+ Scheduler . yieldValue ( value ) ;
69+ return null ;
70+ }
7171
7272 const observable = createBehaviorSubject ( ) ;
7373 const renderer = ReactTestRenderer . create (
74- < Subscription source = { observable } >
75- { ( { value = 'default' } ) => {
76- Scheduler . yieldValue ( value ) ;
77- return null ;
78- } }
79- </ Subscription > ,
74+ < Subscription source = { observable } /> ,
8075 { unstable_isConcurrent : true } ,
8176 ) ;
8277
@@ -94,30 +89,36 @@ describe('useSubscription', () => {
9489 } ) ;
9590
9691 it ( 'should support observable types like RxJS ReplaySubject' , ( ) => {
97- const Subscription = createSubscription ( {
98- getCurrentValue : source => {
99- let currentValue ;
100- source
101- . subscribe ( value => {
102- currentValue = value ;
103- } )
104- . unsubscribe ( ) ;
105- return currentValue ;
106- } ,
107- subscribe : ( source , callback ) => {
108- const subscription = source . subscribe ( callback ) ;
109- return ( ) => subscription . unsubscribe ;
110- } ,
111- } ) ;
92+ function Subscription ( { source} ) {
93+ const value = useSubscription (
94+ ( ) => ( {
95+ getCurrentValue : ( ) => {
96+ let currentValue ;
97+ source
98+ . subscribe ( tempValue => {
99+ currentValue = tempValue ;
100+ } )
101+ . unsubscribe ( ) ;
102+ return currentValue ;
103+ } ,
104+ subscribe : callback => {
105+ const subscription = source . subscribe ( callback ) ;
106+ return ( ) => subscription . unsubscribe ;
107+ } ,
108+ } ) ,
109+ [ source ] ,
110+ ) ;
111+ return < Child value = { value } /> ;
112+ }
112113
113- function render ( { value = 'default' } ) {
114+ function Child ( { value = 'default' } ) {
114115 Scheduler . yieldValue ( value ) ;
115116 return null ;
116117 }
117118
118119 let observable = createReplaySubject ( 'initial' ) ;
119120 const renderer = ReactTestRenderer . create (
120- < Subscription source = { observable } > { render } </ Subscription > ,
121+ < Subscription source = { observable } / >,
121122 { unstable_isConcurrent : true } ,
122123 ) ;
123124 expect ( Scheduler ) . toFlushAndYield ( [ 'initial' ] ) ;
@@ -128,20 +129,26 @@ describe('useSubscription', () => {
128129
129130 // Unsetting the subscriber prop should reset subscribed values
130131 observable = createReplaySubject ( undefined ) ;
131- renderer . update ( < Subscription source = { observable } > { render } </ Subscription > ) ;
132+ renderer . update ( < Subscription source = { observable } / >) ;
132133 expect ( Scheduler ) . toFlushAndYield ( [ 'default' ] ) ;
133134 } ) ;
134135
135136 it ( 'should unsubscribe from old subscribables and subscribe to new subscribables when props change' , ( ) => {
136- const Subscription = createSubscription ( {
137- getCurrentValue : source => source . getValue ( ) ,
138- subscribe : ( source , callback ) => {
139- const subscription = source . subscribe ( callback ) ;
140- return ( ) => subscription . unsubscribe ( ) ;
141- } ,
142- } ) ;
137+ function Subscription ( { source} ) {
138+ const value = useSubscription (
139+ ( ) => ( {
140+ getCurrentValue : ( ) => source . getValue ( ) ,
141+ subscribe : callback => {
142+ const subscription = source . subscribe ( callback ) ;
143+ return ( ) => subscription . unsubscribe ( ) ;
144+ } ,
145+ } ) ,
146+ [ source ] ,
147+ ) ;
148+ return < Child value = { value } /> ;
149+ }
143150
144- function render ( { value = 'default' } ) {
151+ function Child ( { value = 'default' } ) {
145152 Scheduler . yieldValue ( value ) ;
146153 return null ;
147154 }
@@ -150,15 +157,15 @@ describe('useSubscription', () => {
150157 const observableB = createBehaviorSubject ( 'b-0' ) ;
151158
152159 const renderer = ReactTestRenderer . create (
153- < Subscription source = { observableA } > { render } </ Subscription > ,
160+ < Subscription source = { observableA } / >,
154161 { unstable_isConcurrent : true } ,
155162 ) ;
156163
157164 // Updates while subscribed should re-render the child component
158165 expect ( Scheduler ) . toFlushAndYield ( [ 'a-0' ] ) ;
159166
160167 // Unsetting the subscriber prop should reset subscribed values
161- renderer . update ( < Subscription source = { observableB } > { render } </ Subscription > ) ;
168+ renderer . update ( < Subscription source = { observableB } / >) ;
162169 expect ( Scheduler ) . toFlushAndYield ( [ 'b-0' ] ) ;
163170
164171 // Updates to the old subscribable should not re-render the child component
@@ -173,18 +180,29 @@ describe('useSubscription', () => {
173180 it ( 'should ignore values emitted by a new subscribable until the commit phase' , ( ) => {
174181 const log = [ ] ;
175182
176- function Child ( { value} ) {
177- Scheduler . yieldValue ( 'Child: ' + value ) ;
178- return null ;
183+ function Subscription ( { source} ) {
184+ const value = useSubscription (
185+ ( ) => ( {
186+ getCurrentValue : ( ) => source . getValue ( ) ,
187+ subscribe : callback => {
188+ const subscription = source . subscribe ( callback ) ;
189+ return ( ) => subscription . unsubscribe ( ) ;
190+ } ,
191+ } ) ,
192+ [ source ] ,
193+ ) ;
194+ return < Outer value = { value } /> ;
179195 }
180196
181- const Subscription = createSubscription ( {
182- getCurrentValue : source => source . getValue ( ) ,
183- subscribe : ( source , callback ) => {
184- const subscription = source . subscribe ( callback ) ;
185- return ( ) => subscription . unsubscribe ( ) ;
186- } ,
187- } ) ;
197+ function Outer ( { value} ) {
198+ Scheduler . yieldValue ( 'Outer: ' + value ) ;
199+ return < Inner value = { value } /> ;
200+ }
201+
202+ function Inner ( { value} ) {
203+ Scheduler . yieldValue ( 'Inner: ' + value ) ;
204+ return null ;
205+ }
188206
189207 class Parent extends React . Component {
190208 state = { } ;
@@ -208,14 +226,7 @@ describe('useSubscription', () => {
208226 }
209227
210228 render ( ) {
211- return (
212- < Subscription source = { this . state . observed } >
213- { ( { value = 'default' } ) => {
214- Scheduler . yieldValue ( 'Subscriber: ' + value ) ;
215- return < Child value = { value } /> ;
216- } }
217- </ Subscription >
218- ) ;
229+ return < Subscription source = { this . state . observed } /> ;
219230 }
220231 }
221232
@@ -226,12 +237,12 @@ describe('useSubscription', () => {
226237 < Parent observed = { observableA } /> ,
227238 { unstable_isConcurrent : true } ,
228239 ) ;
229- expect ( Scheduler ) . toFlushAndYield ( [ 'Subscriber : a-0' , 'Child : a-0' ] ) ;
240+ expect ( Scheduler ) . toFlushAndYield ( [ 'Outer : a-0' , 'Inner : a-0' ] ) ;
230241 expect ( log ) . toEqual ( [ 'Parent.componentDidMount' ] ) ;
231242
232243 // Start React update, but don't finish
233244 renderer . update ( < Parent observed = { observableB } /> ) ;
234- expect ( Scheduler ) . toFlushAndYieldThrough ( [ 'Subscriber : b-0' ] ) ;
245+ expect ( Scheduler ) . toFlushAndYieldThrough ( [ 'Outer : b-0' ] ) ;
235246 expect ( log ) . toEqual ( [ 'Parent.componentDidMount' ] ) ;
236247
237248 // Emit some updates from the uncommitted subscribable
@@ -247,11 +258,11 @@ describe('useSubscription', () => {
247258 // But the intermediate ones should be ignored,
248259 // And the final rendered output should be the higher-priority observable.
249260 expect ( Scheduler ) . toFlushAndYield ( [
250- 'Child : b-0' ,
251- 'Subscriber : b-3' ,
252- 'Child : b-3' ,
253- 'Subscriber : a-0' ,
254- 'Child : a-0' ,
261+ 'Inner : b-0' ,
262+ 'Outer : b-3' ,
263+ 'Inner : b-3' ,
264+ 'Outer : a-0' ,
265+ 'Inner : a-0' ,
255266 ] ) ;
256267 expect ( log ) . toEqual ( [
257268 'Parent.componentDidMount' ,
@@ -263,18 +274,29 @@ describe('useSubscription', () => {
263274 it ( 'should not drop values emitted between updates' , ( ) => {
264275 const log = [ ] ;
265276
266- function Child ( { value} ) {
267- Scheduler . yieldValue ( 'Child: ' + value ) ;
268- return null ;
277+ function Subscription ( { source} ) {
278+ const value = useSubscription (
279+ ( ) => ( {
280+ getCurrentValue : ( ) => source . getValue ( ) ,
281+ subscribe : callback => {
282+ const subscription = source . subscribe ( callback ) ;
283+ return ( ) => subscription . unsubscribe ( ) ;
284+ } ,
285+ } ) ,
286+ [ source ] ,
287+ ) ;
288+ return < Outer value = { value } /> ;
269289 }
270290
271- const Subscription = createSubscription ( {
272- getCurrentValue : source => source . getValue ( ) ,
273- subscribe : ( source , callback ) => {
274- const subscription = source . subscribe ( callback ) ;
275- return ( ) => subscription . unsubscribe ( ) ;
276- } ,
277- } ) ;
291+ function Outer ( { value} ) {
292+ Scheduler . yieldValue ( 'Outer: ' + value ) ;
293+ return < Inner value = { value } /> ;
294+ }
295+
296+ function Inner ( { value} ) {
297+ Scheduler . yieldValue ( 'Inner: ' + value ) ;
298+ return null ;
299+ }
278300
279301 class Parent extends React . Component {
280302 state = { } ;
@@ -298,14 +320,7 @@ describe('useSubscription', () => {
298320 }
299321
300322 render ( ) {
301- return (
302- < Subscription source = { this . state . observed } >
303- { ( { value = 'default' } ) => {
304- Scheduler . yieldValue ( 'Subscriber: ' + value ) ;
305- return < Child value = { value } /> ;
306- } }
307- </ Subscription >
308- ) ;
323+ return < Subscription source = { this . state . observed } /> ;
309324 }
310325 }
311326
@@ -316,12 +331,12 @@ describe('useSubscription', () => {
316331 < Parent observed = { observableA } /> ,
317332 { unstable_isConcurrent : true } ,
318333 ) ;
319- expect ( Scheduler ) . toFlushAndYield ( [ 'Subscriber : a-0' , 'Child : a-0' ] ) ;
334+ expect ( Scheduler ) . toFlushAndYield ( [ 'Outer : a-0' , 'Inner : a-0' ] ) ;
320335 expect ( log ) . toEqual ( [ 'Parent.componentDidMount' ] ) ;
321336
322337 // Start React update, but don't finish
323338 renderer . update ( < Parent observed = { observableB } /> ) ;
324- expect ( Scheduler ) . toFlushAndYieldThrough ( [ 'Subscriber : b-0' ] ) ;
339+ expect ( Scheduler ) . toFlushAndYieldThrough ( [ 'Outer : b-0' ] ) ;
325340 expect ( log ) . toEqual ( [ 'Parent.componentDidMount' ] ) ;
326341
327342 // Emit some updates from the old subscribable
@@ -335,9 +350,9 @@ describe('useSubscription', () => {
335350 // We expect the new subscribable to finish rendering,
336351 // But then the updated values from the old subscribable should be used.
337352 expect ( Scheduler ) . toFlushAndYield ( [
338- 'Child : b-0' ,
339- 'Subscriber : a-2' ,
340- 'Child : a-2' ,
353+ 'Inner : b-0' ,
354+ 'Outer : a-2' ,
355+ 'Inner : a-2' ,
341356 ] ) ;
342357 expect ( log ) . toEqual ( [
343358 'Parent.componentDidMount' ,
@@ -356,12 +371,24 @@ describe('useSubscription', () => {
356371 } ) ;
357372
358373 it ( 'should guard against updates that happen after unmounting' , ( ) => {
359- const Subscription = createSubscription ( {
360- getCurrentValue : source => source . getValue ( ) ,
361- subscribe : ( source , callback ) => {
362- return source . subscribe ( callback ) ;
363- } ,
364- } ) ;
374+ function Subscription ( { source} ) {
375+ const value = useSubscription (
376+ ( ) => ( {
377+ getCurrentValue : ( ) => source . getValue ( ) ,
378+ subscribe : callback => {
379+ const unsubscribe = source . subscribe ( callback ) ;
380+ return ( ) => unsubscribe ( ) ;
381+ } ,
382+ } ) ,
383+ [ source ] ,
384+ ) ;
385+ return < Child value = { value } /> ;
386+ }
387+
388+ function Child ( { value} ) {
389+ Scheduler . yieldValue ( value ) ;
390+ return null ;
391+ }
365392
366393 const eventHandler = {
367394 _callbacks : [ ] ,
@@ -393,12 +420,7 @@ describe('useSubscription', () => {
393420 } ) ;
394421
395422 const renderer = ReactTestRenderer . create (
396- < Subscription source = { eventHandler } >
397- { ( { value} ) => {
398- Scheduler . yieldValue ( value ) ;
399- return null ;
400- } }
401- </ Subscription > ,
423+ < Subscription source = { eventHandler } /> ,
402424 { unstable_isConcurrent : true } ,
403425 ) ;
404426
0 commit comments