/*
* Copyright (c) 2009 Andrejs Jermakovics.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrejs Jermakovics - initial implementation
*/
package it.unibz.instasearch.indexing;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.lucene.index.IndexWriter;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Unit test for Searcher
*/
public class SearcherTest
{
private static TestSearcher searcher;
private static StorageIndexer indexer;
private static int numDocs;
@BeforeClass
public static void indexStuff() throws IOException, CoreException
{
indexer = new StorageIndexer();
indexTestFiles();
searcher = new TestSearcher(indexer.getIndexDir());
}
@Test
public void testSimpleText() throws Exception
{
List<SearchResultDoc> docs = search("unique");
assertEquals(1, docs.size());
docs = search("another");
assertEquals(3, docs.size());
docs = search("another other");
assertEquals(2, docs.size());
docs = search("another_other");
assertEquals(4, docs.size());
}
@Test
public void testCodeSearches() throws Exception
{
assertFileMatches("file5.txt", "HTTP_REFERER", true);
assertFileMatches("file5.txt", "HTTP_REFER");
assertFileMatches("file5.txt", "attp refered"); // approximate
assertFileMatches("file5.txt", "$_POST['HTTP_REFERER']");
assertFileMatches("file5.txt", "redirect($_POST['HTTP_REFERER']);");
assertFileMatches("file5.txt", "redirect http referer");
assertFileMatches("file6.txt", "TOPIC_OF_INTEREST", true);
assertFileMatches("file6.1.txt", "\"TOPIC OF INTEREST\"");
List<SearchResultDoc> docs = search("TOPIC_OF_INTEREST");
assertEquals(1, docs.size()); // contain topic
docs = search("TOPIC");
assertEquals(4, docs.size()); // contain topic
assertFileMatches("file7.txt", "driveLetter");
assertFileMatches("file7.txt", "server.driveLetter");
assertFileMatches("file7.txt", "server driveLetter");
assertFileMatches("file7.txt", "server drive Letter");
assertFileMatches("file7.txt", "getText(server.driveLetter, int a);");
assertFileMatches("file7.txt", "getString(my.variable, int var2) { }");
assertFileMatches("file1.txt", "file1.txt", "file8.txt");
assertFileMatches("file2.txt", "file2.txt", "file8.txt");
assertFileMatches("file4.xml", "file4.xml", "file8.txt");
assertFileMatches("file9.txt", "idl_Ty");
assertFileMatches("file10.txt", "idlTypeForNonGeneratedPorts");
assertFileMatches("file10.txt", "idl Type For_Non");
assertFileMatches("file11.txt", "pointer->execMethod");
assertFileMatches("file11.txt", "test3_mtdDecl");
}
@Test
public void testMoreCodeSearches() throws Exception
{
assertFileMatches("file6.1.txt", "iNTEReST TOpIc");
assertFileMatches("file16.txt", "\"class MethodClassifier\"");
assertFileMatches("file16.txt", "\"class MethodClassifier\"~1");
assertFileMatches("file16.txt", "class MethodClassifier");
assertFileMatches("file16.txt", "\"class MethodClassifier\" proj:proj1");
assertFileMatches("file15.txt", "\"new MethodClassifier\"");
assertFilesMatch("class MethodClassifier", false, "file16.txt", "file17.txt");
}
@Test
public void testCamelCaseSearch() throws Exception
{
assertFileMatches("file12.txt", "mainTopicHandler");
assertFileMatches("file4.xml", "MyFirstServer");
}
@Test
public void testFieldSearches() throws Exception
{
assertFileMatches("file8.txt", "name:file8.txt");
assertFileMatches("file8.txt", "name:file8");
assertFileMatches("file8.txt", "name:file8*");
assertFileMatches("FileWithoutExtension", "name:FWE");
assertFileMatches("FileWithoutExtension", "without extension");
assertFileMatches("FileWithoutExtension", "FileWithoutExtension");
assertFileMatches("FileWithoutExtension", "FileWithoutExt");
assertFileMatches("file4.xml", "ext:xml");
assertFileMatches("file4.xml", "handler ext:xml");
assertFileMatches("file4.xml", "handler MyFirstServer ext:*");
List<SearchResultDoc> docs = search("proj:proj1");
assertEquals(16, docs.size());
docs = search("proj:\"proj three\"");
assertEquals(3, docs.size());
}
@Test
public void testHyphenatedWords() throws Exception
{
assertFileMatches("file14.txt", "body-css-style", true);
assertFileMatches("file13.txt", "body css style", true);
assertFilesMatch("body css style", false, "file13.txt", "file14.txt");
}
@Test
public void testModifiedDateSearches() throws Exception
{
List<SearchResultDoc> found;
found = search("modified:\"1 day\"");
assertEquals(numDocs, found.size());
found = search("modified:today");
assertEquals(numDocs, found.size());
}
private void assertFileMatches(String expectedFile, String searchString, String... otherFiles) throws Exception
{
List<SearchResultDoc> docs = search(searchString);
assertEquals(expectedFile, docs.get(0).getFileName());
assertEquals(true, docs.size() > otherFiles.length);
for(int i = 0; i < otherFiles.length && i+1 < docs.size(); i++)
{
assertEquals(otherFiles[i], docs.get(i+1).getFileName());
}
}
private void assertFilesMatch(String searchString, boolean doExactSearch, String... expectedFiles) throws Exception
{
AtomicBoolean isExact = new AtomicBoolean(doExactSearch);
List<SearchResultDoc> docs = search(searchString, isExact );
assertEquals(true, docs.size() >= expectedFiles.length);
for(int i = 0; i < expectedFiles.length; i++)
{
assertEquals(expectedFiles[i], docs.get(i).getFileName());
}
assertEquals("Query changed exact flag", doExactSearch, isExact.get());
}
private void assertFileMatches(String expectedFile, String searchString, boolean exact) throws Exception
{
AtomicBoolean isExact = new AtomicBoolean(exact);
List<SearchResultDoc> docs = search(searchString, isExact );
assertEquals(expectedFile, docs.get(0).getFileName());
assertEquals("Exact query comparison failed", exact, isExact.get());
}
private static void indexTestFiles() throws IOException, CoreException
{
IndexWriter writer = indexer.createIndexWriter(true);
indexFile(writer, "/path/FileWithoutExtension", "a file without an extension");
indexFile(writer, "/path/file1.txt", "this is a text file with some unique contents");
indexFile(writer, "/path/file2.txt", "this is another text file with some other contents");
indexFile(writer, "/path/file3.txt", "this is yet another text file with some other contents");
indexFile(writer, "/path/file4.xml", "<handler class=\"com.app.command.MyFirstServer\"/>", "proj2");
indexFile(writer, "/path/file5.txt", "if(true)\n{redirect($_POST['HTTP_REFERER']);\n}", "proj three");
indexFile(writer, "/path/file6.txt", "this is yet another text file with TOPIC_OF_INTEREST");
indexFile(writer, "/path/file6.1.txt", "this is some other text file with TOPIC of INTEREST", "proj three");
indexFile(writer, "/path/file6.2.txt", "this file contains a TOPIC", "proj three");
indexFile(writer, "/path/file7.txt", "getText(server.driveLetter, int a); getString(my.variable, int var2) { }");
indexFile(writer, "/path/file8.txt", "/path/file1.txt \"file2.txt\" file3.txt;file4.xml");
indexFile(writer, "/path/file9.txt", "<handler class=\"id_lTy\" name=\"nm_lTy\"/>");
indexFile(writer, "/path/file10.txt", "String s = \"idlTypeForNonGeneratedPorts\";");
indexFile(writer, "/path/file11.txt", "pointer->execMethod(); new Main()->test3_mtdDecl();");
indexFile(writer, "/path/file12.txt", "public void mainTopicHandler(){ new MyClass(); }");
indexFile(writer, "/path/file13.txt", "body css style body css style body css style");
indexFile(writer, "/path/file14.txt", "some file with body-css-style ");
indexFile(writer, "/path/file15.txt", "Assert.assertEquals(\"Setter\", expected (new MethodClassifier) is");
indexFile(writer, "/path/file16.txt", "class MethodClassifier() { Integer a = new Integer(1); String s = new String(); } ");
indexFile(writer, "/path/file17.txt", "MethodClassifier(); main() { class Different { static class B; } }");
numDocs = writer.numDocs();
writer.close();
}
private static void indexFile(IndexWriter writer, String path, String contents) throws CoreException, IOException
{
indexFile(writer, path, contents, "proj1");
}
private static void indexFile(IndexWriter writer, String path, String contents, String proj) throws CoreException, IOException
{
IStorage file1 = new TestStorage(path, contents);
long time = System.currentTimeMillis() - 1000;
indexer.indexStorage(writer, file1, proj, time, null);
}
private List<SearchResultDoc> search(String searchString) throws Exception
{
return search(searchString, new AtomicBoolean(true) );
}
private List<SearchResultDoc> search(String searchString, AtomicBoolean isExact) throws Exception
{
SearchQuery searchQuery = new SearchQuery(searchString, SearchQuery.UNLIMITED_RESULTS);
searchQuery.setExact( isExact.get() );
SearchResult res = searcher.search(searchQuery);
isExact.set( searchQuery.isExact());
if( res == null )
return Collections.emptyList();
return res.getResultDocs();
}
}