Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: The mock for bidirectional binding to a signal model is missing the model output event emitter #10942

Open
ytchenak opened this issue Feb 1, 2025 · 1 comment
Labels
bug Something isn't working

Comments

@ytchenak
Copy link

ytchenak commented Feb 1, 2025

Description of the bug

The mock for bidirectional binding to a signal model is missing the model output event emitter.
The ngMocks.output function cannot access the model's output using the model name with the 'Change' suffix.

An example of the bug

TypeError: ng_mocks_1.ngMocks.output(...).emit is not a function  

Important: The issue only appears if change detection occurs after the component is created. Otherwise, the bug does not manifest.

import { Component, model, signal } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { MockBuilder, ngMocks } from 'ng-mocks';

@Component({
  selector: 'app-signal',
  imports: [],
  template: ``,
})
export class SignalComponent {
  model = model('')
}
@Component({
  imports: [ SignalComponent],
  selector: 'app-target',
  template: `
    <h1>{{title()}}</h1>
    <app-signal [(model)]=title></app-signal>
  `,
})
export class TargetComponent {
  title = signal('test-default');
}

describe('issue-signal-model', () => {
  beforeEach( () => MockBuilder(TargetComponent) );

  it('issue-signal-model', () => {
    const fixture = TestBed.createComponent(TargetComponent);
    fixture.detectChanges();
    ngMocks.output('app-signal', 'modelChange').emit('test-new');
    fixture.detectChanges();
    expect(ngMocks.find('h1').nativeElement.innerHTML).toEqual('test-new');
  });

});

Expected vs actual behavior

  • Expected: The ngMocks.output function should always be able to access the signal model's output using the model name with the 'Change' suffix.
  • Actual: The function cannot find or emit the expected output event, leading to a TypeError.
@ytchenak ytchenak added the bug Something isn't working label Feb 1, 2025
@ytchenak ytchenak changed the title Bug: Bug: The mock for bidirectional binding to a signal model is missing the model output event emitter Feb 1, 2025
@ytchenak
Copy link
Author

ytchenak commented Feb 2, 2025

It seems that in the case of two-way binding to signal model, Angular adds an output to the component metadata, where the output name matches the model property, and its alias is the model property name with a 'Change' suffix.

I can fix this issue as follows:

diff --git a/libs/ng-mocks/src/lib/common/func.directive-io-parse.ts b/libs/ng-mocks/src/lib/common/func.directive-io-parse.ts
index d818160139..e2a8c59c61 100644
--- a/libs/ng-mocks/src/lib/common/func.directive-io-parse.ts
+++ b/libs/ng-mocks/src/lib/common/func.directive-io-parse.ts
@@ -8,6 +8,10 @@ export default function (param: DirectiveIo): DirectiveIoParsed {
       return { name };
     }
 
+    if (name + 'Change' === alias) {
+      return { name: alias }; // model output
+    }
+
     return { name, alias };
   }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant