Implementing a DSL in Ruby for generating domain specific XML - ruby

I'd like to implement a DSL in Ruby for generating domain specific XML documents (i.e. XML which conforms to a specific schema). I can use e.g. Builder to write the XML in Ruby, which is already a great improvement on writing the XML manually, but I'd also like:
convenience methods that would generate a whole bunch of XML for me
and possibly a way to restrict the generator to a schema (not necessarily an XSD or a DTD, but the implementation could possibly generate only certain tags)
So my plan at the moment is to extend Builder with the convenience methods and ignore the schema restriction side of things for now.
My questions to the community are does this sounds like a reasonable plan, and more importantly, are there any DSLs out there that extend Builder in some fashion that I could use for inspiration.
Unfortunately googling for ruby, xml, builder, extend, dsl, ... doesn't return very interesting results.

I don't know if it uses Builder, but haml is certainly worth looking.
I also found this article wich mentions many more, of those, probably Markaby is the closest to your idea, but the last commit on github is from 2008. Surely looking at _why's code should be entertaining.

Related

Using Page Objects vs Config Files in Selenium

I've been using Ruby Selenium-Webdriver for one of the automation scripts I'm developing and I'm being asked to use Page Objects, we use page objects a lot however for this application I am using CSV file instead, I have defined all the xpaths that I'm using in my application in a CSV file and I'm parsing that CSV file in my script to refer to those objects, I would like to know is there much of a difference in using a class for defining Page Objects or using a CSV file instead apart from performance concern? I believe using a CSV file will be an addon for us from configuration standpoint and will make it much easier to maintain, any suggestions on this?
Edit - In our use case, we're actually automating applications built on a cloud based tool, so basically all the applications share same design structure from HTML standpoint so we define xpath patterns in CSV and then we pass certain parameters to some custom methods that we've developed to generate xpath's automatically using the CSV instead of finding those manually as its overhead for us because we already know that all the applications will share similar xpath pattern for all elements.
Thanks
I think, POM is better than CSV approach. In POM, you put elements for a page in a separate class file. So, if any change is to make then it's easier to find where to change/maintain. Moreover, it won't get too messy as CSV file and you don't need to use extra utility function to parse those.
There is also a pageobjects gem that provides a set of libraries over and above webdriver/watir, simplifying the code.
Plus, why xpaths? Its one of the last recommended ways to identify an element.
As for the frameork aspect, csv should be more of a maintenance problem than PageObjects. Its the basic difference between text and code. You enforce Object oriented approach on your elements in PageObjects but that is not possible with csv.
In the best case scenario, you have created a column/separate sheets defining which page that element xpath belongs to. That sounds like an overhead. As your application / suite grows there can be thousands of elements. Imagine parsing/ manually updating a csv with that kind of data.
Instead in PageObjects, your elements will be restricted to the Page. Any changes to the app will also specify which elements may get impacted. Now, when define your element as an object in PageObject, rather than css, you also dont need to explicitly create your elements by reading the csv.
It completely depends on the application and the type of test you might perform.
Since it is an automated test script, you do not have to really worry about the performance of the script (it might take few more milli seconds to parse, which should be OK).
Maintaining all the elements identification properties & corresponding actions in a CSV file will make the maintenance easier and make the framework application independent which are nice. But maintaining your framework is bit difficult to make it more robust. Both approaches have its own pros and cons.
Refer to below posts [examples are in java - but you will get the idea]:
Keyword driven framework
Advanced Page Objects
Update:
If you like both, you can comeup with your implementation to easily integrate these too.
#ObjectRepository(src="/login.csv")
public class LoginPage{
private Map<String, WebElement> elements;
public void login(){
elements.get("username").sendKeys('');
elements.get("password").sendKeys('');
elements.get("signin").click();
}
}
Ie, define all the elements in a config file like csv/json etc. Let the page object refer to the class for the page elements. All the methods will be part of the page class.

Sparks+Php-activerecord - is it worth to use it?

I've recently 'discovered' Php-activerecord for use with CodeIgniter (using Sparks).
It is surely an easier way of building queries and getting data in and out of the database
than coding the models for yourself.
So my question is: is somebody using php-activerecord, instead of CodeIgniter's builtin activerecord, for a large project (ie. larger than the typical, tutorialish 'blog' example)?
What pitfals are there, when moving on from CodeIgniter models?
Thanks
ActiveRecord seems to be a well known pattern. In your particular case you should bare in mind, that you no longer need the CodeIgniter AR classes and methods.
Extending the php-activerecord models gives you many standarized methods dealing with your data. That's a good portion of code you would have to type in for yourself over and over again in each project (and beacause of the common CRUD actions, the code would be almost the same).
Great library!
I use it with my current CMS under development.
Once you get your head around relationships its a breeze. Activerecord\Model class is a joy to work with I find, however it would be nice to have a benchmarking wrapper. Really though if you have set your database architecture up right by indexing your foreign keys it should help.
Some nice features
callbacks
eager-loading
I have not personally used php-activerecord but it looks like a good ORM with good documentation. It looks like a nice time saver for larger projects, but for smaller ones i'd probably just stick with the standard activerecord class.

How can I build a friendly nosql ORM without polluting the global scope?

For a while, I've been working on building a little Ruby library to interface with CouchDB, a neat little document database with a HTTP interface. Key features are:
document objects are glorified hashes
the JavaScript Map/Reduce functions are written in native Ruby, and parsed into JavaScript using S Expressions
you can interface with multiple Couch databases
it should integrate well with micro-frameworks like Camping
I want to be able to do something like this:
#recipes = Recipes.all
Where "Recipes" is a class defining a couple of required keys that the document has (the class name is automatically used as a "kind" key).
But then in tough times I might want to do something like this:
#recipes.each do |recipe|
recipe.cost = "too much!!"
recipe.push!
end
Now, obviously to be able to "push" like that, I either need the database to be.. somewhere in scope.. or for the document object itself to hold a reference to the database object? How is this done in well-established ORMs like ActiveRecord?
I don't want to have to do, you know, recipe.push!(#couch_database_object), or whatever, because that's yucky! But I don't wan to be some scope-polluting scumbag.
Any advice?

What separates a Ruby DSL from an ordinary API

What are some defining characteristics of a Ruby DSL that separate it from just a regular API?
When you use an API you instantiate objects and call methods in an imperative manner. On the other hand a good DSL should be declarative, representing rules and relationships in your problem domain, not instructions to be executed. Moreover ideally DSL should be readable and modifiable by somebody who is not a programmer (which is not the case with APIs).
Also please keep in mind the distinction between internal and external DSLs.
Internal domain specific language is embedded in a programming language (eg. Ruby). It's easy to implement, but the structure of the DSL is dependent on the parent language it is embedded in.
External domain specific language is a separate language designed with the particular domain in mind. It gives you a greater flexibility when it comes to syntax, but you have to implement the code to interpret it. It's also more secure, as the person editing domain rules doesn't have access to all the power of the parent language.
DSL (domain specific language) is an over-hyped term. If you are simply using a sub-set of a language (say Ruby), how is it a different language than the original? The answer is, it isn't.
However, if you do some preprocessing of the source text to introduce new syntax or new semantics not found in the core language then you indeed have a new language, which may be domain-specific.
The combination of Ruby's poetry mode and operator overloading does present the possibility of having something that is at the same time legal Ruby syntax and a reasonable DSL.
And the continued aggravation that is XML does show that perhaps the simple DSL built into all those config files wasn't completely misguided..
Creating a DSL:
Adding new methods to the Object class so that you can just call them as if they were built-in language constructs. (see rake)
Creating methods on a custom object or set of objects, and then having script files run the statements in the context of a top-level object. (see capistrano)
API design:
Creating methods on a custom object or set of objects, so the user creates an object to use the methods.
Creating methods as class methods, so that the user prefixes the classname in front of all the methods.
Creating methods as a mixin that users include or extend to use the methods in their custom objects.
So yes, the line is thin between them. It's trivial to turn a custom set of objects into a DSL by adding one method that runs a script file in the right context.
The difference between a DSL and an API to me is that a DSL could be at least understood (and verified) if not written as a sub-language of Ruby by someone in that domain.
For example, you could have financial analysts writing rules for a stock trading application in a Ruby DSL and they would never have to know they were using Ruby.
They are, in fact, the same thing. DSLs are generally implemented via the normal language mechanisms in Ruby, so technically they're all APIs.
However, for people to recognize something as a DSL, it usually ends up adding what look like declarative statements to existing classes. Something like the validators and relationship declarations in ActiveRecord.
class Foo << ActiveRecord::Base
validates_uniqueness_of :name
validates_numericality_of :number, :integer_only => true
end
looks like a DSL, while the following doesn't:
class Foo <<ActiveRecord::BAse
def validate
unless unique? name
errors.add(:name, "must be unique")
end
unless number.to_s.match?(/^[-]?\d$/)
errors.add(:number, "must be an integer")
end
end
end
They're both going to be implemented by normal Ruby code. It's just that one looks like you've got cool new language constructs, while the other seems rather pedestrian (and overly verbose, etc. etc.)

Persistence framework?

I'm trying to decide on the best strategy for accessing the database. I understand that this is a generic question and there's no a single good answer, but I will provide some guidelines on what I'm looking for.
The last few years we have been using our own persistence framework, that although limited has served as well. However it needs some major improvements and I'm wondering if I should go that way or use one of the existing frameworks. The criteria that I'm looking for, in order of importance are:
Client code should work with clean objects, width no database knowledge. When using our custom framework the client code looks like:
SessionManager session = new SessionManager();
Order order = session.CreateEntity();
order.Date = DateTime.Now;
// Set other properties
OrderDetail detail = order.AddOrderDetail();
detail.Product = product;
// Other properties
// Commit all changes now
session.Commit();
Should as simple as possible and not "too flexible". We need a single way to do most things.
Should have good support for object-oriented programming. Should handle one-to-many and many-to-many relations, should handle inheritance, support for lazy loading.
Configuration is preferred to be XML based.
With my current knowledge I see these options:
Improve our current framework - Problem is that it needs a good deal of effort.
ADO.NET Entity Framework - Don't have a good understanding, but seems too complicated and has bad reviews.
LINQ to SQL - Does not have good handling of object-oriented practices.
nHibernate - Seems a good option, but some users report too many archaic errors.
SubSonic - From a short introduction, it seems too flexible. I do not want that.
What will you suggest?
EDIT:
Thank you Craig for the elaborate answer. I think it will help more if I give more details about our custom framework. I'm looking for something similar. This is how our custom framework works:
It is based on DataSets, so the first thing you do is configure the
DataSets and write queries you need there.
You create a XML configuration file that specifies how DataSet tables map to objects and also specify associations between them (support for all types of associations).
3.A custom tool parse the XML configuration and generate the necessary code.
4.Generated classes inherit from a common base class.
To be compatible with our framework the database must meet these criteria:
Each table should have a single column as primary key.
All tables must have a primary key of the same data type generated on the
client.
To handle inheritance only single table inheritance is supported. Also the XML file, almost always offers a single way to achieve something.
What we want to support now is:
Remove the dependency from DataSets. SQL code should be generated automatically but the framework should NOT generate the schema. I want to manually control the DB schema.
More robust support for inheritance hierarchies.
Optional integration with LINQ.
I hope it is clearer now what I'm looking for.
Improve our current framework - Problem is that it needs a good deal of effort
In your question, you have not given a reason why you should rewrite functionality which is available from so many other places. I would suggest that reinventing an ORM is not a good use of your time, unless you have unique needs for the ORM which you have not specified in your question.
ADO.NET Entity Framework
We are using the Entity Framework in the real world, production software. Complicated? No more so than most other ORMs as far as I can tell, which is to say, "fairly complicated." However, it is relatively new, and as such there is less community experience and documentation than something like NHibernate. So the lack of documentation may well make it seem more complicated.
The Entity Framework and NHibernate take distinctly different approaches to the problem of bridging the object-relational divide. I've written about that in a good bit more detail in this blog post. You should consider which approach makes the most sense to you.
There has been a great deal of commentary about the Entity Framework, both positive and negative. Some of it is well-founded, and some of the seems to come from people who are pushing other solutions. The well-founded criticisms include
Lack of POCO support. This is not an issue for some applications, it is an issue for others. POCO support will likely be added in a future release, but today, the best the Entity Framework can offer is IPOCO.
A monolithic mapping file. This hasn't been a big issue for us, since our metadata is not in constant flux.
However, some of the criticisms seem to me to miss the forest for the trees. That is, they talk about features other than the essential functionality of object relational mapping, which the Entity Framework has proven to us to do very well.
LINQ to SQL - Does not have good handling of object-oriented practices
I agree. I also don't like the SQL Server focus.
nHibernate - Seems a good option, but some users report too many archaic errors.
Well, the nice thing about NHibernate is that there is a very vibrant community around it, and when you do encounter those esoteric errors (and believe me, the Entity Framework also has its share of esoteric errors; it seems to come with the territory) you can often find solutions very easily. That said, I don't have a lot of personal experience with NHibernate beyond the evaluation we did which led to us choosing the Entity Framework, so I'm going to let other people with more direct experience comment on this.
SubSonic - From a short introduction, it seems too flexible. I do not want that.
SubSonic is, of course, much more than just an ORM, and SubSonic users have the option of choosing a different ORM implementation instead of using SubSonic's ActiveRecord. As a web application framework, I would consider it. However, its ORM feature is not its raison d'ĂȘtre, and I think it's reasonable to suspect that the ORM portion of SubSonic will get less attention than the dedicated ORM frameworks do.
LLBLGen make very good ORM tool which will do almost all of what you need.
iBATIS is my favourite because you get a better grain of control over the SQL
Developer Express Persistence Objects or XPO as it is most known. I use it for 3 years. It provides everything you need, except that it is commercial and you tie yourself with another (single company) for your development. Other than that, Developer Express is one of the best component and framework providers for the .NET platform.
An example of XPO code would be:
using (UnitOfWork uow = new UnitOfWork())
{
Order order = new Order(uow);
order.Date = DateTime.Now();
uow.CommitChanges();
}
I suggest taking a look at the ActiveRecord from Castle
I don't have production experience with it, I've just played around with their sample app. It seems really easy to work with, but I don't know it well enough to know if it fits all your requirements

Resources