switch method parser to state machine

This commit is contained in:
John Bintz 2010-01-30 11:25:49 -05:00
parent 1f1f3eac96
commit bebcdf1046
2 changed files with 42 additions and 20 deletions

View File

@ -84,24 +84,28 @@ class ComicPressTagBuilder {
}
}
const START_PARSE = 'start parse';
const HAS_POST_METHOD = 'has post method';
const HAS_EXTRACT_METHOD = 'has extract method';
public function parse_method($method_name) {
$methods = array();
$parts = explode('_', $method_name);
$state = self::START_PARSE;
$post_method = null;
$extract_method = null;
while (!empty($parts)) {
$current = strtolower(array_shift($parts));
if (is_null($post_method)) {
if (in_array($current, array('first', 'previous', 'next', 'last'))) {
$post_method = $current;
} else {
break;
}
} else {
if (in_array($state, array(self::HAS_POST_METHOD, self::HAS_EXTRACT_METHOD))) {
if ($current == "in") {
if (empty($parts)) {
throw new ComicPressException("No category specified in tag ${method_name}");
}
$is_id = false;
if (count($parts) == 1) {
if (is_numeric($parts[0])) {
@ -112,12 +116,32 @@ class ComicPressTagBuilder {
if (!$is_id) {
$methods[] = array('in', implode('-', $parts));
}
break;
}
if (in_array($current, array('id', 'permalink', 'title', 'timestamp', 'date'))) {
if ($state == self::HAS_EXTRACT_METHOD) {
throw new ComicPressException('Only one extract method can be specified');
}
$extract_method = $current;
$state = self::HAS_EXTRACT_METHOD;
}
}
if ($state == self::START_PARSE) {
if (in_array($current, array('first', 'previous', 'next', 'last'))) {
$post_method = $current;
$state = self::HAS_POST_METHOD;
} else {
throw new ComicPressException("${current} isn't allowed at this point");
}
}
}
if (!is_null($post_method)) {
$methods[] = array($post_method);
foreach (array('post', 'extract') as $prefix) {
if (!is_null(${"${prefix}_method"})) {
$methods[] = array(${"${prefix}_method"});
}
}
return $methods;

View File

@ -198,7 +198,15 @@ class ComicPressTagBuilderTest extends PHPUnit_Framework_TestCase {
array('in', 'category-1'),
array('first')
)
)
),
array(
'first_permalink_in_category_1',
array(
array('in', 'category-1'),
array('first'),
array('permalink'),
)
),
);
}
@ -206,16 +214,6 @@ class ComicPressTagBuilderTest extends PHPUnit_Framework_TestCase {
* @dataProvider providerTestMethodParser
*/
function testMethodParser($method_name, $expected_pieces) {
foreach (array(
1 => array('cat_name' => 'Test 1', 'category_nicename' => 'category-1', 'category_parent' => 0),
2 => array('cat_name' => 'Test 2', 'category_nicename' => 'category-2', 'category_parent' => 0),
3 => array('cat_name' => 'Test 3', 'category_nicename' => 'category-3', 'category_parent' => 2),
4 => array('cat_name' => 'Test 4', 'category_nicename' => 'category-4', 'category_parent' => 2),
5 => array('cat_name' => 'Test 5', 'category_nicename' => 'category-5', 'category_parent' => 0),
) as $id => $category) {
add_category($id, (object)$category);
}
$this->assertEquals($expected_pieces, ComicPressTagBuilder::parse_method($method_name));
}
}