bootstrap-datepicker 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }));