This document discusses test-driven development for Xtext domain-specific languages. It recommends testing features like content assist, validation rules, scoping, quickfixes, parsing, serialization, code generation, and integration with frameworks. Tests should be fast, specific, efficient to write and maintain, and make failures self-explanatory. Both plain JUnit tests and plug-in JUnit tests are demonstrated.
Xtext beyond the defaults - how to tackle performance problemsHolger Schill
Nearly every Eclipse user is aware what Xtext is and what it is useful for. It is always a pleasure to see in which kind of areas it is used.
One reason is clearly, that it is really easy to build a first working example in no time. The grammar alone is sufficient and the rest is done by a code generator. Xtext will generate stub classes, that are ready to fill in individual logic for different areas.
By doing that most of the things just work, because Xtext comes with a lot of defaults that suits in most of the cases.
But as projects get bigger and the amount of models grow, the defaults might not scale and you might need to tweak your language to make working smooth again.
Here it becomes more complicated and you need to understand what’s going on under the covers.
In this session I will go through typical problems and solutions, that we have seen in customer projects. Sometimes it’s a tradeoff to tackle those problems, but it’s important to understand the implications.
For some typical examples I will go into details and explain what’s going on under the covers.
After the session attendees should have an idea how to tweak their own languages and why it might be worth the effort to migrate to a newer version of Xtext.
Deep dive into Xtext scoping local and global scopes explainedHolger Schill
In Xtext's grammar language syntax and structure of models are defined at a single location in a very concise way. The nesting structure and the references between objects are expressed which goes beyond plain abstract syntax trees. By just pointing to a type of an object, we describe the shape of a syntax graph. But the grammar alone has no meaning to describe the visibility rules inside of a resource or across resource boundaries. Therefore Xtext has a concept of scopes that are modeled as a chain of responsibility. Xtext comes with a good default scoping semantic that fits for most simple problems, but when the amount of models grows or your problem cannot be handled by the default you have to get in touch with the scoping API. Or as others have said it: Beyond here are dragons.
Most Xtext users know how to implement scoping rules that are applied within the same resource. After all, the API is pretty straight forward. Referencing objects located in other resources is usually more tricky. Here the so called global scope provider is doing it’s job. By default, the global scope contains every object that has a name. Again, that’s good as a starting point and will work in most of the cases, but for serious languages, it doesn't cut it. Memory consumption and performance will play a bigger role as the amount of models grows. There is no turning back: As a language engineer, you really need to understand what’s going on under the covers to define scaling implementations.
In this session we will provide a thorough explaination of the most important concepts of Xtext’s way of scoping. You will learn, that an object might have different names in different contexts and what's behind nested scopes, shadowing and filtering. We will discuss typical problems and solutions along with best practices for scoping. In the end, it's about the right compromise between implementation effort, memory consumption and performance.
Handling Large-Scale State-Management with React Context and HooksRoy Derks
State-management could make your application feel bloated, especially when handled on a large-scale. The React core team has been working hard to add features to take this trouble away. By using the new Context and Hooks feature I'll show how to handle state-management for large scale applications.
Xtext beyond the defaults - how to tackle performance problemsHolger Schill
Nearly every Eclipse user is aware what Xtext is and what it is useful for. It is always a pleasure to see in which kind of areas it is used.
One reason is clearly, that it is really easy to build a first working example in no time. The grammar alone is sufficient and the rest is done by a code generator. Xtext will generate stub classes, that are ready to fill in individual logic for different areas.
By doing that most of the things just work, because Xtext comes with a lot of defaults that suits in most of the cases.
But as projects get bigger and the amount of models grow, the defaults might not scale and you might need to tweak your language to make working smooth again.
Here it becomes more complicated and you need to understand what’s going on under the covers.
In this session I will go through typical problems and solutions, that we have seen in customer projects. Sometimes it’s a tradeoff to tackle those problems, but it’s important to understand the implications.
For some typical examples I will go into details and explain what’s going on under the covers.
After the session attendees should have an idea how to tweak their own languages and why it might be worth the effort to migrate to a newer version of Xtext.
Deep dive into Xtext scoping local and global scopes explainedHolger Schill
In Xtext's grammar language syntax and structure of models are defined at a single location in a very concise way. The nesting structure and the references between objects are expressed which goes beyond plain abstract syntax trees. By just pointing to a type of an object, we describe the shape of a syntax graph. But the grammar alone has no meaning to describe the visibility rules inside of a resource or across resource boundaries. Therefore Xtext has a concept of scopes that are modeled as a chain of responsibility. Xtext comes with a good default scoping semantic that fits for most simple problems, but when the amount of models grows or your problem cannot be handled by the default you have to get in touch with the scoping API. Or as others have said it: Beyond here are dragons.
Most Xtext users know how to implement scoping rules that are applied within the same resource. After all, the API is pretty straight forward. Referencing objects located in other resources is usually more tricky. Here the so called global scope provider is doing it’s job. By default, the global scope contains every object that has a name. Again, that’s good as a starting point and will work in most of the cases, but for serious languages, it doesn't cut it. Memory consumption and performance will play a bigger role as the amount of models grows. There is no turning back: As a language engineer, you really need to understand what’s going on under the covers to define scaling implementations.
In this session we will provide a thorough explaination of the most important concepts of Xtext’s way of scoping. You will learn, that an object might have different names in different contexts and what's behind nested scopes, shadowing and filtering. We will discuss typical problems and solutions along with best practices for scoping. In the end, it's about the right compromise between implementation effort, memory consumption and performance.
Handling Large-Scale State-Management with React Context and HooksRoy Derks
State-management could make your application feel bloated, especially when handled on a large-scale. The React core team has been working hard to add features to take this trouble away. By using the new Context and Hooks feature I'll show how to handle state-management for large scale applications.
Как построить свой фреймворк для автотестов?Dmitry Buzdin
Мы пройдемся по всем основным блокам построения тестового фреймворка и тому, как они связаны между собой. Вы научитесь собирать свое решение по автоматизации из библиотек с открытым кодом и делать так, чтобы они дополняли друг друга.
Test Driven Development - Phương pháp phát triển phần mềm theo hướng viết test trước.
Áp dụng TDD sẽ đem lại cho bạn thiết kế phần mềm trong sáng hơn và quản lý được chất lượng từng dòng code của mình viết ra.
Bài trình bày của bạn Lê Anh tại Meetup của Ha Noi .NET Group.
Chi tiết vui lòng xem tại: http://tungnt.net
Selenide is simple and powerful in use wrapper-library over Selenium. But what the point just of shorter lines of code? In this talk we will see how to tame your webui mustang with Selenide and put it into fence of simple BDD stories with Easyb. We also consider pros and cons of the approach and compare to available alternatives.
Xcore is a textual format to define ecore models. This not only makes editing and reading much more convenient but has other cool advantages as well. Xcore, for instance, allows to embed Xbase expressions to define logic within EOperations and the like.
In this session you will learn, why and when using Xcore is a good idea and how to use it with Xtext languages. I will explain talk about which URIs to use, and how to properly configure the MWE2 file as well as more complicated setups, with multiple languages and mixtures of ecore, xcore and generated models.
This session aims to shed some light to an emerging test automation framework Karate DSL. This framework resolves many of the test automation problems by having API test-automation along with performance-testing and UI Web Automation testing into a single, unified framework.
This presentation walks the reader through implementing a simple web application and its tests using Python, Flask, and the Pytest testing framework. Emphasis is placed on following the process of test-driven development (TDD) in creating the application.
A short presentation slide deck I gave to interns we have this summer of 2019 on (unit) testing in software development. This is not a code-centric slide deck and just looking at the slides loses some context without being there in person, or having discussions, etc.
Real world selenium resume which gets more job interviewsABSoft Trainings
Don’t miss our “Real World Selenium Resume which gets more Job Interviews” where we will discuss what you should put in your Selenium resume and how, what you shouldn't put to make it amazing and excellent. Note that you can easily apply best practices/tips discussed in this post to other profiles, resumes as well like QTP automation tester, manual tester, developer, fresher.
Как построить свой фреймворк для автотестов?Dmitry Buzdin
Мы пройдемся по всем основным блокам построения тестового фреймворка и тому, как они связаны между собой. Вы научитесь собирать свое решение по автоматизации из библиотек с открытым кодом и делать так, чтобы они дополняли друг друга.
Test Driven Development - Phương pháp phát triển phần mềm theo hướng viết test trước.
Áp dụng TDD sẽ đem lại cho bạn thiết kế phần mềm trong sáng hơn và quản lý được chất lượng từng dòng code của mình viết ra.
Bài trình bày của bạn Lê Anh tại Meetup của Ha Noi .NET Group.
Chi tiết vui lòng xem tại: http://tungnt.net
Selenide is simple and powerful in use wrapper-library over Selenium. But what the point just of shorter lines of code? In this talk we will see how to tame your webui mustang with Selenide and put it into fence of simple BDD stories with Easyb. We also consider pros and cons of the approach and compare to available alternatives.
Xcore is a textual format to define ecore models. This not only makes editing and reading much more convenient but has other cool advantages as well. Xcore, for instance, allows to embed Xbase expressions to define logic within EOperations and the like.
In this session you will learn, why and when using Xcore is a good idea and how to use it with Xtext languages. I will explain talk about which URIs to use, and how to properly configure the MWE2 file as well as more complicated setups, with multiple languages and mixtures of ecore, xcore and generated models.
This session aims to shed some light to an emerging test automation framework Karate DSL. This framework resolves many of the test automation problems by having API test-automation along with performance-testing and UI Web Automation testing into a single, unified framework.
This presentation walks the reader through implementing a simple web application and its tests using Python, Flask, and the Pytest testing framework. Emphasis is placed on following the process of test-driven development (TDD) in creating the application.
A short presentation slide deck I gave to interns we have this summer of 2019 on (unit) testing in software development. This is not a code-centric slide deck and just looking at the slides loses some context without being there in person, or having discussions, etc.
Real world selenium resume which gets more job interviewsABSoft Trainings
Don’t miss our “Real World Selenium Resume which gets more Job Interviews” where we will discuss what you should put in your Selenium resume and how, what you shouldn't put to make it amazing and excellent. Note that you can easily apply best practices/tips discussed in this post to other profiles, resumes as well like QTP automation tester, manual tester, developer, fresher.
Test driven development - JUnit basics and best practicesNarendra Pathai
A presentation covering all the basics of Software Unit testing using JUnit framework. A lot of best practices, myths misconceptions are covered. Naming conventions for test methods and fundamental requirements for doing sustainable Junit testing.
Using xUnit as a Swiss-Aarmy Testing ToolkitChris Oldwood
Modern Unit Testing practices act as a conduit for improved software designs that are more amenable to change and can be easily backed by automation for fast feedback on quality assurance. The necessity of reducing external dependencies forces us to design our modules with minimum coupling which can then be leveraged both at the module, component and subsystem levels in our testing. As we start to integrate our units into larger blocks and interface our resulting components with external systems we find ourselves switching nomenclature as we progress from Unit to Integration testing. But is a change in mindset and tooling really required?
The xUnit testing framework is commonly perceived as an aid to Unit Testing but the constraints that it imposes on the architecture mean that it is an excellent mechanism for invoking arbitrary code in a restricted context. Tests can be partitioned by categorisation at the test and fixture level and through physical packaging leading to a flexible test code structure. Throw in its huge popularity and you have a simplified learning curve for expressing more that just unit tests.
Using scenarios from his current system Chris aims to show how you can use a similar format and tooling for unit, component and integration level tests; albeit with a few liberties taken to work around the inherent differences with each methodology.
Presented at the droidcon NYC 2015:
http://droidcon.nyc/2015/dcnyc/25/
Nearly every Android developer has heard of the Lint and Checkstyle tools - however few use either to its full power, if at all. In addition to maintaining a consistent code style, we will see how to enforce architecture conventions and even prevent wrong usage of both internal and your own APIs.
For example, you have a fancy BaseFragment which should be extended by all your Fragments, or you have a custom logger which should be used instead of android.util.Log. Both of these are perfect use cases for custom Lint checks. This session will show you how to configure Checkstyle and Lint to your liking, and how to use their APIs to create custom checks, as well as how to include both in your Gradle-based project.
Static analysis: Around Java in 60 minutesAndrey Karpov
Theory
Code quality (bugs, vulnerabilities)
Methodologies of code protection against defects
Code Review
Static analysis and everything related to it
Tools
Existing tools of static analysis
SonarQube
PVS-Studio for Java what is it?
Several detected examples of code with defects
More about static analysis
Conclusions
Building a friendly .NET SDK to connect to SpaceMaarten Balliauw
Space is a team tool that integrates chats, meetings, git hosting, automation, and more. It has an HTTP API to integrate third party apps and workflows, but it's massive! And slightly opinionated.
In this session, we will see how we built the .NET SDK for Space, and how we make that massive API more digestible. We will see how we used code generation, and incrementally made the API feel more like a real .NET SDK.
A comparison of different solutions for full-text search in web applications using PostgreSQL and other technology. Presented at the PostgreSQL Conference West, in Seattle, October 2009.
Essentials of Automations: Optimizing FME Workflows with ParametersSafe Software
Are you looking to streamline your workflows and boost your projects’ efficiency? Do you find yourself searching for ways to add flexibility and control over your FME workflows? If so, you’re in the right place.
Join us for an insightful dive into the world of FME parameters, a critical element in optimizing workflow efficiency. This webinar marks the beginning of our three-part “Essentials of Automation” series. This first webinar is designed to equip you with the knowledge and skills to utilize parameters effectively: enhancing the flexibility, maintainability, and user control of your FME projects.
Here’s what you’ll gain:
- Essentials of FME Parameters: Understand the pivotal role of parameters, including Reader/Writer, Transformer, User, and FME Flow categories. Discover how they are the key to unlocking automation and optimization within your workflows.
- Practical Applications in FME Form: Delve into key user parameter types including choice, connections, and file URLs. Allow users to control how a workflow runs, making your workflows more reusable. Learn to import values and deliver the best user experience for your workflows while enhancing accuracy.
- Optimization Strategies in FME Flow: Explore the creation and strategic deployment of parameters in FME Flow, including the use of deployment and geometry parameters, to maximize workflow efficiency.
- Pro Tips for Success: Gain insights on parameterizing connections and leveraging new features like Conditional Visibility for clarity and simplicity.
We’ll wrap up with a glimpse into future webinars, followed by a Q&A session to address your specific questions surrounding this topic.
Don’t miss this opportunity to elevate your FME expertise and drive your projects to new heights of efficiency.
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualityInflectra
In this insightful webinar, Inflectra explores how artificial intelligence (AI) is transforming software development and testing. Discover how AI-powered tools are revolutionizing every stage of the software development lifecycle (SDLC), from design and prototyping to testing, deployment, and monitoring.
Learn about:
• The Future of Testing: How AI is shifting testing towards verification, analysis, and higher-level skills, while reducing repetitive tasks.
• Test Automation: How AI-powered test case generation, optimization, and self-healing tests are making testing more efficient and effective.
• Visual Testing: Explore the emerging capabilities of AI in visual testing and how it's set to revolutionize UI verification.
• Inflectra's AI Solutions: See demonstrations of Inflectra's cutting-edge AI tools like the ChatGPT plugin and Azure Open AI platform, designed to streamline your testing process.
Whether you're a developer, tester, or QA professional, this webinar will give you valuable insights into how AI is shaping the future of software delivery.
Let's dive deeper into the world of ODC! Ricardo Alves (OutSystems) will join us to tell all about the new Data Fabric. After that, Sezen de Bruijn (OutSystems) will get into the details on how to best design a sturdy architecture within ODC.
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
As AI technology is pushing into IT I was wondering myself, as an “infrastructure container kubernetes guy”, how get this fancy AI technology get managed from an infrastructure operational view? Is it possible to apply our lovely cloud native principals as well? What benefit’s both technologies could bring to each other?
Let me take this questions and provide you a short journey through existing deployment models and use cases for AI software. On practical examples, we discuss what cloud/on-premise strategy we may need for applying it to our own infrastructure to get it to work from an enterprise perspective. I want to give an overview about infrastructure requirements and technologies, what could be beneficial or limiting your AI use cases in an enterprise environment. An interactive Demo will give you some insides, what approaches I got already working for real.
GraphRAG is All You need? LLM & Knowledge GraphGuy Korland
Guy Korland, CEO and Co-founder of FalkorDB, will review two articles on the integration of language models with knowledge graphs.
1. Unifying Large Language Models and Knowledge Graphs: A Roadmap.
https://arxiv.org/abs/2306.08302
2. Microsoft Research's GraphRAG paper and a review paper on various uses of knowledge graphs:
https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf91mobiles
91mobiles recently conducted a Smart TV Buyer Insights Survey in which we asked over 3,000 respondents about the TV they own, aspects they look at on a new TV, and their TV buying preferences.
JMeter webinar - integration with InfluxDB and GrafanaRTTS
Watch this recorded webinar about real-time monitoring of application performance. See how to integrate Apache JMeter, the open-source leader in performance testing, with InfluxDB, the open-source time-series database, and Grafana, the open-source analytics and visualization application.
In this webinar, we will review the benefits of leveraging InfluxDB and Grafana when executing load tests and demonstrate how these tools are used to visualize performance metrics.
Length: 30 minutes
Session Overview
-------------------------------------------
During this webinar, we will cover the following topics while demonstrating the integrations of JMeter, InfluxDB and Grafana:
- What out-of-the-box solutions are available for real-time monitoring JMeter tests?
- What are the benefits of integrating InfluxDB and Grafana into the load testing stack?
- Which features are provided by Grafana?
- Demonstration of InfluxDB and Grafana using a practice web application
To view the webinar recording, go to:
https://www.rttsweb.com/jmeter-integration-webinar
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...DanBrown980551
Do you want to learn how to model and simulate an electrical network from scratch in under an hour?
Then welcome to this PowSyBl workshop, hosted by Rte, the French Transmission System Operator (TSO)!
During the webinar, you will discover the PowSyBl ecosystem as well as handle and study an electrical network through an interactive Python notebook.
PowSyBl is an open source project hosted by LF Energy, which offers a comprehensive set of features for electrical grid modelling and simulation. Among other advanced features, PowSyBl provides:
- A fully editable and extendable library for grid component modelling;
- Visualization tools to display your network;
- Grid simulation tools, such as power flows, security analyses (with or without remedial actions) and sensitivity analyses;
The framework is mostly written in Java, with a Python binding so that Python developers can access PowSyBl functionalities as well.
What you will learn during the webinar:
- For beginners: discover PowSyBl's functionalities through a quick general presentation and the notebook, without needing any expert coding skills;
- For advanced developers: master the skills to efficiently apply PowSyBl functionalities to your real-world scenarios.
PHP Frameworks: I want to break free (IPC Berlin 2024)Ralf Eggert
In this presentation, we examine the challenges and limitations of relying too heavily on PHP frameworks in web development. We discuss the history of PHP and its frameworks to understand how this dependence has evolved. The focus will be on providing concrete tips and strategies to reduce reliance on these frameworks, based on real-world examples and practical considerations. The goal is to equip developers with the skills and knowledge to create more flexible and future-proof web applications. We'll explore the importance of maintaining autonomy in a rapidly changing tech landscape and how to make informed decisions in PHP development.
This talk is aimed at encouraging a more independent approach to using PHP frameworks, moving towards a more flexible and future-proof approach to PHP development.
Search and Society: Reimagining Information Access for Radical FuturesBhaskar Mitra
The field of Information retrieval (IR) is currently undergoing a transformative shift, at least partly due to the emerging applications of generative AI to information access. In this talk, we will deliberate on the sociotechnical implications of generative AI for information access. We will argue that there is both a critical necessity and an exciting opportunity for the IR community to re-center our research agendas on societal needs while dismantling the artificial separation between the work on fairness, accountability, transparency, and ethics in IR and the rest of IR research. Instead of adopting a reactionary strategy of trying to mitigate potential social harms from emerging technologies, the community should aim to proactively set the research agenda for the kinds of systems we should build inspired by diverse explicitly stated sociotechnical imaginaries. The sociotechnical imaginaries that underpin the design and development of information access technologies needs to be explicitly articulated, and we need to develop theories of change in context of these diverse perspectives. Our guiding future imaginaries must be informed by other academic fields, such as democratic theory and critical theory, and should be co-developed with social science scholars, legal scholars, civil rights and social justice activists, and artists, among others.
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
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
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