bootstrap-datepicker 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/.gitignore +7 -0
  2. data/.hgignore +3 -0
  3. data/.hgtags +9 -0
  4. data/.travis.yml +4 -0
  5. data/CHANGELOG.md +89 -0
  6. data/CONTRIBUTING.md +40 -0
  7. data/Gemfile +4 -0
  8. data/Gruntfile.js +165 -0
  9. data/LICENSE +202 -0
  10. data/README.md +24 -0
  11. data/Rakefile +1 -0
  12. data/bootstrap-datepicker.gemspec +26 -0
  13. data/bower.json +9 -0
  14. data/build/build.less +67 -0
  15. data/build/build3.less +71 -0
  16. data/build/build_standalone.less +61 -0
  17. data/build/build_standalone3.less +63 -0
  18. data/composer.json +19 -0
  19. data/css/datepicker.css +509 -0
  20. data/css/datepicker3.css +790 -0
  21. data/docs/Makefile +153 -0
  22. data/docs/REAME.md +8 -0
  23. data/docs/_static/demo_head.png +0 -0
  24. data/docs/conf.py +248 -0
  25. data/docs/events.rst +48 -0
  26. data/docs/i18n.rst +28 -0
  27. data/docs/index.rst +122 -0
  28. data/docs/keyboard.rst +30 -0
  29. data/docs/make.bat +190 -0
  30. data/docs/markup.rst +50 -0
  31. data/docs/methods.rst +156 -0
  32. data/docs/options.rst +191 -0
  33. data/js/bootstrap-datepicker.js +1609 -0
  34. data/js/locales/bootstrap-datepicker.ar.js +15 -0
  35. data/js/locales/bootstrap-datepicker.bg.js +14 -0
  36. data/js/locales/bootstrap-datepicker.ca.js +14 -0
  37. data/js/locales/bootstrap-datepicker.cs.js +15 -0
  38. data/js/locales/bootstrap-datepicker.cy.js +14 -0
  39. data/js/locales/bootstrap-datepicker.da.js +15 -0
  40. data/js/locales/bootstrap-datepicker.de.js +17 -0
  41. data/js/locales/bootstrap-datepicker.el.js +13 -0
  42. data/js/locales/bootstrap-datepicker.es.js +14 -0
  43. data/js/locales/bootstrap-datepicker.et.js +18 -0
  44. data/js/locales/bootstrap-datepicker.fa.js +17 -0
  45. data/js/locales/bootstrap-datepicker.fi.js +16 -0
  46. data/js/locales/bootstrap-datepicker.fr.js +17 -0
  47. data/js/locales/bootstrap-datepicker.gl.js +11 -0
  48. data/js/locales/bootstrap-datepicker.he.js +15 -0
  49. data/js/locales/bootstrap-datepicker.hr.js +13 -0
  50. data/js/locales/bootstrap-datepicker.hu.js +16 -0
  51. data/js/locales/bootstrap-datepicker.id.js +15 -0
  52. data/js/locales/bootstrap-datepicker.is.js +14 -0
  53. data/js/locales/bootstrap-datepicker.it.js +16 -0
  54. data/js/locales/bootstrap-datepicker.ja.js +15 -0
  55. data/js/locales/bootstrap-datepicker.ka.js +17 -0
  56. data/js/locales/bootstrap-datepicker.kk.js +15 -0
  57. data/js/locales/bootstrap-datepicker.kr.js +13 -0
  58. data/js/locales/bootstrap-datepicker.lt.js +16 -0
  59. data/js/locales/bootstrap-datepicker.lv.js +16 -0
  60. data/js/locales/bootstrap-datepicker.mk.js +15 -0
  61. data/js/locales/bootstrap-datepicker.ms.js +14 -0
  62. data/js/locales/bootstrap-datepicker.nb.js +14 -0
  63. data/js/locales/bootstrap-datepicker.nl-BE.js +17 -0
  64. data/js/locales/bootstrap-datepicker.nl.js +14 -0
  65. data/js/locales/bootstrap-datepicker.no.js +16 -0
  66. data/js/locales/bootstrap-datepicker.pl.js +15 -0
  67. data/js/locales/bootstrap-datepicker.pt-BR.js +15 -0
  68. data/js/locales/bootstrap-datepicker.pt.js +16 -0
  69. data/js/locales/bootstrap-datepicker.ro.js +15 -0
  70. data/js/locales/bootstrap-datepicker.rs-latin.js +14 -0
  71. data/js/locales/bootstrap-datepicker.rs.js +14 -0
  72. data/js/locales/bootstrap-datepicker.ru.js +15 -0
  73. data/js/locales/bootstrap-datepicker.sk.js +15 -0
  74. data/js/locales/bootstrap-datepicker.sl.js +14 -0
  75. data/js/locales/bootstrap-datepicker.sq.js +15 -0
  76. data/js/locales/bootstrap-datepicker.sv.js +16 -0
  77. data/js/locales/bootstrap-datepicker.sw.js +15 -0
  78. data/js/locales/bootstrap-datepicker.th.js +14 -0
  79. data/js/locales/bootstrap-datepicker.tr.js +16 -0
  80. data/js/locales/bootstrap-datepicker.ua.js +15 -0
  81. data/js/locales/bootstrap-datepicker.uk.js +14 -0
  82. data/js/locales/bootstrap-datepicker.vi.js +16 -0
  83. data/js/locales/bootstrap-datepicker.zh-CN.js +16 -0
  84. data/js/locales/bootstrap-datepicker.zh-TW.js +17 -0
  85. data/less/datepicker.less +265 -0
  86. data/less/datepicker3.less +252 -0
  87. data/lib/bootstrap-datepicker.rb +11 -0
  88. data/lib/bootstrap-datepicker/version.rb +9 -0
  89. data/package.json +32 -0
  90. data/sass/build_standalone-sass.scss +70 -0
  91. data/sass/datepicker.scss +270 -0
  92. data/test/Readme.md +9 -0
  93. data/test/less_test.js +19 -0
  94. data/test/scss_test.js +19 -0
  95. data/test/support/less.patch +4 -0
  96. data/test/support/scss.patch +493 -0
  97. data/tests/README.md +55 -0
  98. data/tests/_coverage.html +26 -0
  99. data/tests/assets/coverage.js +48 -0
  100. data/tests/assets/jquery-1.7.1.min.js +4 -0
  101. data/tests/assets/mock.js +26 -0
  102. data/tests/assets/qunit-logging.js +29 -0
  103. data/tests/assets/qunit.css +235 -0
  104. data/tests/assets/qunit.js +1669 -0
  105. data/tests/assets/utils.js +21 -0
  106. data/tests/run-qunit.js +157 -0
  107. data/tests/suites/calendar-weeks.js +48 -0
  108. data/tests/suites/component.js +202 -0
  109. data/tests/suites/data-api.js +114 -0
  110. data/tests/suites/events.js +306 -0
  111. data/tests/suites/formats.js +235 -0
  112. data/tests/suites/inline.js +28 -0
  113. data/tests/suites/keyboard_navigation/2011.js +92 -0
  114. data/tests/suites/keyboard_navigation/2012.js +468 -0
  115. data/tests/suites/keyboard_navigation/all.js +26 -0
  116. data/tests/suites/methods.js +78 -0
  117. data/tests/suites/mouse_navigation/2011.js +66 -0
  118. data/tests/suites/mouse_navigation/2012.js +251 -0
  119. data/tests/suites/mouse_navigation/all.js +33 -0
  120. data/tests/suites/noconflict.js +20 -0
  121. data/tests/suites/options.js +648 -0
  122. data/tests/tests.html +50 -0
  123. metadata +240 -0
@@ -0,0 +1,306 @@
1
+ module('Events', {
2
+ setup: function(){
3
+ this.input = $('<input type="text" value="31-03-2011">')
4
+ .appendTo('#qunit-fixture')
5
+ .datepicker({format: "dd-mm-yyyy"})
6
+ .focus(); // Activate for visibility checks
7
+ this.dp = this.input.data('datepicker')
8
+ this.picker = this.dp.picker;
9
+ },
10
+ teardown: function(){
11
+ this.picker.remove();
12
+ }
13
+ });
14
+
15
+ test('Selecting a year from decade view triggers changeYear', function(){
16
+ var target,
17
+ triggered = 0;
18
+
19
+ this.input.on('changeYear', function(){
20
+ triggered++;
21
+ });
22
+
23
+ equal(this.dp.viewMode, 0);
24
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
25
+ ok(target.is(':visible'), 'View switcher is visible');
26
+
27
+ target.click();
28
+ ok(this.picker.find('.datepicker-months').is(':visible'), 'Month picker is visible');
29
+ equal(this.dp.viewMode, 1);
30
+ // Not modified when switching modes
31
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
32
+ datesEqual(this.dp.dates[0], UTCDate(2011, 2, 31));
33
+
34
+ target = this.picker.find('.datepicker-months thead th.datepicker-switch');
35
+ ok(target.is(':visible'), 'View switcher is visible');
36
+
37
+ target.click();
38
+ ok(this.picker.find('.datepicker-years').is(':visible'), 'Year picker is visible');
39
+ equal(this.dp.viewMode, 2);
40
+ // Not modified when switching modes
41
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
42
+ datesEqual(this.dp.dates[0], UTCDate(2011, 2, 31));
43
+
44
+ // Change years to test internal state changes
45
+ target = this.picker.find('.datepicker-years tbody span:contains(2010)');
46
+ target.click();
47
+ equal(this.dp.viewMode, 1);
48
+ // Only viewDate modified
49
+ datesEqual(this.dp.viewDate, UTCDate(2010, 2, 1));
50
+ datesEqual(this.dp.dates[0], UTCDate(2011, 2, 31));
51
+ equal(triggered, 1);
52
+ });
53
+
54
+ test('Navigating forward/backward from month view triggers changeYear', function(){
55
+ var target,
56
+ triggered = 0;
57
+
58
+ this.input.on('changeYear', function(){
59
+ triggered++;
60
+ });
61
+
62
+ equal(this.dp.viewMode, 0);
63
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
64
+ ok(target.is(':visible'), 'View switcher is visible');
65
+
66
+ target.click();
67
+ ok(this.picker.find('.datepicker-months').is(':visible'), 'Month picker is visible');
68
+ equal(this.dp.viewMode, 1);
69
+
70
+ target = this.picker.find('.datepicker-months thead th.prev');
71
+ ok(target.is(':visible'), 'Prev switcher is visible');
72
+
73
+ target.click();
74
+ ok(this.picker.find('.datepicker-months').is(':visible'), 'Month picker is visible');
75
+ equal(triggered, 1);
76
+
77
+ target = this.picker.find('.datepicker-months thead th.next');
78
+ ok(target.is(':visible'), 'Next switcher is visible');
79
+
80
+ target.click();
81
+ ok(this.picker.find('.datepicker-months').is(':visible'), 'Month picker is visible');
82
+ equal(triggered, 2);
83
+ });
84
+
85
+ test('Selecting a month from year view triggers changeMonth', function(){
86
+ var target,
87
+ triggered = 0;
88
+
89
+ this.input.on('changeMonth', function(){
90
+ triggered++;
91
+ });
92
+
93
+ equal(this.dp.viewMode, 0);
94
+ target = this.picker.find('.datepicker-days thead th.datepicker-switch');
95
+ ok(target.is(':visible'), 'View switcher is visible');
96
+
97
+ target.click();
98
+ ok(this.picker.find('.datepicker-months').is(':visible'), 'Month picker is visible');
99
+ equal(this.dp.viewMode, 1);
100
+ // Not modified when switching modes
101
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
102
+ datesEqual(this.dp.dates[0], UTCDate(2011, 2, 31));
103
+
104
+ target = this.picker.find('.datepicker-months tbody span:contains(Apr)');
105
+ target.click();
106
+ equal(this.dp.viewMode, 0);
107
+ // Only viewDate modified
108
+ datesEqual(this.dp.viewDate, UTCDate(2011, 3, 1));
109
+ datesEqual(this.dp.dates[0], UTCDate(2011, 2, 31));
110
+ equal(triggered, 1);
111
+ });
112
+
113
+ test('Navigating forward/backward from month view triggers changeMonth', function(){
114
+ var target,
115
+ triggered = 0;
116
+
117
+ this.input.on('changeMonth', function(){
118
+ triggered++;
119
+ });
120
+
121
+ equal(this.dp.viewMode, 0);
122
+ target = this.picker.find('.datepicker-days thead th.prev');
123
+ ok(target.is(':visible'), 'Prev switcher is visible');
124
+
125
+ target.click();
126
+ ok(this.picker.find('.datepicker-days').is(':visible'), 'Day picker is visible');
127
+ equal(triggered, 1);
128
+
129
+ target = this.picker.find('.datepicker-days thead th.next');
130
+ ok(target.is(':visible'), 'Next switcher is visible');
131
+
132
+ target.click();
133
+ ok(this.picker.find('.datepicker-days').is(':visible'), 'Day picker is visible');
134
+ equal(triggered, 2);
135
+ });
136
+
137
+ test('format() returns a formatted date string', function(){
138
+ var target,
139
+ error, out;
140
+
141
+ this.input.on('changeDate', function(e){
142
+ try{
143
+ out = e.format();
144
+ }
145
+ catch(e){
146
+ error = e;
147
+ }
148
+ });
149
+
150
+ equal(this.dp.viewMode, 0);
151
+ target = this.picker.find('.datepicker-days tbody td:nth(15)');
152
+ target.click();
153
+
154
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 14));
155
+ datesEqual(this.dp.dates[0], UTCDate(2011, 2, 14));
156
+ equal(error, undefined)
157
+ equal(out, '14-03-2011');
158
+ });
159
+
160
+ test('format(altformat) returns a formatted date string', function(){
161
+ var target,
162
+ error, out;
163
+
164
+ this.input.on('changeDate', function(e){
165
+ try{
166
+ out = e.format('m/d/yy');
167
+ }
168
+ catch(e){
169
+ error = e;
170
+ }
171
+ });
172
+
173
+ equal(this.dp.viewMode, 0);
174
+ target = this.picker.find('.datepicker-days tbody td:nth(15)');
175
+ target.click();
176
+
177
+ datesEqual(this.dp.viewDate, UTCDate(2011, 2, 14));
178
+ datesEqual(this.dp.dates[0], UTCDate(2011, 2, 14));
179
+ equal(error, undefined)
180
+ equal(out, '3/14/11');
181
+ });
182
+
183
+ test('format(ix) returns a formatted date string of the ix\'th date selected', function(){
184
+ var target,
185
+ error, out;
186
+
187
+ this.dp._process_options({multidate: true});
188
+
189
+ this.input.on('changeDate', function(e){
190
+ try{
191
+ out = e.format(2);
192
+ }
193
+ catch(e){
194
+ error = e;
195
+ }
196
+ });
197
+
198
+ target = this.picker.find('.datepicker-days tbody td:nth(7)');
199
+ equal(target.text(), '6'); // Mar 6
200
+ target.click();
201
+
202
+ target = this.picker.find('.datepicker-days tbody td:nth(15)');
203
+ equal(target.text(), '14'); // Mar 16
204
+ target.click();
205
+
206
+ equal(this.dp.dates.length, 3);
207
+
208
+ equal(error, undefined);
209
+ equal(out, '14-03-2011');
210
+ });
211
+
212
+ test('format(ix, altformat) returns a formatted date string', function(){
213
+ var target,
214
+ error, out;
215
+
216
+ this.dp._process_options({multidate: true});
217
+
218
+ this.input.on('changeDate', function(e){
219
+ try{
220
+ out = e.format(2, 'm/d/yy');
221
+ }
222
+ catch(e){
223
+ error = e;
224
+ }
225
+ });
226
+
227
+ target = this.picker.find('.datepicker-days tbody td:nth(7)');
228
+ equal(target.text(), '6'); // Mar 6
229
+ target.click();
230
+
231
+ target = this.picker.find('.datepicker-days tbody td:nth(15)');
232
+ equal(target.text(), '14'); // Mar 16
233
+ target.click();
234
+
235
+ equal(this.dp.dates.length, 3);
236
+
237
+ equal(error, undefined);
238
+ equal(out, '3/14/11');
239
+ });
240
+
241
+ test('Clear button: triggers change and changeDate events', function(){
242
+ this.input = $('<input type="text" value="31-03-2011">')
243
+ .appendTo('#qunit-fixture')
244
+ .datepicker({
245
+ format: "dd-mm-yyyy",
246
+ clearBtn: true
247
+ })
248
+ .focus(); // Activate for visibility checks
249
+ this.dp = this.input.data('datepicker');
250
+ this.picker = this.dp.picker;
251
+
252
+ var target,
253
+ triggered_change = 0,
254
+ triggered_changeDate = 0;
255
+
256
+ this.input.on({
257
+ changeDate: function(){
258
+ triggered_changeDate++;
259
+ },
260
+ change: function(){
261
+ triggered_change++;
262
+ }
263
+ });
264
+
265
+ this.input.focus();
266
+ ok(this.picker.find('.datepicker-days').is(':visible'), 'Days view visible');
267
+ ok(this.picker.find('.datepicker-days tfoot .clear').is(':visible'), 'Clear button visible');
268
+
269
+ target = this.picker.find('.datepicker-days tfoot .clear');
270
+ target.click();
271
+
272
+ equal(triggered_change, 1);
273
+ equal(triggered_changeDate, 1);
274
+ });
275
+
276
+ test('setDate: triggers change and changeDate events', function(){
277
+ this.input = $('<input type="text" value="31-03-2011">')
278
+ .appendTo('#qunit-fixture')
279
+ .datepicker({
280
+ format: "dd-mm-yyyy"
281
+ })
282
+ .focus(); // Activate for visibility checks
283
+ this.dp = this.input.data('datepicker');
284
+ this.picker = this.dp.picker;
285
+
286
+ var target,
287
+ triggered_change = 0,
288
+ triggered_changeDate = 0;
289
+
290
+ this.input.on({
291
+ changeDate: function(){
292
+ triggered_changeDate++;
293
+ },
294
+ change: function(){
295
+ triggered_change++;
296
+ }
297
+ });
298
+
299
+ this.input.focus();
300
+ ok(this.picker.find('.datepicker-days').is(':visible'), 'Days view visible');
301
+
302
+ this.dp.setDate(new Date(2011, 2, 5));
303
+
304
+ equal(triggered_change, 2);
305
+ equal(triggered_changeDate, 1);
306
+ });
@@ -0,0 +1,235 @@
1
+ module('Formats', {
2
+ setup: function(){
3
+ this.input = $('<input type="text">').appendTo('#qunit-fixture');
4
+ this.date = UTCDate(2012, 2, 15, 0, 0, 0, 0); // March 15, 2012
5
+ },
6
+ teardown: function(){
7
+ this.input.data('datepicker').picker.remove();
8
+ }
9
+ });
10
+
11
+ test('d: Day of month, no leading zero.', function(){
12
+ this.input
13
+ .val('2012-03-05')
14
+ .datepicker({format: 'yyyy-mm-d'})
15
+ .datepicker('setValue');
16
+ equal(this.input.val().split('-')[2], '5');
17
+ });
18
+
19
+ test('dd: Day of month, leading zero.', function(){
20
+ this.input
21
+ .val('2012-03-5')
22
+ .datepicker({format: 'yyyy-mm-dd'})
23
+ .datepicker('setValue');
24
+ equal(this.input.val().split('-')[2], '05');
25
+ });
26
+
27
+ test('D: Day of week, short.', function(){
28
+ this.input
29
+ .val('2012-03-05')
30
+ .datepicker({format: 'yyyy-mm-dd-D'})
31
+ .datepicker('setValue');
32
+ equal(this.input.val().split('-')[3], 'Mon');
33
+ });
34
+
35
+ test('DD: Day of week, long.', function(){
36
+ this.input
37
+ .val('2012-03-05')
38
+ .datepicker({format: 'yyyy-mm-dd-DD'})
39
+ .datepicker('setValue');
40
+ equal(this.input.val().split('-')[3], 'Monday');
41
+ });
42
+
43
+ test('m: Month, no leading zero.', function(){
44
+ this.input
45
+ .val('2012-03-05')
46
+ .datepicker({format: 'yyyy-m-dd'})
47
+ .datepicker('setValue');
48
+ equal(this.input.val().split('-')[1], '3');
49
+ });
50
+
51
+ test('mm: Month, leading zero.', function(){
52
+ this.input
53
+ .val('2012-3-5')
54
+ .datepicker({format: 'yyyy-mm-dd'})
55
+ .datepicker('setValue');
56
+ equal(this.input.val().split('-')[1], '03');
57
+ });
58
+
59
+ test('M: Month shortname.', function(){
60
+ this.input
61
+ .val('2012-Mar-05')
62
+ .datepicker({format: 'yyyy-M-dd'})
63
+ .datepicker('setValue');
64
+ equal(this.input.val().split('-')[1], 'Mar');
65
+ });
66
+
67
+ test('MM: Month full name.', function(){
68
+ this.input
69
+ .val('2012-March-5')
70
+ .datepicker({format: 'yyyy-MM-dd'})
71
+ .datepicker('setValue');
72
+ equal(this.input.val().split('-')[1], 'March');
73
+ });
74
+
75
+ test('yy: Year, two-digit.', function(){
76
+ this.input
77
+ .val('2012-03-05')
78
+ .datepicker({format: 'yy-mm-dd'})
79
+ .datepicker('setValue');
80
+ equal(this.input.val().split('-')[0], '12');
81
+ });
82
+
83
+ test('yyyy: Year, four-digit.', function(){
84
+ this.input
85
+ .val('2012-03-5')
86
+ .datepicker({format: 'yyyy-mm-dd'})
87
+ .datepicker('setValue');
88
+ equal(this.input.val().split('-')[0], '2012');
89
+ });
90
+
91
+ test('dd-mm-yyyy: Regression: Prevent potential month overflow in small-to-large formats (Mar 31, 2012 -> Mar 01, 2012)', function(){
92
+ this.input
93
+ .val('31-03-2012')
94
+ .datepicker({format: 'dd-mm-yyyy'})
95
+ .datepicker('setValue');
96
+ equal(this.input.val(), '31-03-2012');
97
+ });
98
+
99
+ test('dd-mm-yyyy: Leap day', function(){
100
+ this.input
101
+ .val('29-02-2012')
102
+ .datepicker({format: 'dd-mm-yyyy'})
103
+ .datepicker('setValue');
104
+ equal(this.input.val(), '29-02-2012');
105
+ });
106
+
107
+ test('yyyy-mm-dd: Alternative format', function(){
108
+ this.input
109
+ .val('2012-02-12')
110
+ .datepicker({format: 'yyyy-mm-dd'})
111
+ .datepicker('setValue');
112
+ equal(this.input.val(), '2012-02-12');
113
+ });
114
+
115
+ test('yyyy-MM-dd: Regression: Infinite loop when numbers used for month', function(){
116
+ this.input
117
+ .val('2012-02-12')
118
+ .datepicker({format: 'yyyy-MM-dd'})
119
+ .datepicker('setValue');
120
+ equal(this.input.val(), '2012-February-12');
121
+ });
122
+
123
+ test('+1d: Tomorrow', patch_date(function(Date){
124
+ Date.now = UTCDate(2012, 2, 15);
125
+ this.input
126
+ .val('+1d')
127
+ .datepicker({format: 'dd-mm-yyyy'})
128
+ .datepicker('setValue');
129
+ equal(this.input.val(), '16-03-2012');
130
+ }));
131
+
132
+ test('-1d: Yesterday', patch_date(function(Date){
133
+ Date.now = UTCDate(2012, 2, 15);
134
+ this.input
135
+ .val('-1d')
136
+ .datepicker({format: 'dd-mm-yyyy'})
137
+ .datepicker('setValue');
138
+ equal(this.input.val(), '14-03-2012');
139
+ }));
140
+
141
+ test('+1w: Next week', patch_date(function(Date){
142
+ Date.now = UTCDate(2012, 2, 15);
143
+ this.input
144
+ .val('+1w')
145
+ .datepicker({format: 'dd-mm-yyyy'})
146
+ .datepicker('setValue');
147
+ equal(this.input.val(), '22-03-2012');
148
+ }));
149
+
150
+ test('-1w: Last week', patch_date(function(Date){
151
+ Date.now = UTCDate(2012, 2, 15);
152
+ this.input
153
+ .val('-1w')
154
+ .datepicker({format: 'dd-mm-yyyy'})
155
+ .datepicker('setValue');
156
+ equal(this.input.val(), '08-03-2012');
157
+ }));
158
+
159
+ test('+1m: Next month', patch_date(function(Date){
160
+ Date.now = UTCDate(2012, 2, 15);
161
+ this.input
162
+ .val('+1m')
163
+ .datepicker({format: 'dd-mm-yyyy'})
164
+ .datepicker('setValue');
165
+ equal(this.input.val(), '15-04-2012');
166
+ }));
167
+
168
+ test('-1m: Last month', patch_date(function(Date){
169
+ Date.now = UTCDate(2012, 2, 15);
170
+ this.input
171
+ .val('-1m')
172
+ .datepicker({format: 'dd-mm-yyyy'})
173
+ .datepicker('setValue');
174
+ equal(this.input.val(), '15-02-2012');
175
+ }));
176
+
177
+ test('+1y: Next year', patch_date(function(Date){
178
+ Date.now = UTCDate(2012, 2, 15);
179
+ this.input
180
+ .val('+1y')
181
+ .datepicker({format: 'dd-mm-yyyy'})
182
+ .datepicker('setValue');
183
+ equal(this.input.val(), '15-03-2013');
184
+ }));
185
+
186
+ test('-1y: Last year', patch_date(function(Date){
187
+ Date.now = UTCDate(2012, 2, 15);
188
+ this.input
189
+ .val('-1y')
190
+ .datepicker({format: 'dd-mm-yyyy'})
191
+ .datepicker('setValue');
192
+ equal(this.input.val(), '15-03-2011');
193
+ }));
194
+
195
+ test('-1y +2m: Multiformat', patch_date(function(Date){
196
+ Date.now = UTCDate(2012, 2, 15);
197
+ this.input
198
+ .val('-1y +2m')
199
+ .datepicker({format: 'dd-mm-yyyy'})
200
+ .datepicker('setValue');
201
+ equal(this.input.val(), '15-05-2011');
202
+ }));
203
+
204
+ test('Regression: End-of-month bug', patch_date(function(Date){
205
+ Date.now = UTCDate(2012, 4, 31);
206
+ this.input
207
+ .val('29-02-2012')
208
+ .datepicker({format: 'dd-mm-yyyy'})
209
+ .datepicker('setValue');
210
+ equal(this.input.val(), '29-02-2012');
211
+ }));
212
+
213
+ test('Invalid formats are force-parsed into a valid date on tab', patch_date(function(Date){
214
+ Date.now = UTCDate(2012, 4, 31);
215
+ this.input
216
+ .val('44-44-4444')
217
+ .datepicker({format: 'yyyy-MM-dd'})
218
+ .focus();
219
+
220
+ this.input.trigger({
221
+ type: 'keydown',
222
+ keyCode: 9
223
+ });
224
+
225
+ equal(this.input.val(), '56-September-30');
226
+ }));
227
+
228
+ test('Trailing separators', patch_date(function(Date){
229
+ Date.now = UTCDate(2012, 4, 31);
230
+ this.input
231
+ .val('29.02.2012.')
232
+ .datepicker({format: 'dd.mm.yyyy.'})
233
+ .datepicker('setValue');
234
+ equal(this.input.val(), '29.02.2012.');
235
+ }));