Skip to content

Commit

Permalink
test(collectionRepeatManager): finish testing .render()
Browse files Browse the repository at this point in the history
  • Loading branch information
ajoslin committed May 5, 2014
1 parent 958b23c commit 74891ac
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 18 deletions.
4 changes: 2 additions & 2 deletions demos/collection-repeat/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

<title>Collection-Repeat: Early Preview</title>

<link href="../../dist/css/ionic.css" rel="stylesheet">
<script src="../../dist/js/ionic.bundle.js"></script>
<link href="http://code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="http://code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
<link href="style.css" rel="stylesheet">
<script src="script.js"></script>
<script src="contacts.js"></script>
Expand Down
1 change: 1 addition & 0 deletions js/angular/service/collectionRepeatDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ function($cacheFactory, $parse) {
this.transcludeParent[0].appendChild(item.element[0]);
}
reconnectScope(item.scope);
!item.scope.$$phase && item.scope.$digest();
},
getLength: function() {
return this.data && this.data.length || 0;
Expand Down
5 changes: 1 addition & 4 deletions js/angular/service/collectionRepeatManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ function($rootScope, $timeout) {
this.renderItem(i, rect.primaryPos - startPos, rect.secondaryPos);
i++;
}
var bufferEndIndex = i -1;
var bufferEndIndex = i - 1;

for (i in this.renderedItems) {
if (i < bufferStartIndex || i > bufferEndIndex) {
Expand All @@ -207,9 +207,6 @@ function($rootScope, $timeout) {
primaryPos, secondaryPos, secondaryPos
);
this.renderedItems[dataIndex] = item;
if (item.scope && !item.scope.$$phase) {
item.scope.$digest();
}
} else {
delete this.renderedItems[dataIndex];
}
Expand Down
Empty file.
20 changes: 12 additions & 8 deletions test/unit/angular/service/collectionDataSource.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('$collectionDataSource service', function() {

it('should be $cacheFactory', function() {
var cache = {};
module('ionic', function($provide) {
module('ionic', function($provide) {
$provide.value('$cacheFactory', function() { return cache; });
});
var source = setup();
Expand All @@ -89,7 +89,7 @@ describe('$collectionDataSource service', function() {
source.itemCache.remove('a');
expect(source.itemCache.keys()).toEqual(['b']);
});

});

it('.destroy() should cleanup dimensions & cache', function() {
Expand Down Expand Up @@ -210,24 +210,26 @@ describe('$collectionDataSource service', function() {
});

describe('.attachItem()', function() {
it('should add element if it has no parent', function() {
it('should add element if it has no parent and digest', inject(function($rootScope) {
var source = setup({
transcludeParent: angular.element('<div>')
});
var element = angular.element('<div>');
spyOn(window, 'reconnectScope');
var item = {
element: element,
scope: {}
scope: $rootScope.$new()
};

spyOn(item.scope, '$digest');
spyOn(source.transcludeParent[0], 'appendChild');
source.attachItem(item);
expect(source.transcludeParent[0].appendChild).toHaveBeenCalledWith(element[0]);
expect(reconnectScope).toHaveBeenCalledWith(item.scope);
});
expect(item.scope.$digest).toHaveBeenCalled();
}));

it('should not append element if it has a parent already', function() {
it('should not append element if it has a parent already', inject(function($rootScope) {
var element = angular.element('<div>');
var source = setup({
transcludeParent: angular.element('<div>')
Expand All @@ -236,13 +238,15 @@ describe('$collectionDataSource service', function() {
spyOn(window, 'reconnectScope');
var item = {
element: element,
scope: {}
scope: $rootScope.$new()
};
spyOn(item.scope, '$digest');
source.attachItem(item);
spyOn(source.transcludeParent[0], 'appendChild');
expect(source.transcludeParent[0].appendChild).not.toHaveBeenCalled();
expect(reconnectScope).toHaveBeenCalledWith(item.scope);
});
expect(item.scope.$digest).toHaveBeenCalled();
}));
});

describe('.getLength()', function() {
Expand Down
87 changes: 83 additions & 4 deletions test/unit/angular/service/collectionRepeatManager.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ describe('collectionRepeatManager service', function() {
{ width: 100, height: 40 },
{ width: 100, height: 50 }
];
manager.secondaryScrollSize = function() {
manager.secondaryScrollSize = function() {
return 100;
};
var result = manager.calculateDimensions();
Expand Down Expand Up @@ -271,7 +271,7 @@ describe('collectionRepeatManager service', function() {
it('should work with data', function() {
var manager = setup();
spyOn(manager, 'calculateDimensions').andReturn([{
primaryPos: 100, primarySize: 30
primaryPos: 100, primarySize: 30
}]);
manager.resize();
expect(manager.viewportSize).toBe(130);
Expand Down Expand Up @@ -438,8 +438,87 @@ describe('collectionRepeatManager service', function() {
expect(manager.removeItem).toHaveBeenCalledWith('b');
});

//TODO test .render() logic

function mockRendering(options) {
var manager = setup({}, {
keyExpr: 'item',
listExpr: 'items',
heightGetter: function() {
return options.itemHeight;
},
widthGetter: function() {
return options.itemWidth;
}
});
spyOn(manager, 'scrollSize').andReturn(options.scrollHeight);
spyOn(manager, 'secondaryScrollSize').andReturn(options.scrollWidth);
spyOn(manager, 'renderItem').andCallFake(function(i) {
manager.renderedItems[i] = true;
});
spyOn(manager, 'removeItem').andCallFake(function(i) {
delete manager.renderedItems[i];
});
var data = [];
for (var i = 0; i < 100; i++) {
data.push(i);
}
manager.dataSource.setData(data);
return manager;
}

it('should render the first items that fit on screen', function() {
var manager = mockRendering({
itemWidth: 3,
itemHeight: 20,
scrollWidth: 10,
scrollHeight: 100
});
manager.resize(); //triggers render

//it should render (items that fit * items per row) with one extra row at end
expect(Object.keys(manager.renderedItems).length).toBe(18);
for (var i = 0; i < 18; i++) {
expect(manager.renderedItems[i]).toBe(true);
}
expect(manager.renderedItems[18]).toBeUndefined();
});

it('should render items in the middle of the screen', function() {
var manager = mockRendering({
itemWidth: 3,
itemHeight: 20,
scrollWidth: 10,
scrollHeight: 100
});
spyOn(manager, 'scrollValue').andReturn(111);
manager.resize();
var startIndex = 17;
var bufferStartIndex = 14; //one row of buffer before the start
var bufferEndIndex = 35; //start + 17 + 6

expect(Object.keys(manager.renderedItems).length).toBe(22);
for (var i = bufferStartIndex; i <= bufferEndIndex; i++) {
expect(manager.renderedItems[i]).toBe(true);
}
expect(manager.renderedItems[bufferStartIndex - 1]).toBeUndefined();
expect(manager.renderedItems[bufferEndIndex + 1]).toBeUndefined();
});

it('should remove items outside the range', function() {
var manager = mockRendering({
itemWidth: 3,
itemHeight: 20,
scrollWidth: 10,
scrollHeight: 100
});
manager.resize();
manager.removeItem.reset();
manager.renderedItems = { 17: true, 18: true, 19: true };
//resize() re-renders everything, need to just do a normal rerender
manager.render();
expect(manager.removeItem.callCount).toBe(2);
expect(manager.removeItem).toHaveBeenCalledWith('18');
expect(manager.removeItem).toHaveBeenCalledWith('19');
});
});

describe('.renderItem()', function() {
Expand Down

0 comments on commit 74891ac

Please sign in to comment.