Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Unit Test with cross-references to an external emf model
Unit Test with cross-references to an external emf model [message #1781440] Wed, 07 February 2018 11:09 Go to next message
Chris X is currently offline Chris XFriend
Messages: 60
Registered: November 2017
Member
Hi guys,

I have a similar setup to https://typefox.io/linking-xtext-models-with-other-emf-models. From my language it's possible to refer to elements of an instance of an external emf model.

Reference:
    'ref' ref=[ecore::EObject|ID]


This works well!

But I want to do some parsing test without the IDE now.

'''
ref Element1
'''.parse.assertNotNull


So far I build the following class

class MydslWithDependenciesInjectorProvider extends MydslInjectorProvider {

	
	override internalCreateInjector() {
		ExternalModelStandaloneSetup.doSetup
		return super.internalCreateInjector	
	}
}

@RunWith(XtextRunner)
@InjectWith(MydslWithDependenciesInjectorProvider)
class ParsingTest {


And the StandaloneSetup of my external model looks like this

class ExternalModelStandaloneSetup implements ISetup {
	
	@Inject
	private FileExtensionProvider fileExtensionProvider;

	@Inject
	private IResourceServiceProvider resourceServiceProvider;

	@Inject
	private IResourceServiceProvider.Registry registry;
	
	override createInjectorAndDoEMFRegistration() {
		val injector = Guice.createInjector(new ExternalmodelRuntimeModule)
		injector.injectMembers(this)
		for(fileExt: fileExtensionProvider.fileExtensions) 
			registry.extensionToFactoryMap.put(fileExt, resourceServiceProvider)

		// the following implicitly registers the EPackage to the registry
		val externalmodelPackage = ExternalmodelPackage.eINSTANCE
		
		return injector
	}
	
	def static void doSetup() {
		new ExternalModelStandaloneSetup().createInjectorAndDoEMFRegistration()
	}
	
}


But I have no idea how to continue. It would be very nice if someone can give me a small example.

Many thanks!!!

[Updated on: Wed, 07 February 2018 11:11]

Report message to a moderator

Re: Unit Test with cross-references to an external emf model [message #1781443 is a reply to message #1781440] Wed, 07 February 2018 11:38 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
you need to "parse" all resources to the resourceset.
e.g. use one of the parse methods offering to pass a resourceset
and prepopulate it with your non text resources


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Unit Test with cross-references to an external emf model [message #1781460 is a reply to message #1781443] Wed, 07 February 2018 13:21 Go to previous messageGo to next message
Chris X is currently offline Chris XFriend
Messages: 60
Registered: November 2017
Member
Hi Christian,

first many thanks.

But currently I have the following problem in my test:

class ExpressionParsingTest {
		
	// Allows to obtain a new resource set
	@Inject Provider<XtextResourceSet> resourceSetProvider
	@Inject extension ParseHelper<mydslModel>
	@Test 
	def void testExpression() {
	
        @Test 
	def void testParsing() {
		val element = ExternalmodelFactory::eINSTANCE.createElement
                element.name = "element1";
		val resourceSet = resourceSetProvider.get
		val resource = resourceSet.createResource(URI.createURi("myExternalModel.externalmodel"))
		resource.contents.add(element)

 		val model = '''ref element1'''.parse(resourceSet)
 		model.assertNotNull
	}


In this case

val resource = resourceSet.createResource(URI.createURi("myExternalModel.externalmodel"))


returns null

What did I miss in ExternalModelStandaloneSetup?
Re: Unit Test with cross-references to an external emf model [message #1781471 is a reply to message #1781460] Wed, 07 February 2018 15:51 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
there do you register the epackage and factory for the external model?

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Unit Test with cross-references to an external emf model [message #1781472 is a reply to message #1781471] Wed, 07 February 2018 16:39 Go to previous messageGo to next message
Chris X is currently offline Chris XFriend
Messages: 60
Registered: November 2017
Member
For my external model I created an additional plugin as described under the following link

https://github.com/TypeFox/Xtext-XMI/blob/master/io.typefox.xtextxmi.tree.xtext/src/io/typefox/xtextxmi/tree/xtext/TreeStandaloneSetup.xtend

And this plugin has it's own StandaloneSetup that looks like this

class ExternalModelStandaloneSetup implements ISetup {
	
	@Inject
	private FileExtensionProvider fileExtensionProvider;

	@Inject
	private IResourceServiceProvider resourceServiceProvider;

	@Inject
	private IResourceServiceProvider.Registry registry;
	
	override createInjectorAndDoEMFRegistration() {
		val injector = Guice.createInjector(new ExternalmodelRuntimeModule)
		injector.injectMembers(this)
		for(fileExt: fileExtensionProvider.fileExtensions) 
			registry.extensionToFactoryMap.put(fileExt, resourceServiceProvider)

		// the following implicitly registers the EPackage to the registry
		val externalmodelPackage = ExternalmodelPackage.eINSTANCE
		
		return injector
	}
	
	def static void doSetup() {
		new ExternalModelStandaloneSetup().createInjectorAndDoEMFRegistration()
	}
	
}


And currently I'm not sure how and where to register the factory and the package.
In the StandaloneSetup of the external Model or in the StandaloneSetup of the myDsl language.
Re: Unit Test with cross-references to an external emf model [message #1781473 is a reply to message #1781472] Wed, 07 February 2018 16:47 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
no i mean something like in the setups e.g. as it is generated

@SuppressWarnings("all")
public class DomainmodelStandaloneSetupGenerated implements ISetup {

@Override
public Injector createInjectorAndDoEMFRegistration() {
XbaseStandaloneSetup.doSetup();

Injector injector = createInjector();
register(injector);
return injector;
}

public Injector createInjector() {
return Guice.createInjector(new DomainmodelRuntimeModule());
}

public void register(Injector injector) {
if (!EPackage.Registry.INSTANCE.containsKey("http://www.xtext.org/example/Domainmodel")) {
EPackage.Registry.INSTANCE.put("http://www.xtext.org/example/Domainmodel", DomainmodelPackage.eINSTANCE);
}
IResourceFactory resourceFactory = injector.getInstance(IResourceFactory.class);
IResourceServiceProvider serviceProvider = injector.getInstance(IResourceServiceProvider.class);

Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("dmodel", resourceFactory);
IResourceServiceProvider.Registry.INSTANCE.getExtensionToFactoryMap().put("dmodel", serviceProvider);
}
}




Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Unit Test with cross-references to an external emf model [message #1781479 is a reply to message #1781473] Wed, 07 February 2018 17:31 Go to previous messageGo to next message
Chris X is currently offline Chris XFriend
Messages: 60
Registered: November 2017
Member
Hi Christian,

my external model is not generated by a second DSL. It's a separate EMF-Project.
class ExternalmodelStandaloneSetup implements ISetup {
	
	@Inject
	private FileExtensionProvider fileExtensionProvider;

	@Inject
	private IResourceServiceProvider.Registry registry;
	
	override Injector createInjectorAndDoEMFRegistration() {
		val Injector injector = createInjector();
		register(injector);
		return injector;
	}
	
	def static void doSetup() {
		new ExternalmodelStandaloneSetup().createInjectorAndDoEMFRegistration()
	}
	
	def public Injector createInjector() {
		return Guice.createInjector(new ExternalmodelRuntimeModule());
	}
	
	def public void register(Injector injector) {
		if (!EPackage.Registry.INSTANCE.containsKey("http://www.example.com/externmodel/Externmodel")) {
			EPackage.Registry.INSTANCE.put("http://www.example.com/externmodel/Externmodel", ExternmodelPackage.eINSTANCE);
		}
		
/* At this point I get the exception: "com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for org.eclipse.xtext.resource.IResourceFactory was bound.
  while locating org.eclipse.xtext.resource.IResourceFactory */

		val resourceFactory = injector.getInstance(IResourceFactory.class);
val  serviceProvider = injector.getInstance(IResourceServiceProvider.class);		
		Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("externalmodel", resourceFactory);
		IResourceServiceProvider.Registry.INSTANCE.getExtensionToFactoryMap().put("externalmodel", serviceProvider);
	}


In the line "val service Provider ..." I get the following exception (see in code comment)

1) So where do I have to bound the IResourceFactory?
2) And is the Standalonesetup for the externalmodel okay or did I mis something?
3) Is it right that I have to register the factory for the XtextResourceSet? Would it be also okay to register the externalmodel in the Standalonesetup of mydsl?

@All
If someone has a link to an example, then I would be very grateful. I searched for examples but found nothing, only examples for multiple DSLs with cross references like this one https://github.com/szarnekow/testing-multiple-dsls.

Many thanks and sorry for the newbie questions

[Updated on: Wed, 07 February 2018 17:58]

Report message to a moderator

Re: Unit Test with cross-references to an external emf model [message #1781489 is a reply to message #1781479] Wed, 07 February 2018 19:49 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
arrrgggg

from terminal standalonesetup:

if (!Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey("ecore"))
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
"ecore", new EcoreResourceFactoryImpl());
if (!Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey("xmi"))
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
"xmi", new XMIResourceFactoryImpl());
if (!Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey("xtextbin"))
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
"xtextbin", new BinaryGrammarResourceFactoryImpl());
if (!EPackage.Registry.INSTANCE.containsKey(XtextPackage.eNS_URI))
EPackage.Registry.INSTANCE.put(XtextPackage.eNS_URI, XtextPackage.eINSTANCE);


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Unit Test with cross-references to an external emf model [message #1781490 is a reply to message #1781489] Wed, 07 February 2018 19:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
and no simply regesiter your epackage and factory

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Unit Test with cross-references to an external emf model [message #1781491 is a reply to message #1781489] Wed, 07 February 2018 19:54 Go to previous messageGo to next message
Chris X is currently offline Chris XFriend
Messages: 60
Registered: November 2017
Member
Thanks Christian
Re: Unit Test with cross-references to an external emf model [message #1781511 is a reply to message #1781491] Thu, 08 February 2018 05:04 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
P.s. did you reallly follow the example regarding the setup?

https://github.com/TypeFox/Xtext-XMI/blob/master/io.typefox.xtextxmi.tree.xtext/src/io/typefox/xtextxmi/tree/xtext/TreeRuntimeModule.xtend
https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext/src/org/eclipse/xtext/resource/generic/AbstractGenericResourceRuntimeModule.java


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Unit Test with cross-references to an external emf model [message #1781527 is a reply to message #1781511] Thu, 08 February 2018 08:49 Go to previous messageGo to next message
Chris X is currently offline Chris XFriend
Messages: 60
Registered: November 2017
Member
Yes I did.

The only difference is that in the example it's possible to define elements of nodes in the DSL and in the external model. In my case it's possible to define some kinds of elements, like nodes, only in the external model and to refer these elements from the dsl.
Re: Unit Test with cross-references to an external emf model [message #1781529 is a reply to message #1781527] Thu, 08 February 2018 08:55 Go to previous messageGo to next message
Chris X is currently offline Chris XFriend
Messages: 60
Registered: November 2017
Member
Wait !!!!!!! Maybe .... I ..... fu**! I will check something. Maybe I did a stupid mistake

[Updated on: Thu, 08 February 2018 08:56]

Report message to a moderator

Re: Unit Test with cross-references to an external emf model [message #1781530 is a reply to message #1781527] Thu, 08 February 2018 08:56 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
the point is:

your external stuff provides a IResourceSerivce provider for your external metamodel and files. this resourceserviceprovider enables you do refer to this elements from any xtext dsl.
if you want to make sure that this works standalone the code has to ensure

- epackage and resource factory are registered
- the resourceserviceprovider is registered.

both should be done from the standalonesetup you provider

you then can call the standalonesetup from your dsls standalonesetup and or injector provider


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Unit Test with cross-references to an external emf model [message #1781533 is a reply to message #1781530] Thu, 08 February 2018 09:20 Go to previous messageGo to next message
Chris X is currently offline Chris XFriend
Messages: 60
Registered: November 2017
Member
Okay no mistake so far ... most likely:)

Respect to the example of https://github.com/TypeFox/Xtext-XMI "both should be done from the standalonesetup you provider" means:

In the TreeStandalonesetup I have to

1) register the Epackage and create a ResourceFactory for the treemodel and register it
2) register the resource service provider

In the tests package of mydsl create a class

class MydslWithDependenciesInjectorProvider extends MydslInjectorProvider {

	
	override internalCreateInjector() {
		TreeStandaloneSetup.doSetup
		return super.internalCreateInjector	
	}
}


and call it in the unit test class/es with:

@InjectWith(MydslWithDependenciesInjectorProvider)


Hope understand you correct...

And many many thanks. I'm really happy about so much help!! You and the other guys do a really greate job !!!

[Updated on: Thu, 08 February 2018 09:34]

Report message to a moderator

Re: Unit Test with cross-references to an external emf model [message #1781534 is a reply to message #1781533] Thu, 08 February 2018 09:29 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
yes that is what i meant

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Unit Test with cross-references to an external emf model [message #1781538 is a reply to message #1781534] Thu, 08 February 2018 10:15 Go to previous message
Chris X is currently offline Chris XFriend
Messages: 60
Registered: November 2017
Member
Thanks!!!! It works!!!!!

That's one small step for mankind, one giant leap for me :D

Have a nice day!
Previous Topic:Solving Maven dependency between two Xtext projects for production
Next Topic:Build xtext with maven
Goto Forum:
  


Current Time: Tue Apr 16 06:43:23 GMT 2024

Powered by FUDForum. Page generated in 0.06019 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top