Xtext et JUnit

Le projet XText de la fondation Eclipse permet de facilement mettre en place des éditeurs de texte pour les langages dédiés (DSLs). Cependant, il est rapidement assez complexe de manipuler l'API de Xtext afin de l'intégrer à une batterie de tests unitaires.

Je vais donc ici fournir un extrait de code pour faciliter la prise en main et l'utilisation, depuis une application externe (JUnit), des moteurs de validation. L'intérêt est donc de pouvoir exécuter les contrôles de Xtext sur nos données et récupérer les éventuels erreurs et/ou warning remontés :

// On parse le texte extrait de l'éditeur
Injector injector = new MyStandaloneSetup().createInjectorAndDoEMFRegistration();
MyParser parser = injector.getInstance(MyParser.class);
InputStream  input = new ByteArrayInputStream(texte.getBytes());
IParseResult result = parser.doParse(input);

// On execute la validation Xtext
Diagnostic diagnostic = Diagnostician.INSTANCE.validate(parseResult.getRootNode().getElement());

// On récupère les erreurs/warning levés
boolean success = true;
String errorMessage = "Message(s) : \n";
switch (diagnostic.getSeverity()) {
case Diagnostic.ERROR:
 success = false;
 if (diagnostic.getException() != null) {
  diagnostic.getException().printStackTrace();
  errorMessage += diagnostic.getException().getMessage();
 } else if (diagnostic.getChildren().size() > 0) {
  for (Diagnostic d : diagnostic.getChildren()) {
   if (d.getException() != null) {
    d.getException().printStackTrace();
    errorMessage += d.getException().getMessage() + "\n";
   } else {
    errorMessage += d.getMessage() + "\n";
   }
  }
 } else {
  errorMessage += diagnostic.getMessage();
 }
 break;
case Diagnostic.WARNING:
 // No warning thrown
}

A partir de ces résultats, il est donc possible de contrôler simplement, avec les assertions JUnit, les retours des validations. Ce code s'inspire du paragraphe Validating Manually de la document XText.

De la même façon, il est possible de lancer l'exécution des switch qui parsent le contenu de l'éditeur afin de le traiter spécifiquement :

// Voir le parseResult instancié plus haut
MySwitch mySwitch = new MySwitch();
mySwitch.doSwitch(parseResult.getRootNode().getElement());

Enjoy!


Fichier(s) joint(s) :

3 commentaires: