Example #1
0
        it('should listen to window events', () => {
          const handleEventSpy = jasmine.createSpy('handleEvent');
          const addListenerSpy = spyOn(window, 'addEventListener');
          const removeListenerSpy = spyOn(window, 'removeEventListener');
          const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
              NodeFlags.None, null, null, 0, 'button', null, null, [['window', 'windowClick']],
              handleEventSpy)]));

          expect(addListenerSpy).toHaveBeenCalled();
          expect(addListenerSpy.calls.mostRecent().args[0]).toBe('windowClick');
          addListenerSpy.calls.mostRecent().args[1]({name: 'windowClick'});

          expect(handleEventSpy).toHaveBeenCalled();
          const handleEventArgs = handleEventSpy.calls.mostRecent().args;
          expect(handleEventArgs[0]).toBe(view);
          expect(handleEventArgs[1]).toBe('window:windowClick');
          expect(handleEventArgs[2]).toBeTruthy();

          Services.destroyView(view);

          expect(removeListenerSpy).toHaveBeenCalled();
        });
Example #2
0
        it(`should update ${ArgumentType[inlineDynamic]}`, () => {

          const {view, rootNodes} = createAndGetRootNodes(compViewDef(
              [
                elementDef(
                    NodeFlags.None, null, null, 0, 'input', null,
                    [
                      [BindingType.ElementProperty, 'title', SecurityContext.NONE],
                      [BindingType.ElementProperty, 'value', SecurityContext.NONE]
                    ]),
              ],
              null, (check, view) => {
                checkNodeInlineOrDynamic(check, view, 0, inlineDynamic, ['v1', 'v2']);
              }));

          Services.checkAndUpdateView(view);

          const el = rootNodes[0];
          expect(getDOM().getProperty(el, 'title')).toBe('v1');
          expect(getDOM().getProperty(el, 'value')).toBe('v2');

          expect(getDOM().getAttribute(el, 'ng-reflect-title')).toBe('v1');
        });
Example #3
0
    it('should create and attach component views', () => {
      let instance: AComp = undefined !;
      class AComp {
        constructor() { instance = this; }
      }

      const {view, rootNodes} = createAndGetRootNodes(compViewDef([
        elementDef(
            0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
            () => compViewDef([
              elementDef(0, NodeFlags.None, null, null, 0, 'span'),
            ])),
        directiveDef(1, NodeFlags.Component, null, 0, AComp, []),
      ]));

      const compView = asElementData(view, 0).componentView;

      expect(compView.context).toBe(instance);
      expect(compView.component).toBe(instance);

      const compRootEl = getDOM().childNodes(rootNodes[0])[0];
      expect(getDOM().nodeName(compRootEl).toLowerCase()).toBe('span');
    });
Example #4
0
      it('should destroy component views', () => {
        const log: string[] = [];

        class AComp {}

        class ChildProvider {
          ngOnDestroy() { log.push('ngOnDestroy'); }
        }

        const {view, rootNodes} = createAndGetRootNodes(compViewDef([
          elementDef(
              0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
              () => compViewDef([
                elementDef(0, NodeFlags.None, null, null, 1, 'span'),
                directiveDef(1, NodeFlags.OnDestroy, null, 0, ChildProvider, [])
              ])),
          directiveDef(1, NodeFlags.Component, null, 0, AComp, [], null, null, ),
        ]));

        Services.destroyView(view);

        expect(log).toEqual(['ngOnDestroy']);
      });
Example #5
0
    it('should project already attached embedded views', () => {
      class CreateViewService {
        constructor(templateRef: TemplateRef<any>, viewContainerRef: ViewContainerRef) {
          viewContainerRef.createEmbeddedView(templateRef);
        }
      }

      const {view, rootNodes} = createAndGetRootNodes(compViewDef(hostElDef(
          [
            anchorDef(NodeFlags.HasEmbeddedViews, null, 0, 1, null, embeddedViewDef([textDef(
                                                                        null, ['a'])])),
            directiveDef(
                NodeFlags.None, null, 0, CreateViewService, [TemplateRef, ViewContainerRef])
          ],
          [elementDef(NodeFlags.None, null, null, 1, 'div'), ngContentDef(null, 0)])));

      const anchor = asElementData(view, 2);
      expect((getDOM().childNodes(getDOM().firstChild(rootNodes[0]))[0]))
          .toBe(anchor.renderElement);
      const embeddedView = anchor.embeddedViews[0];
      expect((getDOM().childNodes(getDOM().firstChild(rootNodes[0]))[1]))
          .toBe(asTextData(embeddedView, 0).renderText);
    });
      it('should dirty check component views', () => {
        let value: any;
        class AComp {
          a: any;
        }

        const update = jasmine.createSpy('updater').and.callFake((view: ViewData) => {
          setCurrentNode(view, 0);
          checkNodeInline(value);
        });

        const {view, rootNodes} = createAndGetRootNodes(
          compViewDef([
            elementDef(NodeFlags.None, null, null, 1, 'div'),
            directiveDef(NodeFlags.None, null, 0, AComp, [], null, null, () => compViewDef(
              [
                elementDef(NodeFlags.None, null, null, 0, 'span', null, [[BindingType.ElementAttribute, 'a', SecurityContext.NONE]]),
              ], update
            )),
          ]));
        const compView = asProviderData(view, 1).componentView;

        value = 'v1';
        checkAndUpdateView(view);

        expect(update).toHaveBeenCalledWith(compView);

        update.calls.reset();
        checkNoChangesView(view);

        expect(update).toHaveBeenCalledWith(compView);

        value = 'v2';
        expect(() => checkNoChangesView(view))
            .toThrowError(
                `Expression has changed after it was checked. Previous value: 'v1'. Current value: 'v2'.`);
      });
Example #7
0
      it('should dirty check component views', () => {
        let value: any;
        class AComp {
          a: any;
        }

        const update =
            jasmine.createSpy('updater').and.callFake((check: NodeCheckFn, view: ViewData) => {
              check(view, 0, ArgumentType.Inline, value);
            });

        const {view, rootNodes} = createAndGetRootNodes(
          compViewDef([
            elementDef(0, NodeFlags.None, null, null, 1, 'div', null, null, null, null, () => compViewDef(
              [
                elementDef(0, NodeFlags.None, null, null, 0, 'span', null, [[BindingFlags.TypeElementAttribute, 'a', SecurityContext.NONE]]),
              ], null, update
            )),
            directiveDef(1, NodeFlags.Component, null, 0, AComp, []),
          ]));
        const compView = asElementData(view, 0).componentView;

        value = 'v1';
        Services.checkAndUpdateView(view);

        expect(update.calls.mostRecent().args[1]).toBe(compView);

        update.calls.reset();
        Services.checkNoChangesView(view);

        expect(update.calls.mostRecent().args[1]).toBe(compView);

        value = 'v2';
        expect(() => Services.checkNoChangesView(view))
            .toThrowError(
                `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'v1'. Current value: 'v2'.`);
      });
        it(`should update via strategy ${inlineDynamic}`, () => {
          class SomePipe implements PipeTransform {
            transform(v1: any, v2: any) { return [v1 + 10, v2 + 20]; }
          }

          let values: any[];

          const {view, rootNodes} = createAndGetRootNodes(compViewDef(
              [
                elementDef(0, NodeFlags.None, null !, null !, 3, 'span'),
                pipeDef(NodeFlags.None, SomePipe, []),
                purePipeDef(2, 2),
                directiveDef(3, NodeFlags.None, null, 0, Service, [], {data: [0, 'data']}),
              ],
              (check, view) => {
                const pureValue = checkNodeInlineOrDynamic(
                    check, view, 2, inlineDynamic, [nodeValue(view, 1)].concat(values));
                checkNodeInlineOrDynamic(check, view, 3, inlineDynamic, [pureValue]);
              }));
          const service = asProviderData(view, 3).instance;

          values = [1, 2];
          Services.checkAndUpdateView(view);
          const obj0 = service.data;
          expect(obj0).toEqual([11, 22]);

          // instance should not change
          // if the values don't change
          Services.checkAndUpdateView(view);
          expect(service.data).toBe(obj0);

          values = [3, 2];
          Services.checkAndUpdateView(view);
          const obj1 = service.data;
          expect(obj1).not.toBe(obj0);
          expect(obj1).toEqual([13, 22]);
        });
Example #9
0
      it('should query all matches', () => {
        class QueryService {
          a: QueryList<AService>;
        }

        const {view} = createAndGetRootNodes(compViewDef([
          elementDef(NodeFlags.None, null, null, 4, 'div'),
          directiveDef(NodeFlags.None, null, 1, QueryService, []),
          queryDef(
              NodeFlags.TypeContentQuery | NodeFlags.DynamicQuery, someQueryId,
              {'a': QueryBindingType.All}),
          aServiceProvider(),
          aServiceProvider(),
        ]));

        Services.checkAndUpdateView(view);

        const qs: QueryService = asProviderData(view, 1).instance;
        expect(qs.a instanceof QueryList).toBeTruthy();
        expect(qs.a.toArray()).toEqual([
          asProviderData(view, 3).instance,
          asProviderData(view, 4).instance,
        ]);
      });
Example #10
0
    it('should include projected nodes when attaching / detaching embedded views', () => {
      const {view, rootNodes} = createAndGetRootNodes(compViewDef(hostElDef([textDef(0, ['a'])], [
        elementDef(NodeFlags.None, null !, null !, 1, 'div'),
        anchorDef(NodeFlags.EmbeddedViews, null !, 0, 0, null !, embeddedViewDef([
                    ngContentDef(null !, 0),
                    // The anchor would be added by the compiler after the ngContent
                    anchorDef(NodeFlags.None, null !, null !, 0),
                  ])),
      ])));

      const componentView = asElementData(view, 0).componentView;
      const rf = componentView.root.rendererFactory;
      const view0 = createEmbeddedView(componentView, componentView.def.nodes[1]);

      attachEmbeddedView(view, asElementData(componentView, 1), 0, view0);
      expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0])).length).toBe(3);
      expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0]))[1])
          .toBe(asTextData(view, 2).renderText);

      rf.begin !();
      detachEmbeddedView(asElementData(componentView, 1), 0);
      rf.end !();
      expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0])).length).toBe(1);
    });