1ede46466SAndreas Gohr<?php 2ede46466SAndreas Gohr 3ede46466SAndreas Gohrnamespace dokuwiki\test\Search\Collection; 4ede46466SAndreas Gohr 5ede46466SAndreas Gohruse dokuwiki\Search\Collection\PageMetaCollection; 6*21fbd01bSAndreas Gohruse dokuwiki\Search\Exception\IndexIntegrityException; 7ede46466SAndreas Gohruse dokuwiki\Search\Exception\IndexLockException; 8ede46466SAndreas Gohruse dokuwiki\Search\Index\MemoryIndex; 9ede46466SAndreas Gohr 10ede46466SAndreas Gohrclass LookupCollectionTest extends \DokuWikiTest 11ede46466SAndreas Gohr{ 12ede46466SAndreas Gohr /** 13ede46466SAndreas Gohr * Add data and directly check the underlying indexes for correctness 14ede46466SAndreas Gohr */ 15ede46466SAndreas Gohr public function testAddEntity() 16ede46466SAndreas Gohr { 17ede46466SAndreas Gohr $index = new MockLookupCollection('a_entity', 'a_token', 'a_freq', 'a_reverse'); 18ede46466SAndreas Gohr $index->lock(); 19ede46466SAndreas Gohr $index->addEntity('wiki:start', ['wiki:logo.png', 'wiki:banner.jpg', 'wiki:icon.svg']); 20ede46466SAndreas Gohr $index->unlock(); 21ede46466SAndreas Gohr 22ede46466SAndreas Gohr // check entity index 23ede46466SAndreas Gohr $idxEntity = new MemoryIndex('a_entity'); 24ede46466SAndreas Gohr $this->assertEquals('wiki:start', $idxEntity->retrieveRow(0)); 25ede46466SAndreas Gohr 26ede46466SAndreas Gohr // check token index (single file, no suffix) 27ede46466SAndreas Gohr $idxToken = new MemoryIndex('a_token'); 28ede46466SAndreas Gohr $this->assertEquals('wiki:logo.png', $idxToken->retrieveRow(0)); 29ede46466SAndreas Gohr $this->assertEquals('wiki:banner.jpg', $idxToken->retrieveRow(1)); 30ede46466SAndreas Gohr $this->assertEquals('wiki:icon.svg', $idxToken->retrieveRow(2)); 31ede46466SAndreas Gohr 32ede46466SAndreas Gohr // check frequency index — all frequencies are 1 (written without *1) 33ede46466SAndreas Gohr $idxFreq = new MemoryIndex('a_freq'); 34ede46466SAndreas Gohr $this->assertEquals('0', $idxFreq->retrieveRow(0)); // entity 0 with implicit freq 1 35ede46466SAndreas Gohr $this->assertEquals('0', $idxFreq->retrieveRow(1)); 36ede46466SAndreas Gohr $this->assertEquals('0', $idxFreq->retrieveRow(2)); 37ede46466SAndreas Gohr 38ede46466SAndreas Gohr // check reverse index 39ede46466SAndreas Gohr $idxRev = new MemoryIndex('a_reverse'); 40ede46466SAndreas Gohr $this->assertEquals('0:1:2', $idxRev->retrieveRow(0)); 41ede46466SAndreas Gohr } 42ede46466SAndreas Gohr 43ede46466SAndreas Gohr /** 44ede46466SAndreas Gohr * Duplicate tokens should be deduplicated 45ede46466SAndreas Gohr */ 46ede46466SAndreas Gohr public function testAddEntityDedup() 47ede46466SAndreas Gohr { 48ede46466SAndreas Gohr $index = new MockLookupCollection('b_entity', 'b_token', 'b_freq', 'b_reverse'); 49ede46466SAndreas Gohr $index->lock(); 50ede46466SAndreas Gohr $index->addEntity('wiki:start', ['wiki:logo.png', 'wiki:logo.png', 'wiki:banner.jpg']); 51ede46466SAndreas Gohr $index->unlock(); 52ede46466SAndreas Gohr 53ede46466SAndreas Gohr $idxToken = new MemoryIndex('b_token'); 54ede46466SAndreas Gohr $this->assertEquals('wiki:logo.png', $idxToken->retrieveRow(0)); 55ede46466SAndreas Gohr $this->assertEquals('wiki:banner.jpg', $idxToken->retrieveRow(1)); 56ede46466SAndreas Gohr 57ede46466SAndreas Gohr $idxRev = new MemoryIndex('b_reverse'); 58ede46466SAndreas Gohr $this->assertEquals('0:1', $idxRev->retrieveRow(0)); 59ede46466SAndreas Gohr } 60ede46466SAndreas Gohr 61ede46466SAndreas Gohr /** 62ede46466SAndreas Gohr * Updating an entity should remove old tokens and add new ones 63ede46466SAndreas Gohr */ 64ede46466SAndreas Gohr public function testUpdateEntity() 65ede46466SAndreas Gohr { 66ede46466SAndreas Gohr $index = new MockLookupCollection('c_entity', 'c_token', 'c_freq', 'c_reverse'); 67ede46466SAndreas Gohr 68ede46466SAndreas Gohr // initial add 69ede46466SAndreas Gohr $index->lock(); 70ede46466SAndreas Gohr $index->addEntity('wiki:start', ['wiki:logo.png', 'wiki:banner.jpg']); 71ede46466SAndreas Gohr $index->unlock(); 72ede46466SAndreas Gohr 73ede46466SAndreas Gohr // update: remove logo, keep banner, add icon 74ede46466SAndreas Gohr $index->lock(); 75ede46466SAndreas Gohr $index->addEntity('wiki:start', ['wiki:banner.jpg', 'wiki:icon.svg']); 76ede46466SAndreas Gohr $index->unlock(); 77ede46466SAndreas Gohr 78ede46466SAndreas Gohr // logo should be removed from frequency index 79ede46466SAndreas Gohr $idxFreq = new MemoryIndex('c_freq'); 80ede46466SAndreas Gohr $this->assertEquals('', $idxFreq->retrieveRow(0)); // logo removed 81ede46466SAndreas Gohr $this->assertEquals('0', $idxFreq->retrieveRow(1)); // banner still on entity 0 82ede46466SAndreas Gohr $this->assertEquals('0', $idxFreq->retrieveRow(2)); // icon added on entity 0 83ede46466SAndreas Gohr 84ede46466SAndreas Gohr // reverse index should only have banner and icon 85ede46466SAndreas Gohr $idxRev = new MemoryIndex('c_reverse'); 86ede46466SAndreas Gohr $this->assertEquals('1:2', $idxRev->retrieveRow(0)); 87ede46466SAndreas Gohr } 88ede46466SAndreas Gohr 89ede46466SAndreas Gohr /** 90ede46466SAndreas Gohr * Test reverse assignments returns two-level structure with empty group key 91ede46466SAndreas Gohr */ 92ede46466SAndreas Gohr public function testReverseAssignments() 93ede46466SAndreas Gohr { 94ede46466SAndreas Gohr $index = new MockLookupCollection('d_entity', 'd_token', 'd_freq', 'd_reverse'); 95ede46466SAndreas Gohr $index->lock(); 96ede46466SAndreas Gohr $index->addEntity('wiki:start', ['wiki:logo.png', 'wiki:banner.jpg']); 97ede46466SAndreas Gohr $index->unlock(); 98ede46466SAndreas Gohr 99ede46466SAndreas Gohr $result = $index->getReverseAssignments('wiki:start'); 1006734bb8cSAndreas Gohr $this->assertEquals([0 => [0 => 0, 1 => 0]], $result); 101ede46466SAndreas Gohr } 102ede46466SAndreas Gohr 103ede46466SAndreas Gohr /** 104ede46466SAndreas Gohr * Adding entity without lock should throw exception 105ede46466SAndreas Gohr */ 106ede46466SAndreas Gohr public function testAddEntityWithoutLock() 107ede46466SAndreas Gohr { 108ede46466SAndreas Gohr $this->expectException(IndexLockException::class); 109ede46466SAndreas Gohr 110ede46466SAndreas Gohr $index = new MockLookupCollection(); 111ede46466SAndreas Gohr $index->addEntity('wiki:start', ['wiki:logo.png']); 112ede46466SAndreas Gohr } 113ede46466SAndreas Gohr 114ede46466SAndreas Gohr /** 115ede46466SAndreas Gohr * Adding empty token list should clear entity from indexes 116ede46466SAndreas Gohr */ 117ede46466SAndreas Gohr public function testEmptyTokens() 118ede46466SAndreas Gohr { 119ede46466SAndreas Gohr $index = new MockLookupCollection('f_entity', 'f_token', 'f_freq', 'f_reverse'); 120ede46466SAndreas Gohr 121ede46466SAndreas Gohr // add some tokens first 122ede46466SAndreas Gohr $index->lock(); 123ede46466SAndreas Gohr $index->addEntity('wiki:start', ['wiki:logo.png']); 124ede46466SAndreas Gohr $index->unlock(); 125ede46466SAndreas Gohr 126ede46466SAndreas Gohr // now clear 127ede46466SAndreas Gohr $index->lock(); 128ede46466SAndreas Gohr $index->addEntity('wiki:start', []); 129ede46466SAndreas Gohr $index->unlock(); 130ede46466SAndreas Gohr 131ede46466SAndreas Gohr // frequency index should be empty for this token 132ede46466SAndreas Gohr $idxFreq = new MemoryIndex('f_freq'); 133ede46466SAndreas Gohr $this->assertEquals('', $idxFreq->retrieveRow(0)); 134ede46466SAndreas Gohr 135ede46466SAndreas Gohr // reverse index should be empty 136ede46466SAndreas Gohr $idxRev = new MemoryIndex('f_reverse'); 137ede46466SAndreas Gohr $this->assertEquals('', $idxRev->retrieveRow(0)); 138ede46466SAndreas Gohr } 139ede46466SAndreas Gohr 140ede46466SAndreas Gohr /** 141ede46466SAndreas Gohr * Test that PageMetaCollection('relation_media') uses correct index names 142ede46466SAndreas Gohr */ 143ede46466SAndreas Gohr public function testMediaCollection() 144ede46466SAndreas Gohr { 145ede46466SAndreas Gohr $index = new PageMetaCollection('relation_media'); 146ede46466SAndreas Gohr $index->lock(); 147ede46466SAndreas Gohr $index->addEntity('wiki:start', ['wiki:logo.png', 'wiki:banner.jpg']); 148ede46466SAndreas Gohr $index->unlock(); 149ede46466SAndreas Gohr 150ede46466SAndreas Gohr $idxToken = new MemoryIndex('relation_media_w'); 151ede46466SAndreas Gohr $this->assertEquals('wiki:logo.png', $idxToken->retrieveRow(0)); 152ede46466SAndreas Gohr $this->assertEquals('wiki:banner.jpg', $idxToken->retrieveRow(1)); 153ede46466SAndreas Gohr 154ede46466SAndreas Gohr $idxRev = new MemoryIndex('relation_media_p'); 155ede46466SAndreas Gohr $this->assertEquals('0:1', $idxRev->retrieveRow(0)); 156ede46466SAndreas Gohr } 157ede46466SAndreas Gohr 158ede46466SAndreas Gohr /** 159ede46466SAndreas Gohr * Test that PageMetaCollection('relation_references') uses correct index names 160ede46466SAndreas Gohr */ 161ede46466SAndreas Gohr public function testReferencesCollection() 162ede46466SAndreas Gohr { 163ede46466SAndreas Gohr $index = new PageMetaCollection('relation_references'); 164ede46466SAndreas Gohr $index->lock(); 165ede46466SAndreas Gohr $index->addEntity('wiki:start', ['wiki:syntax', 'wiki:welcome']); 166ede46466SAndreas Gohr $index->unlock(); 167ede46466SAndreas Gohr 168ede46466SAndreas Gohr $idxToken = new MemoryIndex('relation_references_w'); 169ede46466SAndreas Gohr $this->assertEquals('wiki:syntax', $idxToken->retrieveRow(0)); 170ede46466SAndreas Gohr $this->assertEquals('wiki:welcome', $idxToken->retrieveRow(1)); 171ede46466SAndreas Gohr 172ede46466SAndreas Gohr $idxRev = new MemoryIndex('relation_references_p'); 173ede46466SAndreas Gohr $this->assertEquals('0:1', $idxRev->retrieveRow(0)); 174ede46466SAndreas Gohr 175ede46466SAndreas Gohr $result = $index->getReverseAssignments('wiki:start'); 1766734bb8cSAndreas Gohr $this->assertEquals([0 => [0 => 0, 1 => 0]], $result); 177ede46466SAndreas Gohr } 178ede46466SAndreas Gohr 179ede46466SAndreas Gohr /** 1806734bb8cSAndreas Gohr * resolveTokens should deduplicate and assign frequency 1 under group 0 181ede46466SAndreas Gohr */ 182ede46466SAndreas Gohr public function testResolveTokens() 183ede46466SAndreas Gohr { 184ede46466SAndreas Gohr $index = new MockLookupCollection('rt_entity', 'rt_token', 'rt_freq', 'rt_reverse'); 185ede46466SAndreas Gohr $index->lock(); 186ede46466SAndreas Gohr 187ede46466SAndreas Gohr $result = $this->callInaccessibleMethod($index, 'resolveTokens', [ 188ede46466SAndreas Gohr ['wiki:logo.png', 'wiki:banner.jpg', 'wiki:logo.png'], 189ede46466SAndreas Gohr ]); 190ede46466SAndreas Gohr 1916734bb8cSAndreas Gohr // all tokens under group 0 (non-split) 1926734bb8cSAndreas Gohr $this->assertArrayHasKey(0, $result); 1936734bb8cSAndreas Gohr $this->assertCount(2, $result[0]); // deduplicated 194ede46466SAndreas Gohr 195ede46466SAndreas Gohr // token IDs are sequential: logo=0, banner=1 1966734bb8cSAndreas Gohr $this->assertEquals(1, $result[0][0]); // logo freq=1 1976734bb8cSAndreas Gohr $this->assertEquals(1, $result[0][1]); // banner freq=1 198ede46466SAndreas Gohr } 199ede46466SAndreas Gohr 200ede46466SAndreas Gohr /** 201ede46466SAndreas Gohr * resolveTokens with empty input should return empty array 202ede46466SAndreas Gohr */ 203ede46466SAndreas Gohr public function testResolveTokensEmpty() 204ede46466SAndreas Gohr { 205ede46466SAndreas Gohr $index = new MockLookupCollection('rte_entity', 'rte_token', 'rte_freq', 'rte_reverse'); 206ede46466SAndreas Gohr $index->lock(); 207ede46466SAndreas Gohr 208ede46466SAndreas Gohr $result = $this->callInaccessibleMethod($index, 'resolveTokens', [[]]); 209ede46466SAndreas Gohr 210ede46466SAndreas Gohr $this->assertEmpty($result); 211ede46466SAndreas Gohr } 212ede46466SAndreas Gohr 213ede46466SAndreas Gohr /** 214ede46466SAndreas Gohr * countTokens should deduplicate and assign frequency 1 215ede46466SAndreas Gohr */ 216ede46466SAndreas Gohr public function testCountTokens() 217ede46466SAndreas Gohr { 218ede46466SAndreas Gohr $index = new MockLookupCollection(); 219ede46466SAndreas Gohr 220ede46466SAndreas Gohr $result = $this->callInaccessibleMethod($index, 'countTokens', [ 221ede46466SAndreas Gohr ['wiki:logo.png', 'wiki:banner.jpg', 'wiki:logo.png'], 222ede46466SAndreas Gohr ]); 223ede46466SAndreas Gohr 224ede46466SAndreas Gohr $this->assertEquals([ 225ede46466SAndreas Gohr 'wiki:logo.png' => 1, 226ede46466SAndreas Gohr 'wiki:banner.jpg' => 1, 227ede46466SAndreas Gohr ], $result); 228ede46466SAndreas Gohr } 2296734bb8cSAndreas Gohr 2306734bb8cSAndreas Gohr /** 2316734bb8cSAndreas Gohr * getEntitiesWithData returns entities that have frequency data 2326734bb8cSAndreas Gohr */ 2336734bb8cSAndreas Gohr public function testGetEntitiesWithData() 2346734bb8cSAndreas Gohr { 2356734bb8cSAndreas Gohr $index = new MockLookupCollection('ewd_entity', 'ewd_token', 'ewd_freq', 'ewd_reverse'); 2366734bb8cSAndreas Gohr $index->lock(); 2376734bb8cSAndreas Gohr $index->addEntity('wiki:start', ['wiki:syntax', 'wiki:welcome']); 2386734bb8cSAndreas Gohr $index->addEntity('wiki:other', ['wiki:syntax']); 2396734bb8cSAndreas Gohr $index->addEntity('wiki:empty', []); 2406734bb8cSAndreas Gohr $index->unlock(); 2416734bb8cSAndreas Gohr 2426734bb8cSAndreas Gohr $result = $index->getEntitiesWithData(); 2436734bb8cSAndreas Gohr sort($result); 2446734bb8cSAndreas Gohr $this->assertEquals(['wiki:other', 'wiki:start'], $result); 2456734bb8cSAndreas Gohr } 2466734bb8cSAndreas Gohr 2476734bb8cSAndreas Gohr /** 2486734bb8cSAndreas Gohr * resolveTokenFrequencies returns entity frequencies for given token IDs 2496734bb8cSAndreas Gohr */ 2506734bb8cSAndreas Gohr public function testResolveTokenFrequencies() 2516734bb8cSAndreas Gohr { 2526734bb8cSAndreas Gohr $index = new MockLookupCollection('rtf_entity', 'rtf_token', 'rtf_freq', 'rtf_reverse'); 2536734bb8cSAndreas Gohr $index->lock(); 2546734bb8cSAndreas Gohr $index->addEntity('wiki:start', ['wiki:syntax', 'wiki:welcome']); 2556734bb8cSAndreas Gohr $index->addEntity('wiki:other', ['wiki:syntax']); 2566734bb8cSAndreas Gohr $index->unlock(); 2576734bb8cSAndreas Gohr 2586734bb8cSAndreas Gohr // token ID 0 = wiki:syntax, referenced by both entities 2596734bb8cSAndreas Gohr $result = $index->resolveTokenFrequencies(0, [0]); 2606734bb8cSAndreas Gohr $this->assertArrayHasKey(0, $result); 2616734bb8cSAndreas Gohr $this->assertCount(2, $result[0]); // two entities have this token 2626734bb8cSAndreas Gohr } 2636734bb8cSAndreas Gohr 2646734bb8cSAndreas Gohr /** 265*21fbd01bSAndreas Gohr * checkIntegrity passes on a healthy non-split collection 266*21fbd01bSAndreas Gohr */ 267*21fbd01bSAndreas Gohr public function testCheckIntegrityHealthy() 268*21fbd01bSAndreas Gohr { 269*21fbd01bSAndreas Gohr $index = new MockLookupCollection('cih_entity', 'cih_token', 'cih_freq', 'cih_reverse'); 270*21fbd01bSAndreas Gohr $index->lock(); 271*21fbd01bSAndreas Gohr $index->addEntity('wiki:start', ['wiki:syntax']); 272*21fbd01bSAndreas Gohr $index->unlock(); 273*21fbd01bSAndreas Gohr 274*21fbd01bSAndreas Gohr $index->checkIntegrity(); // should not throw 275*21fbd01bSAndreas Gohr $this->assertTrue(true); 276*21fbd01bSAndreas Gohr } 277*21fbd01bSAndreas Gohr 278*21fbd01bSAndreas Gohr /** 279*21fbd01bSAndreas Gohr * checkIntegrity passes on an empty non-split collection 280*21fbd01bSAndreas Gohr */ 281*21fbd01bSAndreas Gohr public function testCheckIntegrityEmpty() 282*21fbd01bSAndreas Gohr { 283*21fbd01bSAndreas Gohr $index = new MockLookupCollection('cie_entity', 'cie_token', 'cie_freq', 'cie_reverse'); 284*21fbd01bSAndreas Gohr $index->checkIntegrity(); // should not throw 285*21fbd01bSAndreas Gohr $this->assertTrue(true); 286*21fbd01bSAndreas Gohr } 287*21fbd01bSAndreas Gohr 288*21fbd01bSAndreas Gohr /** 289*21fbd01bSAndreas Gohr * checkIntegrity detects token/frequency mismatch on non-split collection 290*21fbd01bSAndreas Gohr */ 291*21fbd01bSAndreas Gohr public function testCheckIntegrityTokenFreqMismatch() 292*21fbd01bSAndreas Gohr { 293*21fbd01bSAndreas Gohr global $conf; 294*21fbd01bSAndreas Gohr $index = new MockLookupCollection('cim_entity', 'cim_token', 'cim_freq', 'cim_reverse'); 295*21fbd01bSAndreas Gohr $index->lock(); 296*21fbd01bSAndreas Gohr $index->addEntity('wiki:start', ['wiki:syntax']); 297*21fbd01bSAndreas Gohr $index->unlock(); 298*21fbd01bSAndreas Gohr 299*21fbd01bSAndreas Gohr // corrupt: add extra line to token index 300*21fbd01bSAndreas Gohr file_put_contents($conf['indexdir'] . '/cim_token.idx', "extra\n", FILE_APPEND); 301*21fbd01bSAndreas Gohr 302*21fbd01bSAndreas Gohr $this->expectException(IndexIntegrityException::class); 303*21fbd01bSAndreas Gohr (new MockLookupCollection('cim_entity', 'cim_token', 'cim_freq', 'cim_reverse'))->checkIntegrity(); 304*21fbd01bSAndreas Gohr } 305*21fbd01bSAndreas Gohr 306*21fbd01bSAndreas Gohr /** 307*21fbd01bSAndreas Gohr * checkIntegrity detects entity/reverse mismatch on non-split collection 308*21fbd01bSAndreas Gohr */ 309*21fbd01bSAndreas Gohr public function testCheckIntegrityEntityReverseMismatch() 310*21fbd01bSAndreas Gohr { 311*21fbd01bSAndreas Gohr global $conf; 312*21fbd01bSAndreas Gohr $index = new MockLookupCollection('cir_entity', 'cir_token', 'cir_freq', 'cir_reverse'); 313*21fbd01bSAndreas Gohr $index->lock(); 314*21fbd01bSAndreas Gohr $index->addEntity('wiki:start', ['wiki:syntax']); 315*21fbd01bSAndreas Gohr $index->unlock(); 316*21fbd01bSAndreas Gohr 317*21fbd01bSAndreas Gohr // corrupt: add extra line to reverse index 318*21fbd01bSAndreas Gohr file_put_contents($conf['indexdir'] . '/cir_reverse.idx', "0\n", FILE_APPEND); 319*21fbd01bSAndreas Gohr 320*21fbd01bSAndreas Gohr $this->expectException(IndexIntegrityException::class); 321*21fbd01bSAndreas Gohr (new MockLookupCollection('cir_entity', 'cir_token', 'cir_freq', 'cir_reverse'))->checkIntegrity(); 322*21fbd01bSAndreas Gohr } 323*21fbd01bSAndreas Gohr 324*21fbd01bSAndreas Gohr /** 325*21fbd01bSAndreas Gohr * checkIntegrity detects missing frequency index when token index exists 326*21fbd01bSAndreas Gohr */ 327*21fbd01bSAndreas Gohr public function testCheckIntegrityMissingFreqIndex() 328*21fbd01bSAndreas Gohr { 329*21fbd01bSAndreas Gohr global $conf; 330*21fbd01bSAndreas Gohr $index = new MockLookupCollection('cimf_entity', 'cimf_token', 'cimf_freq', 'cimf_reverse'); 331*21fbd01bSAndreas Gohr $index->lock(); 332*21fbd01bSAndreas Gohr $index->addEntity('wiki:start', ['wiki:syntax']); 333*21fbd01bSAndreas Gohr $index->unlock(); 334*21fbd01bSAndreas Gohr 335*21fbd01bSAndreas Gohr // corrupt: delete frequency index 336*21fbd01bSAndreas Gohr @unlink($conf['indexdir'] . '/cimf_freq.idx'); 337*21fbd01bSAndreas Gohr 338*21fbd01bSAndreas Gohr $this->expectException(IndexIntegrityException::class); 339*21fbd01bSAndreas Gohr (new MockLookupCollection('cimf_entity', 'cimf_token', 'cimf_freq', 'cimf_reverse'))->checkIntegrity(); 340*21fbd01bSAndreas Gohr } 341*21fbd01bSAndreas Gohr 342*21fbd01bSAndreas Gohr /** 3436734bb8cSAndreas Gohr * groupToSuffix throws on non-0 group for non-split collection 3446734bb8cSAndreas Gohr */ 3456734bb8cSAndreas Gohr public function testGroupToSuffixValidation() 3466734bb8cSAndreas Gohr { 3476734bb8cSAndreas Gohr $this->expectException(\dokuwiki\Search\Exception\IndexUsageException::class); 3486734bb8cSAndreas Gohr 3496734bb8cSAndreas Gohr $index = new MockLookupCollection('gs_entity', 'gs_token', 'gs_freq', 'gs_reverse'); 3506734bb8cSAndreas Gohr // non-split collection should reject group 5 3516734bb8cSAndreas Gohr $index->getTokenIndex(5); 3526734bb8cSAndreas Gohr } 353ede46466SAndreas Gohr} 354