package org.erlide.engine.model.erlang; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.File; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.erlide.engine.ErlangEngine; import org.erlide.engine.internal.model.root.ErlProject; import org.erlide.engine.model.IErlElement; import org.erlide.engine.model.root.IErlElementLocator; import org.erlide.engine.model.root.IErlModel; import org.erlide.engine.model.root.IErlModule; import org.erlide.engine.model.root.IErlProject; import org.erlide.engine.services.parsing.ScannerService; import org.erlide.engine.services.search.OpenResult; import org.erlide.engine.services.search.OpenService; import org.erlide.engine.util.ErlideTestUtils; import org.erlide.util.FilePathUtils; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.google.common.collect.Lists; public class ErlProjectTest { private static IErlProject[] projects; @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 findIncludeFile() throws Exception { // given // a project with a module and an include including file.hrl final IErlProject project = projects[0]; final String includeName = "a.hrl"; final IErlModule include = ErlideTestUtils.createModule(project, includeName, "-include_lib(\"kernel/include/file.hrl\").\n-record(rec1, {field, another=def}).\n-define(MACRO(A), lists:reverse(A)).\n"); include.open(null); final IErlModule module = ErlideTestUtils.createModule(project, "f.erl", "-module(f).\n-include(\"a.hrl\").\n-export([f/0]).\n-record(rec2, {a, b}).\n" + "f() ->\n lists:reverse([1, 0]),\n lists:reverse([1, 0], [2]).\n"); module.open(null); final IErlElementLocator model = ErlangEngine.getInstance().getModel(); // when // looking for the include final IErlModule include1 = model.findIncludeFromModule(module, includeName, null, IErlElementLocator.Scope.PROJECT_ONLY); final IErlModule include2 = model.findIncludeFromProject(project, "file.hrl", null, IErlElementLocator.Scope.PROJECT_ONLY); // then // it should be found assertEquals(include, include1); assertNotNull(include2); } @Test public void findExternalIncludeFileOnIncludePath() throws Exception { File externalInclude = null; IErlProject project = null; // given // a project with an include dir outside the model try { final String projectName = "testprojectx"; project = ErlideTestUtils .createProject(ErlideTestUtils.getTmpPath(projectName), projectName); final String includeName = "x.hrl"; externalInclude = ErlideTestUtils.createTmpFile(includeName, "-record(rec2, {field, another=def}."); final String includePath = externalInclude.getAbsolutePath(); final IPath p = new Path(includePath).removeLastSegments(1); ((ErlProject) project).setIncludeDirs(Lists.newArrayList(p)); // when // looking for the include file // String includeFile = // ErlangEngine.getInstance().getModelUtilService().findIncludeFile(erlProject, // "x.hrl", ""); project.open(null); final IErlElementLocator model = ErlangEngine.getInstance().getModel(); final IErlModule module = model.findIncludeFromProject(project, null, includePath, IErlElementLocator.Scope.REFERENCED_PROJECTS); final IErlModule module2 = model.findModuleFromProject(project, includeName, null, IErlElementLocator.Scope.REFERENCED_PROJECTS); // then // it should be found in the model assertNotNull(module); assertEquals(module, module2); } finally { if (project != null) { ErlideTestUtils.deleteProject(project); } if (externalInclude != null && externalInclude.exists()) { externalInclude.delete(); } } } @Test public void findIncludeFileOnIncludePathInOtherProject() throws Exception { // http://www.assembla.com/spaces/erlide/tickets/756-navigation--external-include-files-are-not-found IErlModule externalInclude = null; IErlProject project = null, project2 = null; // given // a project with an include dir outside the model try { final String projectName = "testprojectx"; project = ErlideTestUtils .createProject(ErlideTestUtils.getTmpPath(projectName), projectName); final String projectName2 = "testprojecty"; project2 = ErlideTestUtils.createProject( ErlideTestUtils.getTmpPath(projectName2), projectName2); final String includeName = "x.hrl"; externalInclude = ErlideTestUtils.createInclude(project2, "x.hrl", "-record(rec2, {field, another=def}."); final String includePath = externalInclude.getFilePath(); final IPath p = new Path(includePath).removeLastSegments(1); ((ErlProject) project).setIncludeDirs(Lists.newArrayList(p)); // when // looking for the include file project.open(null); final IErlElementLocator model = ErlangEngine.getInstance().getModel(); final IErlModule module = model.findIncludeFromProject(project, includeName, null, IErlElementLocator.Scope.ALL_PROJECTS); // then // it should be found in the project defining it assertNotNull(module); assertEquals(project2, ErlangEngine.getInstance().getModelUtilService().getProject(module)); } finally { if (project != null) { ErlideTestUtils.deleteProject(project); } if (project2 != null) { ErlideTestUtils.deleteProject(project2); } } } @Test public void findFunctionInExternalFilesTest() throws Exception { // given // a module with calls to the lists module final IErlProject project = projects[0]; final IErlModule moduleE = ErlideTestUtils.createModule(project, "e.erl", "-module(e).\n-export([f/0]).\nf() ->\n lists:reverse([1, 0]),\n lists:reverse([1, 0], [2]).\n"); final ScannerService scanner = moduleE.getScanner(); try { moduleE.open(null); // when // looking for lists:reverse/2 and lists:reverse/1 final IErlModel model = ErlangEngine.getInstance().getModel(); final OpenResult res = ErlangEngine.getInstance() .getService(OpenService.class).open(moduleE.getScannerName(), 49, ErlangEngine.getInstance().getModelUtilService() .getImportsAsList(moduleE), project.getProperties().getExternalModules(), model.getPathVars()); final IErlFunction function = ErlangEngine.getInstance().getModelFindService() .findFunction(model, project, moduleE, res.getName(), res.getPath(), res.getFunction(), IErlElementLocator.Scope.PROJECT_ONLY); assertNotNull(function); final IErlElement module = model.findModuleFromProject(project, function.getModuleName(), res.getPath(), IErlElementLocator.Scope.PROJECT_ONLY); // then // the function should be returned and the module, in External Files assertNotNull(module); assertEquals(function.getParent(), module); assertEquals( ErlangEngine.getInstance().getModelUtilService().getProject(function), project); } finally { scanner.dispose(); } } @Test public void findExternalModule() throws Exception { File externalFile = null; IErlProject project = null; try { // given // an erlang project with an external file final String projectName = "testproject"; project = ErlideTestUtils.createTmpErlProject(projectName); final String externalFileName = "external.erl"; externalFile = ErlideTestUtils.createTmpFile(externalFileName, "-module(external).\nf([_ | _]=L ->\n atom_to_list(L).\n"); final String absolutePath = externalFile.getAbsolutePath(); final String externalsFileName = "x.erlidex"; final File externalsFile = ErlideTestUtils.createTmpFile(externalsFileName, absolutePath); ((ErlProject) project) .setExternalModulesFile(externalsFile.getAbsolutePath()); project.open(null); final IErlElementLocator model = ErlangEngine.getInstance().getModel(); // when // looking for it final IErlModule externalModule = model.findModuleFromProject(project, externalFileName, null, IErlElementLocator.Scope.PROJECT_ONLY); // then // we should find it assertNotNull(externalModule); assertTrue(FilePathUtils.equalFilePaths(absolutePath, externalModule.getFilePath(), EFS.getLocalFileSystem().isCaseSensitive())); } finally { if (externalFile != null && externalFile.exists()) { externalFile.delete(); } if (project != null) { ErlideTestUtils.deleteProject(project); } } } }