PATH:
home
/
letacommog
/
crmleta
/
consumerportal
/
libraries
/
angularuiaddons
/
ui-select-master
/
test
'use strict'; describe('ui-select tests', function() { var scope, $rootScope, $compile, $timeout, $injector; var Key = { Enter: 13, Tab: 9, Up: 38, Down: 40, Left: 37, Right: 39, Backspace: 8, Delete: 46, Escape: 27 }; beforeEach(module('ngSanitize', 'ui.select')); beforeEach(inject(function(_$rootScope_, _$compile_, _$timeout_, _$injector_) { $rootScope = _$rootScope_; scope = $rootScope.$new(); $compile = _$compile_; $timeout = _$timeout_; $injector = _$injector_; scope.selection = {}; scope.getGroupLabel = function(person) { return person.age % 2 ? 'even' : 'odd'; }; scope.people = [ { name: 'Adam', email: 'adam@email.com', group: 'Foo', age: 12 }, { name: 'Amalie', email: 'amalie@email.com', group: 'Foo', age: 12 }, { name: 'Estefanía', email: 'estefanía@email.com', group: 'Foo', age: 21 }, { name: 'Adrian', email: 'adrian@email.com', group: 'Foo', age: 21 }, { name: 'Wladimir', email: 'wladimir@email.com', group: 'Foo', age: 30 }, { name: 'Samantha', email: 'samantha@email.com', group: 'bar', age: 30 }, { name: 'Nicole', email: 'nicole@email.com', group: 'bar', age: 43 }, { name: 'Natasha', email: 'natasha@email.com', group: 'Baz', age: 54 } ]; scope.someObject = {}; scope.someObject.people = [ { name: 'Adam', email: 'adam@email.com', group: 'Foo', age: 12 }, { name: 'Amalie', email: 'amalie@email.com', group: 'Foo', age: 12 }, { name: 'Estefanía', email: 'estefanía@email.com', group: 'Foo', age: 21 }, { name: 'Adrian', email: 'adrian@email.com', group: 'Foo', age: 21 }, { name: 'Wladimir', email: 'wladimir@email.com', group: 'Foo', age: 30 }, { name: 'Samantha', email: 'samantha@email.com', group: 'bar', age: 30 }, { name: 'Nicole', email: 'nicole@email.com', group: 'bar', age: 43 }, { name: 'Natasha', email: 'natasha@email.com', group: 'Baz', age: 54 } ]; })); // DSL (domain-specific language) function compileTemplate(template) { var el = $compile(angular.element(template))(scope); scope.$digest(); return el; } function createUiSelect(attrs) { var attrsHtml = ''; if (attrs !== undefined) { if (attrs.disabled !== undefined) { attrsHtml += ' ng-disabled="' + attrs.disabled + '"'; } if (attrs.required !== undefined) { attrsHtml += ' ng-required="' + attrs.required + '"'; } if (attrs.theme !== undefined) { attrsHtml += ' theme="' + attrs.theme + '"'; } if (attrs.tabindex !== undefined) { attrsHtml += ' tabindex="' + attrs.tabindex + '"'; } if (attrs.tagging !== undefined) { attrsHtml += ' tagging="' + attrs.tagging + '"'; } if (attrs.title !== undefined) { attrsHtml += ' title="' + attrs.title + '"'; } } return compileTemplate( '<ui-select ng-model="selection.selected"' + attrsHtml + '> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); } function getMatchLabel(el) { return $(el).find('.ui-select-match > button:first > span[ng-transclude]:not(.ng-hide)').text(); } function clickItem(el, text) { if (!isDropdownOpened(el)){ openDropdown(el); } $(el).find('.ui-select-choices-row div:contains("' + text + '")').click(); scope.$digest(); } function clickMatch(el) { $(el).find('.ui-select-match > button:first').click(); scope.$digest(); } function isDropdownOpened(el) { // Does not work with jQuery 2.*, have to use jQuery 1.11.* // This will be fixed in AngularJS 1.3 // See issue with unit-testing directive using karma https://github.com/angular/angular.js/issues/4640#issuecomment-35002427 return el.scope().$select.open && el.hasClass('open'); } function triggerKeydown(element, keyCode) { var e = jQuery.Event("keydown"); e.which = keyCode; e.keyCode = keyCode; element.trigger(e); } function setSearchText(el, text) { el.scope().$select.search = text; scope.$digest(); $timeout.flush(); } function openDropdown(el) { var $select = el.scope().$select; $select.open = true; scope.$digest(); }; // Tests it('should compile child directives', function() { var el = createUiSelect(); var searchEl = $(el).find('.ui-select-search'); expect(searchEl.length).toEqual(1); var matchEl = $(el).find('.ui-select-match'); expect(matchEl.length).toEqual(1); var choicesContentEl = $(el).find('.ui-select-choices-content'); expect(choicesContentEl.length).toEqual(1); var choicesContainerEl = $(el).find('.ui-select-choices'); expect(choicesContainerEl.length).toEqual(1); openDropdown(el); var choicesEls = $(el).find('.ui-select-choices-row'); expect(choicesEls.length).toEqual(8); }); it('should correctly render initial state', function() { scope.selection.selected = scope.people[0]; var el = createUiSelect(); expect(getMatchLabel(el)).toEqual('Adam'); }); it('should correctly render initial state with track by feature', function() { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search track by person.name"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); scope.selection.selected = { name: 'Samantha', email: 'something different than array source', group: 'bar', age: 30 }; scope.$digest(); expect(getMatchLabel(el)).toEqual('Samantha'); }); it('should display the choices when activated', function() { var el = createUiSelect(); expect(isDropdownOpened(el)).toEqual(false); clickMatch(el); expect(isDropdownOpened(el)).toEqual(true); }); it('should select an item', function() { var el = createUiSelect(); clickItem(el, 'Samantha'); expect(getMatchLabel(el)).toEqual('Samantha'); }); it('should select an item (controller)', function() { var el = createUiSelect(); el.scope().$select.select(scope.people[1]); scope.$digest(); expect(getMatchLabel(el)).toEqual('Amalie'); }); it('should not select a non existing item', function() { var el = createUiSelect(); clickItem(el, "I don't exist"); expect(getMatchLabel(el)).toEqual(''); }); it('should close the choices when an item is selected', function() { var el = createUiSelect(); clickMatch(el); expect(isDropdownOpened(el)).toEqual(true); clickItem(el, 'Samantha'); expect(isDropdownOpened(el)).toEqual(false); }); it('should open/close dropdown when clicking caret icon', function() { var el = createUiSelect({theme : 'select2'}); var searchInput = el.find('.ui-select-search'); var $select = el.scope().$select; expect($select.open).toEqual(false); el.find(".ui-select-toggle").click(); expect($select.open).toEqual(true); el.find(".ui-select-toggle").click(); expect($select.open).toEqual(false); }); it('should pass tabindex to focusser', function() { var el = createUiSelect({tabindex: 5}); expect($(el).find('.ui-select-focusser').attr('tabindex')).toEqual('5'); expect($(el).attr('tabindex')).toEqual(undefined); }); it('should pass tabindex to focusser when tabindex is an expression', function() { scope.tabValue = 22; var el = createUiSelect({tabindex: '{{tabValue + 10}}'}); expect($(el).find('.ui-select-focusser').attr('tabindex')).toEqual('32'); expect($(el).attr('tabindex')).toEqual(undefined); }); it('should not give focusser a tabindex when ui-select does not have one', function() { var el = createUiSelect(); expect($(el).find('.ui-select-focusser').attr('tabindex')).toEqual(undefined); expect($(el).attr('tabindex')).toEqual(undefined); }); it('should be disabled if the attribute says so', function() { var el1 = createUiSelect({disabled: true}); expect(el1.scope().$select.disabled).toEqual(true); clickMatch(el1); expect(isDropdownOpened(el1)).toEqual(false); var el2 = createUiSelect({disabled: false}); expect(el2.scope().$select.disabled).toEqual(false); clickMatch(el2); expect(isDropdownOpened(el2)).toEqual(true); var el3 = createUiSelect(); expect(el3.scope().$select.disabled).toBeFalsy(); clickMatch(el3); expect(isDropdownOpened(el3)).toEqual(true); }); it('should allow tagging if the attribute says so', function() { var el = createUiSelect({tagging: true}); clickMatch(el); $(el).scope().$select.select("I don't exist"); expect($(el).scope().$select.selected).toEqual("I don't exist"); }); it('should format new items using the tagging function when the attribute is a function', function() { scope.taggingFunc = function (name) { return { name: name, email: name + '@email.com', group: 'Foo', age: 12 }; }; var el = createUiSelect({tagging: 'taggingFunc'}); clickMatch(el); $(el).scope().$select.search = 'idontexist'; $(el).scope().$select.activeIndex = 0; $(el).scope().$select.select('idontexist'); expect($(el).scope().$select.selected).toEqual({ name: 'idontexist', email: 'idontexist@email.com', group: 'Foo', age: 12 }); }); // See when an item that evaluates to false (such as "false" or "no") is selected, the placeholder is shown https://github.com/angular-ui/ui-select/pull/32 it('should not display the placeholder when item evaluates to false', function() { scope.items = ['false']; var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match>{{$select.selected}}</ui-select-match> \ <ui-select-choices repeat="item in items | filter: $select.search"> \ <div ng-bind-html="item | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); expect(el.scope().$select.selected).toEqual(undefined); clickItem(el, 'false'); expect(el.scope().$select.selected).toEqual('false'); expect(getMatchLabel(el)).toEqual('false'); }); it('should close an opened select when another one is opened', function() { var el1 = createUiSelect(); var el2 = createUiSelect(); el1.appendTo(document.body); el2.appendTo(document.body); expect(isDropdownOpened(el1)).toEqual(false); expect(isDropdownOpened(el2)).toEqual(false); clickMatch(el1); expect(isDropdownOpened(el1)).toEqual(true); expect(isDropdownOpened(el2)).toEqual(false); clickMatch(el2); expect(isDropdownOpened(el1)).toEqual(false); expect(isDropdownOpened(el2)).toEqual(true); el1.remove(); el2.remove(); }); describe('disabled options', function() { function createUiSelect(attrs) { var attrsDisabled = ''; if (attrs !== undefined) { if (attrs.disabled !== undefined) { attrsDisabled = ' ui-disable-choice="' + attrs.disabled + '"'; } else { attrsDisabled = ''; } } return compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"' + attrsDisabled + '> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); } function disablePerson(opts) { opts = opts || {}; var key = opts.key || 'people', disableAttr = opts.disableAttr || 'disabled', disableBool = opts.disableBool === undefined ? true : opts.disableBool, matchAttr = opts.match || 'name', matchVal = opts.matchVal || 'Wladimir'; scope['_' + key] = angular.copy(scope[key]); scope[key].map(function (model) { if (model[matchAttr] == matchVal) { model[disableAttr] = disableBool; } return model; }); } function resetScope(opts) { opts = opts || {}; var key = opts.key || 'people'; scope[key] = angular.copy(scope['_' + key]); } describe('without disabling expression', function () { beforeEach(function() { disablePerson(); this.el = createUiSelect(); }); it('should not allow disabled options to be selected', function() { clickItem(this.el, 'Wladimir'); expect(getMatchLabel(this.el)).toEqual('Wladimir'); }); it('should set a disabled class on the option', function() { var option = $(this.el).find('.ui-select-choices-row div:contains("Wladimir")'); var container = option.closest('.ui-select-choices-row'); expect(container.hasClass('disabled')).toBeFalsy(); }); }); describe('disable on truthy property', function () { beforeEach(function() { disablePerson({ disableAttr : 'inactive', disableBool : true }); this.el = createUiSelect({ disabled: 'person.inactive' }); }); it('should allow the user to define the selected option', function () { expect($(this.el).find('.ui-select-choices').attr('ui-disable-choice')).toBe('person.inactive'); }); it('should not allow disabled options to be selected', function() { clickItem(this.el, 'Wladimir'); expect(getMatchLabel(this.el)).not.toEqual('Wladimir'); }); it('should set a disabled class on the option', function() { openDropdown(this.el); var option = $(this.el).find('.ui-select-choices-row div:contains("Wladimir")'); var container = option.closest('.ui-select-choices-row'); expect(container.hasClass('disabled')).toBeTruthy(); }); }); describe('disable on inverse property check', function () { beforeEach(function() { disablePerson({ disableAttr : 'active', disableBool : false }); this.el = createUiSelect({ disabled: '!person.active' }); }); it('should allow the user to define the selected option', function () { expect($(this.el).find('.ui-select-choices').attr('ui-disable-choice')).toBe('!person.active'); }); it('should not allow disabled options to be selected', function() { clickItem(this.el, 'Wladimir'); expect(getMatchLabel(this.el)).not.toEqual('Wladimir'); }); it('should set a disabled class on the option', function() { openDropdown(this.el); var option = $(this.el).find('.ui-select-choices-row div:contains("Wladimir")'); var container = option.closest('.ui-select-choices-row'); expect(container.hasClass('disabled')).toBeTruthy(); }); }); describe('disable on expression', function () { beforeEach(function() { disablePerson({ disableAttr : 'status', disableBool : 'inactive' }); this.el = createUiSelect({ disabled: "person.status == 'inactive'" }); }); it('should allow the user to define the selected option', function () { expect($(this.el).find('.ui-select-choices').attr('ui-disable-choice')).toBe("person.status == 'inactive'"); }); it('should not allow disabled options to be selected', function() { clickItem(this.el, 'Wladimir'); expect(getMatchLabel(this.el)).not.toEqual('Wladimir'); }); it('should set a disabled class on the option', function() { openDropdown(this.el); var option = $(this.el).find('.ui-select-choices-row div:contains("Wladimir")'); var container = option.closest('.ui-select-choices-row'); expect(container.hasClass('disabled')).toBeTruthy(); }); }); afterEach(function() { resetScope(); }); }); describe('choices group', function() { function getGroupLabel(item) { return item.parent('.ui-select-choices-group').find('.ui-select-choices-group-label'); } function createUiSelect() { return compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices group-by="\'group\'" repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); } it('should create items group', function() { var el = createUiSelect(); expect(el.find('.ui-select-choices-group').length).toBe(3); }); it('should show label before each group', function() { var el = createUiSelect(); expect(el.find('.ui-select-choices-group .ui-select-choices-group-label').map(function() { return this.textContent; }).toArray()).toEqual(['Foo', 'bar', 'Baz']); }); it('should hide empty groups', function() { var el = createUiSelect(); el.scope().$select.search = 'd'; scope.$digest(); expect(el.find('.ui-select-choices-group .ui-select-choices-group-label').map(function() { return this.textContent; }).toArray()).toEqual(['Foo']); }); it('should change activeItem through groups', function() { var el = createUiSelect(); el.scope().$select.search = 't'; scope.$digest(); openDropdown(el); var choices = el.find('.ui-select-choices-row'); expect(choices.eq(0)).toHaveClass('active'); expect(getGroupLabel(choices.eq(0)).text()).toBe('Foo'); triggerKeydown(el.find('input'), 40 /*Down*/); scope.$digest(); expect(choices.eq(1)).toHaveClass('active'); expect(getGroupLabel(choices.eq(1)).text()).toBe('bar'); }); }); describe('choices group by function', function() { function createUiSelect() { return compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices group-by="getGroupLabel" repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); } it("should extract group value through function", function () { var el = createUiSelect(); expect(el.find('.ui-select-choices-group .ui-select-choices-group-label').map(function() { return this.textContent; }).toArray()).toEqual(['odd', 'even']); }); }); it('should throw when no ui-select-choices found', function() { expect(function() { compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match></ui-select-match> \ </ui-select>' ); }).toThrow(new Error('[ui.select:transcluded] Expected 1 .ui-select-choices but got \'0\'.')); }); it('should throw when no repeat attribute is provided to ui-select-choices', function() { expect(function() { compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-choices></ui-select-choices> \ </ui-select>' ); }).toThrow(new Error('[ui.select:repeat] Expected \'repeat\' expression.')); }); it('should throw when repeat attribute has incorrect format ', function() { expect(function() { compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match></ui-select-match> \ <ui-select-choices repeat="incorrect format people"></ui-select-choices> \ </ui-select>' ); }).toThrow(new Error('[ui.select:iexp] Expected expression in form of \'_item_ in _collection_[ track by _id_]\' but got \'incorrect format people\'.')); }); it('should throw when no ui-select-match found', function() { expect(function() { compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-choices repeat="item in items"></ui-select-choices> \ </ui-select>' ); }).toThrow(new Error('[ui.select:transcluded] Expected 1 .ui-select-match but got \'0\'.')); }); it('should format the model correctly using alias', function() { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); clickItem(el, 'Samantha'); expect(scope.selection.selected).toBe(scope.people[5]); }); it('should parse the model correctly using alias', function() { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); scope.selection.selected = scope.people[5]; scope.$digest(); expect(getMatchLabel(el)).toEqual('Samantha'); }); it('should format the model correctly using property of alias', function() { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person.name as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); clickItem(el, 'Samantha'); expect(scope.selection.selected).toBe('Samantha'); }); it('should parse the model correctly using property of alias', function() { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person.name as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); scope.selection.selected = 'Samantha'; scope.$digest(); expect(getMatchLabel(el)).toEqual('Samantha'); }); it('should parse the model correctly using property of alias with async choices data', function() { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person.name as person in peopleAsync | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); $timeout(function() { scope.peopleAsync = scope.people; }); scope.selection.selected = 'Samantha'; scope.$digest(); expect(getMatchLabel(el)).toEqual(''); $timeout.flush(); //After choices populated (async), it should show match correctly expect(getMatchLabel(el)).toEqual('Samantha'); }); //TODO Is this really something we should expect? it('should parse the model correctly using property of alias but passed whole object', function() { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person.name as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); scope.selection.selected = scope.people[5]; scope.$digest(); expect(getMatchLabel(el)).toEqual('Samantha'); }); it('should format the model correctly without alias', function() { var el = createUiSelect(); clickItem(el, 'Samantha'); expect(scope.selection.selected).toBe(scope.people[5]); }); it('should parse the model correctly without alias', function() { var el = createUiSelect(); scope.selection.selected = scope.people[5]; scope.$digest(); expect(getMatchLabel(el)).toEqual('Samantha'); }); it('should display choices correctly with child array', function() { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person in someObject.people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); scope.selection.selected = scope.people[5]; scope.$digest(); expect(getMatchLabel(el)).toEqual('Samantha'); }); it('should format the model correctly using property of alias and when using child array for choices', function() { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person.name as person in someObject.people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); clickItem(el, 'Samantha'); expect(scope.selection.selected).toBe('Samantha'); }); it('should invoke select callback on select', function () { scope.onSelectFn = function ($item, $model, $label) { scope.$item = $item; scope.$model = $model; }; var el = compileTemplate( '<ui-select on-select="onSelectFn($item, $model)" ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person.name as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); expect(scope.$item).toBeFalsy(); expect(scope.$model).toBeFalsy(); clickItem(el, 'Samantha'); $timeout.flush(); expect(scope.selection.selected).toBe('Samantha'); expect(scope.$item).toEqual(scope.people[5]); expect(scope.$model).toEqual('Samantha'); }); it('should invoke hover callback', function(){ var highlighted; scope.onHighlightFn = function ($item) { highlighted = $item; }; var el = compileTemplate( '<ui-select on-select="onSelectFn($item, $model)" ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices on-highlight="onHighlightFn(person)" repeat="person.name as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); expect(highlighted).toBeFalsy(); if (!isDropdownOpened(el)){ openDropdown(el); } $(el).find('.ui-select-choices-row div:contains("Samantha")').trigger('mouseover'); scope.$digest(); expect(highlighted).toBe(scope.people[5]); }) it('should set $item & $model correctly when invoking callback on select and no single prop. binding', function () { scope.onSelectFn = function ($item, $model, $label) { scope.$item = $item; scope.$model = $model; }; var el = compileTemplate( '<ui-select on-select="onSelectFn($item, $model)" ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); expect(scope.$item).toBeFalsy(); expect(scope.$model).toBeFalsy(); clickItem(el, 'Samantha'); expect(scope.$item).toEqual(scope.$model); }); it('should invoke remove callback on remove', function () { scope.onRemoveFn = function ($item, $model, $label) { scope.$item = $item; scope.$model = $model; }; var el = compileTemplate( '<ui-select multiple on-remove="onRemoveFn($item, $model)" ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person.name as person in people | filter: $select.search"> \ <div ng-bind-html="person.name" | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); expect(scope.$item).toBeFalsy(); expect(scope.$model).toBeFalsy(); clickItem(el, 'Samantha'); clickItem(el, 'Adrian'); el.find('.ui-select-match-item').first().find('.ui-select-match-close').click(); $timeout.flush(); expect(scope.$item).toBe(scope.people[5]); expect(scope.$model).toBe('Samantha'); }); it('should set $item & $model correctly when invoking callback on remove and no single prop. binding', function () { scope.onRemoveFn = function ($item, $model, $label) { scope.$item = $item; scope.$model = $model; }; var el = compileTemplate( '<ui-select multiple on-remove="onRemoveFn($item, $model)" ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name" | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); expect(scope.$item).toBeFalsy(); expect(scope.$model).toBeFalsy(); clickItem(el, 'Samantha'); clickItem(el, 'Adrian'); el.find('.ui-select-match-item').first().find('.ui-select-match-close').click(); $timeout.flush(); expect(scope.$item).toBe(scope.people[5]); expect(scope.$model).toBe(scope.$item); }); it('should append/transclude content (with correct scope) that users add at <match> tag', function () { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match> \ <span ng-if="$select.selected.name!==\'Wladimir\'">{{$select.selected.name}}</span>\ <span ng-if="$select.selected.name===\'Wladimir\'">{{$select.selected.name | uppercase}}</span>\ </ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); clickItem(el, 'Samantha'); expect(getMatchLabel(el).trim()).toEqual('Samantha'); clickItem(el, 'Wladimir'); expect(getMatchLabel(el).trim()).not.toEqual('Wladimir'); expect(getMatchLabel(el).trim()).toEqual('WLADIMIR'); }); it('should append/transclude content (with correct scope) that users add at <choices> tag', function () { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match> \ </ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-if="person.name==\'Wladimir\'"> \ <span class="only-once">I should appear only once</span>\ </div> \ </ui-select-choices> \ </ui-select>' ); openDropdown(el); expect($(el).find('.only-once').length).toEqual(1); }); it('should call refresh function when search text changes', function () { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match> \ </ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search" \ refresh="fetchFromServer($select.search)" refresh-delay="0"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-if="person.name==\'Wladimir\'"> \ <span class="only-once">I should appear only once</span>\ </div> \ </ui-select-choices> \ </ui-select>' ); scope.fetchFromServer = function(){}; spyOn(scope, 'fetchFromServer'); el.scope().$select.search = 'r'; scope.$digest(); $timeout.flush(); expect(scope.fetchFromServer).toHaveBeenCalledWith('r'); }); it('should call refresh function when search text changes', function () { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match> \ </ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search" \ refresh="fetchFromServer($select.search)" refresh-delay="0"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-if="person.name==\'Wladimir\'"> \ <span class="only-once">I should appear only once</span>\ </div> \ </ui-select-choices> \ </ui-select>' ); scope.fetchFromServer = function(){}; spyOn(scope, 'fetchFromServer'); el.scope().$select.search = 'r'; scope.$digest(); $timeout.flush(); expect(scope.fetchFromServer).toHaveBeenCalledWith('r'); }); it('should format view value correctly when using single property binding and refresh funcion', function () { var el = compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match>{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person.name as person in people | filter: $select.search" \ refresh="fetchFromServer($select.search)" refresh-delay="0"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-if="person.name==\'Wladimir\'"> \ <span class="only-once">I should appear only once</span>\ </div> \ </ui-select-choices> \ </ui-select>' ); scope.fetchFromServer = function(searching){ if (searching == 's') return scope.people if (searching == 'o'){ scope.people = []; //To simulate cases were previously selected item isnt in the list anymore } }; setSearchText(el, 'r') clickItem(el, 'Samantha'); expect(getMatchLabel(el)).toBe('Samantha'); setSearchText(el, 'o') expect(getMatchLabel(el)).toBe('Samantha'); }); describe('search-enabled option', function() { var el; function setupSelectComponent(searchEnabled, theme) { el = compileTemplate( '<ui-select ng-model="selection.selected" theme="' + theme + '" search-enabled="' + searchEnabled + '"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); } describe('selectize theme', function() { it('should show search input when true', function() { setupSelectComponent(true, 'selectize'); expect($(el).find('.ui-select-search')).not.toHaveClass('ng-hide'); }); it('should hide search input when false', function() { setupSelectComponent(false, 'selectize'); expect($(el).find('.ui-select-search')).toHaveClass('ng-hide'); }); }); describe('select2 theme', function() { it('should show search input when true', function() { setupSelectComponent('true', 'select2'); expect($(el).find('.select2-search')).not.toHaveClass('ng-hide'); }); it('should hide search input when false', function() { setupSelectComponent('false', 'select2'); expect($(el).find('.select2-search')).toHaveClass('ng-hide'); }); }); describe('bootstrap theme', function() { it('should show search input when true', function() { setupSelectComponent('true', 'bootstrap'); clickMatch(el); expect($(el).find('.ui-select-search')).not.toHaveClass('ng-hide'); }); it('should hide search input when false', function() { setupSelectComponent('false', 'bootstrap'); clickMatch(el); expect($(el).find('.ui-select-search')).toHaveClass('ng-hide'); }); }); }); describe('multi selection', function() { function createUiSelectMultiple(attrs) { var attrsHtml = ''; if (attrs !== undefined) { if (attrs.disabled !== undefined) { attrsHtml += ' ng-disabled="' + attrs.disabled + '"'; } if (attrs.required !== undefined) { attrsHtml += ' ng-required="' + attrs.required + '"'; } if (attrs.tabindex !== undefined) { attrsHtml += ' tabindex="' + attrs.tabindex + '"'; } if (attrs.closeOnSelect !== undefined) { attrsHtml += ' close-on-select="' + attrs.closeOnSelect + '"'; } } return compileTemplate( '<ui-select multiple ng-model="selection.selectedMultiple"' + attrsHtml + ' theme="bootstrap" style="width: 800px;"> \ <ui-select-match placeholder="Pick one...">{{$item.name}} <{{$item.email}}></ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); } it('should render initial state', function() { var el = createUiSelectMultiple(); expect(el).toHaveClass('ui-select-multiple'); expect(el.scope().$select.selected.length).toBe(0); expect(el.find('.ui-select-match-item').length).toBe(0); }); it('should set model as an empty array if ngModel isnt defined after an item is selected', function () { // scope.selection.selectedMultiple = []; var el = createUiSelectMultiple(); expect(scope.selection.selectedMultiple instanceof Array).toBe(false); clickItem(el, 'Samantha'); expect(scope.selection.selectedMultiple instanceof Array).toBe(true); }); it('should render initial selected items', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; //Wladimir & Samantha var el = createUiSelectMultiple(); expect(el.scope().$select.selected.length).toBe(2); expect(el.find('.ui-select-match-item').length).toBe(2); }); it('should remove item by pressing X icon', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; //Wladimir & Samantha var el = createUiSelectMultiple(); expect(el.scope().$select.selected.length).toBe(2); el.find('.ui-select-match-item').first().find('.ui-select-match-close').click(); expect(el.scope().$select.selected.length).toBe(1); // $timeout.flush(); }); it('should pass tabindex to searchInput', function() { var el = createUiSelectMultiple({tabindex: 5}); var searchInput = el.find('.ui-select-search'); expect(searchInput.attr('tabindex')).toEqual('5'); expect($(el).attr('tabindex')).toEqual(undefined); }); it('should pass tabindex to searchInput when tabindex is an expression', function() { scope.tabValue = 22; var el = createUiSelectMultiple({tabindex: '{{tabValue + 10}}'}); var searchInput = el.find('.ui-select-search'); expect(searchInput.attr('tabindex')).toEqual('32'); expect($(el).attr('tabindex')).toEqual(undefined); }); it('should not give searchInput a tabindex when ui-select does not have one', function() { var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); expect(searchInput.attr('tabindex')).toEqual(undefined); expect($(el).attr('tabindex')).toEqual(undefined); }); it('should update size of search input after removing an item', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; //Wladimir & Samantha var el = createUiSelectMultiple(); spyOn(el.scope().$select, 'sizeSearchInput'); var searchInput = el.find('.ui-select-search'); var oldWidth = searchInput.css('width'); el.find('.ui-select-match-item').first().find('.ui-select-match-close').click(); expect(el.scope().$select.sizeSearchInput).toHaveBeenCalled(); }); it('should move to last match when pressing BACKSPACE key from search', function() { var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); expect(isDropdownOpened(el)).toEqual(false); triggerKeydown(searchInput, Key.Backspace); expect(isDropdownOpened(el)).toEqual(false); expect(el.scope().$select.activeMatchIndex).toBe(el.scope().$select.selected.length - 1); }); it('should remove hightlighted match when pressing BACKSPACE key from search and decrease activeMatchIndex', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5], scope.people[6]]; //Wladimir, Samantha & Nicole var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); expect(isDropdownOpened(el)).toEqual(false); triggerKeydown(searchInput, Key.Left); triggerKeydown(searchInput, Key.Left); triggerKeydown(searchInput, Key.Backspace); expect(el.scope().$select.selected).toEqual([scope.people[4], scope.people[6]]); //Wladimir & Nicole expect(el.scope().$select.activeMatchIndex).toBe(0); }); it('should remove hightlighted match when pressing DELETE key from search and keep same activeMatchIndex', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5], scope.people[6]]; //Wladimir, Samantha & Nicole var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); expect(isDropdownOpened(el)).toEqual(false); triggerKeydown(searchInput, Key.Left); triggerKeydown(searchInput, Key.Left); triggerKeydown(searchInput, Key.Delete); expect(el.scope().$select.selected).toEqual([scope.people[4], scope.people[6]]); //Wladimir & Nicole expect(el.scope().$select.activeMatchIndex).toBe(1); }); it('should move to last match when pressing LEFT key from search', function() { var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); expect(isDropdownOpened(el)).toEqual(false); triggerKeydown(searchInput, Key.Left); expect(isDropdownOpened(el)).toEqual(false); expect(el.scope().$select.activeMatchIndex).toBe(el.scope().$select.selected.length - 1); }); it('should move between matches when pressing LEFT key from search', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5], scope.people[6]]; //Wladimir, Samantha & Nicole var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); expect(isDropdownOpened(el)).toEqual(false); triggerKeydown(searchInput, Key.Left) triggerKeydown(searchInput, Key.Left) expect(isDropdownOpened(el)).toEqual(false); expect(el.scope().$select.activeMatchIndex).toBe(el.scope().$select.selected.length - 2); triggerKeydown(searchInput, Key.Left) triggerKeydown(searchInput, Key.Left) triggerKeydown(searchInput, Key.Left) expect(el.scope().$select.activeMatchIndex).toBe(0); }); it('should decrease $select.activeMatchIndex when pressing LEFT key', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5], scope.people[6]]; //Wladimir, Samantha & Nicole var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); el.scope().$select.activeMatchIndex = 3 triggerKeydown(searchInput, Key.Left) triggerKeydown(searchInput, Key.Left) expect(el.scope().$select.activeMatchIndex).toBe(1); }); it('should increase $select.activeMatchIndex when pressing RIGHT key', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5], scope.people[6]]; //Wladimir, Samantha & Nicole var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); el.scope().$select.activeMatchIndex = 0 triggerKeydown(searchInput, Key.Right) triggerKeydown(searchInput, Key.Right) expect(el.scope().$select.activeMatchIndex).toBe(2); }); it('should open dropdown when pressing DOWN key', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; //Wladimir & Samantha var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); expect(isDropdownOpened(el)).toEqual(false); triggerKeydown(searchInput, Key.Down) expect(isDropdownOpened(el)).toEqual(true); }); it('should search/open dropdown when writing to search input', function() { scope.selection.selectedMultiple = [scope.people[5]]; //Wladimir & Samantha var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); el.scope().$select.search = 'r'; scope.$digest(); expect(isDropdownOpened(el)).toEqual(true); }); it('should add selected match to selection array', function() { scope.selection.selectedMultiple = [scope.people[5]]; //Samantha var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); clickItem(el, 'Wladimir'); expect(scope.selection.selectedMultiple).toEqual([scope.people[5], scope.people[4]]); //Samantha & Wladimir }); it('should close dropdown after selecting', function() { scope.selection.selectedMultiple = [scope.people[5]]; //Samantha var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); expect(isDropdownOpened(el)).toEqual(false); triggerKeydown(searchInput, Key.Down) expect(isDropdownOpened(el)).toEqual(true); clickItem(el, 'Wladimir'); expect(isDropdownOpened(el)).toEqual(false); }); it('should not close dropdown after selecting if closeOnSelect=false', function() { scope.selection.selectedMultiple = [scope.people[5]]; //Samantha var el = createUiSelectMultiple({closeOnSelect: false}); var searchInput = el.find('.ui-select-search'); expect(isDropdownOpened(el)).toEqual(false); triggerKeydown(searchInput, Key.Down) expect(isDropdownOpened(el)).toEqual(true); clickItem(el, 'Wladimir'); expect(isDropdownOpened(el)).toEqual(true); }); it('should closes dropdown when pressing ESC key from search input', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5], scope.people[6]]; //Wladimir, Samantha & Nicole var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); expect(isDropdownOpened(el)).toEqual(false); triggerKeydown(searchInput, Key.Down) expect(isDropdownOpened(el)).toEqual(true); triggerKeydown(searchInput, Key.Escape) expect(isDropdownOpened(el)).toEqual(false); }); it('should select highlighted match when pressing ENTER key from dropdown', function() { scope.selection.selectedMultiple = [scope.people[5]]; //Samantha var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); triggerKeydown(searchInput, Key.Down) triggerKeydown(searchInput, Key.Enter) expect(scope.selection.selectedMultiple.length).toEqual(2); }); it('should increase $select.activeIndex when pressing DOWN key from dropdown', function() { var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); triggerKeydown(searchInput, Key.Down); //Open dropdown el.scope().$select.activeIndex = 0 triggerKeydown(searchInput, Key.Down) triggerKeydown(searchInput, Key.Down) expect(el.scope().$select.activeIndex).toBe(2); }); it('should decrease $select.activeIndex when pressing UP key from dropdown', function() { var el = createUiSelectMultiple(); var searchInput = el.find('.ui-select-search'); triggerKeydown(searchInput, Key.Down); //Open dropdown el.scope().$select.activeIndex = 5 triggerKeydown(searchInput, Key.Up) triggerKeydown(searchInput, Key.Up) expect(el.scope().$select.activeIndex).toBe(3); }); it('should render initial selected items', function() { scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; //Wladimir & Samantha var el = createUiSelectMultiple(); expect(el.scope().$select.selected.length).toBe(2); expect(el.find('.ui-select-match-item').length).toBe(2); }); it('should parse the items correctly using single property binding', function() { scope.selection.selectedMultiple = ['wladimir@email.com', 'samantha@email.com']; var el = compileTemplate( '<ui-select multiple ng-model="selection.selectedMultiple" theme="bootstrap" style="width: 800px;"> \ <ui-select-match placeholder="Pick one...">{{$item.name}} <{{$item.email}}></ui-select-match> \ <ui-select-choices repeat="person.email as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); expect(el.scope().$select.selected).toEqual([scope.people[4], scope.people[5]]); }); it('should add selected match to selection array using single property binding', function() { scope.selection.selectedMultiple = ['wladimir@email.com', 'samantha@email.com']; var el = compileTemplate( '<ui-select multiple ng-model="selection.selectedMultiple" theme="bootstrap" style="width: 800px;"> \ <ui-select-match placeholder="Pick one...">{{$item.name}} <{{$item.email}}></ui-select-match> \ <ui-select-choices repeat="person.email as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); var searchInput = el.find('.ui-select-search'); clickItem(el, 'Natasha'); expect(el.scope().$select.selected).toEqual([scope.people[4], scope.people[5], scope.people[7]]); scope.selection.selectedMultiple = ['wladimir@email.com', 'samantha@email.com', 'natasha@email.com']; }); it('should format view value correctly when using single property binding and refresh funcion', function () { scope.selection.selectedMultiple = ['wladimir@email.com', 'samantha@email.com']; var el = compileTemplate( '<ui-select multiple ng-model="selection.selectedMultiple" theme="bootstrap" style="width: 800px;"> \ <ui-select-match placeholder="Pick one...">{{$item.name}} <{{$item.email}}></ui-select-match> \ <ui-select-choices repeat="person.email as person in people | filter: $select.search" \ refresh="fetchFromServer($select.search)" refresh-delay="0"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); var searchInput = el.find('.ui-select-search'); scope.fetchFromServer = function(searching){ if (searching == 'n') return scope.people if (searching == 'o'){ scope.people = []; //To simulate cases were previously selected item isnt in the list anymore } }; setSearchText(el, 'n') clickItem(el, 'Nicole'); expect(el.find('.ui-select-match-item [uis-transclude-append]:not(.ng-hide)').text()) .toBe("Wladimir <wladimir@email.com>Samantha <samantha@email.com>Nicole <nicole@email.com>"); setSearchText(el, 'o') expect(el.find('.ui-select-match-item [uis-transclude-append]:not(.ng-hide)').text()) .toBe("Wladimir <wladimir@email.com>Samantha <samantha@email.com>Nicole <nicole@email.com>"); }); it('should watch changes for $select.selected and update formatted value correctly', function () { scope.selection.selectedMultiple = ['wladimir@email.com', 'samantha@email.com']; var el = compileTemplate( '<ui-select multiple ng-model="selection.selectedMultiple" theme="bootstrap" style="width: 800px;"> \ <ui-select-match placeholder="Pick one...">{{$item.name}} <{{$item.email}}></ui-select-match> \ <ui-select-choices repeat="person.email as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select> \ ' ); var el2 = compileTemplate('<span class="resultDiv" ng-bind="selection.selectedMultiple"></span>'); expect(el.find('.ui-select-match-item [uis-transclude-append]:not(.ng-hide)').text()) .toBe("Wladimir <wladimir@email.com>Samantha <samantha@email.com>"); clickItem(el, 'Nicole'); expect(el.find('.ui-select-match-item [uis-transclude-append]:not(.ng-hide)').text()) .toBe("Wladimir <wladimir@email.com>Samantha <samantha@email.com>Nicole <nicole@email.com>"); expect(scope.selection.selectedMultiple.length).toBe(3); }); it('should change viewvalue only once when updating modelvalue', function () { scope.selection.selectedMultiple = ['wladimir@email.com', 'samantha@email.com']; var el = compileTemplate( '<ui-select ng-change="onlyOnce()" multiple ng-model="selection.selectedMultiple" theme="bootstrap" style="width: 800px;"> \ <ui-select-match placeholder="Pick one...">{{$item.name}} <{{$item.email}}></ui-select-match> \ <ui-select-choices repeat="person.email as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select> \ ' ); scope.counter = 0; scope.onlyOnce = function(){ scope.counter++; } clickItem(el, 'Nicole'); expect(scope.counter).toBe(1); }); it('should run $formatters when changing model directly', function () { scope.selection.selectedMultiple = ['wladimir@email.com', 'samantha@email.com']; var el = compileTemplate( '<ui-select multiple ng-model="selection.selectedMultiple" theme="bootstrap" style="width: 800px;"> \ <ui-select-match placeholder="Pick one...">{{$item.name}} <{{$item.email}}></ui-select-match> \ <ui-select-choices repeat="person.email as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select> \ ' ); // var el2 = compileTemplate('<span class="resultDiv" ng-bind="selection.selectedMultiple"></span>'); scope.selection.selectedMultiple.push("nicole@email.com"); scope.$digest(); scope.$digest(); //2nd $digest needed when using angular 1.3.0-rc.1+, might be related with the fact that the value is an array expect(el.find('.ui-select-match-item [uis-transclude-append]:not(.ng-hide)').text()) .toBe("Wladimir <wladimir@email.com>Samantha <samantha@email.com>Nicole <nicole@email.com>"); }); it('should support multiple="multiple" attribute', function() { var el = compileTemplate( '<ui-select multiple="multiple" ng-model="selection.selectedMultiple" theme="bootstrap" style="width: 800px;"> \ <ui-select-match placeholder="Pick one...">{{$item.name}} <{{$item.email}}></ui-select-match> \ <ui-select-choices repeat="person.email as person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select> \ ' ); expect(el.scope().$select.multiple).toBe(true); }); }); describe('default configuration via uiSelectConfig', function() { describe('searchEnabled option', function() { function setupWithoutAttr(){ return compileTemplate( '<ui-select ng-model="selection.selected"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); } function setupWithAttr(searchEnabled){ return compileTemplate( '<ui-select ng-model="selection.selected" search-enabled="'+searchEnabled+'"> \ <ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \ <ui-select-choices repeat="person in people | filter: $select.search"> \ <div ng-bind-html="person.name | highlight: $select.search"></div> \ <div ng-bind-html="person.email | highlight: $select.search"></div> \ </ui-select-choices> \ </ui-select>' ); } it('should be true by default', function(){ var el = setupWithoutAttr(); expect(el.scope().$select.searchEnabled).toBe(true); }); it('should disable search if default set to false', function(){ var uiSelectConfig = $injector.get('uiSelectConfig'); uiSelectConfig.searchEnabled = false; var el = setupWithoutAttr(); expect(el.scope().$select.searchEnabled).not.toBe(true); }); it('should be overridden by inline option search-enabled=true', function(){ var uiSelectConfig = $injector.get('uiSelectConfig'); uiSelectConfig.searchEnabled = false; var el = setupWithAttr(true); expect(el.scope().$select.searchEnabled).toBe(true); }); it('should be overridden by inline option search-enabled=false', function(){ var uiSelectConfig = $injector.get('uiSelectConfig'); uiSelectConfig.searchEnabled = true; var el = setupWithAttr(false); expect(el.scope().$select.searchEnabled).not.toBe(true); }); }); }); describe('accessibility', function() { it('should have baseTitle in scope', function() { expect(createUiSelect().scope().$select.baseTitle).toBe('Select box'); expect(createUiSelect().scope().$select.focusserTitle).toBe('Select box focus'); expect(createUiSelect({ title: 'Choose a person' }).scope().$select.baseTitle).toBe('Choose a person'); expect(createUiSelect({ title: 'Choose a person' }).scope().$select.focusserTitle).toBe('Choose a person focus'); }); it('should have aria-label on all input and button elements', function() { checkTheme(); checkTheme('select2'); checkTheme('selectize'); checkTheme('bootstrap'); function checkTheme(theme) { var el = createUiSelect({ theme: theme}); checkElements(el.find('input')); checkElements(el.find('button')); function checkElements(els) { for (var i = 0; i < els.length; i++) { expect(els[i].attributes['aria-label']).toBeTruthy(); }; } } }); }); });
[+]
..
[-] select.spec.js
[edit]
[-] helpers.js
[edit]