@@ -123,14 +123,43 @@ export async function render<SutType, WrapperType = SutType>(
123123
124124 await renderFixture ( componentProperties , componentInputs , componentOutputs ) ;
125125
126+ let renderedPropKeys = Object . keys ( componentProperties ) ;
127+ let renderedInputKeys = Object . keys ( componentInputs ) ;
128+ let renderedOutputKeys = Object . keys ( componentOutputs ) ;
126129 const rerender = async (
127- properties ?: Pick < RenderTemplateOptions < SutType > , 'componentProperties' | 'componentInputs' | 'componentOutputs' > ,
130+ properties ?: Pick <
131+ RenderTemplateOptions < SutType > ,
132+ 'componentProperties' | 'componentInputs' | 'componentOutputs' | 'detectChangesOnRender'
133+ > ,
128134 ) => {
129- await renderFixture (
130- properties ?. componentProperties ?? { } ,
131- properties ?. componentInputs ?? { } ,
132- properties ?. componentOutputs ?? { } ,
133- ) ;
135+ const newComponentInputs = properties ?. componentInputs ?? { } ;
136+ for ( const inputKey of renderedInputKeys ) {
137+ if ( ! Object . prototype . hasOwnProperty . call ( newComponentInputs , inputKey ) ) {
138+ delete ( fixture . componentInstance as any ) [ inputKey ] ;
139+ }
140+ }
141+ setComponentInputs ( fixture , newComponentInputs ) ;
142+ renderedInputKeys = Object . keys ( newComponentInputs ) ;
143+
144+ const newComponentOutputs = properties ?. componentOutputs ?? { } ;
145+ for ( const outputKey of renderedOutputKeys ) {
146+ if ( ! Object . prototype . hasOwnProperty . call ( newComponentOutputs , outputKey ) ) {
147+ delete ( fixture . componentInstance as any ) [ outputKey ] ;
148+ }
149+ }
150+ setComponentOutputs ( fixture , newComponentOutputs ) ;
151+ renderedOutputKeys = Object . keys ( newComponentOutputs ) ;
152+
153+ const newComponentProps = properties ?. componentProperties ?? { } ;
154+ const changes = updateProps ( fixture , renderedPropKeys , newComponentProps ) ;
155+ if ( hasOnChangesHook ( fixture . componentInstance ) ) {
156+ fixture . componentInstance . ngOnChanges ( changes ) ;
157+ }
158+ renderedPropKeys = Object . keys ( newComponentProps ) ;
159+
160+ if ( properties ?. detectChangesOnRender !== false ) {
161+ fixture . componentRef . injector . get ( ChangeDetectorRef ) . detectChanges ( ) ;
162+ }
134163 } ;
135164
136165 const changeInput = ( changedInputProperties : Partial < SutType > ) => {
@@ -360,6 +389,31 @@ function getChangesObj(oldProps: Record<string, any> | null, newProps: Record<st
360389 ) ;
361390}
362391
392+ function updateProps < SutType > (
393+ fixture : ComponentFixture < SutType > ,
394+ prevRenderedPropsKeys : string [ ] ,
395+ newProps : Record < string , any > ,
396+ ) {
397+ const componentInstance = fixture . componentInstance as Record < string , any > ;
398+ const simpleChanges : SimpleChanges = { } ;
399+
400+ for ( const key of prevRenderedPropsKeys ) {
401+ if ( ! Object . prototype . hasOwnProperty . call ( newProps , key ) ) {
402+ simpleChanges [ key ] = new SimpleChange ( componentInstance [ key ] , undefined , false ) ;
403+ delete componentInstance [ key ] ;
404+ }
405+ }
406+
407+ for ( const [ key , value ] of Object . entries ( newProps ) ) {
408+ if ( value !== componentInstance [ key ] ) {
409+ simpleChanges [ key ] = new SimpleChange ( componentInstance [ key ] , value , false ) ;
410+ }
411+ }
412+ setComponentProperties ( fixture , newProps ) ;
413+
414+ return simpleChanges ;
415+ }
416+
363417function addAutoDeclarations < SutType > (
364418 sut : Type < SutType > | string ,
365419 {
0 commit comments