| /* |
| * Copyright (c) 2013 CEA and others. |
| * 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: |
| * Christian W. Damus (CEA) - initial API and implementation |
| */ |
| package org.eclipse.uml2.uml.validation.tests; |
| |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| import junit.framework.Test; |
| import junit.framework.TestCase; |
| import junit.framework.TestSuite; |
| |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.validation.service.ITraversalStrategy; |
| import org.eclipse.uml2.uml.Class; |
| import org.eclipse.uml2.uml.Element; |
| import org.eclipse.uml2.uml.Package; |
| import org.eclipse.uml2.uml.Profile; |
| import org.eclipse.uml2.uml.Stereotype; |
| import org.eclipse.uml2.uml.UMLFactory; |
| import org.eclipse.uml2.uml.UMLPackage; |
| import org.eclipse.uml2.uml.resource.UMLResource; |
| import org.eclipse.uml2.uml.tests.util.StandaloneSupport; |
| import org.eclipse.uml2.uml.util.UMLUtil; |
| import org.eclipse.uml2.uml.validation.UMLTraversalStrategy; |
| |
| /** |
| * Test suite for the {@link UMLTraversalStrategy} class and attendant classes. |
| */ |
| public class UMLTraversalStrategyTest |
| extends TestCase { |
| |
| private ITraversalStrategy fixture; |
| |
| private Package model; |
| |
| private Class utils; |
| |
| /** |
| * Initializes me with my name. |
| * |
| * @param name |
| * my name |
| */ |
| public UMLTraversalStrategyTest(String name) { |
| super(name); |
| } |
| |
| public static Test suite() { |
| return new TestSuite(UMLTraversalStrategyTest.class, |
| "UML traversal strategy tests"); //$NON-NLS-1$ |
| } |
| |
| public void testTraversalCoversStereotypesFromRootPackage() { |
| assertTraversal(model, new Element[]{model, utils}); |
| } |
| |
| public void testTraversalCoversStereotypesFromNestedElement() { |
| assertTraversal(utils, new Element[]{utils}, new Element[]{model}); |
| } |
| |
| public void testTraversalCoversStereotypesFromRootNonPackage() { |
| // make the Utils class a root |
| EcoreUtil.remove(utils); |
| model.eResource().getContents().add(utils); |
| |
| assertTraversal(utils, new Element[]{utils}, new Element[]{model}); |
| } |
| |
| // |
| // Test framework |
| // |
| |
| @Override |
| protected void setUp() |
| throws Exception { |
| super.setUp(); |
| |
| fixture = new UMLTraversalStrategy(); |
| |
| ResourceSet rset = new ResourceSetImpl(); |
| if (StandaloneSupport.isStandalone()) { |
| StandaloneSupport.init(rset); |
| } |
| |
| Resource res = rset.createResource(URI.createURI("bogus:///model.uml")); |
| model = UMLFactory.eINSTANCE.createPackage(); |
| model.setName("model"); |
| res.getContents().add(model); |
| |
| Profile profile = (Profile) UMLUtil.load(rset, |
| URI.createURI(UMLResource.STANDARD_L2_PROFILE_URI), |
| UMLPackage.Literals.PROFILE); |
| |
| model.applyProfile(profile); |
| model.applyStereotype(profile.getOwnedStereotype("ModelLibrary")); |
| |
| utils = model.createOwnedClass("Utils", false); |
| utils.applyStereotype(profile.getOwnedStereotype("Utility")); |
| utils |
| .applyStereotype(profile.getOwnedStereotype("ImplementationClass")); |
| } |
| |
| @Override |
| protected void tearDown() |
| throws Exception { |
| |
| ResourceSet rset = model.eResource().getResourceSet(); |
| for (Resource next : rset.getResources()) { |
| next.unload(); |
| } |
| rset.getResources().clear(); |
| rset.eAdapters().clear(); |
| |
| model = null; |
| fixture = null; |
| |
| super.tearDown(); |
| } |
| |
| EObject requireApplication(Element element, Stereotype stereotype) { |
| EObject result = element.getStereotypeApplication(stereotype); |
| assertNotNull("Stereotype not applied", result); |
| return result; |
| } |
| |
| void assertTraversal(Element root, Element[] required) { |
| assertTraversal(root, required, new Element[0]); |
| } |
| |
| void assertTraversal(Element root, Element[] required, Element[] forbidden) { |
| List<Element> expectedTraversal = Arrays.asList(required); |
| Set<EObject> unexpected = new java.util.HashSet<EObject>( |
| Arrays.asList(forbidden)); |
| for (Element next : forbidden) { |
| unexpected.addAll(next.getStereotypeApplications()); |
| } |
| |
| PushBackIterator<Element> expected = new PushBackIterator<Element>( |
| expectedTraversal.iterator()); |
| |
| fixture.startTraversal(Collections.singleton(root), |
| new NullProgressMonitor()); |
| while (expected.hasNext()) { |
| assertTrue("Traversal has too few elements", fixture.hasNext()); |
| |
| Element next = expected.next(); |
| EObject actual = fixture.next(); |
| |
| assertFalse("Traversal includes a forbidden element", |
| unexpected.contains(actual)); |
| |
| if (next != actual) { |
| // compare it with the next one, then |
| expected.pushBack(next); |
| } else { |
| // now grab its stereotype applications, which are in |
| // non-deterministic order |
| Set<EObject> stereotypeApplications = new java.util.HashSet<EObject>( |
| next.getStereotypeApplications()); |
| while (!stereotypeApplications.isEmpty()) { |
| assertTrue("Traversal has too few elements", |
| fixture.hasNext()); |
| assertTrue( |
| "Traversal did not provide a stereotype application", |
| stereotypeApplications.remove(fixture.next())); |
| } |
| } |
| } |
| } |
| |
| static final class PushBackIterator<E> |
| implements Iterator<E> { |
| |
| private final Iterator<E> delegate; |
| |
| private E pushedBack; |
| |
| PushBackIterator(Iterator<E> delegate) { |
| this.delegate = delegate; |
| } |
| |
| public boolean hasNext() { |
| return (pushedBack != null) || delegate.hasNext(); |
| } |
| |
| public E next() { |
| E result = pushedBack; |
| |
| if (result == null) { |
| result = delegate.next(); |
| } else { |
| pushedBack = null; |
| } |
| |
| return result; |
| } |
| |
| public void pushBack(E element) { |
| if (pushedBack != null) { |
| throw new IllegalStateException( |
| "already pushed an element back"); |
| } else if (element == null) { |
| throw new IllegalArgumentException("cannot push null back"); |
| } |
| } |
| |
| public void remove() { |
| throw new UnsupportedOperationException("remove"); |
| } |
| } |
| } |