11import React , { Component } from 'react' ;
2- import { render , cleanup , act } from '@testing-library/react/pure' ;
2+ import {
3+ render ,
4+ cleanup ,
5+ fireEvent ,
6+ act ,
7+ } from '@testing-library/react/pure' ;
38import {
49 view ,
510 store ,
@@ -187,7 +192,35 @@ describe('batching', () => {
187192 expect ( renderCount ) . toBe ( 2 ) ;
188193 } ) ;
189194
190- test ( 'should batch state changes inside native event listeners' , ( ) => {
195+ test ( 'should batch state changes in react event listeners' , ( ) => {
196+ let renderCount = 0 ;
197+ const counter = store ( { num : 0 } ) ;
198+ const MyComp = view ( ( ) => {
199+ renderCount += 1 ;
200+ return (
201+ < button
202+ type = "button"
203+ onClick = { ( ) => {
204+ counter . num += 1 ;
205+ counter . num += 1 ;
206+ } }
207+ >
208+ { counter . num }
209+ </ button >
210+ ) ;
211+ } ) ;
212+
213+ const { container } = render ( < MyComp /> ) ;
214+ const button = container . querySelector ( 'button' ) ;
215+ expect ( renderCount ) . toBe ( 1 ) ;
216+ expect ( container ) . toHaveTextContent ( '0' ) ;
217+ fireEvent . click ( button ) ;
218+ expect ( container ) . toHaveTextContent ( '2' ) ;
219+ expect ( renderCount ) . toBe ( 2 ) ;
220+ } ) ;
221+
222+ // TODO: batching native event handlers causes in input caret jumping bug
223+ test . skip ( 'should batch state changes inside native event listeners' , ( ) => {
191224 let renderCount = 0 ;
192225 const person = store ( { name : 'Bob' } ) ;
193226 const MyComp = view ( ( ) => {
@@ -198,15 +231,15 @@ describe('batching', () => {
198231 const { container } = render ( < MyComp /> ) ;
199232 expect ( renderCount ) . toBe ( 1 ) ;
200233 expect ( container ) . toHaveTextContent ( 'Bob' ) ;
201- const batched = act ( ( ) => {
234+ const handler = act ( ( ) => {
202235 person . name = 'Ann' ;
203236 person . name = 'Rick' ;
204237 } ) ;
205- document . body . addEventListener ( 'click' , batched ) ;
238+ document . body . addEventListener ( 'click' , handler ) ;
206239 document . body . dispatchEvent ( new Event ( 'click' ) ) ;
207240 expect ( container ) . toHaveTextContent ( 'Rick' ) ;
208241 expect ( renderCount ) . toBe ( 2 ) ;
209- document . body . removeEventListener ( 'click' , batched ) ;
242+ document . body . removeEventListener ( 'click' , handler ) ;
210243 } ) ;
211244
212245 // async/await is only batched when it is transpiled to promises and/or generators
@@ -314,6 +347,69 @@ describe('batching', () => {
314347 expect ( renderCount ) . toBe ( 2 ) ;
315348 } ) ;
316349
350+ test ( 'should batch changes in store methods' , ( ) => {
351+ let numOfRuns = 0 ;
352+ let name = '' ;
353+
354+ const myStore = store ( {
355+ firstName : 'My' ,
356+ lastName : 'Store' ,
357+ setName ( firstName , lastName ) {
358+ this . firstName = firstName ;
359+ this . lastName = lastName ;
360+ } ,
361+ } ) ;
362+
363+ const effect = autoEffect ( ( ) => {
364+ name = `${ myStore . firstName } ${ myStore . lastName } ` ;
365+ numOfRuns += 1 ;
366+ } ) ;
367+ expect ( name ) . toBe ( 'My Store' ) ;
368+ expect ( numOfRuns ) . toBe ( 1 ) ;
369+
370+ myStore . setName ( 'Awesome' , 'Stuff' ) ;
371+ expect ( name ) . toBe ( 'Awesome Stuff' ) ;
372+ expect ( numOfRuns ) . toBe ( 2 ) ;
373+
374+ clearEffect ( effect ) ;
375+ } ) ;
376+
377+ test ( 'should batch changes in store setters' , ( ) => {
378+ let numOfRuns = 0 ;
379+ let name = '' ;
380+
381+ const myStore = store ( {
382+ firstName : 'My' ,
383+ middleName : 'Little' ,
384+ lastName : 'Store' ,
385+ get name ( ) {
386+ return `${ this . firstName } ${ this . middleName } ${ this . lastName } ` ;
387+ } ,
388+ set name ( newName ) {
389+ const [ firstName , middleName , lastName ] = newName . split ( ' ' ) ;
390+ this . firstName = firstName ;
391+ this . middleName = middleName ;
392+ this . lastName = lastName ;
393+ } ,
394+ } ) ;
395+
396+ const effect = autoEffect ( ( ) => {
397+ name = myStore . name ;
398+ numOfRuns += 1 ;
399+ } ) ;
400+ expect ( name ) . toBe ( 'My Little Store' ) ;
401+ expect ( numOfRuns ) . toBe ( 1 ) ;
402+
403+ myStore . name = 'Awesome JS Stuff' ;
404+ expect ( name ) . toBe ( 'Awesome JS Stuff' ) ;
405+ expect ( myStore . name ) . toBe ( 'Awesome JS Stuff' ) ;
406+ // the reactions runs two times once for the setter call
407+ // and once for all the mutations inside the setter (alltogether)
408+ expect ( numOfRuns ) . toBe ( 3 ) ;
409+
410+ clearEffect ( effect ) ;
411+ } ) ;
412+
317413 test ( 'should not break Promises' , async ( ) => {
318414 await Promise . resolve ( 12 )
319415 . then ( value => {
0 commit comments