text: import { RenderingTestCase, moduleFor, runAppend, runTask } from 'internal-test-helpers';
  
  import { set } from '@ember/-internals/metal';
  
  moduleFor(
    'outlet view',
    class extends RenderingTestCase {
      constructor() {
        super(...arguments);
  
        let CoreOutlet = this.owner.factoryFor('view:-outlet');
  
        this.component = CoreOutlet.create();
      }
  
      ['@test should not error when initial rendered template is undefined']() {
        let outletState = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'application',
            controller: undefined,
            template: undefined,
          },
  
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        runAppend(this.component);
  
        this.assertText('');
      }
  
      ['@test should render the outlet when set after DOM insertion']() {
        let outletState = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'application',
            controller: undefined,
            template: undefined,
          },
  
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        runAppend(this.component);
  
        this.assertText('');
  
        this.registerTemplate('application', 'HI{{outlet}}');
        outletState = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'application',
            controller: {},
            template: this.owner.lookup('template:application'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        this.assertText('HI');
  
        this.assertStableRerender();
  
        this.registerTemplate('index', '<p>BYE</p>');
        outletState.outlets.main = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'index',
            controller: {},
            template: this.owner.lookup('template:index'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        this.assertText('HIBYE');
      }
  
      ['@test should render the outlet when set before DOM insertion']() {
        this.registerTemplate('application', 'HI{{outlet}}');
        let outletState = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'application',
            controller: {},
            template: this.owner.lookup('template:application'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        runAppend(this.component);
  
        this.assertText('HI');
  
        this.assertStableRerender();
  
        this.registerTemplate('index', '<p>BYE</p>');
        outletState.outlets.main = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'index',
            controller: {},
            template: this.owner.lookup('template:index'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        this.assertText('HIBYE');
      }
  
      ['@test should support an optional name']() {
        this.registerTemplate('application', '<h1>HI</h1>{{outlet "special"}}');
        let outletState = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'application',
            controller: {},
            template: this.owner.lookup('template:application'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        runAppend(this.component);
  
        this.assertText('HI');
  
        this.assertStableRerender();
  
        this.registerTemplate('special', '<p>BYE</p>');
        outletState.outlets.special = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'special',
            controller: {},
            template: this.owner.lookup('template:special'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        this.assertText('HIBYE');
      }
  
      ['@test does not default outlet name when positional argument is present']() {
        this.registerTemplate('application', '<h1>HI</h1>{{outlet someUndefinedThing}}');
        let outletState = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'application',
            controller: {},
            template: this.owner.lookup('template:application'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        runAppend(this.component);
  
        this.assertText('HI');
  
        this.assertStableRerender();
  
        this.registerTemplate('special', '<p>BYE</p>');
        outletState.outlets.main = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'special',
            controller: {},
            template: this.owner.lookup('template:special'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        this.assertText('HI');
      }
  
      ['@test should support bound outlet name']() {
        let controller = { outletName: 'foo' };
        this.registerTemplate('application', '<h1>HI</h1>{{outlet outletName}}');
        let outletState = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'application',
            controller,
            template: this.owner.lookup('template:application'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        runAppend(this.component);
  
        this.assertText('HI');
  
        this.assertStableRerender();
  
        this.registerTemplate('foo', '<p>FOO</p>');
        outletState.outlets.foo = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'foo',
            controller: {},
            template: this.owner.lookup('template:foo'),
          },
          outlets: Object.create(null),
        };
  
        this.registerTemplate('bar', '<p>BAR</p>');
        outletState.outlets.bar = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'bar',
            controller: {},
            template: this.owner.lookup('template:bar'),
          },
          outlets: Object.create(null),
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        this.assertText('HIFOO');
  
        runTask(() => set(controller, 'outletName', 'bar'));
  
        this.assertText('HIBAR');
      }
  
      ['@test outletState can pass through user code (liquid-fire initimate API) ']() {
        this.registerTemplate(
          'outer',
          'A{{#-with-dynamic-vars outletState=(identity (-get-dynamic-var "outletState"))}}B{{outlet}}D{{/-with-dynamic-vars}}E'
        );
        this.registerTemplate('inner', 'C');
  
        // This looks like it doesn't do anything, but its presence
        // guarantees that the outletState gets converted from a reference
        // to a value and then back to a reference. That is what we're
        // testing here.
        this.registerHelper('identity', ([a]) => a);
  
        let outletState = {
          render: {
            owner: this.owner,
            into: undefined,
            outlet: 'main',
            name: 'outer',
            controller: {},
            template: this.owner.lookup('template:outer'),
          },
          outlets: {
            main: {
              render: {
                owner: this.owner,
                into: undefined,
                outlet: 'main',
                name: 'inner',
                controller: {},
                template: this.owner.lookup('template:inner'),
              },
              outlets: Object.create(null),
            },
          },
        };
  
        runTask(() => this.component.setOutletState(outletState));
  
        runAppend(this.component);
  
        this.assertText('ABCDE');
  
        this.assertStableRerender();
      }
    }
  );
  