source: trunk/org.modelica.mdt.test/src/org/modelica/mdt/test/TestModelicaRoot.java @ 322

Last change on this file since 322 was 317, checked in by boris, 19 years ago
  • changed code to compute actual region of a component/class instead of first line as it was before
  • implemented a mechanism to look up the class definition at a certain location in a modelica source file
File size: 15.5 KB
Line 
1/*
2 * This file is part of Modelica Development Tooling.
3 *
4 * Copyright (c) 2005, Link�pings universitet, Department of
5 * Computer and Information Science, PELAB
6 *
7 * All rights reserved.
8 *
9 * (The new BSD license, see also
10 * http://www.opensource.org/licenses/bsd-license.php)
11 *
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are
15 * met:
16 *
17 * * Redistributions of source code must retain the above copyright
18 *   notice, this list of conditions and the following disclaimer.
19 *
20 * * Redistributions in binary form must reproduce the above copyright
21 *   notice, this list of conditions and the following disclaimer in
22 *   the documentation and/or other materials provided with the
23 *   distribution.
24 *
25 * * Neither the name of Link�pings universitet nor the names of its
26 *   contributors may be used to endorse or promote products derived from
27 *   this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
42package org.modelica.mdt.test;
43
44import java.util.Collection;
45import java.util.Collections;
46import java.util.Vector;
47
48import org.eclipse.core.resources.IFile;
49import org.eclipse.core.resources.IFolder;
50import org.eclipse.core.resources.IProject;
51import org.eclipse.core.resources.ResourcesPlugin;
52import org.eclipse.core.runtime.CoreException;
53import org.eclipse.core.runtime.Path;
54import org.eclipse.core.resources.IWorkspaceRoot;
55
56import org.modelica.mdt.core.IModelicaClass;
57import org.modelica.mdt.core.IModelicaElement;
58import org.modelica.mdt.core.IModelicaElementChange;
59import org.modelica.mdt.core.IModelicaElementChangeListener;
60import org.modelica.mdt.core.IModelicaFolder;
61import org.modelica.mdt.core.IModelicaProject;
62import org.modelica.mdt.core.IModelicaRoot;
63import org.modelica.mdt.core.ModelicaCore;
64import org.modelica.mdt.core.compiler.CompilerInstantiationException;
65import org.modelica.mdt.core.compiler.ConnectException;
66import org.modelica.mdt.core.compiler.InvocationError;
67import org.modelica.mdt.core.compiler.UnexpectedReplyException;
68import org.modelica.mdt.internal.core.CorePlugin;
69import org.modelica.mdt.test.util.Area51Projects;
70import org.modelica.mdt.test.util.Utility;
71
72import junit.framework.TestCase;
73
74/**
75 * @author Elmir Jagudin
76 */
77public class TestModelicaRoot extends TestCase
78{
79
80    /* this flags are set from the workspace change listener */
81    private boolean simpleProjectAdded     = false;
82    private boolean modelicaProjectAdded   = false;
83    private boolean simpleProjectRemoved   = false;
84    private boolean modelicaProjectRemoved = false;
85
86   
87    public class WorkspaceChangesListener 
88            implements IModelicaElementChangeListener
89    {
90
91        public void elementsChanged(Collection<IModelicaElementChange> changes) 
92        {
93            for (IModelicaElementChange change : changes)
94            {
95                Object res = change.getElement();
96                if (!(res instanceof IModelicaProject))
97                {
98                    /* we are only interested in changes on projects */
99                    break;
100                }
101                IModelicaProject proj = (IModelicaProject)res;
102               
103                switch (change.getChangeType())
104                {
105                case ADDED:
106                    if (proj.getElementName().equals(PROJECT_NAME_SIM_EXTRA))
107                    {
108                        simpleProjectAdded = true;
109                    }
110                    else if (proj.getElementName().equals(PROJECT_NAME_MOD_EXTRA))
111                    {
112                        modelicaProjectAdded = true;
113                    }
114
115                    break;
116                case REMOVED:
117                    if (proj.getElementName().equals(PROJECT_NAME_SIM_EXTRA))
118                    {
119                        simpleProjectRemoved = true;
120                    }
121                    else if (proj.getElementName().equals(PROJECT_NAME_MOD_EXTRA))
122                    {
123                        modelicaProjectRemoved = true;
124                    }
125                }
126            }
127        }
128    }
129
130    /* this flag is set from folder to package morph detector */
131    private boolean morphedToPackage = false;
132   
133    /**
134     * This class detect when the MORPH_FOLDER folder have morped into
135     * a package by listening to modelica change events.
136     *
137     * To engage this class register it as a listener with modelica root. When
138     * the morph is detected the morphedToPackage flag is set.
139     */
140    public class FolderToPackageMorphDetector 
141        implements IModelicaElementChangeListener
142    {
143        private boolean folderRemoved = false;
144        private boolean packageAdded = false;
145
146        public void elementsChanged(Collection<IModelicaElementChange> changes) 
147        {
148            for (IModelicaElementChange ch : changes)
149            {
150                IModelicaElement element = ch.getElement();
151               
152                if (element.getElementName().equals(MORPH_FOLDER))
153                {
154                    /*
155                     * we are waiting for a removed event for the
156                     * folder event and added event for the package object
157                     */
158                    switch(ch.getChangeType())
159                    {
160                    case REMOVED:
161                        folderRemoved = true;
162                        break;
163                    case ADDED:
164                        assertTrue("element morphed into something wierd",
165                                element instanceof IModelicaClass);
166                        packageAdded = true;
167                        break;
168                    }
169                   
170                    /*
171                     * when both removed and added events recieved we know
172                     * that the folder have morphed
173                     */
174                    morphedToPackage = (folderRemoved && packageAdded);
175                }
176            }
177        }
178    }
179
180    /* this flag is set from folder to package morph detector */
181    private boolean morphedToFolder = false;
182   
183    /**
184     * This class detect when the MORPH_FOLDER package have morped back into
185     * a folder by listening to modelica change events.
186     *
187     * To engage this class register it as a listener with modelica root. When
188     * the morph is detected the morphedToFolder flag is set.
189     */
190    public class PackageToFolderMorphDetector 
191        implements IModelicaElementChangeListener
192    {
193        private boolean packageRemoved = false;
194        private boolean folderAdded = false;
195
196        public void elementsChanged(Collection<IModelicaElementChange> changes) 
197        {
198            for (IModelicaElementChange ch : changes)
199            {
200                IModelicaElement element = ch.getElement();
201               
202                if (element.getElementName().equals(MORPH_FOLDER))
203                {
204                    /*
205                     * we are waiting for a removed event for the
206                     * folder event and added event for the package object
207                     */
208                    switch(ch.getChangeType())
209                    {
210                    case REMOVED:
211                        packageRemoved = true;
212                        break;
213                    case ADDED:
214                        assertTrue("element morphed into something wierd",
215                                element instanceof IModelicaFolder);
216                        folderAdded = true;
217                        break;
218                    }
219                   
220                    /*
221                     * when both removed and added events recieved we know
222                     * that the folder have morphed
223                     */
224                    morphedToFolder = (packageRemoved && folderAdded);
225                }
226            }
227        }
228    }
229       
230   
231    /* names of modelica projects */
232    private Vector<String> modelicaProjects = new Vector<String>(2);
233   
234    /* names of simple (no modelica) projects */
235    private Vector<String> simpleProjects = new Vector<String>(2);
236   
237    private static final String PROJECT_NAME_1 = 
238        TestModelicaRoot.class.getName() + "1";
239    private static final String PROJECT_NAME_2 = 
240        TestModelicaRoot.class.getName() + "2";
241    private static final String PROJECT_NAME_3 = 
242        TestModelicaRoot.class.getName() + "3";
243   
244    private static final String MORPH_FOLDER = "morph_folder";
245   
246    /* the SIMple project which is added and removed */
247    private static final String PROJECT_NAME_SIM_EXTRA = 
248        TestModelicaRoot.class.getName() + "_SIM";
249
250    /* the MODelica project which is added and removed */
251    private static final String PROJECT_NAME_MOD_EXTRA = 
252        TestModelicaRoot.class.getName() + "_MOD";
253
254    /* name of a non existent project */
255    private static final String PROJECT_NAME_NON_EXISTENT = 
256        TestModelicaRoot.class.getName() + "_NON_EXISTENT";
257
258   
259    private IWorkspaceRoot workspaceRoot = 
260            ResourcesPlugin.getWorkspace().getRoot();   
261    private IModelicaRoot modelicaRoot = 
262            ModelicaCore.getModelicaRoot();
263   
264    private IFolder morphFolder = null;
265
266   
267    @Override
268    protected void setUp() throws CoreException
269    {
270        Area51Projects.createProjects();
271
272        /*
273         * create a modelica project
274         */
275        IProject project = workspaceRoot.getProject(PROJECT_NAME_1);
276        if (!project.exists())
277        {
278            IModelicaProject moProj =
279                ModelicaCore.getModelicaRoot().createProject(PROJECT_NAME_1); 
280            assertNotNull("failed to create project", moProj);
281            project = moProj.getProject();
282            /*
283             * create the folder that will be morphed to a package and then
284             * back to folder (se testMorphing())
285             */
286            IFolder folder = project.getFolder(new Path(MORPH_FOLDER));
287            folder.create(false, true, null);
288           
289        }
290        morphFolder = project.getFolder(new Path(MORPH_FOLDER));
291       
292        /*
293         * create a regular projects
294         */
295        project = workspaceRoot.getProject(PROJECT_NAME_2);
296        if (!project.exists())
297        {
298            project.create(null);
299            project.open(null);
300        }
301       
302        /*
303         * create a regular projects which remains closed
304         */
305        project = workspaceRoot.getProject(PROJECT_NAME_3);
306        if (!project.exists())
307        {
308            project.create(null);
309        }
310
311        assertTrue(Collections.addAll(modelicaProjects,
312                PROJECT_NAME_1));
313       
314        assertTrue(Collections.addAll(simpleProjects,
315                PROJECT_NAME_2, PROJECT_NAME_3));
316
317
318    }
319   
320    /**
321     * Test if IModelicaRoot.getProjects() (implemented by ModelicaRoot)
322     * works as prescribed.
323     */
324    public void testGetProjects() throws CoreException
325    {
326 
327        IModelicaProject mproj;
328        for (Object p : modelicaRoot.getProjects())
329        {
330            mproj = (IModelicaProject)p;
331
332            if (modelicaProjects.contains(mproj.getElementName()))
333            {
334                if (mproj.getProject().isOpen())
335                {
336                    assertTrue("project without modelica nature wrapped",
337                        ((IModelicaProject)p).getProject().
338                        hasNature(CorePlugin.MODELICA_NATURE));
339                }
340            }
341            else if (simpleProjects.contains(mproj.getElementName()))
342            {
343                if (mproj.getProject().isOpen())
344                {
345                    assertFalse("project with modelica nature not wrapped",
346                        mproj.getProject().hasNature(CorePlugin.MODELICA_NATURE));
347                }
348            }
349        }
350    }
351   
352    /**
353     * Test if IModelicaRoot.getProject() (implemented by ModelicaRoot)
354     * works as prescribed.
355     */
356    public void testGetProject()
357    {
358        IModelicaProject proj;
359       
360        proj = modelicaRoot.getProject(PROJECT_NAME_1);
361        assertEquals(PROJECT_NAME_1, proj.getElementName());
362       
363        proj = modelicaRoot.getProject(PROJECT_NAME_3);
364        assertEquals(PROJECT_NAME_3, proj.getElementName());
365
366        proj = modelicaRoot.getProject(PROJECT_NAME_2);
367        assertEquals(PROJECT_NAME_2, proj.getElementName());
368       
369        proj = modelicaRoot.getProject(PROJECT_NAME_NON_EXISTENT);
370        assertNull("hmm, an non-existent project found?", proj);
371    }
372   
373   
374    /**
375     * Test adding and removing projects to the workspace and check
376     * if ModelicaRoot picks up the changes.
377     */
378    public void testChangesToWorkspace() throws CoreException
379    {
380        ModelicaCore.getModelicaRoot().
381            addModelicaElementChangeListener(new WorkspaceChangesListener());
382       
383        /*
384         * check if ModelicaRoot picks up additions of projects
385         */
386        IProject simpleProject = 
387            workspaceRoot.getProject(PROJECT_NAME_SIM_EXTRA);
388        simpleProject.create(null);
389        simpleProject.open(null);
390       
391        IProject modelicaProject = 
392            ModelicaCore.getModelicaRoot().
393                createProject(PROJECT_NAME_MOD_EXTRA).getProject();
394        modelicaProject.open(null);
395
396       
397        /* wait for the changes to kick throug */
398        while (!simpleProjectAdded && !modelicaProjectAdded)
399        {
400            Utility.sleep(this, 105);
401        }
402       
403        boolean simpleProjFound = false;
404        boolean modelicaProjFound = false;
405
406        for (Object proj : modelicaRoot.getProjects())
407        {
408            if (proj instanceof IModelicaProject)
409            {
410                String name = ((IModelicaProject)proj).getElementName();
411
412                if (name.equals(PROJECT_NAME_MOD_EXTRA))
413                {
414                    modelicaProjFound = true;
415                }
416                else if (name.equals(PROJECT_NAME_SIM_EXTRA))
417                {
418                    simpleProjFound = true;
419                }
420            }
421        }       
422        assertTrue("ModelicaRoot did not pick up addition of " + 
423                PROJECT_NAME_SIM_EXTRA, simpleProjFound);
424       
425        assertTrue("ModelicaRoot did not pick up addition of " + 
426                PROJECT_NAME_MOD_EXTRA, modelicaProjFound);
427
428        /* check if ModelicaRoot picks up removal of a project */
429        simpleProject.delete(true, true, null);
430        modelicaProject.delete(true, true, null);
431       
432        /* wait for the changes to kick throug */
433        while (!simpleProjectRemoved && !modelicaProjectRemoved)
434        {
435            Utility.sleep(this, 97);
436        }
437
438        for (Object proj : modelicaRoot.getProjects())
439        {
440            if (proj instanceof IModelicaProject)
441            {
442                String name = ((IModelicaProject)proj).getElementName();
443
444                if (name.equals(PROJECT_NAME_MOD_EXTRA))
445                {
446                    fail("ModelicaRoot did not pick up removal of " +
447                            PROJECT_NAME_MOD_EXTRA);
448                }
449                else if (name.equals(PROJECT_NAME_SIM_EXTRA))
450                {
451                    fail("ModelicaRoot did not pick up removal of " +
452                            PROJECT_NAME_SIM_EXTRA);
453                }
454            }
455        }
456    }
457   
458    /**
459     * test that a IModelicaFolder changes to an IModelicaPackage
460     * when a package.mo with correct contents is added to it and
461     * that IModelicaPackage turns back to IModelicaFolder when
462     * the package.mo is removed
463     */
464    public void testMorphing() 
465        throws CoreException, ConnectException, UnexpectedReplyException,
466            InvocationError, CompilerInstantiationException
467    {
468        /* we need to make sure that the folder we are going to morph is loaded */
469        Utility.getProject(PROJECT_NAME_1).getRootFolder().getChildren();
470       
471        /*
472         * check if folder will morph into a package when the package.mo
473         * file is added
474         */
475        IModelicaElementChangeListener listener =
476            new FolderToPackageMorphDetector();
477           
478        ModelicaCore.getModelicaRoot().addModelicaElementChangeListener
479            (listener);
480        IFile file = morphFolder.getFile("package.mo");
481       
482        String contents = 
483            "package " + MORPH_FOLDER + "\n" +
484            "\n" +
485            "end " + MORPH_FOLDER + ";";
486       
487        file.create(Utility.getByteStream(contents), true, null);
488       
489       
490        /* wait tops 7 seconds for the morph to kick in */
491        long waitUntil = System.currentTimeMillis() + 7000;
492        while ((!morphedToPackage) && waitUntil > System.currentTimeMillis())
493        {
494            Utility.sleep(this, 100);
495        }
496       
497        ModelicaCore.getModelicaRoot().
498            removeModelicaElementChangeListener(listener);
499        assertTrue("the folder didn't morph into package, waited for the"+
500                " change around 7 seconds", morphedToPackage); 
501
502        /*
503         * check if package will morph into a folder when the package.mo
504         * file is removed
505         */
506
507        listener =  new PackageToFolderMorphDetector();
508           
509        ModelicaCore.getModelicaRoot().addModelicaElementChangeListener
510            (listener);
511        file.delete(true, false, null);
512       
513        /* wait tops 7 seconds for the morph to kick in */
514        waitUntil = System.currentTimeMillis() + 7000;
515        while ((!morphedToFolder) && waitUntil > System.currentTimeMillis())
516        {
517            Utility.sleep(this, 100);
518        }
519       
520        ModelicaCore.getModelicaRoot().
521            removeModelicaElementChangeListener(listener);
522        assertTrue("the package didn't morph into folder, waited for the"+
523                " change around 7 seconds", morphedToFolder); 
524
525    }
526}
Note: See TracBrowser for help on using the repository browser.