这是测试优先驱动方法如何帮助您获得解决方案的绝佳示例。它可能并不是最好的,但是通过编写测试,您可以自信地重构,并立即查看是否打破了任何现有的测试。无论如何,你可以建立像一些测试:
public function setUp() {
$this->searchParser = new App_Search_Parser();
}
public function testSingleWordParsesToAllWords() {
$this->searchParser->parse('Transport');
$this->assertEquals(
$this->searchParser->getAllWords(),
array('Transport')
);
$this->assertEquals($this->searchParser->getNotWords(), array());
$this->assertEquals($this->searchParser->getAnyWords());
}
public function testParseOfCombinedSearchString() {
$query = 'energy food "olympics 2010" Terrorism ' .
'OR "government" OR cups NOT transport';
$this->searchParser->parse($query);
$this->assertEquals(
$this->searchParser->getAllWords(),
array('energy', 'food', 'olympics 2010')
);
$this->assertEquals(
$this->searchParser->getNotWords(),
array('Transport')
);
$this->assertEquals(
$this->searchParser->getAnyWords(),
array('terrorism', 'government', 'cups')
);
}
其他好的测试将包括:
testParseTwoWords
testParseTwoWordsWithOr
testParseSimpleWithNot
testParseInvalid
- 这里哟你必须确定什么是无效的输入以及你如何解释它,即:
- 'NOT Transport':搜索任何不包含Transport或者通知用户他还必须包含至少一个搜索词的东西?
- 'OR energy':可以用combinator开头吗?
- '食物或非能量':这是否意味着“寻找食物或任何不含能量的食物”,或者它是指“寻找食物而不是能量”,或者这不代表什么意思? (即抛出异常,返回false或诸如此类的东西)
testParseEmpty
然后,写测试一个接一个,并编写通过测试的简单解决方案。然后重构并做出正确的决定,然后再次运行,看看你是否仍然通过测试。 一旦测试通过并且代码被重构,然后编写下一个测试并重复该过程。当您发现特殊情况并重构代码以使其通过所有测试时添加更多测试。如果您打破测试,请备份并重新编写代码(不是测试!),以使其通过。
至于如何解决这个问题,可以看看preg_match,strtok,或者简单地循环访问字符串,并添加令牌。
嗨Jens,\ b(\ w + |“[^”] +“)\ b解析输入似乎是一个很好的解决方案,因为正则表达式的限制,然后我可以使用for循环来看看后面或之后数组桶以查看是否存在NOT或OR并相应地执行操作。 – 2010-03-23 11:31:34