From aee33deb3abedc8e5f9e86f89f44ceff3602c632 Mon Sep 17 00:00:00 2001 From: the_undefined Date: Tue, 22 Apr 2008 19:53:00 +0000 Subject: [PATCH] Implemented CakeTestCase::assertTags Replaced some regex in Form helper test with it git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6710 3807eeeb-6ff5-0310-8944-8be069107fe0 --- .../cases/libs/view/helpers/form.test.php | 28 ++--- cake/tests/lib/cake_test_case.php | 100 ++++++++++++++++++ 2 files changed, 110 insertions(+), 18 deletions(-) diff --git a/cake/tests/cases/libs/view/helpers/form.test.php b/cake/tests/cases/libs/view/helpers/form.test.php index b130c0aea..f5684e4c0 100644 --- a/cake/tests/cases/libs/view/helpers/form.test.php +++ b/cake/tests/cases/libs/view/helpers/form.test.php @@ -241,26 +241,18 @@ class FormHelperTest extends CakeTestCase { $this->Form->params['_Token'] = array('key' => 'testKey'); $result = $this->Form->create('Contact', array('url' => '/contacts/add')); - $this->assertPattern('/^]*>.+$/', $result); - $this->assertPattern('/^]+method="post"[^<>]*>.+$/', $result); - $this->assertPattern('/^]+action="[^"]+"[^<>]*>.+$/', $result); - $this->assertNoPattern('/^]+[^id|method|action]=[^<>]*>/', $result); - $this->assertPattern('/]+type="hidden"[^<>]*\/>/', $result); - $this->assertPattern('/]+name="data\[__Token\]\[key\]"[^<>]*\/>/', $result); - $this->assertPattern('/]+value="testKey"[^<>]*\/>/', $result); - $this->assertPattern('/]+id="\w+"[^<>]*\/>/', $result); - $this->assertNoPattern('/]+[^type|name|value|id]=[^<>]*>/', $result); + $expected = array( + 'form' => array('method' => 'post', 'action' => '/contacts/add'), + 'fieldset' => array('style' => 'display:none;'), + array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')), + array('input' => array('type' => 'hidden', 'name' => 'data[__Token][key]', 'value' => 'testKey', 'id')), + '!fieldset' + ); + $this->assertTags($result, $expected); $result = $this->Form->create('Contact', array('url' => '/contacts/add', 'id' => 'MyForm')); - $this->assertPattern('/^]+id="MyForm"[^<>]*>.+$/', $result); - $this->assertPattern('/^]+method="post"[^<>]*>.+$/', $result); - $this->assertPattern('/^]+action="[^"]+"[^<>]*>.+$/', $result); - $this->assertNoPattern('/^]+[^id|method|action]=[^<>]*>/', $result); - $this->assertPattern('/]+type="hidden"[^<>]*\/>/', $result); - $this->assertPattern('/]+name="data\[__Token\]\[key\]"[^<>]*\/>/', $result); - $this->assertPattern('/]+value="testKey"[^<>]*\/>/', $result); - $this->assertPattern('/]+id="\w+"[^<>]*\/>/', $result); - $this->assertNoPattern('/]+[^type|name|value|id]=[^<>]*>/', $result); + $expected['form']['id'] = 'MyForm'; + $this->assertTags($result, $expected); } function testFormSecurityFields() { diff --git a/cake/tests/lib/cake_test_case.php b/cake/tests/lib/cake_test_case.php index 5cb8a9647..862a66850 100644 --- a/cake/tests/lib/cake_test_case.php +++ b/cake/tests/lib/cake_test_case.php @@ -412,6 +412,106 @@ class CakeTestCase extends UnitTestCase { } } } +/** + * Takes an array $expected and generates a regex from it to match the provided $string. Samples for $expected: + * + * Checks for an input tag with a name attribute (contains any value) and an id attribute that contains 'my-input': + * array('input' => array('name', 'id' => 'my-input')) + * + * Checks for two p elements with some text in them: + * array( + * array('p' => true), + * 'textA', + * '!p', + * array('p' => true), + * 'textB', + * '!p' + * ) + * + * Important: This function is very forgiving about whitespace and also accepts any permutation of attribute order. + * + * @param string $string An HTML/XHTML/XML string + * @param string $expected An array, see above + * @param string $message SimpleTest failure output string + * @access public + */ + function assertTags($string, $expected, $message = '%s') { + $regex = array(); + $normalized = array(); + foreach ($expected as $key => $val) { + if (!is_numeric($key)) { + $normalized[] = array($key => $val); + } else { + $normalized[] = $val; + } + } + foreach ($normalized as $tags) { + if (is_string($tags)) { + if ($tags{0} == '!') { + $regex[] = '<[\s]*\/[\s]*'.substr($tags, 1).'[\s]*>'; + continue; + } + $regex[] = preg_quote($tags, '/'); + continue; + } + foreach ($tags as $tag => $attributes) { + $regex[] = '<'.preg_quote($tag, '/'); + if ($attributes === true) { + $attributes = array(); + } + $attrs = array(); + foreach ($attributes as $attr => $val) { + if (is_numeric($attr)) { + $attr = $val; + $val = '.*?'; + } else { + $val = preg_quote($val, '/'); + } + $attrs[] = '[\s]+'.preg_quote($attr, '/').'="'.$val.'"'; + } + if ($attrs) { + $permutations = $this->__array_permute($attrs); + $regex[] = '('; + foreach ($permutations as $permutation) { + $regex = am($regex, $permutation); + $regex[] = '|'; + } + array_pop($regex); + $regex[] =')'; + } + $regex[] = '[\s]*\/?[\s]*>[^<>]*'; + } + } + $regex = '/^'.join('', $regex).'/Us'; + return $this->assertPattern($regex, $string, $message); + } +/** + * Generates all permutation of an array $items and returns them in a new array. + * + * @param string $items An array of items + * @return array + * @access public + */ + function __array_permute($items, $perms = array()) { + static $permuted; + if (empty($perms)) { + $permuted = array(); + } + + if (empty($items)) { + $permuted[] = $perms; + } else { + $numItems = count($items) - 1; + for ($i = $numItems; $i >= 0; --$i) { + $newItems = $items; + $newPerms = $perms; + list($tmp) = array_splice($newItems, $i, 1); + array_unshift($newPerms, $tmp); + $this->__array_permute($newItems, $newPerms); + } + return $permuted; + } + } /** * Initialize DB connection. *