SlideShare une entreprise Scribd logo
1  sur  44
Test-Driven Development
           of
      Xtext DSLs
        Moritz Eysholdt
we strive for...

...product quality   ...development speed


        features         fast

robustness                      agile

     correctness
without tests   with tests


add source code         easy          easy


 modify source
                        risky          safe
    code

application state
                        large         small
while debugging
without tests           with tests


add source code         easy                    easy


 modify source
                        risky                    safe
    code

application state
                        large                   small
                                          lots of redundancy
while debugging                         architecture may erode
                                    maintenance increasingly difficult
without tests           with tests


add source code         easy                    easy
                                    extracting small test + debugging
                                           may be faster then
 modify source                          debugging large scenario
                        risky                    safe
    code

application state
                        large                   small
while debugging
qualities of (unit) tests

                        fast   run them locally
                    specific    avoid redundancy
          efficient to write    save time
       efficient to maintain    expectations can change
  easy to read/understand      involve domain experts
self-explanatory on failure!   save time
JUnit 4
XtextRunner

         ParameterizedXtextRunner
Test...
  content assist                     validation rules
                         scoping
 quickfixes
               value conversion formatter
  parser/AST                              serializer
                       derived values
exported EObjects
                                    semantic highlighting
               typesystem
 autoedit
                   code generator       interpreter
Test...
  content assist                    validation rules
                         scoping
 quickfixes
              value conversion formatter
            your own code
  parser/AST                         serializer
            integration with framework
            the framework values
                     derived
exported EObjects
                               semantic highlighting
               typesystem
 autoedit
                   code generator     interpreter
person Peter
person Frank knows Peter
person Peter
person Frank knows Peter




                           Model:
                           	   persons+=Person*;
                           	
                           Person:
                           	   'person' name=ID
                           	   ('knows' knows=[Person|ID])?;
test scoping

person Peter
person Frank knows Peter




                           Model:
                           	   persons+=Person*;
                           	
                           Person:
                           	   'person' name=ID
                           	   ('knows' knows=[Person|ID])?;
StringBuilder modelString = new StringBuilder();
modelString.append("person Petern");
modelString.append("person Frank knows Petern");
Model model = parseHelper.parse(modelString);
StringBuilder modelString = new StringBuilder();
modelString.append("person Petern");
modelString.append("person Frank knows Petern");
Model model = parseHelper.parse(modelString);

Person peter = model.getPersons().get(0);
EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

IScope scope = scopeProvider.getScope(peter, reference);
StringBuilder modelString = new StringBuilder();
modelString.append("person Petern");
modelString.append("person Frank knows Petern");
Model model = parseHelper.parse(modelString);

Person peter = model.getPersons().get(0);
EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

IScope scope = scopeProvider.getScope(peter, reference);

List<String> actualList = Lists.newArrayList();
for (IEObjectDescription desc : scope.getAllElements())
  actualList.add(desc.getName().toString());
String actual = Joiner.on(", ").join(actualList);

Assert.assertEquals("Peter, Frank", actual);
@RunWith(XtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;

    @Inject private IScopeProvider scopeProvider;

    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");
      Model model = parseHelper.parse(modelString);

        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
                                                                     JUnit 4 Runner
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;

    @Inject private IScopeProvider scopeProvider;

    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");
      Model model = parseHelper.parse(modelString);

        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
                                                                      JUnit 4 Runner
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;
                                                                   Google Guice Injector
    @Inject private IScopeProvider scopeProvider;
                                                                     Injected Instances
    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");
      Model model = parseHelper.parse(modelString);

        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
                                                                      JUnit 4 Runner
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;
                                                                   Google Guice Injector
    @Inject private IScopeProvider scopeProvider;
                                                                     Injected Instances
    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");            Backups and Restores
      Model model = parseHelper.parse(modelString);
                                                                      EMF Registries
        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
                                                                       JUnit 4 Runner
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;
                                                                   Google Guice Injector
    @Inject private IScopeProvider scopeProvider;
                                                                     Injected Instances
    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");            Backups and Restores
      Model model = parseHelper.parse(modelString);
                                                                      EMF Registries
        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);      Plain JUnit Test:
                                                                              No OSGi
        List<String> actualList = Lists.newArrayList();
                                                                    Injector via StandaloneSetup
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
                                                                       JUnit 4 Runner
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;
                                                                   Google Guice Injector
    @Inject private IScopeProvider scopeProvider;
                                                                     Injected Instances
    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");            Backups and Restores
      Model model = parseHelper.parse(modelString);
                                                                      EMF Registries
        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);
                                                         FAST!
                                                                      Plain JUnit Test:
                                                                              No OSGi
        List<String> actualList = Lists.newArrayList();
                                                                    Injector via StandaloneSetup
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
                                                                       JUnit 4 Runner
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;
                                                                   Google Guice Injector
    @Inject private IScopeProvider scopeProvider;
                                                                     Injected Instances
    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");            Backups and Restores
      Model model = parseHelper.parse(modelString);
                                                                      EMF Registries
        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);
                                                         FAST!
                                                                      Plain JUnit Test:
                                                                              No OSGi
        List<String> actualList = Lists.newArrayList();
                                                                    Injector via StandaloneSetup
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);                 Plug-In JUnit Test:
    }                                                              Eclipse Headless or Workbench
}
                                                                         Injector via Activator
@RunWith(XtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;

    @Inject private IScopeProvider scopeProvider;

    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");
      Model model = parseHelper.parse(modelString);

        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;

    @Inject private IScopeProvider scopeProvider;

    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
            Exchange Components: Customize InjectorProvider
      modelString.append("person Frank knows Petern");
      Model model = parseHelper.parse(modelString); via
                          Components are configured        Google Guice
        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;

    @Inject private IScopeProvider scopeProvider;

    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
            Exchange Components: Customize InjectorProvider
      modelString.append("person Frank knows Petern");
      Model model = parseHelper.parse(modelString); via
                          Components are configured         Google Guice
        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
                Mocking Components vs. Reusing Components
        String actual = Joiner.on(", ").join(actualList);

               Integration tests don’t hurt when they’re
        Assert.assertEquals("Peter, Frank", actual);  not fragile, but specific and fast
    }     Reusing Parser+Linker is more convenient than creating models programmatically
}
@RunWith(XtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;

    @Inject private IScopeProvider scopeProvider;

    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");
      Model model = parseHelper.parse(modelString);
              (XtextRunner)
        Person Java Example
               peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
                      @RunWith(typeof(XtextRunner))
@InjectWith(TestDemoInjectorProvider.class)
                      @InjectWith(typeof(TestDemoInjectorProvider))
public class ScopingTestPlain {
                      class ScopingTestXtend {

    @Inject private ParseHelper<Model> parseHelper;
                          @Inject extension ParseHelper<Model>
                          @Inject extension IScopeProvider
    @Inject private IScopeProvider scopeProvider;
                          @Test
    @Test public void testScope1() throws Exception {
                          def testScope1() {
      StringBuilder modelString model = '''
                          	 val = new StringBuilder();
      modelString.append("person Petern");
                          		    person Peter
      modelString.append("person Frank Frank knows Peter
                          		    person knows Petern");
      Model model = parseHelper.parse(modelString);
                          	 '''.parse
              (XtextRunner)
        Person Java Example
               peter = model.getPersons().get(0);
                              val scope = getScope(model.persons.head, eINSTANCE.person_Knows)
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();
                              val actual = scope.allElements.map[name.toString].join(", ")
        IScope scope = scopeProvider.getScope(peter, reference);
                              assertEquals("Peter, Frank", actual);
        List<String> actualList = Lists.newArrayList();
                            }
        for (IEObjectDescription desc : scope.getAllElements())
                          }
          actualList.add(desc.getName().toString());
        String actual = Joiner.on(", ").join(actualList);

        Assert.assertEquals("Peter, Frank", actual);
    }
}
@RunWith(XtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;
                                                                              Data Flow
    @Inject private IScopeProvider scopeProvider;

    @Test public void testScope1() throws Exception {
      StringBuilder modelString = new StringBuilder();
      modelString.append("person Petern");
      modelString.append("person Frank knows Petern");
      Model model = parseHelper.parse(modelString);                            prepare
        Person peter = model.getPersons().get(0);
        EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows();

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();                        process
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());

        String actual = Joiner.on(", ").join(actualList);
        Assert.assertEquals("Peter, Frank", actual);                          compare
    }
}
@RunWith(XtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
public class ScopingTestPlain {

    @Inject private ParseHelper<Model> parseHelper;
                                                                   Data Flow
    @Inject private IScopeProvider scopeProvider;

    @Test public void testScope1() throws Exception {




                         (DSL File)                                 prepare

        IScope scope = scopeProvider.getScope(peter, reference);

        List<String> actualList = Lists.newArrayList();             process
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());


                         (DSL File)                                compare
    }
}
person Peter
                                                            DSL-File
// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---
	   Frank, !Jim
--- */
person Jack knows Peter
person Peter
                                                                                 DSL-File
// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---
	   Frank, !Jim
--- */
person Jack knows Peter


@RunWith(ParameterizedXtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)                                  JUnit 4 Test
@ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo")
public class ScopingTestPlain {

    @InjectParameter private Offset offset;
    @Inject private IScopeProvider scopeProvider;
                                                                                   beta
    @ParameterSyntax("('at' offset=OFFSET)?")
    @XpectCommaSeparatedValues
    public Iterable<String> elementsInScope() throws Exception {
      Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent();

        IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond());

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        return actualList;
    }
}
person Peter

// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---
	   Frank, !Jim
--- */
person Jack knows Peter


@RunWith(ParameterizedXtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
@ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo")
public class ScopingTestPlain {

    @InjectParameter private Offset offset;
    @Inject private IScopeProvider scopeProvider;

    @ParameterSyntax("('at' offset=OFFSET)?")
    @XpectCommaSeparatedValues
    public Iterable<String> elementsInScope() throws Exception {
      Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent();

        IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond());

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        return actualList;
    }
}
person Peter

// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---
	   Frank, !Jim
--- */
person Jack knows Peter


@RunWith(ParameterizedXtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
                                                                     JUnit 4 Runner
@ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo")
public class ScopingTestPlain {

    @InjectParameter private Offset offset;
    @Inject private IScopeProvider scopeProvider;

    @ParameterSyntax("('at' offset=OFFSET)?")
    @XpectCommaSeparatedValues
    public Iterable<String> elementsInScope() throws Exception {
      Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent();

        IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond());

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        return actualList;
    }
}
person Peter

// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---
	   Frank, !Jim
--- */
person Jack knows Peter


@RunWith(ParameterizedXtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
                                                                     JUnit 4 Runner
@ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo")
public class ScopingTestPlain {

    @InjectParameter private Offset offset;
    @Inject private IScopeProvider scopeProvider;

    @ParameterSyntax("('at' offset=OFFSET)?")                     Folder with DSL-Files
    @XpectCommaSeparatedValues
    public Iterable<String> elementsInScope() throws Exception {
      Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent();

        IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond());

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        return actualList;
    }
}
person Peter

// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---                            Tests as Comments
	   Frank, !Jim
--- */
person Jack knows Peter


@RunWith(ParameterizedXtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
                                                                     JUnit 4 Runner
@ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo")
public class ScopingTestPlain {

    @InjectParameter private Offset offset;
    @Inject private IScopeProvider scopeProvider;

    @ParameterSyntax("('at' offset=OFFSET)?")                     Folder with DSL-Files
    @XpectCommaSeparatedValues
    public Iterable<String> elementsInScope() throws Exception {
      Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent();

        IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond());

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        return actualList;
    }
}
person Peter

// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---
	   Frank, !Jim                                                         Parameters
--- */                                                              STRING, ID, INT, OFFSET
person Jack knows Peter


@RunWith(ParameterizedXtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
@ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo")
public class ScopingTestPlain {

    @InjectParameter private Offset offset;                       Parameter Value
    @Inject private IScopeProvider scopeProvider;

    @ParameterSyntax("('at' offset=OFFSET)?")                     Parameter Syntax
    @XpectCommaSeparatedValues
    public Iterable<String> elementsInScope() throws Exception {
      Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent();

        IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond());

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        return actualList;
    }
}
person Peter

// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---
	   Frank, !Jim                                                         Parameters
--- */                                                              STRING, ID, INT, OFFSET
person Jack knows Peter


@RunWith(ParameterizedXtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
@ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo")
public class ScopingTestPlain {

    @InjectParameter private Offset offset;                       Parameter Value
    @Inject private IScopeProvider scopeProvider;

    @ParameterSyntax("('at' offset=OFFSET)?")                     Parameter Syntax
    @XpectCommaSeparatedValues
    public Iterable<String> elementsInScope() throws Exception {
      Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent();

        IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond());

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        return actualList;                                          Implicit/Explicit
    }
}                                                                     Parameters
person Peter

// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---
	   Frank, !Jim                                                         Expectation
--- */                                                                 SingleLine/MultiLine
person Jack knows Peter


@RunWith(ParameterizedXtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
@ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo")
public class ScopingTestPlain {

    @InjectParameter private Offset offset;
    @Inject private IScopeProvider scopeProvider;
                                                                  Expectation Kind
                                                                  @Xpect, @XpectString,
    @ParameterSyntax("('at' offset=OFFSET)?")                        @XpectLines
    @XpectCommaSeparatedValues
    public Iterable<String> elementsInScope() throws Exception {
      Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent();

        IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond());

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());
        return actualList;
    }
}
                     Actual Value
person Peter

// XPECT elementsInScope at P|eter --> Frank, Peter, Jack
person Frank knows Peter

/* XPECT elementsInScope at P|eter ---
	   Frank, !Jim                                                         Expectation
--- */                                                                 SingleLine/MultiLine
person Jack knows Peter


@RunWith(ParameterizedXtextRunner.class)
@InjectWith(TestDemoInjectorProvider.class)
@ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo")
public class ScopingTestPlain {

    @InjectParameter private Offset offset;
    @Inject private IScopeProvider scopeProvider;
                                                                  Expectation Kind
                                                                  @Xpect, @XpectString,
    @ParameterSyntax("('at' offset=OFFSET)?")                        @XpectLines
    @XpectCommaSeparatedValues
    public Iterable<String> elementsInScope() throws Exception {
      Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent();

        IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond());

        List<String> actualList = Lists.newArrayList();
        for (IEObjectDescription desc : scope.getAllElements())
          actualList.add(desc.getName().toString());                     CaseSensitive?
        return actualList;                                             WhitespaceSensitive?
    }                                                                       Ordered?
}
                     Actual Value
double click here
qualities - a retrospective

                        fast   (depends on developer)



                    specific    (depends on developer)



          efficient to write
       efficient to maintain
  easy to read/understand
self-explanatory on failure!
Eclipse DemoCamp November 2011
 07.11.2011, 18:15 – 22:00 Uhr, Bonn
 08.11.2011, 18:30 – 22:00 Uhr, Dresden
 28.11.2011, 18:30 – 22:00 Uhr, Berlin


Eclipse based DSL Tooling - Meet the Experts
 29.11.2011, 13:30 - 19:00 Uhr, Frankfurt a.M.
Xcore: ECore meets Xtext (Ed Merks)
Verteilte Modellierung mit CDO (Eike Stepper)
Ein Jahr Xtext im Einsatz für HMI-Definition (Stefan Weise & Gerd Zanker)


Embedded Software Engineering-Kongress
 06.12.2011 - 08.12.2011, 09:00 – 18:00 Uhr, Sindelfingen

Contenu connexe

Tendances

Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced JavascriptAdieu
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 
Using Xcore with Xtext
Using Xcore with XtextUsing Xcore with Xtext
Using Xcore with XtextHolger Schill
 
Why TypeScript?
Why TypeScript?Why TypeScript?
Why TypeScript?FITC
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
Lecture 10 - Java Server Faces (JSF)
Lecture 10 - Java Server Faces (JSF)Lecture 10 - Java Server Faces (JSF)
Lecture 10 - Java Server Faces (JSF)Fahad Golra
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHPGuilherme Blanco
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Scott Wlaschin
 
Lets make a better react form
Lets make a better react formLets make a better react form
Lets make a better react formYao Nien Chung
 
PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?Sam Thomas
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass SlidesNir Kaufman
 
Extending the Xbase Typesystem
Extending the Xbase TypesystemExtending the Xbase Typesystem
Extending the Xbase TypesystemSebastian Zarnekow
 

Tendances (20)

Clean code slide
Clean code slideClean code slide
Clean code slide
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
Using Xcore with Xtext
Using Xcore with XtextUsing Xcore with Xtext
Using Xcore with Xtext
 
Why TypeScript?
Why TypeScript?Why TypeScript?
Why TypeScript?
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
The Xtext Grammar Language
The Xtext Grammar LanguageThe Xtext Grammar Language
The Xtext Grammar Language
 
Clean code
Clean codeClean code
Clean code
 
JUnit 5
JUnit 5JUnit 5
JUnit 5
 
TypeScript - An Introduction
TypeScript - An IntroductionTypeScript - An Introduction
TypeScript - An Introduction
 
Lecture 10 - Java Server Faces (JSF)
Lecture 10 - Java Server Faces (JSF)Lecture 10 - Java Server Faces (JSF)
Lecture 10 - Java Server Faces (JSF)
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
 
JPA and Hibernate
JPA and HibernateJPA and Hibernate
JPA and Hibernate
 
Java persistence api 2.1
Java persistence api 2.1Java persistence api 2.1
Java persistence api 2.1
 
Lets make a better react form
Lets make a better react formLets make a better react form
Lets make a better react form
 
PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?PHP unserialization vulnerabilities: What are we missing?
PHP unserialization vulnerabilities: What are we missing?
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
Extending the Xbase Typesystem
Extending the Xbase TypesystemExtending the Xbase Typesystem
Extending the Xbase Typesystem
 

Similaire à Test Xtext scoping

Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartGabriele Lana
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)Danny Preussler
 
Test driven development - JUnit basics and best practices
Test driven development - JUnit basics and best practicesTest driven development - JUnit basics and best practices
Test driven development - JUnit basics and best practicesNarendra Pathai
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testingpleeps
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy PluginsPaul King
 
Using xUnit as a Swiss-Aarmy Testing Toolkit
Using xUnit as a Swiss-Aarmy Testing ToolkitUsing xUnit as a Swiss-Aarmy Testing Toolkit
Using xUnit as a Swiss-Aarmy Testing ToolkitChris Oldwood
 
Testing And Drupal
Testing And DrupalTesting And Drupal
Testing And DrupalPeter Arato
 
Better Code through Lint and Checkstyle
Better Code through Lint and CheckstyleBetter Code through Lint and Checkstyle
Better Code through Lint and CheckstyleMarc Prengemann
 
Static analysis: Around Java in 60 minutes
Static analysis: Around Java in 60 minutesStatic analysis: Around Java in 60 minutes
Static analysis: Around Java in 60 minutesAndrey Karpov
 
Spock: Test Well and Prosper
Spock: Test Well and ProsperSpock: Test Well and Prosper
Spock: Test Well and ProsperKen Kousen
 
Attacks against Microsoft network web clients
Attacks against Microsoft network web clients Attacks against Microsoft network web clients
Attacks against Microsoft network web clients Positive Hack Days
 
Дмитрий Контрерас «Back to the future: the evolution of the Java Type System»
Дмитрий Контрерас «Back to the future: the evolution of the Java Type System»Дмитрий Контрерас «Back to the future: the evolution of the Java Type System»
Дмитрий Контрерас «Back to the future: the evolution of the Java Type System»Anna Shymchenko
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceMaarten Balliauw
 
Advances in Unit Testing: Theory and Practice
Advances in Unit Testing: Theory and PracticeAdvances in Unit Testing: Theory and Practice
Advances in Unit Testing: Theory and PracticeTao Xie
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607Kevin Hazzard
 

Similaire à Test Xtext scoping (20)

Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing Part
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
 
Tdd & unit test
Tdd & unit testTdd & unit test
Tdd & unit test
 
Test driven development - JUnit basics and best practices
Test driven development - JUnit basics and best practicesTest driven development - JUnit basics and best practices
Test driven development - JUnit basics and best practices
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy Plugins
 
Using xUnit as a Swiss-Aarmy Testing Toolkit
Using xUnit as a Swiss-Aarmy Testing ToolkitUsing xUnit as a Swiss-Aarmy Testing Toolkit
Using xUnit as a Swiss-Aarmy Testing Toolkit
 
Testing And Drupal
Testing And DrupalTesting And Drupal
Testing And Drupal
 
Better Code through Lint and Checkstyle
Better Code through Lint and CheckstyleBetter Code through Lint and Checkstyle
Better Code through Lint and Checkstyle
 
Static analysis: Around Java in 60 minutes
Static analysis: Around Java in 60 minutesStatic analysis: Around Java in 60 minutes
Static analysis: Around Java in 60 minutes
 
Spock: Test Well and Prosper
Spock: Test Well and ProsperSpock: Test Well and Prosper
Spock: Test Well and Prosper
 
Attacks against Microsoft network web clients
Attacks against Microsoft network web clients Attacks against Microsoft network web clients
Attacks against Microsoft network web clients
 
Дмитрий Контрерас «Back to the future: the evolution of the Java Type System»
Дмитрий Контрерас «Back to the future: the evolution of the Java Type System»Дмитрий Контрерас «Back to the future: the evolution of the Java Type System»
Дмитрий Контрерас «Back to the future: the evolution of the Java Type System»
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
 
Advances in Unit Testing: Theory and Practice
Advances in Unit Testing: Theory and PracticeAdvances in Unit Testing: Theory and Practice
Advances in Unit Testing: Theory and Practice
 
Junit_.pptx
Junit_.pptxJunit_.pptx
Junit_.pptx
 
Rc2010 tdd
Rc2010 tddRc2010 tdd
Rc2010 tdd
 
Full Text Search In PostgreSQL
Full Text Search In PostgreSQLFull Text Search In PostgreSQL
Full Text Search In PostgreSQL
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607
 

Dernier

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 

Dernier (20)

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 

Test Xtext scoping

  • 1. Test-Driven Development of Xtext DSLs Moritz Eysholdt
  • 2. we strive for... ...product quality ...development speed features fast robustness agile correctness
  • 3. without tests with tests add source code easy easy modify source risky safe code application state large small while debugging
  • 4. without tests with tests add source code easy easy modify source risky safe code application state large small lots of redundancy while debugging architecture may erode maintenance increasingly difficult
  • 5. without tests with tests add source code easy easy extracting small test + debugging may be faster then modify source debugging large scenario risky safe code application state large small while debugging
  • 6. qualities of (unit) tests fast run them locally specific avoid redundancy efficient to write save time efficient to maintain expectations can change easy to read/understand involve domain experts self-explanatory on failure! save time
  • 7. JUnit 4 XtextRunner ParameterizedXtextRunner
  • 8. Test... content assist validation rules scoping quickfixes value conversion formatter parser/AST serializer derived values exported EObjects semantic highlighting typesystem autoedit code generator interpreter
  • 9. Test... content assist validation rules scoping quickfixes value conversion formatter your own code parser/AST serializer integration with framework the framework values derived exported EObjects semantic highlighting typesystem autoedit code generator interpreter
  • 11. person Peter person Frank knows Peter Model: persons+=Person*; Person: 'person' name=ID ('knows' knows=[Person|ID])?;
  • 12. test scoping person Peter person Frank knows Peter Model: persons+=Person*; Person: 'person' name=ID ('knows' knows=[Person|ID])?;
  • 13. StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString);
  • 14. StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference);
  • 15. StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual);
  • 16. @RunWith(XtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; @Inject private IScopeProvider scopeProvider; @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 17. @RunWith(XtextRunner.class) JUnit 4 Runner @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; @Inject private IScopeProvider scopeProvider; @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 18. @RunWith(XtextRunner.class) JUnit 4 Runner @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; Google Guice Injector @Inject private IScopeProvider scopeProvider; Injected Instances @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 19. @RunWith(XtextRunner.class) JUnit 4 Runner @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; Google Guice Injector @Inject private IScopeProvider scopeProvider; Injected Instances @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Backups and Restores Model model = parseHelper.parse(modelString); EMF Registries Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 20. @RunWith(XtextRunner.class) JUnit 4 Runner @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; Google Guice Injector @Inject private IScopeProvider scopeProvider; Injected Instances @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Backups and Restores Model model = parseHelper.parse(modelString); EMF Registries Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); Plain JUnit Test: No OSGi List<String> actualList = Lists.newArrayList(); Injector via StandaloneSetup for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 21. @RunWith(XtextRunner.class) JUnit 4 Runner @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; Google Guice Injector @Inject private IScopeProvider scopeProvider; Injected Instances @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Backups and Restores Model model = parseHelper.parse(modelString); EMF Registries Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); FAST! Plain JUnit Test: No OSGi List<String> actualList = Lists.newArrayList(); Injector via StandaloneSetup for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 22. @RunWith(XtextRunner.class) JUnit 4 Runner @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; Google Guice Injector @Inject private IScopeProvider scopeProvider; Injected Instances @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Backups and Restores Model model = parseHelper.parse(modelString); EMF Registries Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); FAST! Plain JUnit Test: No OSGi List<String> actualList = Lists.newArrayList(); Injector via StandaloneSetup for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); Plug-In JUnit Test: } Eclipse Headless or Workbench } Injector via Activator
  • 23. @RunWith(XtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; @Inject private IScopeProvider scopeProvider; @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 24. @RunWith(XtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; @Inject private IScopeProvider scopeProvider; @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); Exchange Components: Customize InjectorProvider modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); via Components are configured Google Guice Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 25. @RunWith(XtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; @Inject private IScopeProvider scopeProvider; @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); Exchange Components: Customize InjectorProvider modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); via Components are configured Google Guice Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); Mocking Components vs. Reusing Components String actual = Joiner.on(", ").join(actualList); Integration tests don’t hurt when they’re Assert.assertEquals("Peter, Frank", actual); not fragile, but specific and fast } Reusing Parser+Linker is more convenient than creating models programmatically }
  • 26. @RunWith(XtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; @Inject private IScopeProvider scopeProvider; @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); (XtextRunner) Person Java Example peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 27. @RunWith(XtextRunner.class) @RunWith(typeof(XtextRunner)) @InjectWith(TestDemoInjectorProvider.class) @InjectWith(typeof(TestDemoInjectorProvider)) public class ScopingTestPlain { class ScopingTestXtend { @Inject private ParseHelper<Model> parseHelper; @Inject extension ParseHelper<Model> @Inject extension IScopeProvider @Inject private IScopeProvider scopeProvider; @Test @Test public void testScope1() throws Exception { def testScope1() { StringBuilder modelString model = ''' val = new StringBuilder(); modelString.append("person Petern"); person Peter modelString.append("person Frank Frank knows Peter person knows Petern"); Model model = parseHelper.parse(modelString); '''.parse (XtextRunner) Person Java Example peter = model.getPersons().get(0); val scope = getScope(model.persons.head, eINSTANCE.person_Knows) EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); val actual = scope.allElements.map[name.toString].join(", ") IScope scope = scopeProvider.getScope(peter, reference); assertEquals("Peter, Frank", actual); List<String> actualList = Lists.newArrayList(); } for (IEObjectDescription desc : scope.getAllElements()) } actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); } }
  • 28. @RunWith(XtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; Data Flow @Inject private IScopeProvider scopeProvider; @Test public void testScope1() throws Exception { StringBuilder modelString = new StringBuilder(); modelString.append("person Petern"); modelString.append("person Frank knows Petern"); Model model = parseHelper.parse(modelString); prepare Person peter = model.getPersons().get(0); EReference reference = TestDemoPackage.eINSTANCE.getPerson_Knows(); IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); process for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); String actual = Joiner.on(", ").join(actualList); Assert.assertEquals("Peter, Frank", actual); compare } }
  • 29. @RunWith(XtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) public class ScopingTestPlain { @Inject private ParseHelper<Model> parseHelper; Data Flow @Inject private IScopeProvider scopeProvider; @Test public void testScope1() throws Exception { (DSL File) prepare IScope scope = scopeProvider.getScope(peter, reference); List<String> actualList = Lists.newArrayList(); process for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); (DSL File) compare } }
  • 30. person Peter DSL-File // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Frank, !Jim --- */ person Jack knows Peter
  • 31. person Peter DSL-File // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Frank, !Jim --- */ person Jack knows Peter @RunWith(ParameterizedXtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) JUnit 4 Test @ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo") public class ScopingTestPlain { @InjectParameter private Offset offset; @Inject private IScopeProvider scopeProvider; beta @ParameterSyntax("('at' offset=OFFSET)?") @XpectCommaSeparatedValues public Iterable<String> elementsInScope() throws Exception { Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent(); IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond()); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); return actualList; } }
  • 32. person Peter // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Frank, !Jim --- */ person Jack knows Peter @RunWith(ParameterizedXtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) @ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo") public class ScopingTestPlain { @InjectParameter private Offset offset; @Inject private IScopeProvider scopeProvider; @ParameterSyntax("('at' offset=OFFSET)?") @XpectCommaSeparatedValues public Iterable<String> elementsInScope() throws Exception { Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent(); IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond()); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); return actualList; } }
  • 33. person Peter // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Frank, !Jim --- */ person Jack knows Peter @RunWith(ParameterizedXtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) JUnit 4 Runner @ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo") public class ScopingTestPlain { @InjectParameter private Offset offset; @Inject private IScopeProvider scopeProvider; @ParameterSyntax("('at' offset=OFFSET)?") @XpectCommaSeparatedValues public Iterable<String> elementsInScope() throws Exception { Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent(); IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond()); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); return actualList; } }
  • 34. person Peter // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Frank, !Jim --- */ person Jack knows Peter @RunWith(ParameterizedXtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) JUnit 4 Runner @ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo") public class ScopingTestPlain { @InjectParameter private Offset offset; @Inject private IScopeProvider scopeProvider; @ParameterSyntax("('at' offset=OFFSET)?") Folder with DSL-Files @XpectCommaSeparatedValues public Iterable<String> elementsInScope() throws Exception { Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent(); IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond()); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); return actualList; } }
  • 35. person Peter // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Tests as Comments Frank, !Jim --- */ person Jack knows Peter @RunWith(ParameterizedXtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) JUnit 4 Runner @ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo") public class ScopingTestPlain { @InjectParameter private Offset offset; @Inject private IScopeProvider scopeProvider; @ParameterSyntax("('at' offset=OFFSET)?") Folder with DSL-Files @XpectCommaSeparatedValues public Iterable<String> elementsInScope() throws Exception { Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent(); IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond()); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); return actualList; } }
  • 36. person Peter // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Frank, !Jim Parameters --- */ STRING, ID, INT, OFFSET person Jack knows Peter @RunWith(ParameterizedXtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) @ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo") public class ScopingTestPlain { @InjectParameter private Offset offset; Parameter Value @Inject private IScopeProvider scopeProvider; @ParameterSyntax("('at' offset=OFFSET)?") Parameter Syntax @XpectCommaSeparatedValues public Iterable<String> elementsInScope() throws Exception { Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent(); IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond()); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); return actualList; } }
  • 37. person Peter // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Frank, !Jim Parameters --- */ STRING, ID, INT, OFFSET person Jack knows Peter @RunWith(ParameterizedXtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) @ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo") public class ScopingTestPlain { @InjectParameter private Offset offset; Parameter Value @Inject private IScopeProvider scopeProvider; @ParameterSyntax("('at' offset=OFFSET)?") Parameter Syntax @XpectCommaSeparatedValues public Iterable<String> elementsInScope() throws Exception { Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent(); IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond()); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); return actualList; Implicit/Explicit } } Parameters
  • 38. person Peter // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Frank, !Jim Expectation --- */ SingleLine/MultiLine person Jack knows Peter @RunWith(ParameterizedXtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) @ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo") public class ScopingTestPlain { @InjectParameter private Offset offset; @Inject private IScopeProvider scopeProvider; Expectation Kind @Xpect, @XpectString, @ParameterSyntax("('at' offset=OFFSET)?") @XpectLines @XpectCommaSeparatedValues public Iterable<String> elementsInScope() throws Exception { Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent(); IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond()); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); return actualList; } } Actual Value
  • 39. person Peter // XPECT elementsInScope at P|eter --> Frank, Peter, Jack person Frank knows Peter /* XPECT elementsInScope at P|eter --- Frank, !Jim Expectation --- */ SingleLine/MultiLine person Jack knows Peter @RunWith(ParameterizedXtextRunner.class) @InjectWith(TestDemoInjectorProvider.class) @ResourceURIs(baseDir = "testdata/", fileExtensions = "testdemo") public class ScopingTestPlain { @InjectParameter private Offset offset; @Inject private IScopeProvider scopeProvider; Expectation Kind @Xpect, @XpectString, @ParameterSyntax("('at' offset=OFFSET)?") @XpectLines @XpectCommaSeparatedValues public Iterable<String> elementsInScope() throws Exception { Pair<EObject, EStructuralFeature> pair = offset.getEStructuralFeatureByParent(); IScope scope = scopeProvider.getScope(pair.getFirst(), (EReference) pair.getSecond()); List<String> actualList = Lists.newArrayList(); for (IEObjectDescription desc : scope.getAllElements()) actualList.add(desc.getName().toString()); CaseSensitive? return actualList; WhitespaceSensitive? } Ordered? } Actual Value
  • 40.
  • 41.
  • 43. qualities - a retrospective fast (depends on developer) specific (depends on developer) efficient to write efficient to maintain easy to read/understand self-explanatory on failure!
  • 44. Eclipse DemoCamp November 2011 07.11.2011, 18:15 – 22:00 Uhr, Bonn 08.11.2011, 18:30 – 22:00 Uhr, Dresden 28.11.2011, 18:30 – 22:00 Uhr, Berlin Eclipse based DSL Tooling - Meet the Experts 29.11.2011, 13:30 - 19:00 Uhr, Frankfurt a.M. Xcore: ECore meets Xtext (Ed Merks) Verteilte Modellierung mit CDO (Eike Stepper) Ein Jahr Xtext im Einsatz für HMI-Definition (Stefan Weise & Gerd Zanker) Embedded Software Engineering-Kongress 06.12.2011 - 08.12.2011, 09:00 – 18:00 Uhr, Sindelfingen

Notes de l'éditeur

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n