./script/story command

Below I’ve pasted a ./script/story command I’ve been using for about a
week. It has three modes of operation:

  1. ./script/story with no arguments will run all *.story files in the
    story path
  2. ./script/story with a path or glob will run the specified stories
  3. If input is passed in via STDIN, it runs that text as a story. This
    opens up story running via a simple interface (Unix pipes) for
    integration with other tools.

This deals with plain text stories only, and does NOT require an
associated .rb runner file for them. Without Ruby runner code for the
stories, the problem becomes figuring out what steps to use with a
given plain text story file. The solution I put together is quite
simple.

I declare groups of step matchers in a separate directory, taking care
to match the step group name to the file name. When a story file is
run, if any steps match a part of the path, they are included. For
example, my story in
RAILS_ROOT/stories/scenarios/schedule_formatting/weekly.story will
attempt to use the step groups “schedule_formatting” and “weekly” if
they exist.

For cases where that convention is not flexible enough, I added
support for including a comment line in the .story file with
instructions for which steps it should be run with. I think about this
kind of like a she-bang line. So the first line of a .story file could
be:

steps: navigations, more_steps

And that will override the default behavior.

I’m posting this because I hope it might be of immediate use to others
using plain text stories right now, and also because I would like to
consider possibilities for getting this functionality into RSpec core.

WDYT?


Bryan H.
http://brynary.com – My blog


#!/usr/bin/env ruby

class StoryCommand
ROOT_PATH = File.expand_path(File.dirname(FILE) + “/…”)

STORIES_PATH = “#{ROOT_PATH}/stories/scenarios”
STEP_MATCHERS_PATH = “#{ROOT_PATH}/stories/steps”
HELPER_PATH = “#{ROOT_PATH}/stories/helper”

def self.run
self.new.run
end

def run
if ARGV.empty? && first_char = using_stdin?
setup_and_run_story((first_char + STDIN.read).split(“\n”))
elsif ARGV.empty?
run_story_files(all_story_files)
else
run_story_files(ARGV)
end
end

def all_story_files
Dir[“#{STORIES_PATH}/**/*.story”].uniq
end

def using_stdin?
char = nil
begin
char = STDIN.read_nonblock(1)
rescue Errno::EAGAIN
return false
end
return char
end

def clean_story_paths(paths)
paths.map! { |path| File.expand_path(path) }
paths.map! { |path| path.gsub(/.story$/, “”) }
paths.map! { |path| path.gsub(/#{STORIES_PATH}//, “”) }
end

def run_story_files(stories)
clean_story_paths(stories).each do |story|
setup_and_run_story(File.readlines(“#{STORIES_PATH}/#{story}.story”),
story)
end
end

def setup_and_run_story(lines, story_name = nil)
require HELPER_PATH

steps = steps_for_story(lines, story_name)
steps.reject! { |step| 

!File.exist?(“#{STEP_MATCHERS_PATH}/#{step}.rb”) }
steps.each { |step| require “#{STEP_MATCHERS_PATH}/#{step}” }

run_story(lines, steps)

end

def steps_for_story(lines, story_name)
if lines.first =~ /^# steps: /
lines.first.gsub(/^# steps: /, “”).split(“,”).map(&:strip)
else
story_name.to_s.split(“/”)
end
end

def run_story(lines, steps)
tempfile = Tempfile.new(“story”)
lines.each do |line|
tempfile.puts line
end
tempfile.close

with_steps_for(*steps.map(&:to_sym)) do
  run tempfile.path, :type => RailsStory
end

end

end

StoryCommand.run

Here’s the steps I followed:

Generated the test code
rails test
mate test
cd test
script/generate scaffold thing
rake db:create
script/server

Modified things_controller.rb index and new:
def index
end
def new
session[:user] = 5
redirect_to(things_path)
end

Set index.html.erb to:
Hello! <%= session[:user] %>
<%= link_to ‘New thing’, new_thing_path %>


Now when I go to the page in FireFox, I see “Hello” on the screen.
Clicking the link gives me “Hello 5” on my screen. This is expected.

However, when I go to Safari, I only ever see “Hello” and never “Hello
5”. I have, in the Safari preferences, accept cookies set to “Accept
All”. I’ve checked everything I can think of to make sure nothing is
blocking it.

I’ve inspected the session and the only thing I can find is that the
Session ID for the Safari requests is a new 32 character string for
every request, and for FireFox requests it’s the same 128 character
string for every request.

I’m using Ruby on Rails 2.0.2. I hope I’m not forgetting some other
useful piece of info.

How do I get this to work for me in Safari?

Thanks,
Glenn

Sorry, I’m new here, but isn’t this totally irrelevant to RSpec in every
way?

On 1/2/08, Glenn F. [email protected] wrote:

Hello! <%= session[:user] %>

Thanks,
Glenn


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users


Giles B.

Podcast: http://hollywoodgrit.blogspot.com
Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com

Whoops, you’re very right, this isn’t the RoR list! Oh well it’s the
only one I ever use. My bad! Let’s look at it this way… my spec’s
are failing because I can’t use session! What do I do? :slight_smile:

Stub like there’s no tomorrow?


Giles B.

Podcast: http://hollywoodgrit.blogspot.com
Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com

I figured it out. My host, or rather my /etc/hosts mapped localhost
url, had an underscore in it. That was causing the problem. I never
new that was bad. Crazy!

Whoops, you’re very right, this isn’t the RoR list! Oh well it’s the
only one I ever use. My bad! Let’s look at it this way… my spec’s
are failing because I can’t use session! What do I do? :slight_smile: