UNPKG

7.32 kBJavaScriptView Raw
1/*global document*/
2var test = require('tape');
3var AmpCollection = require('ampersand-collection');
4var AmpModel = require('ampersand-model');
5var AmpView = require('ampersand-view');
6var CollectionView = require('../ampersand-collection-view');
7
8
9// test data
10var data = [
11 {id: 1, name: 'mary'},
12 {id: 2, name: 'sue'},
13 {id: 3, name: 'dave'}
14];
15
16// item model
17var Person = AmpModel.extend({
18 props: {id: 'number', name: 'string'}
19});
20
21// collection for that model
22var Collection = AmpCollection.extend({
23 model: Person,
24 last: function () {
25 return this.models[this.models.length - 1];
26 },
27 first: function () {
28 return this.models[0];
29 }
30});
31
32var ItemView = AmpView.extend({
33 template: '<div></div>',
34 bindings: {
35 'model.name': ''
36 },
37 render: function () {
38 this.renderWithTemplate();
39 this.el.id = '_' + this.model.id;
40 return this;
41 }
42});
43
44var MainView = AmpView.extend({
45 initialize: function () {
46 this.el = document.createElement('div');
47 this.el.id = 'container';
48 this.collection = new Collection(data);
49 },
50 render: function (opts) {
51 this.el.innerHTML = '<ul></ul>';
52 this.renderCollection(this.collection, ItemView, this.get('ul'), opts);
53 return this;
54 }
55});
56
57function getRendered(view) {
58 return Array.prototype.slice.call(view.el.querySelectorAll('div'));
59}
60
61function numberRendered(view) {
62 return getRendered(view).length;
63}
64
65test('should render all when calling `render`', function (t) {
66 var coll = new Collection(data);
67 var div = document.createElement('div');
68 var cv = new CollectionView({
69 el: div,
70 collection: coll,
71 view: ItemView
72 });
73 t.equal(cv.el.innerHTML, '');
74 cv.render();
75 t.equal(cv.el.innerHTML, '<div id="_1">mary</div><div id="_2">sue</div><div id="_3">dave</div>');
76 t.end();
77});
78
79test('should call `remove` on view corresponding to removed model', function (t) {
80 var coll = new Collection(data);
81 var div = document.createElement('div');
82 var cv = new CollectionView({
83 el: div,
84 collection: coll,
85 view: ItemView
86 });
87 var count = 0;
88 cv.render();
89 t.equal(cv.views.length, 3);
90 var firstView = cv.views[0];
91 firstView.remove = function () {
92 count++;
93 };
94 coll.remove(coll.at(0));
95 t.equal(cv.views.length, 2);
96 t.equal(count, 1, 'remove should have been called once');
97 t.end();
98});
99
100test('adding to collection should work', function (t) {
101 var coll = new Collection(data);
102 var div = document.createElement('div');
103 var cv = new CollectionView({
104 el: div,
105 collection: coll,
106 view: ItemView
107 });
108 cv.render();
109 var firstView = cv.views[0];
110 var firstEl = firstView && firstView.el;
111
112 coll.add({name: 'henrik', id: 4});
113 t.equal(cv.views.length, 4);
114 t.equal(cv.el.innerHTML, '<div id="_1">mary</div><div id="_2">sue</div><div id="_3">dave</div><div id="_4">henrik</div>');
115 t.equal(cv.views[0], firstView);
116 t.equal(cv.views[0].el, firstEl);
117
118 t.end();
119});
120
121test('add', function (t) {
122 var coll = new Collection(data);
123 var div = document.createElement('div');
124 var view = new CollectionView({
125 el: div,
126 collection: coll,
127 view: ItemView
128 });
129 view.render();
130 view.collection.add({id: 6});
131 t.equal(numberRendered(view), view.collection.length);
132 t.end();
133});
134
135test('remove', function (t) {
136 var coll = new Collection(data);
137 var div = document.createElement('div');
138 var view = new CollectionView({
139 el: div,
140 collection: coll,
141 view: ItemView
142 });
143 view.render();
144 view.collection.remove(view.collection.models[view.collection.models.length - 1]);
145 t.equal(numberRendered(view), view.collection.length);
146 t.end();
147});
148
149test('reset', function (t) {
150 var coll = new Collection(data);
151 var div = document.createElement('div');
152 var view = new CollectionView({
153 el: div,
154 collection: coll,
155 view: ItemView
156 });
157 view.render();
158 view.collection.reset();
159 t.equal(numberRendered(view), view.collection.length);
160 t.equal(numberRendered(view), 0);
161 t.end();
162});
163
164test('sort', function (t) {
165 var coll = new Collection(data);
166 var div = document.createElement('div');
167 var view = new CollectionView({
168 el: div,
169 collection: coll,
170 view: ItemView
171 });
172 view.render();
173 view.collection.comparator = function (model) {
174 return model.get('name');
175 };
176 view.collection.sort();
177 t.equal(numberRendered(view), view.collection.length);
178 var domIds = [];
179 getRendered(view).forEach(function (el) {
180 domIds.push(Number(el.id.slice(1)));
181 });
182 t.deepEqual(domIds, [3, 1, 2]);
183 t.end();
184});
185
186test('animateRemove', function (t) {
187 var coll = new Collection(data);
188 var div = document.createElement('div');
189 var view = new CollectionView({
190 el: div,
191 collection: coll,
192 view: ItemView
193 });
194 view.render();
195 var prevAnimateRemove = ItemView.prototype.animateRemove;
196 ItemView.prototype.animateRemove = function () {
197 var self = this;
198 this.el.className = 'fadeOut';
199 setTimeout(function () {
200 self.remove();
201 }, 100);
202 t.ok('animateRemove called');
203 };
204 view.collection.remove(view.collection.last());
205 setTimeout(function () {
206 t.equal(numberRendered(view), view.collection.length);
207 // set it back
208 ItemView.prototype.animateRemove = prevAnimateRemove;
209 t.end();
210 }, 150);
211});
212
213test('filtered', function (t) {
214 var view = new MainView();
215 view.render({
216 filter: function (model) {
217 return model.get('name').length > 3;
218 }
219 });
220 t.equal(numberRendered(view), 2);
221 t.end();
222});
223
224test('reversed', function (t) {
225 var view = new MainView();
226 view.render({
227 reverse: true
228 });
229 var domIds = [];
230 getRendered(view).forEach(function (el) {
231 domIds.push(Number(el.id.slice(1)));
232 });
233 t.deepEqual(domIds, [3, 2, 1]);
234 t.end();
235});
236
237test('cleanup', function (t) {
238 var coll = new Collection(data);
239 var div = document.createElement('div');
240 var view = new CollectionView({
241 el: div,
242 collection: coll,
243 view: ItemView
244 });
245 view.render();
246 t.equal(numberRendered(view), view.collection.length);
247 var firstModel = view.collection.first();
248 var firstView = view.views[0];
249 firstView.listenTo(firstModel, 'change:something', function () {});
250 t.equal(view.collection.first()._events['change:something'].length, 1);
251 view.remove();
252 // when main view is removed so should registered event handler
253 // from subview
254 t.notOk(view.collection.first()._events['change:something']);
255 t.end();
256});
257
258test('child view can choose to insert self', function (t) {
259 var view = new MainView();
260 ItemView.prototype.insertSelf = true;
261 ItemView.prototype.render = function (extraInfo) {
262 t.ok(extraInfo.containerEl);
263 this.renderWithTemplate();
264 };
265
266 view.render();
267 t.equal(numberRendered(view), 0, 'Parent should not have rendered anything');
268 view.remove();
269 t.end();
270});
271