AbstractLayoutTest.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Tests\Component\Form;
  11. use Symfony\Component\Form\FormError;
  12. use Symfony\Component\Form\FormView;
  13. use Symfony\Component\Form\FormFactory;
  14. use Symfony\Component\Form\CsrfProvider\DefaultCsrfProvider;
  15. use Symfony\Component\Form\Type\Loader\DefaultTypeLoader;
  16. use Symfony\Component\EventDispatcher\EventDispatcher;
  17. abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase
  18. {
  19. protected $factory;
  20. protected function setUp()
  21. {
  22. \Locale::setDefault('en');
  23. $dispatcher = new EventDispatcher();
  24. $validator = $this->getMock('Symfony\Component\Validator\ValidatorInterface');
  25. $csrfProvider = new DefaultCsrfProvider('foo');
  26. $storage = new \Symfony\Component\HttpFoundation\File\TemporaryStorage('foo', 1, \sys_get_temp_dir());
  27. $loader = new DefaultTypeLoader($validator, $csrfProvider , $storage);
  28. $this->factory = new FormFactory($loader);
  29. }
  30. protected function assertXpathNodeValue(\DomElement $element, $expression, $nodeValue)
  31. {
  32. $xpath = new \DOMXPath($element->ownerDocument);
  33. $nodeList = $xpath->evaluate($expression);
  34. $this->assertEquals(1, $nodeList->length);
  35. $this->assertEquals($nodeValue, $nodeList->item(0)->nodeValue);
  36. }
  37. protected function assertMatchesXpath($html, $expression, $count = 1)
  38. {
  39. $dom = new \DomDocument('UTF-8');
  40. try {
  41. // Wrap in <root> node so we can load HTML with multiple tags at
  42. // the top level
  43. $dom->loadXml('<root>'.$html.'</root>');
  44. } catch (\Exception $e) {
  45. return $this->fail(sprintf(
  46. "Failed loading HTML:\n\n%s\n\nError: %s",
  47. $html,
  48. $e->getMessage()
  49. ));
  50. }
  51. $xpath = new \DOMXPath($dom);
  52. $nodeList = $xpath->evaluate('/root'.$expression);
  53. if ($nodeList->length != $count) {
  54. $dom->formatOutput = true;
  55. $this->fail(sprintf(
  56. "Failed asserting that \n\n%s\n\nmatches exactly %s. Matches %s in \n\n%s",
  57. $expression,
  58. $count == 1 ? 'once' : $count . ' times',
  59. $nodeList->length == 1 ? 'once' : $nodeList->length . ' times',
  60. // strip away <root> and </root>
  61. substr($dom->saveHTML(), 6, -8)
  62. ));
  63. }
  64. }
  65. protected function assertWidgetMatchesXpath(FormView $view, array $vars, $xpath)
  66. {
  67. $html = $this->renderWidget($view, array_merge(array(
  68. 'id' => 'my_id',
  69. 'attr' => array('class' => 'my_class'),
  70. ), $vars));
  71. $xpath = trim($xpath).'
  72. [@id="my_id"]
  73. [@class="my_class"]';
  74. $this->assertMatchesXpath($html, $xpath);
  75. }
  76. abstract protected function renderEnctype(FormView $view);
  77. abstract protected function renderLabel(FormView $view, $label = null);
  78. abstract protected function renderErrors(FormView $view);
  79. abstract protected function renderWidget(FormView $view, array $vars = array());
  80. abstract protected function renderRow(FormView $view, array $vars = array());
  81. abstract protected function renderRest(FormView $view, array $vars = array());
  82. public function testEnctype()
  83. {
  84. $form = $this->factory->createBuilder('form', 'name')
  85. ->add('file', 'file')
  86. ->getForm();
  87. $this->assertEquals('enctype="multipart/form-data"', $this->renderEnctype($form->createView()));
  88. }
  89. public function testNoEnctype()
  90. {
  91. $form = $this->factory->createBuilder('form', 'name')
  92. ->add('text', 'text')
  93. ->getForm();
  94. $this->assertEquals('', $this->renderEnctype($form->createView()));
  95. }
  96. public function testLabel()
  97. {
  98. $form = $this->factory->create('text', 'name');
  99. $html = $this->renderLabel($form->createView());
  100. $this->assertMatchesXpath($html,
  101. '/label
  102. [@for="name"]
  103. [.="[trans]Name[/trans]"]
  104. '
  105. );
  106. }
  107. public function testLabelWithCustomText()
  108. {
  109. $form = $this->factory->create('text', 'name');
  110. $html = $this->renderLabel($form->createView(), 'Custom label');
  111. $this->assertMatchesXpath($html,
  112. '/label
  113. [@for="name"]
  114. [.="[trans]Custom label[/trans]"]
  115. '
  116. );
  117. }
  118. public function testErrors()
  119. {
  120. $form = $this->factory->create('text', 'name');
  121. $form->addError(new FormError('Error 1'));
  122. $form->addError(new FormError('Error 2'));
  123. $view = $form->createView();
  124. $html = $this->renderErrors($view);
  125. $this->assertMatchesXpath($html,
  126. '/ul
  127. [
  128. ./li[.="[trans]Error 1[/trans]"]
  129. /following-sibling::li[.="[trans]Error 2[/trans]"]
  130. ]
  131. [count(./li)=2]
  132. '
  133. );
  134. }
  135. public function testCheckedCheckbox()
  136. {
  137. $form = $this->factory->create('checkbox', 'name', array(
  138. 'data' => true,
  139. ));
  140. $this->assertWidgetMatchesXpath($form->createView(), array(),
  141. '/input
  142. [@type="checkbox"]
  143. [@name="name"]
  144. [@checked="checked"]
  145. [@value="1"]
  146. '
  147. );
  148. }
  149. public function testCheckedCheckboxWithValue()
  150. {
  151. $form = $this->factory->create('checkbox', 'name', array(
  152. 'value' => 'foobar',
  153. 'data' => true,
  154. ));
  155. $this->assertWidgetMatchesXpath($form->createView(), array(),
  156. '/input
  157. [@type="checkbox"]
  158. [@name="name"]
  159. [@checked="checked"]
  160. [@value="foobar"]
  161. '
  162. );
  163. }
  164. public function testUncheckedCheckbox()
  165. {
  166. $form = $this->factory->create('checkbox', 'name', array(
  167. 'data' => false,
  168. ));
  169. $this->assertWidgetMatchesXpath($form->createView(), array(),
  170. '/input
  171. [@type="checkbox"]
  172. [@name="name"]
  173. [not(@checked)]
  174. '
  175. );
  176. }
  177. public function testSingleChoice()
  178. {
  179. $form = $this->factory->create('choice', 'name', array(
  180. 'choices' => array('a' => 'A', 'b' => 'B'),
  181. 'data' => 'a',
  182. 'multiple' => false,
  183. 'expanded' => false,
  184. ));
  185. $this->assertWidgetMatchesXpath($form->createView(), array(),
  186. '/select
  187. [@name="name"]
  188. [
  189. ./option[@value="a"][@selected="selected"][.="A"]
  190. /following-sibling::option[@value="b"][not(@selected)][.="B"]
  191. ]
  192. [count(./option)=2]
  193. '
  194. );
  195. }
  196. public function testSingleChoiceWithPreferred()
  197. {
  198. $form = $this->factory->create('choice', 'name', array(
  199. 'choices' => array('a' => 'A', 'b' => 'B'),
  200. 'preferred_choices' => array('b'),
  201. 'data' => 'a',
  202. 'multiple' => false,
  203. 'expanded' => false,
  204. ));
  205. $this->assertWidgetMatchesXpath($form->createView(), array('separator' => '-- sep --'),
  206. '/select
  207. [@name="name"]
  208. [
  209. ./option[@value="b"][not(@selected)][.="B"]
  210. /following-sibling::option[@disabled="disabled"][not(@selected)][.="-- sep --"]
  211. /following-sibling::option[@value="a"][@selected="selected"][.="A"]
  212. ]
  213. [count(./option)=3]
  214. '
  215. );
  216. }
  217. public function testSingleChoiceNonRequired()
  218. {
  219. $form = $this->factory->create('choice', 'name', array(
  220. 'choices' => array('a' => 'A', 'b' => 'B'),
  221. 'required' => false,
  222. 'data' => 'a',
  223. 'multiple' => false,
  224. 'expanded' => false,
  225. ));
  226. $this->assertWidgetMatchesXpath($form->createView(), array(),
  227. '/select
  228. [@name="name"]
  229. [
  230. ./option[@value=""][.=""]
  231. /following-sibling::option[@value="a"][@selected="selected"][.="A"]
  232. /following-sibling::option[@value="b"][not(@selected)][.="B"]
  233. ]
  234. [count(./option)=3]
  235. '
  236. );
  237. }
  238. public function testSingleChoiceGrouped()
  239. {
  240. $form = $this->factory->create('choice', 'name', array(
  241. 'choices' => array(
  242. 'Group1' => array('a' => 'A', 'b' => 'B'),
  243. 'Group2' => array('c' => 'C'),
  244. ),
  245. 'data' => 'a',
  246. 'multiple' => false,
  247. 'expanded' => false,
  248. ));
  249. $this->assertWidgetMatchesXpath($form->createView(), array(),
  250. '/select
  251. [@name="name"]
  252. [./optgroup[@label="Group1"]
  253. [
  254. ./option[@value="a"][@selected="selected"][.="A"]
  255. /following-sibling::option[@value="b"][not(@selected)][.="B"]
  256. ]
  257. [count(./option)=2]
  258. ]
  259. [./optgroup[@label="Group2"]
  260. [./option[@value="c"][not(@selected)][.="C"]]
  261. [count(./option)=1]
  262. ]
  263. [count(./optgroup)=2]
  264. '
  265. );
  266. }
  267. public function testMultipleChoice()
  268. {
  269. $form = $this->factory->create('choice', 'name', array(
  270. 'choices' => array('a' => 'A', 'b' => 'B'),
  271. 'data' => array('a'),
  272. 'multiple' => true,
  273. 'expanded' => false,
  274. ));
  275. $this->assertWidgetMatchesXpath($form->createView(), array(),
  276. '/select
  277. [@name="name[]"]
  278. [@multiple="multiple"]
  279. [
  280. ./option[@value="a"][@selected="selected"][.="A"]
  281. /following-sibling::option[@value="b"][not(@selected)][.="B"]
  282. ]
  283. [count(./option)=2]
  284. '
  285. );
  286. }
  287. public function testMultipleChoiceNonRequired()
  288. {
  289. $form = $this->factory->create('choice', 'name', array(
  290. 'choices' => array('a' => 'A', 'b' => 'B'),
  291. 'data' => array('a'),
  292. 'required' => false,
  293. 'multiple' => true,
  294. 'expanded' => false,
  295. ));
  296. $this->assertWidgetMatchesXpath($form->createView(), array(),
  297. '/select
  298. [@name="name[]"]
  299. [@multiple="multiple"]
  300. [
  301. ./option[@value="a"][@selected="selected"][.="A"]
  302. /following-sibling::option[@value="b"][not(@selected)][.="B"]
  303. ]
  304. [count(./option)=2]
  305. '
  306. );
  307. }
  308. public function testSingleChoiceExpanded()
  309. {
  310. $form = $this->factory->create('choice', 'name', array(
  311. 'choices' => array('a' => 'A', 'b' => 'B'),
  312. 'data' => 'a',
  313. 'multiple' => false,
  314. 'expanded' => true,
  315. ));
  316. $this->assertWidgetMatchesXpath($form->createView(), array(),
  317. '/div
  318. [
  319. ./input[@type="radio"][@name="name"][@id="name_a"][@checked]
  320. /following-sibling::label[@for="name_a"][.="[trans]A[/trans]"]
  321. /following-sibling::input[@type="radio"][@name="name"][@id="name_b"][not(@checked)]
  322. /following-sibling::label[@for="name_b"][.="[trans]B[/trans]"]
  323. ]
  324. [count(./input)=2]
  325. '
  326. );
  327. }
  328. public function testMultipleChoiceExpanded()
  329. {
  330. $form = $this->factory->create('choice', 'name', array(
  331. 'choices' => array('a' => 'A', 'b' => 'B', 'c' => 'C'),
  332. 'data' => array('a', 'c'),
  333. 'multiple' => true,
  334. 'expanded' => true,
  335. ));
  336. $this->assertWidgetMatchesXpath($form->createView(), array(),
  337. '/div
  338. [
  339. ./input[@type="checkbox"][@name="name[a]"][@id="name_a"][@checked]
  340. /following-sibling::label[@for="name_a"][.="[trans]A[/trans]"]
  341. /following-sibling::input[@type="checkbox"][@name="name[b]"][@id="name_b"][not(@checked)]
  342. /following-sibling::label[@for="name_b"][.="[trans]B[/trans]"]
  343. /following-sibling::input[@type="checkbox"][@name="name[c]"][@id="name_c"][@checked]
  344. /following-sibling::label[@for="name_c"][.="[trans]C[/trans]"]
  345. ]
  346. [count(./input)=3]
  347. '
  348. );
  349. }
  350. public function testCountry()
  351. {
  352. $form = $this->factory->create('country', 'name', array(
  353. 'data' => 'AT',
  354. ));
  355. $this->assertWidgetMatchesXpath($form->createView(), array(),
  356. '/select
  357. [@name="name"]
  358. [./option[@value="AT"][@selected="selected"][.="Austria"]]
  359. [count(./option)>200]
  360. '
  361. );
  362. }
  363. public function testCsrf()
  364. {
  365. $form = $this->factory->create('csrf', 'name');
  366. $this->assertWidgetMatchesXpath($form->createView(), array(),
  367. '/input
  368. [@type="hidden"]
  369. [string-length(@value)>=40]
  370. '
  371. );
  372. }
  373. public function testCsrfWithNonRootParent()
  374. {
  375. $form = $this->factory->create('csrf', 'name');
  376. $form->setParent($this->factory->create('form'));
  377. $form->getParent()->setParent($this->factory->create('form'));
  378. $html = $this->renderWidget($form->createView());
  379. $this->assertEquals('', trim($html));
  380. }
  381. public function testDateTime()
  382. {
  383. $form = $this->factory->create('datetime', 'name', array(
  384. 'data' => '2011-02-03 04:05:06',
  385. 'input' => 'string',
  386. 'with_seconds' => false,
  387. ));
  388. $this->assertWidgetMatchesXpath($form->createView(), array(),
  389. '/div
  390. [
  391. ./div
  392. [@id="name_date"]
  393. [
  394. ./select
  395. [@id="name_date_month"]
  396. [./option[@value="2"][@selected="selected"]]
  397. /following-sibling::select
  398. [@id="name_date_day"]
  399. [./option[@value="3"][@selected="selected"]]
  400. /following-sibling::select
  401. [@id="name_date_year"]
  402. [./option[@value="2011"][@selected="selected"]]
  403. ]
  404. /following-sibling::div
  405. [@id="name_time"]
  406. [
  407. ./select
  408. [@id="name_time_hour"]
  409. [./option[@value="4"][@selected="selected"]]
  410. /following-sibling::select
  411. [@id="name_time_minute"]
  412. [./option[@value="5"][@selected="selected"]]
  413. ]
  414. ]
  415. [count(.//select)=5]
  416. '
  417. );
  418. }
  419. public function testDateTimeWithSeconds()
  420. {
  421. $form = $this->factory->create('datetime', 'name', array(
  422. 'data' => '2011-02-03 04:05:06',
  423. 'input' => 'string',
  424. 'with_seconds' => true,
  425. ));
  426. $this->assertWidgetMatchesXpath($form->createView(), array(),
  427. '/div
  428. [
  429. ./div
  430. [@id="name_date"]
  431. [
  432. ./select
  433. [@id="name_date_month"]
  434. [./option[@value="2"][@selected="selected"]]
  435. /following-sibling::select
  436. [@id="name_date_day"]
  437. [./option[@value="3"][@selected="selected"]]
  438. /following-sibling::select
  439. [@id="name_date_year"]
  440. [./option[@value="2011"][@selected="selected"]]
  441. ]
  442. /following-sibling::div
  443. [@id="name_time"]
  444. [
  445. ./select
  446. [@id="name_time_hour"]
  447. [./option[@value="4"][@selected="selected"]]
  448. /following-sibling::select
  449. [@id="name_time_minute"]
  450. [./option[@value="5"][@selected="selected"]]
  451. /following-sibling::select
  452. [@id="name_time_second"]
  453. [./option[@value="6"][@selected="selected"]]
  454. ]
  455. ]
  456. [count(.//select)=6]
  457. '
  458. );
  459. }
  460. public function testDateChoice()
  461. {
  462. $form = $this->factory->create('date', 'name', array(
  463. 'data' => '2011-02-03',
  464. 'input' => 'string',
  465. 'widget' => 'choice',
  466. ));
  467. $this->assertWidgetMatchesXpath($form->createView(), array(),
  468. '/div
  469. [
  470. ./select
  471. [@id="name_month"]
  472. [./option[@value="2"][@selected="selected"]]
  473. /following-sibling::select
  474. [@id="name_day"]
  475. [./option[@value="3"][@selected="selected"]]
  476. /following-sibling::select
  477. [@id="name_year"]
  478. [./option[@value="2011"][@selected="selected"]]
  479. ]
  480. [count(./select)=3]
  481. '
  482. );
  483. }
  484. public function testDateText()
  485. {
  486. $form = $this->factory->create('date', 'name', array(
  487. 'data' => '2011-02-03',
  488. 'input' => 'string',
  489. 'widget' => 'text',
  490. ));
  491. $this->assertWidgetMatchesXpath($form->createView(), array(),
  492. '/input
  493. [@type="text"]
  494. [@name="name"]
  495. [@value="Feb 3, 2011"]
  496. '
  497. );
  498. }
  499. public function testFile()
  500. {
  501. $form = $this->factory->create('file', 'name');
  502. $this->assertWidgetMatchesXpath($form->createView(), array(),
  503. '/div
  504. [
  505. ./input[@type="file"][@id="name_file"]
  506. /following-sibling::input[@type="hidden"][@id="name_token"]
  507. /following-sibling::input[@type="hidden"][@id="name_name"]
  508. ]
  509. [count(./input)=3]
  510. '
  511. );
  512. }
  513. public function testHidden()
  514. {
  515. $form = $this->factory->create('hidden', 'name', array(
  516. 'data' => 'foobar',
  517. ));
  518. $this->assertWidgetMatchesXpath($form->createView(), array(),
  519. '/input
  520. [@type="hidden"]
  521. [@name="name"]
  522. [@value="foobar"]
  523. '
  524. );
  525. }
  526. public function testInteger()
  527. {
  528. $form = $this->factory->create('integer', 'name', array(
  529. 'data' => '123',
  530. ));
  531. $this->assertWidgetMatchesXpath($form->createView(), array(),
  532. '/input
  533. [@type="number"]
  534. [@name="name"]
  535. [@value="123"]
  536. '
  537. );
  538. }
  539. public function testLanguage()
  540. {
  541. $form = $this->factory->create('language', 'name', array(
  542. 'data' => 'de',
  543. ));
  544. $this->assertWidgetMatchesXpath($form->createView(), array(),
  545. '/select
  546. [@name="name"]
  547. [./option[@value="de"][@selected="selected"][.="German"]]
  548. [count(./option)>200]
  549. '
  550. );
  551. }
  552. public function testLocale()
  553. {
  554. $form = $this->factory->create('locale', 'name', array(
  555. 'data' => 'de_AT',
  556. ));
  557. $this->assertWidgetMatchesXpath($form->createView(), array(),
  558. '/select
  559. [@name="name"]
  560. [./option[@value="de_AT"][@selected="selected"][.="German (Austria)"]]
  561. [count(./option)>200]
  562. '
  563. );
  564. }
  565. public function testMoney()
  566. {
  567. $form = $this->factory->create('money', 'name', array(
  568. 'data' => 1234.56,
  569. 'currency' => 'EUR',
  570. ));
  571. $this->assertWidgetMatchesXpath($form->createView(), array(),
  572. '/input
  573. [@type="text"]
  574. [@name="name"]
  575. [@value="1234.56"]
  576. [contains(.., "€")]
  577. '
  578. );
  579. }
  580. public function testNumber()
  581. {
  582. $form = $this->factory->create('number', 'name', array(
  583. 'data' => 1234.56,
  584. ));
  585. $this->assertWidgetMatchesXpath($form->createView(), array(),
  586. '/input
  587. [@type="text"]
  588. [@name="name"]
  589. [@value="1234.56"]
  590. '
  591. );
  592. }
  593. public function testPassword()
  594. {
  595. $form = $this->factory->create('password', 'name', array(
  596. 'data' => 'Pa$sW0rD',
  597. ));
  598. $this->assertWidgetMatchesXpath($form->createView(), array(),
  599. '/input
  600. [@type="password"]
  601. [@name="name"]
  602. [@value=""]
  603. '
  604. );
  605. }
  606. public function testPasswordWithMaxLength()
  607. {
  608. $form = $this->factory->create('password', 'name', array(
  609. 'data' => 'Pa$sW0rD',
  610. 'max_length' => 123,
  611. ));
  612. $this->assertWidgetMatchesXpath($form->createView(), array(),
  613. '/input
  614. [@type="password"]
  615. [@name="name"]
  616. [@value=""]
  617. [@maxlength="123"]
  618. '
  619. );
  620. }
  621. public function testPercent()
  622. {
  623. $form = $this->factory->create('percent', 'name', array(
  624. 'data' => 0.1,
  625. ));
  626. $this->assertWidgetMatchesXpath($form->createView(), array(),
  627. '/input
  628. [@type="text"]
  629. [@name="name"]
  630. [@value="10"]
  631. [contains(.., "%")]
  632. '
  633. );
  634. }
  635. public function testCheckedRadio()
  636. {
  637. $form = $this->factory->create('radio', 'name', array(
  638. 'data' => true,
  639. ));
  640. $this->assertWidgetMatchesXpath($form->createView(), array(),
  641. '/input
  642. [@type="radio"]
  643. [@name="name"]
  644. [@checked="checked"]
  645. [@value=""]
  646. '
  647. );
  648. }
  649. public function testCheckedRadioWithValue()
  650. {
  651. $form = $this->factory->create('radio', 'name', array(
  652. 'data' => true,
  653. 'value' => 'foobar',
  654. ));
  655. $this->assertWidgetMatchesXpath($form->createView(), array(),
  656. '/input
  657. [@type="radio"]
  658. [@name="name"]
  659. [@checked="checked"]
  660. [@value="foobar"]
  661. '
  662. );
  663. }
  664. public function testUncheckedRadio()
  665. {
  666. $form = $this->factory->create('radio', 'name', array(
  667. 'data' => false,
  668. ));
  669. $this->assertWidgetMatchesXpath($form->createView(), array(),
  670. '/input
  671. [@type="radio"]
  672. [@name="name"]
  673. [not(@checked)]
  674. '
  675. );
  676. }
  677. public function testTextarea()
  678. {
  679. $form = $this->factory->create('textarea', 'name', array(
  680. 'data' => 'foobar',
  681. ));
  682. $this->assertWidgetMatchesXpath($form->createView(), array(),
  683. '/textarea
  684. [@name="name"]
  685. [.="foobar"]
  686. '
  687. );
  688. }
  689. public function testText()
  690. {
  691. $form = $this->factory->create('text', 'name', array(
  692. 'data' => 'foobar',
  693. ));
  694. $this->assertWidgetMatchesXpath($form->createView(), array(),
  695. '/input
  696. [@type="text"]
  697. [@name="name"]
  698. [@value="foobar"]
  699. [not(@maxlength)]
  700. '
  701. );
  702. }
  703. public function testTextWithMaxLength()
  704. {
  705. $form = $this->factory->create('text', 'name', array(
  706. 'data' => 'foobar',
  707. 'max_length' => 123,
  708. ));
  709. $this->assertWidgetMatchesXpath($form->createView(), array(),
  710. '/input
  711. [@type="text"]
  712. [@name="name"]
  713. [@value="foobar"]
  714. [@maxlength="123"]
  715. '
  716. );
  717. }
  718. public function testTime()
  719. {
  720. $form = $this->factory->create('time', 'name', array(
  721. 'data' => '04:05:06',
  722. 'input' => 'string',
  723. 'with_seconds' => false,
  724. ));
  725. $this->assertWidgetMatchesXpath($form->createView(), array(),
  726. '/div
  727. [
  728. ./select
  729. [@id="name_hour"]
  730. [@size="1"]
  731. [./option[@value="4"][@selected="selected"]]
  732. /following-sibling::select
  733. [@id="name_minute"]
  734. [@size="1"]
  735. [./option[@value="5"][@selected="selected"]]
  736. ]
  737. [count(./select)=2]
  738. '
  739. );
  740. }
  741. public function testTimeWithSeconds()
  742. {
  743. $form = $this->factory->create('time', 'name', array(
  744. 'data' => '04:05:06',
  745. 'input' => 'string',
  746. 'with_seconds' => true,
  747. ));
  748. $this->assertWidgetMatchesXpath($form->createView(), array(),
  749. '/div
  750. [
  751. ./select
  752. [@id="name_hour"]
  753. [@size="1"]
  754. [./option[@value="4"][@selected="selected"]]
  755. /following-sibling::select
  756. [@id="name_minute"]
  757. [@size="1"]
  758. [./option[@value="5"][@selected="selected"]]
  759. /following-sibling::select
  760. [@id="name_second"]
  761. [@size="1"]
  762. [./option[@value="6"][@selected="selected"]]
  763. ]
  764. [count(./select)=3]
  765. '
  766. );
  767. }
  768. public function testTimezone()
  769. {
  770. $form = $this->factory->create('timezone', 'name', array(
  771. 'data' => 'Europe/Vienna',
  772. ));
  773. $this->assertWidgetMatchesXpath($form->createView(), array(),
  774. '/select
  775. [@name="name"]
  776. [./optgroup
  777. [@label="Europe"]
  778. [./option[@value="Europe/Vienna"][@selected="selected"][.="Vienna"]]
  779. ]
  780. [count(./optgroup)>10]
  781. [count(.//option)>200]
  782. '
  783. );
  784. }
  785. public function testUrl()
  786. {
  787. $form = $this->factory->create('url', 'name', array(
  788. 'data' => 'http://www.google.com',
  789. ));
  790. $this->assertWidgetMatchesXpath($form->createView(), array(),
  791. '/input
  792. [@type="url"]
  793. [@name="name"]
  794. [@value="http://www.google.com"]
  795. '
  796. );
  797. }
  798. }