@@ -475,5 +475,179 @@ describe('NgJestCompiler', () => {
475475 ], MyComp);
476476 ` ) ;
477477 } ) ;
478+
479+ it . failing ( 'should capture constructor type metadata with `emitDecoratorMetadata` enabled' , ( ) => {
480+ const { code, diagnostics } = transformCjs (
481+ `
482+ import {Directive} from '@angular/core';
483+ import {MyOtherClass} from './other-file';
484+
485+ @Directive()
486+ export class MyDir {
487+ constructor(other: MyOtherClass) {}
488+ }
489+ ` ,
490+ { emitDecoratorMetadata : true } ,
491+ ) ;
492+
493+ expect ( diagnostics . length ) . toBe ( 0 ) ;
494+ expect ( code ) . toContain ( 'const other_file_1 = require("./other-file");' ) ;
495+ // This is actual output code
496+ // `
497+ // MyDir.ctorParameters = () => [
498+ // { type: other_file_1.MyOtherClass }
499+ // ];
500+ // exports.MyDir = MyDir = tslib_1.__decorate([
501+ // (0, core_1.Directive)(),
502+ // tslib_1.__metadata("design:paramtypes", [typeof (_a = typeof other_file_1.MyOtherClass !== \\"undefined\\" && other_file_1.MyOtherClass) === \\"function\\" ? _a : Object]])
503+ // ], MyDir);
504+ // `
505+ expect ( code ) . toContain ( dedent `
506+ MyDir.ctorParameters = () => [
507+ { type: other_file_1.MyOtherClass }
508+ ];
509+ exports.MyDir = MyDir = tslib_1.__decorate([
510+ (0, core_1.Directive)(),
511+ tslib_1.__metadata("design:paramtypes", Object])
512+ ], MyDir);
513+ ` ) ;
514+ } ) ;
515+
516+ it . failing ( 'should properly serialize constructor parameter with external qualified name type' , ( ) => {
517+ // This test doesn't pass because `transpileModule` can't resolve `import *`
518+ const { code, diagnostics } = transformCjs ( `
519+ import {Directive} from '@angular/core';
520+ import * as externalFile from './other-file';
521+
522+ @Directive()
523+ export class MyDir {
524+ constructor(other: externalFile.MyOtherClass) {}
525+ }
526+ ` ) ;
527+
528+ expect ( diagnostics . length ) . toBe ( 0 ) ;
529+ expect ( code ) . toContain ( 'const externalFile = require("./other-file");' ) ;
530+ // This is actual output code
531+ // `
532+ // MyDir.ctorParameters = () => [
533+ // { type: undefined }
534+ // ];
535+ // exports.MyDir = MyDir = tslib_1.__decorate([
536+ // (0, core_1.Directive)()
537+ // ], MyDir);
538+ // `
539+ expect ( code ) . toContain ( dedent `
540+ MyDir.ctorParameters = () => [
541+ { type: externalFile.MyOtherClass }
542+ ];
543+ exports.MyDir = MyDir = tslib_1.__decorate([
544+ (0, core_1.Directive)()
545+ ], MyDir);
546+ ` ) ;
547+ } ) ;
548+
549+ it . failing ( 'should not capture constructor parameter types when not resolving to a value' , ( ) => {
550+ // This test doesn't pass because `transpileModule` can't resolve `import *`
551+ const { code, diagnostics } = transformCjs ( `
552+ import {Directive, Inject} from '@angular/core';
553+ import * as angular from './external';
554+ import {IOverlay, KeyCodes} from './external';
555+ import TypeFromDefaultImport from './external';
556+
557+ @Directive()
558+ export class MyDir {
559+ constructor(@Inject('$state') param: angular.IState,
560+ @Inject('$overlay') other: IOverlay,
561+ @Inject('$default') fromDefaultImport: TypeFromDefaultImport,
562+ @Inject('$keyCodes') keyCodes: KeyCodes) {}
563+ }
564+ ` ) ;
565+
566+ expect ( diagnostics . length ) . toBe ( 0 ) ;
567+ // This is actual output code
568+ // `
569+ // "\\"use strict\\";
570+ // Object.defineProperty(exports, \\"__esModule\\", { value: true });
571+ // exports.MyDir = void 0;
572+ // const tslib_1 = require(\\"tslib\\");
573+ // const core_1 = require(\\"@angular/core\\");
574+ // const external_1 = require(\\"./external\\");
575+ // const external_2 = tslib_1.__importDefault(require(\\"./external\\"));
576+ // let MyDir = class MyDir {
577+ // constructor(param, other, fromDefaultImport, keyCodes) { }
578+ // };
579+ // exports.MyDir = MyDir;
580+ // MyDir.ctorParameters = () => [
581+ // { type: undefined, decorators: [{ type: core_1.Inject, args: ['$state',] }] },
582+ // { type: external_1.IOverlay, decorators: [{ type: core_1.Inject, args: ['$overlay',] }] },
583+ // { type: external_2.default, decorators: [{ type: core_1.Inject, args: ['$default',] }] },
584+ // { type: external_1.KeyCodes, decorators: [{ type: core_1.Inject, args: ['$keyCodes',] }] }
585+ // ];
586+ // exports.MyDir = MyDir = tslib_1.__decorate([
587+ // (0, core_1.Directive)()
588+ // ], MyDir);
589+ // "
590+ // `
591+ expect ( code ) . not . toContain ( 'external' ) ;
592+ expect ( code ) . toContain ( dedent `
593+ MyDir.ctorParameters = () => [
594+ { type: undefined, decorators: [{ type: core_1.Inject, args: ['$state',] }] },
595+ { type: undefined, decorators: [{ type: core_1.Inject, args: ['$overlay',] }] },
596+ { type: undefined, decorators: [{ type: core_1.Inject, args: ['$default',] }] },
597+ { type: undefined, decorators: [{ type: core_1.Inject, args: ['$keyCodes',] }] }
598+ ];
599+ exports.MyDir = MyDir = tslib_1.__decorate([
600+ (0, core_1.Directive)()
601+ ], MyDir);
602+ ` ) ;
603+ } ) ;
604+
605+ it . failing (
606+ 'should allow for type-only references to be removed with `emitDecoratorMetadata` from custom decorators' ,
607+ ( ) => {
608+ const { code, diagnostics } = transformCjs (
609+ `
610+ import { ExternalInterface } from './external-interface';
611+
612+ export function CustomDecorator() {
613+ return <T>(target, propertyKey, descriptor: TypedPropertyDescriptor<T>) => {}
614+ }
615+
616+ export class Foo {
617+ @CustomDecorator() static test(): ExternalInterface { return {}; }
618+ }
619+ ` ,
620+ { emitDecoratorMetadata : true } ,
621+ ) ;
622+
623+ expect ( diagnostics . length ) . toBe ( 0 ) ;
624+ // This is actual output code
625+ // `
626+ // "\\"use strict\\";
627+ // var _a;
628+ // Object.defineProperty(exports, \\"__esModule\\", { value: true });
629+ // exports.Foo = void 0;
630+ // exports.CustomDecorator = CustomDecorator;
631+ // const tslib_1 = require(\\"tslib\\");
632+ // const external_interface_1 = require(\\"./external-interface\\");
633+ // function CustomDecorator() {
634+ // return (target, propertyKey, descriptor) => { };
635+ // }
636+ // class Foo {
637+ // static test() { return {}; }
638+ // }
639+ // exports.Foo = Foo;
640+ // tslib_1.__decorate([
641+ // CustomDecorator(),
642+ // tslib_1.__metadata(\\"design:type\\", Function),
643+ // tslib_1.__metadata(\\"design:paramtypes\\", []),
644+ // tslib_1.__metadata(\\"design:returntype\\", typeof (_a = typeof external_interface_1.ExternalInterface !== \\"undefined\\" && external_interface_1.ExternalInterface) === \\"function\\" ? _a : Object)
645+ // ], Foo, \\"test\\", null);
646+ // "
647+ // `
648+ expect ( code ) . not . toContain ( 'ExternalInterface' ) ;
649+ expect ( code ) . toContain ( 'metadata("design:returntype", Object)' ) ;
650+ } ,
651+ ) ;
478652 } ) ;
479653} ) ;
0 commit comments