1
require File.dirname(__FILE__) + "/../../test_helper"
3
class QueryParserTest < Test::Unit::TestCase
4
include Ferret::Analysis
7
parser = Ferret::QueryParser.new(:default_field => "xxx",
8
:fields => ["xxx", "field", "f1", "f2"],
9
:tokenized_fields => ["xxx", "f1", "f2"])
12
['*:word', 'word field:word f1:word f2:word'],
14
['field:word', 'field:word'],
15
['"word1 word2 word#"', '"word1 word2 word"'],
16
['"word1 %%% word3"', '"word1 <> word3"~1'],
17
['field:"one two three"', 'field:"one two three"'],
18
['field:"one %%% three"', 'field:"one %%% three"'],
19
['f1:"one %%% three"', 'f1:"one <> three"~1'],
20
['field:"one <> three"', 'field:"one <> three"'],
21
['field:"one <> three <>"', 'field:"one <> three"'],
22
['field:"one <> <> <> three <>"', 'field:"one <> <> <> three"'],
23
['field:"one <> 222 <> three|four|five <>"', 'field:"one <> 222 <> three|four|five"'],
24
['field:"on1|tw2 THREE|four|five six|seven"', 'field:"on1|tw2 THREE|four|five six|seven"'],
25
['field:"testing|trucks"', 'field:"testing|trucks"'],
26
['[aaa bbb]', '[aaa bbb]'],
27
['{aaa bbb]', '{aaa bbb]'],
28
['field:[aaa bbb}', 'field:[aaa bbb}'],
29
['{aaa bbb}', '{aaa bbb}'],
32
['field:<a\ aa}', 'field:<a aa}'],
38
['field:<=aaa', 'field:<aaa]'],
39
['REQ one REQ two', '+one +two'],
40
['REQ one two', '+one two'],
41
['one REQ two', 'one +two'],
42
['+one +two', '+one +two'],
43
['+one two', '+one two'],
44
['one +two', 'one +two'],
45
['-one -two', '-one -two'],
46
['-one two', '-one two'],
47
['one -two', 'one -two'],
48
['!one !two', '-one -two'],
49
['!one two', '-one two'],
50
['one !two', 'one -two'],
51
['NOT one NOT two', '-one -two'],
52
['NOT one two', '-one two'],
53
['one NOT two', 'one -two'],
54
['NOT two', '-two +*'],
55
['one two', 'one two'],
56
['one OR two', 'one two'],
57
['one AND two', '+one +two'],
58
['one two AND three', 'one two +three'],
59
['one two OR three', 'one two three'],
60
['one (two AND three)', 'one (+two +three)'],
61
['one AND (two OR three)', '+one +(two three)'],
62
['field:(one AND (two OR three))', '+field:one +(field:two field:three)'],
63
['one AND (two OR [aaa vvv})', '+one +(two [aaa vvv})'],
64
['one AND (f1:two OR f2:three) AND four', '+one +(f1:two f2:three) +four'],
65
['one^1.23', 'one^1.23'],
66
['(one AND two)^100.23', '(+one +two)^100.23'],
67
['field:(one AND two)^100.23', '(+field:one +field:two)^100.23'],
68
['field:(one AND [aaa bbb]^23.3)^100.23', '(+field:one +field:[aaa bbb]^23.3)^100.23'],
69
['(REQ field:"one two three")^23', 'field:"one two three"^23.0'],
70
['asdf~0.2', 'asdf~0.2'],
71
['field:asdf~0.2', 'field:asdf~0.2'],
72
['asdf~0.2^100.0', 'asdf~0.2^100.0'],
73
['field:asdf~0.2^0.1', 'field:asdf~0.2^0.1'],
74
['field:"asdf <> asdf|asdf"~4', 'field:"asdf <> asdf|asdf"~4'],
75
['"one two three four five"~5', '"one two three four five"~5'],
78
['asdf?*?asd*dsf?asfd*asdf?', 'asdf?*?asd*dsf?asfd*asdf?'],
79
['field:a* AND field:(b*)', '+field:a* +field:b*'],
80
['field:abc~ AND field:(b*)', '+field:abc~ +field:b*'],
81
['asdf?*?asd*dsf?asfd*asdf?^20.0', 'asdf?*?asd*dsf?asfd*asdf?^20.0'],
83
['*:xxx', 'xxx field:xxx f1:xxx f2:xxx'],
84
['f1|f2:xxx', 'f1:xxx f2:xxx'],
86
['*:asd~0.2', 'asd~0.2 field:asd~0.2 f1:asd~0.2 f2:asd~0.2'],
87
['f1|f2:asd~0.2', 'f1:asd~0.2 f2:asd~0.2'],
89
['*:a?d*^20.0', '(a?d* field:a?d* f1:a?d* f2:a?d*)^20.0'],
90
['f1|f2:a?d*^20.0', '(f1:a?d* f2:a?d*)^20.0'],
92
['*:"asdf <> xxx|yyy"', '"asdf <> xxx|yyy" field:"asdf <> xxx|yyy" f1:"asdf <> xxx|yyy" f2:"asdf <> xxx|yyy"'],
93
['f1|f2:"asdf <> xxx|yyy"', 'f1:"asdf <> xxx|yyy" f2:"asdf <> xxx|yyy"'],
94
['f1|f2:"asdf <> do|yyy"', 'f1:"asdf <> yyy" f2:"asdf <> yyy"'],
95
['f1|f2:"do|cat"', 'f1:cat f2:cat'],
97
['*:[bbb xxx]', '[bbb xxx] field:[bbb xxx] f1:[bbb xxx] f2:[bbb xxx]'],
98
['f1|f2:[bbb xxx]', 'f1:[bbb xxx] f2:[bbb xxx]'],
100
['*:(xxx AND bbb)', '+(xxx field:xxx f1:xxx f2:xxx) +(bbb field:bbb f1:bbb f2:bbb)'],
101
['f1|f2:(xxx AND bbb)', '+(f1:xxx f2:xxx) +(f1:bbb f2:bbb)'],
102
['asdf?*?asd*dsf?asfd*asdf?^20.0', 'asdf?*?asd*dsf?asfd*asdf?^20.0'],
103
['"onewordphrase"', 'onewordphrase'],
107
pairs.each do |query_str, expected|
108
assert_equal(expected, parser.parse(query_str).to_s("xxx"))
112
def test_qp_with_standard_analyzer()
113
parser = Ferret::QueryParser.new(:default_field => "xxx",
114
:fields => ["xxx", "key"],
115
:analyzer => StandardAnalyzer.new)
117
['key:1234', 'key:1234'],
118
['key:(1234 and Dave)', 'key:1234 key:dave'],
119
['key:(1234)', 'key:1234'],
120
['and the but they with', '']
123
pairs.each do |query_str, expected|
124
assert_equal(expected, parser.parse(query_str).to_s("xxx"))
129
def test_qp_changing_fields()
130
parser = Ferret::QueryParser.new(:default_field => "xxx",
131
:fields => ["xxx", "key"],
132
:analyzer => WhiteSpaceAnalyzer.new)
133
assert_equal('word key:word', parser.parse("*:word").to_s("xxx"))
135
parser.fields = ["xxx", "one", "two", "three"]
136
assert_equal('word one:word two:word three:word',
137
parser.parse("*:word").to_s("xxx"))
138
assert_equal('three:word four:word',
139
parser.parse("three:word four:word").to_s("xxx"))
142
def test_qp_allow_any_field()
143
parser = Ferret::QueryParser.new(:default_field => "xxx",
144
:fields => ["xxx", "key"],
145
:analyzer => WhiteSpaceAnalyzer.new,
146
:validate_fields => true)
148
assert_equal('key:word',
149
parser.parse("key:word song:word").to_s("xxx"))
150
assert_equal('word key:word', parser.parse("*:word").to_s("xxx"))
153
parser = Ferret::QueryParser.new(:default_field => "xxx",
154
:fields => ["xxx", "key"],
155
:analyzer => WhiteSpaceAnalyzer.new)
157
assert_equal('key:word song:word',
158
parser.parse("key:word song:word").to_s("xxx"))
159
assert_equal('word key:word', parser.parse("*:word").to_s("xxx"))
162
def do_test_query_parse_exception_raised(str)
163
parser = Ferret::QueryParser.new(:default_field => "xxx",
164
:fields => ["f1", "f2", "f3"],
165
:handle_parse_errors => false)
166
assert_raise(Ferret::QueryParser::QueryParseException,
167
str + " should have failed") do
173
parser = Ferret::QueryParser.new(:default_field => :*,
175
:or_default => false,
176
:analyzer => StandardAnalyzer.new)
178
['word', 'x:word y:word'],
179
['word1 word2', '+(x:word1 y:word1) +(x:word2 y:word2)']
182
pairs.each do |query_str, expected|
183
assert_equal(expected, parser.parse(query_str).to_s(""))
187
def test_prefix_query
188
parser = Ferret::QueryParser.new(:default_field => "xxx",
190
:analyzer => StandardAnalyzer.new)
191
assert_equal(Ferret::Search::PrefixQuery, parser.parse("asdg*").class)
192
assert_equal(Ferret::Search::WildcardQuery, parser.parse("a?dg*").class)
193
assert_equal(Ferret::Search::WildcardQuery, parser.parse("a*dg*").class)
194
assert_equal(Ferret::Search::WildcardQuery, parser.parse("adg*c").class)
198
parser = Ferret::QueryParser.new(:default_field => "xxx",
199
:fields => ["f1", "f2"])
204
['::*&one)(*two(*&"', '"one two"~1'],
216
['<script>', 'script']
219
pairs.each do |query_str, expected|
220
do_test_query_parse_exception_raised(query_str)
221
assert_equal(expected, parser.parse(query_str).to_s("xxx"))
225
def test_use_keywords_switch
226
analyzer = LetterAnalyzer.new
227
parser = Ferret::QueryParser.new(:analyzer => analyzer,
228
:default_field => "xxx")
229
assert_equal("+www (+xxx +yyy) -zzz",
230
parser.parse("REQ www (xxx AND yyy) OR NOT zzz").to_s("xxx"))
232
parser = Ferret::QueryParser.new(:analyzer => analyzer,
233
:default_field => "xxx",
234
:use_keywords => false)
235
assert_equal("req www (xxx and yyy) or not zzz",
236
parser.parse("REQ www (xxx AND yyy) OR NOT zzz").to_s("xxx"))