Home » Modeling » TMF (Xtext) » Example of the power of Xtext and Xbase
Example of the power of Xtext and Xbase [message #1239963] |
Wed, 05 February 2014 11:55 |
Hallvard Traetteberg Messages: 673 Registered: July 2009 Location: Trondheim, Norway |
Senior Member |
|
|
Hi,
I just wanted to share what I consider a good example of the power of
Xtext and Xbase.
I'm teaching a course on object-oriented programmering and use junit to
the students' code. Part of the learning goal of the course is
understanding how methods change the state of objects, that the behavior
of an object can be specified by a state diagram where objects are
states and method calls are transitions (see
https://www.ntnu.no/wiki/pages/viewpage.action?pageId=65937373 as an
example) and that this can be used for writing tests.
Since writing tests can be tedious, I have created a small DSL based on
Xtext and Xbase and a generator that emits junit tests. An example of
the syntax is shown below, where the CardDeck class is tested. It
defines a set of test methods each of which runs through a sequence of
states (some are only one state long).
First of all, it didn't take more than a day to write a prototype (power
of Xtext) and a couple of more days to write a decent generator (power
of Xbase). Second, the Xbase syntax and the use of it-based scopes
allows me to support a very compact syntax. Third, by including method
definitions and allowing to define what is in effect extension methods
for many standard operators, I can make the syntax even more compact.
My teaching assistants confirmed that the syntax is intuitive, in the
sense that they understand the intention of the tests, even though they
don't understand all the mechanisms that make it work. They also
believed that would be able to write their own tests in this syntax, by
looking at examples, although this hasn't been confirmed, yet.
I'll present this example at our local Java interest group later this
month, where DSL and Xtext++ is the topic.
Hallvard
---8<---CardDeck.jextest-----------
test objectstructures.CardDeck
import java.util.Collection
// instance that is used by the tests
instances deck = new CardDeck(2)
// checks the initial state of the deck
sequence constructor {
-->
state {
// use the overloaded operator_equals method, see below
deck == #["S1", "S2", "H1", "H2", "D1", "D2", "C1", "C2"];
}
}
sequence shufflePerfectly {
-- shufflePerfectly -->
state {
deck == #["S1", "D1", "S2", "D2", "H1", "C1", "H2", "C2"];
}
}
sequence deal {
// also needs an instance of the CardHand class
instances CardHand hand
"Move three cards from deck to hand" -- deal(hand, 3) -->
state {
deck == #["S1", "S2", "H1", "H2", "D1"];
}
}
// overload the == operator
// (uses OperatorMapping to infer an appropriately named method)
method boolean == (CardDeck cardDeck, Collection<String> toStrings) {
if (cardDeck.cardCount != toStrings.size) {
return false
}
var i = 0
for (toString : toStrings) {
if (cardDeck.getCard(i).toString != toString) {
return false
}
i = i + 1
}
true
}
|
|
|
Goto Forum:
Current Time: Thu Apr 25 16:45:44 GMT 2024
Powered by FUDForum. Page generated in 0.03076 seconds
|