1. sfTesterForm.class.php
  2. /** * sfTesterForm implements tests for forms submitted by the user. * * @package symfony * @subpackage test * @author Fabien Potencier * @version SVN: $Id: sfTesterForm.class.php 24217 2009-11-22 06:47:54Z fabien $ */
  3. class sfTesterForm extends sfTester
  4. {
  5. protected
  6. $form = null;
  7. /**
  8. * Constructor.
  9. *
  10. * @param sfTestFunctionalBase $browser A browser
  11. * @param lime_test $tester A tester object
  12. */
  13. public function __construct(sfTestFunctionalBase $browser, $tester)
  14. {
  15. parent::__construct($browser, $tester);
  16. $this->browser->addListener('template.filter_parameters', array($this, 'filterTemplateParameters'));
  17. }
  18. /**
  19. * Prepares the tester.
  20. */
  21. public function prepare()
  22. {
  23. $this->form = null;
  24. }
  25. /**
  26. * Initiliazes the tester.
  27. */
  28. public function initialize()
  29. {
  30. if (null === $this->form)
  31. {
  32. $action = $this->browser->getContext()->getActionStack()->getLastEntry()->getActionInstance();
  33. foreach ($action->getVarHolder()->getAll() as $name => $value)
  34. {
  35. if ($value instanceof sfForm && $value->isBound())
  36. {
  37. $this->form = $value;
  38. break;
  39. }
  40. }
  41. }
  42. }
  43. /**
  44. * Returns the current form.
  45. *
  46. * @return sfForm The current sfForm form instance
  47. */
  48. public function getForm()
  49. {
  50. return $this->form;
  51. }
  52. /**
  53. * Tests if the submitted form has some error.
  54. *
  55. * @param Boolean|integer $value Whether to check if the form has error or not, or the number of errors
  56. *
  57. * @return sfTestFunctionalBase|sfTester
  58. */
  59. public function hasErrors($value = true)
  60. {
  61. if (null === $this->form)
  62. {
  63. throw new LogicException('no form has been submitted.');
  64. }
  65. if (is_int($value))
  66. {
  67. $this->tester->is(count($this->form->getErrorSchema()), $value, sprintf('the submitted form has "%s" errors.', $value));
  68. }
  69. else
  70. {
  71. $this->tester->is($this->form->hasErrors(), $value, sprintf('the submitted form %s.', ($value) ? 'has some errors' : 'is valid'));
  72. }
  73. return $this->getObjectToReturn();
  74. }
  75. /**
  76. * Tests if the submitted form has a specific error.
  77. *
  78. * @param mixed $value The error message or the number of errors for the field (optional)
  79. *
  80. * @return sfTestFunctionalBase|sfTester
  81. */
  82. public function hasGlobalError($value = true)
  83. {
  84. return $this->isError(null, $value);
  85. }
  86. /**
  87. * Tests if the submitted form has a specific error.
  88. *
  89. * @param string $field The field name to check for an error (null for global errors)
  90. * @param mixed $value The error message or the number of errors for the field (optional)
  91. *
  92. * @return sfTestFunctionalBase|sfTester
  93. */
  94. public function isError($field, $value = true)
  95. {
  96. if (null === $this->form)
  97. {
  98. throw new LogicException('no form has been submitted.');
  99. }
  100. if (null === $field)
  101. {
  102. $error = new sfValidatorErrorSchema(new sfValidatorPass(), $this->form->getGlobalErrors());
  103. }
  104. else
  105. {
  106. $error = $this->getFormField($field)->getError();
  107. }
  108. if (false === $value)
  109. {
  110. $this->tester->ok(!$error || 0 == count($error), sprintf('the submitted form has no "%s" error.', $field));
  111. }
  112. else if (true === $value)
  113. {
  114. $this->tester->ok($error && count($error) > 0, sprintf('the submitted form has a "%s" error.', $field));
  115. }
  116. else if (is_int($value))
  117. {
  118. $this->tester->ok($error && count($error) == $value, sprintf('the submitted form has %s "%s" error(s).', $value, $field));
  119. }
  120. else if (preg_match('/^(!)?([^a-zA-Z0-9\\\\]).+?\\2[ims]?$/', $value, $match))
  121. {
  122. if (!$error)
  123. {
  124. $this->tester->fail(sprintf('the submitted form has a "%s" error.', $field));
  125. }
  126. else
  127. {
  128. if ($match[1] == '!')
  129. {
  130. $this->tester->unlike($error->getCode(), substr($value, 1), sprintf('the submitted form has a "%s" error that does not match "%s".', $field, $value));
  131. }
  132. else
  133. {
  134. $this->tester->like($error->getCode(), $value, sprintf('the submitted form has a "%s" error that matches "%s".', $field, $value));
  135. }
  136. }
  137. }
  138. else
  139. {
  140. if (!$error)
  141. {
  142. $this->tester->fail(sprintf('the submitted form has a "%s" error (%s).', $field, $value));
  143. }
  144. else
  145. {
  146. $this->tester->is($error->getCode(), $value, sprintf('the submitted form has a "%s" error (%s).', $field, $value));
  147. }
  148. }
  149. return $this->getObjectToReturn();
  150. }
  151. /**
  152. * Outputs some debug information about the current submitted form.
  153. */
  154. public function debug()
  155. {
  156. if (null === $this->form)
  157. {
  158. throw new LogicException('no form has been submitted.');
  159. }
  160. print $this->tester->error('Form debug');
  161. print sprintf("Submitted values: %s\n", str_replace("\n", '', var_export($this->form->getTaintedValues(), true)));
  162. print sprintf("Errors: %s\n", $this->form->getErrorSchema());
  163. exit(1);
  164. }
  165. /**
  166. * Listens to the template.filter_parameters event to get the submitted form object.
  167. *
  168. * @param sfEvent $event The event
  169. * @param array $parameters An array of parameters passed to the template
  170. *
  171. * @return array The array of parameters passed to the template
  172. */
  173. public function filterTemplateParameters(sfEvent $event, $parameters)
  174. {
  175. if (!isset($parameters['sf_type']))
  176. {
  177. return $parameters;
  178. }
  179. if ('action' == $parameters['sf_type'])
  180. {
  181. foreach ($parameters as $key => $value)
  182. {
  183. if ($value instanceof sfForm && $value->isBound())
  184. {
  185. $this->form = $value;
  186. break;
  187. }
  188. }
  189. }
  190. return $parameters;
  191. }
  192. /**
  193. * @param string $path
  194. * @return sfFormField
  195. */
  196. public function getFormField($path)
  197. {
  198. if (false !== $pos = strpos($path, '['))
  199. {
  200. $field = $this->form[substr($path, 0, $pos)];
  201. }
  202. else
  203. {
  204. return $this->form[$path];
  205. }
  206. if (preg_match_all('/\[(?P<part>[^]]+)\]/', $path, $matches))
  207. {
  208. foreach($matches['part'] as $part)
  209. {
  210. $field = $field[$part];
  211. }
  212. }
  213. return $field;
  214. }
  215. }

Debug toolbar