QUnit.test('The ArrayProxy doesn\'t explode when assigned a destroyed object', function() { let proxy1 = ArrayProxy.create(); let proxy2 = ArrayProxy.create(); run(() => proxy1.destroy()); set(proxy2, 'content', proxy1); ok(true, 'No exception was raised'); });
run(function() { TemplateTests.contentController = ArrayProxy.create({ content: emberA(['foo', 'bar']) }); var InnerList = CollectionView.extend({ tagName: 'ul', contentBinding: 'parentView.innerListContent' }); var OuterListItem = EmberView.extend({ innerListView: InnerList, template: compile('{{#collection view.innerListView class="inner"}}{{content}}{{/collection}}{{content}}'), innerListContent: computed(function() { return emberA([1, 2, 3]); }) }); var OuterList = CollectionView.extend({ tagName: 'ul', contentBinding: 'TemplateTests.contentController', itemViewClass: OuterListItem }); view = EmberView.create({ outerListView: OuterList, template: compile('{{collection view.outerListView class="outer"}}') }); });
QUnit.test('empty views should be removed when content is added to the collection (regression, ht: msofaer)', function() { var EmptyView = EmberView.extend({ template : compile('<td>No Rows Yet</td>') }); var ListView = CollectionView.extend({ emptyView: EmptyView }); var listController = ArrayProxy.create({ content : emberA() }); view = EmberView.create({ _viewRegistry: {}, listView: ListView, listController: listController, template: compile('{{#collection view.listView content=view.listController tagName="table"}} <td>{{view.content.title}}</td> {{/collection}}') }); runAppend(view); equal(view.$('tr').length, 1, 'Make sure the empty view is there (regression)'); run(function() { listController.pushObject({ title : 'Go Away, Placeholder Row!' }); }); equal(view.$('tr').length, 1, 'has one row'); equal(view.$('tr:nth-child(1) td').text(), 'Go Away, Placeholder Row!', 'The content is the updated data.'); });
test("upon content change with Array-like content, the DOM should reflect the selection", function() { var tom = {id: 4, name: 'Tom'}, sylvain = {id: 5, name: 'Sylvain'}; var proxy = ArrayProxy.create({ content: Ember.A(), selectedOption: sylvain }); view = EmberView.create({ proxy: proxy, template: Ember.Handlebars.compile( '{{view Ember.Select viewName="select"' + ' contentBinding="view.proxy"' + ' selectionBinding="view.proxy.selectedOption"}}' ) }); run(function() { view.appendTo('#qunit-fixture'); }); var select = view.get('select'), selectEl = select.$()[0]; equal(selectEl.selectedIndex, -1, "Precond: The DOM reflects the lack of selection"); run(function() { proxy.set('content', Ember.A([tom, sylvain])); }); equal(select.get('selection'), sylvain, "Selection was properly set after content change"); equal(selectEl.selectedIndex, 1, "The DOM reflects the correct selection"); });
test("a array_proxy that backs an sorted array_controller that backs a collection view functions properly", function() { var array = Ember.A([{ name: "Other Katz" }]); var arrayProxy = ArrayProxy.create({content: array}); var sortedController = ArrayController.create({ content: arrayProxy, sortProperties: ['name'] }); var container = CollectionView.create({ content: sortedController }); run(function() { container.appendTo('#qunit-fixture'); }); run(function() { arrayProxy.addObjects([{ name: "Scumbag Demon" }, { name: "Lord British" }]); }); equal(container.get('content.length'), 3, 'ArrayController should have 3 entries'); equal(container.get('content.content.length'), 3, 'RecordArray should have 3 entries'); equal(container.get('childViews.length'), 3, 'CollectionView should have 3 entries'); run(function() { container.destroy(); }); });
QUnit.test("upon content change with Array-like content, the DOM should reflect the selection", function() { var tom = { id: 4, name: 'Tom' }; var sylvain = { id: 5, name: 'Sylvain' }; var proxy = ArrayProxy.create({ content: Ember.A(), selectedOption: sylvain }); view = EmberView.create({ proxy: proxy, selectView: SelectView, template: compile( '{{view view.selectView viewName="select"' + ' content=view.proxy' + ' selection=view.proxy.selectedOption}}' ) }); runAppend(view); var select = view.get('select'); var selectEl = select.$()[0]; equal(selectEl.selectedIndex, -1, "Precond: The DOM reflects the lack of selection"); run(function() { proxy.set('content', Ember.A([tom, sylvain])); }); equal(select.get('selection'), sylvain, "Selection was properly set after content change"); equal(selectEl.selectedIndex, 1, "The DOM reflects the correct selection"); });
QUnit.test('should update length for null content', function() { let proxy = ArrayProxy.create({ content: emberA([1, 2, 3]) }); equal(proxy.get('length'), 3, 'precond - length is 3'); proxy.set('content', null); equal(proxy.get('length'), 0, 'length updates'); });
QUnit.test('itemViewClass works in the #collection via container', function() { owner.register('view:example-item', EmberView.extend({ isAlsoCustom: true })); view = EmberView.create({ [OWNER]: owner, exampleCollectionView: CollectionView.extend(), exampleController: ArrayProxy.create({ content: emberA(['alpha']) }), template: compile('{{#collection view.exampleCollectionView content=view.exampleController itemViewClass="example-item"}}beta{{/collection}}') }); runAppend(view); ok(firstGrandchild(view).isAlsoCustom, 'uses the example view class specified in the #collection helper'); });
QUnit.test('itemViewClass works in the #collection helper with a property', function() { var ExampleItemView = EmberView.extend({ isAlsoCustom: true }); var ExampleCollectionView = CollectionView; view = EmberView.create({ possibleItemView: ExampleItemView, exampleCollectionView: ExampleCollectionView, exampleController: ArrayProxy.create({ content: emberA(['alpha']) }), template: compile('{{#collection view.exampleCollectionView content=view.exampleController itemViewClass=view.possibleItemView}}beta{{/collection}}') }); runAppend(view); ok(firstGrandchild(view).isAlsoCustom, 'uses the example view class specified in the #collection helper'); });
QUnit.test('Ember.isArray', function() { var numarray = [1,2,3]; var number = 23; var strarray = ['Hello', 'Hi']; var string = 'Hello'; var object = {}; var length = { length: 12 }; var fn = function() {}; var arrayProxy = ArrayProxy.create({ content: Ember.A() }); equal(isArray(numarray), true, '[1,2,3]'); equal(isArray(number), false, '23'); equal(isArray(strarray), true, '["Hello", "Hi"]'); equal(isArray(string), false, '"Hello"'); equal(isArray(object), false, '{}'); equal(isArray(length), true, '{ length: 12 }'); equal(isArray(global), false, 'global'); equal(isArray(fn), false, 'function() {}'); equal(isArray(arrayProxy), true, '[]'); });
test("itemViewClass works in the #collection helper with a global (DEPRECATED)", function() { TemplateTests.ExampleItemView = EmberView.extend({ isAlsoCustom: true }); view = EmberView.create({ exampleController: ArrayProxy.create({ content: A(['alpha']) }), template: compile('{{#collection content=view.exampleController itemViewClass=TemplateTests.ExampleItemView}}beta{{/collection}}') }); var deprecation = /Resolved the view "TemplateTests.ExampleItemView" on the global context/; if (Ember.FEATURES.isEnabled('ember-htmlbars')) { deprecation = /Global lookup of TemplateTests.ExampleItemView from a Handlebars template is deprecated/; } expectDeprecation(function(){ run(view, 'append'); }, deprecation); ok(firstGrandchild(view).isAlsoCustom, "uses the example view class specified in the #collection helper"); });
test("empty views should be removed when content is added to the collection (regression, ht: msofaer)", function() { var App; run(function() { lookup.App = App = Namespace.create(); }); App.EmptyView = EmberView.extend({ template : EmberHandlebars.compile("<td>No Rows Yet</td>") }); App.ListView = CollectionView.extend({ emptyView: App.EmptyView }); App.listController = ArrayProxy.create({ content : A() }); view = EmberView.create({ template: EmberHandlebars.compile('{{#collection App.ListView contentBinding="App.listController" tagName="table"}} <td>{{view.content.title}}</td> {{/collection}}') }); run(function() { view.appendTo('#qunit-fixture'); }); equal(view.$('tr').length, 1, 'Make sure the empty view is there (regression)'); run(function() { App.listController.pushObject({title : "Go Away, Placeholder Row!"}); }); equal(view.$('tr').length, 1, 'has one row'); equal(view.$('tr:nth-child(1) td').text(), 'Go Away, Placeholder Row!', 'The content is the updated data.'); run(function() { App.destroy(); }); });
QUnit.test("The `unless` helper updates if an array-like object is empty or not", function() { view = EmberView.create({ array: ArrayProxy.create({ content: Ember.A([]) }), template: compile('{{#unless view.array}}Yep{{/unless}}') }); runAppend(view); equal(view.$().text(), 'Yep'); run(function() { view.get('array').pushObject(1); }); equal(view.$().text(), ''); run(function() { view.get('array').removeObject(1); }); equal(view.$().text(), 'Yep'); });
QUnit.test('The `if` helper updates if an array-like object is empty or not', function() { testIfArray(ArrayProxy.create({ content: emberA() })); });
run(function() { array = ArrayProxy.create({ content: emberA([1, 2, 4, 5]) }); });
test("Ember.isArray" ,function() { var arrayProxy = ArrayProxy.create({ content: Ember.A() }); equal(isArray(arrayProxy), true, "[]"); });
this.runTask(() => { set(this.context, 'cond1', ArrayProxy.create({ content: emberA(['hello']) })); set(this.context, 'cond2', ArrayProxy.create({ content: emberA() })); });
get(this.context, 'cond2').pushObjects([1]); }); this.assertText('T1T2'); this.runTask(() => { set(this.context, 'cond1', emberA(['hello'])); set(this.context, 'cond2', emberA()); }); this.assertText('T1F2'); }, ['@test it considers array proxies without content falsy']() { this.renderValues( ArrayProxy.create({ content: emberA(['hello']) }), ArrayProxy.create({ content: null }) ); this.assertText('T1F2'); this.runTask(() => this.rerender()); this.assertText('T1F2'); this.runTask(() => { set(this.context, 'cond1.content', null); set(this.context, 'cond2.content', null); }); this.assertText('F1F2');
QUnit.test('Ember.isEmpty', function() { let arrayProxy = ArrayProxy.create({ content: emberA() }); equal(true, isEmpty(arrayProxy), 'for an ArrayProxy that has empty content'); });
QUnit.test(`regression test for https://github.com/emberjs/ember.js/issues/12475`, function() { let item1a = { id: 1 }; let item1b = { id: 2 }; let item1c = { id: 3 }; let content1 = A([item1a, item1b, item1c]); let proxy = ArrayProxy.create({ content: content1 }); let obj = { proxy }; defineProperty(obj, 'ids', computed('*****@*****.**', function() { return get(this, 'proxy').mapBy('id'); })); // These manually added observers are to simulate the observers added by the // rendering process in a template like: // // {{#each items as |item|}} // {{item.id}} // {{/each}} addObserver(item1a, 'id', function() { }); addObserver(item1b, 'id', function() { }); addObserver(item1c, 'id', function() { }); // The EachProxy has not yet been consumed. Only the manually added // observers are watching. equal(watcherCount(item1a, 'id'), 1); equal(watcherCount(item1b, 'id'), 1); equal(watcherCount(item1c, 'id'), 1); // Consume the each proxy. This causes the EachProxy to add two observers // per item: one for "before" events and one for "after" events. deepEqual(get(obj, 'ids'), [1, 2, 3]); // For each item, the two each proxy observers and one manual added observer // are watching. equal(watcherCount(item1a, 'id'), 3); equal(watcherCount(item1b, 'id'), 3); equal(watcherCount(item1c, 'id'), 3); // This should be a no-op because observers do not fire if the value // 1. is an object and 2. is the same as the old value. proxy.set('content', content1); equal(watcherCount(item1a, 'id'), 3); equal(watcherCount(item1b, 'id'), 3); equal(watcherCount(item1c, 'id'), 3); // This is repeated to catch the regression. It should still be a no-op. proxy.set('content', content1); equal(watcherCount(item1a, 'id'), 3); equal(watcherCount(item1b, 'id'), 3); equal(watcherCount(item1c, 'id'), 3); // Set the content to a new array with completely different items and // repeat the process. let item2a = { id: 4 }; let item2b = { id: 5 }; let item2c = { id: 6 }; let content2 = A([item2a, item2b, item2c]); addObserver(item2a, 'id', function() { }); addObserver(item2b, 'id', function() { }); addObserver(item2c, 'id', function() { }); proxy.set('content', content2); deepEqual(get(obj, 'ids'), [4, 5, 6]); equal(watcherCount(item2a, 'id'), 3); equal(watcherCount(item2b, 'id'), 3); equal(watcherCount(item2c, 'id'), 3); // Ensure that the observers added by the EachProxy on all items in the // first content array have been torn down. equal(watcherCount(item1a, 'id'), 1); equal(watcherCount(item1b, 'id'), 1); equal(watcherCount(item1c, 'id'), 1); proxy.set('content', content2); equal(watcherCount(item2a, 'id'), 3); equal(watcherCount(item2b, 'id'), 3); equal(watcherCount(item2c, 'id'), 3); proxy.set('content', content2); equal(watcherCount(item2a, 'id'), 3); equal(watcherCount(item2b, 'id'), 3); equal(watcherCount(item2c, 'id'), 3); });
QUnit.test("The `if` helper updates if an array-like object is empty or not", function() { testIfArray(ArrayProxy.create({ content: Ember.A([]) })); });
import MutableArrayTests from 'ember-runtime/tests/suites/mutable_array'; import ArrayProxy from 'ember-runtime/system/array_proxy'; import { get } from 'ember-metal/property_get'; import { A as emberA } from 'ember-runtime/system/native_array'; MutableArrayTests.extend({ name: 'Ember.ArrayProxy', newObject(ary) { let ret = ary ? ary.slice() : this.newFixture(3); return ArrayProxy.create({ content: emberA(ret) }); }, mutate(obj) { obj.pushObject(get(obj, 'length') + 1); }, toArray(obj) { return obj.toArray ? obj.toArray() : obj.slice(); } }).run();