@@ -475,5 +475,179 @@ describe('NgJestCompiler', () => {
475
475
], MyComp);
476
476
` ) ;
477
477
} ) ;
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
+ ) ;
478
652
} ) ;
479
653
} ) ;
0 commit comments