/* $Id: TestStateBodyNotationUml.java 18978 2011-01-24 18:25:30Z linus $ ***************************************************************************** * Copyright (c) 2009 Contributors - see below * 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: * mvw ***************************************************************************** * * Some portions of this file was previously release using the BSD License: */ // Copyright (c) 2004-2008 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph appear in all copies. This software program and // documentation are copyrighted by The Regents of the University of // California. The software program and documentation are supplied "AS // IS", without any accompanying services from The Regents. The Regents // does not warrant that the operation of the program will be // uninterrupted or error-free. The end-user understands that the program // was developed for research purposes and is advised not to rely // exclusively on the program for any reason. IN NO EVENT SHALL THE // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. package org.argouml.notation.providers.uml; import java.text.ParseException; import java.util.Collection; import junit.framework.TestCase; import org.argouml.kernel.ProjectManager; import org.argouml.model.InitializeModel; import org.argouml.model.Model; import org.argouml.profile.ProfileFacade; import org.argouml.profile.init.InitProfileSubsystem; /** * Test StateBodyNotationUml (formerly ParserDisplay): parsing state body. * * @author Michiel */ public class TestStateBodyNotationUml extends TestCase { private Object aClass; private Object aStateMachine; private Object aState; /** * The constructor. * * @param str the name */ public TestStateBodyNotationUml(String str) { super(str); InitializeModel.initializeDefault(); } /* * @see junit.framework.TestCase#setUp() */ protected void setUp() { InitializeModel.initializeDefault(); assertTrue("Model subsystem init failed.", Model.isInitiated()); new InitProfileSubsystem().init(); Object model = Model.getModelManagementFactory().createModel(); ProjectManager.getManager().makeEmptyProject(true); aClass = Model.getCoreFactory().buildClass(model); Object returnType = null; Model.getCoreFactory().buildOperation2(aClass, returnType, "myOper"); aStateMachine = Model.getStateMachinesFactory().buildStateMachine(aClass); Object top = Model.getFacade().getTop(aStateMachine); aState = Model.getStateMachinesFactory().buildCompositeState(top); } @Override protected void tearDown() throws Exception { ProjectManager.getManager().removeProject( ProjectManager.getManager().getCurrentProject()); ProfileFacade.reset(); super.tearDown(); } /** * Test the parseStateBody() method: succesful creation. */ public final void testParseStateBodyCreateIndividually() { checkGenerated(aState, "", false, false, false, 0, false); checkGenerated(aState, "entry/test6", true, false, false, 0, false); checkGenerated(aState, "exit/test7", false, true, false, 0, false); checkGenerated(aState, "do/test8", false, false, true, 0, false); checkGenerated(aState, "test9", //this is not a very useful transition false, false, false, 1, false); } /** * Test the parseStateBody() method: succesful creation. */ public final void testParseStateBodyCreateCombined() { /* One of everything */ checkGenerated(aState, "entry/test1\nexit/b\ndo/it\ninternal/activity", true, true, true, 1, false); /* Upper / Lower case */ checkGenerated(aState, "\n\nEntry/a\n\nExit/b\n\nDo/it\n\n\n", true, true, true, 0, false); /* Mixed case */ checkGenerated(aState, "ENTRY/test2\nexIT/b\nDO/it", true, true, true, 0, false); /* A complex internal transition */ checkGenerated(aState, "internal(test3:int=5,b=4.0:float)[g]/" + "activity(params, p),act(ee);", false, false, false, 1, false); /* These are NOT entry/exit/do activities! */ checkGenerated(aState, "entrys/test4\nexiting/b\ndone/it", false, false, false, 3, false); /* Long list of internals */ checkGenerated(aState, "a/a\nb/b\nc/c\nd/d\ne/e\nf/f\ng/g\nh/h\ni/i\nj/j\n" + "k/a\nl/b\nm/c\nn/d\no/e\np/f\nq/g\nr/h\ns/i\nt/j", false, false, false, 20, false); } /** * Test the parseStateBody() method: syntax errors. */ public final void testParseStateBodySyntaxError() { checkGenerated(aState, "do[a/b]test10", false, false, false, 1, true); // or should the 1 be 0 ? } /** * Test the parseStateBody() method: changing the signature. */ public final void testParseStateBodyRemove() { Object st; st = checkGenerated(aState, "entry/test1\nexit/b\ndo/it\ninternal/activity", true, true, true, 1, false); checkChanged(st, "", // deleting it all false, false, false, 0, false); st = checkGenerated(aState, "int1/act1\nexit/test2\nint2/act2\ndo/b\nentry/it", true, true, true, 2, false); checkChanged(st, // changing the sequence only "entry/it\nexit/test2\ndo/b\nint1/act1\nint2/act2", true, true, true, 2, false); } /** * Test the parseStateBody() method: changing the signature. */ public final void testParseStateBodyRemoveInternals() { Object st; st = checkGenerated(aState, "int1/act1\nint2/act2\nint3/act3\nint4/act4\nint5/act5", false, false, false, 5, false); checkChanged(st, "int1/act1\nint5/act5\nint4/act4", false, false, false, 3, false); checkChanged(st, "int5/act5\nint4/act4", false, false, false, 2, false); checkChanged(st, "int6/act6\nint4/act4", false, false, false, 2, false); } /** * Check if the elements are generated or not. * * @param st the parent state in which a sub-state is to be created * @param text the text to be parsed * @param entryAction true if an entry action is expected to be created * @param exitAction true if an exit action is expected to be created * @param doAction true if an do activity is expected to be created * @param internals the number of internal transitions * expected to be created * @param exception true if there is a syntax error * and an exception is expected * @return the internal state in which elements are created */ private Object checkGenerated(Object st, String text, boolean entryAction, boolean exitAction, boolean doAction, int internals, boolean exception) { Object sst = Model.getStateMachinesFactory().buildSimpleState(st); checkChanged(sst, text, entryAction, exitAction, doAction, internals, exception); return sst; } /** * Check if the elements are changed or not. * * @param sst the state to test * @param text the text to be parsed * @param entryAction true if an entry action is expected to be created * @param exitAction true if an exit action is expected to be created * @param doAction true if an do activity is expected to be created * @param internals the number of internal transitions * expected to be created * @param exception true if there is a syntax error * and an exception is expected */ private void checkChanged(Object sst, String text, boolean entryAction, boolean exitAction, boolean doAction, int internals, boolean exception) { try { StateBodyNotationUml sbn = new StateBodyNotationUml(sst); sbn.parseStateBody(sst, text); assertTrue("Expected exception did not happen.", !exception); } catch (ParseException e) { assertTrue("Unexpected exception for " + text, exception); } if (entryAction) { assertTrue("Entry Action was not generated for " + text, Model.getFacade().getEntry(sst) != null); } else { assertTrue("Entry Action was generated for " + text, Model.getFacade().getEntry(sst) == null); } if (exitAction) { assertTrue("Exit Action was not generated for " + text, Model.getFacade().getExit(sst) != null); } else { assertTrue("Exit Action was generated for " + text, Model.getFacade().getExit(sst) == null); } if (doAction) { assertTrue("Do Action was not generated for " + text, Model.getFacade().getDoActivity(sst) != null); } else { assertTrue("Do Action was generated for " + text, Model.getFacade().getDoActivity(sst) == null); } Collection c = Model.getFacade().getInternalTransitions(sst); assertTrue("Incorrect number of internal transitions (" + c.size() + ") found for " + text, c.size() == internals); } /** * Test if help is correctly provided. */ public void testGetHelp() { StateBodyNotationUml notation = new StateBodyNotationUml(aState); String help = notation.getParsingHelp(); assertTrue("No help at all given", help.length() > 0); assertTrue("Parsing help not conform for translation", help.startsWith("parsing.")); } /** * Test if the notationProvider refuses to instantiate * without showing it the right UML element. */ public void testValidObjectCheck() { try { new StateBodyNotationUml(aClass); fail("The NotationProvider did not throw for a wrong UML element."); } catch (IllegalArgumentException e) { /* Everything fine... */ } } }