1# Copyright(C) 2006 Brazil
2#     All rights reserved.
3#     This is free software with ABSOLUTELY NO WARRANTY.
4#
5# You can redistribute it and/or modify it under the terms of
6# the GNU General Public License version 2.
7require 'test/unit'
8require 'senna'
9require 'test_tools'
10
11$KCODE = 'e'
12
13class IndexAdvancedTest < Test::Unit::TestCase
14  def test_create_with_keys
15    sym = Senna::Sym::create('ext_key')
16    symid = sym.get('key1')
17    index = sym.index_create_with_keys('create_with_keys')
18    assert_equal('create_with_keys', index.path)
19    assert_equal(symid, index.keys.get('key1'))
20    index.remove
21    sym.remove
22  end
23
24  def test_open_with_keys
25    index = Senna::Index.create('open_with_keys')
26    index.upd('key2', nil, 'test')
27    index.close
28    sym = Senna::Sym::create('ext_key')
29    sym.get('key1')
30    symid = sym.get('key2')
31    index = sym.index_open_with_keys('open_with_keys')
32    assert_equal('open_with_keys', index.path)
33    assert_equal(symid, index.keys.get('key2'))               # check whether keys is replaced
34    index.remove
35    sym.remove
36  end
37
38  def test_update
39    index = TestIndex::create(0, Senna::INDEX_DELIMITED)
40    index.update('key1', 1, nil, 'test')
41    assert_equal(1, index.select('test').nhits)
42
43    index.update('key1', 1, 'test', 'changed')
44    assert_equal(1, index.select('changed').nhits)
45  end
46
47  def test_update_multisection
48    index = TestIndex::create(0, Senna::INDEX_DELIMITED)
49    index.update('key1', 1, nil, 'test')
50    index.update('key1', 2, nil, 'document')
51    index.update('key2', 1, nil, 'document')
52    index.update('key3', 3, nil, 'other')
53
54    assert_equal(1, index.select('test').nhits)
55    assert_equal(2, index.select('document').nhits)
56    assert_equal(1, index.select('other').nhits)              # check for isolated section
57    assert_equal(0, index.select('nohit').nhits)
58
59    index.update('key3', 3, 'other', 'changed')
60    assert_equal(1, index.select('changed').nhits)
61  end
62
63  def test_update_multivalue
64    index = TestIndex::create(0, Senna::INDEX_DELIMITED)
65    vals = Senna::Values::open('test', 1)
66    vals.add('document', 2)
67    index.update('key1', 1, nil, vals)
68    vals = Senna::Values::open('document', 1)
69    vals.add('test', 2)
70    index.update('key2', 1, nil, vals)
71
72    rcs = index.select('test')
73    assert(rcs.find('key1') < rcs.find('key2'))
74    rcs = index.select('document')
75    assert(rcs.find('key1') > rcs.find('key2'))
76
77    vals2 = Senna::Values::open('changed', 1)
78    vals2.add('document', 2)
79    index.update('key2', 1, vals, vals2)
80    assert_equal(1, index.select('changed').nhits)
81    rcs = index.select('document')
82    assert_equal(rcs.find('key1'), rcs.find('key2'))
83  end
84
85  def test_update_multisection_multivalue
86    index = TestIndex::create(0, Senna::INDEX_DELIMITED)
87    vals = Senna::Values::open('test', 1)
88    vals.add('document', 2)
89    index.update('key1', 1, nil, vals)
90    vals = Senna::Values::open('is', 3)
91    vals.add('here', 4)
92    index.update('key1', 2, nil, vals)
93
94    vals = Senna::Values::open('here', 2)
95    vals.add('is', 4)
96    index.update('key2', 1, nil, vals)
97    vals = Senna::Values::open('document', 1)
98    vals.add('of test', 3)
99    index.update('key2', 2, nil, vals)
100
101    rcs = index.select('test')
102    assert_equal(2, rcs.nhits)
103    assert(rcs.find('key1') < rcs.find('key2'))
104
105    rcs = index.select('here')
106    assert_equal(2, rcs.nhits)
107    assert(rcs.find('key1') > rcs.find('key2'))
108
109    rcs = index.select('of')
110    assert_equal(1, rcs.nhits)
111
112    assert_equal(0, index.select('nohit').nhits)
113
114    vals2 = Senna::Values::open('changed', 1)
115    vals2.add('document', 2)
116
117    index.update('key2', 2, vals, vals2)
118
119    assert_equal(1, index.select('changed').nhits)
120
121    rcs = index.select('document')
122    assert_equal(rcs.find('key1'), rcs.find('key2'))
123  end
124
125  def test_select
126    index = TestIndex::create(0, Senna::INDEX_DELIMITED)
127    index.update('a', 1, nil, 'a')
128    index.update('b', 1, nil, 'b')
129    index.update('a&b', 1, nil, 'a b')
130    index.update('c', 1, nil, 'c')
131
132    assert_equal(2, index.select('a').nhits)
133    assert_equal(2, index.select('b').nhits)
134    assert_equal(1, index.select('a b').nhits)
135
136    # a or b
137    rcs = index.select('a')
138    index.select('b', rcs)
139
140    assert_equal(3, rcs.nhits)
141    assert_equal(0, rcs.find('c'))
142
143    # b and a
144    rcs = index.select('b')
145    index.select('a', rcs, Senna::SEL_AND)
146
147    assert_equal(1, rcs.nhits)
148    assert_not_equal(0, rcs.find('a&b'))
149
150    # (b or a) \ b
151    rcs = index.select('b')
152    index.select('a', rcs)
153    index.select('b', rcs, Senna::SEL_BUT)
154
155    assert_equal(1, rcs.nhits)
156    assert_not_equal(0, rcs.find('a'))
157
158    # adjust
159    rcs = index.select('a')
160    scoreuni = rcs.find('a')
161    scoreand = rcs.find('a&b')
162    index.select('b', rcs, Senna::SEL_ADJUST)
163
164    assert_equal(2, rcs.nhits)
165    assert_equal(scoreuni, rcs.find('a'))
166    assert(scoreand < rcs.find('a&b'))
167  end
168
169  def test_select_optarg_mode
170    index = TestIndex::create(0, Senna::INDEX_DELIMITED)
171    index.update('1', 1, nil, 'test document is here')
172
173    rcs = index.select('test', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_EXACT))
174    assert_equal(1, rcs.nhits)
175    rcs = index.select('tes', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_EXACT))
176    assert_equal(0, rcs.nhits)
177    # Now, Senna doesn't make an index which contains infomation for suffix search in english words.
178    rcs = index.select('tes', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_PARTIAL))
179    assert_equal(1, rcs.nhits)
180    rcs = index.select('est doc', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_PARTIAL))
181    assert_equal(0, rcs.nhits)
182    rcs = index.select('test', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_UNSPLIT))
183    assert_equal(1, rcs.nhits)
184
185    rcs = index.select('test here', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_NEAR, 2))
186    assert_equal(1, rcs.nhits)
187    rcs = index.select('test here', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_NEAR, 1))
188    assert_equal(0, rcs.nhits)
189
190    # Note: This behavior will be changed in future
191    rcs = index.select('you must test here', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_SIMILAR, 2))
192    assert_equal(1, rcs.nhits)
193    rcs = index.select('test here now', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_SIMILAR, 1))
194    assert_equal(1, rcs.nhits)
195    rcs = index.select('test', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_TERM_EXTRACT, 1))
196    assert_equal(1, rcs.nhits)
197  end
198
199  def test_select_optarg_mode_ja
200    index = TestIndex::create
201    # �ƥ��� ʸ�� �� ���� �� ���� �ޤ�
202    index.update('1', 1, nil, '�ƥ���ʸ��Ϥ����ˤ���ޤ�')
203    rcs = index.select('�ƥ���', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_EXACT))
204    assert_equal(1, rcs.nhits)
205    rcs = index.select('�ƥ�', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_EXACT))
206    assert_equal(0, rcs.nhits)
207    # Now, Senna doesn't make an index which contains infomation for suffix search in english words.
208    rcs = index.select('�ƥ�', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_PARTIAL))
209    assert_equal(1, rcs.nhits)
210    rcs = index.select('����ʸ', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_PARTIAL))
211    assert_equal(1, rcs.nhits)
212    rcs = index.select('�ƥ���', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_UNSPLIT))
213    assert_equal(1, rcs.nhits)
214
215    rcs = index.select('�ƥ��� ����', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_NEAR, 2))
216    assert_equal(1, rcs.nhits)
217    rcs = index.select('�ƥ��� ����', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_NEAR, 1))
218    assert_equal(0, rcs.nhits)
219
220    # Note: This behavior will be changed in future
221    rcs = index.select('���줬�ƥ���ʸ��', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_SIMILAR, 2))
222    assert_equal(1, rcs.nhits)
223    rcs = index.select('�ƥ��ȤϤ�����', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_SIMILAR, 1))
224    assert_equal(1, rcs.nhits)
225  end
226
227  def test_select_optarg_vector_func
228    index = TestIndex::create(0, Senna::INDEX_DELIMITED)
229    index.update('1', 1, nil, 'test')
230    index.update('1', 2, nil, 'document')
231    index.update('2', 1, nil, 'document')
232    index.update('2', 2, nil, 'other')
233
234    # vector
235    assert_equal(0, index.select('test', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_EXACT, 0, [0, 1])).nhits)
236    assert_equal(1, index.select('document', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_EXACT, 0, [1, 0])).nhits)
237    score = index.select('test', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_EXACT, 0, [1, 0])).find('1')
238    assert(score < index.select('test', nil, Senna::SEL_OR, Senna::get_select_optarg(Senna::SEL_EXACT, 0, [2, 0])).find('1'))
239
240    # func
241    rcs = index.select('document', nil, Senna::SEL_OR,
242                       Senna::get_select_optarg(Senna::SEL_EXACT, 0, nil) {|r, docid, secno| return docid.to_i * 2 + secno - 1})
243    assert_equal(2, rcs.nhits)
244    assert_equal(3, rcs.find('1'))
245    assert_equal(4, rcs.find('2'))
246  end
247
248  # ToDo: Confirm specification, and write test.
249  def test_select_near_ngram_ja
250    assert(true);
251  end
252
253  def test_info
254    index = TestIndex::create(200, Senna::INDEX_DELIMITED | Senna::INDEX_NGRAM, 0, Senna::ENC_UTF8)
255    info = index.info
256    assert(info[0..4] === [0, 200, Senna::INDEX_DELIMITED | Senna::INDEX_NGRAM, 512, Senna::ENC_UTF8])
257    assert_equal(0, info[5])
258    assert_equal(0, info[7])
259    assert_equal(info[6], info[8])
260  end
261
262  def test_info_num_key_lex
263    index = TestIndex::create(0, Senna::INDEX_DELIMITED)
264
265    index.update('1', 1, nil, 'test')
266    info = index.info
267    assert_equal(1, info[5])
268    assert_equal(1, info[7])
269
270    index.update('1', 2, nil, 'document')
271    info = index.info
272    assert_equal(1, info[5])
273    assert_equal(2, info[7])
274
275    index.update('2', 1, nil, 'test document')
276    info = index.info
277    assert_equal(2, info[5])
278    assert_equal(2, info[7])
279
280    index.update('2', 1, 'test document', 'changed document')
281    info = index.info
282    assert_equal(2, info[5])
283    assert_equal(3, info[7])
284
285    index.update('2', 1, 'changed document', nil)
286    index = index.info
287    assert_equal(2, info[5])
288    assert_equal(3, info[7])
289  end
290
291  # This API will be implemented in future.
292  def test_related_term
293    assert(true)
294  end
295end
296
297