diff options
-rw-r--r-- | app/Core/Lexer.php | 3 | ||||
-rw-r--r-- | app/Model/TaskFilter.php | 19 | ||||
-rw-r--r-- | docs/search.markdown | 7 | ||||
-rw-r--r-- | tests/units/LexerTest.php | 30 | ||||
-rw-r--r-- | tests/units/TaskFilterTest.php | 31 |
5 files changed, 90 insertions, 0 deletions
diff --git a/app/Core/Lexer.php b/app/Core/Lexer.php index d277f998..f6978bbd 100644 --- a/app/Core/Lexer.php +++ b/app/Core/Lexer.php @@ -33,6 +33,8 @@ class Lexer "/^(category:)/" => 'T_CATEGORY', "/^(column:)/" => 'T_COLUMN', "/^(project:)/" => 'T_PROJECT', + "/^(ref:)/" => 'T_REFERENCE', + "/^(reference:)/" => 'T_REFERENCE', "/^(\s+)/" => 'T_WHITESPACE', '/^([<=>]{0,2}[0-9]{4}-[0-9]{2}-[0-9]{2})/' => 'T_DATE', '/^(yesterday|tomorrow|today)/' => 'T_DATE', @@ -124,6 +126,7 @@ class Lexer case 'T_STATUS': case 'T_DUE': case 'T_DESCRIPTION': + case 'T_REFERENCE': $next = next($tokens); if ($next !== false && ($next['token'] === 'T_DATE' || $next['token'] === 'T_STRING')) { diff --git a/app/Model/TaskFilter.php b/app/Model/TaskFilter.php index e9d9ccbd..0bac3f46 100644 --- a/app/Model/TaskFilter.php +++ b/app/Model/TaskFilter.php @@ -68,6 +68,9 @@ class TaskFilter extends Base case 'T_COLUMN': $this->filterByColumnName($value); break; + case 'T_REFERENCE': + $this->filterByReference($value); + break; } } @@ -141,6 +144,22 @@ class TaskFilter extends Base } /** + * Filter by reference + * + * @access public + * @param string $reference + * @return TaskFilter + */ + public function filterByReference($reference) + { + if (! empty($reference)) { + $this->query->eq(Task::TABLE.'.reference', $reference); + } + + return $this; + } + + /** * Filter by title * * @access public diff --git a/docs/search.markdown b/docs/search.markdown index 1d254b29..99b76393 100644 --- a/docs/search.markdown +++ b/docs/search.markdown @@ -144,3 +144,10 @@ Attribute: **column** - Find tasks by column name: `column:"Work in progress"` - Find tasks for several columns: `column:"Backlog" column:ready` + +Search by external reference +---------------------------- + +The task reference is an external id of your task, by example a ticket number from another software. + +- Find tasks with a reference: `ref:1234` or `reference:TICKET-1234` diff --git a/tests/units/LexerTest.php b/tests/units/LexerTest.php index 38974357..0e3a61ae 100644 --- a/tests/units/LexerTest.php +++ b/tests/units/LexerTest.php @@ -171,6 +171,36 @@ class LexerTest extends Base ); } + public function testReferenceQuery() + { + $lexer = new Lexer; + + $this->assertEquals( + array(array('match' => 'ref:', 'token' => 'T_REFERENCE'), array('match' => '123', 'token' => 'T_STRING')), + $lexer->tokenize('ref:123') + ); + + $this->assertEquals( + array(array('match' => 'reference:', 'token' => 'T_REFERENCE'), array('match' => '456', 'token' => 'T_STRING')), + $lexer->tokenize('reference:456') + ); + + $this->assertEquals( + array('T_REFERENCE' => '123'), + $lexer->map($lexer->tokenize('reference:123')) + ); + + $this->assertEquals( + array('T_REFERENCE' => '456'), + $lexer->map($lexer->tokenize('ref:456')) + ); + + $this->assertEquals( + array(), + $lexer->map($lexer->tokenize('ref: ')) + ); + } + public function testDescriptionQuery() { $lexer = new Lexer; diff --git a/tests/units/TaskFilterTest.php b/tests/units/TaskFilterTest.php index c68e8880..6a48f194 100644 --- a/tests/units/TaskFilterTest.php +++ b/tests/units/TaskFilterTest.php @@ -27,6 +27,37 @@ class TaskFilterTest extends Base $this->assertEmpty($tf->search('search something')->findAll()); } + public function testSearchWithReference() + { + $p = new Project($this->container); + $tc = new TaskCreation($this->container); + $tf = new TaskFilter($this->container); + + $this->assertEquals(1, $p->create(array('name' => 'test'))); + $this->assertNotFalse($tc->create(array('project_id' => 1, 'title' => 'task1'))); + $this->assertNotFalse($tc->create(array('project_id' => 1, 'title' => 'task2', 'reference' => 123))); + + $tf->search('ref:123'); + $tasks = $tf->findAll(); + $this->assertNotEmpty($tasks); + $this->assertCount(1, $tasks); + $this->assertEquals('task2', $tasks[0]['title']); + + $tf->search('reference:123'); + $tasks = $tf->findAll(); + $this->assertNotEmpty($tasks); + $this->assertCount(1, $tasks); + $this->assertEquals('task2', $tasks[0]['title']); + + $tf->search('ref:plop'); + $tasks = $tf->findAll(); + $this->assertEmpty($tasks); + + $tf->search('ref:'); + $tasks = $tf->findAll(); + $this->assertEmpty($tasks); + } + public function testSearchWithStatus() { $p = new Project($this->container); |