ChoiceFormFieldTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  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\Component\DomCrawler\Tests\Field;
  11. use Symfony\Component\DomCrawler\Field\ChoiceFormField;
  12. class ChoiceFormFieldTest extends FormFieldTestCase
  13. {
  14. public function testInitialize()
  15. {
  16. $node = $this->createNode('textarea', '');
  17. try {
  18. $field = new ChoiceFormField($node);
  19. $this->fail('->initialize() throws a \LogicException if the node is not an input or a select');
  20. } catch (\LogicException $e) {
  21. $this->assertTrue(true, '->initialize() throws a \LogicException if the node is not an input or a select');
  22. }
  23. $node = $this->createNode('input', '', ['type' => 'text']);
  24. try {
  25. $field = new ChoiceFormField($node);
  26. $this->fail('->initialize() throws a \LogicException if the node is an input with a type different from checkbox or radio');
  27. } catch (\LogicException $e) {
  28. $this->assertTrue(true, '->initialize() throws a \LogicException if the node is an input with a type different from checkbox or radio');
  29. }
  30. }
  31. public function testGetType()
  32. {
  33. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'foo']);
  34. $field = new ChoiceFormField($node);
  35. $this->assertEquals('radio', $field->getType(), '->getType() returns radio for radio buttons');
  36. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name', 'value' => 'foo']);
  37. $field = new ChoiceFormField($node);
  38. $this->assertEquals('checkbox', $field->getType(), '->getType() returns radio for a checkbox');
  39. $node = $this->createNode('select', '');
  40. $field = new ChoiceFormField($node);
  41. $this->assertEquals('select', $field->getType(), '->getType() returns radio for a select');
  42. }
  43. public function testIsMultiple()
  44. {
  45. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'foo']);
  46. $field = new ChoiceFormField($node);
  47. $this->assertFalse($field->isMultiple(), '->isMultiple() returns false for radio buttons');
  48. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name', 'value' => 'foo']);
  49. $field = new ChoiceFormField($node);
  50. $this->assertFalse($field->isMultiple(), '->isMultiple() returns false for checkboxes');
  51. $node = $this->createNode('select', '');
  52. $field = new ChoiceFormField($node);
  53. $this->assertFalse($field->isMultiple(), '->isMultiple() returns false for selects without the multiple attribute');
  54. $node = $this->createNode('select', '', ['multiple' => 'multiple']);
  55. $field = new ChoiceFormField($node);
  56. $this->assertTrue($field->isMultiple(), '->isMultiple() returns true for selects with the multiple attribute');
  57. $node = $this->createNode('select', '', ['multiple' => '']);
  58. $field = new ChoiceFormField($node);
  59. $this->assertTrue($field->isMultiple(), '->isMultiple() returns true for selects with an empty multiple attribute');
  60. }
  61. public function testSelects()
  62. {
  63. $node = $this->createSelectNode(['foo' => false, 'bar' => false]);
  64. $field = new ChoiceFormField($node);
  65. $this->assertTrue($field->hasValue(), '->hasValue() returns true for selects');
  66. $this->assertEquals('foo', $field->getValue(), '->getValue() returns the first option if none are selected');
  67. $this->assertFalse($field->isMultiple(), '->isMultiple() returns false when no multiple attribute is defined');
  68. $node = $this->createSelectNode(['foo' => false, 'bar' => true]);
  69. $field = new ChoiceFormField($node);
  70. $this->assertEquals('bar', $field->getValue(), '->getValue() returns the selected option');
  71. $field->setValue('foo');
  72. $this->assertEquals('foo', $field->getValue(), '->setValue() changes the selected option');
  73. try {
  74. $field->setValue('foobar');
  75. $this->fail('->setValue() throws an \InvalidArgumentException if the value is not one of the selected options');
  76. } catch (\InvalidArgumentException $e) {
  77. $this->assertTrue(true, '->setValue() throws an \InvalidArgumentException if the value is not one of the selected options');
  78. }
  79. try {
  80. $field->setValue(['foobar']);
  81. $this->fail('->setValue() throws an \InvalidArgumentException if the value is an array');
  82. } catch (\InvalidArgumentException $e) {
  83. $this->assertTrue(true, '->setValue() throws an \InvalidArgumentException if the value is an array');
  84. }
  85. }
  86. public function testSelectWithEmptyBooleanAttribute()
  87. {
  88. $node = $this->createSelectNode(['foo' => false, 'bar' => true], [], '');
  89. $field = new ChoiceFormField($node);
  90. $this->assertEquals('bar', $field->getValue());
  91. }
  92. public function testSelectIsDisabled()
  93. {
  94. $node = $this->createSelectNode(['foo' => false, 'bar' => true], ['disabled' => 'disabled']);
  95. $field = new ChoiceFormField($node);
  96. $this->assertTrue($field->isDisabled(), '->isDisabled() returns true for selects with a disabled attribute');
  97. }
  98. public function testMultipleSelects()
  99. {
  100. $node = $this->createSelectNode(['foo' => false, 'bar' => false], ['multiple' => 'multiple']);
  101. $field = new ChoiceFormField($node);
  102. $this->assertEquals([], $field->getValue(), '->setValue() returns an empty array if multiple is true and no option is selected');
  103. $field->setValue('foo');
  104. $this->assertEquals(['foo'], $field->getValue(), '->setValue() returns an array of options if multiple is true');
  105. $field->setValue('bar');
  106. $this->assertEquals(['bar'], $field->getValue(), '->setValue() returns an array of options if multiple is true');
  107. $field->setValue(['foo', 'bar']);
  108. $this->assertEquals(['foo', 'bar'], $field->getValue(), '->setValue() returns an array of options if multiple is true');
  109. $node = $this->createSelectNode(['foo' => true, 'bar' => true], ['multiple' => 'multiple']);
  110. $field = new ChoiceFormField($node);
  111. $this->assertEquals(['foo', 'bar'], $field->getValue(), '->getValue() returns the selected options');
  112. try {
  113. $field->setValue(['foobar']);
  114. $this->fail('->setValue() throws an \InvalidArgumentException if the value is not one of the options');
  115. } catch (\InvalidArgumentException $e) {
  116. $this->assertTrue(true, '->setValue() throws an \InvalidArgumentException if the value is not one of the options');
  117. }
  118. }
  119. public function testRadioButtons()
  120. {
  121. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'foo']);
  122. $field = new ChoiceFormField($node);
  123. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'bar']);
  124. $field->addChoice($node);
  125. $this->assertFalse($field->hasValue(), '->hasValue() returns false when no radio button is selected');
  126. $this->assertNull($field->getValue(), '->getValue() returns null if no radio button is selected');
  127. $this->assertFalse($field->isMultiple(), '->isMultiple() returns false for radio buttons');
  128. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'foo']);
  129. $field = new ChoiceFormField($node);
  130. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'bar', 'checked' => 'checked']);
  131. $field->addChoice($node);
  132. $this->assertTrue($field->hasValue(), '->hasValue() returns true when a radio button is selected');
  133. $this->assertEquals('bar', $field->getValue(), '->getValue() returns the value attribute of the selected radio button');
  134. $field->setValue('foo');
  135. $this->assertEquals('foo', $field->getValue(), '->setValue() changes the selected radio button');
  136. try {
  137. $field->setValue('foobar');
  138. $this->fail('->setValue() throws an \InvalidArgumentException if the value is not one of the radio button values');
  139. } catch (\InvalidArgumentException $e) {
  140. $this->assertTrue(true, '->setValue() throws an \InvalidArgumentException if the value is not one of the radio button values');
  141. }
  142. }
  143. public function testRadioButtonsWithEmptyBooleanAttribute()
  144. {
  145. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'foo']);
  146. $field = new ChoiceFormField($node);
  147. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'bar', 'checked' => '']);
  148. $field->addChoice($node);
  149. $this->assertTrue($field->hasValue(), '->hasValue() returns true when a radio button is selected');
  150. $this->assertEquals('bar', $field->getValue(), '->getValue() returns the value attribute of the selected radio button');
  151. }
  152. public function testRadioButtonIsDisabled()
  153. {
  154. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'foo', 'disabled' => 'disabled']);
  155. $field = new ChoiceFormField($node);
  156. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'bar']);
  157. $field->addChoice($node);
  158. $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'baz', 'disabled' => '']);
  159. $field->addChoice($node);
  160. $field->select('foo');
  161. $this->assertEquals('foo', $field->getValue(), '->getValue() returns the value attribute of the selected radio button');
  162. $this->assertTrue($field->isDisabled());
  163. $field->select('bar');
  164. $this->assertEquals('bar', $field->getValue(), '->getValue() returns the value attribute of the selected radio button');
  165. $this->assertFalse($field->isDisabled());
  166. $field->select('baz');
  167. $this->assertEquals('baz', $field->getValue(), '->getValue() returns the value attribute of the selected radio button');
  168. $this->assertTrue($field->isDisabled());
  169. }
  170. public function testCheckboxes()
  171. {
  172. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name']);
  173. $field = new ChoiceFormField($node);
  174. $this->assertFalse($field->hasValue(), '->hasValue() returns false when the checkbox is not checked');
  175. $this->assertNull($field->getValue(), '->getValue() returns null if the checkbox is not checked');
  176. $this->assertFalse($field->isMultiple(), '->hasValue() returns false for checkboxes');
  177. try {
  178. $field->addChoice(new \DOMElement('input'));
  179. $this->fail('->addChoice() throws a \LogicException for checkboxes');
  180. } catch (\LogicException $e) {
  181. $this->assertTrue(true, '->initialize() throws a \LogicException for checkboxes');
  182. }
  183. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name', 'checked' => 'checked']);
  184. $field = new ChoiceFormField($node);
  185. $this->assertTrue($field->hasValue(), '->hasValue() returns true when the checkbox is checked');
  186. $this->assertEquals('on', $field->getValue(), '->getValue() returns 1 if the checkbox is checked and has no value attribute');
  187. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name', 'checked' => 'checked', 'value' => 'foo']);
  188. $field = new ChoiceFormField($node);
  189. $this->assertEquals('foo', $field->getValue(), '->getValue() returns the value attribute if the checkbox is checked');
  190. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name', 'checked' => 'checked', 'value' => 'foo']);
  191. $field = new ChoiceFormField($node);
  192. $field->setValue(false);
  193. $this->assertNull($field->getValue(), '->setValue() unchecks the checkbox is value is false');
  194. $field->setValue(true);
  195. $this->assertEquals('foo', $field->getValue(), '->setValue() checks the checkbox is value is true');
  196. try {
  197. $field->setValue('bar');
  198. $this->fail('->setValue() throws an \InvalidArgumentException if the value is not one from the value attribute');
  199. } catch (\InvalidArgumentException $e) {
  200. $this->assertTrue(true, '->setValue() throws an \InvalidArgumentException if the value is not one from the value attribute');
  201. }
  202. }
  203. public function testCheckboxWithEmptyBooleanAttribute()
  204. {
  205. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name', 'value' => 'foo', 'checked' => '']);
  206. $field = new ChoiceFormField($node);
  207. $this->assertTrue($field->hasValue(), '->hasValue() returns true when the checkbox is checked');
  208. $this->assertEquals('foo', $field->getValue());
  209. }
  210. public function testTick()
  211. {
  212. $node = $this->createSelectNode(['foo' => false, 'bar' => false]);
  213. $field = new ChoiceFormField($node);
  214. try {
  215. $field->tick();
  216. $this->fail('->tick() throws a \LogicException for select boxes');
  217. } catch (\LogicException $e) {
  218. $this->assertTrue(true, '->tick() throws a \LogicException for select boxes');
  219. }
  220. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name']);
  221. $field = new ChoiceFormField($node);
  222. $field->tick();
  223. $this->assertEquals('on', $field->getValue(), '->tick() ticks checkboxes');
  224. }
  225. public function testUntick()
  226. {
  227. $node = $this->createSelectNode(['foo' => false, 'bar' => false]);
  228. $field = new ChoiceFormField($node);
  229. try {
  230. $field->untick();
  231. $this->fail('->untick() throws a \LogicException for select boxes');
  232. } catch (\LogicException $e) {
  233. $this->assertTrue(true, '->untick() throws a \LogicException for select boxes');
  234. }
  235. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name', 'checked' => 'checked']);
  236. $field = new ChoiceFormField($node);
  237. $field->untick();
  238. $this->assertNull($field->getValue(), '->untick() unticks checkboxes');
  239. }
  240. public function testSelect()
  241. {
  242. $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name', 'checked' => 'checked']);
  243. $field = new ChoiceFormField($node);
  244. $field->select(true);
  245. $this->assertEquals('on', $field->getValue(), '->select() changes the value of the field');
  246. $field->select(false);
  247. $this->assertNull($field->getValue(), '->select() changes the value of the field');
  248. $node = $this->createSelectNode(['foo' => false, 'bar' => false]);
  249. $field = new ChoiceFormField($node);
  250. $field->select('foo');
  251. $this->assertEquals('foo', $field->getValue(), '->select() changes the selected option');
  252. }
  253. public function testOptionWithNoValue()
  254. {
  255. $node = $this->createSelectNodeWithEmptyOption(['foo' => false, 'bar' => false]);
  256. $field = new ChoiceFormField($node);
  257. $this->assertEquals('foo', $field->getValue());
  258. $node = $this->createSelectNodeWithEmptyOption(['foo' => false, 'bar' => true]);
  259. $field = new ChoiceFormField($node);
  260. $this->assertEquals('bar', $field->getValue());
  261. $field->select('foo');
  262. $this->assertEquals('foo', $field->getValue(), '->select() changes the selected option');
  263. }
  264. public function testDisableValidation()
  265. {
  266. $node = $this->createSelectNode(['foo' => false, 'bar' => false]);
  267. $field = new ChoiceFormField($node);
  268. $field->disableValidation();
  269. $field->setValue('foobar');
  270. $this->assertEquals('foobar', $field->getValue(), '->disableValidation() allows to set a value which is not in the selected options.');
  271. $node = $this->createSelectNode(['foo' => false, 'bar' => false], ['multiple' => 'multiple']);
  272. $field = new ChoiceFormField($node);
  273. $field->disableValidation();
  274. $field->setValue(['foobar']);
  275. $this->assertEquals(['foobar'], $field->getValue(), '->disableValidation() allows to set a value which is not in the selected options.');
  276. }
  277. public function testSelectWithEmptyValue()
  278. {
  279. $node = $this->createSelectNodeWithEmptyOption(['' => true, 'Female' => false, 'Male' => false]);
  280. $field = new ChoiceFormField($node);
  281. $this->assertSame('', $field->getValue());
  282. }
  283. protected function createSelectNode($options, $attributes = [], $selectedAttrText = 'selected')
  284. {
  285. $document = new \DOMDocument();
  286. $node = $document->createElement('select');
  287. foreach ($attributes as $name => $value) {
  288. $node->setAttribute($name, $value);
  289. }
  290. $node->setAttribute('name', 'name');
  291. foreach ($options as $value => $selected) {
  292. $option = $document->createElement('option', $value);
  293. $option->setAttribute('value', $value);
  294. if ($selected) {
  295. $option->setAttribute('selected', $selectedAttrText);
  296. }
  297. $node->appendChild($option);
  298. }
  299. return $node;
  300. }
  301. protected function createSelectNodeWithEmptyOption($options, $attributes = [])
  302. {
  303. $document = new \DOMDocument();
  304. $node = $document->createElement('select');
  305. foreach ($attributes as $name => $value) {
  306. $node->setAttribute($name, $value);
  307. }
  308. $node->setAttribute('name', 'name');
  309. foreach ($options as $value => $selected) {
  310. $option = $document->createElement('option', $value);
  311. if ($selected) {
  312. $option->setAttribute('selected', 'selected');
  313. }
  314. $node->appendChild($option);
  315. }
  316. return $node;
  317. }
  318. }