[rspec-devel] [ rspec-Feature Requests-5702 ] Spec generation from a YAML-format spec list proof-of-concept

noreply at rubyforge.org noreply at rubyforge.org
Thu Oct 26 17:30:31 EDT 2006

Feature Requests item #5702, was opened at 2006-09-09 01:53
You can respond by visiting: 

Category: None
Group: None
>Status: Closed
Priority: 3
Submitted By: Eero Saynatkari (esaynatkari)
>Assigned to: Aslak Hellesoy (aslak_hellesoy)
Summary: Spec generation from a YAML-format spec list proof-of-concept

Initial Comment:
Hey. Quick hack, no access to Ruby right now but this
should work--and you get to write the tests :)

I find it much easier to write up the specs in a somewhat
natural-looking syntax first (my thought pattern is not
interrupted by trying to figure out how the spec is to
be tested etc.) so I figured we can generate skeleton
specs this way.

Given a YAML file that looks something like this:

context one:
  - Specification one

This script will generate a 'proper' specification
in the form of

context 'context one' do
  specify 'Specification one' do
    raise NotImplementedError.new('"Specification one"')

If there is a target file given, the script will use
it to write to. If the target file already has contexts
and specifications, the script will do two things: for
all contexts it has that already exist in the file, it
will insert its specifications to the top of that context.
Any non-existing contexts will be appended to the file.

The code should be easy to follow.

#!/usr/bin/env ruby -w

require 'yaml'

# Output an entire context and all its specs
def write_contexts(contexts, out = $stdout)
  # Write the remaining new specs out
  contexts.each {|context, specifications|
    out.puts %{context "#{context}" do} 
    specifications.each {|spec|
      out.puts make_spec(spec)
    }                                 # specifications.each  
    out.puts "end"
  }                                   # data.each
end                                   # context

# Generate one empty spec
def make_spec(spec)
  %{  specify "#{spec}" do\n    raise NotImplementedError.new('"#{spec}"')\n  end}
end                                   # specify

if __FILE__ == $0
  filename = ARGV.shift
  target   = ARGV.shift

  data = YAML.load File.read(filename)

  # Target file
  if target 
    old_data = File.readlines target if File.file? target

    # Overwrite the file interlacing
    File.open(target, 'w') {|f|
      (old_data || []).each {|line|
        # Write the data back
        f.puts line

        # Look for contexts 
        if line =~ /^\s*context\s+('|")(.*?[^\])\1/
          # Check if we have new specs for this context
          if data[$2]
            # Inject the new specs here
            data[$2].each {|spec| f.puts make_spec(spec)}

            # Remove the specs from the equation
            data.delete $2
          end                           # if new specs  
        end                             # if context  
      }                                 # old_data.each 

      # Write the remaining contexts
      write_contexts data, f
    }                                   # open target

  # Direct output
    # Print each context and specification section in turn
    write_contexts data
  end                                 # if target
end                                   # if __FILE__


>Comment By: Aslak Hellesoy (aslak_hellesoy)
Date: 2006-10-26 17:30

We're not going to implement this in the core.


Comment By: Aslak Hellesoy (aslak_hellesoy)
Date: 2006-09-12 16:51

Nifty, but I'm not sold on the utility of this feature. You can achieve similar easy by using macros/live templates in your editor. It's a bit too bells and whistly for my taste.

What do others think?


You can respond by visiting: 

More information about the rspec-devel mailing list