Skip to content

Commit

Permalink
feature #278 [Core] Add support for unbound values in StringInput (ss…
Browse files Browse the repository at this point in the history
…tok)

This PR was merged into the 2.0-dev branch.

Discussion
----------

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | Closes #230 
| License       | MIT

Aka "search anything", if no field name is specified this uses the default configured field.

Additionally we might add support for a default operator (or type in our case) in the future.
Secondly only StringInput has support for this now.

Commits
-------

52d8acf [Core] Add support for unbound values in StringInput
  • Loading branch information
sstok committed May 27, 2020
2 parents f796b5a + 52d8acf commit c62d733
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 5 deletions.
18 changes: 18 additions & 0 deletions lib/Core/Input/ProcessorConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Rollerworks\Component\Search\Input;

use Rollerworks\Component\Search\Exception\InputProcessorException;
use Rollerworks\Component\Search\FieldSet;

/**
Expand Down Expand Up @@ -47,6 +48,9 @@ class ProcessorConfig
*/
private $cacheTTL;

/** @var string|null */
private $defaultField;

public function __construct(FieldSet $fieldSet)
{
$this->fieldSet = $fieldSet;
Expand Down Expand Up @@ -127,4 +131,18 @@ public function getCacheTTL()
{
return $this->cacheTTL;
}

public function getDefaultField(bool $error = false): ?string
{
if ($this->defaultField === null && $error) {
throw new InputProcessorException('', 'No default field was configured.');
}

return $this->defaultField;
}

public function setDefaultField(string $defaultField): void
{
$this->defaultField = $defaultField;
}
}
13 changes: 10 additions & 3 deletions lib/Core/Input/StringInput.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@
* Caution: The error message reports the character position not the byte position.
* Multi byte may cause some problems when using substr() rather then mb_substr().
*
* Each query-pair is a 'field-name: value1, value2;'.
* Each query-pair is a 'field-name: value1, value2;' or 'value1, value2;'.
*
* Tip: The field-name can be omitted, which uses the default field-name configured
* in the ProcessorConfig. This should only be used for the first values list.
*
* Query-pairs can be nested inside a group "(field-name: value1, value2;)"
* Subgroups are threaded as AND-case to there parent,
Expand All @@ -53,7 +56,7 @@
*
* Each value inside a query-pair is separated with a single comma.
* A value containing special characters (<>[](),;~!*?=) or spaces
* must be surrounded by quotes.
* must be surrounded by quotes or use a custom value lexer.
*
* Note surrounding spaces are ignored. Example: field: value , value2 ;
*
Expand Down Expand Up @@ -268,7 +271,11 @@ private function fieldValuesPairs(bool $inGroup = false): void
throw $this->lexer->createFormatException(StringLexerException::CANNOT_CLOSE_UNOPENED_GROUP);
}

$fieldName = $this->getFieldName($this->lexer->fieldIdentification());
if ($this->lexer->isGlimpse(StringLexer::FIELD_NAME)) {
$fieldName = $this->getFieldName($this->lexer->fieldIdentification());
} else {
$fieldName = $this->config->getDefaultField(true);
}

$this->lexer->skipEmptyLines();
$this->fieldValues($fieldName);
Expand Down
2 changes: 1 addition & 1 deletion lib/Core/Input/StringLexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/
final class StringLexer
{
private const FIELD_NAME = '/@?_?(\p{L}[\p{L}\p{N}_-]*)\s*:/Au';
public const FIELD_NAME = '/@?_?(\p{L}[\p{L}\p{N}_-]*)\s*:/Au';

public const PATTERN_MATCH = 'pattern-match';
public const SIMPLE_VALUE = 'simple-value';
Expand Down
8 changes: 8 additions & 0 deletions lib/Core/Tests/Input/InputProcessorTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public function it_processes_values($input, array $order = [])
{
$processor = $this->getProcessor();
$config = new ProcessorConfig($this->getFieldSet(true, true));
$config->setDefaultField('id');

$expectedGroup = new ValuesGroup();

Expand Down Expand Up @@ -156,6 +157,7 @@ public function it_processes_multiple_fields($input)
{
$processor = $this->getProcessor();
$config = new ProcessorConfig($this->getFieldSet());
$config->setDefaultField('name');

$expectedGroup = new ValuesGroup();

Expand Down Expand Up @@ -189,6 +191,7 @@ public function it_processes_range_values($input)
{
$processor = $this->getProcessor();
$config = new ProcessorConfig($this->getFieldSet());
$config->setDefaultField('id');

$expectedGroup = new ValuesGroup();

Expand Down Expand Up @@ -226,6 +229,7 @@ public function it_processes_comparisons($input)
{
$processor = $this->getProcessor();
$config = new ProcessorConfig($this->getFieldSet());
$config->setDefaultField('id');

$expectedGroup = new ValuesGroup();

Expand Down Expand Up @@ -296,6 +300,7 @@ public function it_processes_groups($input)
{
$processor = $this->getProcessor();
$config = new ProcessorConfig($this->getFieldSet());
$config->setDefaultField('name');

$expectedGroup = new ValuesGroup();

Expand Down Expand Up @@ -339,6 +344,7 @@ public function it_processes_root_logical($input, string $logical = ValuesGroup:
{
$processor = $this->getProcessor();
$config = new ProcessorConfig($this->getFieldSet());
$config->setDefaultField('name');

$expectedGroup = new ValuesGroup($logical);

Expand Down Expand Up @@ -366,6 +372,7 @@ public function it_processes_multiple_subgroups($input)
{
$processor = $this->getProcessor();
$config = new ProcessorConfig($this->getFieldSet());
$config->setDefaultField('name');

$expectedGroup = new ValuesGroup();

Expand Down Expand Up @@ -404,6 +411,7 @@ public function it_processes_nested_subgroups($input)
{
$processor = $this->getProcessor();
$config = new ProcessorConfig($this->getFieldSet());
$config->setDefaultField('name');

$expectedGroup = new ValuesGroup();
$nestedGroup = new ValuesGroup();
Expand Down
25 changes: 24 additions & 1 deletion lib/Core/Tests/Input/StringQueryInputTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Rollerworks\Component\Search\Tests\Input;

use Rollerworks\Component\Search\ConditionErrorMessage;
use Rollerworks\Component\Search\Exception\InputProcessorException;
use Rollerworks\Component\Search\Exception\StringLexerException;
use Rollerworks\Component\Search\Exception\UnexpectedTypeException;
use Rollerworks\Component\Search\Extension\Core\Type\TextType;
Expand Down Expand Up @@ -103,6 +104,7 @@ public function it_processes_aliased_fields($input)

$processor = $this->getProcessor($labelResolver);
$config = new ProcessorConfig($this->getFieldSet());
$config->setDefaultField('name');

$expectedGroup = new ValuesGroup();

Expand All @@ -112,7 +114,8 @@ public function it_processes_aliased_fields($input)
$expectedGroup->addField('name', $values);

$condition = new SearchCondition($config->getFieldSet(), $expectedGroup);
self::assertEquals($condition, $processor->process($config, $input));

$this->assertConditionEquals($input, $condition, $processor, $config);
}

/**
Expand Down Expand Up @@ -184,6 +187,17 @@ public function testPatternMatchLexerNoEndLessLoop()
$this->assertConditionContainsErrors('name: ~!!*"value";', $config, [$error]);
}

/** @test */
public function it_fails_with_unbound_values_and_no_default_field()
{
$config = new ProcessorConfig($this->getFieldSet());

$e = new InputProcessorException('', 'No default field was configured.');
$error = $e->toErrorMessageObj();

$this->assertConditionContainsErrors('value;', $config, [$error]);
}

/**
* @test
*/
Expand Down Expand Up @@ -328,20 +342,23 @@ public function provideMultipleValues()
return [
['name: value, value2; date: "12-16-2014";'],
['name: value, value2; date: "12-16-2014"'],
['value1; date: "12-16-2014"; value, value2'], // Possible, but not recommended
];
}

public function provideRangeValues()
{
return [
['id: 1~10, 15 ~ 30, ] 100~200 ], 310~400[, !50~70; date: [12-16-2014 ~ 12-20-2014];'],
['1~10, 15 ~ 30, ] 100~200 ], 310~400[, !50~70; date: [12-16-2014 ~ 12-20-2014];'],
];
}

public function provideComparisonValues()
{
return [
['id: >1, <2, <=5, >=8, <>20; date: >="12-16-2014";'],
['>1, <2, <=5, >=8, <>20; date: >="12-16-2014";'],
];
}

Expand All @@ -358,21 +375,25 @@ public function provideGroupTests()
['name: value, value2; (name: value3, value4;); *(name: value8, value10;);'],
['name: value, value2; (name: value3, value4); *(name: value8, value10)'],
['name: value, value2; (name: value3, value4); *(name: value8, value10;)'],
['value, value2; (value3, value4); *(value8, value10;)'],
];
}

public function provideRootLogicalTests()
{
return [
['name: value, value2;'],
['value, value2;'],
['*name: value, value2;', ValuesGroup::GROUP_LOGICAL_OR],
['*value, value2;', ValuesGroup::GROUP_LOGICAL_OR],
];
}

public function provideMultipleSubGroupTests()
{
return [
['(name: value, value2); (name: value3, "value4");'],
['(name: value, value2); (value3, "value4");'],
];
}

Expand All @@ -383,6 +404,7 @@ public function provideNestedGroupTests()
['((name: value, value2;);)'],
['((name: value, value2;))'],
['((name: value, value2))'],
['((value, value2))'],
];
}

Expand All @@ -391,6 +413,7 @@ public function provideAliasedFieldsTests()
return [
['first-name: value1; first-name: value, value2;'],
['first-name: value, value2;'],
['value, value2;'],
];
}

Expand Down

0 comments on commit c62d733

Please sign in to comment.