|
| 1 | +// When constructing a Date, the month is zero-based. This can be confusing, since people are |
| 2 | +// used to seeing them one-based. So we create these aliases to make reading the tests easier. |
| 3 | +var JAN = 0, FEB = 1, MAR = 2, APR = 3, MAY = 4, JUN = 5, JUL = 6, AUG = 7, SEP = 8, OCT = 9, |
| 4 | + NOV = 10, DEC = 11; |
| 5 | + |
| 6 | +var initialDate = new Date(2015, FEB, 15); |
| 7 | + |
| 8 | +var ngElement, element, scope, pageScope, controller; |
| 9 | +var $compile, $timeout, $$rAF, $animate, $window, keyCodes, dateUtil, dateLocale; |
| 10 | + |
| 11 | +var DATEPICKER_TEMPLATE = |
| 12 | + '<md-datepicker name="birthday" ' + |
| 13 | + 'md-max-date="maxDate" ' + |
| 14 | + 'md-min-date="minDate" ' + |
| 15 | + 'md-date-filter="dateFilter" ' + |
| 16 | + 'md-month-filter="monthFilter" ' + |
| 17 | + 'ng-model="myDate" ' + |
| 18 | + 'ng-change="dateChangedHandler()" ' + |
| 19 | + 'ng-focus="focusHandler()" ' + |
| 20 | + 'ng-blur="blurHandler()" ' + |
| 21 | + 'ng-required="isRequired" ' + |
| 22 | + 'ng-disabled="isDisabled">' + |
| 23 | + '</md-datepicker>'; |
| 24 | + |
| 25 | +/** |
| 26 | + * Compile and link the given template and store values for element, scope, and controller. |
| 27 | + * @param {string} template |
| 28 | + * @returns {JQLite} The root compiled element. |
| 29 | + */ |
| 30 | +function createDatepickerInstance(template) { |
| 31 | + var outputElement = $compile(template)(pageScope); |
| 32 | + pageScope.$apply(); |
| 33 | + |
| 34 | + ngElement = outputElement[0].tagName === 'MD-DATEPICKER' ? |
| 35 | + outputElement : outputElement.find('md-datepicker'); |
| 36 | + element = ngElement[0]; |
| 37 | + scope = ngElement.isolateScope(); |
| 38 | + controller = ngElement.controller('mdDatepicker'); |
| 39 | + |
| 40 | + return outputElement; |
| 41 | +} |
| 42 | + |
| 43 | +/** Populates the inputElement with a value and triggers the input events. */ |
| 44 | +function populateInputElement(inputString) { |
| 45 | + controller.ngInputElement.val(inputString).triggerHandler('input'); |
| 46 | + $timeout.flush(); |
| 47 | + pageScope.$apply(); |
| 48 | +} |
1 | 49 |
|
2 | 50 | describe('md-datepicker', function() { |
3 | | - // When constructing a Date, the month is zero-based. This can be confusing, since people are |
4 | | - // used to seeing them one-based. So we create these aliases to make reading the tests easier. |
5 | | - var JAN = 0, FEB = 1, MAR = 2, APR = 3, MAY = 4, JUN = 5, JUL = 6, AUG = 7, SEP = 8, OCT = 9, |
6 | | - NOV = 10, DEC = 11; |
7 | | - |
8 | | - var initialDate = new Date(2015, FEB, 15); |
9 | | - |
10 | | - var ngElement, element, scope, pageScope, controller; |
11 | | - var $compile, $timeout, $$rAF, $animate, $window, keyCodes, dateUtil, dateLocale; |
12 | | - |
13 | | - var DATEPICKER_TEMPLATE = |
14 | | - '<md-datepicker name="birthday" ' + |
15 | | - 'md-max-date="maxDate" ' + |
16 | | - 'md-min-date="minDate" ' + |
17 | | - 'md-date-filter="dateFilter"' + |
18 | | - 'md-month-filter="monthFilter"' + |
19 | | - 'ng-model="myDate" ' + |
20 | | - 'ng-change="dateChangedHandler()" ' + |
21 | | - 'ng-focus="focusHandler()" ' + |
22 | | - 'ng-blur="blurHandler()" ' + |
23 | | - 'ng-required="isRequired" ' + |
24 | | - 'ng-disabled="isDisabled">' + |
25 | | - '</md-datepicker>'; |
26 | | - |
27 | 51 | beforeEach(module('material.components.datepicker', 'material.components.input', 'ngAnimateMock')); |
28 | 52 |
|
29 | 53 | beforeEach(inject(function($rootScope, $injector) { |
@@ -51,31 +75,6 @@ describe('md-datepicker', function() { |
51 | 75 | ngElement.remove(); |
52 | 76 | }); |
53 | 77 |
|
54 | | - /** |
55 | | - * Compile and link the given template and store values for element, scope, and controller. |
56 | | - * @param {string} template |
57 | | - * @returns {angular.JQLite} The root compiled element. |
58 | | - */ |
59 | | - function createDatepickerInstance(template) { |
60 | | - var outputElement = $compile(template)(pageScope); |
61 | | - pageScope.$apply(); |
62 | | - |
63 | | - ngElement = outputElement[0].tagName == 'MD-DATEPICKER' ? |
64 | | - outputElement : outputElement.find('md-datepicker'); |
65 | | - element = ngElement[0]; |
66 | | - scope = ngElement.isolateScope(); |
67 | | - controller = ngElement.controller('mdDatepicker'); |
68 | | - |
69 | | - return outputElement; |
70 | | - } |
71 | | - |
72 | | - /** Populates the inputElement with a value and triggers the input events. */ |
73 | | - function populateInputElement(inputString) { |
74 | | - controller.ngInputElement.val(inputString).triggerHandler('input'); |
75 | | - $timeout.flush(); |
76 | | - pageScope.$apply(); |
77 | | - } |
78 | | - |
79 | 78 | it('should be the same date object as the initial ng-model', function() { |
80 | 79 | expect(pageScope.myDate).toBe(initialDate); |
81 | 80 | }); |
@@ -591,9 +590,9 @@ describe('md-datepicker', function() { |
591 | 590 | body.removeChild(element); |
592 | 591 | }); |
593 | 592 |
|
594 | | - it('should shink the calendar pane when it would otherwise not fit on the screen', function() { |
| 593 | + it('should shrink the calendar pane when it would otherwise not fit on the screen', function() { |
595 | 594 | // Fake the window being very narrow so that the calendar pane won't fit on-screen. |
596 | | - controller.$window = {innerWidth: 200, innherHeight: 800}; |
| 595 | + controller.$window = {innerWidth: 200, innerHeight: 800}; |
597 | 596 |
|
598 | 597 | // Open the calendar pane. |
599 | 598 | controller.openCalendarPane({}); |
@@ -893,3 +892,57 @@ describe('md-datepicker', function() { |
893 | 892 | }); |
894 | 893 |
|
895 | 894 | }); |
| 895 | + |
| 896 | +describe('md-datepicker with MomentJS custom formatting', function() { |
| 897 | + beforeEach(module('material.components.datepicker', 'material.components.input', 'ngAnimateMock')); |
| 898 | + |
| 899 | + beforeEach(module(function($mdDateLocaleProvider) { |
| 900 | + $mdDateLocaleProvider.formatDate = function(date) { |
| 901 | + return date ? moment(date).format('M/D') : ''; |
| 902 | + }; |
| 903 | + $mdDateLocaleProvider.parseDate = function(dateString) { |
| 904 | + var m = moment(dateString, 'M/D', true); |
| 905 | + return m.isValid() ? m.toDate() : new Date(NaN); |
| 906 | + }; |
| 907 | + $mdDateLocaleProvider.isDateComplete = function(dateString) { |
| 908 | + dateString = dateString.trim(); |
| 909 | + // Look for two chunks of content (either numbers or text) separated by delimiters. |
| 910 | + var re = /^(([a-zA-Z]{3,}|[0-9]{1,4})([ .,]+|[/-]))([a-zA-Z]{3,}|[0-9]{1,4})/; |
| 911 | + return re.test(dateString); |
| 912 | + }; |
| 913 | + })); |
| 914 | + |
| 915 | + beforeEach(inject(function($rootScope, $injector) { |
| 916 | + $compile = $injector.get('$compile'); |
| 917 | + $timeout = $injector.get('$timeout'); |
| 918 | + |
| 919 | + pageScope = $rootScope.$new(); |
| 920 | + pageScope.myDate = initialDate; |
| 921 | + pageScope.isDisabled = false; |
| 922 | + pageScope.dateChangedHandler = jasmine.createSpy('ng-change handler'); |
| 923 | + |
| 924 | + createDatepickerInstance(DATEPICKER_TEMPLATE); |
| 925 | + controller.closeCalendarPane(); |
| 926 | + })); |
| 927 | + |
| 928 | + afterEach(function() { |
| 929 | + controller.isAttached && controller.closeCalendarPane(); |
| 930 | + pageScope.$destroy(); |
| 931 | + ngElement.remove(); |
| 932 | + }); |
| 933 | + |
| 934 | + it('should update the model value and close the calendar pane', function() { |
| 935 | + var date = new Date(2020, SEP, 1); |
| 936 | + controller.openCalendarPane({ |
| 937 | + target: controller.inputElement |
| 938 | + }); |
| 939 | + scope.$emit('md-calendar-change', date); |
| 940 | + scope.$apply(); |
| 941 | + expect(pageScope.myDate).toEqual(date); |
| 942 | + expect(controller.ngModelCtrl.$modelValue).toEqual(date); |
| 943 | + |
| 944 | + expect(controller.inputElement.value).toEqual('9/1'); |
| 945 | + expect(controller.calendarPaneOpenedFrom).toBe(null); |
| 946 | + expect(controller.isCalendarOpen).toBe(false); |
| 947 | + }); |
| 948 | +}); |
0 commit comments