import Application from '@ember/application'; import Controller from '@ember/controller'; import { Component } from 'ember-glimmer'; import { compile } from 'ember-template-compiler'; import { moduleFor, ApplicationTestCase } from 'internal-test-helpers'; import { ENV } from 'ember-environment'; moduleFor( 'Application Lifecycle - Component Registration', class extends ApplicationTestCase { // This is necessary for this.application.instanceInitializer to not leak between tests createApplication(options) { return super.createApplication(options, Application.extend()); } ['@test The helper becomes the body of the component']() { this.addTemplate('components/expand-it', '

hello {{yield}}

'); this.addTemplate('application', 'Hello world {{#expand-it}}world{{/expand-it}}'); return this.visit('/').then(() => { this.assertText('Hello world hello world'); this.assertComponentElement(this.element.firstElementChild, { tagName: 'div', content: '

hello world

', }); }); } ['@test The helper becomes the body of the component (ENV._TEMPLATE_ONLY_GLIMMER_COMPONENTS = true;)']() { ENV._TEMPLATE_ONLY_GLIMMER_COMPONENTS = true; this.addTemplate('components/expand-it', '

hello {{yield}}

'); this.addTemplate('application', 'Hello world {{#expand-it}}world{{/expand-it}}'); return this.visit('/').then(() => { this.assertInnerHTML('Hello world

hello world

'); ENV._TEMPLATE_ONLY_GLIMMER_COMPONENTS = false; }); } ['@test If a component is registered, it is used'](assert) { this.addTemplate('components/expand-it', '

hello {{yield}}

'); this.addTemplate('application', `Hello world {{#expand-it}}world{{/expand-it}}`); this.application.instanceInitializer({ name: 'expand-it-component', initialize(applicationInstance) { applicationInstance.register( 'component:expand-it', Component.extend({ classNames: 'testing123', }) ); }, }); return this.visit('/').then(() => { let text = this.$('div.testing123') .text() .trim(); assert.equal(text, 'hello world', 'The component is composed correctly'); }); } ['@test Late-registered components can be rendered with custom `layout` property'](assert) { this.addTemplate('application', `
there goes {{my-hero}}
`); this.application.instanceInitializer({ name: 'my-hero-component', initialize(applicationInstance) { applicationInstance.register( 'component:my-hero', Component.extend({ classNames: 'testing123', layout: compile('watch him as he GOES'), }) ); }, }); return this.visit('/').then(() => { let text = this.$('#wrapper') .text() .trim(); assert.equal( text, 'there goes watch him as he GOES', 'The component is composed correctly' ); }); } ['@test Late-registered components can be rendered with template registered on the container']( assert ) { this.addTemplate( 'application', `
hello world {{sally-rutherford}}-{{#sally-rutherford}}!!!{{/sally-rutherford}}
` ); this.application.instanceInitializer({ name: 'sally-rutherford-component-template', initialize(applicationInstance) { applicationInstance.register( 'template:components/sally-rutherford', compile('funkytowny{{yield}}') ); }, }); this.application.instanceInitializer({ name: 'sally-rutherford-component', initialize(applicationInstance) { applicationInstance.register('component:sally-rutherford', Component); }, }); return this.visit('/').then(() => { let text = this.$('#wrapper') .text() .trim(); assert.equal( text, 'hello world funkytowny-funkytowny!!!', 'The component is composed correctly' ); }); } ['@test Late-registered components can be rendered with ONLY the template registered on the container']( assert ) { this.addTemplate( 'application', `
hello world {{borf-snorlax}}-{{#borf-snorlax}}!!!{{/borf-snorlax}}
` ); this.application.instanceInitializer({ name: 'borf-snorlax-component-template', initialize(applicationInstance) { applicationInstance.register( 'template:components/borf-snorlax', compile('goodfreakingTIMES{{yield}}') ); }, }); return this.visit('/').then(() => { let text = this.$('#wrapper') .text() .trim(); assert.equal( text, 'hello world goodfreakingTIMES-goodfreakingTIMES!!!', 'The component is composed correctly' ); }); } ['@test Assigning layoutName to a component should setup the template as a layout'](assert) { assert.expect(1); this.addTemplate( 'application', `
{{#my-component}}{{text}}{{/my-component}}
` ); this.addTemplate('foo-bar-baz', '{{text}}-{{yield}}'); this.application.instanceInitializer({ name: 'application-controller', initialize(applicationInstance) { applicationInstance.register( 'controller:application', Controller.extend({ text: 'outer', }) ); }, }); this.application.instanceInitializer({ name: 'my-component-component', initialize(applicationInstance) { applicationInstance.register( 'component:my-component', Component.extend({ text: 'inner', layoutName: 'foo-bar-baz', }) ); }, }); return this.visit('/').then(() => { let text = this.$('#wrapper') .text() .trim(); assert.equal(text, 'inner-outer', 'The component is composed correctly'); }); } ['@test Assigning layoutName and layout to a component should use the `layout` value'](assert) { assert.expect(1); this.addTemplate( 'application', `
{{#my-component}}{{text}}{{/my-component}}
` ); this.addTemplate('foo-bar-baz', 'No way!'); this.application.instanceInitializer({ name: 'application-controller-layout', initialize(applicationInstance) { applicationInstance.register( 'controller:application', Controller.extend({ text: 'outer', }) ); }, }); this.application.instanceInitializer({ name: 'my-component-component-layout', initialize(applicationInstance) { applicationInstance.register( 'component:my-component', Component.extend({ text: 'inner', layoutName: 'foo-bar-baz', layout: compile('{{text}}-{{yield}}'), }) ); }, }); return this.visit('/').then(() => { let text = this.$('#wrapper') .text() .trim(); assert.equal(text, 'inner-outer', 'The component is composed correctly'); }); } ['@test Using name of component that does not exist']() { this.addTemplate('application', `
{{#no-good}} {{/no-good}}
`); // TODO: Use the async form of expectAssertion here when it is available expectAssertion(() => { this.visit('/'); }, /.* named "no-good" .*/); return this.runLoopSettled(); } } );