diff --git a/packages/ember-glimmer/tests/integration/components/curly-components-test.js b/packages/ember-glimmer/tests/integration/components/curly-components-test.js index 66b0d32ffef..79f1c382a68 100644 --- a/packages/ember-glimmer/tests/integration/components/curly-components-test.js +++ b/packages/ember-glimmer/tests/integration/components/curly-components-test.js @@ -6,7 +6,7 @@ import { Component, compile, htmlSafe } from '../../utils/helpers'; import { A as emberA } from 'ember-runtime/system/native_array'; import { strip } from '../../utils/abstract-test-case'; import { moduleFor, RenderingTest } from '../../utils/test-case'; -import { classes, equalTokens, equalsElement } from '../../utils/test-helpers'; +import { classes, equalTokens, equalsElement, styles } from '../../utils/test-helpers'; import { computed } from 'ember-metal/computed'; import run from 'ember-metal/run_loop'; import inject from 'ember-runtime/inject'; @@ -2391,4 +2391,71 @@ moduleFor('Components test: curly components', class extends RenderingTest { this.render('{{foo-bar}}'); }, /You must call `this._super\(...arguments\);` when implementing `init` in a component. Please update .* to call `this._super` from `init`/); } + + ['@htmlbars should toggle visibility with isVisible'](assert) { + let assertStyle = (expected) => { + let matcher = styles(expected); + let actual = this.firstChild.getAttribute('style'); + + assert.pushResult({ + result: matcher.match(actual), + message: matcher.message(), + actual, + expected + }); + }; + + this.registerComponent('foo-bar', { + template: `

foo

` + }); + + this.render(`{{foo-bar id="foo-bar" isVisible=visible}}`, { + visible: false + }); + + assertStyle('display: none;'); + + this.assertStableRerender(); + + this.runTask(() => { set(this.context, 'visible', true); }); + assertStyle(''); + + this.runTask(() => { set(this.context, 'visible', false); }); + assertStyle('display: none;'); + } + + ['@htmlbars isVisible does not overwrite component style'](assert) { + this.registerComponent('foo-bar', { + ComponentClass: Component.extend({ + attributeBindings: ['style'], + style: htmlSafe('color: blue;') + }), + + template: `

foo

` + }); + + this.render(`{{foo-bar id="foo-bar" isVisible=visible}}`, { + visible: false + }); + + this.assertComponentElement(this.firstChild, { + tagName: 'div', + attrs: { id: 'foo-bar', style: styles('color: blue; display: none;') } + }); + + this.assertStableRerender(); + + this.runTask(() => { set(this.context, 'visible', true); }); + + this.assertComponentElement(this.firstChild, { + tagName: 'div', + attrs: { id: 'foo-bar', style: styles('color: blue;') } + }); + + this.runTask(() => { set(this.context, 'visible', false); }); + this.assertComponentElement(this.firstChild, { + tagName: 'div', + attrs: { id: 'foo-bar', style: styles('color: blue; display: none;') } + }); + } }); diff --git a/packages/ember-glimmer/tests/utils/test-helpers.js b/packages/ember-glimmer/tests/utils/test-helpers.js index 4f747b0a0f1..451daa1196b 100644 --- a/packages/ember-glimmer/tests/utils/test-helpers.js +++ b/packages/ember-glimmer/tests/utils/test-helpers.js @@ -76,7 +76,7 @@ export function equalTokens(actualContainer, expectedHTML, message = null) { const MATCHER_BRAND = '3d4ef194-13be-4ccf-8dc7-862eea02c93e'; function isMatcher(obj) { - return typeof obj === 'object' && MATCHER_BRAND in obj; + return typeof obj === 'object' && obj !== null && MATCHER_BRAND in obj; } const HTMLElement = window.HTMLElement; @@ -88,9 +88,10 @@ export function equalsElement(element, tagName, attributes, content) { let expectedCount = 0; for (let name in attributes) { - expectedCount++; - let expected = attributes[name]; + if (expected !== null) { + expectedCount++; + } let matcher = isMatcher(expected) ? expected : equalsAttr(expected); @@ -186,8 +187,12 @@ export function styles(expected) { [MATCHER_BRAND]: true, match(actual) { + // coerce `null` or `undefined` to an empty string + // needed for matching empty styles on IE9 - IE11 + actual = actual || ''; actual = actual.trim(); - return actual && ( + + return ( expected.split(';').map(s => s.trim()).filter(s => s).sort().join('; ') === actual.split(';').map(s => s.trim()).filter(s => s).sort().join('; ') ); diff --git a/packages/ember-views/tests/views/view/is_visible_test.js b/packages/ember-views/tests/views/view/is_visible_test.js deleted file mode 100644 index d8912c7f75a..00000000000 --- a/packages/ember-views/tests/views/view/is_visible_test.js +++ /dev/null @@ -1,102 +0,0 @@ -import { getDebugFunction, setDebugFunction } from 'ember-metal/debug'; -import { get } from 'ember-metal/property_get'; -import { set } from 'ember-metal/property_set'; -import run from 'ember-metal/run_loop'; -import { computed } from 'ember-metal/computed'; -import EmberView from 'ember-views/views/view'; - -let view; -let warnings, originalWarn; - -QUnit.module('EmberView#isVisible', { - setup() { - warnings = []; - originalWarn = getDebugFunction('warn'); - setDebugFunction('warn', function(message, test) { - if (!test) { - warnings.push(message); - } - }); - }, - - teardown() { - if (view) { - run(() => view.destroy()); - } - setDebugFunction('warn', originalWarn); - } -}); - -QUnit.test('should hide views when isVisible is false', function() { - view = EmberView.create({ - isVisible: false - }); - - run(() => view.append()); - - ok(view.$().is(':hidden'), 'the view is hidden'); - - run(() => set(view, 'isVisible', true)); - - ok(view.$().is(':visible'), 'the view is visible'); - run(() => view.destroyElement()); - - deepEqual(warnings, [], 'no warnings were triggered'); -}); - -QUnit.test('should hide element if isVisible is false before element is created', function() { - view = EmberView.create({ - isVisible: false - }); - - ok(!get(view, 'isVisible'), 'precond - view is not visible'); - - set(view, 'template', () => 'foo'); - - run(() => view.append()); - - ok(view.$().is(':hidden'), 'should be hidden'); - - run(() => view.destroyElement()); - - run(() => set(view, 'isVisible', true)); - - run(() => view.append()); - - ok(view.$().is(':visible'), 'view should be visible'); - - run(() => view.destroyElement()); - - deepEqual(warnings, [], 'no warnings were triggered'); -}); - -QUnit.test('should hide views when isVisible is a CP returning false', function() { - view = EmberView.extend({ - isVisible: computed(function() { - return false; - }) - }).create(); - - run(() => view.append()); - - ok(view.$().is(':hidden'), 'the view is hidden'); - - run(() => set(view, 'isVisible', true)); - - ok(view.$().is(':visible'), 'the view is visible'); - run(() => view.destroyElement()); - - deepEqual(warnings, [], 'no warnings were triggered'); -}); - -QUnit.test('doesn\'t overwrite existing style attribute bindings', function() { - view = EmberView.create({ - isVisible: false, - attributeBindings: ['style'], - style: 'color: blue;' - }); - - run(() => view.append()); - - equal(view.$().attr('style'), 'color: blue; display: none;', 'has concatenated style attribute'); -});