Login   Register  
PHP Classes
elePHPant
Icontem

File: FuzzyIndexTest.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Philipp Strazny  >  Fuzzy Index  >  FuzzyIndexTest.php  >  Download  
File: FuzzyIndexTest.php
Role: Unit test script
Content type: text/plain
Description: tests for FuzzyIndex and heuristics
Class: Fuzzy Index
Index text for performing fuzzy search
Author: By
Last change: updated tests to take newly added foreign keys into account
added test for delete_location
Date: 2012-06-16 22:17
Size: 12,982 bytes
 

Contents

Class file image Download
<?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));
	}
	
}