-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(tabs): broadcast tab.shown/tab.hidden to only child scopes
Addresses #588
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.4
- v1.2.3
- v1.2.2
- v1.2.1
- v1.2.0
- v1.1.1
- v1.1.0
- v1.0.1
- v1.0.0
- v1.0.0-rc.5
- v1.0.0-rc.4
- v1.0.0-rc.3
- v1.0.0-rc.2
- v1.0.0-rc.1
- v1.0.0-rc.0
- v1.0.0-beta.14
- v1.0.0-beta.13
- v1.0.0-beta.12
- v1.0.0-beta.11
- v1.0.0-beta.10
- v1.0.0-beta.10-nightly-16570
- v1.0.0-beta.9
- v1.0.0-beta.8
- v1.0.0-beta.7
- v1.0.0-beta.6
- v1.0.0-beta.5
- v1.0.0-beta.5b
- v1.0.0-beta.4
- v1.0.0-beta.3
- v1.0.0-beta.2
- v1.0.0-beta.1
- v0.9.27
- v0.9.26
- v0.9.25
- testing
- 1.0.0
Showing
2 changed files
with
356 additions
and
272 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,236 +1,306 @@ | ||
describe('Tab Bar Controller', function() { | ||
var compile, element, scope, ctrl; | ||
|
||
describe('tabs', function() { | ||
beforeEach(module('ionic.ui.tabs')); | ||
|
||
beforeEach(inject(function($compile, $rootScope, $controller) { | ||
compile = $compile; | ||
scope = $rootScope; | ||
var e = compile('<tabs></tabs>')(scope); | ||
ctrl = e.scope().tabsController; | ||
})); | ||
describe('$ionicTabs controller', function() { | ||
|
||
it('Select item in controller works', function() { | ||
// Verify no items selected | ||
expect(ctrl.getSelectedControllerIndex()).toEqual(undefined); | ||
var ctrl, scope; | ||
beforeEach(inject(function($rootScope, $controller) { | ||
scope = $rootScope.$new(); | ||
ctrl = $controller('$ionicTabs', { | ||
$scope: scope | ||
}); | ||
})); | ||
|
||
// Try selecting beyond the bounds | ||
ctrl.selectController(1); | ||
expect(ctrl.getSelectedControllerIndex()).toEqual(undefined); | ||
it('select should change getSelectedControllerIndex', function() { | ||
// Verify no items selected | ||
expect(ctrl.getSelectedControllerIndex()).toBeUndefined(); | ||
expect(scope.selectedIndex).toBe(-1); | ||
|
||
// Add a controller | ||
ctrl.add({ | ||
title: 'Cats', | ||
icon: 'icon-kitty-kat' | ||
}); | ||
// Try selecting beyond the bounds | ||
ctrl.selectController(1); | ||
expect(ctrl.getSelectedControllerIndex()).toBeUndefined(); | ||
expect(scope.selectedIndex).toBe(-1); | ||
|
||
expect(ctrl.getSelectedControllerIndex()).toEqual(0); | ||
// Add a controller | ||
ctrl.add({ | ||
title: 'Cats', | ||
icon: 'icon-kitty-kat' | ||
}); | ||
|
||
ctrl.add({ | ||
title: 'Cats', | ||
icon: 'icon-kitty-kat' | ||
}); | ||
expect(ctrl.getSelectedControllerIndex()).toEqual(0); | ||
expect(scope.selectedIndex).toBe(0); | ||
|
||
expect(ctrl.getSelectedControllerIndex()).toEqual(0); | ||
ctrl.add({ | ||
title: 'Cats', | ||
icon: 'icon-kitty-kat' | ||
}); | ||
|
||
ctrl.select(1); | ||
expect(ctrl.getSelectedControllerIndex()).toEqual(0); | ||
expect(scope.selectedIndex).toBe(0); | ||
|
||
expect(ctrl.getSelectedControllerIndex()).toEqual(1); | ||
}); | ||
ctrl.select(1); | ||
|
||
it('Calls change callback', function() { | ||
scope.onControllerChanged = function(oldC, oldI, newC, newI) { | ||
}; | ||
|
||
// Add a controller | ||
ctrl.add({ | ||
title: 'Cats', | ||
icon: 'icon-kitty-kat' | ||
}); | ||
ctrl.add({ | ||
title: 'Dogs', | ||
icon: 'icon-rufus' | ||
expect(ctrl.getSelectedControllerIndex()).toEqual(1); | ||
expect(scope.selectedIndex).toBe(1); | ||
}); | ||
|
||
spyOn(ctrl, 'controllerChanged'); | ||
it('select should emit viewData if emit is passed in', function() { | ||
ctrl.add({ title: 'foo', icon: 'icon' }); | ||
ctrl.add({ title: 'bar', icon: 'icon2' }); | ||
|
||
expect(ctrl.getSelectedControllerIndex()).toEqual(0); | ||
ctrl.select(1); | ||
var viewData; | ||
spyOn(scope, '$emit').andCallFake(function(e, data) { | ||
viewData = data; | ||
}); | ||
|
||
expect(ctrl.controllerChanged).toHaveBeenCalled(); | ||
}); | ||
}); | ||
ctrl.select(0); | ||
expect(scope.$emit).not.toHaveBeenCalled(); | ||
|
||
describe('Tabs directive', function() { | ||
var compile, element, scope; | ||
ctrl.select(1, true); | ||
expect(scope.$emit).toHaveBeenCalledWith('viewState.changeHistory', jasmine.any(Object)); | ||
expect(viewData).toBeTruthy(); | ||
expect(viewData.type).toBe('tab'); | ||
expect(viewData.typeIndex).toBe(1); | ||
expect(viewData.title).toBe('bar'); | ||
}); | ||
it('select should go to root if emit is true and selecting same tab index', inject(function($ionicViewService) { | ||
ctrl.add({ title: 'foo', icon: 'icon' }); | ||
|
||
beforeEach(module('ionic.ui.tabs')); | ||
spyOn($ionicViewService, 'goToHistoryRoot'); | ||
spyOn($ionicViewService, 'getCurrentView').andCallFake(function() { | ||
return { historyId:'001' }; | ||
}); | ||
|
||
beforeEach(inject(function($compile, $rootScope) { | ||
compile = $compile; | ||
scope = $rootScope; | ||
})); | ||
expect(scope.selectedIndex).toBe(0); | ||
//Emit != true | ||
ctrl.select(0); | ||
expect($ionicViewService.goToHistoryRoot).not.toHaveBeenCalled(); | ||
|
||
it('Has tab class', function() { | ||
element = compile('<tabs></tabs>')(scope); | ||
scope.$digest(); | ||
expect(element.find('.tabs').hasClass('tabs')).toBe(true); | ||
}); | ||
ctrl.select(0, true); | ||
expect($ionicViewService.goToHistoryRoot).toHaveBeenCalledWith('001'); | ||
})); | ||
it('select should call change callback', function() { | ||
scope.onControllerChanged = function(oldC, oldI, newC, newI) { | ||
}; | ||
|
||
it('Has tab children', function() { | ||
element = compile('<tabs></tabs>')(scope); | ||
scope = element.scope(); | ||
scope.controllers = [ | ||
{ title: 'Home', icon: 'icon-home' }, | ||
{ title: 'Fun', icon: 'icon-fun' }, | ||
{ title: 'Beer', icon: 'icon-beer' }, | ||
]; | ||
scope.$digest(); | ||
expect(element.find('a').length).toBe(3); | ||
}); | ||
// Add a controller | ||
ctrl.add({ title: 'Cats', icon: 'icon-kitty-kat' }); | ||
ctrl.add({ title: 'Dogs', icon: 'icon-rufus' }); | ||
|
||
it('Has compiled children', function() { | ||
element = compile('<tabs>' + | ||
'<tab active="true" title="Item" icon="icon-default"></tab>' + | ||
'<tab active="true" title="Item" icon="icon-default"></tab>' + | ||
'</tabs>')(scope); | ||
scope.$digest(); | ||
expect(element.find('a').length).toBe(2); | ||
}); | ||
spyOn(ctrl, 'controllerChanged'); | ||
|
||
it('Sets style on child tabs', function() { | ||
element = compile('<tabs tabs-type="tabs-positive" tabs-style="tabs-icon-bottom">' + | ||
'<tab active="true" title="Item" icon="icon-default"></tab>' + | ||
'<tab active="true" title="Item" icon="icon-default"></tab>' + | ||
'</tabs>')(scope); | ||
scope.$digest(); | ||
var tabs = element[0].querySelector('.tabs'); | ||
expect(angular.element(tabs).hasClass('tabs-positive')).toEqual(true); | ||
expect(angular.element(tabs).hasClass('tabs-icon-bottom')).toEqual(true); | ||
}); | ||
expect(ctrl.getSelectedControllerIndex()).toEqual(0); | ||
ctrl.select(1); | ||
|
||
expect(ctrl.controllerChanged).toHaveBeenCalled(); | ||
}); | ||
it('select should change activeAnimation=animation', function() { | ||
// Add a controller | ||
ctrl.add({ title: 'Cats', icon: 'icon-kitty-kat' }); | ||
ctrl.add({ title: 'Dogs', icon: 'icon-rufus' }); | ||
|
||
expect(scope.activeAnimation).toBeUndefined(); | ||
scope.animation = 'superfast'; | ||
ctrl.select(1); | ||
expect(scope.activeAnimation).toBe('superfast'); | ||
|
||
scope.animation = 'woah'; | ||
ctrl.select(0); | ||
expect(scope.activeAnimation).toBe('woah'); | ||
}); | ||
|
||
it('Has nav-view', function() { | ||
element = compile('<tabs>' + | ||
'<tab active="true" title="Item 1" href="#/page1"><nav-view name="name1"></nav-view></tab>' + | ||
'<tab active="true" title="Item 2" href="/page2">content2</tab>' + | ||
'</tabs>')(scope); | ||
scope = element.scope(); | ||
scope.$digest(); | ||
expect(scope.tabCount).toEqual(2); | ||
expect(scope.selectedIndex).toEqual(0); | ||
expect(scope.controllers.length).toEqual(2); | ||
expect(scope.controllers[0].hasNavView).toEqual(true); | ||
expect(scope.controllers[0].navViewName).toEqual('name1'); | ||
expect(scope.controllers[0].url).toEqual('/page1'); | ||
expect(scope.controllers[1].hasNavView).toEqual(false); | ||
expect(scope.controllers[1].url).toEqual('/page2'); | ||
}); | ||
}); | ||
|
||
describe('Tab Item directive', function() { | ||
var compile, element, scope, ctrl; | ||
describe('tabs directive', function() { | ||
var compile, scope, element; | ||
beforeEach(inject(function($compile, $rootScope) { | ||
compile = $compile; | ||
scope = $rootScope; | ||
})); | ||
|
||
it('Has tab class', function() { | ||
var element = compile('<tabs></tabs>')(scope); | ||
scope.$digest(); | ||
expect(element.find('.tabs').hasClass('tabs')).toBe(true); | ||
}); | ||
|
||
beforeEach(module('ionic.ui.tabs')); | ||
it('Has tab children', function() { | ||
element = compile('<tabs></tabs>')(scope); | ||
scope = element.scope(); | ||
scope.controllers = [ | ||
{ title: 'Home', icon: 'icon-home' }, | ||
{ title: 'Fun', icon: 'icon-fun' }, | ||
{ title: 'Beer', icon: 'icon-beer' }, | ||
]; | ||
scope.$digest(); | ||
expect(element.find('a').length).toBe(3); | ||
}); | ||
|
||
beforeEach(inject(function($compile, $rootScope, $document, $controller) { | ||
compile = $compile; | ||
scope = $rootScope; | ||
it('Has compiled children', function() { | ||
element = compile('<tabs>' + | ||
'<tab active="true" title="Item" icon="icon-default"></tab>' + | ||
'<tab active="true" title="Item" icon="icon-default"></tab>' + | ||
'</tabs>')(scope); | ||
scope.$digest(); | ||
expect(element.find('a').length).toBe(2); | ||
}); | ||
|
||
scope.badgeValue = 3; | ||
scope.badgeStyle = 'badge-assertive'; | ||
element = compile('<tabs>' + | ||
'<tab title="Item" icon="icon-default" badge="badgeValue" badge-style="{{badgeStyle}}"></tab>' + | ||
it('Sets style on child tabs', function() { | ||
element = compile('<tabs tabs-type="tabs-positive" tabs-style="tabs-icon-bottom">' + | ||
'<tab active="true" title="Item" icon="icon-default"></tab>' + | ||
'<tab active="true" title="Item" icon="icon-default"></tab>' + | ||
'</tabs>')(scope); | ||
scope.$digest(); | ||
$document[0].body.appendChild(element[0]); | ||
})); | ||
|
||
it('Title works', function() { | ||
//The badge's text gets in the way of just doing .text() on the element itself, so exclude it | ||
var notBadge = angular.element(element[0].querySelectorAll('a >:not(.badge)')); | ||
expect(notBadge.text().trim()).toEqual('Item'); | ||
}); | ||
scope.$digest(); | ||
var tabs = element[0].querySelector('.tabs'); | ||
expect(angular.element(tabs).hasClass('tabs-positive')).toEqual(true); | ||
expect(angular.element(tabs).hasClass('tabs-icon-bottom')).toEqual(true); | ||
}); | ||
|
||
it('Default icon works', function() { | ||
scope.$digest(); | ||
var i = element[0].querySelectorAll('i')[1]; | ||
expect(angular.element(i).hasClass('icon-default')).toEqual(true); | ||
}); | ||
it('Has nav-view', function() { | ||
element = compile('<tabs>' + | ||
'<tab active="true" title="Item 1" href="#/page1"><nav-view name="name1"></nav-view></tab>' + | ||
'<tab active="true" title="Item 2" href="/page2">content2</tab>' + | ||
'</tabs>')(scope); | ||
scope = element.scope(); | ||
scope.$digest(); | ||
expect(scope.tabCount).toEqual(2); | ||
expect(scope.selectedIndex).toEqual(0); | ||
expect(scope.controllers.length).toEqual(2); | ||
expect(scope.controllers[0].hasNavView).toEqual(true); | ||
expect(scope.controllers[0].navViewName).toEqual('name1'); | ||
expect(scope.controllers[0].url).toEqual('/page1'); | ||
expect(scope.controllers[1].hasNavView).toEqual(false); | ||
expect(scope.controllers[1].url).toEqual('/page2'); | ||
}); | ||
|
||
it('Badge works', function() { | ||
scope.$digest(); | ||
var i = element[0].querySelector('.badge'); | ||
expect(i.innerHTML).toEqual('3'); | ||
expect(i.className).toMatch('badge-assertive'); | ||
}); | ||
|
||
it('Badge updates', function() { | ||
scope.badgeValue = 10; | ||
scope.$digest(); | ||
var i = element[0].querySelectorAll('i')[0]; | ||
expect(i.innerHTML).toEqual('10'); | ||
}); | ||
describe('tab-item Directive', function() { | ||
|
||
var compile, element, scope, ctrl; | ||
beforeEach(inject(function($compile, $rootScope, $document, $controller) { | ||
compile = $compile; | ||
scope = $rootScope.$new(); | ||
|
||
scope.badgeValue = 3; | ||
scope.badgeStyleValue = 'badge-assertive'; | ||
element = compile('<tabs>' + | ||
'<tab title="Item" icon="icon-default" badge="badgeValue" badge-style="{{badgeStyleValue}}"></tab>' + | ||
'</tabs>')(scope); | ||
scope.$digest(); | ||
$document[0].body.appendChild(element[0]); | ||
})); | ||
|
||
it('Title works', function() { | ||
//The badge's text gets in the way of just doing .text() on the element itself, so exclude it | ||
var notBadge = angular.element(element[0].querySelectorAll('a >:not(.badge)')); | ||
expect(notBadge.text().trim()).toEqual('Item'); | ||
}); | ||
|
||
it('Click sets correct tab index', function() { | ||
var a = element.find('a:eq(0)'); | ||
var itemScope = a.isolateScope(); | ||
//spyOn(a, 'click'); | ||
spyOn(itemScope, 'selectTab'); | ||
a.click(); | ||
expect(itemScope.selectTab).toHaveBeenCalled(); | ||
}); | ||
}); | ||
it('Default icon works', function() { | ||
scope.$digest(); | ||
var i = element[0].querySelectorAll('i')[1]; | ||
expect(angular.element(i).hasClass('icon-default')).toEqual(true); | ||
}); | ||
|
||
describe('Tab Controller Item directive', function() { | ||
var compile, element, scope, ctrl; | ||
it('Badge works', function() { | ||
scope.$digest(); | ||
var i = element[0].querySelector('.badge'); | ||
expect(i.innerHTML).toEqual('3'); | ||
expect(i.className).toMatch('badge-assertive'); | ||
scope.$apply("badgeStyleValue = 'badge-danger'"); | ||
expect(i.className).toMatch('badge-danger'); | ||
}); | ||
|
||
beforeEach(module('ionic.ui.tabs')); | ||
it('Badge updates', function() { | ||
scope.badgeValue = 10; | ||
scope.$digest(); | ||
var i = element[0].querySelectorAll('i')[0]; | ||
expect(i.innerHTML).toEqual('10'); | ||
}); | ||
|
||
beforeEach(inject(function($compile, $rootScope, $document, $controller) { | ||
compile = $compile; | ||
scope = $rootScope; | ||
|
||
scope.badgeValue = 3; | ||
scope.isActive = false; | ||
element = compile('<tabs class="tabs">' + | ||
'<tab-controller-item icon-title="Icon <b>title</b>" icon="icon-class" icon-on="icon-on-class" icon-off="icon-off-class" badge="badgeValue" badge-style="badgeStyle" active="isActive" index="0"></tab-controller-item>' + | ||
'</tabs>')(scope); | ||
scope.$digest(); | ||
$document[0].body.appendChild(element[0]); | ||
})); | ||
|
||
it('Icon title works as html', function() { | ||
expect(element.find('a').find('span').html()).toEqual('Icon <b>title</b>'); | ||
it('Click sets correct tab index', function() { | ||
var a = element.find('a:eq(0)'); | ||
var itemScope = a.isolateScope(); | ||
//spyOn(a, 'click'); | ||
spyOn(itemScope, 'selectTab'); | ||
a.click(); | ||
expect(itemScope.selectTab).toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
it('Icon classes works', function() { | ||
var title = ''; | ||
var elements = element[0].querySelectorAll('.icon-class'); | ||
expect(elements.length).toEqual(1); | ||
var elements = element[0].querySelectorAll('.icon-off-class'); | ||
expect(elements.length).toEqual(1); | ||
describe('tab directive', function() { | ||
var scope, tab; | ||
beforeEach(inject(function($compile, $rootScope, $controller) { | ||
var tabsScope = $rootScope.$new(); | ||
//Setup a fake tabs controller for our tab to use so we dont have to have a parent tabs directive (isolated test) | ||
var ctrl = $controller('$ionicTabs', { | ||
$scope: tabsScope | ||
}); | ||
|
||
//Create an outer div that has a tabsController on it so tab thinks it's in a <tabs> | ||
var element = angular.element('<div><tab><div class="my-content"></div></tab></div>'); | ||
element.data('$tabsController', ctrl); | ||
$compile(element)(tabsScope) | ||
tabsScope.$apply(); | ||
|
||
tab = element.find('tab'); | ||
scope = tab.scope(); | ||
})); | ||
}); | ||
|
||
it('Active switch works', function() { | ||
var elements = element[0].querySelectorAll('.icon-on-class'); | ||
expect(elements.length).toEqual(0); | ||
describe('tab-controller-item Directive', function() { | ||
|
||
scope.isActive = true; | ||
scope.$digest(); | ||
var compile, element, scope, ctrl; | ||
beforeEach(inject(function($compile, $rootScope, $document, $controller) { | ||
compile = $compile; | ||
scope = $rootScope; | ||
|
||
var elements = element[0].querySelectorAll('.icon-on-class'); | ||
expect(elements.length).toEqual(1); | ||
}); | ||
scope.badgeValue = 3; | ||
scope.isActive = false; | ||
element = compile('<tabs class="tabs">' + | ||
'<tab-controller-item icon-title="Icon <b>title</b>" icon="icon-class" icon-on="icon-on-class" icon-off="icon-off-class" badge="badgeValue" badge-style="badgeStyle" active="isActive" index="0"></tab-controller-item>' + | ||
'</tabs>')(scope); | ||
scope.$digest(); | ||
$document[0].body.appendChild(element[0]); | ||
})); | ||
|
||
it('Badge updates', function() { | ||
scope.badgeValue = 10; | ||
scope.badgeStyle = 'badge-assertive'; | ||
scope.$digest(); | ||
var i = element[0].querySelector('.badge'); | ||
expect(i.innerHTML).toEqual('10'); | ||
expect(i.className).toMatch('badge-assertive'); | ||
scope.$apply('badgeStyle = "badge-super"'); | ||
expect(i.className).toMatch('badge-super'); | ||
}); | ||
it('Icon title works as html', function() { | ||
expect(element.find('a').find('span').html()).toEqual('Icon <b>title</b>'); | ||
}); | ||
|
||
it('Icon classes works', function() { | ||
var title = ''; | ||
var elements = element[0].querySelectorAll('.icon-class'); | ||
expect(elements.length).toEqual(1); | ||
var elements = element[0].querySelectorAll('.icon-off-class'); | ||
expect(elements.length).toEqual(1); | ||
}); | ||
|
||
it('Active switch works', function() { | ||
var elements = element[0].querySelectorAll('.icon-on-class'); | ||
expect(elements.length).toEqual(0); | ||
|
||
scope.isActive = true; | ||
scope.$digest(); | ||
|
||
var elements = element[0].querySelectorAll('.icon-on-class'); | ||
expect(elements.length).toEqual(1); | ||
}); | ||
|
||
it('Badge updates', function() { | ||
scope.badgeValue = 10; | ||
scope.badgeStyle = 'badge-assertive'; | ||
scope.$digest(); | ||
var i = element[0].querySelector('.badge'); | ||
expect(i.innerHTML).toEqual('10'); | ||
expect(i.className).toMatch('badge-assertive'); | ||
scope.$apply('badgeStyle = "badge-super"'); | ||
expect(i.className).toMatch('badge-super'); | ||
}); | ||
|
||
|
||
}); | ||
}); | ||
|
||
|