From 424267632c515e0ec401858b72bd2703bc6c5e50 Mon Sep 17 00:00:00 2001 From: Sergio Arbeo Date: Fri, 4 Mar 2016 11:50:53 +0530 Subject: [PATCH 1/3] [FEATURE beta] Use RenderingTest class and `moduleFor` for component invocation This PR is a POC on using `RenderingTest` class and `moduleFor` in component invocation tests. --- .../tests/utils/abstract-test-case.js | 12 +- .../integration/component_invocation_test.js | 1411 ++++++++--------- packages/ember-runtime/tests/utils.js | 78 + 3 files changed, 731 insertions(+), 770 deletions(-) diff --git a/packages/ember-glimmer/tests/utils/abstract-test-case.js b/packages/ember-glimmer/tests/utils/abstract-test-case.js index 74c0989617a..b7694c7b08e 100644 --- a/packages/ember-glimmer/tests/utils/abstract-test-case.js +++ b/packages/ember-glimmer/tests/utils/abstract-test-case.js @@ -37,6 +37,14 @@ export function applyMixins(TestClass, ...mixins) { return TestClass; } +function compileIfNeeded(template, options = {}) { + if (typeof template === 'string') { + return compile(template, options); + } else { + return template; + } +} + export function moduleFor(description, TestClass, ...mixins) { let context; @@ -156,7 +164,7 @@ export class RenderingTest extends TestCase { render(templateStr, context = {}) { let { renderer, owner } = this; - owner.register('template:-top-level', compile(templateStr)); + owner.register('template:-top-level', compileIfNeeded(templateStr)); let attrs = assign({}, context, { tagName: '', @@ -198,7 +206,7 @@ export class RenderingTest extends TestCase { } if (typeof template === 'string') { - owner.register(`template:components/${name}`, compile(template, { env })); + owner.register(`template:components/${name}`, compileIfNeeded(template, { env })); } } diff --git a/packages/ember-htmlbars/tests/integration/component_invocation_test.js b/packages/ember-htmlbars/tests/integration/component_invocation_test.js index 4151b1fb555..973d585cc2b 100644 --- a/packages/ember-htmlbars/tests/integration/component_invocation_test.js +++ b/packages/ember-htmlbars/tests/integration/component_invocation_test.js @@ -1,955 +1,830 @@ import Ember from 'ember-metal/core'; -import EmberView from 'ember-views/views/view'; -import jQuery from 'ember-views/system/jquery'; -import compile from 'ember-template-compiler/system/compile'; -import ComponentLookup from 'ember-views/component_lookup'; import Component from 'ember-views/components/component'; import GlimmerComponent from 'ember-htmlbars/glimmer-component'; -import { runAppend, runDestroy } from 'ember-runtime/tests/utils'; -import { set } from 'ember-metal/property_set'; import run from 'ember-metal/run_loop'; import { A as emberA } from 'ember-runtime/system/native_array'; -import buildOwner from 'container/tests/test-helpers/build-owner'; -import { OWNER } from 'container/owner'; - -var owner, view; - -function commonSetup() { - owner = buildOwner(); - owner.registerOptionsForType('component', { singleton: false }); - owner.registerOptionsForType('view', { singleton: false }); - owner.registerOptionsForType('template', { instantiate: false }); - owner.register('component-lookup:main', ComponentLookup); -} - -function commonTeardown() { - runDestroy(owner); - runDestroy(view); - owner = view = null; -} - -function appendViewFor(template, hash={}) { - let view = EmberView.extend({ - [OWNER]: owner, - template: compile(template) - }).create(hash); +import compile from 'ember-template-compiler/system/compile'; +import { RenderingTest, moduleFor } from 'ember-htmlbars/tests/utils/test-case'; - runAppend(view); +moduleFor('component - invocation', class extends RenderingTest { + ['@test non-block without properties']() { + expect(1); - return view; -} + this.registerComponent('non-block', { + template: 'In layout' + }); -QUnit.module('component - invocation', { - setup() { - commonSetup(); - }, + this.render('{{non-block}}'); - teardown() { - commonTeardown(); + equal(this.$().text(), 'In layout'); } -}); - -QUnit.test('non-block without properties', function() { - expect(1); - - owner.register('template:components/non-block', compile('In layout')); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{non-block}}') - }).create(); + ['@test GlimmerComponent cannot be invoked with curly braces']() { + this.registerComponent('non-block', { + ComponentClass: GlimmerComponent.extend(), + template: 'In layout' + }); - runAppend(view); - - equal(jQuery('#qunit-fixture').text(), 'In layout'); -}); - -QUnit.test('GlimmerComponent cannot be invoked with curly braces', function() { - owner.register('template:components/non-block', compile('In layout')); - owner.register('component:non-block', GlimmerComponent.extend()); - - expectAssertion(function() { - view = appendViewFor('{{non-block}}'); - }, /cannot invoke the 'non-block' component with curly braces/); -}); - -QUnit.test('block without properties', function() { - expect(1); - - owner.register('template:components/with-block', compile('In layout - {{yield}}')); + expectAssertion(() => { + this.render('{{non-block}}'); + }, /cannot invoke the 'non-block' component with curly braces/); + } - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#with-block}}In template{{/with-block}}') - }).create(); + ['@test block without properties']() { + expect(1); - runAppend(view); + this.registerComponent('with-block', { + template: 'In layout - {{yield}}' + }); - equal(jQuery('#qunit-fixture').text(), 'In layout - In template'); -}); + this.render('{{#with-block}}In template{{/with-block}}'); -QUnit.test('non-block with properties on attrs', function() { - expect(1); + equal(this.$().text(), 'In layout - In template'); + } - owner.register('template:components/non-block', compile('In layout - someProp: {{attrs.someProp}}')); + ['@test non-block with properties on attrs']() { + expect(1); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{non-block someProp="something here"}}') - }).create(); + this.registerComponent('non-block', { + template: 'In layout - someProp: {{attrs.someProp}}' + }); - runAppend(view); + this.render('{{non-block someProp="something here"}}'); - equal(jQuery('#qunit-fixture').text(), 'In layout - someProp: something here'); -}); + equal(this.$().text(), 'In layout - someProp: something here'); + } -QUnit.test('non-block with properties on attrs and component class', function() { - owner.register('component:non-block', Component.extend()); - owner.register('template:components/non-block', compile('In layout - someProp: {{attrs.someProp}}')); + ['@test non-block with properties on attrs and component class']() { + this.registerComponent('non-block', { + ComponentClass: Component.extend(), + template: 'In layout - someProp: {{attrs.someProp}}' + }); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{non-block someProp="something here"}}') - }).create(); + this.render('{{non-block someProp="something here"}}'); - runAppend(view); + equal(this.$().text(), 'In layout - someProp: something here'); + } - equal(jQuery('#qunit-fixture').text(), 'In layout - someProp: something here'); -}); -QUnit.test('non-block with properties on overridden in init', function() { - owner.register('component:non-block', Component.extend({ - someProp: null, + ['@test non-block with properties on overridden in init']() { + this.registerComponent('non-block', { + ComponentClass: Component.extend({ + someProp: null, - init() { - this._super(...arguments); - this.someProp = 'value set in init'; - } - })); - owner.register('template:components/non-block', compile('In layout - someProp: {{someProp}}')); + init() { + this._super(...arguments); + this.someProp = 'value set in init'; + } + }), - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{non-block someProp="something passed when invoked"}}') - }).create(); + template: 'In layout - someProp: {{someProp}}' + }); - runAppend(view); + this.render('{{non-block someProp="something passed when invoked"}}'); - equal(view.$().text(), 'In layout - someProp: value set in init'); -}); + equal(this.$().text(), 'In layout - someProp: value set in init'); + } -QUnit.test('lookup of component takes priority over property', function() { - expect(1); + ['@test lookup of component takes priority over property']() { + expect(1); - owner.register('template:components/some-component', compile('some-component')); + this.registerComponent('some-component', { + template: 'some-component' + }); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{some-prop}} {{some-component}}'), - context: { + this.render('{{some-prop}} {{some-component}}', { 'some-component': 'not-some-component', 'some-prop': 'some-prop' - } - }).create(); + }); - runAppend(view); - - equal(jQuery('#qunit-fixture').text(), 'some-prop some-component'); -}); + equal(this.$().text(), 'some-prop some-component'); + } -QUnit.test('component without dash is not looked up', function() { - expect(1); + ['@test component without dash is not looked up']() { + expect(1); - owner.register('template:components/somecomponent', compile('somecomponent')); + this.registerComponent('somecomponent', { + template: 'somecomponent' + }); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{somecomponent}}'), - context: { + this.render('{{somecomponent}}', { 'somecomponent': 'notsomecomponent' - } - }).create(); - - runAppend(view); - - equal(jQuery('#qunit-fixture').text(), 'notsomecomponent'); -}); - -QUnit.test('rerendering component with attrs from parent', function() { - var willUpdate = 0; - var didReceiveAttrs = 0; - - owner.register('component:non-block', Component.extend({ - didReceiveAttrs() { - didReceiveAttrs++; - }, - - willUpdate() { - willUpdate++; - } - })); - owner.register('template:components/non-block', compile('In layout - someProp: {{attrs.someProp}}')); - - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{non-block someProp=view.someProp}}'), - someProp: 'wycats' - }).create(); + }); - runAppend(view); - - equal(didReceiveAttrs, 1, 'The didReceiveAttrs hook fired'); + equal(this.$().text(), 'notsomecomponent'); + } - equal(jQuery('#qunit-fixture').text(), 'In layout - someProp: wycats'); + ['@test rerendering component with attrs from parent']() { + let willUpdate = 0; + let didReceiveAttrs = 0; - run(function() { - view.set('someProp', 'tomdale'); - }); + this.registerComponent('non-block', { + ComponentClass: Component.extend({ + didReceiveAttrs() { + didReceiveAttrs++; + }, - equal(jQuery('#qunit-fixture').text(), 'In layout - someProp: tomdale'); - equal(didReceiveAttrs, 2, 'The didReceiveAttrs hook fired again'); - equal(willUpdate, 1, 'The willUpdate hook fired once'); + willUpdate() { + willUpdate++; + } + }), - run(view, 'rerender'); + template: 'In layout - someProp: {{attrs.someProp}}' + }); - equal(jQuery('#qunit-fixture').text(), 'In layout - someProp: tomdale'); - equal(didReceiveAttrs, 3, 'The didReceiveAttrs hook fired again'); - equal(willUpdate, 2, 'The willUpdate hook fired again'); -}); + this.render('{{non-block someProp=view.someProp}}', { + someProp: 'wycats' + }); + equal(didReceiveAttrs, 1, 'The didReceiveAttrs hook fired'); -QUnit.test('[DEPRECATED] non-block with properties on self', function() { - // TODO: attrs - // expectDeprecation("You accessed the `someProp` attribute directly. Please use `attrs.someProp` instead."); + equal(this.$().text(), 'In layout - someProp: wycats'); - owner.register('template:components/non-block', compile('In layout - someProp: {{someProp}}')); + run(() => { + this.component.set('someProp', 'tomdale'); + }); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{non-block someProp="something here"}}') - }).create(); + equal(this.$().text(), 'In layout - someProp: tomdale'); + equal(didReceiveAttrs, 2, 'The didReceiveAttrs hook fired again'); + equal(willUpdate, 1, 'The willUpdate hook fired once'); - runAppend(view); + run(() => { + this.rerender(); + }); - equal(jQuery('#qunit-fixture').text(), 'In layout - someProp: something here'); -}); + equal(this.$().text(), 'In layout - someProp: tomdale'); + equal(didReceiveAttrs, 3, 'The didReceiveAttrs hook fired again'); + equal(willUpdate, 2, 'The willUpdate hook fired again'); + } -QUnit.test('block with properties on attrs', function() { - expect(1); + ['@test [DEPRECATED] non-block with properties on self']() { + // TODO: attrs + // expectDeprecation("You accessed the `someProp` attribute directly. Please use `attrs.someProp` instead."); - owner.register('template:components/with-block', compile('In layout - someProp: {{attrs.someProp}} - {{yield}}')); + this.registerComponent('non-block', { + template: 'In layout - someProp: {{someProp}}' + }); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#with-block someProp="something here"}}In template{{/with-block}}') - }).create(); + this.render('{{non-block someProp="something here"}}'); - runAppend(view); + equal(this.$().text(), 'In layout - someProp: something here'); + } - equal(jQuery('#qunit-fixture').text(), 'In layout - someProp: something here - In template'); -}); + ['@test block with properties on attrs']() { + expect(1); -QUnit.test('[DEPRECATED] block with properties on self', function() { - // TODO: attrs - // expectDeprecation("You accessed the `someProp` attribute directly. Please use `attrs.someProp` instead."); + this.registerComponent('with-block', { + template: 'In layout - someProp: {{attrs.someProp}} - {{yield}}' + }); - owner.register('template:components/with-block', compile('In layout - someProp: {{someProp}} - {{yield}}')); + this.render('{{#with-block someProp="something here"}}In template{{/with-block}}'); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#with-block someProp="something here"}}In template{{/with-block}}') - }).create(); + equal(this.$().text(), 'In layout - someProp: something here - In template'); + } - runAppend(view); + ['@test [DEPRECATED] block with properties on self']() { + // TODO: attrs + // expectDeprecation("You accessed the `someProp` attribute directly. Please use `attrs.someProp` instead."); - equal(jQuery('#qunit-fixture').text(), 'In layout - someProp: something here - In template'); -}); + this.registerComponent('with-block', { + template: 'In layout - someProp: {{someProp}} - {{yield}}' + }); -QUnit.test('with ariaRole specified', function() { - expect(1); + this.render('{{#with-block someProp="something here"}}In template{{/with-block}}'); - owner.register('template:components/aria-test', compile('Here!')); + equal(this.$().text(), 'In layout - someProp: something here - In template'); + } - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{aria-test id="aria-test" ariaRole="main"}}') - }).create(); + ['@test with ariaRole specified']() { + expect(1); - runAppend(view); + this.registerComponent('aria-test', { + template: 'Here!' + }); - equal(view.$('#aria-test').attr('role'), 'main', 'role attribute is applied'); -}); + this.render('{{aria-test id="aria-test" ariaRole="main"}}'); -QUnit.test('`template` specified in a component is overridden by block', function() { - expect(1); + equal(this.$('#aria-test').attr('role'), 'main', 'role attribute is applied'); + } - owner.register('component:with-block', Component.extend({ - layout: compile('{{yield}}'), - template: compile('Oh, noes!') - })); + ['@test `template` specified in a component is overridden by block']() { + expect(1); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#with-block}}Whoop, whoop!{{/with-block}}') - }).create(); + this.registerComponent('with-block', { + ComponentClass: Component.extend({ + layout: compile('{{yield}}'), + template: compile('Oh, noes!') + }) + }); - runAppend(view); + this.render('{{#with-block}}Whoop, whoop!{{/with-block}}'); - equal(view.$().text(), 'Whoop, whoop!', 'block provided always overrides template property'); -}); + equal(this.$().text(), 'Whoop, whoop!', 'block provided always overrides template property'); + } -QUnit.test('hasBlock is true when block supplied', function() { - expect(1); + ['@test hasBlock is true when block supplied']() { + expect(1); - owner.register('template:components/with-block', compile('{{#if hasBlock}}{{yield}}{{else}}No Block!{{/if}}')); + this.registerComponent('with-block', { + template: '{{#if hasBlock}}{{yield}}{{else}}No Block!{{/if}}' + }); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#with-block}}In template{{/with-block}}') - }).create(); + this.render('{{#with-block}}In template{{/with-block}}'); - runAppend(view); + equal(this.$().text(), 'In template'); + } - equal(jQuery('#qunit-fixture').text(), 'In template'); -}); + ['@test hasBlock is false when no block supplied']() { + expect(1); -QUnit.test('hasBlock is false when no block supplied', function() { - expect(1); + this.registerComponent('with-block', { + template: '{{#if hasBlock}}{{yield}}{{else}}No Block!{{/if}}' + }); - owner.register('template:components/with-block', compile('{{#if hasBlock}}{{yield}}{{else}}No Block!{{/if}}')); + this.render('{{with-block}}'); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{with-block}}') - }).create(); + equal(this.$().text(), 'No Block!'); + } - runAppend(view); + ['@test hasBlock is false when no block supplied']() { + expect(1); - equal(jQuery('#qunit-fixture').text(), 'No Block!'); -}); + this.registerComponent('with-block', { + template: '{{#if hasBlock}}{{yield}}{{else}}No Block!{{/if}}' + }); -QUnit.test('hasBlockParams is true when block param supplied', function() { - expect(1); + this.render('{{with-block}}'); - owner.register('template:components/with-block', compile('{{#if hasBlockParams}}{{yield this}} - In Component{{else}}{{yield}} No Block!{{/if}}')); + equal(this.$().text(), 'No Block!'); + } - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#with-block as |something|}}In template{{/with-block}}') - }).create(); + ['@test hasBlockParams is true when block param supplied']() { + expect(1); - runAppend(view); + this.registerComponent('with-block', { + template: '{{#if hasBlockParams}}{{yield this}} - In Component{{else}}{{yield}} No Block!{{/if}}' + }); - equal(jQuery('#qunit-fixture').text(), 'In template - In Component'); -}); + this.render('{{#with-block as |something|}}In template{{/with-block}}'); -QUnit.test('hasBlockParams is false when no block param supplied', function() { - expect(1); + equal(this.$().text(), 'In template - In Component'); + } - owner.register('template:components/with-block', compile('{{#if hasBlockParams}}{{yield this}}{{else}}{{yield}} No Block Param!{{/if}}')); + ['@test hasBlockParams is false when no block param supplied']() { + expect(1); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#with-block}}In block{{/with-block}}') - }).create(); + this.registerComponent('with-block', { + template: '{{#if hasBlockParams}}{{yield this}}{{else}}{{yield}} No Block Param!{{/if}}' + }); - runAppend(view); + this.render('{{#with-block}}In block{{/with-block}}'); - equal(jQuery('#qunit-fixture').text(), 'In block No Block Param!'); -}); + equal(this.$().text(), 'In block No Block Param!'); + } -QUnit.test('static named positional parameters', function() { - var SampleComponent = Component.extend(); - SampleComponent.reopenClass({ - positionalParams: ['name', 'age'] - }); - owner.register('template:components/sample-component', compile('{{attrs.name}}{{attrs.age}}')); - owner.register('component:sample-component', SampleComponent); + ['@test static named positional parameters']() { + let SampleComponent = Component.extend(); + SampleComponent.reopenClass({ + positionalParams: ['name', 'age'] + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{sample-component "Quint" 4}}') - }).create(); + this.registerComponent('sample-component', { + ComponentClass: SampleComponent, + template: '{{attrs.name}}{{attrs.age}}' + }); - runAppend(view); + this.render('{{sample-component "Quint" 4}}'); - equal(jQuery('#qunit-fixture').text(), 'Quint4'); -}); + equal(this.$().text(), 'Quint4'); + } -QUnit.test('dynamic named positional parameters', function() { - var SampleComponent = Component.extend(); - SampleComponent.reopenClass({ - positionalParams: ['name', 'age'] - }); + ['@test dynamic named positional parameters']() { + let SampleComponent = Component.extend(); + SampleComponent.reopenClass({ + positionalParams: ['name', 'age'] + }); - owner.register('template:components/sample-component', compile('{{attrs.name}}{{attrs.age}}')); - owner.register('component:sample-component', SampleComponent); + this.registerComponent('sample-component', { + ComponentClass: SampleComponent, + template: '{{attrs.name}}{{attrs.age}}' + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{sample-component myName myAge}}'), - context: { + this.render('{{sample-component myName myAge}}', { myName: 'Quint', myAge: 4 - } - }).create(); + }); - runAppend(view); + equal(this.$().text(), 'Quint4'); - equal(jQuery('#qunit-fixture').text(), 'Quint4'); - run(function() { - set(view.context, 'myName', 'Edward'); - set(view.context, 'myAge', '5'); - }); + run(() => { + this.component.set('myName', 'Edward'); + this.component.set('myAge', '5'); + }); - equal(jQuery('#qunit-fixture').text(), 'Edward5'); -}); - -QUnit.test('if a value is passed as a non-positional parameter, it takes precedence over the named one', function() { - var SampleComponent = Component.extend(); - SampleComponent.reopenClass({ - positionalParams: ['name'] - }); - - owner.register('template:components/sample-component', compile('{{attrs.name}}')); - owner.register('component:sample-component', SampleComponent); - - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{sample-component notMyName name=myName}}'), - context: { - myName: 'Quint', - notMyName: 'Sergio' - } - }).create(); - - expectAssertion(function() { - runAppend(view); - }, `You cannot specify both a positional param (at position 0) and the hash argument \`name\`.`); -}); + equal(this.$().text(), 'Edward5'); + } -QUnit.test('static arbitrary number of positional parameters', function() { - var SampleComponent = Component.extend(); - SampleComponent.reopenClass({ - positionalParams: 'names' - }); + ['@test if a value is passed as a non-positional parameter, it takes precedence over the named one']() { + let SampleComponent = Component.extend(); + SampleComponent.reopenClass({ + positionalParams: ['name'] + }); + + this.registerComponent('sample-component', { + ComponentClass: SampleComponent, + template: '{{attrs.name}}' + }); + + expectAssertion(() => { + this.render('{{sample-component notMyName name=myName}}', { + myName: 'Quint', + notMyName: 'Sergio' + }); + }, `You cannot specify both a positional param (at position 0) and the hash argument \`name\`.`); + } - owner.register('template:components/sample-component', compile('{{#each attrs.names as |name|}}{{name}}{{/each}}')); - owner.register('component:sample-component', SampleComponent); + ['@test static arbitrary number of positional parameters']() { + let SampleComponent = Component.extend(); + SampleComponent.reopenClass({ + positionalParams: 'names' + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{sample-component "Foo" 4 "Bar" id="args-3"}}{{sample-component "Foo" 4 "Bar" 5 "Baz" id="args-5"}}{{component "sample-component" "Foo" 4 "Bar" 5 "Baz" id="helper"}}') - }).create(); + this.registerComponent('sample-component', { + ComponentClass: SampleComponent, + template: '{{#each attrs.names as |name|}}{{name}}{{/each}}' + }); - runAppend(view); + this.render('{{sample-component "Foo" 4 "Bar" id="args-3"}}{{sample-component "Foo" 4 "Bar" 5 "Baz" id="args-5"}}{{component "sample-component" "Foo" 4 "Bar" 5 "Baz" id="helper"}}'); - equal(view.$('#args-3').text(), 'Foo4Bar'); - equal(view.$('#args-5').text(), 'Foo4Bar5Baz'); - equal(view.$('#helper').text(), 'Foo4Bar5Baz'); -}); + equal(this.$('#args-3').text(), 'Foo4Bar'); + equal(this.$('#args-5').text(), 'Foo4Bar5Baz'); + equal(this.$('#helper').text(), 'Foo4Bar5Baz'); + } -QUnit.test('arbitrary positional parameter conflict with hash parameter is reported', function() { - var SampleComponent = Component.extend(); - SampleComponent.reopenClass({ - positionalParams: 'names' - }); - - owner.register('template:components/sample-component', compile('{{#each attrs.names as |name|}}{{name}}{{/each}}')); - owner.register('component:sample-component', SampleComponent); - - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{sample-component "Foo" 4 "Bar" names=numbers id="args-3"}}'), - context: { - numbers: [1, 2, 3] - } - }).create(); - - expectAssertion(function() { - runAppend(view); - }, `You cannot specify positional parameters and the hash argument \`names\`.`); -}); + ['@test arbitrary positional parameter conflict with hash parameter is reported']() { + let SampleComponent = Component.extend(); + SampleComponent.reopenClass({ + positionalParams: 'names' + }); + + this.registerComponent('sample-component', { + ComponentClass: SampleComponent, + template: '{{#each attrs.names as |name|}}{{name}}{{/each}}' + }); + + expectAssertion(() => { + this.render('{{sample-component "Foo" 4 "Bar" names=numbers id="args-3"}}', { + numbers: [1, 2, 3] + }); + }, `You cannot specify positional parameters and the hash argument \`names\`.`); + } -QUnit.test('can use hash parameter instead of arbitrary positional param [GH #12444]', function() { - var SampleComponent = Component.extend(); - SampleComponent.reopenClass({ - positionalParams: 'names' - }); + ['@test can use hash parameter instead of arbitrary positional param [GH #12444]']() { + let SampleComponent = Component.extend(); + SampleComponent.reopenClass({ + positionalParams: 'names' + }); - owner.register('template:components/sample-component', compile('{{#each attrs.names as |name|}}{{name}}{{/each}}')); - owner.register('component:sample-component', SampleComponent); + this.registerComponent('sample-component', { + ComponentClass: SampleComponent, + template: '{{#each attrs.names as |name|}}{{name}}{{/each}}' + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{sample-component names=things id="args-3"}}'), - context: { + this.render('{{sample-component names=things id="args-3"}}', { things: ['Foo', 4, 'Bar'] - } - }).create(); - - runAppend(view); + }); - equal(view.$('#args-3').text(), 'Foo4Bar'); -}); + equal(this.$('#args-3').text(), 'Foo4Bar'); + } -QUnit.test('can use hash parameter instead of positional param', function() { - var SampleComponent = Component.extend(); - SampleComponent.reopenClass({ - positionalParams: ['first', 'second'] - }); + ['@test can use hash parameter instead of positional param']() { + let SampleComponent = Component.extend(); + SampleComponent.reopenClass({ + positionalParams: ['first', 'second'] + }); - owner.register('template:components/sample-component', compile('{{attrs.first}} - {{attrs.second}}')); - owner.register('component:sample-component', SampleComponent); + this.registerComponent('sample-component', { + ComponentClass: SampleComponent, + template: '{{attrs.first}} - {{attrs.second}}' + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile(` + this.render(` {{sample-component "one" "two" id="two-positional"}} {{sample-component "one" second="two" id="one-positional"}} {{sample-component first="one" second="two" id="no-positional"}} - - `), - context: { + `, { things: ['Foo', 4, 'Bar'] - } - }).create(); - - runAppend(view); + }); - equal(view.$('#two-positional').text(), 'one - two'); - equal(view.$('#one-positional').text(), 'one - two'); - equal(view.$('#no-positional').text(), 'one - two'); -}); + equal(this.$('#two-positional').text(), 'one - two'); + equal(this.$('#one-positional').text(), 'one - two'); + equal(this.$('#no-positional').text(), 'one - two'); + } -QUnit.test('dynamic arbitrary number of positional parameters', function() { - var SampleComponent = Component.extend(); - SampleComponent.reopenClass({ - positionalParams: 'n' - }); - owner.register('template:components/sample-component', compile('{{#each attrs.n as |name|}}{{name}}{{/each}}')); - owner.register('component:sample-component', SampleComponent); - - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{sample-component user1 user2 id="direct"}}{{component "sample-component" user1 user2 id="helper"}}'), - context: { + ['@test dynamic arbitrary number of positional parameters']() { + let SampleComponent = Component.extend(); + SampleComponent.reopenClass({ + positionalParams: 'n' + }); + this.registerComponent('sample-component', { + ComponentClass: SampleComponent, + template: '{{#each attrs.n as |name|}}{{name}}{{/each}}' + }); + + this.render('{{sample-component user1 user2 id="direct"}}{{component "sample-component" user1 user2 id="helper"}}', { user1: 'Foo', user2: 4 - } - }).create(); - - runAppend(view); - - equal(view.$('#direct').text(), 'Foo4'); - equal(view.$('#helper').text(), 'Foo4'); - run(function() { - set(view.context, 'user1', 'Bar'); - set(view.context, 'user2', '5'); - }); - - equal(view.$('#direct').text(), 'Bar5'); - equal(view.$('#helper').text(), 'Bar5'); - - run(function() { - set(view.context, 'user2', '6'); - }); - - equal(view.$('#direct').text(), 'Bar6'); - equal(view.$('#helper').text(), 'Bar6'); -}); + }); -QUnit.test('moduleName is available on _renderNode when a layout is present', function() { - expect(1); - - var layoutModuleName = 'my-app-name/templates/components/sample-component'; - var sampleComponentLayout = compile('Sample Component - {{yield}}', { - moduleName: layoutModuleName - }); - owner.register('template:components/sample-component', sampleComponentLayout); - owner.register('component:sample-component', Component.extend({ - didInsertElement: function() { - equal(this._renderNode.lastResult.template.meta.moduleName, layoutModuleName); - } - })); - - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{sample-component}}') - }).create(); - - runAppend(view); -}); - -QUnit.test('moduleName is available on _renderNode when no layout is present', function() { - expect(1); + equal(this.$('#direct').text(), 'Foo4'); + equal(this.$('#helper').text(), 'Foo4'); - var templateModuleName = 'my-app-name/templates/application'; - owner.register('component:sample-component', Component.extend({ - didInsertElement: function() { - equal(this._renderNode.lastResult.template.meta.moduleName, templateModuleName); - } - })); + run(() => { + this.component.set('user1', 'Bar'); + this.component.set('user2', '5'); + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{#sample-component}}Derp{{/sample-component}}', { - moduleName: templateModuleName - }) - }).create(); - - runAppend(view); -}); + equal(this.$('#direct').text(), 'Bar5'); + equal(this.$('#helper').text(), 'Bar5'); -QUnit.test('{{component}} helper works with positional params', function() { - var SampleComponent = Component.extend(); - SampleComponent.reopenClass({ - positionalParams: ['name', 'age'] - }); - - owner.register('template:components/sample-component', compile('{{attrs.name}}{{attrs.age}}')); - owner.register('component:sample-component', SampleComponent); - - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{component "sample-component" myName myAge}}'), - context: { - myName: 'Quint', - myAge: 4 - } - }).create(); + run(() => { + this.component.set('user2', '6'); + }); - runAppend(view); - equal(jQuery('#qunit-fixture').text(), 'Quint4'); - run(function() { - set(view.context, 'myName', 'Edward'); - set(view.context, 'myAge', '5'); - }); - - equal(jQuery('#qunit-fixture').text(), 'Edward5'); -}); - -QUnit.test('yield to inverse', function() { - owner.register('template:components/my-if', compile('{{#if predicate}}Yes:{{yield someValue}}{{else}}No:{{yield to="inverse"}}{{/if}}')); - - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{#my-if predicate=activated someValue=42 as |result|}}Hello{{result}}{{else}}Goodbye{{/my-if}}'), - context: { - activated: true - } - }).create(); + equal(this.$('#direct').text(), 'Bar6'); + equal(this.$('#helper').text(), 'Bar6'); + } - runAppend(view); - equal(jQuery('#qunit-fixture').text(), 'Yes:Hello42'); - run(function() { - set(view.context, 'activated', false); - }); + ['@test moduleName is available on _renderNode when a layout is present']() { + expect(1); - equal(jQuery('#qunit-fixture').text(), 'No:Goodbye'); -}); + let layoutModuleName = 'my-app-name/templates/components/sample-component'; + let sampleComponentLayout = compile('Sample Component - {{yield}}', { + moduleName: layoutModuleName + }); -QUnit.test('parameterized hasBlock inverse', function() { - owner.register('template:components/check-inverse', compile('{{#if (hasBlock "inverse")}}Yes{{else}}No{{/if}}')); + this.owner.register('template:components/sample-component', sampleComponentLayout); + this.owner.register('component:sample-component', Component.extend({ + didInsertElement: function() { + equal(this._renderNode.lastResult.template.meta.moduleName, layoutModuleName); + } + })); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{#check-inverse id="expect-no"}}{{/check-inverse}} {{#check-inverse id="expect-yes"}}{{else}}{{/check-inverse}}') - }).create(); + this.render('{{sample-component}}'); + } - runAppend(view); - equal(jQuery('#qunit-fixture #expect-no').text(), 'No'); - equal(jQuery('#qunit-fixture #expect-yes').text(), 'Yes'); -}); + ['@test moduleName is available on _renderNode when no layout is present']() { + expect(1); -QUnit.test('parameterized hasBlock default', function() { - owner.register('template:components/check-block', compile('{{#if (hasBlock)}}Yes{{else}}No{{/if}}')); + let templateModuleName = 'my-app-name/templates/application'; + this.registerComponent('sample-component', { + ComponentClass: Component.extend({ + didInsertElement: function() { + equal(this._renderNode.lastResult.template.meta.moduleName, templateModuleName); + } + }) + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{check-block id="expect-no"}} {{#check-block id="expect-yes"}}{{/check-block}}') - }).create(); + this.render(compile('{{#sample-component}}Derp{{/sample-component}}', { + moduleName: templateModuleName + })); + } - runAppend(view); - equal(jQuery('#qunit-fixture #expect-no').text(), 'No'); - equal(jQuery('#qunit-fixture #expect-yes').text(), 'Yes'); -}); + ['@test {{component}} helper works with positional params']() { + let SampleComponent = Component.extend(); + SampleComponent.reopenClass({ + positionalParams: ['name', 'age'] + }); -QUnit.test('non-expression hasBlock ', function() { - owner.register('template:components/check-block', compile('{{#if hasBlock}}Yes{{else}}No{{/if}}')); + this.registerComponent('sample-component', { + ComponentClass: SampleComponent, + template: '{{attrs.name}}{{attrs.age}}' + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{check-block id="expect-no"}} {{#check-block id="expect-yes"}}{{/check-block}}') - }).create(); + this.render('{{component "sample-component" myName myAge}}', { + myName: 'Quint', + myAge: 4 + }); - runAppend(view); - equal(jQuery('#qunit-fixture #expect-no').text(), 'No'); - equal(jQuery('#qunit-fixture #expect-yes').text(), 'Yes'); -}); + equal(this.$().text(), 'Quint4'); -QUnit.test('parameterized hasBlockParams', function() { - owner.register('template:components/check-params', compile('{{#if (hasBlockParams)}}Yes{{else}}No{{/if}}')); + run(() => { + this.component.set('myName', 'Edward'); + this.component.set('myAge', '5'); + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{#check-params id="expect-no"}}{{/check-params}} {{#check-params id="expect-yes" as |foo|}}{{/check-params}}') - }).create(); + equal(this.$().text(), 'Edward5'); + } - runAppend(view); - equal(jQuery('#qunit-fixture #expect-no').text(), 'No'); - equal(jQuery('#qunit-fixture #expect-yes').text(), 'Yes'); -}); + ['@test yield to inverse']() { + this.registerComponent('my-if', { + template: '{{#if predicate}}Yes:{{yield someValue}}{{else}}No:{{yield to="inverse"}}{{/if}}' + }); -QUnit.test('non-expression hasBlockParams', function() { - owner.register('template:components/check-params', compile('{{#if hasBlockParams}}Yes{{else}}No{{/if}}')); + this.render('{{#my-if predicate=activated someValue=42 as |result|}}Hello{{result}}{{else}}Goodbye{{/my-if}}', { + activated: true + }); - view = EmberView.extend({ - [OWNER]: owner, - layout: compile('{{#check-params id="expect-no"}}{{/check-params}} {{#check-params id="expect-yes" as |foo|}}{{/check-params}}') - }).create(); + equal(this.$().text(), 'Yes:Hello42'); - runAppend(view); - equal(jQuery('#qunit-fixture #expect-no').text(), 'No'); - equal(jQuery('#qunit-fixture #expect-yes').text(), 'Yes'); -}); + run(() => { + this.component.set('activated', false); + }); -QUnit.test('components in template of a yielding component should have the proper parentView', function() { - var outer, innerTemplate, innerLayout; - - owner.register('component:x-outer', Component.extend({ - init() { - this._super(...arguments); - outer = this; - } - })); - - owner.register('component:x-inner-in-template', Component.extend({ - init() { - this._super(...arguments); - innerTemplate = this; - } - })); - - owner.register('component:x-inner-in-layout', Component.extend({ - init() { - this._super(...arguments); - innerLayout = this; - } - })); - - owner.register('template:components/x-outer', compile('{{x-inner-in-layout}}{{yield}}')); - - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#x-outer}}{{x-inner-in-template}}{{/x-outer}}') - }).create(); - - runAppend(view); - - equal(innerTemplate.parentView, outer, 'receives the wrapping component as its parentView in template blocks'); - equal(innerLayout.parentView, outer, 'receives the wrapping component as its parentView in layout'); - equal(outer.parentView, view, 'x-outer receives the ambient scope as its parentView'); -}); + equal(this.$().text(), 'No:Goodbye'); + } -QUnit.test('newly-added sub-components get correct parentView', function() { - var outer, inner; + ['@test parameterized hasBlock inverse']() { + this.registerComponent('check-inverse', { + template: '{{#if (hasBlock "inverse")}}Yes{{else}}No{{/if}}' + }); - owner.register('component:x-outer', Component.extend({ - init() { - this._super(...arguments); - outer = this; - } - })); + this.render('{{#check-inverse id="expect-no"}}{{/check-inverse}} {{#check-inverse id="expect-yes"}}{{else}}{{/check-inverse}}'); - owner.register('component:x-inner', Component.extend({ - init() { - this._super(...arguments); - inner = this; - } - })); + equal(this.$('#expect-no').text(), 'No'); + equal(this.$('#expect-yes').text(), 'Yes'); + } - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#x-outer}}{{#if view.showInner}}{{x-inner}}{{/if}}{{/x-outer}}'), - showInner: false - }).create(); + ['@test parameterized hasBlock default']() { + this.registerComponent('check-block', { + template: '{{#if (hasBlock)}}Yes{{else}}No{{/if}}' + }); - runAppend(view); + this.render('{{check-block id="expect-no"}} {{#check-block id="expect-yes"}}{{/check-block}}'); - run(() => { view.set('showInner', true); }); + equal(this.$('#expect-no').text(), 'No'); + equal(this.$('#expect-yes').text(), 'Yes'); + } - equal(inner.parentView, outer, 'receives the wrapping component as its parentView in template blocks'); - equal(outer.parentView, view, 'x-outer receives the ambient scope as its parentView'); -}); + ['@test non-expression hasBlock ']() { + this.registerComponent('check-block', { + template: '{{#if hasBlock}}Yes{{else}}No{{/if}}' + }); -QUnit.test('components should receive the viewRegistry from the parent view', function() { - var outer, innerTemplate, innerLayout; - - var viewRegistry = {}; - - owner.register('component:x-outer', Component.extend({ - init() { - this._super(...arguments); - outer = this; - } - })); - - owner.register('component:x-inner-in-template', Component.extend({ - init() { - this._super(...arguments); - innerTemplate = this; - } - })); - - owner.register('component:x-inner-in-layout', Component.extend({ - init() { - this._super(...arguments); - innerLayout = this; - } - })); - - owner.register('template:components/x-outer', compile('{{x-inner-in-layout}}{{yield}}')); - - view = EmberView.extend({ - [OWNER]: owner, - _viewRegistry: viewRegistry, - template: compile('{{#x-outer}}{{x-inner-in-template}}{{/x-outer}}') - }).create(); - - runAppend(view); - - equal(innerTemplate._viewRegistry, viewRegistry); - equal(innerLayout._viewRegistry, viewRegistry); - equal(outer._viewRegistry, viewRegistry); -}); + this.render('{{check-block id="expect-no"}} {{#check-block id="expect-yes"}}{{/check-block}}'); -QUnit.test('comopnent should rerender when a property is changed during children\'s rendering', function() { - expectDeprecation(/modified value twice in a single render/); + equal(this.$('#expect-no').text(), 'No'); + equal(this.$('#expect-yes').text(), 'Yes'); + } - var outer, middle; + ['@test parameterized hasBlockParams']() { + this.registerComponent('check-params', { + template: '{{#if (hasBlockParams)}}Yes{{else}}No{{/if}}' + }); - owner.register('component:x-outer', Component.extend({ - value: 1, - grabReference: Ember.on('init', function() { - outer = this; - }) - })); + this.render('{{#check-params id="expect-no"}}{{/check-params}} {{#check-params id="expect-yes" as |foo|}}{{/check-params}}'); - owner.register('component:x-middle', Component.extend({ - value: null, - grabReference: Ember.on('init', function() { - middle = this; - }) - })); + equal(this.$('#expect-no').text(), 'No'); + equal(this.$('#expect-yes').text(), 'Yes'); + } - owner.register('component:x-inner', Component.extend({ - value: null, - pushDataUp: Ember.observer('value', function() { - middle.set('value', this.get('value')); - }) - })); + ['@test non-expression hasBlockParams']() { + this.registerComponent('check-params', { + template: '{{#if hasBlockParams}}Yes{{else}}No{{/if}}' + }); - owner.register('template:components/x-outer', compile('{{#x-middle}}{{x-inner value=value}}{{/x-middle}}')); - owner.register('template:components/x-middle', compile('
{{value}}
{{yield}}')); - owner.register('template:components/x-inner', compile('
{{value}}
')); + this.render('{{#check-params id="expect-no"}}{{/check-params}} {{#check-params id="expect-yes" as |foo|}}{{/check-params}}'); + equal(this.$('#expect-no').text(), 'No'); + equal(this.$('#expect-yes').text(), 'Yes'); + } - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{x-outer}}') - }).create(); + ['@test components in template of a yielding component should have the proper parentView']() { + let outer, innerTemplate, innerLayout; + + this.registerComponent('x-outer', { + ComponentClass: Component.extend({ + init() { + this._super(...arguments); + outer = this; + } + }), + template: '{{x-inner-in-layout}}{{yield}}' + }); + + this.registerComponent('x-inner-in-template', { + ComponentClass: Component.extend({ + init() { + this._super(...arguments); + innerTemplate = this; + } + }) + }); + + this.registerComponent('x-inner-in-layout', { + ComponentClass: Component.extend({ + init() { + this._super(...arguments); + innerLayout = this; + } + }) + }); + + this.render('{{#x-outer}}{{x-inner-in-template}}{{/x-outer}}'); + + equal(innerTemplate.parentView, outer, 'receives the wrapping component as its parentView in template blocks'); + equal(innerLayout.parentView, outer, 'receives the wrapping component as its parentView in layout'); + equal(outer.parentView, this.component, 'x-outer receives the ambient scope as its parentView'); + } - runAppend(view); + ['@test newly-added sub-components get correct parentView']() { + let outer, inner; + + this.registerComponent('x-outer', { + ComponentClass: Component.extend({ + init() { + this._super(...arguments); + outer = this; + } + }) + }); + + this.registerComponent('x-inner', { + ComponentClass: Component.extend({ + init() { + this._super(...arguments); + inner = this; + } + }) + }); + + this.render('{{#x-outer}}{{#if view.showInner}}{{x-inner}}{{/if}}{{/x-outer}}', { + showInner: false + }); + + run(() => { this.component.set('showInner', true); }); + + equal(inner.parentView, outer, 'receives the wrapping component as its parentView in template blocks'); + equal(outer.parentView, this.component, 'x-outer receives the ambient scope as its parentView'); + } - equal(view.$('#inner-value').text(), '1', 'initial render of inner'); - equal(view.$('#middle-value').text(), '', 'initial render of middle (observers do not run during init)'); + ['@test components should receive the viewRegistry from the parent view']() { + let outer, innerTemplate, innerLayout; + + let viewRegistry = {}; + + this.registerComponent('x-outer', { + ComponentClass: Component.extend({ + init() { + this._super(...arguments); + outer = this; + } + }), + template: '{{x-inner-in-layout}}{{yield}}' + }); + + this.registerComponent('x-inner-in-template', { + ComponentClass: Component.extend({ + init() { + this._super(...arguments); + innerTemplate = this; + } + }) + }); + + this.registerComponent('x-inner-in-layout', { + ComponentClass: Component.extend({ + init() { + this._super(...arguments); + innerLayout = this; + } + }) + }); + + this.render('{{#x-outer}}{{x-inner-in-template}}{{/x-outer}}', { + _viewRegistry: viewRegistry + }); + + equal(innerTemplate._viewRegistry, viewRegistry); + equal(innerLayout._viewRegistry, viewRegistry); + equal(outer._viewRegistry, viewRegistry); + } - run(() => outer.set('value', 2)); + ['@test comopnent should rerender when a property is changed during children\'s rendering']() { + expectDeprecation(/modified value twice in a single render/); + + let outer, middle; + + this.registerComponent('x-outer', { + ComponentClass: Component.extend({ + value: 1, + init() { + this._super(...arguments); + outer = this; + } + }), + template: '{{#x-middle}}{{x-inner value=value}}{{/x-middle}}' + }); + + this.registerComponent('x-middle', { + ComponentClass: Component.extend({ + value: null, + init() { + this._super(...arguments); + middle = this; + } + }), + template: '
{{value}}
{{yield}}' + }); + + this.registerComponent('x-inner', { + ComponentClass: Component.extend({ + value: null, + pushDataUp: Ember.observer('value', function() { + middle.set('value', this.get('value')); + }) + }), + template: '
{{value}}
' + }); + + + this.render('{{x-outer}}'); + + equal(this.$('#inner-value').text(), '1', 'initial render of inner'); + equal(this.$('#middle-value').text(), '', 'initial render of middle (observers do not run during init)'); + + run(() => outer.set('value', 2)); + + equal(this.$('#inner-value').text(), '2', 'second render of inner'); + equal(this.$('#middle-value').text(), '2', 'second render of middle'); + + run(() => outer.set('value', 3)); + + equal(this.$('#inner-value').text(), '3', 'third render of inner'); + equal(this.$('#middle-value').text(), '3', 'third render of middle'); + } - equal(view.$('#inner-value').text(), '2', 'second render of inner'); - equal(view.$('#middle-value').text(), '2', 'second render of middle'); + ['@test non-block with each rendering child components']() { + expect(2); - run(() => outer.set('value', 3)); + this.registerComponent('non-block', { + template: 'In layout. {{#each attrs.items as |item|}}[{{child-non-block item=item}}]{{/each}}' + }); + this.registerComponent('child-non-block', { + template: 'Child: {{attrs.item}}.' + }); - equal(view.$('#inner-value').text(), '3', 'third render of inner'); - equal(view.$('#middle-value').text(), '3', 'third render of middle'); -}); + let items = emberA(['Tom', 'Dick', 'Harry']); -QUnit.test('non-block with each rendering child components', function() { - expect(2); + this.render('{{non-block items=view.items}}', { + items: items + }); - owner.register('template:components/non-block', compile('In layout. {{#each attrs.items as |item|}}[{{child-non-block item=item}}]{{/each}}')); - owner.register('template:components/child-non-block', compile('Child: {{attrs.item}}.')); + equal(this.$().text(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.]'); - var items = emberA(['Tom', 'Dick', 'Harry']); + run(() => { + items.pushObject('James'); + }); - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{non-block items=view.items}}'), - items: items - }).create(); + equal(this.$().text(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.][Child: James.]'); + } - runAppend(view); + ['@test specifying classNames results in correct class'](assert) { + expect(3); - equal(jQuery('#qunit-fixture').text(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.]'); + let clickyThing; + this.registerComponent('some-clicky-thing', { + ComponentClass: Component.extend({ + tagName: 'button', + classNames: ['foo', 'bar'], + init() { + this._super(...arguments); + clickyThing = this; + } + }) + }); - run(function() { - items.pushObject('James'); - }); + this.render('{{#some-clicky-thing classNames="baz"}}Click Me{{/some-clicky-thing}}'); - equal(jQuery('#qunit-fixture').text(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.][Child: James.]'); -}); + let button = this.$('button'); + assert.ok(button.is('.foo.bar.baz.ember-view'), 'the element has the correct classes: ' + button.attr('class')); -QUnit.test('specifying classNames results in correct class', function(assert) { - expect(3); + let expectedClassNames = ['ember-view', 'foo', 'bar', 'baz']; + assert.deepEqual(clickyThing.get('classNames'), expectedClassNames, 'classNames are properly combined'); - let clickyThing; - owner.register('component:some-clicky-thing', Component.extend({ - tagName: 'button', - classNames: ['foo', 'bar'], - init() { - this._super(...arguments); - clickyThing = this; - } - })); + let buttonClassNames = button.attr('class'); + assert.deepEqual(buttonClassNames.split(' '), expectedClassNames, 'all classes are set 1:1 in DOM'); + } - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#some-clicky-thing classNames="baz"}}Click Me{{/some-clicky-thing}}') - }).create(); + ['@test specifying custom concatenatedProperties avoids clobbering'](assert) { + expect(1); - runAppend(view); + let clickyThing; + this.registerComponent('some-clicky-thing', { + ComponentClass: Component.extend({ + concatenatedProperties: ['blahzz'], + blahzz: ['blark', 'pory'], + init() { + this._super(...arguments); + clickyThing = this; + } + }) + }); - let button = view.$('button'); - ok(button.is('.foo.bar.baz.ember-view'), 'the element has the correct classes: ' + button.attr('class')); + this.render('{{#some-clicky-thing blahzz="baz"}}Click Me{{/some-clicky-thing}}'); - let expectedClassNames = ['ember-view', 'foo', 'bar', 'baz']; - assert.deepEqual(clickyThing.get('classNames'), expectedClassNames, 'classNames are properly combined'); + assert.deepEqual(clickyThing.get('blahzz'), ['blark', 'pory', 'baz'], 'property is properly combined'); + } - let buttonClassNames = button.attr('class'); - assert.deepEqual(buttonClassNames.split(' '), expectedClassNames, 'all classes are set 1:1 in DOM'); }); -QUnit.test('specifying custom concatenatedProperties avoids clobbering', function(assert) { - expect(1); - - let clickyThing; - owner.register('component:some-clicky-thing', Component.extend({ - concatenatedProperties: ['blahzz'], - blahzz: ['blark', 'pory'], - init() { - this._super(...arguments); - clickyThing = this; - } - })); - - view = EmberView.extend({ - [OWNER]: owner, - template: compile('{{#some-clicky-thing blahzz="baz"}}Click Me{{/some-clicky-thing}}') - }).create(); - - runAppend(view); - - assert.deepEqual(clickyThing.get('blahzz'), ['blark', 'pory', 'baz'], 'property is properly combined'); -}); diff --git a/packages/ember-runtime/tests/utils.js b/packages/ember-runtime/tests/utils.js index 2e8fa7a9b08..dd273565a22 100644 --- a/packages/ember-runtime/tests/utils.js +++ b/packages/ember-runtime/tests/utils.js @@ -1,4 +1,12 @@ +import { OWNER } from 'container/owner'; +import Component from 'ember-views/components/component'; +import ComponentLookup from 'ember-views/component_lookup'; +import buildOwner from 'container/tests/test-helpers/build-owner'; import run from 'ember-metal/run_loop'; +import symbol from 'ember-metal/symbol'; + +export const TEST_OWNER = symbol('TEST_OWNER'); +export const TEST_MAIN_COMPONENT = symbol('TEST_MAIN_COMPONENT'); function runAppend(view) { run(view, 'appendTo', '#qunit-fixture'); @@ -10,7 +18,77 @@ function runDestroy(destroyed) { } } +function moduleForApp(moduleName, options={}) { + let setup = function() { + this[TEST_OWNER] = buildOwner(); + this[TEST_OWNER].registerOptionsForType('component', { singleton: false }); + this[TEST_OWNER].registerOptionsForType('template', { instantiate: false }); + this[TEST_OWNER].register('component-lookup:main', ComponentLookup); + + this.getOwner = () => this[TEST_OWNER]; + this.register = register; + this.render = render; + this.rerender = rerender; + this.$ = customSelector; + + if (typeof options.setup === 'function') { + options.setup.apply(this, arguments); + } + }; + + let teardown = function() { + if (typeof options.teardown === 'function') { + options.teardown.apply(this, arguments); + } + + if (this[TEST_MAIN_COMPONENT]) { + runDestroy(this[TEST_MAIN_COMPONENT]); + } + + runDestroy(this[TEST_OWNER]); + + this[TEST_MAIN_COMPONENT] = this[TEST_OWNER] = null; + }; + + QUnit.module(moduleName, { + setup, + teardown + }); +} + +function register(fullName, factory, options) { + this.getOwner().register(fullName, factory, options); + return factory; +} + +function render(template, hash={}) { + if (this[TEST_MAIN_COMPONENT]) { + ok(false, 'you cannot render twice in the same test'); + return; + } + + this[TEST_MAIN_COMPONENT] = Component.extend({ + template, + [OWNER]: this.getOwner() + }).create(hash); + + runAppend(this[TEST_MAIN_COMPONENT]); + + return this[TEST_MAIN_COMPONENT]; +} + +function rerender() { + if (this[TEST_MAIN_COMPONENT]) { + run(this[TEST_MAIN_COMPONENT], 'rerender'); + } +} + +function customSelector() { + return this[TEST_MAIN_COMPONENT].$(...arguments); +} + export { + moduleForApp, runAppend, runDestroy }; From 05a84988a347ff7e3506f2098facd4b57021a4f6 Mon Sep 17 00:00:00 2001 From: Sergio Arbeo Date: Sat, 5 Mar 2016 01:56:26 +0530 Subject: [PATCH 2/3] Modify `textValue` method to allow a selector parameter This make the tests more homogeneous being able to select text from any part of the component. --- .../tests/utils/abstract-test-case.js | 4 +- .../integration/component_invocation_test.js | 114 +++++++++--------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/packages/ember-glimmer/tests/utils/abstract-test-case.js b/packages/ember-glimmer/tests/utils/abstract-test-case.js index b7694c7b08e..2b63e7463a1 100644 --- a/packages/ember-glimmer/tests/utils/abstract-test-case.js +++ b/packages/ember-glimmer/tests/utils/abstract-test-case.js @@ -210,8 +210,8 @@ export class RenderingTest extends TestCase { } } - textValue() { - return this.$().text(); + textValue(sel) { + return this.$(sel).text(); } assertText(text) { diff --git a/packages/ember-htmlbars/tests/integration/component_invocation_test.js b/packages/ember-htmlbars/tests/integration/component_invocation_test.js index 973d585cc2b..a4f1ecc52f5 100644 --- a/packages/ember-htmlbars/tests/integration/component_invocation_test.js +++ b/packages/ember-htmlbars/tests/integration/component_invocation_test.js @@ -16,7 +16,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block}}'); - equal(this.$().text(), 'In layout'); + equal(this.textValue(), 'In layout'); } ['@test GlimmerComponent cannot be invoked with curly braces']() { @@ -39,7 +39,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block}}In template{{/with-block}}'); - equal(this.$().text(), 'In layout - In template'); + equal(this.textValue(), 'In layout - In template'); } ['@test non-block with properties on attrs']() { @@ -51,7 +51,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block someProp="something here"}}'); - equal(this.$().text(), 'In layout - someProp: something here'); + equal(this.textValue(), 'In layout - someProp: something here'); } ['@test non-block with properties on attrs and component class']() { @@ -62,7 +62,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block someProp="something here"}}'); - equal(this.$().text(), 'In layout - someProp: something here'); + equal(this.textValue(), 'In layout - someProp: something here'); } @@ -82,7 +82,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block someProp="something passed when invoked"}}'); - equal(this.$().text(), 'In layout - someProp: value set in init'); + equal(this.textValue(), 'In layout - someProp: value set in init'); } ['@test lookup of component takes priority over property']() { @@ -97,7 +97,7 @@ moduleFor('component - invocation', class extends RenderingTest { 'some-prop': 'some-prop' }); - equal(this.$().text(), 'some-prop some-component'); + equal(this.textValue(), 'some-prop some-component'); } ['@test component without dash is not looked up']() { @@ -111,7 +111,7 @@ moduleFor('component - invocation', class extends RenderingTest { 'somecomponent': 'notsomecomponent' }); - equal(this.$().text(), 'notsomecomponent'); + equal(this.textValue(), 'notsomecomponent'); } ['@test rerendering component with attrs from parent']() { @@ -138,13 +138,13 @@ moduleFor('component - invocation', class extends RenderingTest { equal(didReceiveAttrs, 1, 'The didReceiveAttrs hook fired'); - equal(this.$().text(), 'In layout - someProp: wycats'); + equal(this.textValue(), 'In layout - someProp: wycats'); run(() => { this.component.set('someProp', 'tomdale'); }); - equal(this.$().text(), 'In layout - someProp: tomdale'); + equal(this.textValue(), 'In layout - someProp: tomdale'); equal(didReceiveAttrs, 2, 'The didReceiveAttrs hook fired again'); equal(willUpdate, 1, 'The willUpdate hook fired once'); @@ -152,7 +152,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.rerender(); }); - equal(this.$().text(), 'In layout - someProp: tomdale'); + equal(this.textValue(), 'In layout - someProp: tomdale'); equal(didReceiveAttrs, 3, 'The didReceiveAttrs hook fired again'); equal(willUpdate, 2, 'The willUpdate hook fired again'); } @@ -167,7 +167,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block someProp="something here"}}'); - equal(this.$().text(), 'In layout - someProp: something here'); + equal(this.textValue(), 'In layout - someProp: something here'); } ['@test block with properties on attrs']() { @@ -179,7 +179,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block someProp="something here"}}In template{{/with-block}}'); - equal(this.$().text(), 'In layout - someProp: something here - In template'); + equal(this.textValue(), 'In layout - someProp: something here - In template'); } ['@test [DEPRECATED] block with properties on self']() { @@ -192,7 +192,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block someProp="something here"}}In template{{/with-block}}'); - equal(this.$().text(), 'In layout - someProp: something here - In template'); + equal(this.textValue(), 'In layout - someProp: something here - In template'); } ['@test with ariaRole specified']() { @@ -219,7 +219,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block}}Whoop, whoop!{{/with-block}}'); - equal(this.$().text(), 'Whoop, whoop!', 'block provided always overrides template property'); + equal(this.textValue(), 'Whoop, whoop!', 'block provided always overrides template property'); } ['@test hasBlock is true when block supplied']() { @@ -231,7 +231,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block}}In template{{/with-block}}'); - equal(this.$().text(), 'In template'); + equal(this.textValue(), 'In template'); } ['@test hasBlock is false when no block supplied']() { @@ -243,7 +243,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{with-block}}'); - equal(this.$().text(), 'No Block!'); + equal(this.textValue(), 'No Block!'); } ['@test hasBlock is false when no block supplied']() { @@ -255,7 +255,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{with-block}}'); - equal(this.$().text(), 'No Block!'); + equal(this.textValue(), 'No Block!'); } ['@test hasBlockParams is true when block param supplied']() { @@ -267,7 +267,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block as |something|}}In template{{/with-block}}'); - equal(this.$().text(), 'In template - In Component'); + equal(this.textValue(), 'In template - In Component'); } ['@test hasBlockParams is false when no block param supplied']() { @@ -279,7 +279,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block}}In block{{/with-block}}'); - equal(this.$().text(), 'In block No Block Param!'); + equal(this.textValue(), 'In block No Block Param!'); } ['@test static named positional parameters']() { @@ -295,7 +295,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{sample-component "Quint" 4}}'); - equal(this.$().text(), 'Quint4'); + equal(this.textValue(), 'Quint4'); } ['@test dynamic named positional parameters']() { @@ -314,14 +314,14 @@ moduleFor('component - invocation', class extends RenderingTest { myAge: 4 }); - equal(this.$().text(), 'Quint4'); + equal(this.textValue(), 'Quint4'); run(() => { this.component.set('myName', 'Edward'); this.component.set('myAge', '5'); }); - equal(this.$().text(), 'Edward5'); + equal(this.textValue(), 'Edward5'); } ['@test if a value is passed as a non-positional parameter, it takes precedence over the named one']() { @@ -356,9 +356,9 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{sample-component "Foo" 4 "Bar" id="args-3"}}{{sample-component "Foo" 4 "Bar" 5 "Baz" id="args-5"}}{{component "sample-component" "Foo" 4 "Bar" 5 "Baz" id="helper"}}'); - equal(this.$('#args-3').text(), 'Foo4Bar'); - equal(this.$('#args-5').text(), 'Foo4Bar5Baz'); - equal(this.$('#helper').text(), 'Foo4Bar5Baz'); + equal(this.textValue('#args-3'), 'Foo4Bar'); + equal(this.textValue('#args-5'), 'Foo4Bar5Baz'); + equal(this.textValue('#helper'), 'Foo4Bar5Baz'); } ['@test arbitrary positional parameter conflict with hash parameter is reported']() { @@ -394,7 +394,7 @@ moduleFor('component - invocation', class extends RenderingTest { things: ['Foo', 4, 'Bar'] }); - equal(this.$('#args-3').text(), 'Foo4Bar'); + equal(this.textValue('#args-3'), 'Foo4Bar'); } ['@test can use hash parameter instead of positional param']() { @@ -416,9 +416,9 @@ moduleFor('component - invocation', class extends RenderingTest { things: ['Foo', 4, 'Bar'] }); - equal(this.$('#two-positional').text(), 'one - two'); - equal(this.$('#one-positional').text(), 'one - two'); - equal(this.$('#no-positional').text(), 'one - two'); + equal(this.textValue('#two-positional'), 'one - two'); + equal(this.textValue('#one-positional'), 'one - two'); + equal(this.textValue('#no-positional'), 'one - two'); } ['@test dynamic arbitrary number of positional parameters']() { @@ -436,23 +436,23 @@ moduleFor('component - invocation', class extends RenderingTest { user2: 4 }); - equal(this.$('#direct').text(), 'Foo4'); - equal(this.$('#helper').text(), 'Foo4'); + equal(this.textValue('#direct'), 'Foo4'); + equal(this.textValue('#helper'), 'Foo4'); run(() => { this.component.set('user1', 'Bar'); this.component.set('user2', '5'); }); - equal(this.$('#direct').text(), 'Bar5'); - equal(this.$('#helper').text(), 'Bar5'); + equal(this.textValue('#direct'), 'Bar5'); + equal(this.textValue('#helper'), 'Bar5'); run(() => { this.component.set('user2', '6'); }); - equal(this.$('#direct').text(), 'Bar6'); - equal(this.$('#helper').text(), 'Bar6'); + equal(this.textValue('#direct'), 'Bar6'); + equal(this.textValue('#helper'), 'Bar6'); } ['@test moduleName is available on _renderNode when a layout is present']() { @@ -506,14 +506,14 @@ moduleFor('component - invocation', class extends RenderingTest { myAge: 4 }); - equal(this.$().text(), 'Quint4'); + equal(this.textValue(), 'Quint4'); run(() => { this.component.set('myName', 'Edward'); this.component.set('myAge', '5'); }); - equal(this.$().text(), 'Edward5'); + equal(this.textValue(), 'Edward5'); } ['@test yield to inverse']() { @@ -525,13 +525,13 @@ moduleFor('component - invocation', class extends RenderingTest { activated: true }); - equal(this.$().text(), 'Yes:Hello42'); + equal(this.textValue(), 'Yes:Hello42'); run(() => { this.component.set('activated', false); }); - equal(this.$().text(), 'No:Goodbye'); + equal(this.textValue(), 'No:Goodbye'); } ['@test parameterized hasBlock inverse']() { @@ -541,8 +541,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#check-inverse id="expect-no"}}{{/check-inverse}} {{#check-inverse id="expect-yes"}}{{else}}{{/check-inverse}}'); - equal(this.$('#expect-no').text(), 'No'); - equal(this.$('#expect-yes').text(), 'Yes'); + equal(this.textValue('#expect-no'), 'No'); + equal(this.textValue('#expect-yes'), 'Yes'); } ['@test parameterized hasBlock default']() { @@ -552,8 +552,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{check-block id="expect-no"}} {{#check-block id="expect-yes"}}{{/check-block}}'); - equal(this.$('#expect-no').text(), 'No'); - equal(this.$('#expect-yes').text(), 'Yes'); + equal(this.textValue('#expect-no'), 'No'); + equal(this.textValue('#expect-yes'), 'Yes'); } ['@test non-expression hasBlock ']() { @@ -563,8 +563,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{check-block id="expect-no"}} {{#check-block id="expect-yes"}}{{/check-block}}'); - equal(this.$('#expect-no').text(), 'No'); - equal(this.$('#expect-yes').text(), 'Yes'); + equal(this.textValue('#expect-no'), 'No'); + equal(this.textValue('#expect-yes'), 'Yes'); } ['@test parameterized hasBlockParams']() { @@ -574,8 +574,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#check-params id="expect-no"}}{{/check-params}} {{#check-params id="expect-yes" as |foo|}}{{/check-params}}'); - equal(this.$('#expect-no').text(), 'No'); - equal(this.$('#expect-yes').text(), 'Yes'); + equal(this.textValue('#expect-no'), 'No'); + equal(this.textValue('#expect-yes'), 'Yes'); } ['@test non-expression hasBlockParams']() { @@ -585,8 +585,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#check-params id="expect-no"}}{{/check-params}} {{#check-params id="expect-yes" as |foo|}}{{/check-params}}'); - equal(this.$('#expect-no').text(), 'No'); - equal(this.$('#expect-yes').text(), 'Yes'); + equal(this.textValue('#expect-no'), 'No'); + equal(this.textValue('#expect-yes'), 'Yes'); } ['@test components in template of a yielding component should have the proper parentView']() { @@ -740,18 +740,18 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{x-outer}}'); - equal(this.$('#inner-value').text(), '1', 'initial render of inner'); - equal(this.$('#middle-value').text(), '', 'initial render of middle (observers do not run during init)'); + equal(this.textValue('#inner-value'), '1', 'initial render of inner'); + equal(this.textValue('#middle-value'), '', 'initial render of middle (observers do not run during init)'); run(() => outer.set('value', 2)); - equal(this.$('#inner-value').text(), '2', 'second render of inner'); - equal(this.$('#middle-value').text(), '2', 'second render of middle'); + equal(this.textValue('#inner-value'), '2', 'second render of inner'); + equal(this.textValue('#middle-value'), '2', 'second render of middle'); run(() => outer.set('value', 3)); - equal(this.$('#inner-value').text(), '3', 'third render of inner'); - equal(this.$('#middle-value').text(), '3', 'third render of middle'); + equal(this.textValue('#inner-value'), '3', 'third render of inner'); + equal(this.textValue('#middle-value'), '3', 'third render of middle'); } ['@test non-block with each rendering child components']() { @@ -770,13 +770,13 @@ moduleFor('component - invocation', class extends RenderingTest { items: items }); - equal(this.$().text(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.]'); + equal(this.textValue(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.]'); run(() => { items.pushObject('James'); }); - equal(this.$().text(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.][Child: James.]'); + equal(this.textValue(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.][Child: James.]'); } ['@test specifying classNames results in correct class'](assert) { From b131c4a774c0924b59ef3eb378c061a94433efae Mon Sep 17 00:00:00 2001 From: Sergio Arbeo Date: Mon, 7 Mar 2016 23:11:22 +0100 Subject: [PATCH 3/3] Replace `equal(textValue)` with `assertText` This commit changes all `equal(this.textValue(), expected)` for the added `this.assertText`. It adds a couple of parameters and adds a nice message too. --- .../tests/utils/abstract-test-case.js | 14 ++- .../integration/component_invocation_test.js | 114 +++++++++--------- 2 files changed, 69 insertions(+), 59 deletions(-) diff --git a/packages/ember-glimmer/tests/utils/abstract-test-case.js b/packages/ember-glimmer/tests/utils/abstract-test-case.js index 2b63e7463a1..6e877ed65d7 100644 --- a/packages/ember-glimmer/tests/utils/abstract-test-case.js +++ b/packages/ember-glimmer/tests/utils/abstract-test-case.js @@ -214,8 +214,18 @@ export class RenderingTest extends TestCase { return this.$(sel).text(); } - assertText(text) { - assert.strictEqual(this.textValue(), text, '#qunit-fixture content'); + assertText(text, sel, msg) { + let errorText; + + if (msg) { + errorText = msg; + } else if (sel) { + errorText = `text in ${sel} was expected to be ${text} but found ${text}`; + } else { + errorText = `text was expected to be ${text} but found ${text}`; + } + + assert.strictEqual(this.textValue(sel), text, errorText); } assertHTML(html) { diff --git a/packages/ember-htmlbars/tests/integration/component_invocation_test.js b/packages/ember-htmlbars/tests/integration/component_invocation_test.js index a4f1ecc52f5..a53c89cc56b 100644 --- a/packages/ember-htmlbars/tests/integration/component_invocation_test.js +++ b/packages/ember-htmlbars/tests/integration/component_invocation_test.js @@ -16,7 +16,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block}}'); - equal(this.textValue(), 'In layout'); + this.assertText('In layout'); } ['@test GlimmerComponent cannot be invoked with curly braces']() { @@ -39,7 +39,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block}}In template{{/with-block}}'); - equal(this.textValue(), 'In layout - In template'); + this.assertText('In layout - In template'); } ['@test non-block with properties on attrs']() { @@ -51,7 +51,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block someProp="something here"}}'); - equal(this.textValue(), 'In layout - someProp: something here'); + this.assertText('In layout - someProp: something here'); } ['@test non-block with properties on attrs and component class']() { @@ -62,7 +62,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block someProp="something here"}}'); - equal(this.textValue(), 'In layout - someProp: something here'); + this.assertText('In layout - someProp: something here'); } @@ -82,7 +82,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block someProp="something passed when invoked"}}'); - equal(this.textValue(), 'In layout - someProp: value set in init'); + this.assertText('In layout - someProp: value set in init'); } ['@test lookup of component takes priority over property']() { @@ -97,7 +97,7 @@ moduleFor('component - invocation', class extends RenderingTest { 'some-prop': 'some-prop' }); - equal(this.textValue(), 'some-prop some-component'); + this.assertText('some-prop some-component'); } ['@test component without dash is not looked up']() { @@ -111,7 +111,7 @@ moduleFor('component - invocation', class extends RenderingTest { 'somecomponent': 'notsomecomponent' }); - equal(this.textValue(), 'notsomecomponent'); + this.assertText('notsomecomponent'); } ['@test rerendering component with attrs from parent']() { @@ -138,13 +138,13 @@ moduleFor('component - invocation', class extends RenderingTest { equal(didReceiveAttrs, 1, 'The didReceiveAttrs hook fired'); - equal(this.textValue(), 'In layout - someProp: wycats'); + this.assertText('In layout - someProp: wycats'); run(() => { this.component.set('someProp', 'tomdale'); }); - equal(this.textValue(), 'In layout - someProp: tomdale'); + this.assertText('In layout - someProp: tomdale'); equal(didReceiveAttrs, 2, 'The didReceiveAttrs hook fired again'); equal(willUpdate, 1, 'The willUpdate hook fired once'); @@ -152,7 +152,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.rerender(); }); - equal(this.textValue(), 'In layout - someProp: tomdale'); + this.assertText('In layout - someProp: tomdale'); equal(didReceiveAttrs, 3, 'The didReceiveAttrs hook fired again'); equal(willUpdate, 2, 'The willUpdate hook fired again'); } @@ -167,7 +167,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{non-block someProp="something here"}}'); - equal(this.textValue(), 'In layout - someProp: something here'); + this.assertText('In layout - someProp: something here'); } ['@test block with properties on attrs']() { @@ -179,7 +179,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block someProp="something here"}}In template{{/with-block}}'); - equal(this.textValue(), 'In layout - someProp: something here - In template'); + this.assertText('In layout - someProp: something here - In template'); } ['@test [DEPRECATED] block with properties on self']() { @@ -192,7 +192,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block someProp="something here"}}In template{{/with-block}}'); - equal(this.textValue(), 'In layout - someProp: something here - In template'); + this.assertText('In layout - someProp: something here - In template'); } ['@test with ariaRole specified']() { @@ -219,7 +219,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block}}Whoop, whoop!{{/with-block}}'); - equal(this.textValue(), 'Whoop, whoop!', 'block provided always overrides template property'); + this.assertText('Whoop, whoop!', null, 'block provided always overrides template property'); } ['@test hasBlock is true when block supplied']() { @@ -231,7 +231,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block}}In template{{/with-block}}'); - equal(this.textValue(), 'In template'); + this.assertText('In template'); } ['@test hasBlock is false when no block supplied']() { @@ -243,7 +243,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{with-block}}'); - equal(this.textValue(), 'No Block!'); + this.assertText('No Block!'); } ['@test hasBlock is false when no block supplied']() { @@ -255,7 +255,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{with-block}}'); - equal(this.textValue(), 'No Block!'); + this.assertText('No Block!'); } ['@test hasBlockParams is true when block param supplied']() { @@ -267,7 +267,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block as |something|}}In template{{/with-block}}'); - equal(this.textValue(), 'In template - In Component'); + this.assertText('In template - In Component'); } ['@test hasBlockParams is false when no block param supplied']() { @@ -279,7 +279,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#with-block}}In block{{/with-block}}'); - equal(this.textValue(), 'In block No Block Param!'); + this.assertText('In block No Block Param!'); } ['@test static named positional parameters']() { @@ -295,7 +295,7 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{sample-component "Quint" 4}}'); - equal(this.textValue(), 'Quint4'); + this.assertText('Quint4'); } ['@test dynamic named positional parameters']() { @@ -314,14 +314,14 @@ moduleFor('component - invocation', class extends RenderingTest { myAge: 4 }); - equal(this.textValue(), 'Quint4'); + this.assertText('Quint4'); run(() => { this.component.set('myName', 'Edward'); this.component.set('myAge', '5'); }); - equal(this.textValue(), 'Edward5'); + this.assertText('Edward5'); } ['@test if a value is passed as a non-positional parameter, it takes precedence over the named one']() { @@ -356,9 +356,9 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{sample-component "Foo" 4 "Bar" id="args-3"}}{{sample-component "Foo" 4 "Bar" 5 "Baz" id="args-5"}}{{component "sample-component" "Foo" 4 "Bar" 5 "Baz" id="helper"}}'); - equal(this.textValue('#args-3'), 'Foo4Bar'); - equal(this.textValue('#args-5'), 'Foo4Bar5Baz'); - equal(this.textValue('#helper'), 'Foo4Bar5Baz'); + this.assertText('Foo4Bar', '#args-3'); + this.assertText('Foo4Bar5Baz', '#args-5'); + this.assertText('Foo4Bar5Baz', '#helper'); } ['@test arbitrary positional parameter conflict with hash parameter is reported']() { @@ -394,7 +394,7 @@ moduleFor('component - invocation', class extends RenderingTest { things: ['Foo', 4, 'Bar'] }); - equal(this.textValue('#args-3'), 'Foo4Bar'); + this.assertText('Foo4Bar', '#args-3'); } ['@test can use hash parameter instead of positional param']() { @@ -416,9 +416,9 @@ moduleFor('component - invocation', class extends RenderingTest { things: ['Foo', 4, 'Bar'] }); - equal(this.textValue('#two-positional'), 'one - two'); - equal(this.textValue('#one-positional'), 'one - two'); - equal(this.textValue('#no-positional'), 'one - two'); + this.assertText('one - two', '#two-positional'); + this.assertText('one - two', '#one-positional'); + this.assertText('one - two', '#no-positional'); } ['@test dynamic arbitrary number of positional parameters']() { @@ -436,23 +436,23 @@ moduleFor('component - invocation', class extends RenderingTest { user2: 4 }); - equal(this.textValue('#direct'), 'Foo4'); - equal(this.textValue('#helper'), 'Foo4'); + this.assertText('Foo4', '#direct'); + this.assertText('Foo4', '#helper'); run(() => { this.component.set('user1', 'Bar'); this.component.set('user2', '5'); }); - equal(this.textValue('#direct'), 'Bar5'); - equal(this.textValue('#helper'), 'Bar5'); + this.assertText('Bar5', '#direct'); + this.assertText('Bar5', '#helper'); run(() => { this.component.set('user2', '6'); }); - equal(this.textValue('#direct'), 'Bar6'); - equal(this.textValue('#helper'), 'Bar6'); + this.assertText('Bar6', '#direct'); + this.assertText('Bar6', '#helper'); } ['@test moduleName is available on _renderNode when a layout is present']() { @@ -506,14 +506,14 @@ moduleFor('component - invocation', class extends RenderingTest { myAge: 4 }); - equal(this.textValue(), 'Quint4'); + this.assertText('Quint4'); run(() => { this.component.set('myName', 'Edward'); this.component.set('myAge', '5'); }); - equal(this.textValue(), 'Edward5'); + this.assertText('Edward5'); } ['@test yield to inverse']() { @@ -525,13 +525,13 @@ moduleFor('component - invocation', class extends RenderingTest { activated: true }); - equal(this.textValue(), 'Yes:Hello42'); + this.assertText('Yes:Hello42'); run(() => { this.component.set('activated', false); }); - equal(this.textValue(), 'No:Goodbye'); + this.assertText('No:Goodbye'); } ['@test parameterized hasBlock inverse']() { @@ -541,8 +541,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#check-inverse id="expect-no"}}{{/check-inverse}} {{#check-inverse id="expect-yes"}}{{else}}{{/check-inverse}}'); - equal(this.textValue('#expect-no'), 'No'); - equal(this.textValue('#expect-yes'), 'Yes'); + this.assertText('No', '#expect-no'); + this.assertText('Yes', '#expect-yes'); } ['@test parameterized hasBlock default']() { @@ -552,8 +552,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{check-block id="expect-no"}} {{#check-block id="expect-yes"}}{{/check-block}}'); - equal(this.textValue('#expect-no'), 'No'); - equal(this.textValue('#expect-yes'), 'Yes'); + this.assertText('No', '#expect-no'); + this.assertText('Yes', '#expect-yes'); } ['@test non-expression hasBlock ']() { @@ -563,8 +563,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{check-block id="expect-no"}} {{#check-block id="expect-yes"}}{{/check-block}}'); - equal(this.textValue('#expect-no'), 'No'); - equal(this.textValue('#expect-yes'), 'Yes'); + this.assertText('No', '#expect-no'); + this.assertText('Yes', '#expect-yes'); } ['@test parameterized hasBlockParams']() { @@ -574,8 +574,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#check-params id="expect-no"}}{{/check-params}} {{#check-params id="expect-yes" as |foo|}}{{/check-params}}'); - equal(this.textValue('#expect-no'), 'No'); - equal(this.textValue('#expect-yes'), 'Yes'); + this.assertText('No', '#expect-no'); + this.assertText('Yes', '#expect-yes'); } ['@test non-expression hasBlockParams']() { @@ -585,8 +585,8 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{#check-params id="expect-no"}}{{/check-params}} {{#check-params id="expect-yes" as |foo|}}{{/check-params}}'); - equal(this.textValue('#expect-no'), 'No'); - equal(this.textValue('#expect-yes'), 'Yes'); + this.assertText('No', '#expect-no'); + this.assertText('Yes', '#expect-yes'); } ['@test components in template of a yielding component should have the proper parentView']() { @@ -740,18 +740,18 @@ moduleFor('component - invocation', class extends RenderingTest { this.render('{{x-outer}}'); - equal(this.textValue('#inner-value'), '1', 'initial render of inner'); - equal(this.textValue('#middle-value'), '', 'initial render of middle (observers do not run during init)'); + this.assertText('1', '#inner-value', 'initial render of inner'); + this.assertText('', '#middle-value', 'initial render of middle (observers do not run during init)'); run(() => outer.set('value', 2)); - equal(this.textValue('#inner-value'), '2', 'second render of inner'); - equal(this.textValue('#middle-value'), '2', 'second render of middle'); + this.assertText('2', '#inner-value', 'second render of inner'); + this.assertText('2', '#middle-value', 'second render of middle'); run(() => outer.set('value', 3)); - equal(this.textValue('#inner-value'), '3', 'third render of inner'); - equal(this.textValue('#middle-value'), '3', 'third render of middle'); + this.assertText('3', '#inner-value', 'third render of inner'); + this.assertText('3', '#middle-value', 'third render of middle'); } ['@test non-block with each rendering child components']() { @@ -770,13 +770,13 @@ moduleFor('component - invocation', class extends RenderingTest { items: items }); - equal(this.textValue(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.]'); + this.assertText('In layout. [Child: Tom.][Child: Dick.][Child: Harry.]'); run(() => { items.pushObject('James'); }); - equal(this.textValue(), 'In layout. [Child: Tom.][Child: Dick.][Child: Harry.][Child: James.]'); + this.assertText('In layout. [Child: Tom.][Child: Dick.][Child: Harry.][Child: James.]'); } ['@test specifying classNames results in correct class'](assert) {