rules.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. QUnit.module( "rules" );
  2. QUnit.test( "rules() - internal - input", function( assert ) {
  3. var element = $( "#firstname" );
  4. $( "#testForm1" ).validate();
  5. assert.deepEqual( element.rules(), { required: true, minlength: 2 } );
  6. } );
  7. QUnit.test( "rules(), ignore method:false", function( assert ) {
  8. var element = $( "#firstnamec" );
  9. $( "#testForm1clean" ).validate( {
  10. rules: {
  11. firstnamec: { required: false, minlength: 2 }
  12. }
  13. } );
  14. assert.deepEqual( element.rules(), { minlength: 2 } );
  15. } );
  16. QUnit.test( "rules() HTML5 required (no value)", function( assert ) {
  17. var element = $( "#testForm11text1" );
  18. $( "#testForm11" ).validate();
  19. assert.deepEqual( element.rules(), { required: true } );
  20. } );
  21. QUnit.test( "rules() - internal - select", function( assert ) {
  22. var element = $( "#meal" );
  23. $( "#testForm3" ).validate();
  24. assert.deepEqual( element.rules(), { required: true } );
  25. } );
  26. QUnit.test( "rules() - external", function( assert ) {
  27. var element = $( "#text1" );
  28. $( "#form" ).validate( {
  29. rules: {
  30. action: { date: true, min: 5 }
  31. }
  32. } );
  33. assert.deepEqual( element.rules(), { date: true, min: 5 } );
  34. } );
  35. QUnit.test( "rules() - external - complete form", function( assert ) {
  36. assert.expect( 1 );
  37. var methods = $.extend( {}, $.validator.methods ),
  38. messages = $.extend( {}, $.validator.messages ),
  39. v;
  40. $.validator.addMethod( "verifyTest", function() {
  41. assert.ok( true, "method executed" );
  42. return true;
  43. } );
  44. v = $( "#form" ).validate( {
  45. rules: {
  46. action: { verifyTest: true }
  47. }
  48. } );
  49. v.form();
  50. $.validator.methods = methods;
  51. $.validator.messages = messages;
  52. } );
  53. QUnit.test( "rules() - internal - input", function( assert ) {
  54. var element = $( "#form8input" );
  55. $( "#testForm8" ).validate();
  56. assert.deepEqual( element.rules(), { required: true, number: true, rangelength: [ 2, 8 ] } );
  57. } );
  58. QUnit.test( "rules(), merge min/max to range, minlength/maxlength to rangelength", function( assert ) {
  59. jQuery.validator.autoCreateRanges = true;
  60. $( "#testForm1clean" ).validate( {
  61. rules: {
  62. firstnamec: {
  63. min: -15,
  64. max: 0
  65. },
  66. lastname: {
  67. minlength: 0,
  68. maxlength: 10
  69. }
  70. }
  71. } );
  72. assert.deepEqual( $( "#firstnamec" ).rules(), { range: [ -15, 0 ] } );
  73. assert.deepEqual( $( "#lastnamec" ).rules(), { rangelength: [ 0, 10 ] } );
  74. jQuery.validator.autoCreateRanges = false;
  75. } );
  76. QUnit.test( "rules(), guarantee that required is at front", function( assert ) {
  77. $( "#testForm1" ).validate();
  78. var v = $( "#v2" ).validate(),
  79. v1 = $( "#subformRequired" ).validate();
  80. function flatRules( element ) {
  81. var result = [];
  82. jQuery.each( $( element ).rules(), function( key ) { result.push( key ); } );
  83. return result.join( " " );
  84. }
  85. assert.equal( flatRules( "#firstname" ), "required minlength" );
  86. assert.equal( flatRules( "#v2-i6" ), "required minlength maxlength" );
  87. assert.equal( flatRules( "#co_name" ), "required maxlength" );
  88. v.destroy();
  89. v1.destroy();
  90. jQuery.validator.autoCreateRanges = true;
  91. v = $( "#v2" ).validate();
  92. assert.equal( flatRules( "#v2-i6" ), "required rangelength" );
  93. v1 = $( "#subformRequired" ).validate( {
  94. rules: {
  95. co_name: "required"
  96. }
  97. } );
  98. $( "#co_name" ).removeClass();
  99. assert.equal( flatRules( "#co_name" ), "required maxlength" );
  100. jQuery.validator.autoCreateRanges = false;
  101. } );
  102. QUnit.test( "rules(), evaluate dynamic parameters", function( assert ) {
  103. assert.expect( 2 );
  104. $( "#testForm1clean" ).validate( {
  105. rules: {
  106. firstnamec: {
  107. min: function( element ) {
  108. assert.equal( $( "#firstnamec" )[ 0 ], element );
  109. return 12;
  110. }
  111. }
  112. }
  113. } );
  114. assert.deepEqual( $( "#firstnamec" ).rules(), { min: 12 } );
  115. } );
  116. QUnit.test( "rules(), class and attribute combinations", function( assert ) {
  117. $.validator.addMethod( "customMethod1", function() {
  118. return false;
  119. }, "" );
  120. $.validator.addMethod( "customMethod2", function() {
  121. return false;
  122. }, "" );
  123. $( "#v2" ).validate( {
  124. rules: {
  125. "v2-i7": {
  126. required: true,
  127. minlength: 2,
  128. customMethod: true
  129. }
  130. }
  131. } );
  132. assert.deepEqual( $( "#v2-i1" ).rules(), { required: true } );
  133. assert.deepEqual( $( "#v2-i2" ).rules(), { required: true, email: true } );
  134. assert.deepEqual( $( "#v2-i3" ).rules(), { url: true } );
  135. assert.deepEqual( $( "#v2-i4" ).rules(), { required: true, minlength: 2 } );
  136. assert.deepEqual( $( "#v2-i5" ).rules(), { required: true, minlength: 2, maxlength: 5, customMethod1: "123" } );
  137. jQuery.validator.autoCreateRanges = true;
  138. assert.deepEqual( $( "#v2-i5" ).rules(), { required: true, customMethod1: "123", rangelength: [ 2, 5 ] } );
  139. assert.deepEqual( $( "#v2-i6" ).rules(), { required: true, customMethod2: true, rangelength: [ 2, 5 ] } );
  140. jQuery.validator.autoCreateRanges = false;
  141. assert.deepEqual( $( "#v2-i7" ).rules(), { required: true, minlength: 2, customMethod: true } );
  142. delete $.validator.methods.customMethod1;
  143. delete $.validator.messages.customMethod1;
  144. delete $.validator.methods.customMethod2;
  145. delete $.validator.messages.customMethod2;
  146. delete $.validator.classRuleSettings.customMethod2;
  147. } );
  148. QUnit.test( "rules(), dependency checks", function( assert ) {
  149. var v = $( "#testForm1clean" ).validate( {
  150. rules: {
  151. firstnamec: {
  152. min: {
  153. param: 5,
  154. depends: function( el ) {
  155. return ( /^a/ ).test( $( el ).val() );
  156. }
  157. }
  158. },
  159. lastname: {
  160. max: {
  161. param: 12
  162. },
  163. email: {
  164. depends: function() { return true; }
  165. }
  166. }
  167. }
  168. } ),
  169. rules = $( "#firstnamec" ).rules();
  170. assert.equal( v.objectLength( rules ), 0 );
  171. $( "#firstnamec" ).val( "ab" );
  172. assert.deepEqual( $( "#firstnamec" ).rules(), { min: 5 } );
  173. assert.deepEqual( $( "#lastnamec" ).rules(), { max: 12, email: true } );
  174. } );
  175. QUnit.test( "rules(), add and remove", function( assert ) {
  176. $.validator.addMethod( "customMethod1", function() {
  177. return false;
  178. }, "" );
  179. $( "#v2" ).validate();
  180. $( "#v2-i5" ).removeClass( "required" ).removeAttr( "minlength maxlength" );
  181. assert.deepEqual( $( "#v2-i5" ).rules(), { customMethod1: "123" } );
  182. $( "#v2-i5" ).addClass( "required" ).attr( {
  183. minlength: 2,
  184. maxlength: 5
  185. } );
  186. assert.deepEqual( $( "#v2-i5" ).rules(), { required: true, minlength: 2, maxlength: 5, customMethod1: "123" } );
  187. $( "#v2-i5" ).addClass( "email" ).attr( { min: 5 } );
  188. assert.deepEqual( $( "#v2-i5" ).rules(), { required: true, email: true, minlength: 2, maxlength: 5, min: 5, customMethod1: "123" } );
  189. $( "#v2-i5" ).removeClass( "required email" ).removeAttr( "minlength maxlength customMethod1 min" );
  190. assert.deepEqual( $( "#v2-i5" ).rules(), {} );
  191. delete $.validator.methods.customMethod1;
  192. delete $.validator.messages.customMethod1;
  193. } );
  194. QUnit.test( "rules(), add and remove static rules", function( assert ) {
  195. $( "#testForm1clean" ).validate( {
  196. rules: {
  197. firstnamec: "required date"
  198. }
  199. } );
  200. assert.deepEqual( $( "#firstnamec" ).rules(), { required: true, date: true } );
  201. $( "#firstnamec" ).rules( "remove", "date" );
  202. assert.deepEqual( $( "#firstnamec" ).rules(), { required: true } );
  203. $( "#firstnamec" ).rules( "add", "email" );
  204. assert.deepEqual( $( "#firstnamec" ).rules(), { required: true, email: true } );
  205. $( "#firstnamec" ).rules( "remove", "required" );
  206. assert.deepEqual( $( "#firstnamec" ).rules(), { email: true } );
  207. assert.deepEqual( $( "#firstnamec" ).rules( "remove" ), { email: true } );
  208. assert.deepEqual( $( "#firstnamec" ).rules(), {} );
  209. $( "#firstnamec" ).rules( "add", "required email" );
  210. assert.deepEqual( $( "#firstnamec" ).rules(), { required: true, email: true } );
  211. assert.deepEqual( $( "#lastnamec" ).rules(), {} );
  212. $( "#lastnamec" ).rules( "add", "required" );
  213. $( "#lastnamec" ).rules( "add", {
  214. minlength: 2
  215. } );
  216. assert.deepEqual( $( "#lastnamec" ).rules(), { required: true, minlength: 2 } );
  217. var removedRules = $( "#lastnamec" ).rules( "remove", "required email" );
  218. assert.deepEqual( $( "#lastnamec" ).rules(), { minlength: 2 } );
  219. $( "#lastnamec" ).rules( "add", removedRules );
  220. assert.deepEqual( $( "#lastnamec" ).rules(), { required: true, minlength: 2 } );
  221. } );
  222. QUnit.test( "rules(), add messages", function( assert ) {
  223. $( "#firstnamec" ).attr( "title", null );
  224. var v = $( "#testForm1clean" ).validate( {
  225. rules: {
  226. firstnamec: "required"
  227. }
  228. } );
  229. $( "#testForm1clean" ).valid();
  230. $( "#firstnamec" ).valid();
  231. assert.deepEqual( v.settings.messages.firstname, undefined );
  232. $( "#firstnamec" ).rules( "add", {
  233. messages: {
  234. required: "required"
  235. }
  236. } );
  237. $( "#firstnamec" ).valid();
  238. assert.deepEqual( v.errorList[ 0 ] && v.errorList[ 0 ].message, "required" );
  239. $( "#firstnamec" ).val( "test" );
  240. $( "#firstnamec" ).valid();
  241. assert.equal( v.errorList.length, 0 );
  242. } );
  243. QUnit.test( "rules(), rangelength attribute as array", function( assert ) {
  244. $( "#testForm13" ).validate();
  245. assert.deepEqual( $( "#cars-select" ).rules(), {
  246. required: true,
  247. rangelength: [ 2, 3 ]
  248. } );
  249. } );
  250. QUnit.test( "rules(), global/local normalizer", function( assert ) {
  251. var username = $( "#usernamec" ),
  252. urlc = $( "#urlc" ),
  253. lastname = $( "#lastnamec" ),
  254. v;
  255. username.val( "\t\t \r" );
  256. urlc.val( "" );
  257. v = $( "#testForm1clean" ).validate( {
  258. // Using the normalizer to trim the value of all elements before validating them.
  259. normalizer: function( value ) {
  260. // This normalizer should only be called for the username element, and nothing else.
  261. assert.notEqual( this, urlc[ 0 ], "This normalizer should not be called for urlc element." );
  262. assert.equal( this, username[ 0 ], "`this` in this normalizer should be the username element." );
  263. // Trim the value of the input
  264. return $.trim( value );
  265. },
  266. rules: {
  267. username: {
  268. required: true
  269. },
  270. urlc: {
  271. required: true,
  272. url: true,
  273. // Using the normalizer to append https:// if it's not
  274. // present on the input value
  275. normalizer: function( value ) {
  276. assert.equal( this, urlc[ 0 ], "`this` in the normalizer should be the urlc element." );
  277. var url = value;
  278. // Check if it doesn't start with http:// or https:// or ftp://
  279. if ( url && url.substr( 0, 7 ) !== "http://" &&
  280. url.substr( 0, 8 ) !== "https://" &&
  281. url.substr( 0, 6 ) !== "ftp://" ) {
  282. // Then prefix with http:// or even https://
  283. url = "https://" + url;
  284. }
  285. // Return the new url
  286. return url;
  287. }
  288. },
  289. lastname: {
  290. required: true,
  291. normalizer: function( value ) {
  292. assert.equal( this, lastname[ 0 ], "`this` in the normalizer should be the lastname element." );
  293. // Return null in order to make sure an exception is thrown
  294. // when normalizer returns a non string value.
  295. value = null;
  296. return value;
  297. }
  298. }
  299. }
  300. } );
  301. // Validate only the username and the url elements.
  302. username.valid();
  303. assert.equal( v.invalidElements()[ 0 ], username[ 0 ], "The username should be invalid" );
  304. urlc.valid();
  305. assert.equal( v.invalidElements()[ 0 ], urlc[ 0 ], "The url should be invalid" );
  306. assert.equal( v.numberOfInvalids(), 2, "There is two invalid elements" );
  307. username.val( "something" );
  308. urlc.val( "google.com" );
  309. username.trigger( "keyup" );
  310. urlc.trigger( "keyup" );
  311. assert.equal( v.numberOfInvalids(), 0, "All elements are valid" );
  312. assert.equal( v.size(), 0, "All elements are valid" );
  313. // Validate the lastname element, which will throw an exception
  314. assert.throws( function() {
  315. v.check( lastname[ 0 ] );
  316. }, function( err ) {
  317. return err.name === "TypeError" && err.message === "The normalizer should return a string value.";
  318. }, "This should throw a TypeError exception." );
  319. } );
  320. QUnit.test( "rules() - on unexpected input", function( assert ) {
  321. var emptySet = $( "#firstname .mynonexistantclass" ),
  322. nonFormElement = $( "div#foo" ),
  323. result;
  324. result = emptySet.rules( "add", "whatever" );
  325. assert.deepEqual( result, undefined, "can work on an empty set without a js error" );
  326. result = nonFormElement.rules( "add", "whatever" );
  327. assert.deepEqual( result, undefined, "can work on a non-form element" );
  328. } );