corrade-http-templates – Blame information for rev 62

Subversion Repositories:
Rev:
Rev Author Line No. Line
62 office 1 $(function () {
2  
3 $.mockjaxSettings.logging = false
4  
5 $.mockjax({
6 url: '/success',
7 status: 200,
8 responseText: 'cool'
9 })
10  
11 $.mockjax({
12 url: '/error',
13 status: 418,
14 responseText: 'dang'
15 })
16  
17 QUnit.module("validator")
18  
19 QUnit.test("should provide no conflict", function (assert) {
20 var validator = $.fn.validator.noConflict()
21 assert.ok(!$.fn.validator, 'validator was set back to undefined (org value)')
22 $.fn.validator = validator
23 })
24  
25 QUnit.test("should be defined on jquery object", function (assert) {
26 var div = $('<div></div>')
27 assert.ok(div.validator, 'validator method is defined')
28 })
29  
30 QUnit.test("should return element", function (assert) {
31 var form = $('<form></form>')
32 assert.ok(form.validator()[0] == form[0], 'same element returned')
33 })
34  
35 QUnit.test("should expose defaults var for settings", function (assert) {
36 assert.ok($.fn.validator.Constructor.DEFAULTS, 'default object exposed')
37 })
38  
39 QUnit.test('should not fire validated when validate is prevented', function (assert) {
40 var done = assert.async()
41 $('<form><input type="email"></form>')
42 .on('validate.bs.validator', function (e) {
43 e.preventDefault()
44 assert.ok(true)
45 done()
46 })
47 .on('validated.bs.validator', function (e) {
48 assert.ok(false)
49 })
50 .validator('validate')
51 })
52  
53 QUnit.test('should validate match', 2, function (assert) {
54 var done = assert.async()
55 var form = '<form>'
56 + '<input type="text" id="canon" value="pizza">'
57 + '<input type="text" id="wannabe" value="hotpocket" data-match="#canon">'
58 + '</form>'
59  
60 form = $(form)
61 .appendTo($('#qunit-fixture'))
62 .on('invalid.bs.validator', function (e) {
63 var $el = $(e.relatedTarget)
64 if ($el.attr('id') !== 'wannabe') return
65 assert.ok(true)
66 $el.val('pizza').trigger('input')
67 })
68 .on('valid.bs.validator', function (e) {
69 var $el = $(e.relatedTarget)
70 if ($el.attr('id') !== 'wannabe') return
71 assert.ok(true)
72 done()
73 })
74 .validator('validate')
75 })
76  
77 QUnit.test('should validate minlength', 2, function (assert) {
78 var done = assert.async()
79 $('<form><input type="text" data-minlength="6" value="pizza"></form>')
80 .on('invalid.bs.validator', function (e) {
81 assert.ok(true)
82 $(e.relatedTarget).val('pizzas').trigger('input')
83 })
84 .on('valid.bs.validator', function (e) {
85 assert.ok(true)
86 done()
87 })
88 .validator('validate')
89 })
90  
91 QUnit.test('should allow custom generic error message', function (assert) {
92 var done = assert.async()
93 var form = '<form>'
94 + '<div class="form-group">'
95 + '<input type="text" data-minlength="6" data-error="generic error" value="pizza">'
96 + '<div class="help-block with-errors">6 characters</div>'
97 + '</div>'
98 + '</form>'
99  
100 $(form)
101 .on('invalid.bs.validator', function (e) {
102 assert.ok($(this).find('.help-block.with-errors').text() == 'generic error', 'generic error message was set')
103 done()
104 })
105 .validator('validate')
106 })
107  
108 QUnit.test('should allow custom error-specific message for standard attribute validators', function (assert) {
109 var form = '<form>'
110 + '<div class="form-group">'
111 + '<input type="email" data-type-error="type" value="pizza">'
112 + '<div id="type" class="help-block with-errors"></div>'
113 + '</div>'
114 + '<div class="form-group">'
115 + '<input type="text" pattern="burger" data-pattern-error="pattern" value="pizza">'
116 + '<div id="pattern" class="help-block with-errors"></div>'
117 + '</div>'
118 + '<div class="form-group">'
119 + '<input type="number" min="5" data-min-error="min" value="0">'
120 + '<div id="min" class="help-block with-errors"></div>'
121 + '</div>'
122 + '<div class="form-group">'
123 + '<input type="number" max="5" data-max-error="max" value="10">'
124 + '<div id="max" class="help-block with-errors"></div>'
125 + '</div>'
126 + '<div class="form-group">'
127 + '<input type="number" min="0" step="5" data-step-error="step" value="3">'
128 + '<div id="step" class="help-block with-errors"></div>'
129 + '</div>'
130 + '<div class="form-group">'
131 + '<input type="text" data-required-error="required" required>'
132 + '<div id="required" class="help-block with-errors"></div>'
133 + '</div>'
134 + '</form>'
135  
136 $(form)
137 .appendTo('#qunit-fixture')
138 .validator('validate')
139  
140 assert.equal($('#type').text(), 'type', 'type error message was set')
141 assert.equal($('#pattern').text(), 'pattern', 'pattern error message was set')
142 assert.equal($('#min').text(), 'min', 'min error message was set')
143 assert.equal($('#max').text(), 'max', 'max error message was set')
144 assert.equal($('#step').text(), 'step', 'step error message was set')
145 assert.equal($('#required').text(), 'required', 'required error message was set')
146 })
147  
148 QUnit.test('should allow custom error-specific message for non-standard validators', function (assert) {
149 var done = assert.async()
150 var form = '<form>'
151 + '<div class="form-group">'
152 + '<input type="text" data-minlength="6" data-minlength-error="minlength error" value="pizza">'
153 + '<div class="help-block with-errors">6 characters</div>'
154 + '</div>'
155 + '</form>'
156  
157 $(form)
158 .on('invalid.bs.validator', function (e) {
159 assert.ok($(this).find('.help-block.with-errors').text() == 'minlength error', 'specific error message was set')
160 done()
161 })
162 .validator('validate')
163 })
164  
165 QUnit.test('should give precedence to specific error message over generic error message', function (assert) {
166 var done = assert.async()
167 var form = '<form>'
168 + '<div class="form-group">'
169 + '<input type="text" data-minlength="6" data-error="generic error" data-minlength-error="minlength error" value="pizza">'
170 + '<div class="help-block with-errors">6 characters</div>'
171 + '</div>'
172 + '</form>'
173  
174 $(form)
175 .on('invalid.bs.validator', function (e) {
176 assert.ok($(this).find('.help-block.with-errors').text() == 'minlength error', 'specific error message displayed instead of generic error')
177 done()
178 })
179 .validator('validate')
180 })
181  
182 QUnit.test('should escape html in error messages if html option is false', function (assert) {
183 var done = assert.async()
184 var form = '<form>'
185 + '<div class="form-group">'
186 + '<input type="text" data-minlength="6" data-minlength-error="<em>Too short</em>" value="pizza">'
187 + '<div class="help-block with-errors"></div>'
188 + '</div>'
189 + '</form>'
190  
191 $(form)
192 .on('invalid.bs.validator', function (e) {
193 assert.ok($(this).find('.help-block.with-errors').text() == '<em>Too short</em>', 'html escaped from error message')
194 done()
195 })
196 .validator({html: false})
197 .validator('validate')
198 })
199  
200 QUnit.test('should allow html in error messages if html option is true', function (assert) {
201 var done = assert.async()
202 var form = '<form>'
203 + '<div class="form-group">'
204 + '<input type="text" data-minlength="6" data-minlength-error="<em>Too short</em>" value="pizza">'
205 + '<div class="help-block with-errors"></div>'
206 + '</div>'
207 + '</form>'
208  
209 $(form)
210 .on('invalid.bs.validator', function (e) {
211 assert.ok($(this).find('.help-block.with-errors').text() == 'Too short', 'html allowed in error message')
212 done()
213 })
214 .validator({html: true})
215 .validator('validate')
216 })
217  
218 QUnit.test('should restore .help-block content once valid', function (assert) {
219 var done = assert.async()
220 var form = '<form>'
221 + '<div class="form-group">'
222 + '<input type="text" data-minlength="6" value="pizza">'
223 + '<div class="help-block with-errors">6 characters</div>'
224 + '</div>'
225 + '</form>'
226  
227 $(form)
228 .on('invalid.bs.validator', function (e) {
229 assert.ok($(this).find('.help-block.with-errors').text() != '6 characters', 'error message was set')
230 $(e.relatedTarget).val('pizzas').trigger('input')
231 })
232 .on('valid.bs.validator', function (e) {
233 assert.ok($(this).find('.help-block.with-errors').text() == '6 characters', 'help text was restored')
234 done()
235 })
236 .validator('validate')
237 })
238  
239 QUnit.test('should add .has-error class to the closest .form-group', function (assert) {
240 var done = assert.async()
241 var form = '<form>'
242 + '<div class="form-group">'
243 + '<input type="text" data-minlength="6" value="pizza">'
244 + '</div>'
245 + '</form>'
246  
247 $(form)
248 .on('invalid.bs.validator', function (e) {
249 assert.ok($(this).find('.form-group').hasClass('has-error'), '.has-error class added to form-group')
250 $(e.relatedTarget).val('pizzas').trigger('input')
251 })
252 .on('valid.bs.validator', function (e) {
253 assert.ok(!$(this).find('.form-group').hasClass('has-error'), '.has-error class removed from form-group')
254 done()
255 })
256 .validator('validate')
257 })
258  
259 QUnit.test('should add feedback classes to .form-control-feedback elements when the form group .has-feedback', function (assert) {
260 var done = assert.async()
261 var form = '<form>'
262 + '<div class="form-group has-feedback">'
263 + '<input type="text" data-minlength="6" value="pizza">'
264 + '<div class="form-control-feedback"></div>'
265 + '</div>'
266 + '</form>'
267  
268 $(form)
269 .on('invalid.bs.validator', function (e) {
270 assert.ok($(this).find('.form-control-feedback').hasClass('glyphicon-remove'), 'error feedback class added to .form-control-feedback')
271 $(e.relatedTarget).val('pizzas').trigger('input')
272 })
273 .on('valid.bs.validator', function (e) {
274 assert.ok($(this).find('.form-control-feedback').hasClass('glyphicon-ok'), 'success feedback class added to .form-control-feedback')
275 done()
276 })
277 .validator('validate')
278 })
279  
280 QUnit.test('should not add feedback classes to .form-control-feedback elements when the form group does not .has-feedback', function (assert) {
281 var done = assert.async()
282 var form = '<form>'
283 + '<div class="form-group">'
284 + '<input type="text" data-minlength="6" value="pizza">'
285 + '<div class="form-control-feedback"></div>'
286 + '</div>'
287 + '</form>'
288  
289 $(form)
290 .on('invalid.bs.validator', function (e) {
291 assert.ok(!$(this).find('.form-control-feedback').hasClass('glyphicon-remove'), 'error feedback class not added to .form-control-feedback')
292 $(e.relatedTarget).val('pizzas').trigger('input')
293 })
294 .on('valid.bs.validator', function (e) {
295 assert.ok(!$(this).find('.form-control-feedback').hasClass('glyphicon-ok'), 'success feedback class not added to .form-control-feedback')
296 done()
297 })
298 .validator('validate')
299 })
300  
301 QUnit.test('should not add success feedback classes to empty fields', function (assert) {
302 var done = assert.async()
303 var form = '<form>'
304 + '<div class="form-group has-feedback">'
305 + '<input type="text" data-minlength="6" value="pizza">'
306 + '<div class="form-control-feedback"></div>'
307 + '</div>'
308 + '</form>'
309  
310 $(form)
311 .on('invalid.bs.validator', function (e) {
312 assert.ok($(this).find('.form-control-feedback').hasClass('glyphicon-remove'), 'error feedback class added to .form-control-feedback')
313 $(e.relatedTarget).val('').trigger('input')
314 })
315 .on('valid.bs.validator', function (e) {
316 assert.ok(!$(this).find('.form-control-feedback').hasClass('glyphicon-ok'), 'success feedback class not added to .form-control-feedback')
317 assert.ok(!$(this).find('.form-group').hasClass('has-success'), '.has-success not added to .form-group')
318 done()
319 })
320 .validator('validate')
321 })
322  
323 QUnit.test('should disable submit button unless form is complete and valid', function (assert) {
324 var form = '<form>'
325 + '<input id="required" type="text" required>'
326 + '<input id="minlength" type="text" data-minlength="6">'
327 + '<button type="submit" id="btn">Submit</button>'
328 + '</form>'
329  
330 form = $(form)
331 .appendTo('#qunit-fixture')
332 .validator()
333  
334 var $btn = $('#btn')
335  
336 assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is incomplete and invalid')
337 $('#required').val('hamburgers').trigger('input')
338 assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is sufficiently complete and no fields are invalid')
339 $('#minlength').val('pizza').trigger('input')
340 assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is invalid')
341 $('#minlength').val('pizzas').trigger('input')
342 assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is complete and valid')
343 })
344  
345 QUnit.test('should not disable submit button if disable option is set to false', function (assert) {
346 var form = '<form>'
347 + '<input id="required" type="text" required>'
348 + '<input id="minlength" type="text" data-minlength="6">'
349 + '<button type="submit" id="btn">Submit</button>'
350 + '</form>'
351  
352 form = $(form)
353 .appendTo('#qunit-fixture')
354 .validator({ disable: false })
355  
356 var $btn = $('#btn')
357  
358 assert.ok($btn.not('.disabled'), 'submit button enabled although form is incomplete and invalid because disabling of submit is disabled')
359 $('#required').val('hamburgers').trigger('input')
360 $('#minlength').val('pizza').trigger('input')
361 assert.ok($btn.not('.disabled'), 'submit button enabled although form is invalid because disabling of submit is disable')
362 })
363  
364 QUnit.test('should only disable the submit buttons', function (assert) {
365 var form = '<form>'
366 + '<input id="required" type="text" required>'
367 + '<button type="submit" id="submit">Submit</button>'
368 + '<button type="button" id="cancel">Cancel</button>'
369 + '<button id="btn">Undefined Type</button>'
370 + '</form>'
371  
372 form = $(form)
373 .appendTo('#qunit-fixture')
374 .validator()
375  
376 var $submit = $('#submit')
377 var $cancel = $('#cancel')
378 var $btn = $('#btn')
379  
380 assert.ok($submit.hasClass('disabled'), 'submit button disabled')
381 assert.ok(!$cancel.hasClass('disabled'), 'cancel button not disabled')
382 assert.ok(!$btn.hasClass('disabled'), 'button without a type not disabled')
383 })
384  
385 QUnit.test('should respect the required attribute on checkboxes', function (assert) {
386 var form = '<form>'
387 + '<input id="required" type="checkbox" required>'
388 + '<button type="submit" id="btn">Submit</button>'
389 + '</form>'
390  
391 form = $(form)
392 .appendTo('#qunit-fixture')
393 .validator()
394  
395 var $btn = $('#btn')
396  
397 assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is incomplete')
398 $('#required').prop('checked', true).trigger('change')
399 assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is complete')
400 $('#required').prop('checked', false).trigger('change')
401 assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is incomplete')
402 $('#required').prop('checked', true).trigger('change')
403 assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is complete')
404 })
405  
406 QUnit.test('should respect the required attribute on radio button groups', function (assert) {
407 var form = '<form>'
408 + '<input type="radio" id="required1" name="radioGroup" required>'
409 + '<input type="radio" id="required2" name="radioGroup" required>'
410 + '<button type="submit" id="btn">Submit</button>'
411 + '</form>'
412  
413 form = $(form)
414 .appendTo('#qunit-fixture')
415 .validator()
416  
417 var $btn = $('#btn')
418  
419 assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is incomplete')
420 $('#required1').prop('checked', true).trigger('change')
421 assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is complete')
422 $('#required2').prop('checked', false).trigger('change')
423 assert.ok(!$btn.hasClass('disabled'), 'submit button still enabled')
424 })
425  
426 QUnit.test('should support [form] attribute on submit buttons outside of form element', function (assert) {
427 var form = '<form id="myForm">'
428 + '<input type="text" id="input" required>'
429 + '</form>'
430 + '<button type="submit" form="myForm" id="btn">Submit</button>'
431  
432 form = $(form)
433 .appendTo('#qunit-fixture')
434 .validator()
435  
436 var $btn = $('#btn')
437  
438 assert.ok($btn.hasClass('disabled'), 'submit button outside of referenced form is disabled')
439 $('#input').val('sup').trigger('change')
440 assert.ok(!$btn.hasClass('disabled'), 'submit button outside of referenced form reacted to changes')
441 })
442  
443 QUnit.test('should ignore button fields', function (assert) {
444 var form = '<form>'
445 + '<div class="form-group">'
446 + '<input type="text" data-error="error" required>'
447 + '<input type="submit" value="Submit">'
448 + '<div id="errors" class="help-block with-errors">valid</div>'
449 + '</div>'
450 + '</form>'
451  
452 form = $(form)
453 .appendTo('#qunit-fixture')
454 .validator('validate')
455  
456 var $errors = $('#errors')
457  
458 assert.equal($errors.text(), 'error', 'buttons did not inadvertently get validated and clear the form-group errors')
459 })
460  
461 QUnit.test('should validate remote endpoints with success if response is 200', function (assert) {
462 var done = assert.async()
463 var form = '<form>'
464 + '<input id="remote" type="text" value="foo" data-remote="/success">'
465 + '</form>'
466  
467 form = $(form)
468 .appendTo('#qunit-fixture')
469 .on('valid.bs.validator', function (e) {
470 assert.ok(e.relatedTarget === $('#remote')[0], 'remote endpoint validated successfully with a 200 response')
471 done()
472 })
473 .validator('validate')
474 })
475  
476 QUnit.test('should validate remote endpoints with error if response is 4xx', function (assert) {
477 var done = assert.async()
478 var form = '<form>'
479 + '<input id="remote" type="text" value="foo" data-remote="/error">'
480 + '</form>'
481  
482 form = $(form)
483 .appendTo('#qunit-fixture')
484 .on('invalid.bs.validator', function (e) {
485 assert.ok(e.relatedTarget === $('#remote')[0], 'remote endpoint validated with error with a 4xx response')
486 done()
487 })
488 .validator('validate')
489 })
490  
491 QUnit.test('should clean up after itself when destroy called', function (assert) {
492 var done = assert.async()
493 var form = '<form>'
494 + '<div class="form-group has-feedback">'
495 + '<input type="text" data-error="error message" required>'
496 + '<div class="form-control-feedback"></div>'
497 + '<div class="help-block with-errors">original content</div>'
498 + '</div>'
499 + '<button type="submit">Submit</button>'
500 + '</form>'
501  
502 form = $(form)
503 .appendTo('#qunit-fixture')
504 .validator('validate')
505  
506 var validator = form.data('bs.validator')
507  
508 window.setTimeout(function () {
509 form.validator('destroy')
510  
511 Object.keys(validator).forEach(function (key) {
512 assert.ok(validator[key] === null, 'removed ' + key + ' reference from plugin instance')
513 })
514  
515 assert.ok(!form.data('bs.validator'), 'removed data reference to plugin instance')
516 assert.ok(!form.attr('novalidate'), 'removed novalidate browser override')
517 assert.ok(Object.keys(form.find('input').data()).length === 1, 'removed data left on inputs (excluding data-* attrs)')
518 assert.ok(!form.find('.has-error').length, 'removed has-error class from all inputs')
519 assert.ok(!form.find('.glyphicon-remove').length, 'removed feedback class from all inputs')
520 assert.ok(form.find('.help-block').html() === 'original content', 'help block content restored')
521 assert.ok(!form.find('button').is('.disabled'), 're-enabled submit button')
522 done()
523 })
524 })
525  
526 QUnit.test('should run custom validators', function (assert) {
527 var form = '<form>'
528 + '<div class="form-group">'
529 + '<input type="text" id="foo" data-foo="foo" value="foo">'
530 + '<div class="help-block with-errors"></div>'
531 + '</div>'
532 + '<div class="form-group">'
533 + '<input type="text" id="bar" data-foo="foo" value="bar">'
534 + '<div class="help-block with-errors"></div>'
535 + '</div>'
536 + '<div class="form-group">'
537 + '<input type="text" id="baz" data-foo value="baz">'
538 + '<div class="help-block with-errors"></div>'
539 + '</div>'
540 + '<button type="submit">Submit</button>'
541 + '</form>'
542  
543 var options = {
544 custom: {
545 foo: function ($el) {
546 if ($el.data('foo') != $el.val()) return 'not equal to ' + $el.data('foo')
547 }
548 }
549 }
550  
551 form = $(form)
552 .appendTo('#qunit-fixture')
553 .validator(options)
554 .validator('validate')
555  
556 assert.ok($('#foo').data('bs.validator.errors').length === 0, 'foo input is valid')
557 assert.ok($('#bar').data('bs.validator.errors').length === 1, 'bar input is invalid')
558 assert.ok($('#bar').data('bs.validator.errors')[0] === 'not equal to foo', 'bar error is custom error')
559 assert.ok($('#baz').data('bs.validator.errors').length === 1, 'baz ran validator even though data-foo has no attr value')
560 })
561  
562 QUnit.test('should update set of fields', function (assert) {
563 var form = '<form><button id="btn" type="submit">Submit</button></form>'
564 var group = '<div class="form-group">'
565 + '<input type="text" data-error="error" required>'
566 + '<div id="errors" class="help-block with-errors"></div>'
567 + '</div>'
568  
569 form = $(form)
570 .appendTo('#qunit-fixture')
571 .validator()
572 .append(group)
573 .validator('validate')
574  
575 var $errors = $('#errors')
576  
577 assert.equal($errors.text(), '', 'field was not validated since it was added after the validator was initialized')
578  
579 form.validator('update')
580  
581 assert.ok($('#btn').hasClass('disabled'), 'submit was disabled after update because form is now incomplete')
582  
583 form.validator('validate')
584  
585 assert.equal($errors.text(), 'error', 'field was validated after a call to .validator(\'update\')')
586 })
587  
588 QUnit.test('should respect data-validate attr to force validation on an input', function (assert) {
589 var inputSelector = $.fn.validator.Constructor.INPUT_SELECTOR
590 $.fn.validator.Constructor.INPUT_SELECTOR = inputSelector + ':not(.skip-validation)'
591  
592 var form = '<form>'
593 + '<div class="form-group">'
594 + '<input type="text" class="skip-validation" data-error="error" data-validate="true" required>'
595 + '<div id="validated" class="help-block with-errors"></div>'
596 + '</div>'
597 + '<div class="form-group">'
598 + '<input type="text" data-error="error" data-validate="false" required>'
599 + '<div id="skipped" class="help-block with-errors"></div>'
600 + '</div>'
601 + '<button type="submit">Submit</button>'
602 + '</form>'
603  
604 form = $(form)
605 .appendTo('#qunit-fixture')
606 .validator('validate')
607  
608 assert.equal($('#validated').text(), 'error', 'validation of skipped field was forced due to data-validate="true"')
609 assert.equal($('#skipped').text(), '', 'validation of field was bypassed due to data-validate="false"')
610  
611 $('[data-validate="true"]').attr('data-validate', false)
612 form.validator('update')
613  
614 assert.equal($('#validated').text(), '', 'error is cleared when data-validate="false" and the form is updated')
615  
616 $.fn.validator.Constructor.INPUT_SELECTOR = inputSelector
617 })
618  
619 QUnit.test('should not trim spaces off of the end of input values when running validators', function (assert) {
620 var form = '<form>'
621 + '<div class="form-group">'
622 + '<input type="text" data-error="error" pattern="foo" value="foo " required>'
623 + '<div id="errors" class="help-block with-errors"></div>'
624 + '</div>'
625 + '</form>'
626  
627 form = $(form)
628 .appendTo('#qunit-fixture')
629 .validator('validate')
630  
631 assert.equal($('#errors').text(), 'error', 'space at the end of input is not being trimmed off')
632 })
633  
634 QUnit.test('should re-run match validator on source input change', function (assert) {
635 var form = '<form>'
636 + '<div class="form-group">'
637 + '<input type="text" id="source" value="foo" required>'
638 + '<div class="help-block with-errors"></div>'
639 + '</div>'
640 + '<div class="form-group">'
641 + '<input type="text" id="confirm" data-error="error" data-match="#source" value="foo" required>'
642 + '<div id="errors" class="help-block with-errors"></div>'
643 + '</div>'
644 + '</form>'
645  
646 form = $(form)
647 .appendTo('#qunit-fixture')
648 .validator('validate')
649  
650 assert.equal($('#errors').text(), '', 'fields are initially matching')
651  
652 $('#source').val('bar')
653 form.validator('validate')
654  
655 assert.equal($('#errors').text(), 'error', 'error is raised on source change')
656 })
657  
658 QUnit.test('should reinitialize plugin on form reset', function (assert) {
659 var done = assert.async()
660 var form = '<form>'
661 + '<div class="form-group">'
662 + '<input type="text" data-minlength="6">'
663 + '<div id="errors" class="help-block with-errors"></div>'
664 + '</div>'
665 + '</form>'
666  
667 form = $(form)
668 .appendTo('#qunit-fixture')
669 .validator()
670  
671 form.find('input').val('foo')
672  
673 form.validator('validate')
674 form.trigger('reset')
675  
676 window.setTimeout(function () {
677 assert.equal($('#errors').text(), '', 'error is cleared on form reset')
678 done()
679 }, 0)
680 })
681  
682 QUnit.test('should validate select elements', function (assert) {
683 var form = '<form>'
684 + '<div class="form-group">'
685 + '<select required>'
686 + '<option value=""></option>'
687 + '<option id="option" value="foo">Foo</option>'
688 + '</select>'
689 + '</div>'
690 + '<button type="submit" id="btn">Submit</button>'
691 + '</form>'
692  
693 var $form = $(form)
694 .appendTo('#qunit-fixture')
695 .validator('validate')
696  
697 var $btn = $('#btn')
698  
699 assert.ok($form.find('.form-group').hasClass('has-error'), '.has-error class is added to form-group')
700 assert.ok($btn.hasClass('disabled'), 'submit button disabled because form is incomplete')
701  
702 $('#option').prop('selected', true)
703 $('select').trigger('input')
704  
705 assert.ok(!$form.find('.form-group').hasClass('has-error'), '.has-error class is removed from form-group')
706 assert.ok(!$btn.hasClass('disabled'), 'submit button enabled because form is complete')
707 })
708  
709 QUnit.test('should not add .has-error class to the pristine select with required and multiple attribute', function (assert) {
710 var form = '<form>'
711 + '<div class="form-group">'
712 + '<select required multiple>'
713 + '<option value="foo">Foo</option>'
714 + '</select>'
715 + '</div>'
716 + '</form>'
717  
718 var $form = $(form)
719 .appendTo('#qunit-fixture')
720 .validator()
721  
722 assert.ok(!$form.find('.form-group').hasClass('has-error'), '.has-error class is not added to form-group')
723 })
724  
725 QUnit.test('should not clobber server-side errors', function (assert) {
726 var form = '<form>'
727 + '<div class="form-group has-error">'
728 + '<input type="text" value="foo" required>'
729 + '<div class="help-block with-errors">server says foo is invalid</div>'
730 + '</div>'
731 + '</form>'
732  
733 var $form = $(form)
734 .appendTo('#qunit-fixture')
735 .validator()
736  
737 assert.ok($form.find('.form-group').hasClass('has-error'), '.has-error class is not removed from form-group')
738 })
739 })