/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
import {ViewEncapsulation} from '../../src/core';
import {defineComponent, markDirty} from '../../src/render3/index';
import {bind, componentRefresh, container, containerRefreshEnd, containerRefreshStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, text, textBinding} from '../../src/render3/instructions';
import {createRendererType2} from '../../src/view/index';
import {getRendererFactory2} from './imported_renderer2';
import {containerEl, renderComponent, renderToHtml, requestAnimationFrame, toHtml} from './render_util';
describe('component', () => {
  class CounterComponent {
    count = 0;
    increment() { this.count++; }
    static ngComponentDef = defineComponent({
      type: CounterComponent,
      tag: 'counter',
      template: function(ctx: CounterComponent, cm: boolean) {
        if (cm) {
          text(0);
        }
        textBinding(0, bind(ctx.count));
      },
      factory: () => new CounterComponent,
      inputs: {count: 'count'},
      methods: {increment: 'increment'}
    });
  }
  describe('renderComponent', () => {
    it('should render on initial call', () => {
      renderComponent(CounterComponent);
      expect(toHtml(containerEl)).toEqual('0');
    });
    it('should re-render on input change or method invocation', () => {
      const component = renderComponent(CounterComponent);
      expect(toHtml(containerEl)).toEqual('0');
      component.count = 123;
      markDirty(component, requestAnimationFrame);
      expect(toHtml(containerEl)).toEqual('0');
      requestAnimationFrame.flush();
      expect(toHtml(containerEl)).toEqual('123');
      component.increment();
      markDirty(component, requestAnimationFrame);
      expect(toHtml(containerEl)).toEqual('123');
      requestAnimationFrame.flush();
      expect(toHtml(containerEl)).toEqual('124');
    });
  });
});
describe('component with a container', () => {
  function showItems(ctx: {items: string[]}, cm: boolean) {
    if (cm) {
      container(0);
    }
    containerRefreshStart(0);
    {
      for (const item of ctx.items) {
        const cm0 = embeddedViewStart(0);
        {
          if (cm0) {
            text(0);
          }
          textBinding(0, bind(item));
        }
        embeddedViewEnd();
      }
    }
    containerRefreshEnd();
  }
  class WrapperComponent {
    items: string[];
    static ngComponentDef = defineComponent({
      type: WrapperComponent,
      tag: 'wrapper',
      template: function ChildComponentTemplate(ctx: {items: string[]}, cm: boolean) {
        if (cm) {
          container(0);
        }
        containerRefreshStart(0);
        {
          const cm0 = embeddedViewStart(0);
          { showItems({items: ctx.items}, cm0); }
          embeddedViewEnd();
        }
        containerRefreshEnd();
      },
      factory: () => new WrapperComponent,
      inputs: {items: 'items'}
    });
  }
  function template(ctx: {items: string[]}, cm: boolean) {
    if (cm) {
      elementStart(0, WrapperComponent);
      elementEnd();
    }
    elementProperty(0, 'items', bind(ctx.items));
    WrapperComponent.ngComponentDef.h(1, 0);
    componentRefresh(1, 0);
  }
  it('should re-render on input change', () => {
    const ctx: {items: string[]} = {items: ['a']};
    expect(renderToHtml(template, ctx)).toEqual('