/*******************************************************************************
* Copyright (c) 2006-2012
* Software Technology Group, Dresden University of Technology
* DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026
*
* 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:
* Software Technology Group - TU Dresden, Germany;
* DevBoost GmbH - Berlin, Germany
* - initial API and implementation
******************************************************************************/
package org.reuseware.coconut.test;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import static org.junit.Assert.*;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.junit.Before;
import org.junit.Test;
import org.reuseware.coconut.compositionprogram.CompositionLink;
import org.reuseware.coconut.compositionprogram.CompositionProgram;
import org.reuseware.coconut.compositionprogram.FragmentInstance;
import org.reuseware.coconut.fragment.ComposedFragment;
import org.reuseware.coconut.fragment.Fragment;
public class ReusewareFeaturesCompositionTest extends AbstractReusewareCompositionTestCase {
@Override
public AbstractReusewareTestHelper getTestHelper() {
//return new SokanReusewareTestHelper();
return new ResourceSetReusewareTestHelper();
}
@Before
public void init() throws Exception {
// out store
File outStoreFolder = new File("../org.reuseware.coconut.test/out");
AbstractReusewareTestHelper.deleteDirectory(outStoreFolder, false, false);
outStoreFolder.mkdir();
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"out",
new String[] {});
// store with default fracol
assertRegisterFragmentStore(
"org.reuseware.coconut.resource",
"store",
new String[]{});
}
@Test
public void testRepositoryBasics() throws Exception {
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"testdata/repositoryBasics",
new String[] {"ecore"});
CompositionProgram cp = getCompositionProgram(new String[] {
"org","reuseware","test","basic","repositoryBasics","composition.ucl"
});
for(FragmentInstance fi : cp.getFragmentInstances()) {
assertNotNull(fi.getUFI() + " fragment missing", fi.getFragment());
assertEquals(fi.getUFI(), fi.getFragment().getUFI());
}
//the cp is reloaded. therefore this is fine
assertTrue(cp.getComposedFragments().size() == 0);
cp.compose();
//now we should have composed fragments
assertTrue(cp.getComposedFragments().size() == 4);
}
@Test
public void testNonContributingExtensions() throws Exception {
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"testdata/nonContributingExtensions",
new String[] {"ecore"});
Fragment f; EPackage p; EClassifier c1, c2;
f = getFragment(new String[] {
"org","reuseware","test","basic","nonContributingExtensions","Empty.ecore"
});
assertTrue(f instanceof ComposedFragment);
p = (EPackage) f.getContents().get(0);
//Empty, because the configurations on the target of a step are not further followed
assertEquals(0, p.getEClassifiers().size());
f = getFragment(new String[] {
"org","reuseware","test","basic","nonContributingExtensions","OneA.ecore"
});
assertTrue(f instanceof ComposedFragment);
p = (EPackage) f.getContents().get(0);
//Only one EClass A, because the second link is NOT contributing, the same A is "added twice"
assertEquals(1, p.getEClassifiers().size());
c1 = p.getEClassifiers().get(0);
assertEquals("A", c1.getName());
f = getFragment(new String[] {
"org","reuseware","test","basic","nonContributingExtensions","TwoA.ecore"
});
assertTrue(f instanceof ComposedFragment);
p = (EPackage) f.getContents().get(0);
//Two EClass A, because both links are contributing;
//Also, no A should be stolen because of config link direction
assertEquals(2, p.getEClassifiers().size());
c1 = p.getEClassifiers().get(0);
assertEquals("A", c1.getName());
c2 = p.getEClassifiers().get(1);
assertEquals("A", c2.getName());
f = getFragment(new String[] {
"org","reuseware","test","basic","nonContributingExtensions","OneAWithOp.ecore"
});
assertTrue(f instanceof ComposedFragment);
p = (EPackage) f.getContents().get(0);
//One EClass A with Op B, because one link is contributing and pulls in the other
assertEquals(1, p.getEClassifiers().size());
c1 = p.getEClassifiers().get(0);
assertEquals("A", c1.getName());
assertEquals(1, ((EClass)c1).getEOperations().size());
}
@Test
public void testFragmentReference() throws Exception {
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"testdata/fragmentReference",
new String[] {"ecore"});
Fragment referencedF = getFragment(new String[] {
"org","reuseware","test","basic","fragmentReference","typeA.ecore"
});
Fragment f; EPackage p; EClassifier c; EOperation o;
f = getFragment(new String[] {
"org","reuseware","test","basic","fragmentReference","noReference.ecore"
});
EPackage referencedP = (EPackage) referencedF.getContents().get(0);
EClassifier referencedC = referencedP.getEClassifiers().get(0);
p = (EPackage) f.getContents().get(0);
c = p.getEClassifier("B");
assertNotNull(c);
o = ((EClass)c).getEOperations().get(0);
assertNotSame(referencedC, o.getEType());
assertSame(o.eResource(), o.getEType().eResource());
f = getFragment(new String[] {
"org","reuseware","test","basic","fragmentReference","withReference.ecore"
});
p = (EPackage) f.getContents().get(0);
c = p.getEClassifier("B");
o = ((EClass)c).getEOperations().get(0);
assertSame(referencedC, o.getEType());
assertNotSame(o.eResource(), o.getEType().eResource());
}
@Test
public void testCompositionProgramContext() throws Exception {
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"testdata/compositionProgramContext",
new String[] {"ecore"});
Fragment fA = getFragment(new String[] {
"org","reuseware","test","basic","compositionProgramContext","ComposedA.ecore"
});
Fragment fB = getFragment(new String[] {
"org","reuseware","test","basic","compositionProgramContext","ComposedB.ecore"
});
EPackage pA = (EPackage) fA.getContents().get(0);
EClass A = (EClass) pA.getEClassifier("A");
assertNotNull(A);
EReference r = (EReference) A.getEStructuralFeature("crossReference");
EPackage pB = (EPackage) fB.getContents().get(0);
EClass B = (EClass) pB.getEClassifier("B");
//The context of the composition program allows cross-referencing between different composed fragments
assertEquals("The cross-reference should now point at B", B, r.getEType());
}
@Test
public void testValueHookWithIndex() throws Exception {
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"testdata/valueHookWithIndex",
new String[] {"ecore"});
Fragment f = getFragment(new String[] {
"org","reuseware","test","basic","valueHookWithIndex","valueHookWithIndexComposed.ecore"
});
EPackage p = (EPackage) f.getContents().get(0);
EClassifier c = p.getEClassifiers().get(0);
//HOOK should be replaced by TEST in the name String
assertTrue("Value 'ExtendedTESTClass' expected, but was '" + c.getName() + "'",
c.getName().equals("ExtendedTESTClass"));
}
@Test
public void testValueHookContribution() throws Exception {
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"testdata/valueHookContribution",
new String[] {"ecore"});
Fragment f = getFragment(new String[] {
"org","reuseware","test","basic","valueHookContribution","composedA.ecore"
});
EPackage p = (EPackage) f.getContents().get(0);
//ensure package we look at is A
assertTrue("Expected package A",
p.getNsPrefix().equals("A"));
//ValuePrototype from B.ecore should change A to B
assertTrue("After the composition Package A should have turned into B",
p.getName().equals("B"));
}
@Test
public void testSamePointNameGrouping() throws Exception {
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"testdata/samePointNameGrouping",
new String[] {"ecore"});
Fragment f = getFragment(new String[] {
"org","reuseware","test","basic","samePointNameGrouping","composed","Rec.ecore"
});
//there should be 5 EPackage root elements: 1 from Rec.ecore and 4 from Contrib.ecore
assertEquals(5, f.getContents().size());
}
@Test
public void testRexclBasics() throws Exception {
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"testdata/rexclBasics",
new String[] {"ecore"});
Fragment f = getFragment(new String[] {
"org","reuseware","test","basic","rexclBasics","result.ecore"
});
CompositionProgram cp = getCompositionProgramForComposedFragment(f.getUFI());
assertNotNull(cp);
assertFalse("Composition program is empty", cp.getFragmentInstances().isEmpty());
assertFalse("Composition program is empty", cp.getCompositionLinks().isEmpty());
boolean result = true;
for(CompositionLink link : cp.getCompositionLinks()) {
link.match();
result = result && isLinkValid(link);
}
assertTrue("Ivalid links in " + cp.getUCPI(), result);
assertFalse("Composition result is empty", f.getContents().isEmpty());
EPackage p = (EPackage) f.getContents().get(0);
//there should 4 classes in here C1-C2-C3-C1
assertEquals(4, p.getEClassifiers().size());
}
public void testCyclicDependency() throws Exception {
PrintStream origError = System.err;
ByteArrayOutputStream allOutput = new ByteArrayOutputStream();
PrintStream err = new PrintStream(allOutput);
System.setErr(err);
assertRegisterFragmentStore(
"org.reuseware.coconut.test",
"testdata/cyclicDependency",
new String[] {"ecore"});
origError.print(allOutput.toString());
assertTrue("Cyclic dependency expected",
allOutput.toString().contains(
"[Sokan] Possible cyclic dependency (involved artifacts: [[org, reuseware, test, basic, cyclicDependency, cyclicDependencyComposed.ecore]])"));
System.setErr(origError);
err.close();
}
}