Implementing a Rutema parser

How to implement a parser

In this example we will walk through implementing a parser that extends the capabilities of Rutema::MinimalXMLParser and in the process show you how easy it is.

Adding a step

Lets add a <compare> element to our little testing DSL that will fail if two parameters differ.
We want the element in the specification to be in the form

<compare param1="" param2=""/>

In order to "execute" a step, the parser needs to assign a command to it.
patir offers a Command abstraction that is used by rutema for this purpose.
There are two concrete implementations of it, ShellCommand (which executes commands in a shell) and RubyCommand which wraps ruby code in the Command abstraction. For details check the patir documentation.

For this example lets just add a bit of ruby as our command:

require 'rubygems'
require 'rutema/system'

class SampleParser < Rutema::MinimalXMLParser
  def element_compare step
    #create the command and assign it to the step"compare") do |cmd|
      #the command success is set by the return value of the block
      if step.param1==step.param2
        cmd.error="Things don't match"
Now whenever the parser encounters a compare element it will assign the command and it will be executed when passed to the runner.

Ofcourse the above code has several holes. Always validate the step contents before doing anything:

unless step.has_param1? && step.has_param2?
  raise ParserError,"Missing one of param1/param2 attributes"
You can verify the existence of any attribute by using step.has_attribute_name? - always a good idea!
Errors during parsing should throw a ParserException as above.
Also a good idea is to rescue all exceptions within a RubyCommand and set the cmd.error attribute accordingly.

Using the parser

Assuming you saved your brand new parser in my_brand_new_parser.rb, you use it by replacing the configuration.parser directove with something like the following:

  require 'my_brand_new_parser'
Remember, rutema configuration files are valid ruby code!