<?php
/**
* @author Philipp Strazny <philipp at strazny dot com>
* @since 2012-01
* Test class for FuzzyIndex.
* usage:
* phpunit FuzzyIndexTest.php
* or
* phpunit --coverage-html reports FuzzyIndexTest.php
*
* 2012-06-16:
* modified testInsert_snippet_locations() to conform to new foreign key constraints
* added testDelete_location
*/
require_once('FuzzyIndex.php');
class FuzzyIndexTest extends PHPUnit_Framework_TestCase
{
protected $tmpfile;
protected $fi;
private function rmTestDbs(){
$testdbs = glob('testdb-[0-9]*');
foreach($testdbs as $t){
@unlink($t);
}
}
public function setUp(){
$this->rmTestDbs();//clean up potential leftovers from previous runs
$this->tmpfile = 'testdb-'.microtime(true);
$this->fi = new FuzzyIndex($this->tmpfile);
}
public function tearDown(){
@unlink($tmpfile);
}
public function test__construct(){
$this->assertTrue(file_exists($this->tmpfile));
$expected=array('locations','snippets','snippet_locations', 'location_length', 'sqlite_sequence');
$tables = $this->fi->list_tables();
$diff = array_diff($tables, $expected);
//print_r($diff);
$this->assertEmpty($diff);
}
/**
* @expectedException InvalidArgumentException
*/
public function test__constructBadFileEmpty(){
$fi = new FuzzyIndex('');
}
/**
* @expectedException InvalidArgumentException
*/
public function test__constructBadFileDot(){
$fi = new FuzzyIndex('.');
}
public function testGetDBSize(){
$size = $this->fi->getDBSize();
$this->assertTrue($size>0);
}
public function testInsert_location(){
$locationid = $this->fi->insert_location('testA', 1, 5);
$this->assertEquals($locationid, 1);
$locationid = $this->fi->insert_location('testB', 1, 5);
$this->assertEquals($locationid, 2);
}
/**
* @depends testInsert_location
*/
public function testget_locationid(){
$locationid = $this->fi->get_locationid('testA');
$this->assertFalse($locationid);
$this->fi->insert_location('testA', 1, 5);
$locationid = $this->fi->get_locationid('testA');
$this->assertEquals($locationid, 1);
}
public function testInsert_snippet(){
$snippetid = $this->fi->insert_snippet('testA');
$this->assertEquals($snippetid, 1);
$snippetid = $this->fi->insert_snippet('testB');
$this->assertEquals($snippetid, 2);
}
/**
* @depends testInsert_snippet
*/
public function testget_snippetid(){
$snippetid = $this->fi->get_snippetid('testA');
$this->assertFalse($snippetid);
$this->fi->insert_snippet('testA');
$snippetid = $this->fi->get_snippetid('testA');
$this->assertEquals($snippetid, 1);
}
public function testInsert_snippet_locations(){
// insert some locations and snippets
// to avoid foreign key violation below
$this->fi->insert_location('test',1,1);
$this->fi->insert_snippet('test1');
$this->fi->insert_snippet('test2');
$this->fi->insert_snippet('test3');
$snippetids = array(1, 2, 3);
$rowid = $this->fi->insert_snippet_locations($snippetids, 1);
$this->assertFalse(empty($rowid));
$this->fi=null;
$dbh = new PDO('sqlite:'.$this->tmpfile);
$res = $dbh->query('SELECT * FROM snippet_locations');
$valpairs = $res->fetchAll();
$sids = array();
$lids = array();
foreach($valpairs as $vpair){
$sids[] = $vpair['snippetid'];
$lids[] = $vpair['locationid'];
}
$this->assertEquals(count($valpairs), 3);
$this->assertEmpty(array_diff($snippetids, $sids));
$this->assertEmpty(array_diff(array_unique($lids), array(1)));
}
public function testGetHeuristic(){
$heuristic = $this->fi->getHeuristic();
$this->assertTrue($heuristic instanceof CharsHeuristic);
}
public function testGet_snippetids(){
$snippets = array('a','b','c');
$snippetids = $this->fi->get_snippetids($snippets);
$expected = array('1','2','3');
sort($snippetids);
$this->assertEquals($expected, $snippetids);
$snippets = array('d', 'a', 'e', 'b','c');
$snippetids = $this->fi->get_snippetids($snippets);
$expected = array('1','2','3', '4', '5');
sort($snippetids);
$this->assertEquals($expected, $snippetids);
}
/**
* @depends testGetHeuristic
* @depends testGet_snippetids
*/
public function testInsert_string(){
$string = 'hello';
$this->fi->insert_string($string, 'somelocation');
$snippets = $this->fi->getHeuristic()->makeSnippets($string);
$snippetids = $this->fi->get_snippetids($snippets);
sort($snippetids);
$expected = array('1','2','3', '4', '5');
$this->assertEquals($expected, $snippetids);
}
/**
* @depends testInsert_string
*/
public function testGet_best_locations(){
$locations_and_strings = array(
'loc01'=>'market research',
'loc02'=>'marketer',
'loc03'=>'bull market',
'loc04'=>'banking',
'loc05'=>'ponzi scheme',
'loc06'=>'investment banker',
'loc07'=>'criminals');
foreach($locations_and_strings as $loc=>$string){
$this->fi->insert_string($string, $loc);
}
$bestlocations = $this->fi->get_best_locations('', 3, 50);
$this->assertTrue(empty($bestlocations));
$string = 'marketing';
$bestlocations = $this->fi->get_best_locations($string, 3, 50);
$this->assertFalse(empty($bestlocations));
$this->assertRegExp('/loc02/', $bestlocations[0]);
}
/**
* @expectedException InvalidArgumentException
*/
public function testInsert_stringEmptyString(){
$this->fi->insert_string('', 'somelocation');
}
/**
* @expectedException InvalidArgumentException
*/
public function testInsert_stringEmptyLocation(){
$this->fi->insert_string('somestring', '');
}
public function testMakeSnippets(){
$heuristic = new BaseHeuristic();
$snippets = $heuristic->makeSnippets('test');
$expected = array('test');
$this->assertEquals($expected, $snippets);
}
/**
* @depends testMakeSnippets
*/
public function testCharsHeuristicMake_snippets(){
$string = 'Hello';
$expected = array(' He', 'Hel', 'ell', 'llo', 'lo ');
sort($expected);
$snippets = $this->fi->getHeuristic()->makeSnippets($string);
sort($snippets);
$this->assertEquals($expected, $snippets);
}
public function testGetHeuristicName(){
$name = $this->fi->getHeuristicName();
$this->assertEquals('CharsHeuristic', $name);
}
/**
* @depends testGetHeuristicName
*/
public function testSetHeuristic(){
$curheuristic = $this->fi->getHeuristicName();
$this->assertEquals($curheuristic, 'CharsHeuristic');
$newheuristic = 'WordChunkHeuristic';
$this->fi->setHeuristic($newheuristic);
$curheuristic = $this->fi->getHeuristicName();
$this->assertEquals($curheuristic, $newheuristic);
}
/**
* @expectedException InvalidArgumentException
*/
public function testSetHeuristicBad(){
$this->fi->setHeuristic('badheuristic');
}
/**
* @depends testSetHeuristic
* @depends testGetHeuristic
* @depends testMakeSnippets
*/
public function testLowercaseCharsHeuristicMake_snippets(){
$string = 'Hello';
$expected = array(' he', 'hel', 'ell', 'llo', 'lo ');
sort($expected);
$this->fi->setHeuristic('LowercaseCharsHeuristic');
$snippets = $this->fi->getHeuristic()->makeSnippets($string);
sort($snippets);
$this->assertEquals($expected, $snippets);
}
/**
* @depends testSetHeuristic
* @depends testGetHeuristic
* @depends testMakeSnippets
*/
public function testWordCharsHeuristicMake_snippets(){
$string = 'Hel-lo';
$expected = array('Hel');
//' He', 'el-', 'l-lo', 'lo ' all contain non-word characters
// and are removed
sort($expected);
$this->fi->setHeuristic('WordCharsHeuristic');
$snippets = $this->fi->getHeuristic()->makeSnippets($string);
sort($snippets);
$this->assertEquals($expected, $snippets);
}
/**
* @depends testSetHeuristic
* @depends testGetHeuristic
* @depends testMakeSnippets
*/
public function testLowercaseWordCharsHeuristicMake_snippets(){
$string = 'Hel-lo';
$expected = array('hel');
//' He', 'el-', 'l-lo', 'lo ' all contain non-word characters
// and are removed
sort($expected);
$this->fi->setHeuristic('LowercaseWordCharsHeuristic');
$snippets = $this->fi->getHeuristic()->makeSnippets($string);
sort($snippets);
$this->assertEquals($expected, $snippets);
}
/**
* @depends testSetHeuristic
* @depends testGetHeuristic
* @depends testMakeSnippets
*/
public function testWordHeuristicMake_snippets(){
$string = 'Look here: this, of course, is a well-formed sentence!';
$expected = array('Look', 'here', 'this', 'of', 'course', 'is', 'a', 'well-formed', 'sentence');
sort($expected);
$this->fi->setHeuristic('WordHeuristic');
$snippets = $this->fi->getHeuristic()->makeSnippets($string);
sort($snippets);
$this->assertEquals($expected, $snippets);
}
/**
* @depends testSetHeuristic
* @depends testGetHeuristic
* @depends testMakeSnippets
*/
public function testLowercaseWordHeuristicMake_snippets(){
$string = 'Look here: this, of course, is a well-formed sentence!';
$expected = array('look', 'here', 'this', 'of', 'course', 'is', 'a', 'well-formed', 'sentence');
sort($expected);
$this->fi->setHeuristic('LowercaseWordHeuristic');
$snippets = $this->fi->getHeuristic()->makeSnippets($string);
sort($snippets);
$this->assertEquals($expected, $snippets);
}
/**
* @depends testSetHeuristic
* @depends testGetHeuristic
* @depends testMakeSnippets
*/
public function testWordChunkHeuristicMake_snippets(){
$string = 'Look here: this, of course, is a well-formed sentence!';
$expected = array('Look', 'here', 'this', 'of', 'course', 'is', 'a', 'well', 'formed', 'sentence');
sort($expected);
$this->fi->setHeuristic('WordChunkHeuristic');
$snippets = $this->fi->getHeuristic()->makeSnippets($string);
sort($snippets);
$this->assertEquals($expected, $snippets);
}
/**
* @depends testSetHeuristic
* @depends testGetHeuristic
* @depends testMakeSnippets
*/
public function testLowercaseWordChunkHeuristicMake_snippets(){
$string = 'Look here: this, of course, is a well-formed sentence!';
$expected = array('look', 'here', 'this', 'of', 'course', 'is', 'a', 'well', 'formed', 'sentence');
sort($expected);
$this->fi->setHeuristic('LowercaseWordChunkHeuristic');
$snippets = $this->fi->getHeuristic()->makeSnippets($string);
sort($snippets);
$this->assertEquals($expected, $snippets);
}
/**
* @expectedException InvalidArgumentException
*/
public function testCharsHeuristic_badConstructorNull(){
$heuristic = new CharsHeuristic(null);
}
/**
* @expectedException InvalidArgumentException
*/
public function testCharsHeuristic_badConstructorZero(){
$heuristic = new CharsHeuristic(0);
}
/**
* @expectedException InvalidArgumentException
*/
public function testCharsHeuristic_badConstructorString(){
$heuristic = new CharsHeuristic('test');
}
/**
* @expectedException InvalidArgumentException
*/
public function testCharsHeuristic_badConstructorLargeNumber(){
$heuristic = new CharsHeuristic(10000);
}
/**
* @expectedException InvalidArgumentException
*/
public function testLoad_lines_from_fileEmptyFilename(){
$this->fi->load_lines_from_file('');
}
/**
* @expectedException InvalidArgumentException
*/
public function testLoad_lines_from_fileBadFile(){
$this->fi->load_lines_from_file('badfile0u909u0');
}
public function testLoad_lines_from_file(){
$bom = "\xef\xbb\xbf";
$lines = $bom."line one\n\nline two\nline three";
$tmpfile = microtime(true);
file_put_contents($tmpfile, $lines);
$this->expectOutputRegex('/3 of 4 lines loaded/');
$this->fi->load_lines_from_file($tmpfile);
unlink($tmpfile);
}
public function testLoad_lines_from_file_fullstring(){
$bom = "\xef\xbb\xbf";
$lines = $bom."line one\n\nline two\nline three";
$tmpfile = microtime(true);
file_put_contents($tmpfile, $lines);
$this->expectOutputRegex('/3 of 4 lines loaded/');
$this->fi->load_lines_from_file($tmpfile, true);
unlink($tmpfile);
}
public function testDelete_location(){
$this->fi->setHeuristic('WordHeuristic');
$string = 'abc';
$this->fi->insert_string($string, 'location1');
$string = 'bcd';
$this->fi->insert_string($string, 'location2');
$string = 'cde';
$this->fi->insert_string($string, 'location3');
$string = 'def';
$this->fi->insert_string($string, 'location2');
$dbh = new PDO('sqlite:'.$this->tmpfile);
$res = $dbh->query('SELECT locationid FROM locations');
$vals = $res->fetchAll();
$this->assertEquals(count($vals), 3);
$res = $dbh->query('SELECT locationid FROM snippet_locations');
$vals = $res->fetchAll();
$this->assertEquals(count($vals), 4);
$this->fi->delete_location(2);
$res = $dbh->query('SELECT locationid FROM locations');
$vals = $res->fetchAll();
$this->assertEquals(count($vals), 2);
$res = $dbh->query('SELECT locationid FROM snippet_locations');
$vals = $res->fetchAll();
$this->assertEquals(count($vals), 2);
$locids = array();
foreach ($vals as $val){
$locids[] = $val['locationid'];
}
$this->assertEquals($locids, array(1, 3));
}
}
|