Package org.erlide.engine.util

Source Code of org.erlide.engine.util.ModelUtilsTests

package org.erlide.engine.util;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.Collection;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
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.IErlModel;
import org.erlide.engine.model.erlang.ErlangFunction;
import org.erlide.engine.model.erlang.IErlFunction;
import org.erlide.engine.model.erlang.IErlImport;
import org.erlide.engine.model.erlang.IErlModule;
import org.erlide.engine.model.erlang.IErlPreprocessorDef;
import org.erlide.engine.model.erlang.IErlRecordDef;
import org.erlide.engine.model.erlang.IErlTypespec;
import org.erlide.engine.model.root.ErlElementKind;
import org.erlide.engine.model.root.IErlElement;
import org.erlide.engine.model.root.IErlElementLocator;
import org.erlide.engine.model.root.IErlProject;
import org.erlide.engine.services.parsing.ScannerService;
import org.erlide.engine.services.search.ModelFindService;
import org.erlide.engine.services.search.ModelUtilService;
import org.erlide.testing.utils.WorkspaceTest;
import org.erlide.util.ErlLogger;
import org.erlide.util.SystemConfiguration;
import org.junit.Before;
import org.junit.Test;

import com.ericsson.otp.erlang.OtpErlangAtom;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangLong;
import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangTuple;
import com.google.common.collect.Lists;

public class ModelUtilsTests extends WorkspaceTest {

    private IErlProject project1;
    private IErlProject project2;

    @Before
    public void setup() throws Exception {
        setUpProject("testproject1");
        setUpProject("testproject2");
        project1 = getErlProject("testproject1");
        project2 = getErlProject("testproject2");

        modelUtilService = ErlangEngine.getInstance().getModelUtilService();
        modelFindService = ErlangEngine.getInstance().getModelFindService();
    }

    private ModelUtilService modelUtilService;
    private ModelFindService modelFindService;

    @Test
    public void getImportsAsListTest() throws Exception {
        // given
        // an Erlang module with imports
        final IErlModule moduleA = createModule(project1, "ax.erl",
                "-module(ax).\n-import(lists, [reverse/1, foldl/3].\n");
        moduleA.open(null);
        // when
        // fetching imports as list of OtpErlangTuple
        final Collection<IErlElement> children = moduleA.getChildren();
        final Collection<IErlImport> imports2 = moduleA.getImports();
        final List<OtpErlangObject> imports = modelUtilService.getImportsAsList(moduleA);
        // then
        // they should be returned
        assertEquals(2, children.size());
        assertEquals(1, imports2.size());
        assertEquals(1, imports.size());
        final OtpErlangAtom listAtom = new OtpErlangAtom("lists");
        assertEquals(new OtpErlangTuple(new OtpErlangObject[] {
                listAtom,
                new OtpErlangList(new OtpErlangObject[] { makeTuple2("reverse", 1),
                        makeTuple2("foldl", 3) }) }), imports.get(0));
    }

    @Test
    public void findExternalTypeTest() throws Exception {
        // given
        // an Erlang module with typedef
        final IErlModule moduleB = createModule(project1, "bx.erl",
                "-module(bx).\n-type concat_thing() :: atom() | integer() | float() | string().\n");
        // final IErlModule moduleC =
        // createErlModule(projects[1],
        // "c.erl", "-module(c).\n-type cc() :: b:concat_thing().\n");
        final ScannerService scanner = moduleB.getScanner();
        try {
            moduleB.open(null);
            project1.open(null);
            // moduleC.open(null);
            // when
            // looking for it
            // within project
            final IErlElementLocator model = ErlangEngine.getInstance().getModel();

            final IErlElement element1 = modelFindService.findTypeDef(model, project1,
                    moduleB, "bx", "concat_thing", moduleB.getResource().getLocation()
                            .toPortableString(), IErlElementLocator.Scope.PROJECT_ONLY);
            // in other project but path given
            final IErlElement element2 = modelFindService.findTypeDef(model, project2,
                    moduleB, "bx", "concat_thing", moduleB.getResource().getLocation()
                            .toPortableString(), IErlElementLocator.Scope.PROJECT_ONLY);
            // in other project no path given, search all projects true
            final IErlElement element3 = modelFindService.findTypeDef(model, project2,
                    moduleB, "bx", "concat_thing", null,
                    IErlElementLocator.Scope.ALL_PROJECTS);
            // in other project no path given, search all projects false, ->
            // null
            final IErlElement element4 = modelFindService.findTypeDef(model, project2,
                    moduleB, "bx", "concat_thing", null,
                    IErlElementLocator.Scope.PROJECT_ONLY);

            // then
            // it should be returned if found
            assertTrue(element1 instanceof IErlTypespec);
            assertNull(element2);
            assertTrue(element3 instanceof IErlTypespec);
            assertNull(element4);
        } finally {
            scanner.dispose();
        }
    }

    @Test
    public void findExternalFunctionModuleTest() throws Exception {
        // given
        // a module with functions and functions
        final IErlModule moduleD = createModule(project1, "d.erl",
                "-module(d).\n-export([f/0]).\nf() ->\n    ok.\ng() ->\n    ?MODULE:f().\n");
        moduleD.open(null);
        // when
        // looking for it with ?MODULE
        final IErlElementLocator model = ErlangEngine.getInstance().getModel();
        final IErlElement element1 = modelFindService.findFunction(model, project1,
                moduleD, "?MODULE", null, new ErlangFunction("f", 0),
                IErlElementLocator.Scope.PROJECT_ONLY);
        // then
        // it should be found
        assertTrue(element1 instanceof IErlFunction);
    }

    @Test
    public void findPreprocessorDefTest() throws Exception {
        // given
        // a module with includes and record
        final IErlProject project = project1;
        final IErlModule include = createInclude(project, "a.hrl",
                "-record(rec1, {field, another=def}).\n-define(MACRO(A), lists:reverse(A)).\n");
        final IErlModule module = 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);
        project.open(null);
        final IErlPreprocessorDef preprocessorDef1 = modelFindService
                .findPreprocessorDef(module, "rec1", ErlElementKind.RECORD_DEF);
        final IErlPreprocessorDef preprocessorDef2 = modelFindService
                .findPreprocessorDef(include, "rec1", ErlElementKind.RECORD_DEF);
        final IErlPreprocessorDef preprocessorDef3 = modelFindService
                .findPreprocessorDef(Lists.newArrayList(project1, project2), "f.erl",
                        "rec2", ErlElementKind.RECORD_DEF);
        // then
        // the record should be returned
        assertNotNull(module);
        assertNotNull(preprocessorDef1);
        assertTrue(preprocessorDef1 instanceof IErlRecordDef);
        assertEquals(preprocessorDef1, preprocessorDef2);
        assertEquals(preprocessorDef1.getParent(), include);
        assertNotNull(preprocessorDef3);
        assertEquals(preprocessorDef3.getParent(), module);
    }

    @Test
    public void findPreprocessorDefOtpIncludeTest() throws Exception {
        // given
        // a module with includes and record
        final IErlProject project = project1;
        final IErlModule module = createModule(
                project,
                "g.erl",
                "-module(g).\n-include_lib(\"kernel/include/file.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);
        // when
        // looking for the record
        final IErlPreprocessorDef preprocessorDef = modelFindService.findPreprocessorDef(
                module, "file_info", ErlElementKind.RECORD_DEF);
        // then
        // the record should be returned
        assertNotNull(module);
        assertNotNull(preprocessorDef);
        assertTrue(preprocessorDef instanceof IErlRecordDef);
        assertEquals(
                ErlangEngine.getInstance().getModelUtilService()
                        .getProject(preprocessorDef), project);
    }

    private OtpErlangTuple makeTuple2(final String functionName, final int arity) {
        return new OtpErlangTuple(new OtpErlangObject[] {
                new OtpErlangAtom(functionName), new OtpErlangLong(arity) });
    }

    @Test
    public void getPreprocessorDefs() throws Exception {
        final IErlProject project = project1;
        final IErlModule module = createModule(project, "a.erl", "-module(g).\n"
                + "-include_lib(\"kernel/include/file.hrl\").\n" + "-export([f/0]).\n"
                + "-define(A(B), '++B++').\n" + "-record(rec2, {a, b}).\n" + "f() ->\n"
                + "    lists:reverse([1, 0]),\n" + "    lists:reverse([1, 0], [2]).\n");
        module.open(null);
        final List<IErlPreprocessorDef> macroDefs = modelUtilService
                .getAllPreprocessorDefs(module, ErlElementKind.MACRO_DEF);
        final List<IErlPreprocessorDef> recordDefs = modelUtilService
                .getAllPreprocessorDefs(module, ErlElementKind.RECORD_DEF);
        assertEquals(2, macroDefs.size());
        assertEquals(3, recordDefs.size());
    }

    @Test
    public void getExternalModuleWithPrefix() throws Exception {
        File externalFile = null;
        IErlProject project = null;
        try {
            // given
            // an erlang project and an external file not in any project
            final String projectName = "testproject";
            project = createTmpErlProject(projectName);
            final String externalFileName = "external.erl";
            externalFile = 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 = createTmpFile(externalsFileName, absolutePath);
            ((ErlProject) project)
                    .setExternalModulesFile(externalsFile.getAbsolutePath());
            project.open(null);
            // when
            // looking via prefix
            final List<String> moduleNames0 = modelUtilService.findUnitsWithPrefix("ex",
                    project, false, false);
            final List<String> modules1 = modelUtilService.findUnitsWithPrefix("ex",
                    project, true, false);
            final List<String> listModules = modelUtilService.findUnitsWithPrefix("list",
                    project, true, false);
            // then
            // we should find it iff we check externals
            assertEquals(0, moduleNames0.size());
            assertEquals(1, modules1.size());
            assertEquals(SystemConfiguration.withoutExtension(externalFileName),
                    modules1.get(0));
            assertEquals(1, listModules.size());
            assertEquals("lists", listModules.get(0));
        } finally {
            if (externalFile != null && externalFile.exists()) {
                externalFile.delete();
            }
            if (project != null) {
                deleteProject(project);
            }
        }
    }

    @Test
    public void findExternalModuleFromPath() throws Exception {
        File externalFile = null;
        IErlProject project = null;
        try {
            // given
            // an erlang project and an external file not in any project
            final String projectName = "testproject";
            project = createTmpErlProject(projectName);
            final String externalFileName = "external1.erl";
            externalFile = createTmpFile(externalFileName,
                    "-module(external1).\nf([_ | _]=L ->\n    atom_to_list(L).\n");
            final String absolutePath = externalFile.getAbsolutePath();
            final String externalsFileName = "x.erlidex";
            final File externalsFile = createTmpFile(externalsFileName, absolutePath);
            ((ErlProject) project)
                    .setExternalModulesFile(externalsFile.getAbsolutePath());
            project.open(null);
            // when
            // looking for it
            final IErlElementLocator model = getModel();
            final IErlModule module = modelFindService.findModule(model, null, null,
                    absolutePath, IErlElementLocator.Scope.ALL_PROJECTS);
            // then
            // we should find it
            assertNotNull(module);
            assertEquals(externalFileName, module.getName());
        } finally {
            if (externalFile != null && externalFile.exists()) {
                externalFile.delete();
            }
            if (project != null) {
                deleteProject(project);
            }
        }
    }

    @Test
    public void findExternalIncludeFromPath() throws Exception {
        File externalFile = null;
        IErlProject project = null;
        try {
            // given
            // an erlang project and an external file not in any project
            final String projectName = "testproject";
            project = createTmpErlProject(projectName);
            final String externalFileName = "external.hrl";
            externalFile = 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 = createTmpFile(externalsFileName, absolutePath);
            ((ErlProject) project).setExternalIncludesFile(externalsFile
                    .getAbsolutePath());
            project.open(null);
            // when
            // looking for it
            final IErlElementLocator model = ErlangEngine.getInstance().getModel();
            final IErlModule module = modelFindService.findInclude(model, project, null,
                    externalFileName, absolutePath);
            // then
            // we should find it
            assertNotNull(module);
            assertEquals(externalFileName, module.getName());
        } finally {
            if (externalFile != null && externalFile.exists()) {
                externalFile.delete();
            }
            if (project != null) {
                deleteProject(project);
            }
        }
    }

    @Test
    public void getModulesWithReferencedProjectsWithPrefix() throws Exception {
        // given
        // two erlang projects, the first references the second, second has
        // an erlang module
        final IProject project = project1.getWorkspaceProject();
        final IProjectDescription description = project.getDescription();
        final IProject[] refs = new IProject[] { project2.getWorkspaceProject() };
        description.setReferencedProjects(refs);
        project.setDescription(description, null);
        final IErlModule module = createModule(project2, "abc.erl",
                "-module(abc).\n-export(f/0)\nf() ->\n   {abc, ok}.\n");
        createModule(project1, "bbc.erl",
                "-module(bbc).\n-export(f/0)\nf() ->\n   {abc, ok}.\n");
        // when
        // looking for module with prefix, it should be found
        final List<String> moduleNames = modelUtilService.findUnitsWithPrefix("a",
                project1, false, false);
        // then
        // we should find it
        assertNotNull(moduleNames);
        assertEquals(1, moduleNames.size());
        assertEquals(module.getModuleName(), moduleNames.get(0));
    }

    @Test
    public void getModuleFromExternalModulePath() throws Exception {
        File externalFile = null;
        IErlProject project = null;
        try {
            // given
            // an erlang project and an external file not in any project
            final String projectName = "testproject";
            project = createTmpErlProject(projectName);
            final String externalFileName = "external2.erl";
            externalFile = createTmpFile(externalFileName,
                    "-module(external2).\nf([_ | _]=L ->\n    atom_to_list(L).\n");
            final String absolutePath = externalFile.getAbsolutePath();
            final String externalsFileName = "x.erlidex";
            final File externalsFile = createTmpFile(externalsFileName, absolutePath);
            ((ErlProject) project)
                    .setExternalModulesFile(externalsFile.getAbsolutePath());
            project.open(null);
            // when
            // looking for it with its external module path
            final IErlModel model = ErlangEngine.getInstance().getModel();
            final IErlModule module = modelFindService.findModule(model, null, null,
                    absolutePath, IErlElementLocator.Scope.ALL_PROJECTS);
            assertNotNull(module);
            final String externalModulePath = ErlangEngine.getInstance()
                    .getModelUtilService().getExternalModulePath(module);
            ErlLogger.debug(" >> %s", externalModulePath);
            final IErlModule module2 = modelUtilService.getModuleFromExternalModulePath(
                    model, externalModulePath);
            // then
            // we should find it
            assertNotNull(module2);
            assertEquals(externalFileName, module.getName());
            assertEquals(module, module2);
        } finally {
            if (externalFile != null && externalFile.exists()) {
                externalFile.delete();
            }
            if (project != null) {
                deleteProject(project);
            }
        }
    }

    @Test
    public void findTypespec() throws Exception {
        // given
        // a project with a module and an include with a typespec
        final IErlProject project = project1;
        final String includeName = "a.hrl";
        final IErlModule include = createModule(project, includeName,
                "-type date() :: {pos_integer(), pos_integer(), pos_integer()}.\n");
        include.open(null);
        final IErlModule module = 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);
        // when
        // looking for the typespec
        final IErlTypespec typespec = modelFindService.findTypespec(module, "date");
        // then
        // it should be found
        assertNotNull(typespec);
        assertEquals(typespec.getParent(), include);
    }

    @Test
    public void findPreprocessorDefExternalIncludeOnIncludePathTest() throws Exception {
        File externalInclude = null;
        IErlProject project = null;
        // given
        // a project with an include dir outside the model, the include file
        // contains a record def
        try {
            // ErlModelCache.getDefault().setNoModelCache(true);
            // ErlModelCache.getDefault().clearModelCache();
            final String projectName = "testprojectx";
            project = createProject(projectName, getTmpPath(projectName));
            final IErlModule module = createModule(project, "a.erl",
                    "-include(\"x.hrl\").\n");
            final String includeName = "x.hrl";
            externalInclude = 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));
            project.open(null);
            // when
            // looking for the record def
            final IErlPreprocessorDef preprocessorDef = modelFindService
                    .findPreprocessorDef(module, "rec2", ErlElementKind.RECORD_DEF);
            final Collection<IErlProject> myprojects = Lists.newArrayList(project);
            ErlangEngine
                    .getInstance()
                    .getModelFindService()
                    .findPreprocessorDef(myprojects, "a.erl", "rec2",
                            ErlElementKind.RECORD_DEF);
            // then
            // it should be found
            assertNotNull(preprocessorDef);
        } finally {
            if (project != null) {
                deleteProject(project);
            }
            if (externalInclude != null && externalInclude.exists()) {
                externalInclude.delete();
            }
            // ErlModelCache.getDefault().setNoModelCache(false);
        }
    }

    @Test
    public void findPreprocessorDefExternalIncludePathTest() throws Exception {
        File externalInclude = null;
        IErlProject project = null;
        // given
        // a project with an include dir outside the model, the include file
        // contains a record def
        try {
            final String projectName = "testprojectx";
            project = createProject(projectName, getTmpPath(projectName));
            final IErlModule module = createModule(project, "a.erl",
                    "-include(\"x.hrl\").\n");
            final String includeName = "x.hrl";
            externalInclude = createTmpFile(includeName,
                    "-record(rec2, {field, another=def}.");
            final String includePath = externalInclude.getAbsolutePath();
            final String externalsFileName = "x.erlidex";
            final File externalsFile = createTmpFile(externalsFileName, includePath);
            ((ErlProject) project).setExternalIncludesFile(externalsFile
                    .getAbsolutePath());
            project.open(null);
            // when
            // looking for the record def
            final IErlPreprocessorDef preprocessorDef = modelFindService
                    .findPreprocessorDef(module, "rec2", ErlElementKind.RECORD_DEF);
            final Collection<IErlProject> myprojects = Lists.newArrayList(project);
            modelFindService.findPreprocessorDef(myprojects, "a.erl", "rec2",
                    ErlElementKind.RECORD_DEF);
            // then
            // it should be found
            assertNotNull(preprocessorDef);
        } finally {
            if (project != null) {
                deleteProject(project);
            }
            if (externalInclude != null && externalInclude.exists()) {
                externalInclude.delete();
            }
        }
    }

}
TOP

Related Classes of org.erlide.engine.util.ModelUtilsTests

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.