1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
<?php
namespace Micropoly\Search;
use PHPUnit\Framework\TestCase;
class ParserTest extends TestCase
{
/**
* @covers \Micropoly\Search\Parser::tokenize
* @dataProvider tokenizeDataProvider
*/
public function testTokenize($input, $want)
{
$have = [];
foreach (Parser::tokenize($input) as $tok)
$have[] = $tok;
$this->assertSame($want, $have);
}
public function tokenizeDataProvider()
{
return [
["", []],
["hello", [
[Parser::TOK_WORD, "hello"],
]],
["hello world", [
[Parser::TOK_WORD, "hello"],
[Parser::TOK_WORD, "world"],
]],
['"hello world"', [
[Parser::TOK_WORD, "hello world"],
]],
['"hello\\"quote\\\\"', [
[Parser::TOK_WORD , 'hello"quote\\'],
]],
["foo\\ bar", [
[Parser::TOK_WORD, "foo bar"],
]],
['foo\\\\bar\\"baz', [
[Parser::TOK_WORD, 'foo\\bar"baz'],
]],
['foo\\', [
[Parser::TOK_WORD, 'foo\\'],
]],
["#foo #bar", [
[Parser::TOK_TAG, "foo"],
[Parser::TOK_TAG, "bar"],
]],
["#foo\\ bar", [
[Parser::TOK_TAG, "foo bar"],
]],
["and or not ()( )", [
[Parser::TOK_OP, "and"],
[Parser::TOK_OP, "or"],
[Parser::TOK_OP, "not"],
[Parser::TOK_PAROPEN, null],
[Parser::TOK_PARCLOSE, null],
[Parser::TOK_PAROPEN, null],
[Parser::TOK_PARCLOSE, null],
]],
["(#foo)", [
[Parser::TOK_PAROPEN, null],
[Parser::TOK_TAG, "foo"],
[Parser::TOK_PARCLOSE, null],
]],
["foo:bar", [
[Parser::TOK_PROP, "foo"],
[Parser::TOK_WORD, "bar"],
]],
];
}
public function testTokenizeFailUnclosedString()
{
$this->expectException(ParseError::class);
foreach (Parser::tokenize('foo "bar') as $_);
}
/**
* @param string $input
* @param bool|null|SearchExpr $exprOrFalseForErr
* @dataProvider parseDataProvider
*/
public function testParse(string $input, $exprOrFalseForErr)
{
if ($exprOrFalseForErr === false)
$this->expectException(ParseError::class);
$have = Parser::parse($input);
if ($have !== null)
$have = $have->toString();
$want = $exprOrFalseForErr === null ? null : $exprOrFalseForErr->toString();
$this->assertSame($want, $have);
}
public function parseDataProvider()
{
return [
["", null],
["(", false],
[")", false],
["foo", new FTSExpr("foo")],
["foo #bar", new LogicOp(LogicOp::OP_AND, new FTSExpr("foo"), new TagExpr("bar"))],
["(foo and #bar) or not baz", new LogicOp(
LogicOp::OP_OR, new LogicOp(
LogicOp::OP_AND,
new FTSExpr("foo"),
new TagExpr("bar")
), new NotOp(new FTSExpr("baz"))
)],
["foo bar", new FTSLogicOp(LogicOp::OP_AND, new FTSExpr("foo"), new FTSExpr("bar"))],
];
}
}
|