|
| 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