@@ -172,34 +172,6 @@ describe('row details', () => {
172172 grid . closeItemDetails ( { value : 'foo0' } ) ;
173173 expect ( cells [ 1 ] . hidden ) . to . be . true ;
174174 } ) ;
175-
176- it ( 'should invoke the body renderer when opening details' , ( ) => {
177- grid . renderer = sinon . spy ( ) ;
178-
179- openRowDetails ( 0 ) ;
180-
181- grid . renderer . args . forEach ( ( [ _root , _owner , model ] , index ) => {
182- if ( index === 0 ) {
183- expect ( model . detailsOpened ) . to . be . true ;
184- } else {
185- expect ( model . detailsOpened ) . to . be . false ;
186- }
187- } ) ;
188- } ) ;
189-
190- it ( 'should invoke the body renderer when closing details' , ( ) => {
191- grid . renderer = sinon . spy ( ) ;
192-
193- openRowDetails ( 0 ) ;
194-
195- grid . renderer . resetHistory ( ) ;
196-
197- closeRowDetails ( 0 ) ;
198-
199- grid . renderer . args . forEach ( ( [ _root , _owner , model ] ) => {
200- expect ( model . detailsOpened ) . to . be . false ;
201- } ) ;
202- } ) ;
203175 } ) ;
204176
205177 describe ( 'repeat' , ( ) => {
@@ -322,6 +294,81 @@ describe('row details', () => {
322294 } ) ;
323295 } ) ;
324296
297+ describe ( 'selective row update' , ( ) => {
298+ let renderer ;
299+
300+ beforeEach ( async ( ) => {
301+ grid = fixtureSync ( `
302+ <vaadin-grid style="width: 50px; height: 400px" size="100">
303+ <vaadin-grid-column></vaadin-grid-column>
304+ </vaadin-grid>
305+ ` ) ;
306+ grid . rowDetailsRenderer = simpleDetailsRenderer ;
307+ renderer = sinon . spy ( indexRenderer ) ;
308+ grid . querySelector ( 'vaadin-grid-column' ) . renderer = renderer ;
309+
310+ grid . dataProvider = infiniteDataProvider ;
311+ flushGrid ( grid ) ;
312+ bodyRows = getRows ( grid . $ . items ) ;
313+ await nextFrame ( ) ;
314+
315+ renderer . resetHistory ( ) ;
316+ } ) ;
317+
318+ it ( 'should only invoke the body renderer for the opened row' , ( ) => {
319+ openRowDetails ( 1 ) ;
320+
321+ expect ( renderer ) . to . be . calledOnce ;
322+ expect ( renderer . firstCall . args [ 2 ] . index ) . to . equal ( 1 ) ;
323+ expect ( renderer . firstCall . args [ 2 ] . detailsOpened ) . to . be . true ;
324+ } ) ;
325+
326+ it ( 'should only invoke the body renderer for the closed row' , ( ) => {
327+ openRowDetails ( 1 ) ;
328+ renderer . resetHistory ( ) ;
329+
330+ closeRowDetails ( 1 ) ;
331+
332+ expect ( renderer ) . to . be . calledOnce ;
333+ expect ( renderer . firstCall . args [ 2 ] . index ) . to . equal ( 1 ) ;
334+ expect ( renderer . firstCall . args [ 2 ] . detailsOpened ) . to . be . false ;
335+ } ) ;
336+
337+ it ( 'should only invoke the body renderer for the newly opened row' , ( ) => {
338+ openRowDetails ( 0 ) ;
339+ renderer . resetHistory ( ) ;
340+
341+ openRowDetails ( 2 ) ;
342+
343+ expect ( renderer ) . to . be . calledOnce ;
344+ expect ( renderer . firstCall . args [ 2 ] . index ) . to . equal ( 2 ) ;
345+ expect ( renderer . firstCall . args [ 2 ] . detailsOpened ) . to . be . true ;
346+ } ) ;
347+
348+ it ( 'should only invoke the body renderer for affected rows when replacing detailsOpenedItems' , ( ) => {
349+ openRowDetails ( 0 ) ;
350+ renderer . resetHistory ( ) ;
351+
352+ grid . detailsOpenedItems = [ grid . _dataProviderController . rootCache . items [ 2 ] ] ;
353+ flushGrid ( grid ) ;
354+
355+ expect ( renderer ) . to . be . calledTwice ;
356+ const renderedIndexes = renderer . getCalls ( ) . map ( ( call ) => call . args [ 2 ] . index ) ;
357+ expect ( renderedIndexes ) . to . include ( 0 ) ;
358+ expect ( renderedIndexes ) . to . include ( 2 ) ;
359+ } ) ;
360+
361+ it ( 'should not invoke the body renderer when detailsOpenedItems is set to the same value' , ( ) => {
362+ openRowDetails ( 1 ) ;
363+ renderer . resetHistory ( ) ;
364+
365+ grid . detailsOpenedItems = [ ...grid . detailsOpenedItems ] ;
366+ flushGrid ( grid ) ;
367+
368+ expect ( renderer ) . to . not . be . called ;
369+ } ) ;
370+ } ) ;
371+
325372 describe ( 'lazily set details renderer' , ( ) => {
326373 beforeEach ( async ( ) => {
327374 grid = fixtureSync ( `
0 commit comments