@@ -27,6 +27,7 @@ import { CURLY_TEST_COMPONENT, GLIMMER_TEST_COMPONENT } from './components';
2727import { assertElementShape , assertEmberishElement } from './dom/assertions' ;
2828import { assertingElement , toInnerHTML } from './dom/simple-utils' ;
2929import { equalTokens , isServerMarker , normalizeSnapshot } from './snapshot' ;
30+ import { defineComponent } from './test-helpers/define' ;
3031
3132type Expand < T > = T extends infer O ? { [ K in keyof O ] : O [ K ] } : never ;
3233type Present < T > = Exclude < T , null | undefined > ;
@@ -430,6 +431,151 @@ export class RenderTest implements IRenderTest {
430431 inTransaction ( result . env , ( ) => destroy ( result ) ) ;
431432 }
432433
434+ private assertEachCompareResults ( items ) {
435+ [ ...( this . element as unknown as HTMLElement ) . querySelectorAll ( '.test-item' ) ] . forEach (
436+ ( el , index ) => {
437+ let key = Array . isArray ( items [ index ] ) ? items [ index ] [ 0 ] : index ;
438+ let value = Array . isArray ( items [ index ] ) ? items [ index ] [ 1 ] : items [ index ] ;
439+
440+ QUnit . assert . equal ( el . innerText , `${ key } .${ value } ` ) ;
441+ }
442+ ) ;
443+ }
444+
445+ protected assertReactivity < T > (
446+ Klass : new ( ...args : any [ ] ) => { get value ( ) : T ; update : ( ) => void } ,
447+ shouldUpdate = true ,
448+ message ?: string
449+ ) {
450+ let instance ;
451+ let count = 0 ;
452+
453+ class TestComponent extends Klass {
454+ constructor ( ...args : unknown [ ] ) {
455+ super ( ...args ) ;
456+ // eslint-disable-next-line @typescript-eslint/no-this-alias
457+ instance = this ;
458+ }
459+
460+ override get value ( ) {
461+ count ++ ;
462+
463+ return super . value ;
464+ }
465+ }
466+
467+ if ( message ) {
468+ QUnit . assert . ok ( true , message ) ;
469+ }
470+
471+ let comp = defineComponent ( { } , `<div class="test">{{this.value}}</div>` , {
472+ strictMode : true ,
473+ definition : TestComponent ,
474+ } ) ;
475+
476+ this . renderComponent ( comp ) ;
477+
478+ QUnit . assert . equal ( count , 1 , `The count is 1` ) ;
479+
480+ instance . update ( ) ;
481+
482+ this . rerender ( ) ;
483+
484+ QUnit . assert . equal (
485+ count ,
486+ shouldUpdate ? 2 : 1 ,
487+ shouldUpdate ? `The count is updated` : `The could should not update`
488+ ) ;
489+
490+ this . assertStableRerender ( ) ;
491+ }
492+
493+ protected assertEachInReactivity (
494+ Klass : new ( ...args : any [ ] ) => { collection : number [ ] ; update : ( ) => void }
495+ ) {
496+ let instance : TestComponent ;
497+
498+ class TestComponent extends Klass {
499+ constructor ( ...args ) {
500+ super ( ...args ) ;
501+ // eslint-disable-next-line
502+ instance = this ;
503+ }
504+ }
505+
506+ let comp = defineComponent (
507+ { } ,
508+ `
509+ <ul>
510+ {{#each-in this.collection as |lhs rhs|}}
511+ <li class="test-item">{{lhs}}.{{rhs}}</li>
512+ {{/each-in}}
513+ </ul>
514+ ` ,
515+ {
516+ strictMode : true ,
517+ definition : TestComponent ,
518+ }
519+ ) ;
520+
521+ this . renderComponent ( comp ) ;
522+
523+ let { collection } = instance ;
524+
525+ this . assertEachCompareResults (
526+ Symbol . iterator in collection ? Array . from ( collection ) : Object . entries ( collection )
527+ ) ;
528+
529+ instance . update ( ) ;
530+
531+ this . rerender ( ) ;
532+
533+ this . assertEachCompareResults (
534+ Symbol . iterator in collection ? Array . from ( collection ) : Object . entries ( collection )
535+ ) ;
536+ }
537+
538+ protected assertEachReactivity (
539+ Klass : new ( ...args : any [ ] ) => { collection : number [ ] ; update : ( ) => void }
540+ ) {
541+ let instance : TestComponent ;
542+
543+ class TestComponent extends Klass {
544+ constructor ( ...args : any [ ] ) {
545+ super ( ...args ) ;
546+ // eslint-disable-next-line
547+ instance = this ;
548+ }
549+ }
550+
551+ let comp = defineComponent (
552+ { } ,
553+ `
554+ <ul>
555+ {{#each this.collection as |value index|}}
556+ <li class="test-item">{{index}}.{{value}}</li>
557+ {{/each}}
558+ </ul>
559+ ` ,
560+ {
561+ strictMode : true ,
562+ definition : TestComponent ,
563+ }
564+ ) ;
565+
566+ this . renderComponent ( comp ) ;
567+
568+ this . assertEachCompareResults ( Array . from ( instance . collection ) . map ( ( v , i ) => [ i , v ] ) ) ;
569+
570+ instance . update ( ) ;
571+
572+ this . rerender ( ) ;
573+
574+ this . assertEachCompareResults ( Array . from ( instance . collection ) . map ( ( v , i ) => [ i , v ] ) ) ;
575+
576+ this . assertStableRerender ( ) ;
577+ }
578+
433579 protected set ( key : string , value : unknown ) : void {
434580 this . context [ key ] = value ;
435581 dirtyTagFor ( this . context , key ) ;
0 commit comments