From 65de61ba0d7ffb5e19bb3e0d95748d40de2483c2 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 2 Feb 2024 14:30:53 +0000 Subject: [PATCH] test: add compliance output tests for `output()` (#54217) Adds compliance output tests for `output()` to verify that we are emitting proper full compilation output, as well as proper partial compilation output that can be linked to match the full output. PR Close #54217 --- .../src/ngtsc/testing/fake_core/index.ts | 5 + .../output_function/GOLDEN_PARTIAL.js | 114 ++++++++++++++++++ .../output_function/TEST_CASES.json | 50 ++++++++ .../output_function/mixed_variants.js | 12 ++ .../output_function/mixed_variants.ts | 14 +++ .../output_function/output_in_component.js | 9 ++ .../output_function/output_in_component.ts | 11 ++ .../output_function/output_in_directive.js | 9 ++ .../output_function/output_in_directive.ts | 10 ++ 9 files changed, 234 insertions(+) create mode 100644 packages/compiler-cli/test/compliance/test_cases/output_function/GOLDEN_PARTIAL.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/output_function/TEST_CASES.json create mode 100644 packages/compiler-cli/test/compliance/test_cases/output_function/mixed_variants.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/output_function/mixed_variants.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/output_function/output_in_component.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/output_function/output_in_component.ts create mode 100644 packages/compiler-cli/test/compliance/test_cases/output_function/output_in_directive.js create mode 100644 packages/compiler-cli/test/compliance/test_cases/output_function/output_in_directive.ts diff --git a/packages/compiler-cli/src/ngtsc/testing/fake_core/index.ts b/packages/compiler-cli/src/ngtsc/testing/fake_core/index.ts index 2b817cebf83..813e482404e 100644 --- a/packages/compiler-cli/src/ngtsc/testing/fake_core/index.ts +++ b/packages/compiler-cli/src/ngtsc/testing/fake_core/index.ts @@ -172,3 +172,8 @@ export const viewChild: any = null!; export const viewChildren: any = null!; export const contentChild: any = null!; export const contentChildren: any = null!; + +/** Initializer-based output() API. */ +export function output(_opts?: {alias?: string}): EventEmitter { + return null!; +} diff --git a/packages/compiler-cli/test/compliance/test_cases/output_function/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/output_function/GOLDEN_PARTIAL.js new file mode 100644 index 00000000000..567dc552b0d --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/output_function/GOLDEN_PARTIAL.js @@ -0,0 +1,114 @@ +/**************************************************************************************************** + * PARTIAL FILE: output_in_directive.js + ****************************************************************************************************/ +import { Directive, output } from '@angular/core'; +import * as i0 from "@angular/core"; +export class TestDir { + constructor() { + this.a = output(); + this.b = output({}); + this.c = output({ alias: 'cPublic' }); + } +} +TestDir.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: TestDir, deps: [], target: i0.ɵɵFactoryTarget.Directive }); +TestDir.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: TestDir, isStandalone: true, outputs: { a: "a", b: "b", c: "cPublic" }, ngImport: i0 }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: TestDir, decorators: [{ + type: Directive, + args: [{ + standalone: true, + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: output_in_directive.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class TestDir { + a: import("@angular/core").EventEmitter; + b: import("@angular/core").EventEmitter; + c: import("@angular/core").EventEmitter; + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵdir: i0.ɵɵDirectiveDeclaration; +} + +/**************************************************************************************************** + * PARTIAL FILE: output_in_component.js + ****************************************************************************************************/ +import { Component, output } from '@angular/core'; +import * as i0 from "@angular/core"; +export class TestComp { + constructor() { + this.a = output(); + this.b = output({}); + this.c = output({ alias: 'cPublic' }); + } +} +TestComp.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: TestComp, deps: [], target: i0.ɵɵFactoryTarget.Component }); +TestComp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: TestComp, isStandalone: true, selector: "ng-component", outputs: { a: "a", b: "b", c: "cPublic" }, ngImport: i0, template: 'Works', isInline: true }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: TestComp, decorators: [{ + type: Component, + args: [{ + standalone: true, + template: 'Works', + }] + }] }); + +/**************************************************************************************************** + * PARTIAL FILE: output_in_component.d.ts + ****************************************************************************************************/ +import * as i0 from "@angular/core"; +export declare class TestComp { + a: import("@angular/core").EventEmitter; + b: import("@angular/core").EventEmitter; + c: import("@angular/core").EventEmitter; + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; +} + +/**************************************************************************************************** + * PARTIAL FILE: mixed_variants.js + ****************************************************************************************************/ +import { Directive, EventEmitter, Output, output } from '@angular/core'; +import * as i0 from "@angular/core"; +export class TestDir { + constructor() { + this.click1 = output(); + this.click2 = output(); + this._bla = output({ alias: 'decoratorPublicName' }); + this.clickDecorator1 = new EventEmitter(); + this.clickDecorator2 = new EventEmitter(); + this._blaDecorator = new EventEmitter(); + } +} +TestDir.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: TestDir, deps: [], target: i0.ɵɵFactoryTarget.Directive }); +TestDir.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: TestDir, isStandalone: true, outputs: { click1: "click1", click2: "click2", _bla: "decoratorPublicName", clickDecorator1: "clickDecorator1", clickDecorator2: "clickDecorator2", _blaDecorator: "decoratorPublicName" }, ngImport: i0 }); +i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: TestDir, decorators: [{ + type: Directive, + args: [{ + standalone: true, + }] + }], propDecorators: { clickDecorator1: [{ + type: Output + }], clickDecorator2: [{ + type: Output + }], _blaDecorator: [{ + type: Output, + args: ['decoratorPublicName'] + }] } }); + +/**************************************************************************************************** + * PARTIAL FILE: mixed_variants.d.ts + ****************************************************************************************************/ +import { EventEmitter } from '@angular/core'; +import * as i0 from "@angular/core"; +export declare class TestDir { + click1: EventEmitter; + click2: EventEmitter; + _bla: EventEmitter; + clickDecorator1: EventEmitter; + clickDecorator2: EventEmitter; + _blaDecorator: EventEmitter; + static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵdir: i0.ɵɵDirectiveDeclaration; +} + diff --git a/packages/compiler-cli/test/compliance/test_cases/output_function/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/output_function/TEST_CASES.json new file mode 100644 index 00000000000..504799c4ca4 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/output_function/TEST_CASES.json @@ -0,0 +1,50 @@ +{ + "$schema": "../test_case_schema.json", + "cases": [ + { + "description": "should generate an output mapping for the directive", + "inputFiles": ["output_in_directive.ts"], + "expectations": [ + { + "files": [ + { + "expected": "output_in_directive.js", + "generated": "output_in_directive.js" + } + ], + "failureMessage": "Incorrect definition" + } + ] + }, + { + "description": "should generate an output mapping for the component", + "inputFiles": ["output_in_component.ts"], + "expectations": [ + { + "files": [ + { + "expected": "output_in_component.js", + "generated": "output_in_component.js" + } + ], + "failureMessage": "Incorrect definition" + } + ] + }, + { + "description": "should handle a mix of decorator-based and initializer-based outputs", + "inputFiles": ["mixed_variants.ts"], + "expectations": [ + { + "files": [ + { + "expected": "mixed_variants.js", + "generated": "mixed_variants.js" + } + ], + "failureMessage": "Incorrect output" + } + ] + } + ] +} diff --git a/packages/compiler-cli/test/compliance/test_cases/output_function/mixed_variants.js b/packages/compiler-cli/test/compliance/test_cases/output_function/mixed_variants.js new file mode 100644 index 00000000000..dd4d1fcf00d --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/output_function/mixed_variants.js @@ -0,0 +1,12 @@ +TestDir.ɵdir = /* @__PURE__ */ $r3$.ɵɵdefineDirective({ + … + outputs: { + click1: "click1", + click2: "click2", + _bla: "decoratorPublicName", + clickDecorator1: "clickDecorator1", + clickDecorator2: "clickDecorator2", + _blaDecorator: "decoratorPublicName" + }, + … +}); diff --git a/packages/compiler-cli/test/compliance/test_cases/output_function/mixed_variants.ts b/packages/compiler-cli/test/compliance/test_cases/output_function/mixed_variants.ts new file mode 100644 index 00000000000..af19b3e1992 --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/output_function/mixed_variants.ts @@ -0,0 +1,14 @@ +import {Directive, EventEmitter, Output, output} from '@angular/core'; + +@Directive({ + standalone: true, +}) +export class TestDir { + click1 = output(); + click2 = output(); + _bla = output({alias: 'decoratorPublicName'}); + + @Output() clickDecorator1 = new EventEmitter(); + @Output() clickDecorator2 = new EventEmitter(); + @Output('decoratorPublicName') _blaDecorator = new EventEmitter(); +} diff --git a/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_component.js b/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_component.js new file mode 100644 index 00000000000..e0d8f9d0ecd --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_component.js @@ -0,0 +1,9 @@ +TestComp.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({ + … + outputs: { + a: "a", + b: "b", + c: "cPublic" + }, + … + }); diff --git a/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_component.ts b/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_component.ts new file mode 100644 index 00000000000..442bda01aab --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_component.ts @@ -0,0 +1,11 @@ +import {Component, output} from '@angular/core'; + +@Component({ + standalone: true, + template: 'Works', +}) +export class TestComp { + a = output(); + b = output({}); + c = output({alias: 'cPublic'}); +} diff --git a/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_directive.js b/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_directive.js new file mode 100644 index 00000000000..5bcbb73248e --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_directive.js @@ -0,0 +1,9 @@ +TestDir.ɵdir = /*@__PURE__*/ $r3$.ɵɵdefineDirective({ + … + outputs: { + a: "a", + b: "b", + c: "cPublic" + }, + … + }); diff --git a/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_directive.ts b/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_directive.ts new file mode 100644 index 00000000000..c3fdaa7a8de --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/output_function/output_in_directive.ts @@ -0,0 +1,10 @@ +import {Directive, output} from '@angular/core'; + +@Directive({ + standalone: true, +}) +export class TestDir { + a = output(); + b = output({}); + c = output({alias: 'cPublic'}); +}