package org.erlide.ui.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.erlide.engine.ErlangEngine;
import org.erlide.engine.model.ErlModelException;
import org.erlide.engine.model.root.IErlModule;
import org.erlide.engine.model.root.IErlProject;
import org.erlide.engine.services.search.ErlSearchScope;
import org.erlide.engine.services.search.ErlangSearchPattern;
import org.erlide.engine.services.search.LimitTo;
import org.erlide.engine.services.search.SearchFor;
import org.erlide.engine.services.search.SearchPatternFactory;
import org.erlide.engine.util.ErlideTestUtils;
import org.erlide.ui.internal.search.ErlSearchQuery;
import org.erlide.ui.internal.search.ErlangSearchElement;
import org.erlide.ui.internal.search.ErlangSearchResult;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class SearchTest {
static IErlProject projects[] = null;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
ErlideTestUtils.initProjects();
// We set up projects here, it's quite costly
final String name1 = "testproject1";
final IErlProject erlProject1 = ErlideTestUtils
.createProject(ErlideTestUtils.getTmpPath(name1), name1);
final String name2 = "testproject2";
final IErlProject erlProject2 = ErlideTestUtils
.createProject(ErlideTestUtils.getTmpPath(name2), name2);
projects = new IErlProject[] { erlProject1, erlProject2 };
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
ErlideTestUtils.deleteProjects();
}
@Before
public void setUp() throws Exception {
ErlideTestUtils.initModulesAndIncludes();
}
@After
public void tearDown() throws Exception {
ErlideTestUtils.deleteModules();
}
@Test
public void findExternalCallsReferencesTest() throws Exception {
findExternalCallsTestAux(LimitTo.REFERENCES, 1);
}
@Test
public void findExternalCallsDefinitionsTest() throws Exception {
findExternalCallsTestAux(LimitTo.DEFINITIONS, 2);
}
@Test
public void findExternalCallsAllOccurencesTest() throws Exception {
findExternalCallsTestAux(LimitTo.ALL_OCCURRENCES, 3);
}
private void findExternalCallsTestAux(final LimitTo limitTo, final int nFoundExpected)
throws CoreException, ErlModelException, OperationCanceledException {
// given
// a module a with an exported function f
// and a module b which calls a:f()
final IErlModule moduleA = ErlideTestUtils.createModule(projects[0], "a.erl",
"-module(a).\n-export([f/0]).\nf() ->\n ok.\n");
final IErlModule moduleB = ErlideTestUtils.createModule(projects[0], "b.erl",
"-module(b).\n-export([f/0]).\nf() ->\n a:f().\n");
moduleA.open(null);
moduleB.open(null);
// when
// searching for the call to a:f
final ErlangSearchPattern ref = new SearchPatternFactory(
ErlangEngine.getInstance().getModelUtilService()).getSearchPattern(
SearchFor.FUNCTION, "a", "f", 0, limitTo, moduleA);
final ErlSearchScope scope = new ErlSearchScope(moduleA);
scope.addModule(moduleB);
final ErlSearchQuery query = new ErlSearchQuery(ref, scope, "");
query.run(new NullProgressMonitor());
// then
// it should be found in module b
final ErlangSearchResult searchResult = (ErlangSearchResult) query
.getSearchResult();
assertEquals(nFoundExpected, searchResult.getMatchCount());
final List<ErlangSearchElement> result = searchResult.getResult();
if (limitTo == LimitTo.REFERENCES) {
// f is only referred in moduleB, but declarations matches in any
// module as long as arity and name are equal
assertFalse(hasModule(moduleA, result));
} else {
assertTrue(hasModule(moduleA, result));
}
assertTrue(hasModule(moduleB, result));
}
@Test
public void findCallAfterRecordRef() throws Exception {
// given
// a module a with an exported function f
// and a module b which calls a:f()
final IErlModule moduleA = ErlideTestUtils.createModule(projects[0], "a.erl",
"-module(a).\n-export([f/0]).\nf() ->\n ok.\n");
final IErlModule moduleB = ErlideTestUtils.createModule(projects[0], "b.erl",
"-module(b).\n-export([f/0]).\nf() ->\n #a.b,\n a:f().\n");
moduleA.open(null);
moduleB.open(null);
// when
// searching for the call to a:f
final ErlangSearchPattern ref = new SearchPatternFactory(
ErlangEngine.getInstance().getModelUtilService()).getSearchPattern(
SearchFor.FUNCTION, "a", "f", 0, LimitTo.REFERENCES, moduleA);
final ErlSearchScope scope = new ErlSearchScope(moduleA);
scope.addModule(moduleB);
final ErlSearchQuery query = new ErlSearchQuery(ref, scope, "");
query.run(new NullProgressMonitor());
// then
// it should be found in module b
final ErlangSearchResult searchResult = (ErlangSearchResult) query
.getSearchResult();
assertEquals(1, searchResult.getMatchCount());
final List<ErlangSearchElement> result = searchResult.getResult();
assertTrue(hasModule(moduleB, result));
assertFalse(hasModule(moduleA, result));
}
@Test
public void findVariableRef() throws Exception {
// given
// a module a with an exported function f
// and a module b which calls a:f()
final IErlModule moduleA = ErlideTestUtils.createModule(projects[0], "a.erl",
"-module(a).\n-export([f/1]).\nf(A) ->\n {A}.\n");
final IErlModule moduleB = ErlideTestUtils.createModule(projects[0], "b.erl",
"-module(b).\n-export([f/0]).\nf(A) ->\n [A].\n");
moduleA.open(null);
moduleB.open(null);
// when
// searching for the variable A from module a
final ErlangSearchPattern pattern = new SearchPatternFactory(
ErlangEngine.getInstance().getModelUtilService()).getSearchPattern(
SearchFor.VARIABLE, null, "A", 0, LimitTo.ALL_OCCURRENCES,
moduleA);
final ErlSearchScope scope = new ErlSearchScope(moduleA);
scope.addModule(moduleB);
final ErlSearchScope reducedScope = pattern.reduceScope(scope);
final ErlSearchQuery query = new ErlSearchQuery(pattern, reducedScope, "");
query.run(new NullProgressMonitor());
// then
// it should be found in module a
final ErlangSearchResult searchResult = (ErlangSearchResult) query
.getSearchResult();
assertEquals(2, searchResult.getMatchCount());
final List<ErlangSearchElement> result = searchResult.getResult();
assertTrue(hasModule(moduleA, result));
assertFalse(hasModule(moduleB, result));
}
private boolean hasModule(final IErlModule module,
final List<ErlangSearchElement> result) {
for (final ErlangSearchElement erlangSearchElement : result) {
if (erlangSearchElement.getModule().equals(module)) {
return true;
}
}
return false;
}
}