validator.test.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. <?php
  2. class ValidatorTest extends PHPUnit_Framework_TestCase {
  3. /**
  4. * Setup the test environment.
  5. */
  6. public function setUp()
  7. {
  8. Config::set('database.default', 'sqlite');
  9. }
  10. /**
  11. * Tear down the test environment.
  12. */
  13. public function tearDown()
  14. {
  15. Config::set('database.default', 'mysql');
  16. $_FILES = array();
  17. }
  18. /**
  19. * Test the required validation rule.
  20. *
  21. * @group laravel
  22. */
  23. public function testRequiredRule()
  24. {
  25. $input = array('name' => 'Taylor Otwell');
  26. $rules = array('name' => 'required');
  27. $this->assertTrue(Validator::make($input, $rules)->valid());
  28. $input['name'] = '';
  29. $this->assertFalse(Validator::make($input, $rules)->valid());
  30. unset($input['name']);
  31. $this->assertFalse(Validator::make($input, $rules)->valid());
  32. $_FILES['name']['tmp_name'] = 'foo';
  33. $this->assertTrue(Validator::make($_FILES, $rules)->valid());
  34. $_FILES['name']['tmp_name'] = '';
  35. $this->assertFalse(Validator::make($_FILES, $rules)->valid());
  36. }
  37. /**
  38. * Test the confirmed validation rule.
  39. *
  40. * @group laravel
  41. */
  42. public function testTheConfirmedRule()
  43. {
  44. $input = array('password' => 'foo', 'password_confirmation' => 'foo');
  45. $rules = array('password' => 'confirmed');
  46. $this->assertTrue(Validator::make($input, $rules)->valid());
  47. $input['password_confirmation'] = 'foo_bar';
  48. $this->assertFalse(Validator::make($input, $rules)->valid());
  49. unset($input['password_confirmation']);
  50. $this->assertFalse(Validator::make($input, $rules)->valid());
  51. }
  52. /**
  53. * Test the different validation rule.
  54. *
  55. * @group laravel
  56. */
  57. public function testTheDifferentRule()
  58. {
  59. $input = array('password' => 'foo', 'password_confirmation' => 'bar');
  60. $rules = array('password' => 'different:password_confirmation');
  61. $this->assertTrue(Validator::make($input, $rules)->valid());
  62. $input['password_confirmation'] = 'foo';
  63. $this->assertFalse(Validator::make($input, $rules)->valid());
  64. unset($input['password_confirmation']);
  65. $this->assertFalse(Validator::make($input, $rules)->valid());
  66. }
  67. /**
  68. * Test the accepted validation rule.
  69. *
  70. * @group laravel
  71. */
  72. public function testTheAcceptedRule()
  73. {
  74. $input = array('terms' => '1');
  75. $rules = array('terms' => 'accepted');
  76. $this->assertTrue(Validator::make($input, $rules)->valid());
  77. $input['terms'] = 'yes';
  78. $this->assertTrue(Validator::make($input, $rules)->valid());
  79. $input['terms'] = '2';
  80. $this->assertFalse(Validator::make($input, $rules)->valid());
  81. // The accepted rule implies required, so should fail if field not present.
  82. unset($input['terms']);
  83. $this->assertFalse(Validator::make($input, $rules)->valid());
  84. }
  85. /**
  86. * Test the numeric validation rule.
  87. *
  88. * @group laravel
  89. */
  90. public function testTheNumericRule()
  91. {
  92. $input = array('amount' => '1.21');
  93. $rules = array('amount' => 'numeric');
  94. $this->assertTrue(Validator::make($input, $rules)->valid());
  95. $input['amount'] = '1';
  96. $this->assertTrue(Validator::make($input, $rules)->valid());
  97. $input['amount'] = 1.2;
  98. $this->assertTrue(Validator::make($input, $rules)->valid());
  99. $input['amount'] = '1.2a';
  100. $this->assertFalse(Validator::make($input, $rules)->valid());
  101. }
  102. /**
  103. * Test the integer validation rule.
  104. *
  105. * @group laravel
  106. */
  107. public function testTheIntegerRule()
  108. {
  109. $input = array('amount' => '1');
  110. $rules = array('amount' => 'integer');
  111. $this->assertTrue(Validator::make($input, $rules)->valid());
  112. $input['amount'] = '0';
  113. $this->assertTrue(Validator::make($input, $rules)->valid());
  114. $input['amount'] = 1.2;
  115. $this->assertFalse(Validator::make($input, $rules)->valid());
  116. $input['amount'] = '1.2a';
  117. $this->assertFalse(Validator::make($input, $rules)->valid());
  118. }
  119. /**
  120. * Test the size validation rule.
  121. *
  122. * @group laravel
  123. */
  124. public function testTheSizeRule()
  125. {
  126. $input = array('amount' => '1.21');
  127. $rules = array('amount' => 'numeric|size:1.21');
  128. $this->assertTrue(Validator::make($input, $rules)->valid());
  129. $rules = array('amount' => 'numeric|size:1');
  130. $this->assertFalse(Validator::make($input, $rules)->valid());
  131. // If no numeric rule is on the field, it is treated as a string
  132. $input = array('amount' => '111');
  133. $rules = array('amount' => 'size:3');
  134. $this->assertTrue(Validator::make($input, $rules)->valid());
  135. $rules = array('amount' => 'size:4');
  136. $this->assertFalse(Validator::make($input, $rules)->valid());
  137. // The size rules checks kilobytes on files
  138. $_FILES['photo']['tmp_name'] = 'foo';
  139. $_FILES['photo']['size'] = 10240;
  140. $rules = array('photo' => 'size:10');
  141. $this->assertTrue(Validator::make($_FILES, $rules)->valid());
  142. $_FILES['photo']['size'] = 14000;
  143. $this->assertFalse(Validator::make($_FILES, $rules)->valid());
  144. }
  145. /**
  146. * Test the between validation rule.
  147. *
  148. * @group laravel
  149. */
  150. public function testTheBetweenRule()
  151. {
  152. $input = array('amount' => '1.21');
  153. $rules = array('amount' => 'numeric|between:1,2');
  154. $this->assertTrue(Validator::make($input, $rules)->valid());
  155. $rules = array('amount' => 'numeric|between:2,3');
  156. $this->assertFalse(Validator::make($input, $rules)->valid());
  157. // If no numeric rule is on the field, it is treated as a string
  158. $input = array('amount' => '111');
  159. $rules = array('amount' => 'between:1,3');
  160. $this->assertTrue(Validator::make($input, $rules)->valid());
  161. $rules = array('amount' => 'between:100,111');
  162. $this->assertFalse(Validator::make($input, $rules)->valid());
  163. // The size rules checks kilobytes on files
  164. $_FILES['photo']['tmp_name'] = 'foo';
  165. $_FILES['photo']['size'] = 10240;
  166. $rules = array('photo' => 'between:9,11');
  167. $this->assertTrue(Validator::make($_FILES, $rules)->valid());
  168. $_FILES['photo']['size'] = 14000;
  169. $this->assertFalse(Validator::make($_FILES, $rules)->valid());
  170. }
  171. /**
  172. * Test the between validation rule.
  173. *
  174. * @group laravel
  175. */
  176. public function testTheMinRule()
  177. {
  178. $input = array('amount' => '1.21');
  179. $rules = array('amount' => 'numeric|min:1');
  180. $this->assertTrue(Validator::make($input, $rules)->valid());
  181. $rules = array('amount' => 'numeric|min:2');
  182. $this->assertFalse(Validator::make($input, $rules)->valid());
  183. // If no numeric rule is on the field, it is treated as a string
  184. $input = array('amount' => '01');
  185. $rules = array('amount' => 'min:2');
  186. $this->assertTrue(Validator::make($input, $rules)->valid());
  187. $rules = array('amount' => 'min:3');
  188. $this->assertFalse(Validator::make($input, $rules)->valid());
  189. // The size rules checks kilobytes on files
  190. $_FILES['photo']['tmp_name'] = 'foo';
  191. $_FILES['photo']['size'] = 10240;
  192. $rules = array('photo' => 'min:9');
  193. $this->assertTrue(Validator::make($_FILES, $rules)->valid());
  194. $_FILES['photo']['size'] = 8000;
  195. $this->assertFalse(Validator::make($_FILES, $rules)->valid());
  196. }
  197. /**
  198. * Test the between validation rule.
  199. *
  200. * @group laravel
  201. */
  202. public function testTheMaxRule()
  203. {
  204. $input = array('amount' => '1.21');
  205. $rules = array('amount' => 'numeric|max:2');
  206. $this->assertTrue(Validator::make($input, $rules)->valid());
  207. $rules = array('amount' => 'numeric|max:1');
  208. $this->assertFalse(Validator::make($input, $rules)->valid());
  209. // If no numeric rule is on the field, it is treated as a string
  210. $input = array('amount' => '01');
  211. $rules = array('amount' => 'max:3');
  212. $this->assertTrue(Validator::make($input, $rules)->valid());
  213. $rules = array('amount' => 'max:1');
  214. $this->assertFalse(Validator::make($input, $rules)->valid());
  215. // The size rules checks kilobytes on files
  216. $_FILES['photo']['tmp_name'] = 'foo';
  217. $_FILES['photo']['size'] = 10240;
  218. $rules = array('photo' => 'max:11');
  219. $this->assertTrue(Validator::make($_FILES, $rules)->valid());
  220. $_FILES['photo']['size'] = 140000;
  221. $this->assertFalse(Validator::make($_FILES, $rules)->valid());
  222. }
  223. /**
  224. * Test the in validation rule.
  225. *
  226. * @group laravel
  227. */
  228. public function testTheInRule()
  229. {
  230. $input = array('size' => 'L');
  231. $rules = array('size' => 'in:S,M,L');
  232. $this->assertTrue(Validator::make($input, $rules)->valid());
  233. $input['size'] = 'XL';
  234. $this->assertFalse(Validator::make($input, $rules)->valid());
  235. }
  236. /**
  237. * Test the not-in validation rule.
  238. *
  239. * @group laravel
  240. */
  241. public function testTheNotInRule()
  242. {
  243. $input = array('size' => 'L');
  244. $rules = array('size' => 'not_in:S,M,L');
  245. $this->assertFalse(Validator::make($input, $rules)->valid());
  246. $input['size'] = 'XL';
  247. $this->assertTrue(Validator::make($input, $rules)->valid());
  248. }
  249. /**
  250. * Test the IP validation rule.
  251. *
  252. * @group laravel
  253. */
  254. public function testTheIPRule()
  255. {
  256. $input = array('ip' => '192.168.1.1');
  257. $rules = array('ip' => 'ip');
  258. $this->assertTrue(Validator::make($input, $rules)->valid());
  259. $input['ip'] = '192.111';
  260. $this->assertFalse(Validator::make($input, $rules)->valid());
  261. }
  262. /**
  263. * Test the e-mail validation rule.
  264. *
  265. * @group laravel
  266. */
  267. public function testTheEmailRule()
  268. {
  269. $input = array('email' => 'example@gmail.com');
  270. $rules = array('email' => 'email');
  271. $this->assertTrue(Validator::make($input, $rules)->valid());
  272. $input['email'] = 'blas-asok';
  273. $this->assertFalse(Validator::make($input, $rules)->valid());
  274. }
  275. /**
  276. * Test the URL validation rule.
  277. *
  278. * @group laravel
  279. */
  280. public function testTheUrlRule()
  281. {
  282. $input = array('url' => 'http://www.google.com');
  283. $rules = array('url' => 'url');
  284. $this->assertTrue(Validator::make($input, $rules)->valid());
  285. $input['url'] = 'blas-asok';
  286. $this->assertFalse(Validator::make($input, $rules)->valid());
  287. }
  288. /**
  289. * Test the active URL validation rule.
  290. *
  291. * @group laravel
  292. */
  293. public function testTheActiveUrlRule()
  294. {
  295. $input = array('url' => 'http://google.com');
  296. $rules = array('url' => 'active_url');
  297. $this->assertTrue(Validator::make($input, $rules)->valid());
  298. $input['url'] = 'http://asdlk-aselkaiwels.com';
  299. $this->assertFalse(Validator::make($input, $rules)->valid());
  300. }
  301. /**
  302. * Test the image validation rule.
  303. *
  304. * @group laravel
  305. */
  306. public function testTheImageRule()
  307. {
  308. $_FILES['photo']['tmp_name'] = path('storage').'files/desert.jpg';
  309. $rules = array('photo' => 'image');
  310. $this->assertTrue(Validator::make($_FILES, $rules)->valid());
  311. $_FILES['photo']['tmp_name'] = path('app').'routes.php';
  312. $this->assertFalse(Validator::make($_FILES, $rules)->valid());
  313. }
  314. /**
  315. * Test the alpha validation rule.
  316. *
  317. * @group laravel
  318. */
  319. public function testTheAlphaRule()
  320. {
  321. $input = array('name' => 'TaylorOtwell');
  322. $rules = array('name' => 'alpha');
  323. $this->assertTrue(Validator::make($input, $rules)->valid());
  324. $input['name'] = 'Taylor Otwell';
  325. $this->assertFalse(Validator::make($input, $rules)->valid());
  326. }
  327. /**
  328. * Test the alpha_num validation rule.
  329. *
  330. * @group laravel
  331. */
  332. public function testTheAlphaNumRule()
  333. {
  334. $input = array('name' => 'TaylorOtwell1');
  335. $rules = array('name' => 'alpha_num');
  336. $this->assertTrue(Validator::make($input, $rules)->valid());
  337. $input['name'] = 'Taylor Otwell';
  338. $this->assertFalse(Validator::make($input, $rules)->valid());
  339. }
  340. /**
  341. * Test the alpha_num validation rule.
  342. *
  343. * @group laravel
  344. */
  345. public function testTheAlphaDashRule()
  346. {
  347. $input = array('name' => 'Taylor-Otwell_1');
  348. $rules = array('name' => 'alpha_dash');
  349. $this->assertTrue(Validator::make($input, $rules)->valid());
  350. $input['name'] = 'Taylor Otwell';
  351. $this->assertFalse(Validator::make($input, $rules)->valid());
  352. }
  353. /**
  354. * Test the mimes validation rule.
  355. *
  356. * @group laravel
  357. */
  358. public function testTheMimesRule()
  359. {
  360. $_FILES['file']['tmp_name'] = path('app').'routes.php';
  361. $rules = array('file' => 'mimes:php,txt');
  362. $this->assertTrue(Validator::make($_FILES, $rules)->valid());
  363. $rules = array('file' => 'mimes:jpg,bmp');
  364. $this->assertFalse(Validator::make($_FILES, $rules)->valid());
  365. $_FILES['file']['tmp_name'] = path('storage').'files/desert.jpg';
  366. $rules['file'] = 'mimes:jpg,bmp';
  367. $this->assertTrue(Validator::make($_FILES, $rules)->valid());
  368. $rules['file'] = 'mimes:txt,bmp';
  369. $this->assertFalse(Validator::make($_FILES, $rules)->valid());
  370. }
  371. /**
  372. * Test the unique validation rule.
  373. *
  374. * @group laravel
  375. */
  376. public function testUniqueRule()
  377. {
  378. $input = array('code' => 'ZZ');
  379. $rules = array('code' => 'unique:validation_unique');
  380. $this->assertTrue(Validator::make($input, $rules)->valid());
  381. $input = array('code' => 'AR');
  382. $this->assertFalse(Validator::make($input, $rules)->valid());
  383. $rules = array('code' => 'unique:validation_unique,code,AR,code');
  384. $this->assertTrue(Validator::make($input, $rules)->valid());
  385. }
  386. /**
  387. * Tests the exists validation rule.
  388. *
  389. * @group laravel
  390. */
  391. public function testExistsRule()
  392. {
  393. $input = array('code' => 'TX');
  394. $rules = array('code' => 'exists:validation_unique');
  395. $this->assertTrue(Validator::make($input, $rules)->valid());
  396. $input['code'] = array('TX', 'NY');
  397. $rules = array('code' => 'exists:validation_unique,code');
  398. $this->assertTrue(Validator::make($input, $rules)->valid());
  399. $input['code'] = array('TX', 'XX');
  400. $this->assertFalse(Validator::make($input, $rules)->valid());
  401. $input['code'] = 'XX';
  402. $this->assertFalse(Validator::make($input, $rules)->valid());
  403. }
  404. /**
  405. * Test that the validator sets the correct messages.
  406. *
  407. * @group laravel
  408. */
  409. public function testCorrectMessagesAreSet()
  410. {
  411. $lang = require path('app').'language/en/validation.php';
  412. $input = array('email' => 'example-foo');
  413. $rules = array('name' => 'required', 'email' => 'required|email');
  414. $v = Validator::make($input, $rules);
  415. $v->valid();
  416. $messages = $v->errors;
  417. $this->assertInstanceOf('Laravel\\Messages', $messages);
  418. $this->assertEquals(str_replace(':attribute', 'name', $lang['required']), $messages->first('name'));
  419. $this->assertEquals(str_replace(':attribute', 'email', $lang['email']), $messages->first('email'));
  420. }
  421. /**
  422. * Test that custom messages are recognized.
  423. *
  424. * @group laravel
  425. */
  426. public function testCustomMessagesAreRecognize()
  427. {
  428. $messages = array('required' => 'Required!');
  429. $rules = array('name' => 'required');
  430. $v = Validator::make(array(), $rules, $messages);
  431. $v->valid();
  432. $this->assertEquals('Required!', $v->errors->first('name'));
  433. $messages['email_required'] = 'Email Required!';
  434. $rules = array('name' => 'required', 'email' => 'required');
  435. $v = Validator::make(array(), $rules, $messages);
  436. $v->valid();
  437. $this->assertEquals('Required!', $v->errors->first('name'));
  438. $this->assertEquals('Email Required!', $v->errors->first('email'));
  439. $rules = array('custom' => 'required');
  440. $v = Validator::make(array(), $rules);
  441. $v->valid();
  442. $this->assertEquals('This field is required!', $v->errors->first('custom'));
  443. }
  444. /**
  445. * Test that size replacements are made on messages.
  446. *
  447. * @group laravel
  448. */
  449. public function testNumericSizeReplacementsAreMade()
  450. {
  451. $lang = require path('app').'language/en/validation.php';
  452. $input = array('amount' => 100);
  453. $rules = array('amount' => 'numeric|size:80');
  454. $v = Validator::make($input, $rules);
  455. $v->valid();
  456. $this->assertEquals(str_replace(array(':attribute', ':size'), array('amount', '80'), $lang['size']['numeric']), $v->errors->first('amount'));
  457. $rules = array('amount' => 'numeric|between:70,80');
  458. $v = Validator::make($input, $rules);
  459. $v->valid();
  460. $expect = str_replace(array(':attribute', ':min', ':max'), array('amount', '70', '80'), $lang['between']['numeric']);
  461. $this->assertEquals($expect, $v->errors->first('amount'));
  462. $rules = array('amount' => 'numeric|min:120');
  463. $v = Validator::make($input, $rules);
  464. $v->valid();
  465. $expect = str_replace(array(':attribute', ':min'), array('amount', '120'), $lang['min']['numeric']);
  466. $this->assertEquals($expect, $v->errors->first('amount'));
  467. $rules = array('amount' => 'numeric|max:20');
  468. $v = Validator::make($input, $rules);
  469. $v->valid();
  470. $expect = str_replace(array(':attribute', ':max'), array('amount', '20'), $lang['max']['numeric']);
  471. $this->assertEquals($expect, $v->errors->first('amount'));
  472. }
  473. /**
  474. * Test that string size replacements are made on messages.
  475. *
  476. * @group laravel
  477. */
  478. public function testStringSizeReplacementsAreMade()
  479. {
  480. $lang = require path('app').'language/en/validation.php';
  481. $input = array('amount' => '100');
  482. $rules = array('amount' => 'size:80');
  483. $v = Validator::make($input, $rules);
  484. $v->valid();
  485. $this->assertEquals(str_replace(array(':attribute', ':size'), array('amount', '80'), $lang['size']['string']), $v->errors->first('amount'));
  486. $rules = array('amount' => 'between:70,80');
  487. $v = Validator::make($input, $rules);
  488. $v->valid();
  489. $expect = str_replace(array(':attribute', ':min', ':max'), array('amount', '70', '80'), $lang['between']['string']);
  490. $this->assertEquals($expect, $v->errors->first('amount'));
  491. $rules = array('amount' => 'min:120');
  492. $v = Validator::make($input, $rules);
  493. $v->valid();
  494. $expect = str_replace(array(':attribute', ':min'), array('amount', '120'), $lang['min']['string']);
  495. $this->assertEquals($expect, $v->errors->first('amount'));
  496. $rules = array('amount' => 'max:2');
  497. $v = Validator::make($input, $rules);
  498. $v->valid();
  499. $expect = str_replace(array(':attribute', ':max'), array('amount', '2'), $lang['max']['string']);
  500. $this->assertEquals($expect, $v->errors->first('amount'));
  501. }
  502. /**
  503. * Test that string size replacements are made on messages.
  504. *
  505. * @group laravel
  506. */
  507. public function testFileSizeReplacementsAreMade()
  508. {
  509. $lang = require path('app').'language/en/validation.php';
  510. $_FILES['amount']['tmp_name'] = 'foo';
  511. $_FILES['amount']['size'] = 10000;
  512. $rules = array('amount' => 'size:80');
  513. $v = Validator::make($_FILES, $rules);
  514. $v->valid();
  515. $this->assertEquals(str_replace(array(':attribute', ':size'), array('amount', '80'), $lang['size']['file']), $v->errors->first('amount'));
  516. $rules = array('amount' => 'between:70,80');
  517. $v = Validator::make($_FILES, $rules);
  518. $v->valid();
  519. $expect = str_replace(array(':attribute', ':min', ':max'), array('amount', '70', '80'), $lang['between']['file']);
  520. $this->assertEquals($expect, $v->errors->first('amount'));
  521. $rules = array('amount' => 'min:120');
  522. $v = Validator::make($_FILES, $rules);
  523. $v->valid();
  524. $expect = str_replace(array(':attribute', ':min'), array('amount', '120'), $lang['min']['file']);
  525. $this->assertEquals($expect, $v->errors->first('amount'));
  526. $rules = array('amount' => 'max:2');
  527. $v = Validator::make($_FILES, $rules);
  528. $v->valid();
  529. $expect = str_replace(array(':attribute', ':max'), array('amount', '2'), $lang['max']['file']);
  530. $this->assertEquals($expect, $v->errors->first('amount'));
  531. }
  532. /**
  533. * Test that values get replaced in messages.
  534. *
  535. * @group laravel
  536. */
  537. public function testValuesGetReplaced()
  538. {
  539. $lang = require path('app').'language/en/validation.php';
  540. $_FILES['file']['tmp_name'] = path('storage').'files/desert.jpg';
  541. $rules = array('file' => 'mimes:php,txt');
  542. $v = Validator::make($_FILES, $rules);
  543. $v->valid();
  544. $expect = str_replace(array(':attribute', ':values'), array('file', 'php, txt'), $lang['mimes']);
  545. $this->assertEquals($expect, $v->errors->first('file'));
  546. }
  547. /**
  548. * Test custom attribute names are replaced.
  549. *
  550. * @group laravel
  551. */
  552. public function testCustomAttributesAreReplaced()
  553. {
  554. $lang = require path('app').'language/en/validation.php';
  555. $rules = array('test_attribute' => 'required');
  556. $v = Validator::make(array(), $rules);
  557. $v->valid();
  558. $expect = str_replace(':attribute', 'attribute', $lang['required']);
  559. $this->assertEquals($expect, $v->errors->first('test_attribute'));
  560. }
  561. }