UNPKG

angular-material-npfixed

Version:

The Angular Material project is an implementation of Material Design in Angular.js. This project provides a set of reusable, well-tested, and accessible Material Design UI components. Angular Material is supported internally at Google by the Angular.js, M

805 lines (622 loc) 24.8 kB
describe('md-slider', function() { var $compile, $timeout, $log, $mdConstant, pageScope; beforeEach(module('ngAria')); beforeEach(module('material.components.slider')); beforeEach(inject(function($injector) { var $rootScope = $injector.get('$rootScope'); pageScope = $rootScope.$new(); $compile = $injector.get('$compile'); $timeout = $injector.get('$timeout'); $mdConstant = $injector.get('$mdConstant'); $log = $injector.get('$log'); })); function setup(attrs, dimensions) { var slider; slider = $compile('<md-slider ' + (attrs || '') + '>')(pageScope); spyOn( slider[0].querySelector('.md-track-container'), 'getBoundingClientRect' ).and.returnValue(angular.extend({ width: 100, height: 100, left: 0, right: 0, bottom: 0, top: 0 }, dimensions || {})); return slider; } function setupContainer(attrs, sliderAttrs) { return $compile('<md-slider-container ' + (attrs || '') + '>' + '<md-slider ' + (sliderAttrs || '') + '></md-slider>' + '</md-slider-container>')(pageScope); } function getWrapper(slider) { return angular.element(slider[0].querySelector('.md-slider-wrapper')); } it('should not set model below the min', function() { var slider = setup('ng-model="value" min="0" max="100"'); pageScope.$apply('value = -50'); expect(slider.attr('aria-valuenow')).toEqual('0'); }); it('should not set model above the max', function() { var slider = setup('ng-model="value" min="0" max="100"'); pageScope.$apply('value = 150'); expect(slider.attr('aria-valuenow')).toEqual('100'); }); it('should set model on press', function() { var slider = setup('ng-model="value" min="0" max="100"'); pageScope.$apply('value = 50'); var wrapper = getWrapper(slider); wrapper.triggerHandler({type: '$md.pressdown', pointer: { x: 30 }}); wrapper.triggerHandler({type: '$md.dragstart', pointer: { x: 30 }}); $timeout.flush(); expect(pageScope.value).toBe(30); // When going past max, it should clamp to max. wrapper.triggerHandler({type: '$md.drag', pointer: { x: 150 }}); $timeout.flush(); expect(pageScope.value).toBe(100); wrapper.triggerHandler({type: '$md.drag', pointer: { x: 50 }}); $timeout.flush(); expect(pageScope.value).toBe(50); }); it('should increment model on right arrow', function() { var slider = setup('min="100" max="104" step="2" ng-model="model"'); pageScope.$apply('model = 100'); var wrapper = getWrapper(slider); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.RIGHT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(102); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.RIGHT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(104); // Stays at max. wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.RIGHT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(104); }); it('should decrement model on left arrow', function() { var slider = setup('min="100" max="104" step="2" ng-model="model"'); pageScope.$apply('model = 104'); var wrapper = getWrapper(slider); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.LEFT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(102); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.LEFT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(100); // Stays at min. wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.LEFT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(100); }); it('should update the thumb text', function() { var slider = setup('ng-model="value" md-discrete min="0" max="100" step="1"'); var wrapper = getWrapper(slider); pageScope.$apply('value = 30'); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('30'); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.LEFT_ARROW }); $timeout.flush(); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('29'); wrapper.triggerHandler({type: '$md.pressdown', pointer: { x: 30 }}); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('30'); wrapper.triggerHandler({type: '$md.dragstart', pointer: { x: 31 }}); wrapper.triggerHandler({type: '$md.drag', pointer: { x: 31 }}); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('31'); }); it('should update the thumb text with the model value when using ng-change', function() { pageScope.stayAt50 = function () { pageScope.value = 50; }; var slider = setup('ng-model="value" min="0" max="100" ng-change="stayAt50()"'); var wrapper = getWrapper(slider); wrapper.triggerHandler({type: '$md.pressdown', pointer: { x: 30 }}); $timeout.flush(); expect(pageScope.value).toBe(50); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('50'); }); it('should call $log.warn if aria-label isn\'t provided', function() { spyOn($log, "warn"); setup('min="100" max="104" step="2" ng-model="model"'); expect($log.warn).toHaveBeenCalled(); }); it('should not call $log.warn if aria-label is provided', function() { spyOn($log, "warn"); setup('aria-label="banana" min="100" max="104" step="2" ng-model="model"'); expect($log.warn).not.toHaveBeenCalled(); }); it('should add aria attributes', function() { var slider = setup('min="100" max="104" step="2" ng-model="model"'); var wrapper = getWrapper(slider); pageScope.$apply('model = 102'); expect(wrapper.attr('role')).toEqual('slider'); expect(slider.attr('aria-valuemin')).toEqual('100'); expect(slider.attr('aria-valuemax')).toEqual('104'); expect(slider.attr('aria-valuenow')).toEqual('102'); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.LEFT_ARROW }); $timeout.flush(); expect(slider.attr('aria-valuenow')).toEqual('100'); }); it('should ignore pressdown events when disabled', function() { pageScope.isDisabled = true; var slider = setup('ng-disabled="isDisabled"'); var wrapper = getWrapper(slider); pageScope.$digest(); // Doesn't add active class on pressdown when disabled wrapper.triggerHandler({ type: '$md.pressdown', pointer: {} }); expect(slider).not.toHaveClass('md-active'); // Doesn't remove active class up on pressup when disabled slider.addClass('md-active'); wrapper.triggerHandler({ type: '$md.pressup', pointer: {} }); expect(slider).toHaveClass('md-active'); }); it('should disable via the `disabled` attribute', function() { var slider = setup('disabled'); var wrapper = getWrapper(slider); pageScope.$digest(); // Check for disabled state by triggering the pressdown handler and asserting that // the slider is not active. wrapper.triggerHandler({ type: '$md.pressdown', pointer: {} }); expect(slider).not.toHaveClass('md-active'); }); it('should add active class on pressdown and remove on blur', function() { var slider = setup(); var wrapper = getWrapper(slider); expect(slider).not.toHaveClass('md-active'); wrapper.triggerHandler({ type: '$md.pressdown', pointer: {} }); expect(slider).toHaveClass('md-active'); wrapper.triggerHandler({ type: 'blur', pointer: {} }); expect(slider).not.toHaveClass('md-active'); }); it('should add md-min class only when at min value', function() { var slider = setup('ng-model="model" min="0" max="30"'); var wrapper = getWrapper(slider); pageScope.$apply('model = 0'); expect(slider).toHaveClass('md-min'); wrapper.triggerHandler({type: '$md.dragstart', pointer: {x: 0}}); wrapper.triggerHandler({type: '$md.drag', pointer: {x: 10}}); $timeout.flush(); expect(slider).not.toHaveClass('md-min'); }); it('should add md-max class only when at max value', function() { var slider = setup('ng-model="model" min="0" max="30"'); var wrapper = getWrapper(slider); pageScope.$apply('model = 30'); expect(slider).toHaveClass('md-max'); wrapper.triggerHandler({type: '$md.dragstart', pointer: {x: 30}}); wrapper.triggerHandler({type: '$md.drag', pointer: {x: 10}}); $timeout.flush(); expect(slider).not.toHaveClass('md-max'); }); it('should increment at a predictable step', function() { buildSlider(0.1, 0, 1).drag({x:70}); expect(pageScope.value).toBe(0.7); buildSlider(0.25, 0, 1).drag({x:45}); expect(pageScope.value).toBe(0.5); buildSlider(0.25, 0, 1).drag({x:35}); expect(pageScope.value).toBe(0.25); buildSlider(1, 0, 100).drag({x:90}); expect(pageScope.value).toBe(90); buildSlider(20, 5, 45).drag({x:50}); expect(pageScope.value).toBe(25); function buildSlider(step, min, max) { var slider = setup('ng-model="value" min="' + min + '" max="' + max + '" step="' + step + '"'); pageScope.$apply('value = 0.5'); var wrapper = getWrapper(slider); return { drag : function simulateDrag(drag) { wrapper.triggerHandler({type: '$md.pressdown', pointer: drag }); wrapper.triggerHandler({type: '$md.dragstart', pointer: drag }); $timeout.flush(); } }; } }); describe('vertical', function () { it('should set model on press', function() { var slider = setup('md-vertical ng-model="value" min="0" max="100"'); pageScope.$apply('value = 50'); var wrapper = getWrapper(slider); wrapper.triggerHandler({type: '$md.pressdown', pointer: { y: 70 }}); wrapper.triggerHandler({type: '$md.dragstart', pointer: { y: 70 }}); $timeout.flush(); expect(pageScope.value).toBe(30); // When going past max, it should clamp to max. wrapper.triggerHandler({type: '$md.drag', pointer: { y: 0 }}); $timeout.flush(); expect(pageScope.value).toBe(100); wrapper.triggerHandler({type: '$md.drag', pointer: { y: 50 }}); $timeout.flush(); expect(pageScope.value).toBe(50); }); it('should increment model on up arrow', function() { var slider = setup('md-vertical min="100" max="104" step="2" ng-model="model"'); pageScope.$apply('model = 100'); var wrapper = getWrapper(slider); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.UP_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(102); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.UP_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(104); // Stays at max. wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.UP_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(104); }); it('should decrement model on down arrow', function() { var slider = setup('md-vertical min="100" max="104" step="2" ng-model="model"'); pageScope.$apply('model = 104'); var wrapper = getWrapper(slider); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.DOWN_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(102); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.DOWN_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(100); // Stays at min. wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.DOWN_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(100); }); it('should update the thumb text', function() { var slider = setup('md-vertical ng-model="value" md-discrete min="0" max="100" step="1"'); var wrapper = getWrapper(slider); pageScope.$apply('value = 30'); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('30'); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.DOWN_ARROW }); $timeout.flush(); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('29'); wrapper.triggerHandler({type: '$md.pressdown', pointer: { y: 70 }}); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('30'); wrapper.triggerHandler({type: '$md.dragstart', pointer: { y: 93 }}); wrapper.triggerHandler({type: '$md.drag', pointer: { y: 93 }}); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('7'); }); it('should add md-min class only when at min value', function() { var slider = setup('md-vertical ng-model="model" min="0" max="30"'); var wrapper = getWrapper(slider); pageScope.$apply('model = 0'); expect(slider).toHaveClass('md-min'); wrapper.triggerHandler({type: '$md.dragstart', pointer: {y: 0}}); wrapper.triggerHandler({type: '$md.drag', pointer: {y: 10}}); $timeout.flush(); expect(slider).not.toHaveClass('md-min'); }); it('should add md-max class only when at max value', function() { var slider = setup('md-vertical ng-model="model" min="0" max="30"'); var wrapper = getWrapper(slider); pageScope.$apply('model = 30'); expect(slider).toHaveClass('md-max'); wrapper.triggerHandler({type: '$md.dragstart', pointer: {y: 30}}); wrapper.triggerHandler({type: '$md.drag', pointer: {y: 10}}); $timeout.flush(); expect(slider).not.toHaveClass('md-max'); }); it('should increment at a predictable step', function() { buildSlider(0.1, 0, 1).drag({y:30}); expect(pageScope.value).toBe(0.7); buildSlider(0.25, 0, 1).drag({y:45}); expect(pageScope.value).toBe(0.5); buildSlider(0.25, 0, 1).drag({y:75}); expect(pageScope.value).toBe(0.25); buildSlider(1, 0, 100).drag({y:10}); expect(pageScope.value).toBe(90); buildSlider(20, 5, 45).drag({y:50}); expect(pageScope.value).toBe(25); function buildSlider(step, min, max) { var slider = setup('md-vertical ng-model="value" min="' + min + '" max="' + max + '" step="' + step + '"'); pageScope.$apply('value = 0.5'); var wrapper = getWrapper(slider); return { drag : function simulateDrag(drag) { wrapper.triggerHandler({type: '$md.pressdown', pointer: drag }); wrapper.triggerHandler({type: '$md.dragstart', pointer: drag }); $timeout.flush(); } }; } }); }); describe('slider container', function () { it('should have `._md` class indicator', inject(function() { var element = setupContainer('disabled="disabled"'); expect(element.hasClass('_md')).toBe(true); })); it('should disable via the `disabled` attribute', function() { var container = setupContainer('disabled="disabled"'); var slider = angular.element(container[0].querySelector('md-slider')); var wrapper = getWrapper(container); // Check for disabled state by triggering the pressdown handler and asserting that // the slider is not active. wrapper.triggerHandler({ type: '$md.pressdown', pointer: {} }); expect(slider).not.toHaveClass('md-active'); }); it('should disable via the `ngDisabled` attribute', function() { var container = setupContainer('ng-disabled="isDisabled"'); var slider = angular.element(container[0].querySelector('md-slider')); var wrapper = getWrapper(container); // Check for disabled state by triggering the pressdown handler and asserting that // the slider is not active. wrapper.triggerHandler({ type: '$md.pressdown', pointer: {} }); expect(slider).toHaveClass('md-active'); // Removing focus from the slider wrapper.triggerHandler({ type: 'blur', pointer: {} }); pageScope.$apply('isDisabled = true'); wrapper.triggerHandler({ type: '$md.pressdown', pointer: {} }); expect(slider).not.toHaveClass('md-active'); }); it('should disable related inputs', inject(function($compile) { var container = setupContainer('ng-disabled="isDisabled"'); var slider = angular.element(container[0].querySelector('md-slider')); var inputContainer = $compile('<md-input-container><input /></md-input-container>')(pageScope); var input = angular.element(inputContainer[0].querySelector('input')); container.append(input); expect(input.attr('disabled')).toEqual(undefined); pageScope.$apply('isDisabled = true'); expect(input.attr('disabled')).toEqual('disabled'); })); }); describe('invert', function () { it('should set model on press', function() { var slider = setup('md-vertical md-invert ng-model="value" min="0" max="100"'); pageScope.$apply('value = 50'); var wrapper = getWrapper(slider); wrapper.triggerHandler({type: '$md.pressdown', pointer: { y: 70 }}); wrapper.triggerHandler({type: '$md.dragstart', pointer: { y: 70 }}); $timeout.flush(); expect(pageScope.value).toBe(70); // When going past max, it should clamp to max. wrapper.triggerHandler({type: '$md.drag', pointer: { y: 0 }}); $timeout.flush(); expect(pageScope.value).toBe(0); wrapper.triggerHandler({type: '$md.drag', pointer: { y: 50 }}); $timeout.flush(); expect(pageScope.value).toBe(50); }); it('should decrement model on up arrow', function() { var slider = setup('md-vertical md-invert min="100" max="104" step="2" ng-model="model"'); pageScope.$apply('model = 104'); var wrapper = getWrapper(slider); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.UP_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(102); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.UP_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(100); // Stays at min. wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.UP_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(100); }); it('should increment model on down arrow', function() { var slider = setup('md-vertical md-invert min="100" max="104" step="2" ng-model="model"'); pageScope.$apply('model = 100'); var wrapper = getWrapper(slider); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.DOWN_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(102); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.DOWN_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(104); // Stays at max. wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.DOWN_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(104); }); it('should update the thumb text', function() { var slider = setup('md-vertical md-invert ng-model="value" md-discrete min="0" max="100" step="1"'); var wrapper = getWrapper(slider); pageScope.$apply('value = 30'); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('30'); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.DOWN_ARROW }); $timeout.flush(); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('31'); wrapper.triggerHandler({type: '$md.pressdown', pointer: { y: 70 }}); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('70'); wrapper.triggerHandler({type: '$md.dragstart', pointer: { y: 93 }}); wrapper.triggerHandler({type: '$md.drag', pointer: { y: 93 }}); expect(slider[0].querySelector('.md-thumb-text').textContent).toBe('93'); }); it('should add md-min class only when at min value', function() { var slider = setup('md-vertical md-invert ng-model="model" min="0" max="30"'); var wrapper = getWrapper(slider); pageScope.$apply('model = 0'); expect(slider).toHaveClass('md-min'); wrapper.triggerHandler({type: '$md.dragstart', pointer: {y: 0}}); wrapper.triggerHandler({type: '$md.drag', pointer: {y: 10}}); $timeout.flush(); expect(slider).not.toHaveClass('md-min'); }); it('should add md-max class only when at max value', function() { var slider = setup('md-vertical md-invert ng-model="model" min="0" max="30"'); var wrapper = getWrapper(slider); pageScope.$apply('model = 30'); expect(slider).toHaveClass('md-max'); wrapper.triggerHandler({type: '$md.dragstart', pointer: {y: 30}}); wrapper.triggerHandler({type: '$md.drag', pointer: {y: 10}}); $timeout.flush(); expect(slider).not.toHaveClass('md-max'); }); it('should increment at a predictable step', function() { buildSlider(0.1, 0, 1).drag({y:30}); expect(pageScope.value).toBe(0.3); buildSlider(0.25, 0, 1).drag({y:45}); expect(pageScope.value).toBe(0.5); buildSlider(0.25, 0, 1).drag({y:75}); expect(pageScope.value).toBe(0.75); buildSlider(1, 0, 100).drag({y:10}); expect(pageScope.value).toBe(10); buildSlider(20, 5, 45).drag({y:50}); expect(pageScope.value).toBe(25); function buildSlider(step, min, max) { var slider = setup('md-vertical md-invert ng-model="value" min="' + min + '" max="' + max + '" step="' + step + '"'); pageScope.$apply('value = 0.5'); var wrapper = getWrapper(slider); return { drag : function simulateDrag(drag) { wrapper.triggerHandler({type: '$md.pressdown', pointer: drag }); wrapper.triggerHandler({type: '$md.dragstart', pointer: drag }); $timeout.flush(); } }; } }); it('should increment model on left arrow', function() { var slider = setup('md-invert min="100" max="104" step="2" ng-model="model"'); pageScope.$apply('model = 100'); var wrapper = getWrapper(slider); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.LEFT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(102); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.LEFT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(104); // Stays at max. wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.LEFT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(104); }); it('should decrement model on right arrow', function() { var slider = setup('md-invert min="100" max="104" step="2" ng-model="model"'); pageScope.$apply('model = 104'); var wrapper = getWrapper(slider); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.RIGHT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(102); wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.RIGHT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(100); // Stays at min. wrapper.triggerHandler({ type: 'keydown', keyCode: $mdConstant.KEY_CODE.RIGHT_ARROW }); $timeout.flush(); expect(pageScope.model).toBe(100); }); }); it('should set a default tabindex', function() { var slider = setup(); var wrapper = getWrapper(slider); expect(wrapper.attr('tabindex')).toBe('0'); }); it('should set a -1 tabindex to disabled slider', function() { var slider = setup('ng-disabled="isDisabled"'); var wrapper = getWrapper(slider); expect(wrapper.attr('tabindex')).toBe('-1'); }); it('should not overwrite tabindex attribute', function() { var slider = setup('tabindex="2"'); var wrapper = getWrapper(slider); expect(wrapper.attr('tabindex')).toBe('2'); }); });