xref: /dokuwiki/_test/tests/Search/Collection/DirectCollectionTest.php (revision 21fbd01b3c3eea88b767376b7b158f31f0f63127)
1ede46466SAndreas Gohr<?php
2ede46466SAndreas Gohr
3ede46466SAndreas Gohrnamespace dokuwiki\test\Search\Collection;
4ede46466SAndreas Gohr
5ede46466SAndreas Gohruse dokuwiki\Search\Collection\PageTitleCollection;
6*21fbd01bSAndreas Gohruse dokuwiki\Search\Exception\IndexIntegrityException;
7ede46466SAndreas Gohruse dokuwiki\Search\Exception\IndexLockException;
8ede46466SAndreas Gohruse dokuwiki\Search\Index\MemoryIndex;
9ede46466SAndreas Gohr
10ede46466SAndreas Gohrclass DirectCollectionTest extends \DokuWikiTest
11ede46466SAndreas Gohr{
12ede46466SAndreas Gohr    /**
13ede46466SAndreas Gohr     * Add a token and verify it's stored at the entity's position
14ede46466SAndreas Gohr     */
15ede46466SAndreas Gohr    public function testAddEntity()
16ede46466SAndreas Gohr    {
17ede46466SAndreas Gohr        $index = new MockDirectCollection('a_entity', 'a_token');
18ede46466SAndreas Gohr        $index->lock();
19ede46466SAndreas Gohr        $index->addEntity('wiki:start', ['Welcome to DokuWiki']);
20ede46466SAndreas Gohr        $index->unlock();
21ede46466SAndreas Gohr
22ede46466SAndreas Gohr        $idxEntity = new MemoryIndex('a_entity');
23ede46466SAndreas Gohr        $this->assertEquals('wiki:start', $idxEntity->retrieveRow(0));
24ede46466SAndreas Gohr
25ede46466SAndreas Gohr        $idxToken = new MemoryIndex('a_token');
26ede46466SAndreas Gohr        $this->assertEquals('Welcome to DokuWiki', $idxToken->retrieveRow(0));
27ede46466SAndreas Gohr    }
28ede46466SAndreas Gohr
29ede46466SAndreas Gohr    /**
30ede46466SAndreas Gohr     * Updating an entity should overwrite the previous token
31ede46466SAndreas Gohr     */
32ede46466SAndreas Gohr    public function testUpdateEntity()
33ede46466SAndreas Gohr    {
34ede46466SAndreas Gohr        $index = new MockDirectCollection('b_entity', 'b_token');
35ede46466SAndreas Gohr
36ede46466SAndreas Gohr        $index->lock();
37ede46466SAndreas Gohr        $index->addEntity('wiki:start', ['Old Title']);
38ede46466SAndreas Gohr        $index->unlock();
39ede46466SAndreas Gohr
40ede46466SAndreas Gohr        $index->lock();
41ede46466SAndreas Gohr        $index->addEntity('wiki:start', ['New Title']);
42ede46466SAndreas Gohr        $index->unlock();
43ede46466SAndreas Gohr
44ede46466SAndreas Gohr        $idxToken = new MemoryIndex('b_token');
45ede46466SAndreas Gohr        $this->assertEquals('New Title', $idxToken->retrieveRow(0));
46ede46466SAndreas Gohr    }
47ede46466SAndreas Gohr
48ede46466SAndreas Gohr    /**
49ede46466SAndreas Gohr     * Empty token list should store empty string
50ede46466SAndreas Gohr     */
51ede46466SAndreas Gohr    public function testEmptyToken()
52ede46466SAndreas Gohr    {
53ede46466SAndreas Gohr        $index = new MockDirectCollection('c_entity', 'c_token');
54ede46466SAndreas Gohr        $index->lock();
55ede46466SAndreas Gohr        $index->addEntity('wiki:start', []);
56ede46466SAndreas Gohr        $index->unlock();
57ede46466SAndreas Gohr
58ede46466SAndreas Gohr        $idxToken = new MemoryIndex('c_token');
59ede46466SAndreas Gohr        $this->assertEquals('', $idxToken->retrieveRow(0));
60ede46466SAndreas Gohr    }
61ede46466SAndreas Gohr
62ede46466SAndreas Gohr    /**
63ede46466SAndreas Gohr     * getToken should return the stored value
64ede46466SAndreas Gohr     */
65ede46466SAndreas Gohr    public function testGetToken()
66ede46466SAndreas Gohr    {
67ede46466SAndreas Gohr        $index = new MockDirectCollection('d_entity', 'd_token');
68ede46466SAndreas Gohr        $index->lock();
69ede46466SAndreas Gohr        $index->addEntity('wiki:start', ['My Page Title']);
70ede46466SAndreas Gohr        $index->unlock();
71ede46466SAndreas Gohr
72ede46466SAndreas Gohr        $this->assertEquals('My Page Title', $index->getToken('wiki:start'));
73ede46466SAndreas Gohr    }
74ede46466SAndreas Gohr
75ede46466SAndreas Gohr    /**
76ede46466SAndreas Gohr     * Adding entity without lock should throw exception
77ede46466SAndreas Gohr     */
78ede46466SAndreas Gohr    public function testAddEntityWithoutLock()
79ede46466SAndreas Gohr    {
80ede46466SAndreas Gohr        $this->expectException(IndexLockException::class);
81ede46466SAndreas Gohr
82ede46466SAndreas Gohr        $index = new MockDirectCollection();
83ede46466SAndreas Gohr        $index->addEntity('wiki:start', ['Title']);
84ede46466SAndreas Gohr    }
85ede46466SAndreas Gohr
86ede46466SAndreas Gohr    /**
87ede46466SAndreas Gohr     * Test that PageTitleCollection uses correct index names
88ede46466SAndreas Gohr     */
89ede46466SAndreas Gohr    public function testPageTitleCollection()
90ede46466SAndreas Gohr    {
91ede46466SAndreas Gohr        $index = new PageTitleCollection();
92ede46466SAndreas Gohr        $index->lock();
93ede46466SAndreas Gohr        $index->addEntity('wiki:start', ['Welcome']);
94ede46466SAndreas Gohr        $index->unlock();
95ede46466SAndreas Gohr
96ede46466SAndreas Gohr        $idxToken = new MemoryIndex('title');
97ede46466SAndreas Gohr        $this->assertEquals('Welcome', $idxToken->retrieveRow(0));
98ede46466SAndreas Gohr
99ede46466SAndreas Gohr        $this->assertEquals('Welcome', $index->getToken('wiki:start'));
100ede46466SAndreas Gohr    }
1016734bb8cSAndreas Gohr
1026734bb8cSAndreas Gohr    /**
1036734bb8cSAndreas Gohr     * resolveTokenFrequencies maps token RID = entity RID with frequency 1
1046734bb8cSAndreas Gohr     */
1056734bb8cSAndreas Gohr    public function testResolveTokenFrequencies()
1066734bb8cSAndreas Gohr    {
1076734bb8cSAndreas Gohr        $index = new MockDirectCollection('rtf_entity', 'rtf_token');
1086734bb8cSAndreas Gohr        $index->lock();
1096734bb8cSAndreas Gohr        $index->addEntity('wiki:start', ['Title One']);
1106734bb8cSAndreas Gohr        $index->addEntity('wiki:syntax', ['Title Two']);
1116734bb8cSAndreas Gohr        $index->unlock();
1126734bb8cSAndreas Gohr
1136734bb8cSAndreas Gohr        $result = $index->resolveTokenFrequencies(0, [0, 1]);
1146734bb8cSAndreas Gohr        $this->assertEquals([
1156734bb8cSAndreas Gohr            0 => [0 => 1],
1166734bb8cSAndreas Gohr            1 => [1 => 1],
1176734bb8cSAndreas Gohr        ], $result);
1186734bb8cSAndreas Gohr    }
1196734bb8cSAndreas Gohr
1206734bb8cSAndreas Gohr    /**
1216734bb8cSAndreas Gohr     * getEntitiesWithData returns entities that have non-empty tokens
1226734bb8cSAndreas Gohr     */
1236734bb8cSAndreas Gohr    public function testGetEntitiesWithData()
1246734bb8cSAndreas Gohr    {
1256734bb8cSAndreas Gohr        $index = new MockDirectCollection('ewd_entity', 'ewd_token');
1266734bb8cSAndreas Gohr        $index->lock();
1276734bb8cSAndreas Gohr        $index->addEntity('wiki:start', ['Title One']);
1286734bb8cSAndreas Gohr        $index->addEntity('wiki:empty', []);
1296734bb8cSAndreas Gohr        $index->addEntity('wiki:syntax', ['Title Two']);
1306734bb8cSAndreas Gohr        $index->unlock();
1316734bb8cSAndreas Gohr
1326734bb8cSAndreas Gohr        $result = $index->getEntitiesWithData();
1336734bb8cSAndreas Gohr        sort($result);
1346734bb8cSAndreas Gohr        $this->assertEquals(['wiki:start', 'wiki:syntax'], $result);
1356734bb8cSAndreas Gohr    }
136*21fbd01bSAndreas Gohr
137*21fbd01bSAndreas Gohr    /**
138*21fbd01bSAndreas Gohr     * checkIntegrity passes on a healthy DirectCollection
139*21fbd01bSAndreas Gohr     */
140*21fbd01bSAndreas Gohr    public function testCheckIntegrityHealthy()
141*21fbd01bSAndreas Gohr    {
142*21fbd01bSAndreas Gohr        $index = new MockDirectCollection('cih_entity', 'cih_token');
143*21fbd01bSAndreas Gohr        $index->lock();
144*21fbd01bSAndreas Gohr        $index->addEntity('wiki:start', ['Title One']);
145*21fbd01bSAndreas Gohr        $index->unlock();
146*21fbd01bSAndreas Gohr
147*21fbd01bSAndreas Gohr        $index->checkIntegrity(); // should not throw
148*21fbd01bSAndreas Gohr        $this->assertTrue(true);
149*21fbd01bSAndreas Gohr    }
150*21fbd01bSAndreas Gohr
151*21fbd01bSAndreas Gohr    /**
152*21fbd01bSAndreas Gohr     * checkIntegrity passes on an empty DirectCollection
153*21fbd01bSAndreas Gohr     */
154*21fbd01bSAndreas Gohr    public function testCheckIntegrityEmpty()
155*21fbd01bSAndreas Gohr    {
156*21fbd01bSAndreas Gohr        $index = new MockDirectCollection('cie_entity', 'cie_token');
157*21fbd01bSAndreas Gohr        $index->checkIntegrity(); // should not throw
158*21fbd01bSAndreas Gohr        $this->assertTrue(true);
159*21fbd01bSAndreas Gohr    }
160*21fbd01bSAndreas Gohr
161*21fbd01bSAndreas Gohr    /**
162*21fbd01bSAndreas Gohr     * checkIntegrity detects entity/token line count mismatch
163*21fbd01bSAndreas Gohr     */
164*21fbd01bSAndreas Gohr    public function testCheckIntegrityMismatch()
165*21fbd01bSAndreas Gohr    {
166*21fbd01bSAndreas Gohr        global $conf;
167*21fbd01bSAndreas Gohr        $index = new MockDirectCollection('cim_entity', 'cim_token');
168*21fbd01bSAndreas Gohr        $index->lock();
169*21fbd01bSAndreas Gohr        $index->addEntity('wiki:start', ['Title One']);
170*21fbd01bSAndreas Gohr        $index->unlock();
171*21fbd01bSAndreas Gohr
172*21fbd01bSAndreas Gohr        // corrupt: add extra line to token index
173*21fbd01bSAndreas Gohr        file_put_contents($conf['indexdir'] . '/cim_token.idx', "extra\n", FILE_APPEND);
174*21fbd01bSAndreas Gohr
175*21fbd01bSAndreas Gohr        $this->expectException(IndexIntegrityException::class);
176*21fbd01bSAndreas Gohr        (new MockDirectCollection('cim_entity', 'cim_token'))->checkIntegrity();
177*21fbd01bSAndreas Gohr    }
178ede46466SAndreas Gohr}
179