UNPKG

thalassa-aqueduct

Version:

Dynamic haproxy load balancer and configuration. Part of Thalassa

479 lines (403 loc) 15.3 kB
describe('tabs', function() { beforeEach(module('ui.bootstrap.tabs', 'template/tabs/tabset.html', 'template/tabs/tab.html')); var elm, scope; function titles() { return elm.find('ul.nav-tabs li'); } function contents() { return elm.find('div.tab-content div.tab-pane'); } function expectTitles(titlesArray) { var t = titles(); expect(t.length).toEqual(titlesArray.length); for (var i=0; i<t.length; i++) { expect(t.eq(i).text().trim()).toEqual(titlesArray[i]); } } function expectContents(contentsArray) { var c = contents(); expect(c.length).toEqual(contentsArray.length); for (var i=0; i<c.length; i++) { expect(c.eq(i).text().trim()).toEqual(contentsArray[i]); } } describe('basics', function() { beforeEach(inject(function($compile, $rootScope) { scope = $rootScope.$new(); scope.first = '1'; scope.second = '2'; scope.actives = {}; scope.selectFirst = jasmine.createSpy(); scope.selectSecond = jasmine.createSpy(); elm = $compile([ '<div>', ' <tabset>', ' <tab heading="First Tab {{first}}" active="actives.one" select="selectFirst()">', ' first content is {{first}}', ' </tab>', ' <tab active="actives.two" select="selectSecond()">', ' <tab-heading><b>Second</b> Tab {{second}}</tab-heading>', ' second content is {{second}}', ' </tab>', ' </tabs>', '</div>' ].join('\n'))(scope); scope.$apply(); return elm; })); it('should create clickable titles', function() { var t = titles(); expect(t.length).toBe(2); expect(t.find('a').eq(0).text()).toBe('First Tab 1'); //It should put the tab-heading element into the 'a' title expect(t.find('a').eq(1).children().is('tab-heading')).toBe(true); expect(t.find('a').eq(1).children().html()).toBe('<b>Second</b> Tab 2'); }); it('should bind tabs content and set first tab active', function() { expectContents(['first content is 1', 'second content is 2']); expect(titles().eq(0)).toHaveClass('active'); expect(titles().eq(1)).not.toHaveClass('active'); expect(scope.actives.one).toBe(true); expect(scope.actives.two).toBe(false); }); it('should change active on click', function() { titles().eq(1).find('a').click(); expect(contents().eq(1)).toHaveClass('active'); expect(titles().eq(0)).not.toHaveClass('active'); expect(titles().eq(1)).toHaveClass('active'); expect(scope.actives.one).toBe(false); expect(scope.actives.two).toBe(true); }); it('should call select callback on select', function() { titles().eq(1).find('a').click(); expect(scope.selectSecond).toHaveBeenCalled(); titles().eq(0).find('a').click(); expect(scope.selectFirst).toHaveBeenCalled(); }); }); describe('ng-repeat', function() { beforeEach(inject(function($compile, $rootScope) { scope = $rootScope.$new(); function makeTab() { return { active: false, select: jasmine.createSpy() }; } scope.tabs = [ makeTab(), makeTab(), makeTab(), makeTab() ]; elm = $compile([ '<tabset>', ' <tab ng-repeat="t in tabs" active="t.active" select="t.select()">', ' <tab-heading><b>heading</b> {{index}}</tab-heading>', ' content {{$index}}', ' </tab>', '</tabset>' ].join('\n'))(scope); scope.$apply(); })); function titles() { return elm.find('ul.nav-tabs li'); } function contents() { return elm.find('div.tab-content div.tab-pane'); } function expectTabActive(activeTab) { var _titles = titles(); angular.forEach(scope.tabs, function(tab, i) { if (activeTab === tab) { expect(tab.active).toBe(true); //It should only call select ONCE for each select expect(tab.select.callCount).toBe(1); expect(_titles.eq(i)).toHaveClass('active'); expect(contents().eq(i).text().trim()).toBe('content ' + i); expect(contents().eq(i)).toHaveClass('active'); } else { expect(tab.active).toBe(false); expect(_titles.eq(i)).not.toHaveClass('active'); } }); } it('should make tab titles with first content and first active', function() { expect(titles().length).toBe(scope.tabs.length); expectTabActive(scope.tabs[0]); }); it('should switch active when clicking', function() { titles().eq(3).find('a').click(); expectTabActive(scope.tabs[3]); }); it('should switch active when setting active=true', function() { scope.$apply('tabs[2].active = true'); expectTabActive(scope.tabs[2]); }); it('should deselect all when no tabs are active', function() { angular.forEach(scope.tabs, function(t) { t.active = false; }); scope.$apply(); expectTabActive(null); expect(contents().filter('.active').length).toBe(0); scope.tabs[2].active = true; scope.$apply(); expectTabActive(scope.tabs[2]); }); }); describe('advanced tab-heading element', function() { beforeEach(inject(function($compile, $rootScope) { scope = $rootScope.$new(); scope.myHtml = "<b>hello</b>, there!"; scope.value = true; elm = $compile([ '<tabset>', ' <tab>', ' <tab-heading ng-bind-html-unsafe="myHtml" ng-show="value">', ' </tab-heading>', ' </tab>', ' <tab><data-tab-heading>1</data-tab-heading></tab>', ' <tab><div data-tab-heading>2</div></tab>', ' <tab><div tab-heading>3</div></tab>', '</tabset>' ].join('\n'))(scope); scope.$apply(); })); function heading() { return elm.find('ul li a').children(); } it('should create a heading bound to myHtml', function() { expect(heading().eq(0).html()).toBe("<b>hello</b>, there!"); }); it('should hide and show the heading depending on value', function() { expect(heading().eq(0).css('display')).not.toBe('none'); scope.$apply('value = false'); expect(heading().eq(0).css('display')).toBe('none'); scope.$apply('value = true'); expect(heading().eq(0).css('display')).not.toBe('none'); }); it('should have a tab-heading no matter what syntax was used', function() { expect(heading().eq(1).text()).toBe('1'); expect(heading().eq(2).text()).toBe('2'); expect(heading().eq(3).text()).toBe('3'); }); }); //Tests that http://git.io/lG6I9Q is fixed describe('tab ordering', function() { beforeEach(inject(function($compile, $rootScope) { scope = $rootScope.$new(); scope.tabs = [ { title:"Title 1", available:true }, { title:"Title 2", available:true }, { title:"Title 3", available:true } ]; elm = $compile([ '<tabset>', ' <!-- a comment -->', ' <div>div that makes troubles</div>', ' <tab heading="first">First Static</tab>', ' <div>another div that may do evil</div>', ' <tab ng-repeat="tab in tabs | filter:tabIsAvailable" active="tab.active" heading="{{tab.title}}">some content</tab>', ' <!-- another comment -->', ' <tab heading="mid">Mid Static</tab>', ' a text node', ' <!-- another comment -->', ' <span>yet another span that may do evil</span>', ' <tab ng-repeat="tab in tabs | filter:tabIsAvailable" active="tab.active" heading="Second {{tab.title}}">some content</tab>', ' a text node', ' <span>yet another span that may do evil</span>', ' <!-- another comment -->', ' <tab heading="last">Last Static</tab>', ' a text node', ' <span>yet another span that may do evil</span>', ' <!-- another comment -->', '</tabset>' ].join('\n'))(scope); scope.tabIsAvailable = function(tab) { return tab.available; }; })); it('should preserve correct ordering', function() { function titles() { return elm.find('ul.nav-tabs li a'); } scope.$apply(); expect(titles().length).toBe(9); scope.$apply('tabs[1].available=false'); scope.$digest(); expect(titles().length).toBe(7); scope.$apply('tabs[0].available=false'); scope.$digest(); expect(titles().length).toBe(5); scope.$apply('tabs[2].available=false'); scope.$digest(); expect(titles().length).toBe(3); scope.$apply('tabs[0].available=true'); scope.$digest(); expect(titles().length).toBe(5); scope.$apply('tabs[1].available=true'); scope.$apply('tabs[2].available=true'); scope.$digest(); expect(titles().length).toBe(9); expect(titles().eq(0).text().trim()).toBe("first"); expect(titles().eq(1).text().trim()).toBe("Title 1"); expect(titles().eq(2).text().trim()).toBe("Title 2"); expect(titles().eq(3).text().trim()).toBe("Title 3"); expect(titles().eq(4).text().trim()).toBe("mid"); expect(titles().eq(5).text().trim()).toBe("Second Title 1"); expect(titles().eq(6).text().trim()).toBe("Second Title 2"); expect(titles().eq(7).text().trim()).toBe("Second Title 3"); expect(titles().eq(8).text().trim()).toBe("last"); }); }); describe('tabset controller', function() { function mockTab() { return { active: false }; } var ctrl; beforeEach(inject(function($controller, $rootScope) { scope = $rootScope; //instantiate the controller stand-alone, without the directive ctrl = $controller('TabsetController', {$scope: scope, $element: null}); })); describe('select', function() { it('should mark given tab selected', function() { var tab = mockTab(); ctrl.select(tab); expect(tab.active).toBe(true); }); it('should deselect other tabs', function() { var tab1 = mockTab(), tab2 = mockTab(), tab3 = mockTab(); ctrl.addTab(tab1); ctrl.addTab(tab2); ctrl.addTab(tab3); ctrl.select(tab1); expect(tab1.active).toBe(true); expect(tab2.active).toBe(false); expect(tab3.active).toBe(false); ctrl.select(tab2); expect(tab1.active).toBe(false); expect(tab2.active).toBe(true); expect(tab3.active).toBe(false); ctrl.select(tab3); expect(tab1.active).toBe(false); expect(tab2.active).toBe(false); expect(tab3.active).toBe(true); }); }); describe('addTab', function() { it('should append tab', function() { var tab1 = mockTab(), tab2 = mockTab(); expect(ctrl.tabs).toEqual([]); ctrl.addTab(tab1); expect(ctrl.tabs).toEqual([tab1]); ctrl.addTab(tab2); expect(ctrl.tabs).toEqual([tab1, tab2]); }); it('should select the first one', function() { var tab1 = mockTab(), tab2 = mockTab(); ctrl.addTab(tab1); expect(tab1.active).toBe(true); ctrl.addTab(tab2); expect(tab1.active).toBe(true); }); }); }); describe('remove', function() { it('should remove title tabs when elements are destroyed and change selection', inject(function($controller, $compile, $rootScope) { scope = $rootScope.$new(); elm = $compile("<tabset><tab heading='1'>Hello</tab><tab ng-repeat='i in list' heading='tab {{i}}'>content {{i}}</tab></tabset>")(scope); scope.$apply(); expectTitles(['1']); expectContents(['Hello']); scope.$apply('list = [1,2,3]'); expectTitles(['1', 'tab 1', 'tab 2', 'tab 3']); expectContents(['Hello', 'content 1', 'content 2', 'content 3']); titles().find('a').eq(3).click(); expect(contents().eq(3)).toHaveClass('active'); expect(titles().eq(3)).toHaveClass('active'); scope.$apply('list = [1,2]'); expectTitles(['1', 'tab 1', 'tab 2']); expectContents(['Hello', 'content 1', 'content 2']); expect(titles().eq(2)).toHaveClass('active'); expect(contents().eq(2)).toHaveClass('active'); })); }); describe('disabled', function() { beforeEach(inject(function($compile, $rootScope) { scope = $rootScope.$new(); function makeTab(disabled) { return { active: false, select: jasmine.createSpy(), disabled: disabled }; } scope.tabs = [ makeTab(false), makeTab(true), makeTab(false), makeTab(true) ]; elm = $compile([ '<tabset>', ' <tab ng-repeat="t in tabs" active="t.active" select="t.select()" disabled="t.disabled">', ' <tab-heading><b>heading</b> {{index}}</tab-heading>', ' content {{$index}}', ' </tab>', '</tabset>' ].join('\n'))(scope); scope.$apply(); })); function expectTabActive(activeTab) { var _titles = titles(); angular.forEach(scope.tabs, function(tab, i) { if (activeTab === tab) { expect(tab.active).toBe(true); expect(tab.select.callCount).toBe( (tab.disabled) ? 0 : 1 ); expect(_titles.eq(i)).toHaveClass('active'); expect(contents().eq(i).text().trim()).toBe('content ' + i); expect(contents().eq(i)).toHaveClass('active'); } else { expect(tab.active).toBe(false); expect(_titles.eq(i)).not.toHaveClass('active'); } }); } it('should not switch active when clicking on title', function() { titles().eq(2).find('a').click(); expectTabActive(scope.tabs[2]); titles().eq(3).find('a').click(); expectTabActive(scope.tabs[2]); }); it('should not switch active when setting active=true', function() { scope.$apply('tabs[2].active = true'); expectTabActive(scope.tabs[2]); scope.$apply('tabs[3].active = true'); expectTabActive(scope.tabs[2]); }); it('should toggle between states', function() { expect(titles().eq(3)).toHaveClass('disabled'); scope.$apply('tabs[3].disabled = false'); expect(titles().eq(3)).not.toHaveClass('disabled'); expect(titles().eq(2)).not.toHaveClass('disabled'); scope.$apply('tabs[2].disabled = true'); expect(titles().eq(2)).toHaveClass('disabled'); }); }); describe('vertical', function() { beforeEach(inject(function($compile, $rootScope) { scope = $rootScope.$new(); elm = $compile('<tabset vertical="true"></tabset>')(scope); scope.$apply(); })); it('to stack tabs', function() { expect(elm.find('ul.nav-tabs')).toHaveClass('nav-stacked'); }); }); describe('type', function() { beforeEach(inject(function($compile, $rootScope) { scope = $rootScope.$new(); scope.navType = 'pills'; elm = $compile('<tabset type="navType"></tabset>')(scope); scope.$apply(); })); it('to show pills', function() { expect(elm.find('ul')).toHaveClass('nav-pills'); expect(elm.find('ul')).not.toHaveClass('nav-tabs'); }); }); });