Example: Integrate EUnit into a standard JUnit plug-in test

package org.eclipse.epsilon.examples.eunit.junit;

import java.io.File;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.common.util.URI;
import org.eclipse.epsilon.emc.emf.EmfModel;
import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException;
import org.eclipse.epsilon.eol.execute.operations.contributors.OperationContributor;
import org.eclipse.epsilon.eol.models.IModel;
import org.eclipse.epsilon.etl.EtlModule;
import org.eclipse.epsilon.eunit.junit.EUnitTestRunner;
import org.eclipse.epsilon.eunit.junit.IEUnitSuite;
import org.junit.runner.RunWith;

/**
 * Example EUnit-based JUnit plug-in test suite which uses a custom contributor
 * to invoke an ETL transformation from an EUnit test suite. This custom
 * contributor is required since running an Ant script from a JUnit plug-in test
 * (from Tycho, for instance) is quite difficult to set up.
 */
@RunWith(EUnitTestRunner.class)
public class JUnitIntegrationExampleSuite implements IEUnitSuite {

  public static final class ExampleTestOperationContributor extends
      OperationContributor {
    @Override
    public boolean contributesTo(Object target) {
      return true;
    }

    public void transform() throws Exception {
      EtlModule etl = new EtlModule();
      etl.getContext().setModelRepository(context.getModelRepository());
      etl.parse(new File("resources/etl/Tree2Graph.etl"));
      etl.execute();
    }
  }

  @Override
  public OperationContributor getOperationContributor() {
    return new ExampleTestOperationContributor();
  }

  @Override
  public java.net.URI getModuleURI() throws Exception {
    return getResourceURI("tests/example.eunit");
  }

  @Override
  public List<IModel> prepareModels() throws Exception {
    final List<IModel> models = new ArrayList<IModel>();
    
    models.add(loadEmptyModel("Tree", "metamodels/tree.ecore"));
    models.add(loadEmptyModel("Graph", "metamodels/graph.ecore"));
    models.add(loadEmptyModel("GraphExpected", "metamodels/graph.ecore"));

    return models;
  }

  private EmfModelloadEmptyModel(String name, String metamodelPath) throws EolModelLoadingException {
    EmfModel model = new EmfModel();
    model.setName(name);
    model.setMetamodelFileUri(getResourceEmfURI(metamodelPath));
    model.setModelFileUri(URI.createFileURI(new File("Empty" + name + ".model").getAbsolutePath()));
    model.setReadOnLoad(false);
    model.setStoredOnDisposal(false);
    model.load();
    return model;
  }

  private java.net.URI getResourceURI(String resourcePath) throws URISyntaxException {
    return getClass().getResource("/resources/" + resourcePath).toURI();
  }

  private URI getResourceEmfURI(String resourcePath) {
    return URI.createURI(getClass().getResource("/resources/" + resourcePath).toExternalForm());
  }

}
@test
operation emptyToEmpty() {
  transform();
  assertEqualModels("Graph", "GraphExpected");
}

@test
operation oneNodeToRoot() {
  var t = newRoot('A');
  var g = new GraphExpected!Graph;
  g.newNode('A');
  transform();
  assertEqualModels("Graph", "GraphExpected");
}

@test
operation twoLevels() {
  var root = newRoot('A');
  root.newChild('B');
  root.newChild('C');

  var g = new GraphExpected!Graph;
  var gMain = g.newNode('A');
  gMain.newChild('B');
  gMain.newChild('C');

  transform();
  assertEqualModels("Graph", "GraphExpected");
}

operation newRoot(label : String) : Tree!Tree {
  var t = new Tree!Tree;
  t.label = label;
  return t;
}

operation Tree!Tree newChild(label : String) : Tree!Tree {
  var child = new Tree!Tree;
  child.label = label;
  child.parent = self;
  return child;
}

operation GraphExpected!Graph newNode(name : String) : GraphExpected!Node {
  var node = new GraphExpected!Node;
  node.name = name;
  self.nodes.add(node);
  return node;
}

operation GraphExpected!Node linkTo(target : GraphExpected!Node) : GraphExpected!Edge {
  var edge = new GraphExpected!Edge;
  edge.source = self;
  edge.target = target;
  return edge;
}

operation GraphExpected!Node newChild(label : String) : GraphExpected!Node {
  var node = self.eContainer.newNode(label);
  self.linkTo(node);
  return node;
}
rule Tree2Node 
  transform t : Tree!Tree
  to n : Graph!Node {
  
  n.name = t.label;
  if (t.parent.isDefined()) {
    var e : new Graph!Edge;
    e.source ::= t.parent;
    e.target = n;
  }
  else {
      // root node: create root element for the graph model
      new Graph!Graph;
  }

    // add node to graph
    Graph!Graph.allInstances.first().nodes.add(n);
}

Check out the code from the SVN:

  • go to the SVN repository
  • navigate to trunk/examples
  • check out the org.eclipse.epsilon.eunit.examples.junit project

Once you have checked out/imported the code, to run the example you need to go through the following steps:

  1. register any .ecore metamodels in the org.eclipse.epsilon.eunit.examples.junit project
  2. right click the .launch file in the org.eclipse.epsilon.eunit.examples.junit project
  3. select Run as... and click the first item in the menu that pops up

What's this?

In this example we show how to write an EUnit/JUnit plug-in test of an ETL transformation.

What are .emf files?

.emf files are Ecore metamodels expressed using the Emfatic textual syntax.

More examples...

Epsilon Object Language
Epsilon Transformation Language
Epsilon Generation Language
Epsilon Validation Language
Epsilon Merging Language
Epsilon Flock
Combining the Epsilon Languages
EuGENia
EUnit

Even more examples...

More examples are available in the examples folder of the SVN repository.