2
0

ElementTest.php 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Form
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. if (!defined('PHPUnit_MAIN_METHOD')) {
  23. define('PHPUnit_MAIN_METHOD', 'Zend_Form_ElementTest::main');
  24. }
  25. // error_reporting(E_ALL);
  26. require_once 'Zend/Form/Element.php';
  27. require_once 'Zend/Config.php';
  28. require_once 'Zend/Controller/Action/HelperBroker.php';
  29. require_once 'Zend/Form.php';
  30. require_once 'Zend/Form/Decorator/Abstract.php';
  31. require_once 'Zend/Form/Decorator/HtmlTag.php';
  32. require_once 'Zend/Loader/PluginLoader.php';
  33. require_once 'Zend/Registry.php';
  34. require_once 'Zend/Translate.php';
  35. require_once 'Zend/Validate/NotEmpty.php';
  36. require_once 'Zend/Validate/EmailAddress.php';
  37. require_once 'Zend/View.php';
  38. /**
  39. * @category Zend
  40. * @package Zend_Form
  41. * @subpackage UnitTests
  42. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  43. * @license http://framework.zend.com/license/new-bsd New BSD License
  44. * @group Zend_Form
  45. */
  46. class Zend_Form_ElementTest extends PHPUnit_Framework_TestCase
  47. {
  48. public static function main()
  49. {
  50. $suite = new PHPUnit_Framework_TestSuite('Zend_Form_ElementTest');
  51. $result = PHPUnit_TextUI_TestRunner::run($suite);
  52. }
  53. public function setUp()
  54. {
  55. Zend_Registry::_unsetInstance();
  56. Zend_Form::setDefaultTranslator(null);
  57. if (isset($this->error)) {
  58. unset($this->error);
  59. }
  60. $this->element = new Zend_Form_Element('foo');
  61. Zend_Controller_Action_HelperBroker::resetHelpers();
  62. }
  63. public function tearDown()
  64. {
  65. }
  66. public function getView()
  67. {
  68. $view = new Zend_View();
  69. $libPath = dirname(__FILE__) . '/../../../library';
  70. $view->addHelperPath($libPath . '/Zend/View/Helper');
  71. return $view;
  72. }
  73. public function testConstructorRequiresMinimallyElementName()
  74. {
  75. try {
  76. $element = new Zend_Form_Element(1);
  77. $this->fail('Zend_Form_Element constructor should not accept integer argument');
  78. } catch (Zend_Form_Exception $e) {
  79. }
  80. try {
  81. $element = new Zend_Form_Element(true);
  82. $this->fail('Zend_Form_Element constructor should not accept boolean argument');
  83. } catch (Zend_Form_Exception $e) {
  84. }
  85. try {
  86. $element = new Zend_Form_Element('foo');
  87. } catch (Exception $e) {
  88. $this->fail('Zend_Form_Element constructor should accept String values');
  89. }
  90. $config = array('foo' => 'bar');
  91. try {
  92. $element = new Zend_Form_Element($config);
  93. $this->fail('Zend_Form_Element constructor requires array with name element');
  94. } catch (Zend_Form_Exception $e) {
  95. }
  96. $config = array('name' => 'bar');
  97. try {
  98. $element = new Zend_Form_Element($config);
  99. } catch (Zend_Form_Exception $e) {
  100. $this->fail('Zend_Form_Element constructor should accept array with name element');
  101. }
  102. $config = new Zend_Config(array('foo' => 'bar'));
  103. try {
  104. $element = new Zend_Form_Element($config);
  105. $this->fail('Zend_Form_Element constructor requires Zend_Config object with name element');
  106. } catch (Zend_Form_Exception $e) {
  107. }
  108. $config = new Zend_Config(array('name' => 'bar'));
  109. try {
  110. $element = new Zend_Form_Element($config);
  111. } catch (Zend_Form_Exception $e) {
  112. $this->fail('Zend_Form_Element constructor should accept Zend_Config with name element');
  113. }
  114. }
  115. public function testNoTranslatorByDefault()
  116. {
  117. $this->assertNull($this->element->getTranslator());
  118. }
  119. public function testGetTranslatorRetrievesGlobalDefaultWhenAvailable()
  120. {
  121. $this->testNoTranslatorByDefault();
  122. $translator = new Zend_Translate('array', array('foo' => 'bar'));
  123. Zend_Form::setDefaultTranslator($translator);
  124. $received = $this->element->getTranslator();
  125. $this->assertSame($translator->getAdapter(), $received);
  126. }
  127. public function testTranslatorAccessorsWork()
  128. {
  129. $translator = new Zend_Translate('array', array('foo' => 'bar'));
  130. $this->element->setTranslator($translator);
  131. $received = $this->element->getTranslator($translator);
  132. $this->assertSame($translator->getAdapter(), $received);
  133. }
  134. public function testCanDisableTranslation()
  135. {
  136. $this->testGetTranslatorRetrievesGlobalDefaultWhenAvailable();
  137. $this->element->setDisableTranslator(true);
  138. $this->assertNull($this->element->getTranslator());
  139. }
  140. public function testSetNameNormalizesValueToContainOnlyValidVariableCharacters()
  141. {
  142. $this->element->setName('f%\o^&*)o\(%$b#@!.a}{;-,r');
  143. $this->assertEquals('foobar', $this->element->getName());
  144. try {
  145. $this->element->setName('%\^&*)\(%$#@!.}{;-,');
  146. $this->fail('Empty names should raise exception');
  147. } catch (Zend_Form_Exception $e) {
  148. $this->assertContains('Invalid name provided', $e->getMessage());
  149. }
  150. }
  151. public function testZeroIsAllowedAsElementName()
  152. {
  153. try {
  154. $this->element->setName(0);
  155. $this->assertSame('0', $this->element->getName());
  156. } catch (Zend_Form_Exception $e) {
  157. $this->fail('Should allow zero as element name');
  158. }
  159. }
  160. /**
  161. * @group ZF-2851
  162. */
  163. public function testSetNameShouldNotAllowEmptyString()
  164. {
  165. foreach (array('', ' ', ' ') as $name) {
  166. try {
  167. $this->element->setName($name);
  168. $this->fail('setName() should not allow empty string');
  169. } catch (Zend_Form_Exception $e) {
  170. $this->assertContains('Invalid name', $e->getMessage());
  171. }
  172. }
  173. }
  174. public function testElementValueInitiallyNull()
  175. {
  176. $this->assertNull($this->element->getValue());
  177. }
  178. public function testValueAccessorsWork()
  179. {
  180. $this->element->setValue('bar');
  181. $this->assertContains('bar', $this->element->getValue());
  182. }
  183. public function testGetValueFiltersValue()
  184. {
  185. $this->element->setValue('This 0 is 1 a-2-TEST')
  186. ->addFilter('alnum')
  187. ->addFilter('stringToUpper');
  188. $test = $this->element->getValue();
  189. $this->assertEquals('THIS0IS1A2TEST', $test);
  190. }
  191. public function checkFilterValues($item, $key)
  192. {
  193. $this->assertRegexp('/^[A-Z]+$/', $item);
  194. }
  195. public function testRetrievingArrayValueFiltersAllArrayValues()
  196. {
  197. $this->element->setValue(array(
  198. 'foo',
  199. array(
  200. 'bar',
  201. 'baz'
  202. ),
  203. 'bat'
  204. ))
  205. ->setIsArray(true)
  206. ->addFilter('StringToUpper');
  207. $test = $this->element->getValue();
  208. $this->assertTrue(is_array($test));
  209. array_walk_recursive($test, array($this, 'checkFilterValues'));
  210. }
  211. public function testRetrievingArrayValueDoesNotFilterAllValuesWhenNotIsArray()
  212. {
  213. $values = array(
  214. 'foo',
  215. array(
  216. 'bar',
  217. 'baz'
  218. ),
  219. 'bat'
  220. );
  221. $this->element->setValue($values)
  222. ->addFilter(new Zend_Form_ElementTest_ArrayFilter());
  223. $test = $this->element->getValue();
  224. $this->assertTrue(is_array($test));
  225. require_once 'Zend/Json.php';
  226. $test = Zend_Json::encode($test);
  227. $this->assertNotContains('foo', $test);
  228. foreach (array('bar', 'baz', 'bat') as $value) {
  229. $this->assertContains($value, $test);
  230. }
  231. }
  232. public function testGetUnfilteredValueRetrievesOriginalValue()
  233. {
  234. $this->element->setValue('bar');
  235. $this->assertSame('bar', $this->element->getUnfilteredValue());
  236. }
  237. public function testLabelInitiallyNull()
  238. {
  239. $this->assertNull($this->element->getLabel());
  240. }
  241. public function testLabelAccessorsWork()
  242. {
  243. $this->element->setLabel('FooBar');
  244. $this->assertEquals('FooBar', $this->element->getLabel());
  245. }
  246. public function testOrderNullByDefault()
  247. {
  248. $this->assertNull($this->element->getOrder());
  249. }
  250. public function testCanSetOrder()
  251. {
  252. $this->testOrderNullByDefault();
  253. $this->element->setOrder(50);
  254. $this->assertEquals(50, $this->element->getOrder());
  255. }
  256. public function testRequiredFlagFalseByDefault()
  257. {
  258. $this->assertFalse($this->element->isRequired());
  259. }
  260. public function testRequiredAcccessorsWork()
  261. {
  262. $this->assertFalse($this->element->isRequired());
  263. $this->element->setRequired(true);
  264. $this->assertTrue($this->element->isRequired());
  265. }
  266. public function testIsValidInsertsNotEmptyValidatorWhenElementIsRequiredByDefault()
  267. {
  268. $this->_checkZf2794();
  269. $this->element->setRequired(true);
  270. $this->assertFalse($this->element->isValid(''));
  271. $validator = $this->element->getValidator('NotEmpty');
  272. $this->assertTrue($validator instanceof Zend_Validate_NotEmpty);
  273. $this->assertTrue($validator->zfBreakChainOnFailure);
  274. }
  275. /**
  276. * @group ZF-2862
  277. */
  278. public function testBreakChainOnFailureFlagsForExistingValidatorsRemainSetWhenNotEmptyValidatorAutoInserted()
  279. {
  280. $this->_checkZf2794();
  281. $username = new Zend_Form_Element('username');
  282. $username->addValidator('stringLength', true, array(5, 20))
  283. ->addValidator('regex', true, array('/^[a-zA-Z0-9_]*$/'))
  284. ->addFilter('StringToLower')
  285. ->setRequired(true);
  286. $form = new Zend_Form(array('elements' => array($username)));
  287. $form->isValid(array('username' => '#'));
  288. $validator = $username->getValidator('stringLength');
  289. $this->assertTrue($validator->zfBreakChainOnFailure);
  290. $validator = $username->getValidator('regex');
  291. $this->assertTrue($validator->zfBreakChainOnFailure);
  292. }
  293. public function testAutoInsertNotEmptyValidatorFlagTrueByDefault()
  294. {
  295. $this->assertTrue($this->element->autoInsertNotEmptyValidator());
  296. }
  297. public function testCanSetAutoInsertNotEmptyValidatorFlag()
  298. {
  299. $this->testAutoInsertNotEmptyValidatorFlagTrueByDefault();
  300. $this->element->setAutoInsertNotEmptyValidator(false);
  301. $this->assertFalse($this->element->autoInsertNotEmptyValidator());
  302. $this->element->setAutoInsertNotEmptyValidator(true);
  303. $this->assertTrue($this->element->autoInsertNotEmptyValidator());
  304. }
  305. public function testIsValidDoesNotInsertNotEmptyValidatorWhenElementIsRequiredButAutoInsertNotEmptyValidatorFlagIsFalse()
  306. {
  307. $this->element->setAutoInsertNotEmptyValidator(false)
  308. ->setRequired(true);
  309. $this->assertTrue($this->element->isValid(''));
  310. }
  311. public function testDescriptionInitiallyNull()
  312. {
  313. $this->assertNull($this->element->getDescription());
  314. }
  315. public function testCanSetDescription()
  316. {
  317. $this->testDescriptionInitiallyNull();
  318. $this->element->setDescription('element hint');
  319. $this->assertEquals('element hint', $this->element->getDescription());
  320. }
  321. public function testElementIsNotArrayByDefault()
  322. {
  323. $this->assertFalse($this->element->isArray());
  324. }
  325. public function testCanSetArrayFlag()
  326. {
  327. $this->testElementIsNotArrayByDefault();
  328. $this->element->setIsArray(true);
  329. $this->assertTrue($this->element->isArray());
  330. $this->element->setIsArray(false);
  331. $this->assertFalse($this->element->isArray());
  332. }
  333. public function testElementBelongsToNullByDefault()
  334. {
  335. $this->assertNull($this->element->getBelongsTo());
  336. }
  337. public function testCanSetArrayElementBelongsTo()
  338. {
  339. $this->testElementBelongsToNullByDefault();
  340. $this->element->setBelongsTo('foo');
  341. $this->assertEquals('foo', $this->element->getBelongsTo());
  342. }
  343. public function testArrayElementBelongsToNormalizedToValidVariableCharactersOnly()
  344. {
  345. $this->testElementBelongsToNullByDefault();
  346. $this->element->setBelongsTo('f%\o^&*)o\(%$b#@!.a}{;-,r');
  347. $this->assertEquals('foobar', $this->element->getBelongsTo());
  348. }
  349. public function testGetTypeReturnsCurrentElementClass()
  350. {
  351. $this->assertEquals('Zend_Form_Element', $this->element->getType());
  352. }
  353. public function testCanUseAccessorsToSetIndidualAttribs()
  354. {
  355. $this->element->setAttrib('foo', 'bar')
  356. ->setAttrib('bar', 'baz')
  357. ->setAttrib('baz', 'bat');
  358. $this->assertEquals('bar', $this->element->getAttrib('foo'));
  359. $this->assertEquals('baz', $this->element->getAttrib('bar'));
  360. $this->assertEquals('bat', $this->element->getAttrib('baz'));
  361. }
  362. public function testGetUndefinedAttribShouldReturnNull()
  363. {
  364. $this->assertNull($this->element->getAttrib('bogus'));
  365. }
  366. public function testSetAttribThrowsExceptionsForKeysWithLeadingUnderscores()
  367. {
  368. try {
  369. $this->element->setAttrib('_foo', 'bar');
  370. $this->fail('setAttrib() should throw an exception for invalid keys');
  371. } catch (Zend_Form_Exception $e) {
  372. $this->assertContains('Invalid attribute', $e->getMessage());
  373. }
  374. }
  375. public function testPassingNullValueToSetAttribUnsetsAttrib()
  376. {
  377. $this->element->setAttrib('foo', 'bar');
  378. $this->assertEquals('bar', $this->element->getAttrib('foo'));
  379. $this->element->setAttrib('foo', null);
  380. $this->assertFalse(isset($this->element->foo));
  381. }
  382. public function testSetAttribsSetsMultipleAttribs()
  383. {
  384. $this->element->setAttribs(array(
  385. 'foo' => 'bar',
  386. 'bar' => 'baz',
  387. 'baz' => 'bat'
  388. ));
  389. $this->assertEquals('bar', $this->element->getAttrib('foo'));
  390. $this->assertEquals('baz', $this->element->getAttrib('bar'));
  391. $this->assertEquals('bat', $this->element->getAttrib('baz'));
  392. }
  393. public function testGetAttribsRetrievesAllAttributes()
  394. {
  395. $attribs = array(
  396. 'foo' => 'bar',
  397. 'bar' => 'baz',
  398. 'baz' => 'bat'
  399. );
  400. $this->element->setAttribs($attribs);
  401. $attribs['helper'] = 'formText';
  402. $received = $this->element->getAttribs();
  403. $this->assertEquals($attribs, $received);
  404. }
  405. public function testPassingNullValuesToSetAttribsUnsetsAttribs()
  406. {
  407. $this->testSetAttribsSetsMultipleAttribs();
  408. $this->element->setAttribs(array('foo' => null));
  409. $this->assertNull($this->element->foo);
  410. }
  411. public function testRetrievingOverloadedValuesThrowsExceptionWithInvalidKey()
  412. {
  413. try {
  414. $name = $this->element->_name;
  415. $this->fail('Overloading should not return protected or private members');
  416. } catch (Zend_Form_Exception $e) {
  417. $this->assertContains('Cannot retrieve value for protected/private', $e->getMessage());
  418. }
  419. }
  420. public function testCanSetAndRetrieveAttribsViaOverloading()
  421. {
  422. $this->element->foo = 'bar';
  423. $this->assertEquals('bar', $this->element->foo);
  424. }
  425. public function testGetPluginLoaderRetrievesDefaultValidatorPluginLoader()
  426. {
  427. $loader = $this->element->getPluginLoader('validate');
  428. $this->assertTrue($loader instanceof Zend_Loader_PluginLoader);
  429. $paths = $loader->getPaths('Zend_Validate');
  430. $this->assertTrue(is_array($paths), var_export($loader, 1));
  431. $this->assertTrue(0 < count($paths));
  432. $this->assertContains('Validate', $paths[0]);
  433. }
  434. public function testGetPluginLoaderRetrievesDefaultFilterPluginLoader()
  435. {
  436. $loader = $this->element->getPluginLoader('filter');
  437. $this->assertTrue($loader instanceof Zend_Loader_PluginLoader);
  438. $paths = $loader->getPaths('Zend_Filter');
  439. $this->assertTrue(is_array($paths));
  440. $this->assertTrue(0 < count($paths));
  441. $this->assertContains('Filter', $paths[0]);
  442. }
  443. public function testGetPluginLoaderRetrievesDefaultDecoratorPluginLoader()
  444. {
  445. $loader = $this->element->getPluginLoader('decorator');
  446. $this->assertTrue($loader instanceof Zend_Loader_PluginLoader);
  447. $paths = $loader->getPaths('Zend_Form_Decorator');
  448. $this->assertTrue(is_array($paths));
  449. $this->assertTrue(0 < count($paths));
  450. $this->assertContains('Decorator', $paths[0]);
  451. }
  452. public function testCanSetCustomValidatorPluginLoader()
  453. {
  454. $loader = new Zend_Loader_PluginLoader();
  455. $this->element->setPluginLoader($loader, 'validate');
  456. $test = $this->element->getPluginLoader('validate');
  457. $this->assertSame($loader, $test);
  458. }
  459. public function testPassingInvalidTypeToSetPluginLoaderThrowsException()
  460. {
  461. $loader = new Zend_Loader_PluginLoader();
  462. try {
  463. $this->element->setPluginLoader($loader, 'foo');
  464. $this->fail('Invalid loader type should raise exception');
  465. } catch (Zend_Form_Exception $e) {
  466. $this->assertContains('Invalid type', $e->getMessage());
  467. }
  468. }
  469. public function testPassingInvalidTypeToGetPluginLoaderThrowsException()
  470. {
  471. try {
  472. $this->element->getPluginLoader('foo');
  473. $this->fail('Invalid loader type should raise exception');
  474. } catch (Zend_Form_Exception $e) {
  475. $this->assertContains('Invalid type', $e->getMessage());
  476. }
  477. }
  478. public function testCanSetCustomFilterPluginLoader()
  479. {
  480. $loader = new Zend_Loader_PluginLoader();
  481. $this->element->setPluginLoader($loader, 'filter');
  482. $test = $this->element->getPluginLoader('filter');
  483. $this->assertSame($loader, $test);
  484. }
  485. public function testCanSetCustomDecoratorPluginLoader()
  486. {
  487. $loader = new Zend_Loader_PluginLoader();
  488. $this->element->setPluginLoader($loader, 'decorator');
  489. $test = $this->element->getPluginLoader('decorator');
  490. $this->assertSame($loader, $test);
  491. }
  492. public function testPassingInvalidLoaderTypeToAddPrefixPathThrowsException()
  493. {
  494. try {
  495. $this->element->addPrefixPath('Zend_Foo', 'Zend/Foo/', 'foo');
  496. $this->fail('Invalid loader type should raise exception');
  497. } catch (Zend_Form_Exception $e) {
  498. $this->assertContains('Invalid type', $e->getMessage());
  499. }
  500. }
  501. public function testCanAddValidatorPluginLoaderPrefixPath()
  502. {
  503. $loader = $this->element->getPluginLoader('validate');
  504. $this->element->addPrefixPath('Zend_Form', 'Zend/Form/', 'validate');
  505. $paths = $loader->getPaths('Zend_Form');
  506. $this->assertTrue(is_array($paths));
  507. $this->assertContains('Form', $paths[0]);
  508. }
  509. public function testAddingValidatorPluginLoaderPrefixPathDoesNotAffectOtherLoaders()
  510. {
  511. $validateLoader = $this->element->getPluginLoader('validate');
  512. $filterLoader = $this->element->getPluginLoader('filter');
  513. $decoratorLoader = $this->element->getPluginLoader('decorator');
  514. $this->element->addPrefixPath('Zend_Form', 'Zend/Form/', 'validate');
  515. $this->assertFalse($filterLoader->getPaths('Zend_Form'));
  516. $this->assertFalse($decoratorLoader->getPaths('Zend_Form'));
  517. }
  518. public function testCanAddFilterPluginLoaderPrefixPath()
  519. {
  520. $loader = $this->element->getPluginLoader('validate');
  521. $this->element->addPrefixPath('Zend_Form', 'Zend/Form/', 'validate');
  522. $paths = $loader->getPaths('Zend_Form');
  523. $this->assertTrue(is_array($paths));
  524. $this->assertContains('Form', $paths[0]);
  525. }
  526. public function testAddingFilterPluginLoaderPrefixPathDoesNotAffectOtherLoaders()
  527. {
  528. $filterLoader = $this->element->getPluginLoader('filter');
  529. $validateLoader = $this->element->getPluginLoader('validate');
  530. $decoratorLoader = $this->element->getPluginLoader('decorator');
  531. $this->element->addPrefixPath('Zend_Form', 'Zend/Form/', 'filter');
  532. $this->assertFalse($validateLoader->getPaths('Zend_Form'));
  533. $this->assertFalse($decoratorLoader->getPaths('Zend_Form'));
  534. }
  535. public function testCanAddDecoratorPluginLoaderPrefixPath()
  536. {
  537. $loader = $this->element->getPluginLoader('decorator');
  538. $this->element->addPrefixPath('Zend_Foo', 'Zend/Foo/', 'decorator');
  539. $paths = $loader->getPaths('Zend_Foo');
  540. $this->assertTrue(is_array($paths));
  541. $this->assertContains('Foo', $paths[0]);
  542. }
  543. public function testAddingDecoratorrPluginLoaderPrefixPathDoesNotAffectOtherLoaders()
  544. {
  545. $decoratorLoader = $this->element->getPluginLoader('decorator');
  546. $filterLoader = $this->element->getPluginLoader('filter');
  547. $validateLoader = $this->element->getPluginLoader('validate');
  548. $this->element->addPrefixPath('Zend_Foo', 'Zend/Foo/', 'decorator');
  549. $this->assertFalse($validateLoader->getPaths('Zend_Foo'));
  550. $this->assertFalse($filterLoader->getPaths('Zend_Foo'));
  551. }
  552. public function testCanAddAllPluginLoaderPrefixPathsSimultaneously()
  553. {
  554. $validatorLoader = new Zend_Loader_PluginLoader();
  555. $filterLoader = new Zend_Loader_PluginLoader();
  556. $decoratorLoader = new Zend_Loader_PluginLoader();
  557. $this->element->setPluginLoader($validatorLoader, 'validate')
  558. ->setPluginLoader($filterLoader, 'filter')
  559. ->setPluginLoader($decoratorLoader, 'decorator')
  560. ->addPrefixPath('Zend', 'Zend/');
  561. $paths = $filterLoader->getPaths('Zend_Filter');
  562. $this->assertTrue(is_array($paths));
  563. $this->assertContains('Filter', $paths[0]);
  564. $paths = $validatorLoader->getPaths('Zend_Validate');
  565. $this->assertTrue(is_array($paths));
  566. $this->assertContains('Validate', $paths[0]);
  567. $paths = $decoratorLoader->getPaths('Zend_Decorator');
  568. $this->assertTrue(is_array($paths), var_export($paths, 1));
  569. $this->assertContains('Decorator', $paths[0]);
  570. }
  571. public function testPassingInvalidValidatorToAddValidatorThrowsException()
  572. {
  573. try {
  574. $this->element->addValidator(123);
  575. $this->fail('Invalid validator should raise exception');
  576. } catch (Zend_Form_Exception $e) {
  577. $this->assertContains('Invalid validator', $e->getMessage());
  578. }
  579. }
  580. public function testCanAddSingleValidatorAsString()
  581. {
  582. $this->_checkZf2794();
  583. $this->assertFalse($this->element->getValidator('digits'));
  584. $this->element->addValidator('digits');
  585. $validator = $this->element->getValidator('digits');
  586. $this->assertTrue($validator instanceof Zend_Validate_Digits, var_export($validator, 1));
  587. $this->assertFalse($validator->zfBreakChainOnFailure);
  588. }
  589. public function testCanNotRetrieveSingleValidatorRegisteredAsStringUsingClassName()
  590. {
  591. $this->assertFalse($this->element->getValidator('digits'));
  592. $this->element->addValidator('digits');
  593. $this->assertFalse($this->element->getValidator('Zend_Validate_Digits'));
  594. }
  595. public function testCanAddSingleValidatorAsValidatorObject()
  596. {
  597. $this->assertFalse($this->element->getValidator('Zend_Validate_Digits'));
  598. require_once 'Zend/Validate/Digits.php';
  599. $validator = new Zend_Validate_Digits();
  600. $this->element->addValidator($validator);
  601. $test = $this->element->getValidator('Zend_Validate_Digits');
  602. $this->assertSame($validator, $test);
  603. $this->assertFalse($validator->zfBreakChainOnFailure);
  604. }
  605. public function testOptionsAreCastToArrayWhenAddingValidator()
  606. {
  607. $this->_checkZf2794();
  608. try {
  609. $this->element->addValidator('Alnum', false, true);
  610. } catch (Exception $e) {
  611. $this->fail('Should be able to add non-array validator options');
  612. }
  613. $validator = $this->element->getValidator('Alnum');
  614. $this->assertTrue($validator instanceof Zend_Validate_Alnum);
  615. $this->assertTrue($validator->allowWhiteSpace);
  616. }
  617. public function testCanRetrieveSingleValidatorRegisteredAsValidatorObjectUsingShortName()
  618. {
  619. $this->_checkZf2794();
  620. $this->assertFalse($this->element->getValidator('digits'));
  621. require_once 'Zend/Validate/Digits.php';
  622. $validator = new Zend_Validate_Digits();
  623. $this->element->addValidator($validator);
  624. $test = $this->element->getValidator('digits');
  625. $this->assertSame($validator, $test);
  626. $this->assertFalse($validator->zfBreakChainOnFailure);
  627. }
  628. public function testRetrievingNamedValidatorShouldNotReorderValidators()
  629. {
  630. $this->element->addValidators(array(
  631. 'NotEmpty',
  632. 'Alnum',
  633. 'Digits',
  634. ));
  635. $validator = $this->element->getValidator('Alnum');
  636. $validators = $this->element->getValidators();
  637. $i = 0;
  638. $order = array();
  639. foreach (array_keys($validators) as $name) {
  640. $order[$name] = $i;
  641. ++$i;
  642. }
  643. $this->assertEquals(1, $order['Zend_Validate_Alnum'], var_export($order, 1));
  644. }
  645. public function testCanAddMultipleValidators()
  646. {
  647. $this->_checkZf2794();
  648. $this->assertFalse($this->element->getValidator('Zend_Validate_Digits'));
  649. $this->assertFalse($this->element->getValidator('Zend_Validate_Alnum'));
  650. $this->element->addValidators(array('digits', 'alnum'));
  651. $digits = $this->element->getValidator('digits');
  652. $this->assertTrue($digits instanceof Zend_Validate_Digits);
  653. $alnum = $this->element->getValidator('alnum');
  654. $this->assertTrue($alnum instanceof Zend_Validate_Alnum);
  655. }
  656. public function testRemovingUnregisteredValidatorReturnsObjectInstance()
  657. {
  658. $this->assertSame($this->element, $this->element->removeValidator('bogus'));
  659. }
  660. public function testPassingMessagesOptionToAddValidatorSetsValidatorMessages()
  661. {
  662. $messageTemplates = array(
  663. Zend_Validate_Digits::NOT_DIGITS => 'Value should only contain digits',
  664. Zend_Validate_Digits::STRING_EMPTY => 'Value needs some digits',
  665. );
  666. $this->element->setAllowEmpty(false)
  667. ->addValidator('digits', false, array('messages' => $messageTemplates));
  668. $this->element->isValid('');
  669. $messages = $this->element->getMessages();
  670. $found = false;
  671. foreach ($messages as $key => $message) {
  672. if ($key == Zend_Validate_Digits::STRING_EMPTY) {
  673. $found = true;
  674. break;
  675. }
  676. }
  677. $this->assertTrue($found, 'Empty string message not found: ' . var_export($messages, 1));
  678. $this->assertEquals($messageTemplates[Zend_Validate_Digits::STRING_EMPTY], $message);
  679. $this->element->isValid('abc');
  680. $messages = $this->element->getMessages();
  681. $found = false;
  682. foreach ($messages as $key => $message) {
  683. if ($key == Zend_Validate_Digits::NOT_DIGITS) {
  684. $found = true;
  685. break;
  686. }
  687. }
  688. $this->assertTrue($found, 'Not digits message not found');
  689. $this->assertEquals($messageTemplates[Zend_Validate_Digits::NOT_DIGITS], $message);
  690. }
  691. public function testCanPassSingleMessageToValidatorToSetValidatorMessages()
  692. {
  693. $this->_checkZf2794();
  694. $message = 'My custom empty message';
  695. $this->element->addValidator('notEmpty', false, array('messages' => $message))
  696. ->setRequired(true);
  697. $this->element->isValid('');
  698. $messages = $this->element->getMessages();
  699. $this->assertEquals(1, count($messages));
  700. $this->assertEquals($message, current($messages));
  701. }
  702. public function testMessagesAreTranslatedForCurrentLocale()
  703. {
  704. $localeFile = dirname(__FILE__) . '/_files/locale/array.php';
  705. $translations = include($localeFile);
  706. $translator = new Zend_Translate('array', $translations, 'en');
  707. $translator->setLocale('en');
  708. $this->element->setAllowEmpty(false)
  709. ->setTranslator($translator)
  710. ->addValidator('digits');
  711. $this->element->isValid('');
  712. $messages = $this->element->getMessages();
  713. $found = false;
  714. foreach ($messages as $key => $message) {
  715. if ($key == 'digitsStringEmpty') {
  716. $found = true;
  717. break;
  718. }
  719. }
  720. $this->assertTrue($found, 'String Empty message not found: ' . var_export($messages, 1));
  721. $this->assertEquals($translations['stringEmpty'], $message);
  722. $this->element->isValid('abc');
  723. $messages = $this->element->getMessages();
  724. $found = false;
  725. foreach ($messages as $key => $message) {
  726. if ($key == 'notDigits') {
  727. $found = true;
  728. break;
  729. }
  730. }
  731. $this->assertTrue($found, 'Not Digits message not found');
  732. $this->assertEquals($translations['notDigits'], $message);
  733. }
  734. /**#@+
  735. * @group ZF-2988
  736. */
  737. public function testSettingErrorMessageShouldOverrideValidationErrorMessages()
  738. {
  739. $this->element->addValidator('Alpha');
  740. $this->element->addErrorMessage('Invalid value entered');
  741. $this->assertFalse($this->element->isValid(123));
  742. $messages = $this->element->getMessages();
  743. $this->assertEquals(1, count($messages));
  744. $this->assertEquals('Invalid value entered', array_shift($messages));
  745. }
  746. public function testCustomErrorMessagesShouldBeManagedInAStack()
  747. {
  748. $this->element->addValidator('Alpha');
  749. $this->element->addErrorMessage('Invalid value entered');
  750. $this->element->addErrorMessage('Really, it is not valid');
  751. $messages = $this->element->getErrorMessages();
  752. $this->assertEquals(2, count($messages));
  753. $this->assertFalse($this->element->isValid(123));
  754. $messages = $this->element->getMessages();
  755. $this->assertEquals(2, count($messages));
  756. $this->assertEquals('Invalid value entered', array_shift($messages));
  757. $this->assertEquals('Really, it is not valid', array_shift($messages));
  758. }
  759. public function testShouldAllowSettingMultipleErrorMessagesAtOnce()
  760. {
  761. $set1 = array('foo', 'bar', 'baz');
  762. $this->element->addErrorMessages($set1);
  763. $this->assertSame($set1, $this->element->getErrorMessages());
  764. }
  765. public function testSetErrorMessagesShouldOverwriteMessages()
  766. {
  767. $set1 = array('foo', 'bar', 'baz');
  768. $set2 = array('bat', 'cat');
  769. $this->element->addErrorMessages($set1);
  770. $this->assertSame($set1, $this->element->getErrorMessages());
  771. $this->element->setErrorMessages($set2);
  772. $this->assertSame($set2, $this->element->getErrorMessages());
  773. }
  774. public function testCustomErrorMessageStackShouldBeClearable()
  775. {
  776. $this->testCustomErrorMessagesShouldBeManagedInAStack();
  777. $this->element->clearErrorMessages();
  778. $messages = $this->element->getErrorMessages();
  779. $this->assertTrue(empty($messages));
  780. }
  781. public function testCustomErrorMessagesShouldBeTranslated()
  782. {
  783. $translations = array(
  784. 'foo' => 'Foo message',
  785. );
  786. $translate = new Zend_Translate('array', $translations);
  787. $this->element->setTranslator($translate)
  788. ->addErrorMessage('foo')
  789. ->addValidator('Alpha');
  790. $this->assertFalse($this->element->isValid(123));
  791. $messages = $this->element->getMessages();
  792. $this->assertEquals(1, count($messages));
  793. $this->assertEquals('Foo message', array_shift($messages));
  794. }
  795. public function testCustomErrorMessagesShouldAllowValueSubstitution()
  796. {
  797. $this->element->addErrorMessage('"%value%" is an invalid value')
  798. ->addValidator('Alpha');
  799. $this->assertFalse($this->element->isValid(123));
  800. $this->assertTrue($this->element->hasErrors());
  801. $messages = $this->element->getMessages();
  802. $this->assertEquals(1, count($messages));
  803. $this->assertEquals('"123" is an invalid value', array_shift($messages));
  804. }
  805. public function testShouldAllowMarkingElementAsInvalid()
  806. {
  807. $this->element->setValue('foo');
  808. $this->element->addErrorMessage('Invalid value entered');
  809. $this->assertFalse($this->element->hasErrors());
  810. $this->element->markAsError();
  811. $this->assertTrue($this->element->hasErrors());
  812. $messages = $this->element->getMessages();
  813. $this->assertEquals(1, count($messages));
  814. $this->assertEquals('Invalid value entered', array_shift($messages));
  815. }
  816. public function testShouldAllowPushingErrorsOntoErrorStackWithErrorMessages()
  817. {
  818. $this->element->setValue('foo');
  819. $this->assertFalse($this->element->hasErrors());
  820. $this->element->setErrors(array('Error 1', 'Error 2'))
  821. ->addError('Error 3')
  822. ->addErrors(array('Error 4', 'Error 5'));
  823. $this->assertTrue($this->element->hasErrors());
  824. $messages = $this->element->getMessages();
  825. $this->assertEquals(5, count($messages));
  826. foreach (range(1, 5) as $id) {
  827. $message = 'Error ' . $id;
  828. $this->assertContains($message, $messages);
  829. }
  830. }
  831. public function testHasErrorsShouldIndicateStatusOfValidationErrors()
  832. {
  833. $this->element->setValue('foo');
  834. $this->assertFalse($this->element->hasErrors());
  835. $this->element->markAsError();
  836. $this->assertTrue($this->element->hasErrors());
  837. }
  838. /**#@-*/
  839. public function testAddingErrorToArrayElementShouldLoopOverAllValues()
  840. {
  841. $this->element->setIsArray(true)
  842. ->setValue(array('foo', 'bar', 'baz'))
  843. ->addError('error with value %value%');
  844. $errors = $this->element->getMessages();
  845. require_once 'Zend/Json.php';
  846. $errors = Zend_Json::encode($errors);
  847. foreach (array('foo', 'bar', 'baz') as $value) {
  848. $message = 'error with value ' . $value;
  849. $this->assertContains($message, $errors);
  850. }
  851. }
  852. /** ZF-2568 */
  853. public function testTranslatedMessagesCanContainVariableSubstitution()
  854. {
  855. $localeFile = dirname(__FILE__) . '/_files/locale/array.php';
  856. $translations = include($localeFile);
  857. $translations['notDigits'] .= ' "%value%"';
  858. $translator = new Zend_Translate('array', $translations, 'en');
  859. $translator->setLocale('en');
  860. $this->element->setAllowEmpty(false)
  861. ->setTranslator($translator)
  862. ->addValidator('digits');
  863. $this->element->isValid('abc');
  864. $messages = $this->element->getMessages();
  865. $found = false;
  866. foreach ($messages as $key => $message) {
  867. if ($key == 'notDigits') {
  868. $found = true;
  869. break;
  870. }
  871. }
  872. $this->assertTrue($found, 'String Empty message not found: ' . var_export($messages, 1));
  873. $this->assertContains(' "abc"', $message);
  874. $this->assertContains('Translating the notDigits string', $message);
  875. }
  876. public function testCanRemoveValidator()
  877. {
  878. $this->_checkZf2794();
  879. $this->assertFalse($this->element->getValidator('Zend_Validate_Digits'));
  880. $this->element->addValidator('digits');
  881. $digits = $this->element->getValidator('digits');
  882. $this->assertTrue($digits instanceof Zend_Validate_Digits);
  883. $this->element->removeValidator('digits');
  884. $this->assertFalse($this->element->getValidator('digits'));
  885. }
  886. public function testCanClearAllValidators()
  887. {
  888. $this->_checkZf2794();
  889. $this->testCanAddMultipleValidators();
  890. $validators = $this->element->getValidators();
  891. $this->element->clearValidators();
  892. $test = $this->element->getValidators();
  893. $this->assertNotEquals($validators, $test);
  894. $this->assertTrue(empty($test));
  895. foreach (array_keys($validators) as $validator) {
  896. $this->assertFalse($this->element->getValidator($validator));
  897. }
  898. }
  899. public function testCanValidateElement()
  900. {
  901. $this->element->addValidator(new Zend_Validate_NotEmpty())
  902. ->addValidator(new Zend_Validate_EmailAddress());
  903. try {
  904. $result = $this->element->isValid('matthew@zend.com');
  905. } catch (Exception $e) {
  906. $this->fail('Validating an element should work');
  907. }
  908. }
  909. public function testCanValidateArrayValue()
  910. {
  911. $this->element->setIsArray(true)
  912. ->addValidator('InArray', false, array(array('foo', 'bar', 'baz', 'bat')));
  913. $this->assertTrue($this->element->isValid(array('foo', 'bat')));
  914. }
  915. public function testShouldAllowZeroAsNonEmptyValue()
  916. {
  917. $this->element->addValidator('between', false, array(1, 100));
  918. $this->assertFalse($this->element->isValid('0'));
  919. }
  920. public function testIsValidPopulatesElementValue()
  921. {
  922. $this->testCanValidateElement();
  923. $this->assertEquals('matthew@zend.com', $this->element->getValue());
  924. }
  925. public function testErrorsPopulatedFollowingFailedIsValidCheck()
  926. {
  927. $this->element->addValidator(new Zend_Validate_NotEmpty())
  928. ->addValidator(new Zend_Validate_EmailAddress());
  929. $result = $this->element->isValid('matthew');
  930. if ($result) {
  931. $this->fail('Invalid data should fail validations');
  932. }
  933. $errors = $this->element->getErrors();
  934. $this->assertTrue(is_array($errors));
  935. $this->assertTrue(0 < count($errors));
  936. }
  937. public function testMessagesPopulatedFollowingFailedIsValidCheck()
  938. {
  939. require_once 'Zend/Validate/NotEmpty.php';
  940. require_once 'Zend/Validate/EmailAddress.php';
  941. $this->element->addValidator(new Zend_Validate_NotEmpty())
  942. ->addValidator(new Zend_Validate_EmailAddress());
  943. $result = $this->element->isValid('matthew');
  944. if ($result) {
  945. $this->fail('Invalid data should fail validations');
  946. }
  947. $messages = $this->element->getMessages();
  948. $this->assertTrue(is_array($messages));
  949. $this->assertTrue(0 < count($messages));
  950. }
  951. public function testOptionalElementDoesNotPerformValidationsOnEmptyValuesByDefault()
  952. {
  953. $this->element->addValidator(new Zend_Validate_EmailAddress());
  954. $result = $this->element->isValid('');
  955. if (!$result) {
  956. $this->fail('Empty data should not fail validations');
  957. }
  958. $errors = $this->element->getErrors();
  959. $this->assertTrue(is_array($errors));
  960. $this->assertTrue(empty($errors));
  961. }
  962. public function testOptionalElementDoesPerformValidationsWhenAllowEmptyIsFalse()
  963. {
  964. $this->element->setAllowEmpty(false)
  965. ->addValidator(new Zend_Validate_EmailAddress());
  966. $result = $this->element->isValid('');
  967. if ($result) {
  968. $this->fail('Empty data should fail validations when AllowEmpty is false');
  969. }
  970. $errors = $this->element->getErrors();
  971. $this->assertTrue(is_array($errors));
  972. $this->assertTrue(0 < count($errors));
  973. }
  974. public function testAddingInvalidFilterTypeThrowsException()
  975. {
  976. try {
  977. $this->element->addFilter(123);
  978. $this->fail('Invalid filter type should raise exception');
  979. } catch (Zend_Form_Exception $e) {
  980. $this->assertContains('Invalid filter', $e->getMessage());
  981. }
  982. }
  983. public function testCanAddSingleFilterAsString()
  984. {
  985. $this->_checkZf2794();
  986. $this->assertFalse($this->element->getFilter('digits'));
  987. $this->element->addFilter('digits');
  988. $filter = $this->element->getFilter('digits');
  989. $this->assertTrue($filter instanceof Zend_Filter_Digits);
  990. }
  991. public function testCanNotRetrieveSingleFilterRegisteredAsStringUsingClassName()
  992. {
  993. $this->assertFalse($this->element->getFilter('digits'));
  994. $this->element->addFilter('digits');
  995. $this->assertFalse($this->element->getFilter('Zend_Filter_Digits'));
  996. }
  997. public function testCanAddSingleFilterAsFilterObject()
  998. {
  999. $this->assertFalse($this->element->getFilter('Zend_Filter_Digits'));
  1000. require_once 'Zend/Filter/Digits.php';
  1001. $filter = new Zend_Filter_Digits();
  1002. $this->element->addFilter($filter);
  1003. $test = $this->element->getFilter('Zend_Filter_Digits');
  1004. $this->assertSame($filter, $test);
  1005. }
  1006. public function testCanRetrieveSingleFilterRegisteredAsFilterObjectUsingShortName()
  1007. {
  1008. $this->_checkZf2794();
  1009. $this->assertFalse($this->element->getFilter('digits'));
  1010. require_once 'Zend/Filter/Digits.php';
  1011. $filter = new Zend_Filter_Digits();
  1012. $this->element->addFilter($filter);
  1013. $test = $this->element->getFilter('digits');
  1014. }
  1015. public function testRetrievingNamedFilterShouldNotReorderFilters()
  1016. {
  1017. $this->element->addFilters(array(
  1018. 'Alpha',
  1019. 'Alnum',
  1020. 'Digits',
  1021. ));
  1022. $filter = $this->element->getFilter('Alnum');
  1023. $filters = $this->element->getFilters();
  1024. $i = 0;
  1025. $order = array();
  1026. foreach (array_keys($filters) as $name) {
  1027. $order[$name] = $i;
  1028. ++$i;
  1029. }
  1030. $this->assertEquals(1, $order['Zend_Filter_Alnum'], var_export($order, 1));
  1031. }
  1032. public function testOptionsAreCastToArrayWhenAddingFilter()
  1033. {
  1034. $this->_checkZf2794();
  1035. try {
  1036. $this->element->addFilter('Alnum', true);
  1037. } catch (Exception $e) {
  1038. $this->fail('Should be able to add non-array filter options');
  1039. }
  1040. $filter = $this->element->getFilter('Alnum');
  1041. $this->assertTrue($filter instanceof Zend_Filter_Alnum);
  1042. $this->assertTrue($filter->allowWhiteSpace);
  1043. }
  1044. public function testShouldUseFilterConstructorOptionsAsPassedToAddFilter()
  1045. {
  1046. $this->element->addFilter('HtmlEntities', array(array('quotestyle' => ENT_QUOTES, 'charset' => 'UTF-8')));
  1047. $filter = $this->element->getFilter('HtmlEntities');
  1048. $this->assertTrue($filter instanceof Zend_Filter_HtmlEntities);
  1049. $this->assertEquals(ENT_QUOTES, $filter->getQuoteStyle());
  1050. $this->assertEquals('UTF-8', $filter->getCharSet());
  1051. }
  1052. public function testCanAddMultipleFilters()
  1053. {
  1054. $this->_checkZf2794();
  1055. $this->assertFalse($this->element->getFilter('Zend_Filter_Digits'));
  1056. $this->assertFalse($this->element->getFilter('Zend_Filter_Alnum'));
  1057. $this->element->addFilters(array('digits', 'alnum'));
  1058. $digits = $this->element->getFilter('digits');
  1059. $this->assertTrue($digits instanceof Zend_Filter_Digits);
  1060. $alnum = $this->element->getFilter('alnum');
  1061. $this->assertTrue($alnum instanceof Zend_Filter_Alnum);
  1062. }
  1063. public function testRemovingUnregisteredFilterReturnsObjectInstance()
  1064. {
  1065. $this->assertSame($this->element, $this->element->removeFilter('bogus'));
  1066. }
  1067. public function testCanRemoveFilter()
  1068. {
  1069. $this->_checkZf2794();
  1070. $this->assertFalse($this->element->getFilter('Zend_Filter_Digits'));
  1071. $this->element->addFilter('digits');
  1072. $digits = $this->element->getFilter('digits');
  1073. $this->assertTrue($digits instanceof Zend_Filter_Digits);
  1074. $this->element->removeFilter('digits');
  1075. $this->assertFalse($this->element->getFilter('digits'));
  1076. }
  1077. public function testCanClearAllFilters()
  1078. {
  1079. $this->_checkZf2794();
  1080. $this->testCanAddMultipleFilters();
  1081. $filters = $this->element->getFilters();
  1082. $this->element->clearFilters();
  1083. $test = $this->element->getFilters();
  1084. $this->assertNotEquals($filters, $test);
  1085. $this->assertTrue(empty($test));
  1086. foreach (array_keys($filters) as $filter) {
  1087. $this->assertFalse($this->element->getFilter($filter));
  1088. }
  1089. }
  1090. public function testGetViewReturnsNullWithNoViewRenderer()
  1091. {
  1092. $this->assertNull($this->element->getView());
  1093. }
  1094. public function testGetViewReturnsViewRendererViewInstanceIfViewRendererActive()
  1095. {
  1096. $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
  1097. $viewRenderer->initView();
  1098. $view = $viewRenderer->view;
  1099. $test = $this->element->getView();
  1100. $this->assertSame($view, $test);
  1101. }
  1102. public function testCanSetView()
  1103. {
  1104. $view = new Zend_View();
  1105. $this->assertNull($this->element->getView());
  1106. $this->element->setView($view);
  1107. $received = $this->element->getView();
  1108. $this->assertSame($view, $received);
  1109. }
  1110. public function testViewHelperDecoratorRegisteredByDefault()
  1111. {
  1112. $this->_checkZf2794();
  1113. $decorator = $this->element->getDecorator('viewHelper');
  1114. $this->assertTrue($decorator instanceof Zend_Form_Decorator_ViewHelper);
  1115. }
  1116. /**
  1117. * @group ZF-4822
  1118. */
  1119. public function testErrorsDecoratorRegisteredByDefault()
  1120. {
  1121. $this->_checkZf2794();
  1122. $decorator = $this->element->getDecorator('errors');
  1123. $this->assertTrue($decorator instanceof Zend_Form_Decorator_Errors);
  1124. }
  1125. /**
  1126. * @group ZF-4822
  1127. */
  1128. public function testDescriptionDecoratorRegisteredByDefault()
  1129. {
  1130. $this->_checkZf2794();
  1131. $decorator = $this->element->getDecorator('description');
  1132. $this->assertTrue($decorator instanceof Zend_Form_Decorator_Description);
  1133. $options = $decorator->getOptions();
  1134. $this->assertTrue(array_key_exists('tag', $options));
  1135. $this->assertEquals('p', $options['tag']);
  1136. $this->assertTrue(array_key_exists('class', $options));
  1137. $this->assertEquals('description', $options['class']);
  1138. }
  1139. /**
  1140. * @group ZF-4822
  1141. */
  1142. public function testHtmlTagDecoratorRegisteredByDefault()
  1143. {
  1144. $this->_checkZf2794();
  1145. $decorator = $this->element->getDecorator('HtmlTag');
  1146. $this->assertTrue($decorator instanceof Zend_Form_Decorator_HtmlTag);
  1147. }
  1148. /**
  1149. * @group ZF-4822
  1150. */
  1151. public function testLabelDecoratorRegisteredByDefault()
  1152. {
  1153. $this->_checkZf2794();
  1154. $decorator = $this->element->getDecorator('Label');
  1155. $this->assertTrue($decorator instanceof Zend_Form_Decorator_Label);
  1156. }
  1157. public function testCanDisableRegisteringDefaultDecoratorsDuringInitialization()
  1158. {
  1159. $element = new Zend_Form_Element('foo', array('disableLoadDefaultDecorators' => true));
  1160. $decorators = $element->getDecorators();
  1161. $this->assertEquals(array(), $decorators);
  1162. }
  1163. public function testAddingInvalidDecoratorThrowsException()
  1164. {
  1165. try {
  1166. $this->element->addDecorator(123);
  1167. $this->fail('Invalid decorator type should raise exception');
  1168. } catch (Zend_Form_Exception $e) {
  1169. $this->assertContains('Invalid decorator', $e->getMessage());
  1170. }
  1171. }
  1172. public function testCanAddSingleDecoratorAsString()
  1173. {
  1174. $this->_checkZf2794();
  1175. $this->element->clearDecorators();
  1176. $this->assertFalse($this->element->getDecorator('viewHelper'));
  1177. $this->element->addDecorator('viewHelper');
  1178. $decorator = $this->element->getDecorator('viewHelper');
  1179. $this->assertTrue($decorator instanceof Zend_Form_Decorator_ViewHelper);
  1180. }
  1181. public function testCanNotRetrieveSingleDecoratorRegisteredAsStringUsingClassName()
  1182. {
  1183. $this->assertFalse($this->element->getDecorator('Zend_Form_Decorator_ViewHelper'));
  1184. }
  1185. public function testCanAddSingleDecoratorAsDecoratorObject()
  1186. {
  1187. $this->element->clearDecorators();
  1188. $this->assertFalse($this->element->getDecorator('viewHelper'));
  1189. $decorator = new Zend_Form_Decorator_ViewHelper;
  1190. $this->element->addDecorator($decorator);
  1191. $test = $this->element->getDecorator('Zend_Form_Decorator_ViewHelper');
  1192. $this->assertSame($decorator, $test);
  1193. }
  1194. /**
  1195. * @group ZF-3597
  1196. */
  1197. public function testAddingConcreteDecoratorShouldHonorOrder()
  1198. {
  1199. require_once dirname(__FILE__) . '/_files/decorators/TableRow.php';
  1200. $decorator = new My_Decorator_TableRow();
  1201. $this->element->setLabel('Foo')
  1202. ->setDescription('sample description')
  1203. ->clearDecorators()
  1204. ->addDecorators(array(
  1205. 'ViewHelper',
  1206. $decorator,
  1207. ));
  1208. $html = $this->element->render($this->getView());
  1209. $this->assertRegexp('#<tr><td>Foo</td><td>.*?<input[^>]+>.*?</td><td>sample description</td></tr>#s', $html, $html);
  1210. }
  1211. public function testCanRetrieveSingleDecoratorRegisteredAsDecoratorObjectUsingShortName()
  1212. {
  1213. $this->_checkZf2794();
  1214. $this->element->clearDecorators();
  1215. $this->assertFalse($this->element->getDecorator('viewHelper'));
  1216. $decorator = new Zend_Form_Decorator_ViewHelper;
  1217. $this->element->addDecorator($decorator);
  1218. $test = $this->element->getDecorator('viewHelper');
  1219. $this->assertSame($decorator, $test);
  1220. }
  1221. public function testCanAddMultipleDecorators()
  1222. {
  1223. $this->_checkZf2794();
  1224. $this->element->clearDecorators();
  1225. $this->assertFalse($this->element->getDecorator('viewHelper'));
  1226. $testDecorator = new Zend_Form_ElementTest_Decorator;
  1227. $this->element->addDecorators(array(
  1228. 'ViewHelper',
  1229. $testDecorator
  1230. ));
  1231. $viewHelper = $this->element->getDecorator('viewHelper');
  1232. $this->assertTrue($viewHelper instanceof Zend_Form_Decorator_ViewHelper);
  1233. $decorator = $this->element->getDecorator('decorator');
  1234. $this->assertSame($testDecorator, $decorator);
  1235. }
  1236. public function testRemovingUnregisteredDecoratorReturnsObjectInstance()
  1237. {
  1238. $this->_checkZf2794();
  1239. $this->assertSame($this->element, $this->element->removeDecorator('bogus'));
  1240. }
  1241. public function testCanRemoveDecorator()
  1242. {
  1243. $this->testViewHelperDecoratorRegisteredByDefault();
  1244. $this->element->removeDecorator('viewHelper');
  1245. $this->assertFalse($this->element->getDecorator('viewHelper'));
  1246. }
  1247. /**
  1248. * @group ZF-3069
  1249. */
  1250. public function testRemovingNamedDecoratorsShouldWork()
  1251. {
  1252. $this->_checkZf2794();
  1253. $this->element->setDecorators(array(
  1254. 'ViewHelper',
  1255. array(array('div' => 'HtmlTag'), array('tag' => 'div')),
  1256. array(array('div2' => 'HtmlTag'), array('tag' => 'div')),
  1257. ));
  1258. $decorators = $this->element->getDecorators();
  1259. $this->assertTrue(array_key_exists('div', $decorators));
  1260. $this->assertTrue(array_key_exists('div2', $decorators));
  1261. $this->element->removeDecorator('div');
  1262. $decorators = $this->element->getDecorators();
  1263. $this->assertFalse(array_key_exists('div', $decorators));
  1264. $this->assertTrue(array_key_exists('div2', $decorators));
  1265. }
  1266. public function testCanClearAllDecorators()
  1267. {
  1268. $this->testCanAddMultipleDecorators();
  1269. $this->element->clearDecorators();
  1270. $this->assertFalse($this->element->getDecorator('viewHelper'));
  1271. $this->assertFalse($this->element->getDecorator('decorator'));
  1272. }
  1273. public function testCanAddDecoratorAliasesToAllowMultipleDecoratorsOfSameType()
  1274. {
  1275. $this->_checkZf2794();
  1276. $this->element->setDecorators(array(
  1277. array('HtmlTag', array('tag' => 'span')),
  1278. array('decorator' => array('FooBar' => 'HtmlTag'), 'options' => array('tag' => 'div')),
  1279. ));
  1280. $decorator = $this->element->getDecorator('FooBar');
  1281. $this->assertTrue($decorator instanceof Zend_Form_Decorator_HtmlTag);
  1282. $this->assertEquals('div', $decorator->getOption('tag'));
  1283. $decorator = $this->element->getDecorator('HtmlTag');
  1284. $this->assertTrue($decorator instanceof Zend_Form_Decorator_HtmlTag);
  1285. $this->assertEquals('span', $decorator->getOption('tag'));
  1286. }
  1287. public function testRetrievingNamedDecoratorShouldNotReorderDecorators()
  1288. {
  1289. $this->element->setDecorators(array(
  1290. 'ViewHelper',
  1291. 'Errors',
  1292. array(array('inner' => 'HtmlTag'), array('tag' => 'div', 'class' => 'element')),
  1293. 'Label',
  1294. array(array('outer' => 'HtmlTag'), array('tag' => 'div')),
  1295. ));
  1296. $decorator = $this->element->getDecorator('inner');
  1297. $decorators = $this->element->getDecorators();
  1298. $i = 0;
  1299. $order = array();
  1300. foreach (array_keys($decorators) as $name) {
  1301. $order[$name] = $i;
  1302. ++$i;
  1303. }
  1304. $this->assertEquals(2, $order['inner'], var_export($order, 1));
  1305. }
  1306. /**
  1307. * @group ZF-3376
  1308. */
  1309. public function testSetDecoratorsShouldAcceptReturnOfGetDecorators()
  1310. {
  1311. $this->element->setDecorators(array(
  1312. 'ViewHelper',
  1313. 'Errors',
  1314. array('input' => 'HtmlTag', array('tag' => 'div', 'class' => 'input')),
  1315. 'Label',
  1316. array('element' => 'HtmlTag', array('tag' => 'div', 'class' => 'element')),
  1317. ));
  1318. $decorators = $this->element->getDecorators();
  1319. $this->element->setDecorators($decorators);
  1320. $this->assertSame($decorators, $this->element->getDecorators());
  1321. }
  1322. public function testRenderElementReturnsMarkup()
  1323. {
  1324. $this->element->setName('foo');
  1325. $html = $this->element->render($this->getView());
  1326. $this->assertTrue(is_string($html));
  1327. $this->assertFalse(empty($html));
  1328. $this->assertContains('<input', $html);
  1329. $this->assertContains('"foo"', $html);
  1330. }
  1331. public function testRenderElementRendersLabelWhenProvided()
  1332. {
  1333. $this->element->setView($this->getView());
  1334. $this->element->setName('foo')
  1335. ->setLabel('Foo');
  1336. $html = $this->element->render();
  1337. $this->assertTrue(is_string($html));
  1338. $this->assertFalse(empty($html));
  1339. $this->assertContains('<label', $html);
  1340. $this->assertContains('Foo', $html);
  1341. $this->assertContains('</label>', $html);
  1342. }
  1343. public function testRenderElementRendersValueWhenProvided()
  1344. {
  1345. $this->element->setView($this->getView());
  1346. $this->element->setName('foo')
  1347. ->setValue('bar');
  1348. $html = $this->element->render();
  1349. $this->assertTrue(is_string($html));
  1350. $this->assertFalse(empty($html));
  1351. $this->assertContains('<input', $html);
  1352. $this->assertContains('"foo"', $html);
  1353. $this->assertContains('"bar"', $html);
  1354. }
  1355. public function testRenderElementRendersErrorsWhenProvided()
  1356. {
  1357. $this->_checkZf2794();
  1358. $this->element->setView($this->getView())
  1359. ->setRequired(true)
  1360. ->setName('foo')
  1361. ->addValidator('NotEmpty');
  1362. $this->element->isValid('');
  1363. $html = $this->element->render();
  1364. $this->assertTrue(is_string($html));
  1365. $this->assertFalse(empty($html));
  1366. $this->assertContains('error', $html);
  1367. $this->assertRegexp('/empty/i', $html);
  1368. }
  1369. public function testToStringProxiesToRender()
  1370. {
  1371. $this->element->setView($this->getView());
  1372. $this->element->setName('foo');
  1373. $html = $this->element->__toString();
  1374. $this->assertTrue(is_string($html));
  1375. $this->assertFalse(empty($html));
  1376. $this->assertContains('<input', $html);
  1377. $this->assertContains('"foo"', $html);
  1378. }
  1379. public function raiseDecoratorException($content, $element, $options)
  1380. {
  1381. throw new Exception('Raising exception in decorator callback');
  1382. }
  1383. public function handleDecoratorErrors($errno, $errstr, $errfile = '', $errline = 0, array $errcontext = array())
  1384. {
  1385. $this->error = $errstr;
  1386. }
  1387. public function testToStringRaisesErrorWhenExceptionCaught()
  1388. {
  1389. $this->element->setDecorators(array(
  1390. array(
  1391. 'decorator' => 'Callback',
  1392. 'options' => array('callback' => array($this, 'raiseDecoratorException'))
  1393. ),
  1394. ));
  1395. $origErrorHandler = set_error_handler(array($this, 'handleDecoratorErrors'), E_USER_WARNING);
  1396. $text = $this->element->__toString();
  1397. restore_error_handler();
  1398. $this->assertTrue(empty($text));
  1399. $this->assertTrue(isset($this->error));
  1400. $this->assertEquals('Raising exception in decorator callback', $this->error);
  1401. }
  1402. public function getOptions()
  1403. {
  1404. $options = array(
  1405. 'name' => 'changed',
  1406. 'value' => 'foo',
  1407. 'label' => 'bar',
  1408. 'order' => 50,
  1409. 'required' => false,
  1410. 'foo' => 'bar',
  1411. 'baz' => 'bat'
  1412. );
  1413. return $options;
  1414. }
  1415. public function testCanSetObjectStateViaSetOptions()
  1416. {
  1417. $options = $this->getOptions();
  1418. $this->element->setOptions($options);
  1419. $this->assertEquals('changed', $this->element->getName());
  1420. $this->assertEquals('foo', $this->element->getValue());
  1421. $this->assertEquals('bar', $this->element->getLabel());
  1422. $this->assertEquals(50, $this->element->getOrder());
  1423. $this->assertFalse($this->element->isRequired());
  1424. $this->assertEquals('bar', $this->element->foo);
  1425. $this->assertEquals('bat', $this->element->baz);
  1426. }
  1427. public function testSetOptionsSkipsCallsToSetOptionsAndSetConfig()
  1428. {
  1429. $options = $this->getOptions();
  1430. $config = new Zend_Config($options);
  1431. $options['config'] = $config;
  1432. $options['options'] = $config->toArray();
  1433. $this->element->setOptions($options);
  1434. }
  1435. public function testSetOptionsSkipsSettingAccessorsRequiringObjectsWhenNoObjectPresent()
  1436. {
  1437. $options = $this->getOptions();
  1438. $options['translator'] = true;
  1439. $options['pluginLoader'] = true;
  1440. $options['view'] = true;
  1441. $this->element->setOptions($options);
  1442. }
  1443. public function testSetOptionsSetsArrayOfStringValidators()
  1444. {
  1445. $this->_checkZf2794();
  1446. $options = $this->getOptions();
  1447. $options['validators'] = array(
  1448. 'notEmpty',
  1449. 'digits'
  1450. );
  1451. $this->element->setOptions($options);
  1452. $validator = $this->element->getValidator('notEmpty');
  1453. $this->assertTrue($validator instanceof Zend_Validate_NotEmpty);
  1454. $validator = $this->element->getValidator('digits');
  1455. $this->assertTrue($validator instanceof Zend_Validate_Digits);
  1456. }
  1457. public function testSetOptionsSetsArrayOfArrayValidators()
  1458. {
  1459. $this->_checkZf2794();
  1460. $options = $this->getOptions();
  1461. $options['validators'] = array(
  1462. array('notEmpty', true, array(Zend_Validate_NotEmpty::ALL)),
  1463. array('digits', true, array('bar')),
  1464. );
  1465. $this->element->setOptions($options);
  1466. $validator = $this->element->getValidator('notEmpty');
  1467. $this->assertTrue($validator instanceof Zend_Validate_NotEmpty);
  1468. $this->assertTrue($validator->zfBreakChainOnFailure);
  1469. $validator = $this->element->getValidator('digits');
  1470. $this->assertTrue($validator instanceof Zend_Validate_Digits);
  1471. $this->assertTrue($validator->zfBreakChainOnFailure);
  1472. }
  1473. public function testSetOptionsSetsArrayOfAssociativeArrayValidators()
  1474. {
  1475. $this->_checkZf2794();
  1476. $options = $this->getOptions();
  1477. $options['validators'] = array(
  1478. array(
  1479. 'options' => array(Zend_Validate_NotEmpty::ALL),
  1480. 'breakChainOnFailure' => true,
  1481. 'validator' => 'notEmpty',
  1482. ),
  1483. array(
  1484. 'options' => array('bar'),
  1485. 'validator' => 'digits',
  1486. 'breakChainOnFailure' => true,
  1487. ),
  1488. );
  1489. $this->element->setOptions($options);
  1490. $validator = $this->element->getValidator('notEmpty');
  1491. $this->assertTrue($validator instanceof Zend_Validate_NotEmpty);
  1492. $this->assertTrue($validator->zfBreakChainOnFailure);
  1493. $validator = $this->element->getValidator('digits');
  1494. $this->assertTrue($validator instanceof Zend_Validate_Digits);
  1495. $this->assertTrue($validator->zfBreakChainOnFailure);
  1496. }
  1497. public function testSetOptionsSetsArrayOfStringFilters()
  1498. {
  1499. $this->_checkZf2794();
  1500. $options = $this->getOptions();
  1501. $options['filters'] = array('StringToUpper', 'Alpha');
  1502. $this->element->setOptions($options);
  1503. $filter = $this->element->getFilter('StringToUpper');
  1504. $this->assertTrue($filter instanceof Zend_Filter_StringToUpper);
  1505. $filter = $this->element->getFilter('Alpha');
  1506. $this->assertTrue($filter instanceof Zend_Filter_Alpha);
  1507. }
  1508. public function testSetOptionsSetsArrayOfArrayFilters()
  1509. {
  1510. $this->_checkZf2794();
  1511. $options = $this->getOptions();
  1512. $options['filters'] = array(
  1513. array('Digits', array('bar' => 'baz')),
  1514. array('Alpha', array('foo')),
  1515. );
  1516. $this->element->setOptions($options);
  1517. $filter = $this->element->getFilter('Digits');
  1518. $this->assertTrue($filter instanceof Zend_Filter_Digits);
  1519. $filter = $this->element->getFilter('Alpha');
  1520. $this->assertTrue($filter instanceof Zend_Filter_Alpha);
  1521. }
  1522. public function testSetOptionsSetsArrayOfAssociativeArrayFilters()
  1523. {
  1524. $this->_checkZf2794();
  1525. $options = $this->getOptions();
  1526. $options['filters'] = array(
  1527. array(
  1528. 'options' => array('baz'),
  1529. 'filter' => 'Digits'
  1530. ),
  1531. array(
  1532. 'options' => array('foo'),
  1533. 'filter' => 'Alpha',
  1534. ),
  1535. );
  1536. $this->element->setOptions($options);
  1537. $filter = $this->element->getFilter('Digits');
  1538. $this->assertTrue($filter instanceof Zend_Filter_Digits);
  1539. $filter = $this->element->getFilter('Alpha');
  1540. $this->assertTrue($filter instanceof Zend_Filter_Alpha);
  1541. }
  1542. public function testSetOptionsSetsArrayOfStringDecorators()
  1543. {
  1544. $this->_checkZf2794();
  1545. $options = $this->getOptions();
  1546. $options['decorators'] = array('label', 'form');
  1547. $this->element->setOptions($options);
  1548. $this->assertFalse($this->element->getDecorator('viewHelper'));
  1549. $this->assertFalse($this->element->getDecorator('errors'));
  1550. $decorator = $this->element->getDecorator('label');
  1551. $this->assertTrue($decorator instanceof Zend_Form_Decorator_Label);
  1552. $decorator = $this->element->getDecorator('form');
  1553. $this->assertTrue($decorator instanceof Zend_Form_Decorator_Form);
  1554. }
  1555. public function testSetOptionsSetsArrayOfArrayDecorators()
  1556. {
  1557. $this->_checkZf2794();
  1558. $options = $this->getOptions();
  1559. $options['decorators'] = array(
  1560. array('label', array('id' => 'mylabel')),
  1561. array('form', array('id' => 'form')),
  1562. );
  1563. $this->element->setOptions($options);
  1564. $this->assertFalse($this->element->getDecorator('viewHelper'));
  1565. $this->assertFalse($this->element->getDecorator('errors'));
  1566. $decorator = $this->element->getDecorator('label');
  1567. $this->assertTrue($decorator instanceof Zend_Form_Decorator_Label);
  1568. $options = $decorator->getOptions();
  1569. $this->assertEquals('mylabel', $options['id']);
  1570. $decorator = $this->element->getDecorator('form');
  1571. $this->assertTrue($decorator instanceof Zend_Form_Decorator_Form);
  1572. $options = $decorator->getOptions();
  1573. $this->assertEquals('form', $options['id']);
  1574. }
  1575. public function testSetOptionsSetsArrayOfAssocArrayDecorators()
  1576. {
  1577. $this->_checkZf2794();
  1578. $options = $this->getOptions();
  1579. $options['decorators'] = array(
  1580. array(
  1581. 'options' => array('id' => 'mylabel'),
  1582. 'decorator' => 'label',
  1583. ),
  1584. array(
  1585. 'options' => array('id' => 'form'),
  1586. 'decorator' => 'form',
  1587. ),
  1588. );
  1589. $this->element->setOptions($options);
  1590. $this->assertFalse($this->element->getDecorator('viewHelper'));
  1591. $this->assertFalse($this->element->getDecorator('errors'));
  1592. $decorator = $this->element->getDecorator('label');
  1593. $this->assertTrue($decorator instanceof Zend_Form_Decorator_Label);
  1594. $options = $decorator->getOptions();
  1595. $this->assertEquals('mylabel', $options['id']);
  1596. $decorator = $this->element->getDecorator('form');
  1597. $this->assertTrue($decorator instanceof Zend_Form_Decorator_Form);
  1598. $options = $decorator->getOptions();
  1599. $this->assertEquals('form', $options['id']);
  1600. }
  1601. public function testSetOptionsSetsGlobalPrefixPaths()
  1602. {
  1603. $options = $this->getOptions();
  1604. $options['prefixPath'] = array(
  1605. 'prefix' => 'Zend_Foo',
  1606. 'path' => 'Zend/Foo/'
  1607. );
  1608. $this->element->setOptions($options);
  1609. foreach (array('validate', 'filter', 'decorator') as $type) {
  1610. $loader = $this->element->getPluginLoader($type);
  1611. $paths = $loader->getPaths('Zend_Foo_' . ucfirst($type));
  1612. $this->assertTrue(is_array($paths), "Failed for type $type: " . var_export($paths, 1));
  1613. $this->assertFalse(empty($paths));
  1614. $this->assertContains('Foo', $paths[0]);
  1615. }
  1616. }
  1617. public function testSetOptionsSetsIndividualPrefixPathsFromKeyedArrays()
  1618. {
  1619. $options = $this->getOptions();
  1620. $options['prefixPath'] = array(
  1621. 'filter' => array('prefix' => 'Zend_Foo', 'path' => 'Zend/Foo/')
  1622. );
  1623. $this->element->setOptions($options);
  1624. $loader = $this->element->getPluginLoader('filter');
  1625. $paths = $loader->getPaths('Zend_Foo');
  1626. $this->assertTrue(is_array($paths));
  1627. $this->assertFalse(empty($paths));
  1628. $this->assertContains('Foo', $paths[0]);
  1629. }
  1630. public function testSetOptionsSetsIndividualPrefixPathsFromUnKeyedArrays()
  1631. {
  1632. $options = $this->getOptions();
  1633. $options['prefixPath'] = array(
  1634. array('type' => 'decorator', 'prefix' => 'Zend_Foo', 'path' => 'Zend/Foo/')
  1635. );
  1636. $this->element->setOptions($options);
  1637. $loader = $this->element->getPluginLoader('decorator');
  1638. $paths = $loader->getPaths('Zend_Foo');
  1639. $this->assertTrue(is_array($paths));
  1640. $this->assertFalse(empty($paths));
  1641. $this->assertContains('Foo', $paths[0]);
  1642. }
  1643. public function testCanSetObjectStateViaSetConfig()
  1644. {
  1645. $config = new Zend_Config($this->getOptions());
  1646. $this->element->setConfig($config);
  1647. $this->assertEquals('changed', $this->element->getName());
  1648. $this->assertEquals('foo', $this->element->getValue());
  1649. $this->assertEquals('bar', $this->element->getLabel());
  1650. $this->assertEquals(50, $this->element->getOrder());
  1651. $this->assertFalse($this->element->isRequired());
  1652. $this->assertEquals('bar', $this->element->foo);
  1653. $this->assertEquals('bat', $this->element->baz);
  1654. }
  1655. public function testPassingConfigObjectToConstructorSetsObjectState()
  1656. {
  1657. $config = new Zend_Config($this->getOptions());
  1658. $element = new Zend_Form_Element($config);
  1659. $this->assertEquals('changed', $element->getName());
  1660. $this->assertEquals('foo', $element->getValue());
  1661. $this->assertEquals('bar', $element->getLabel());
  1662. $this->assertEquals(50, $element->getOrder());
  1663. $this->assertFalse($element->isRequired());
  1664. $this->assertEquals('bar', $element->foo);
  1665. $this->assertEquals('bat', $element->baz);
  1666. }
  1667. public function testValueIsFilteredPriorToValidation()
  1668. {
  1669. $this->_checkZf2794();
  1670. $this->element->addFilter('StringTrim')
  1671. ->addValidator('StringLength', false, array(3, 8));
  1672. $this->assertTrue($this->element->isValid(' foobar '));
  1673. $this->assertEquals('foobar', $this->element->getValue());
  1674. $this->element->setFilters(array('StringTrim'))
  1675. ->setRequired(true)
  1676. ->setValidators(array('NotEmpty'));
  1677. $this->assertFalse($this->element->isValid(' '));
  1678. }
  1679. public function testTranslatedLabel()
  1680. {
  1681. $this->element->setLabel('FooBar');
  1682. $translator = new Zend_Translate('array', array('FooBar' => 'BazBar'));
  1683. $this->element->setTranslator($translator);
  1684. $this->assertEquals('BazBar', $this->element->getLabel());
  1685. }
  1686. // Extensions
  1687. public function testInitCalledBeforeLoadDecorators()
  1688. {
  1689. $element = new Zend_Form_ElementTest_Element('test');
  1690. $decorators = $element->getDecorators();
  1691. $this->assertTrue(empty($decorators));
  1692. }
  1693. /**
  1694. * @group ZF-3217
  1695. */
  1696. public function testElementShouldOverloadToRenderDecorators()
  1697. {
  1698. $this->element->setLabel('Foo Label')
  1699. ->setView($this->getView());
  1700. $html = $this->element->renderViewHelper();
  1701. $this->assertContains('<input', $html);
  1702. $this->assertContains('id="' . $this->element->getFullyQualifiedName() . '"', $html, 'Received: ' . $html);
  1703. $this->assertNotContains('<dd', $html);
  1704. $this->assertNotContains('<label', $html);
  1705. $html = $this->element->renderLabel('this is the content');
  1706. $this->assertRegexp('#<label[^>]*for="' . $this->element->getFullyQualifiedName() . '"[^>]*>Foo Label</label>#', $html);
  1707. $this->assertContains('this is the content', $html);
  1708. $this->assertNotContains('<input', $html);
  1709. }
  1710. /**
  1711. * @group ZF-3217
  1712. * @expectedException Zend_Form_Element_Exception
  1713. */
  1714. public function testOverloadingToInvalidMethodsShouldThrowAnException()
  1715. {
  1716. $html = $this->element->bogusMethodCall();
  1717. }
  1718. /**
  1719. * @group ZF-5150
  1720. */
  1721. public function testMarkingAsErrorShouldCauseIsErrorToReturnFalse()
  1722. {
  1723. $this->element->setValue('foo');
  1724. $this->element->markAsError();
  1725. $this->assertFalse($this->element->isValid('foo'));
  1726. }
  1727. /**
  1728. * @group ZF-4915
  1729. */
  1730. public function testElementShouldAllowSettingDefaultErrorMessageSeparator()
  1731. {
  1732. $this->element->setErrorMessageSeparator('|');
  1733. $this->assertEquals('|', $this->element->getErrorMessageSeparator());
  1734. }
  1735. /**
  1736. * @group ZF-4915
  1737. */
  1738. public function testElementShouldUseSemicolonAndSpaceAsDefaultErrorMessageSeparator()
  1739. {
  1740. $this->assertEquals('; ', $this->element->getErrorMessageSeparator());
  1741. }
  1742. /**
  1743. * Used by test methods susceptible to ZF-2794, marks a test as incomplete
  1744. *
  1745. * @link http://framework.zend.com/issues/browse/ZF-2794
  1746. * @return void
  1747. */
  1748. protected function _checkZf2794()
  1749. {
  1750. if (strtolower(substr(PHP_OS, 0, 3)) == 'win' && version_compare(PHP_VERSION, '5.1.4', '=')) {
  1751. $this->markTestIncomplete('Error occurs for PHP 5.1.4 on Windows');
  1752. }
  1753. }
  1754. /**
  1755. * @ZF-8882
  1756. */
  1757. public function testErrorMessagesShouldNotBeTranslatedWhenTranslatorIsDisabled()
  1758. {
  1759. $translations = array(
  1760. 'foo' => 'Foo message',
  1761. );
  1762. $translate = new Zend_Translate('array', $translations);
  1763. $this->element->setTranslator($translate)
  1764. ->addErrorMessage('foo')
  1765. ->addValidator('Alpha');
  1766. $this->assertFalse($this->element->isValid(123));
  1767. $messages = $this->element->getMessages();
  1768. $this->assertEquals(1, count($messages));
  1769. $this->assertEquals('Foo message', array_shift($messages));
  1770. $this->element->setDisableTranslator(true);
  1771. $this->assertFalse($this->element->isValid(123));
  1772. $messages = $this->element->getMessages();
  1773. $this->assertEquals(1, count($messages));
  1774. $this->assertEquals('foo', array_shift($messages));
  1775. }
  1776. /**
  1777. * @group ZF-9275
  1778. */
  1779. public function testElementDoesntOverrideDefaultValidatorTranslatorWithDefaultRegistryTranslator()
  1780. {
  1781. $registryTranslations = array('alphaInvalid' => 'Registry message');
  1782. $registryTranslate = new Zend_Translate('array', $registryTranslations);
  1783. Zend_Registry::set('Zend_Translate', $registryTranslate);
  1784. $validatorTranslations = array('alphaInvalid' => 'Validator message');
  1785. $validatorTranslate = new Zend_Translate('array', $validatorTranslations);
  1786. Zend_Validate_Abstract::setDefaultTranslator($validatorTranslate);
  1787. $elementTranslations = array('alphaInvalid' => 'Element message');
  1788. $elementTranslate = new Zend_Translate('array', $elementTranslations);
  1789. // the default validate translator should beat the registry one
  1790. $this->element->addValidator('Alpha');
  1791. $this->assertFalse($this->element->isValid(123));
  1792. $messages = $this->element->getMessages();
  1793. $this->assertEquals('Validator message', $messages['alphaInvalid']);
  1794. }
  1795. /**
  1796. * @group ZF-9275
  1797. */
  1798. public function testDefaultTranslatorDoesntOverrideElementTranslatorOnValdiation()
  1799. {
  1800. $registryTranslations = array('alphaInvalid' => 'Registry message');
  1801. $registryTranslate = new Zend_Translate('array', $registryTranslations);
  1802. Zend_Registry::set('Zend_Translate', $registryTranslate);
  1803. $validatorTranslations = array('alphaInvalid' => 'Validator message');
  1804. $validatorTranslate = new Zend_Translate('array', $validatorTranslations);
  1805. Zend_Validate_Abstract::setDefaultTranslator($validatorTranslate);
  1806. $elementTranslations = array('alphaInvalid' => 'Element message');
  1807. $elementTranslate = new Zend_Translate('array', $elementTranslations);
  1808. $this->element->addValidator('Alpha');
  1809. $this->element->setTranslator($elementTranslate);
  1810. $this->assertFalse($this->element->isValid(123));
  1811. $messages = $this->element->getMessages();
  1812. $this->assertEquals('Element message', $messages['alphaInvalid']);
  1813. }
  1814. /**
  1815. * @group ZF-9275
  1816. */
  1817. public function testValidatorsDefaultTranslatorDoesntOverrideFormsDefaultTranslator()
  1818. {
  1819. $formTranslations = array('alphaInvalid' => 'Form message');
  1820. $formTranslate = new Zend_Translate('array', $formTranslations);
  1821. Zend_Form::setDefaultTranslator($formTranslate);
  1822. $validatorTranslations = array('alphaInvalid' => 'Validator message');
  1823. $validatorTranslate = new Zend_Translate('array', $validatorTranslations);
  1824. Zend_Validate_Abstract::setDefaultTranslator($validatorTranslate);
  1825. // the default validate translator should beat the registry one
  1826. $this->element->addValidator('Alpha');
  1827. $this->assertFalse($this->element->isValid(123));
  1828. $messages = $this->element->getMessages();
  1829. $this->assertEquals('Form message', $messages['alphaInvalid']);
  1830. }
  1831. /**
  1832. * @group ZF-9275
  1833. */
  1834. public function testElementsTranslatorDoesntOverrideValidatorsDirectlyAttachedTranslator()
  1835. {
  1836. $elementTranslations = array('alphaInvalid' => 'Element message');
  1837. $elementTranslate = new Zend_Translate('array', $elementTranslations);
  1838. $validatorTranslations = array('alphaInvalid' => 'Direct validator message');
  1839. $validatorTranslate = new Zend_Translate('array', $validatorTranslations);
  1840. $validator = new Zend_Validate_Alpha();
  1841. $validator->setTranslator($validatorTranslate);
  1842. $this->element->addValidator($validator);
  1843. $this->assertFalse($this->element->isValid(123));
  1844. $messages = $this->element->getMessages();
  1845. $this->assertEquals('Direct validator message', $messages['alphaInvalid']);
  1846. }
  1847. /**
  1848. * Prove the fluent interface on Zend_Form::loadDefaultDecorators
  1849. *
  1850. * @link http://framework.zend.com/issues/browse/ZF-9913
  1851. * @return void
  1852. */
  1853. public function testFluentInterfaceOnLoadDefaultDecorators()
  1854. {
  1855. $this->assertSame($this->element, $this->element->loadDefaultDecorators());
  1856. }
  1857. /**
  1858. * @group ZF-7552
  1859. */
  1860. public function testAddDecoratorsKeepsNonNumericKeyNames()
  1861. {
  1862. $this->element->addDecorators(array(array(array('td' => 'HtmlTag'),
  1863. array('tag' => 'td')),
  1864. array(array('tr' => 'HtmlTag'),
  1865. array('tag' => 'tr')),
  1866. array('HtmlTag', array('tag' => 'baz'))));
  1867. $t1 = $this->element->getDecorators();
  1868. $this->element->setDecorators($t1);
  1869. $t2 = $this->element->getDecorators();
  1870. $this->assertEquals($t1, $t2);
  1871. }
  1872. }
  1873. class Zend_Form_ElementTest_Decorator extends Zend_Form_Decorator_Abstract
  1874. {
  1875. }
  1876. class Zend_Form_ElementTest_Element extends Zend_Form_Element
  1877. {
  1878. public function init()
  1879. {
  1880. $this->setDisableLoadDefaultDecorators(true);
  1881. }
  1882. }
  1883. class Zend_Form_ElementTest_ArrayFilter implements Zend_Filter_Interface
  1884. {
  1885. public function filter($value)
  1886. {
  1887. $value = array_filter($value, array($this, '_filter'));
  1888. return $value;
  1889. }
  1890. protected function _filter($value)
  1891. {
  1892. if (is_array($value)) {
  1893. return array_filter($value, array($this, '_filter'));
  1894. }
  1895. return (strstr($value, 'ba'));
  1896. }
  1897. /**
  1898. * Check array notation for validators
  1899. */
  1900. public function testValidatorsGivenArrayKeysOnValidation()
  1901. {
  1902. $username = new Zend_Form_Element('username');
  1903. $username->addValidator('stringLength', true, array('min' => 5, 'max' => 20, 'ignore' => 'something'));
  1904. $form = new Zend_Form(array('elements' => array($username)));
  1905. $this->assertTrue($form->isValid(array('username' => 'abcde')));
  1906. }
  1907. /**
  1908. * @group ZF-6822
  1909. */
  1910. public function testValidatorByUsingStringNotation()
  1911. {
  1912. $this->_checkZf2794();
  1913. $username = new Zend_Form_Element('username');
  1914. $username->addValidator('stringLength', true, array(5, 20))
  1915. ->addValidator('regex', true, '/^[a-zA-Z0-9_]*$/')
  1916. ->addFilter('StringToLower')
  1917. ->setRequired(true);
  1918. $form = new Zend_Form(array('elements' => array($username)));
  1919. $form->isValid(array('username' => '#'));
  1920. $validator = $username->getValidator('stringLength');
  1921. $this->assertTrue($validator->zfBreakChainOnFailure);
  1922. $validator = $username->getValidator('regex');
  1923. $this->assertTrue($validator->zfBreakChainOnFailure);
  1924. }
  1925. }
  1926. if (PHPUnit_MAIN_METHOD == 'Zend_Form_ElementTest::main') {
  1927. Zend_Form_ElementTest::main();
  1928. }