diff --git a/lib/selenium_driver_manager.rb b/lib/selenium_driver_manager.rb new file mode 100644 index 00000000..5019ba3c --- /dev/null +++ b/lib/selenium_driver_manager.rb @@ -0,0 +1,34 @@ +require 'singleton' +require 'selenium' + +class SeleniumDriverManager + include Singleton + + def running_selenium_driver + start + driver + end + + def start + return if running? + driver.start + @running = true + end + + def stop + return unless running? + driver.stop + @running = false + end + + def running? + @running + end + + protected + + def driver + @driver ||= Selenium::SeleniumDriver.new("localhost", 4444, "*chrome", "http://localhost", 15000) + end + +end diff --git a/script/spec b/script/spec new file mode 100755 index 00000000..d8155657 --- /dev/null +++ b/script/spec @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../vendor/plugins/rspec/lib")) +require 'spec' +exit ::Spec::Runner::CommandLine.run(::Spec::Runner::OptionParser.parse(ARGV, STDERR, STDOUT)) diff --git a/script/spec_server b/script/spec_server new file mode 100755 index 00000000..17b56f87 --- /dev/null +++ b/script/spec_server @@ -0,0 +1,116 @@ +#!/usr/bin/env ruby +$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/plugins/rspec/lib' # For rspec installed as plugin +require 'rubygems' +require 'drb/drb' +require 'rbconfig' +require 'spec' +require 'optparse' + +# This is based on Florian Weber's TDDMate +module Spec + module Runner + class RailsSpecServer + def run(argv, stderr, stdout) + $stdout = stdout + $stderr = stderr + + base = ActiveRecord::Base + def base.clear_reloadable_connections! + active_connections.each do |name, conn| + if conn.requires_reloading? + conn.disconnect! + active_connections.delete(name) + end + end + end + + if ActionController.const_defined?(:Dispatcher) + dispatcher = ::ActionController::Dispatcher.new($stdout) + dispatcher.cleanup_application + elsif ::Dispatcher.respond_to?(:reset_application!) + ::Dispatcher.reset_application! + else + raise "Application reloading failed" + end + if Object.const_defined?(:Fixtures) && Fixtures.respond_to?(:reset_cache) + Fixtures.reset_cache + end + + ::Dependencies.mechanism = :load + require_dependency('application.rb') unless Object.const_defined?(:ApplicationController) + load File.dirname(__FILE__) + '/../spec/spec_helper.rb' + + if in_memory_database? + load "#{RAILS_ROOT}/db/schema.rb" # use db agnostic schema by default + ActiveRecord::Migrator.up('db/migrate') # use migrations + end + + ::Spec::Runner::CommandLine.run( + ::Spec::Runner::OptionParser.parse( + argv, + $stderr, + $stdout + ) + ) + end + + def in_memory_database? + ENV["RAILS_ENV"] == "test" and + ::ActiveRecord::Base.connection.class.to_s == "ActiveRecord::ConnectionAdapters::SQLite3Adapter" and + ::Rails::Configuration.new.database_configuration['test']['database'] == ':memory:' + end + end + end +end +puts "Loading Rails environment" + +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'dispatcher' + +def restart_test_server + puts "restarting" + config = ::Config::CONFIG + ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] + command_line = [ruby, $0, ARGV].flatten.join(' ') + exec(command_line) +end + +def daemonize(pid_file = nil) + return yield if $DEBUG + pid = Process.fork{ + Process.setsid + Dir.chdir(RAILS_ROOT) + trap("SIGINT"){ exit! 0 } + trap("SIGTERM"){ exit! 0 } + trap("SIGHUP"){ restart_test_server } + File.open("/dev/null"){|f| + STDERR.reopen f + STDIN.reopen f + STDOUT.reopen f + } + yield + } + puts "spec_server launched. (PID: %d)" % pid + File.open(pid_file,"w"){|f| f.puts pid } if pid_file + exit! 0 +end + +options = Hash.new +opts = OptionParser.new +opts.on("-d", "--daemon"){|v| options[:daemon] = true } +opts.on("-p", "--pid PIDFILE"){|v| options[:pid] = v } +opts.parse!(ARGV) + +puts "Ready" +exec_server = lambda { + trap("USR2") { restart_test_server } if Signal.list.has_key?("USR2") + DRb.start_service("druby://127.0.0.1:8989", Spec::Runner::RailsSpecServer.new) + DRb.thread.join +} + +if options[:daemon] + daemonize(options[:pid], &exec_server) +else + exec_server.call +end diff --git a/script/story b/script/story new file mode 100755 index 00000000..defeee71 --- /dev/null +++ b/script/story @@ -0,0 +1,77 @@ +#!/usr/bin/env ruby +require 'rubygems' + +class StoryCommand + ROOT_PATH = File.expand_path(File.dirname(__FILE__) + "/..") + + STORIES_PATH = "#{ROOT_PATH}/stories" + STEP_MATCHERS_PATH = "#{ROOT_PATH}/stories/steps" + HELPER_PATH = "#{ROOT_PATH}/stories/helper" + DRIVER_MANAGER_PATH = "#{ROOT_PATH}/lib/selenium_driver_manager" + + require DRIVER_MANAGER_PATH + + def self.run + self.new.run + end + + def run + if ARGV.reject { |a| a =~ /^-/ }.any? + run_story_files(ARGV.dup) + else + run_story_files(all_story_files) + end + ensure + SeleniumDriverManager.instance.stop + end + + def all_story_files + Dir["#{STORIES_PATH}/**/*.story"].uniq + end + + def clean_story_paths(paths) + paths.reject! { |path| path =~ /^-/ } + 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) + 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 => SeleniumRailsStory + end + end + +end + +StoryCommand.run \ No newline at end of file diff --git a/spec/rcov.opts b/spec/rcov.opts new file mode 100644 index 00000000..baf694c9 --- /dev/null +++ b/spec/rcov.opts @@ -0,0 +1,2 @@ +--exclude "spec/*,gems/*" +--rails \ No newline at end of file diff --git a/spec/spec.opts b/spec/spec.opts new file mode 100644 index 00000000..391705bf --- /dev/null +++ b/spec/spec.opts @@ -0,0 +1,4 @@ +--colour +--format progress +--loadby mtime +--reverse diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 00000000..938dd7b4 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,47 @@ +# This file is copied to ~/spec when you run 'ruby script/generate rspec' +# from the project root directory. +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'spec' +require 'spec/rails' + +Spec::Runner.configure do |config| + # If you're not using ActiveRecord you should remove these + # lines, delete config/database.yml and disable :active_record + # in your config/boot.rb + config.use_transactional_fixtures = true + config.use_instantiated_fixtures = false + config.fixture_path = RAILS_ROOT + '/spec/fixtures/' + + # == Fixtures + # + # You can declare fixtures for each example_group like this: + # describe "...." do + # fixtures :table_a, :table_b + # + # Alternatively, if you prefer to declare them only once, you can + # do so right here. Just uncomment the next line and replace the fixture + # names with your fixtures. + # + # config.global_fixtures = :table_a, :table_b + # + # If you declare global fixtures, be aware that they will be declared + # for all of your examples, even those that don't use them. + # + # You can also declare which fixtures to use (for example fixtures for test/fixtures): + # + # config.fixture_path = RAILS_ROOT + '/spec/fixtures/' + # + # == Mock Framework + # + # RSpec uses it's own mocking framework by default. If you prefer to + # use mocha, flexmock or RR, uncomment the appropriate line: + # + # config.mock_with :mocha + # config.mock_with :flexmock + # config.mock_with :rr + # + # == Notes + # + # For more information take a look at Spec::Example::Configuration and Spec::Runner +end diff --git a/stories/helper.rb b/stories/helper.rb new file mode 100644 index 00000000..8ad77009 --- /dev/null +++ b/stories/helper.rb @@ -0,0 +1,115 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +$:.unshift File.join(File.dirname(__FILE__), *%w[.. vendor plugings rspec lib]) +require 'test_help' +require 'test/unit/testresult' +require 'spec' +require 'spec/rails' +require 'spec/story' +require 'webrat/selenium' + +module Spec + module Story + class StepGroup + def include_steps_for(name) + require File.expand_path(File.dirname(__FILE__) + "/steps/#{name}") + step_matchers = rspec_story_steps[name.to_sym] + warn "WARNING: 0 step matchers found for include_steps_for(:#{name}). Are you missing an include?" if step_matchers.empty? + self << step_matchers + end + end + end +end + +Test::Unit.run = true + +class SeleniumRailsStory < Test::Unit::TestCase + include Spec::Matchers + include Spec::Rails::Matchers + + def initialize #:nodoc: + # TODO - eliminate this hack, which is here to stop + # Rails Stories from dumping the example summary. + Spec::Runner::Options.class_eval do + def examples_should_be_run? + false + end + end + + @_result = Test::Unit::TestResult.new + end + + def should_see(text_or_regexp) + if text_or_regexp.is_a?(Regexp) + response.should have_tag("*", text_or_regexp) + else + response.should have_tag("*", /#{Regexp.escape(text_or_regexp)}/i) + end + end + + def response + webrat_session.response_body + end + + def method_missing(name, *args) + if webrat_session.respond_to?(name) + webrat_session.send(name, *args) + else + super + end + end + +protected + + def webrat_session + @webrat_session ||= begin + Webrat::SeleniumSession.new(SeleniumDriverManager.instance.running_selenium_driver) + end + end +end + +class DatabaseResetListener + include Singleton + def scenario_started(*args) + if defined?(ActiveRecord::Base) + connection = ActiveRecord::Base.connection + %w[users].each do |table| + connection.execute "DELETE FROM #{table}" + end + end + end + + def scenario_succeeded(*args) + end + alias :scenario_pending :scenario_succeeded + alias :scenario_failed :scenario_succeeded +end + +class CookieResetListener + include Singleton + def scenario_started(*args) + %w[tracks_login auth_token _session_id].each do |cookie_name| + SeleniumDriverManager.instance.running_selenium_driver.get_eval("window.document.cookie = '#{cookie_name}=;expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/';") + end + end + + def scenario_succeeded(*args) + end + alias :scenario_pending :scenario_succeeded + alias :scenario_failed :scenario_succeeded +end + +class Spec::Story::Runner::ScenarioRunner + def initialize + @listeners = [DatabaseResetListener.instance, CookieResetListener.instance] + end +end + +class Spec::Story::GivenScenario + def perform(instance, name = nil) + scenario = Spec::Story::Runner::StoryRunner.scenario_from_current_story @name + runner = Spec::Story::Runner::ScenarioRunner.new + runner.instance_variable_set(:@listeners,[]) + runner.run(scenario, instance) + end +end diff --git a/stories/login/first_run.story b/stories/login/first_run.story new file mode 100644 index 00000000..ca1ed89b --- /dev/null +++ b/stories/login/first_run.story @@ -0,0 +1,15 @@ +Story: First run shows admin signup + + As a user who just installed Tracks + I want to create an admin account + So that I have control over all preferences and users + + Scenario: Successful signup + Given no users exist + And a visitor named Reinier + When Reinier visits the site + Then he should see a signup form + When Reinier successfully submits the signup form + Then Reinier should see the tasks listing page + And Reinier should be an admin + \ No newline at end of file diff --git a/stories/login/logging_in.story b/stories/login/logging_in.story new file mode 100644 index 00000000..c6235100 --- /dev/null +++ b/stories/login/logging_in.story @@ -0,0 +1,22 @@ +Story: Existing user logging in + + As an existing user + I want to log in with my username and password + So that I can securely get things done + + Scenario: Login success + Given an admin user Reinier with the password abracadabra + And Reinier is not logged in + When Reinier visits the login page + And Reinier successfully submits the login form + Then Reinier should see the tasks listing page + And Reinier should see the message Login successful + + Scenario: Login failure + Given an admin user Reinier with the password abracadabra + And Reinier is not logged in + When Reinier visits the login page + And Reinier submits the login form with an incorrect password + Then Reinier should see the login page again + And Reinier should see the message Login unsuccessful + \ No newline at end of file diff --git a/stories/steps/login.rb b/stories/steps/login.rb new file mode 100644 index 00000000..42599521 --- /dev/null +++ b/stories/steps/login.rb @@ -0,0 +1,68 @@ +steps_for :login do + Given "an admin user Reinier with the password abracadabra" do + @reinier = User.create!(:login => 'reinier', :password => 'abracadabra', :password_confirmation => 'abracadabra', :is_admin => true) + @reinier.create_preference + end + + Given "Reinier is not logged in" do + end + + Given "no users exist" do + User.delete_all + end + + Given "a visitor named Reinier" do + end + + When "Reinier submits the login form with an incorrect password" do + fills_in 'Login', :with => 'reinier' + fills_in 'Password', :with => 'incorrectpass' + clicks_button + end + + When "Reinier visits the login page" do + visits '/login' + end + + When "Reinier successfully submits the login form" do + fills_in 'Login', :with => 'reinier' + fills_in 'Password', :with => 'abracadabra' + clicks_button + end + + When "Reinier visits the site" do + visits '/' + end + + When "Reinier successfully submits the signup form" do + fills_in 'Desired login', :with => 'reinier' + fills_in 'Choose password', :with => 'abracadabra' + fills_in 'Confirm password', :with => 'abracadabra' + clicks_button + end + + Then "he should see a signup form" do + should_see 'create an admin account' + end + + Then "Reinier should see the tasks listing page" do + response.should have_tag('title', /list tasks/i) + end + + Then "Reinier should be an admin" do + response.should have_tag('a', /Admin/i) + end + + Then "Reinier should see the message Login successful" do + should_see 'Login successful' + end + + Then "Reinier should see the login page again" do + response.should have_tag('title', /login/i) + end + + Then "Reinier should see the message Login unsuccessful" do + should_see 'Login unsuccessful' + end + +end \ No newline at end of file diff --git a/test/selenium/login/first_run_shows_signup.rsel b/test/selenium/login/first_run_shows_signup.rsel deleted file mode 100644 index 64d328c0..00000000 --- a/test/selenium/login/first_run_shows_signup.rsel +++ /dev/null @@ -1,8 +0,0 @@ -setup :clear_tables => [:users, :preferences] -open '/' -assert_title 'exact:TRACKS::Sign up as the admin user' -type "user_login", "admin" -type "user_password", "abracadabra" -type "user_password_confirmation", "abracadabra" -click_and_wait "signup" -assert_title 'exact:TRACKS::List tasks' diff --git a/test/selenium/login/login_failure.rsel b/test/selenium/login/login_failure.rsel deleted file mode 100644 index 1c2e5f8b..00000000 --- a/test/selenium/login/login_failure.rsel +++ /dev/null @@ -1,9 +0,0 @@ -setup :fixtures => :all -open :controller => 'login', :action => 'logout' -open :controller => 'login' -assert_title 'exact:TRACKS::Login' -type "user_login", "admin" -type "user_password", "incorrect_password" -click_and_wait "login" -assert_title 'exact:TRACKS::Login' -verify_text_present 'Login unsuccessful' diff --git a/test/selenium/login/login_success.rsel b/test/selenium/login/login_success.rsel deleted file mode 100644 index bad10df4..00000000 --- a/test/selenium/login/login_success.rsel +++ /dev/null @@ -1,12 +0,0 @@ -setup :fixtures => :all -open :controller => 'login', :action => 'logout' -open :controller => 'login' -assert_title 'exact:TRACKS::Login' -type "user_login", "admin" -type "user_password", "abracadabra" -click_and_wait "login" -assert_title 'exact:TRACKS::List tasks' -wait_for_visible "flash" -wait_for_text "flash", "Login successful: session will not expire." -#next line slows down the test unacceptably, but is useful in ensuring that the message disappears. -#wait_for_not_visible "flash" \ No newline at end of file diff --git a/vendor/plugins/rspec-rails/.gitignore b/vendor/plugins/rspec-rails/.gitignore new file mode 100644 index 00000000..8c6c23dc --- /dev/null +++ b/vendor/plugins/rspec-rails/.gitignore @@ -0,0 +1,4 @@ +tmtags +.DS_Store +.emacs-project +*~ diff --git a/vendor/plugins/rspec-rails/CHANGES b/vendor/plugins/rspec-rails/CHANGES new file mode 100644 index 00000000..23db2de6 --- /dev/null +++ b/vendor/plugins/rspec-rails/CHANGES @@ -0,0 +1,26 @@ +== Version 1.1.5 + +* Add conditional so Rails 2.1.0 doesn't warn about cache_template_extensions (patch from James Herdman) +* Fixed stub_model examples to work with Rails 2.1.0 (the code was fine, just the spec needed patching) + +== Version 1.1.4 + +Maintenance release. + +* Moved mock_model and stub_model to their own module: Spec::Rails::Mocks +* Setting mock_model object id with stubs hash - patch from Adam Meehan +* Added as_new_record to stub_model e.g. stub_model(Foo).as_new_record +* Improved stub_model such that new_record? does "the right thing" +* Patch from Pat Maddox to get integrate_views to work in nested example groups. +* Patch from Pat Maddox to get controller_name to work in nested example groups. +* Patch from Corey Haines to add include_text matcher +* Added stub_model method which creates a real model instance with :id stubbed and data access prohibited. +* Applied patch from Pat Maddox to handle redirect_to w/ SSL. Closes #320. +* Added #helper and #assigns to helper specs. +* Applied patch from Bryan Helmkamp to tweak format of generated spec.opts to be more obvious. Closes #162. +* Tweaked list of exceptions (ignores) for autotest +* Applied patch from Rick Olson to get rspec_on_rails working with rails edge (>= 8862) +* Applied patch from Wincent Colaiuta to invert sense of "spec --diff". Closes #281. +* Allow any type of render in view specs. Closes #57. +* Applied patch from Ian White to get rspec working with edge rails (8804). Closes #271. +* Applied patch from Jon Strother to have spec_server reload fixtures. Closes #344. \ No newline at end of file diff --git a/vendor/plugins/rspec-rails/MIT-LICENSE b/vendor/plugins/rspec-rails/MIT-LICENSE new file mode 100644 index 00000000..239d8e7e --- /dev/null +++ b/vendor/plugins/rspec-rails/MIT-LICENSE @@ -0,0 +1,31 @@ +==================================================================== +== RSpec +Copyright (c) 2005-2007 The RSpec Development Team +==================================================================== +== ARTS +Copyright (c) 2006 Kevin Clark, Jake Howerton +==================================================================== +== ZenTest +Copyright (c) 2001-2006 Ryan Davis, Eric Hodel, Zen Spider Software +==================================================================== +== AssertSelect +Copyright (c) 2006 Assaf Arkin +==================================================================== + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/plugins/rspec-rails/README b/vendor/plugins/rspec-rails/README new file mode 100644 index 00000000..9008b8a5 --- /dev/null +++ b/vendor/plugins/rspec-rails/README @@ -0,0 +1,3 @@ +See the rdoc for Spec::Rails for usage documentation. + +See ~/rspec/README for instructions on running rspec_on_rails' examples. \ No newline at end of file diff --git a/vendor/plugins/rspec-rails/Rakefile b/vendor/plugins/rspec-rails/Rakefile new file mode 100644 index 00000000..39b5d225 --- /dev/null +++ b/vendor/plugins/rspec-rails/Rakefile @@ -0,0 +1,9 @@ +require 'rake' +require 'rake/rdoctask' + +desc 'Generate RDoc' +rd = Rake::RDocTask.new do |rdoc| + rdoc.rdoc_dir = '../doc/output/rdoc-rails' + rdoc.options << '--title' << 'Spec::Rails' << '--line-numbers' << '--inline-source' << '--main' << 'Spec::Rails' + rdoc.rdoc_files.include('MIT-LICENSE', 'lib/**/*.rb') +end diff --git a/vendor/plugins/rspec-rails/generators/rspec/CHANGES b/vendor/plugins/rspec-rails/generators/rspec/CHANGES new file mode 100644 index 00000000..69f37090 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec/CHANGES @@ -0,0 +1 @@ +Please refer to the CHANGES file for RSpec's core \ No newline at end of file diff --git a/vendor/plugins/rspec-rails/generators/rspec/rspec_generator.rb b/vendor/plugins/rspec-rails/generators/rspec/rspec_generator.rb new file mode 100644 index 00000000..d5512e38 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec/rspec_generator.rb @@ -0,0 +1,35 @@ +require 'rbconfig' + +# This generator bootstraps a Rails project for use with RSpec +class RspecGenerator < Rails::Generator::Base + DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], + Config::CONFIG['ruby_install_name']) + + def initialize(runtime_args, runtime_options = {}) + super + end + + def manifest + record do |m| + script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] } + + m.directory 'spec' + m.template 'spec_helper.rb', 'spec/spec_helper.rb' + m.file 'spec.opts', 'spec/spec.opts' + m.file 'rcov.opts', 'spec/rcov.opts' + m.file 'script/spec_server', 'script/spec_server', script_options + m.file 'script/spec', 'script/spec', script_options + + m.directory 'stories' + m.file 'all_stories.rb', 'stories/all.rb' + m.file 'stories_helper.rb', 'stories/helper.rb' + end + end + +protected + + def banner + "Usage: #{$0} rspec" + end + +end diff --git a/vendor/plugins/rspec-rails/generators/rspec/templates/all_stories.rb b/vendor/plugins/rspec-rails/generators/rspec/templates/all_stories.rb new file mode 100644 index 00000000..2e8f46a4 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec/templates/all_stories.rb @@ -0,0 +1,4 @@ +dir = File.dirname(__FILE__) +Dir[File.expand_path("#{dir}/**/*.rb")].uniq.each do |file| + require file +end \ No newline at end of file diff --git a/vendor/plugins/rspec-rails/generators/rspec/templates/previous_failures.txt b/vendor/plugins/rspec-rails/generators/rspec/templates/previous_failures.txt new file mode 100644 index 00000000..e69de29b diff --git a/vendor/plugins/rspec-rails/generators/rspec/templates/rcov.opts b/vendor/plugins/rspec-rails/generators/rspec/templates/rcov.opts new file mode 100644 index 00000000..baf694c9 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec/templates/rcov.opts @@ -0,0 +1,2 @@ +--exclude "spec/*,gems/*" +--rails \ No newline at end of file diff --git a/vendor/plugins/rspec-rails/generators/rspec/templates/script/spec b/vendor/plugins/rspec-rails/generators/rspec/templates/script/spec new file mode 100644 index 00000000..d8155657 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec/templates/script/spec @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../vendor/plugins/rspec/lib")) +require 'spec' +exit ::Spec::Runner::CommandLine.run(::Spec::Runner::OptionParser.parse(ARGV, STDERR, STDOUT)) diff --git a/vendor/plugins/rspec-rails/generators/rspec/templates/script/spec_server b/vendor/plugins/rspec-rails/generators/rspec/templates/script/spec_server new file mode 100644 index 00000000..17b56f87 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec/templates/script/spec_server @@ -0,0 +1,116 @@ +#!/usr/bin/env ruby +$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/plugins/rspec/lib' # For rspec installed as plugin +require 'rubygems' +require 'drb/drb' +require 'rbconfig' +require 'spec' +require 'optparse' + +# This is based on Florian Weber's TDDMate +module Spec + module Runner + class RailsSpecServer + def run(argv, stderr, stdout) + $stdout = stdout + $stderr = stderr + + base = ActiveRecord::Base + def base.clear_reloadable_connections! + active_connections.each do |name, conn| + if conn.requires_reloading? + conn.disconnect! + active_connections.delete(name) + end + end + end + + if ActionController.const_defined?(:Dispatcher) + dispatcher = ::ActionController::Dispatcher.new($stdout) + dispatcher.cleanup_application + elsif ::Dispatcher.respond_to?(:reset_application!) + ::Dispatcher.reset_application! + else + raise "Application reloading failed" + end + if Object.const_defined?(:Fixtures) && Fixtures.respond_to?(:reset_cache) + Fixtures.reset_cache + end + + ::Dependencies.mechanism = :load + require_dependency('application.rb') unless Object.const_defined?(:ApplicationController) + load File.dirname(__FILE__) + '/../spec/spec_helper.rb' + + if in_memory_database? + load "#{RAILS_ROOT}/db/schema.rb" # use db agnostic schema by default + ActiveRecord::Migrator.up('db/migrate') # use migrations + end + + ::Spec::Runner::CommandLine.run( + ::Spec::Runner::OptionParser.parse( + argv, + $stderr, + $stdout + ) + ) + end + + def in_memory_database? + ENV["RAILS_ENV"] == "test" and + ::ActiveRecord::Base.connection.class.to_s == "ActiveRecord::ConnectionAdapters::SQLite3Adapter" and + ::Rails::Configuration.new.database_configuration['test']['database'] == ':memory:' + end + end + end +end +puts "Loading Rails environment" + +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'dispatcher' + +def restart_test_server + puts "restarting" + config = ::Config::CONFIG + ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] + command_line = [ruby, $0, ARGV].flatten.join(' ') + exec(command_line) +end + +def daemonize(pid_file = nil) + return yield if $DEBUG + pid = Process.fork{ + Process.setsid + Dir.chdir(RAILS_ROOT) + trap("SIGINT"){ exit! 0 } + trap("SIGTERM"){ exit! 0 } + trap("SIGHUP"){ restart_test_server } + File.open("/dev/null"){|f| + STDERR.reopen f + STDIN.reopen f + STDOUT.reopen f + } + yield + } + puts "spec_server launched. (PID: %d)" % pid + File.open(pid_file,"w"){|f| f.puts pid } if pid_file + exit! 0 +end + +options = Hash.new +opts = OptionParser.new +opts.on("-d", "--daemon"){|v| options[:daemon] = true } +opts.on("-p", "--pid PIDFILE"){|v| options[:pid] = v } +opts.parse!(ARGV) + +puts "Ready" +exec_server = lambda { + trap("USR2") { restart_test_server } if Signal.list.has_key?("USR2") + DRb.start_service("druby://127.0.0.1:8989", Spec::Runner::RailsSpecServer.new) + DRb.thread.join +} + +if options[:daemon] + daemonize(options[:pid], &exec_server) +else + exec_server.call +end diff --git a/vendor/plugins/rspec-rails/generators/rspec/templates/spec.opts b/vendor/plugins/rspec-rails/generators/rspec/templates/spec.opts new file mode 100644 index 00000000..391705bf --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec/templates/spec.opts @@ -0,0 +1,4 @@ +--colour +--format progress +--loadby mtime +--reverse diff --git a/vendor/plugins/rspec-rails/generators/rspec/templates/spec_helper.rb b/vendor/plugins/rspec-rails/generators/rspec/templates/spec_helper.rb new file mode 100644 index 00000000..938dd7b4 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec/templates/spec_helper.rb @@ -0,0 +1,47 @@ +# This file is copied to ~/spec when you run 'ruby script/generate rspec' +# from the project root directory. +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'spec' +require 'spec/rails' + +Spec::Runner.configure do |config| + # If you're not using ActiveRecord you should remove these + # lines, delete config/database.yml and disable :active_record + # in your config/boot.rb + config.use_transactional_fixtures = true + config.use_instantiated_fixtures = false + config.fixture_path = RAILS_ROOT + '/spec/fixtures/' + + # == Fixtures + # + # You can declare fixtures for each example_group like this: + # describe "...." do + # fixtures :table_a, :table_b + # + # Alternatively, if you prefer to declare them only once, you can + # do so right here. Just uncomment the next line and replace the fixture + # names with your fixtures. + # + # config.global_fixtures = :table_a, :table_b + # + # If you declare global fixtures, be aware that they will be declared + # for all of your examples, even those that don't use them. + # + # You can also declare which fixtures to use (for example fixtures for test/fixtures): + # + # config.fixture_path = RAILS_ROOT + '/spec/fixtures/' + # + # == Mock Framework + # + # RSpec uses it's own mocking framework by default. If you prefer to + # use mocha, flexmock or RR, uncomment the appropriate line: + # + # config.mock_with :mocha + # config.mock_with :flexmock + # config.mock_with :rr + # + # == Notes + # + # For more information take a look at Spec::Example::Configuration and Spec::Runner +end diff --git a/vendor/plugins/rspec-rails/generators/rspec/templates/stories_helper.rb b/vendor/plugins/rspec-rails/generators/rspec/templates/stories_helper.rb new file mode 100644 index 00000000..da7a13a6 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec/templates/stories_helper.rb @@ -0,0 +1,3 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'spec/rails/story_adapter' \ No newline at end of file diff --git a/vendor/plugins/rspec-rails/generators/rspec_controller/USAGE b/vendor/plugins/rspec-rails/generators/rspec_controller/USAGE new file mode 100755 index 00000000..1546c325 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_controller/USAGE @@ -0,0 +1,33 @@ +Description: + The rspec_controller generator creates stub specs and files for a new + controller and its views. + + The generator takes a controller name and a list of views as arguments. + The controller name may be given in CamelCase or under_score and should + not be suffixed with 'Controller'. To create a controller within a + module, specify the controller name as 'module/controller'. + + The generator creates stubs for a controller (and spec), a view (and spec) + for each view in the argument list, plus a helper. + +Example: + ./script/generate rspec_controller dog bark fetch + ... + create spec/controllers/dog_controller_spec.rb + create app/controllers/dog_controller.rb + create app/helpers/dog_helper.rb + create spec/views/dog/bark_view_spec.rb + create app/views/dog/bark.rhtml + create spec/views/dog/fetch_view_spec.rb + create app/views/dog/fetch.rhtml + +Modules Example: + ./script/generate rspec_controller 'pets/dog' bark fetch + ... + create spec/controllers/pets/dog_controller_spec.rb + create app/controllers/pets/dog_controller.rb + create app/helpers/pets/dog_helper.rb + create spec/views/pets/dog/bark_view_spec.rb + create app/views/pets/dog/bark.rhtml + create spec/views/pets/dog/fetch_view_spec.rb + create app/views/pets/dog/fetch.rhtml diff --git a/vendor/plugins/rspec-rails/generators/rspec_controller/rspec_controller_generator.rb b/vendor/plugins/rspec-rails/generators/rspec_controller/rspec_controller_generator.rb new file mode 100755 index 00000000..93348305 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_controller/rspec_controller_generator.rb @@ -0,0 +1,49 @@ +require 'rails_generator/generators/components/controller/controller_generator' + +class RspecControllerGenerator < ControllerGenerator + + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, "#{class_name}Controller", "#{class_name}Helper" + + # Controller, helper, views, and spec directories. + m.directory File.join('app/controllers', class_path) + m.directory File.join('app/helpers', class_path) + m.directory File.join('app/views', class_path, file_name) + m.directory File.join('spec/controllers', class_path) + m.directory File.join('spec/helpers', class_path) + m.directory File.join('spec/views', class_path, file_name) + + if Rails::VERSION::STRING < "2.0.0" + @default_file_extension = "rhtml" + else + @default_file_extension = "html.erb" + end + + # Controller spec, class, and helper. + m.template 'controller_spec.rb', + File.join('spec/controllers', class_path, "#{file_name}_controller_spec.rb") + + m.template 'helper_spec.rb', + File.join('spec/helpers', class_path, "#{file_name}_helper_spec.rb") + + m.template 'controller:controller.rb', + File.join('app/controllers', class_path, "#{file_name}_controller.rb") + + m.template 'controller:helper.rb', + File.join('app/helpers', class_path, "#{file_name}_helper.rb") + + # Spec and view template for each action. + actions.each do |action| + m.template 'view_spec.rb', + File.join('spec/views', class_path, file_name, "#{action}.#{@default_file_extension}_spec.rb"), + :assigns => { :action => action, :model => file_name } + path = File.join('app/views', class_path, file_name, "#{action}.#{@default_file_extension}") + m.template "controller:view.#{@default_file_extension}", + path, + :assigns => { :action => action, :path => path } + end + end + end +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_controller/templates/controller_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_controller/templates/controller_spec.rb new file mode 100755 index 00000000..cb25fe77 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_controller/templates/controller_spec.rb @@ -0,0 +1,25 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper') + +describe <%= class_name %>Controller do + +<% if actions.empty? -%> + #Delete this example and add some real ones +<% else -%> + #Delete these examples and add some real ones +<% end -%> + it "should use <%= class_name %>Controller" do + controller.should be_an_instance_of(<%= class_name %>Controller) + end + +<% unless actions.empty? -%> +<% for action in actions -%> + + describe "GET '<%= action %>'" do + it "should be successful" do + get '<%= action %>' + response.should be_success + end + end +<% end -%> +<% end -%> +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_controller/templates/helper_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_controller/templates/helper_spec.rb new file mode 100644 index 00000000..11c65048 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_controller/templates/helper_spec.rb @@ -0,0 +1,11 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper') + +describe <%= class_name %>Helper do + + #Delete this example and add some real ones or delete this file + it "should be included in the object returned by #helper" do + included_modules = (class << helper; self; end).send :included_modules + included_modules.should include(<%= class_name %>Helper) + end + +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_controller/templates/view_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_controller/templates/view_spec.rb new file mode 100644 index 00000000..d550d6a1 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_controller/templates/view_spec.rb @@ -0,0 +1,12 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper') + +describe "/<%= class_name.underscore %>/<%= action %>" do + before(:each) do + render '<%= class_name.underscore %>/<%= action %>' + end + + #Delete this example and add some real ones or delete this file + it "should tell you where to find the file" do + response.should have_tag('p', %r[Find me in app/views/<%= class_name.underscore %>/<%= action %>]) + end +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_model/USAGE b/vendor/plugins/rspec-rails/generators/rspec_model/USAGE new file mode 100755 index 00000000..a7b78141 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_model/USAGE @@ -0,0 +1,18 @@ +Description: + The rspec_model generator creates stubs for a new model. + + The generator takes a model name as its argument. The model name may be + given in CamelCase or under_score and should not be suffixed with 'Model'. + + The generator creates a model class in app/models, an RSpec spec in + spec/models, database fixtures in spec/fixtures/plural_name.yml, and a migration + in db/migrate. + +Example: + ./script/generate rspec_model Account + + This will create an Account model: + Model: app/models/account.rb + Spec: spec/models/account_spec.rb + Fixtures: spec/fixtures/accounts.yml + Migration: db/migrate/XXX_add_accounts.rb diff --git a/vendor/plugins/rspec-rails/generators/rspec_model/rspec_model_generator.rb b/vendor/plugins/rspec-rails/generators/rspec_model/rspec_model_generator.rb new file mode 100755 index 00000000..7f5e3494 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_model/rspec_model_generator.rb @@ -0,0 +1,30 @@ +require 'rails_generator/generators/components/model/model_generator' + +class RspecModelGenerator < ModelGenerator + + def manifest + + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, class_name + + # Model, spec, and fixture directories. + m.directory File.join('app/models', class_path) + m.directory File.join('spec/models', class_path) + m.directory File.join('spec/fixtures', class_path) + + # Model class, spec and fixtures. + m.template 'model:model.rb', File.join('app/models', class_path, "#{file_name}.rb") + m.template 'model:fixtures.yml', File.join('spec/fixtures', class_path, "#{table_name}.yml") + m.template 'model_spec.rb', File.join('spec/models', class_path, "#{file_name}_spec.rb") + + unless options[:skip_migration] + m.migration_template 'model:migration.rb', 'db/migrate', :assigns => { + :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}" + }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}" + end + + end + end + +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_model/templates/model_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_model/templates/model_spec.rb new file mode 100755 index 00000000..648908b4 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_model/templates/model_spec.rb @@ -0,0 +1,11 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper') + +describe <%= class_name %> do + before(:each) do + @<%= file_name %> = <%= class_name %>.new + end + + it "should be valid" do + @<%= file_name %>.should be_valid + end +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_scaffold/rspec_scaffold_generator.rb b/vendor/plugins/rspec-rails/generators/rspec_scaffold/rspec_scaffold_generator.rb new file mode 100644 index 00000000..0dab8250 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_scaffold/rspec_scaffold_generator.rb @@ -0,0 +1,167 @@ +class RspecScaffoldGenerator < Rails::Generator::NamedBase + default_options :skip_migration => false + + attr_reader :controller_name, + :controller_class_path, + :controller_file_path, + :controller_class_nesting, + :controller_class_nesting_depth, + :controller_class_name, + :controller_singular_name, + :controller_plural_name, + :resource_edit_path, + :default_file_extension + alias_method :controller_file_name, :controller_singular_name + alias_method :controller_table_name, :controller_plural_name + + def initialize(runtime_args, runtime_options = {}) + super + + @controller_name = @name.pluralize + + base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name) + @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name) + + if @controller_class_nesting.empty? + @controller_class_name = @controller_class_name_without_nesting + else + @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}" + end + + if Rails::VERSION::STRING < "2.0.0" + @resource_generator = "scaffold_resource" + @default_file_extension = "rhtml" + else + @resource_generator = "scaffold" + @default_file_extension = "html.erb" + end + + if ActionController::Base.respond_to?(:resource_action_separator) + @resource_edit_path = "/edit" + else + @resource_edit_path = ";edit" + end + end + + def manifest + record do |m| + + # Check for class naming collisions. + m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper") + m.class_collisions(class_path, "#{class_name}") + + # Controller, helper, views, and spec directories. + m.directory(File.join('app/models', class_path)) + m.directory(File.join('app/controllers', controller_class_path)) + m.directory(File.join('app/helpers', controller_class_path)) + m.directory(File.join('app/views', controller_class_path, controller_file_name)) + m.directory(File.join('spec/controllers', controller_class_path)) + m.directory(File.join('spec/models', class_path)) + m.directory(File.join('spec/helpers', class_path)) + m.directory File.join('spec/fixtures', class_path) + m.directory File.join('spec/views', controller_class_path, controller_file_name) + + # Controller spec, class, and helper. + m.template 'rspec_scaffold:routing_spec.rb', + File.join('spec/controllers', controller_class_path, "#{controller_file_name}_routing_spec.rb") + + m.template 'rspec_scaffold:controller_spec.rb', + File.join('spec/controllers', controller_class_path, "#{controller_file_name}_controller_spec.rb") + + m.template "#{@resource_generator}:controller.rb", + File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb") + + m.template 'rspec_scaffold:helper_spec.rb', + File.join('spec/helpers', class_path, "#{controller_file_name}_helper_spec.rb") + + m.template "#{@resource_generator}:helper.rb", + File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb") + + for action in scaffold_views + m.template( + "#{@resource_generator}:view_#{action}.#{@default_file_extension}", + File.join('app/views', controller_class_path, controller_file_name, "#{action}.#{default_file_extension}") + ) + end + + # Model class, unit test, and fixtures. + m.template 'model:model.rb', File.join('app/models', class_path, "#{file_name}.rb") + m.template 'model:fixtures.yml', File.join('spec/fixtures', class_path, "#{table_name}.yml") + m.template 'rspec_model:model_spec.rb', File.join('spec/models', class_path, "#{file_name}_spec.rb") + + # View specs + m.template "rspec_scaffold:edit_erb_spec.rb", + File.join('spec/views', controller_class_path, controller_file_name, "edit.#{default_file_extension}_spec.rb") + m.template "rspec_scaffold:index_erb_spec.rb", + File.join('spec/views', controller_class_path, controller_file_name, "index.#{default_file_extension}_spec.rb") + m.template "rspec_scaffold:new_erb_spec.rb", + File.join('spec/views', controller_class_path, controller_file_name, "new.#{default_file_extension}_spec.rb") + m.template "rspec_scaffold:show_erb_spec.rb", + File.join('spec/views', controller_class_path, controller_file_name, "show.#{default_file_extension}_spec.rb") + + unless options[:skip_migration] + m.migration_template( + 'model:migration.rb', 'db/migrate', + :assigns => { + :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}", + :attributes => attributes + }, + :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}" + ) + end + + m.route_resources controller_file_name + + end + end + + protected + # Override with your own usage banner. + def banner + "Usage: #{$0} rspec_scaffold ModelName [field:type field:type]" + end + + def add_options!(opt) + opt.separator '' + opt.separator 'Options:' + opt.on("--skip-migration", + "Don't generate a migration file for this model") { |v| options[:skip_migration] = v } + end + + def scaffold_views + %w[ index show new edit ] + end + + def model_name + class_name.demodulize + end +end + +module Rails + module Generator + class GeneratedAttribute + def default_value + @default_value ||= case type + when :int, :integer then "\"1\"" + when :float then "\"1.5\"" + when :decimal then "\"9.99\"" + when :datetime, :timestamp, :time then "Time.now" + when :date then "Date.today" + when :string then "\"MyString\"" + when :text then "\"MyText\"" + when :boolean then "false" + else + "" + end + end + + def input_type + @input_type ||= case type + when :text then "textarea" + else + "input" + end + end + end + end +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/controller_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/controller_spec.rb new file mode 100755 index 00000000..ae7b1a70 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/controller_spec.rb @@ -0,0 +1,313 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper') + +describe <%= controller_class_name %>Controller do + describe "handling GET /<%= table_name %>" do + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>) + <%= class_name %>.stub!(:find).and_return([@<%= file_name %>]) + end + + def do_get + get :index + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should render index template" do + do_get + response.should render_template('index') + end + + it "should find all <%= table_name %>" do + <%= class_name %>.should_receive(:find).with(:all).and_return([@<%= file_name %>]) + do_get + end + + it "should assign the found <%= table_name %> for the view" do + do_get + assigns[:<%= table_name %>].should == [@<%= file_name %>] + end + end + + describe "handling GET /<%= table_name %>.xml" do + + before(:each) do + @<%= file_name.pluralize %> = mock("Array of <%= class_name.pluralize %>", :to_xml => "XML") + <%= class_name %>.stub!(:find).and_return(@<%= file_name.pluralize %>) + end + + def do_get + @request.env["HTTP_ACCEPT"] = "application/xml" + get :index + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should find all <%= table_name %>" do + <%= class_name %>.should_receive(:find).with(:all).and_return(@<%= file_name.pluralize %>) + do_get + end + + it "should render the found <%= table_name %> as xml" do + @<%= file_name.pluralize %>.should_receive(:to_xml).and_return("XML") + do_get + response.body.should == "XML" + end + end + + describe "handling GET /<%= table_name %>/1" do + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>) + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def do_get + get :show, :id => "1" + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should render show template" do + do_get + response.should render_template('show') + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).with("1").and_return(@<%= file_name %>) + do_get + end + + it "should assign the found <%= file_name %> for the view" do + do_get + assigns[:<%= file_name %>].should equal(@<%= file_name %>) + end + end + + describe "handling GET /<%= table_name %>/1.xml" do + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>, :to_xml => "XML") + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def do_get + @request.env["HTTP_ACCEPT"] = "application/xml" + get :show, :id => "1" + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).with("1").and_return(@<%= file_name %>) + do_get + end + + it "should render the found <%= file_name %> as xml" do + @<%= file_name %>.should_receive(:to_xml).and_return("XML") + do_get + response.body.should == "XML" + end + end + + describe "handling GET /<%= table_name %>/new" do + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>) + <%= class_name %>.stub!(:new).and_return(@<%= file_name %>) + end + + def do_get + get :new + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should render new template" do + do_get + response.should render_template('new') + end + + it "should create an new <%= file_name %>" do + <%= class_name %>.should_receive(:new).and_return(@<%= file_name %>) + do_get + end + + it "should not save the new <%= file_name %>" do + @<%= file_name %>.should_not_receive(:save) + do_get + end + + it "should assign the new <%= file_name %> for the view" do + do_get + assigns[:<%= file_name %>].should equal(@<%= file_name %>) + end + end + + describe "handling GET /<%= table_name %>/1/edit" do + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>) + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def do_get + get :edit, :id => "1" + end + + it "should be successful" do + do_get + response.should be_success + end + + it "should render edit template" do + do_get + response.should render_template('edit') + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).and_return(@<%= file_name %>) + do_get + end + + it "should assign the found <%= class_name %> for the view" do + do_get + assigns[:<%= file_name %>].should equal(@<%= file_name %>) + end + end + + describe "handling POST /<%= table_name %>" do + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>, :to_param => "1") + <%= class_name %>.stub!(:new).and_return(@<%= file_name %>) + end + + describe "with successful save" do + + def do_post + @<%= file_name %>.should_receive(:save).and_return(true) + post :create, :<%= file_name %> => {} + end + + it "should create a new <%= file_name %>" do + <%= class_name %>.should_receive(:new).with({}).and_return(@<%= file_name %>) + do_post + end + + it "should redirect to the new <%= file_name %>" do + do_post + response.should redirect_to(<%= table_name.singularize %>_url("1")) + end + + end + + describe "with failed save" do + + def do_post + @<%= file_name %>.should_receive(:save).and_return(false) + post :create, :<%= file_name %> => {} + end + + it "should re-render 'new'" do + do_post + response.should render_template('new') + end + + end + end + + describe "handling PUT /<%= table_name %>/1" do + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>, :to_param => "1") + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + describe "with successful update" do + + def do_put + @<%= file_name %>.should_receive(:update_attributes).and_return(true) + put :update, :id => "1" + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).with("1").and_return(@<%= file_name %>) + do_put + end + + it "should update the found <%= file_name %>" do + do_put + assigns(:<%= file_name %>).should equal(@<%= file_name %>) + end + + it "should assign the found <%= file_name %> for the view" do + do_put + assigns(:<%= file_name %>).should equal(@<%= file_name %>) + end + + it "should redirect to the <%= file_name %>" do + do_put + response.should redirect_to(<%= table_name.singularize %>_url("1")) + end + + end + + describe "with failed update" do + + def do_put + @<%= file_name %>.should_receive(:update_attributes).and_return(false) + put :update, :id => "1" + end + + it "should re-render 'edit'" do + do_put + response.should render_template('edit') + end + + end + end + + describe "handling DELETE /<%= table_name %>/1" do + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>, :destroy => true) + <%= class_name %>.stub!(:find).and_return(@<%= file_name %>) + end + + def do_delete + delete :destroy, :id => "1" + end + + it "should find the <%= file_name %> requested" do + <%= class_name %>.should_receive(:find).with("1").and_return(@<%= file_name %>) + do_delete + end + + it "should call destroy on the found <%= file_name %>" do + @<%= file_name %>.should_receive(:destroy) + do_delete + end + + it "should redirect to the <%= table_name %> list" do + do_delete + response.should redirect_to(<%= table_name %>_url) + end + end +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/edit_erb_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/edit_erb_spec.rb new file mode 100644 index 00000000..86e23a27 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/edit_erb_spec.rb @@ -0,0 +1,25 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper') + +describe "/<%= table_name %>/edit.<%= default_file_extension %>" do + include <%= controller_class_name %>Helper + + before do + @<%= file_name %> = mock_model(<%= class_name %>) +<% for attribute in attributes -%> + @<%= file_name %>.stub!(:<%= attribute.name %>).and_return(<%= attribute.default_value %>) +<% end -%> + assigns[:<%= file_name %>] = @<%= file_name %> + end + + it "should render edit form" do + render "/<%= table_name %>/edit.<%= default_file_extension %>" + + response.should have_tag("form[action=#{<%= file_name %>_path(@<%= file_name %>)}][method=post]") do +<% for attribute in attributes -%><% unless attribute.name =~ /_id/ || [:datetime, :timestamp, :time, :date].index(attribute.type) -%> + with_tag('<%= attribute.input_type -%>#<%= file_name %>_<%= attribute.name %>[name=?]', "<%= file_name %>[<%= attribute.name %>]") +<% end -%><% end -%> + end + end +end + + diff --git a/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/helper_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/helper_spec.rb new file mode 100644 index 00000000..900b027a --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/helper_spec.rb @@ -0,0 +1,11 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper') + +describe <%= controller_class_name %>Helper do + + #Delete this example and add some real ones or delete this file + it "should be included in the object returned by #helper" do + included_modules = (class << helper; self; end).send :included_modules + included_modules.should include(<%= controller_class_name %>Helper) + end + +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/index_erb_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/index_erb_spec.rb new file mode 100644 index 00000000..660c284f --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/index_erb_spec.rb @@ -0,0 +1,22 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper') + +describe "/<%= table_name %>/index.<%= default_file_extension %>" do + include <%= controller_class_name %>Helper + + before(:each) do +<% [98,99].each do |id| -%> + <%= file_name %>_<%= id %> = mock_model(<%= class_name %>) +<% for attribute in attributes -%> + <%= file_name %>_<%= id %>.should_receive(:<%= attribute.name %>).and_return(<%= attribute.default_value %>) +<% end -%><% end %> + assigns[:<%= table_name %>] = [<%= file_name %>_98, <%= file_name %>_99] + end + + it "should render list of <%= table_name %>" do + render "/<%= table_name %>/index.<%= default_file_extension %>" +<% for attribute in attributes -%><% unless attribute.name =~ /_id/ || [:datetime, :timestamp, :time, :date].index(attribute.type) -%> + response.should have_tag("tr>td", <%= attribute.default_value %>, 2) +<% end -%><% end -%> + end +end + diff --git a/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/new_erb_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/new_erb_spec.rb new file mode 100644 index 00000000..f0442e9b --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/new_erb_spec.rb @@ -0,0 +1,26 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper') + +describe "/<%= table_name %>/new.<%= default_file_extension %>" do + include <%= controller_class_name %>Helper + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>) + @<%= file_name %>.stub!(:new_record?).and_return(true) +<% for attribute in attributes -%> + @<%= file_name %>.stub!(:<%= attribute.name %>).and_return(<%= attribute.default_value %>) +<% end -%> + assigns[:<%= file_name %>] = @<%= file_name %> + end + + it "should render new form" do + render "/<%= table_name %>/new.<%= default_file_extension %>" + + response.should have_tag("form[action=?][method=post]", <%= table_name %>_path) do +<% for attribute in attributes -%><% unless attribute.name =~ /_id/ || [:datetime, :timestamp, :time, :date].index(attribute.type) -%> + with_tag("<%= attribute.input_type -%>#<%= file_name %>_<%= attribute.name %>[name=?]", "<%= file_name %>[<%= attribute.name %>]") +<% end -%><% end -%> + end + end +end + + diff --git a/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/routing_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/routing_spec.rb new file mode 100644 index 00000000..ca53a7ca --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/routing_spec.rb @@ -0,0 +1,61 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper') + +describe <%= controller_class_name %>Controller do + describe "route generation" do + + it "should map { :controller => '<%= table_name %>', :action => 'index' } to /<%= table_name %>" do + route_for(:controller => "<%= table_name %>", :action => "index").should == "/<%= table_name %>" + end + + it "should map { :controller => '<%= table_name %>', :action => 'new' } to /<%= table_name %>/new" do + route_for(:controller => "<%= table_name %>", :action => "new").should == "/<%= table_name %>/new" + end + + it "should map { :controller => '<%= table_name %>', :action => 'show', :id => 1 } to /<%= table_name %>/1" do + route_for(:controller => "<%= table_name %>", :action => "show", :id => 1).should == "/<%= table_name %>/1" + end + + it "should map { :controller => '<%= table_name %>', :action => 'edit', :id => 1 } to /<%= table_name %>/1<%= resource_edit_path %>" do + route_for(:controller => "<%= table_name %>", :action => "edit", :id => 1).should == "/<%= table_name %>/1<%= resource_edit_path %>" + end + + it "should map { :controller => '<%= table_name %>', :action => 'update', :id => 1} to /<%= table_name %>/1" do + route_for(:controller => "<%= table_name %>", :action => "update", :id => 1).should == "/<%= table_name %>/1" + end + + it "should map { :controller => '<%= table_name %>', :action => 'destroy', :id => 1} to /<%= table_name %>/1" do + route_for(:controller => "<%= table_name %>", :action => "destroy", :id => 1).should == "/<%= table_name %>/1" + end + end + + describe "route recognition" do + + it "should generate params { :controller => '<%= table_name %>', action => 'index' } from GET /<%= table_name %>" do + params_from(:get, "/<%= table_name %>").should == {:controller => "<%= table_name %>", :action => "index"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'new' } from GET /<%= table_name %>/new" do + params_from(:get, "/<%= table_name %>/new").should == {:controller => "<%= table_name %>", :action => "new"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'create' } from POST /<%= table_name %>" do + params_from(:post, "/<%= table_name %>").should == {:controller => "<%= table_name %>", :action => "create"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'show', id => '1' } from GET /<%= table_name %>/1" do + params_from(:get, "/<%= table_name %>/1").should == {:controller => "<%= table_name %>", :action => "show", :id => "1"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'edit', id => '1' } from GET /<%= table_name %>/1;edit" do + params_from(:get, "/<%= table_name %>/1<%= resource_edit_path %>").should == {:controller => "<%= table_name %>", :action => "edit", :id => "1"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'update', id => '1' } from PUT /<%= table_name %>/1" do + params_from(:put, "/<%= table_name %>/1").should == {:controller => "<%= table_name %>", :action => "update", :id => "1"} + end + + it "should generate params { :controller => '<%= table_name %>', action => 'destroy', id => '1' } from DELETE /<%= table_name %>/1" do + params_from(:delete, "/<%= table_name %>/1").should == {:controller => "<%= table_name %>", :action => "destroy", :id => "1"} + end + end +end diff --git a/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/show_erb_spec.rb b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/show_erb_spec.rb new file mode 100644 index 00000000..36dae549 --- /dev/null +++ b/vendor/plugins/rspec-rails/generators/rspec_scaffold/templates/show_erb_spec.rb @@ -0,0 +1,22 @@ +require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper') + +describe "/<%= table_name %>/show.<%= default_file_extension %>" do + include <%= controller_class_name %>Helper + + before(:each) do + @<%= file_name %> = mock_model(<%= class_name %>) +<% for attribute in attributes -%> + @<%= file_name %>.stub!(:<%= attribute.name %>).and_return(<%= attribute.default_value %>) +<% end -%> + + assigns[:<%= file_name %>] = @<%= file_name %> + end + + it "should render attributes in
" do
+ render "/<%= table_name %>/show.<%= default_file_extension %>"
+<% for attribute in attributes -%><% unless attribute.name =~ /_id/ || [:datetime, :timestamp, :time, :date].index(attribute.type) -%>
+ response.should have_text(/<%= Regexp.escape(attribute.default_value)[1..-2]%>/)
+<% end -%><% end -%>
+ end
+end
+
diff --git a/vendor/plugins/rspec-rails/init.rb b/vendor/plugins/rspec-rails/init.rb
new file mode 100644
index 00000000..6262f036
--- /dev/null
+++ b/vendor/plugins/rspec-rails/init.rb
@@ -0,0 +1,9 @@
+# Placeholder to satisfy Rails.
+#
+# Do NOT add any require statements to this file. Doing
+# so will cause Rails to load this plugin all of the time.
+#
+# Running 'ruby script/generate rspec' will
+# generate spec/spec_helper.rb, which includes the necessary
+# require statements and configuration. This file should
+# be required by all of your spec files.
\ No newline at end of file
diff --git a/vendor/plugins/rspec-rails/lib/autotest/discover.rb b/vendor/plugins/rspec-rails/lib/autotest/discover.rb
new file mode 100644
index 00000000..8e6968e2
--- /dev/null
+++ b/vendor/plugins/rspec-rails/lib/autotest/discover.rb
@@ -0,0 +1 @@
+# This needs to be here for >= ZenTest-3.9.0 to add this directory to the load path.
\ No newline at end of file
diff --git a/vendor/plugins/rspec-rails/lib/autotest/rails_rspec.rb b/vendor/plugins/rspec-rails/lib/autotest/rails_rspec.rb
new file mode 100644
index 00000000..c6fe446b
--- /dev/null
+++ b/vendor/plugins/rspec-rails/lib/autotest/rails_rspec.rb
@@ -0,0 +1,81 @@
+# (c) Copyright 2006 Nick Sieger \n"This is not a big problem," he said.\n Guitar Guitar Bass Drums foo bar a paragraph a paragraph a paragraph a paragraph a paragraphpath can include the controller path or not. It
+ # can also include an optional extension (no extension assumes .rhtml).
+ #
+ # Note that partials must be spelled with the preceding underscore.
+ #
+ # == Examples
+ #
+ # response.should render_template('list')
+ # response.should render_template('same_controller/list')
+ # response.should render_template('other_controller/list')
+ #
+ # #rjs
+ # response.should render_template('list.rjs')
+ # response.should render_template('same_controller/list.rjs')
+ # response.should render_template('other_controller/list.rjs')
+ #
+ # #partials
+ # response.should render_template('_a_partial')
+ # response.should render_template('same_controller/_a_partial')
+ # response.should render_template('other_controller/_a_partial')
+ def render_template(path)
+ RenderTemplate.new(path.to_s, @controller)
+ end
+
+ end
+ end
+end
diff --git a/vendor/plugins/rspec-rails/lib/spec/rails/mocks.rb b/vendor/plugins/rspec-rails/lib/spec/rails/mocks.rb
new file mode 100644
index 00000000..740ecf3d
--- /dev/null
+++ b/vendor/plugins/rspec-rails/lib/spec/rails/mocks.rb
@@ -0,0 +1,117 @@
+module Spec
+ module Rails
+
+ class IllegalDataAccessException < StandardError; end
+
+ module Mocks
+
+ # Creates a mock object instance for a +model_class+ with common
+ # methods stubbed out. Additional methods may be easily stubbed (via
+ # add_stubs) if +stubs+ is passed.
+ def mock_model(model_class, options_and_stubs = {})
+ id = next_id
+ options_and_stubs.reverse_merge!({
+ :id => id,
+ :to_param => id.to_s,
+ :new_record? => false,
+ :errors => stub("errors", :count => 0)
+ })
+ m = mock("#{model_class.name}_#{options_and_stubs[:id]}", options_and_stubs)
+ m.send(:__mock_proxy).instance_eval <<-CODE
+ def @target.is_a?(other)
+ #{model_class}.ancestors.include?(other)
+ end
+ def @target.kind_of?(other)
+ #{model_class}.ancestors.include?(other)
+ end
+ def @target.instance_of?(other)
+ other == #{model_class}
+ end
+ def @target.class
+ #{model_class}
+ end
+ CODE
+ yield m if block_given?
+ m
+ end
+
+ module ModelStubber
+ def connection
+ raise Spec::Rails::IllegalDataAccessException.new("stubbed models are not allowed to access the database")
+ end
+ def new_record?
+ id.nil?
+ end
+ def as_new_record
+ self.id = nil
+ self
+ end
+ end
+
+ # :call-seq:
+ # stub_model(Model)
+ # stub_model(Model).as_new_record
+ # stub_model(Model, hash_of_stubs)
+ #
+ # Creates an instance of +Model+ that is prohibited from accessing the
+ # database. For each key in +hash_of_stubs+, if the model has a
+ # matching attribute (determined by asking it, which it answers based
+ # on schema.rb) are simply assigned the submitted values. If the model
+ # does not have a matching attribute, the key/value pair is assigned
+ # as a stub return value using RSpec's mocking/stubbing framework.
+ #
+ # new_record? is overridden to return the result of id.nil? This means
+ # that by default new_record? will return false. If you want the
+ # object to behave as a new record, sending it +as_new_record+ will
+ # set the id to nil. You can also explicitly set :id => nil, in which
+ # case new_record? will return true, but using +as_new_record+ makes
+ # the example a bit more descriptive.
+ #
+ # While you can use stub_model in any example (model, view,
+ # controller, helper), it is especially useful in view examples,
+ # which are inherently more state-based than interaction-based.
+ #
+ # == Examples
+ #
+ # stub_model(Person)
+ # stub_model(Person).as_new_record
+ # stub_model(Person, :id => 37)
+ # stub_model(Person) do |person|
+ # model.first_name = "David"
+ # end
+ def stub_model(model_class, stubs = {})
+ stubs = {:id => next_id}.merge(stubs)
+ returning model_class.new do |model|
+ model.id = stubs.delete(:id)
+ model.extend ModelStubber
+ stubs.each do |k,v|
+ if model.has_attribute?(k)
+ model[k] = stubs.delete(k)
+ end
+ end
+ add_stubs(model, stubs)
+ yield model if block_given?
+ end
+ end
+
+ #--
+ # TODO - Shouldn't this just be an extension of stub! ??
+ # - object.stub!(:method => return_value, :method2 => return_value2, :etc => etc)
+ #++
+ # Stubs methods on +object+ (if +object+ is a symbol or string a new mock
+ # with that name will be created). +stubs+ is a Hash of method=>value
+ def add_stubs(object, stubs = {}) #:nodoc:
+ m = [String, Symbol].index(object.class) ? mock(object.to_s) : object
+ stubs.each {|k,v| m.stub!(k).and_return(v)}
+ m
+ end
+
+ private
+ @@model_id = 1000
+ def next_id
+ @@model_id += 1
+ end
+
+ end
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec-rails/lib/spec/rails/story_adapter.rb b/vendor/plugins/rspec-rails/lib/spec/rails/story_adapter.rb
new file mode 100644
index 00000000..66124afe
--- /dev/null
+++ b/vendor/plugins/rspec-rails/lib/spec/rails/story_adapter.rb
@@ -0,0 +1,71 @@
+# WARNING - THIS IS PURELY EXPERIMENTAL AT THIS POINT
+# Courtesy of Brian Takita and Yurii Rashkovskii
+
+$:.unshift File.join(File.dirname(__FILE__), *%w[.. .. .. .. rspec lib])
+if defined?(ActiveRecord::Base)
+ require 'test_help'
+else
+ require 'action_controller/test_process'
+ require 'action_controller/integration'
+end
+require 'test/unit/testresult'
+require 'spec'
+require 'spec/rails'
+
+Test::Unit.run = true
+
+ActionController::Integration::Session.send(:include, Spec::Matchers)
+ActionController::Integration::Session.send(:include, Spec::Rails::Matchers)
+
+class RailsStory < ActionController::IntegrationTest
+ if defined?(ActiveRecord::Base)
+ self.use_transactional_fixtures = true
+ else
+ def self.fixture_table_names; []; end # Workaround for projects that don't use ActiveRecord
+ end
+
+ def initialize #:nodoc:
+ # TODO - eliminate this hack, which is here to stop
+ # Rails Stories from dumping the example summary.
+ Spec::Runner::Options.class_eval do
+ def examples_should_be_run?
+ false
+ end
+ end
+ @_result = Test::Unit::TestResult.new
+ end
+end
+
+class ActiveRecordSafetyListener
+ include Singleton
+ def scenario_started(*args)
+ if defined?(ActiveRecord::Base)
+ ActiveRecord::Base.send :increment_open_transactions unless Rails::VERSION::STRING == "1.1.6"
+ ActiveRecord::Base.connection.begin_db_transaction
+ end
+ end
+
+ def scenario_succeeded(*args)
+ if defined?(ActiveRecord::Base)
+ ActiveRecord::Base.connection.rollback_db_transaction
+ ActiveRecord::Base.send :decrement_open_transactions unless Rails::VERSION::STRING == "1.1.6"
+ end
+ end
+ alias :scenario_pending :scenario_succeeded
+ alias :scenario_failed :scenario_succeeded
+end
+
+class Spec::Story::Runner::ScenarioRunner
+ def initialize
+ @listeners = [ActiveRecordSafetyListener.instance]
+ end
+end
+
+class Spec::Story::GivenScenario
+ def perform(instance, name = nil)
+ scenario = Spec::Story::Runner::StoryRunner.scenario_from_current_story @name
+ runner = Spec::Story::Runner::ScenarioRunner.new
+ runner.instance_variable_set(:@listeners,[])
+ runner.run(scenario, instance)
+ end
+end
diff --git a/vendor/plugins/rspec-rails/lib/spec/rails/version.rb b/vendor/plugins/rspec-rails/lib/spec/rails/version.rb
new file mode 100644
index 00000000..61e4244a
--- /dev/null
+++ b/vendor/plugins/rspec-rails/lib/spec/rails/version.rb
@@ -0,0 +1,23 @@
+module Spec
+ module Rails
+ module VERSION #:nodoc:
+ BUILD_TIME_UTC = 20080615141040
+ end
+ end
+end
+
+# Verify that the plugin has the same revision as RSpec
+if Spec::Rails::VERSION::BUILD_TIME_UTC != Spec::VERSION::BUILD_TIME_UTC
+ raise <<-EOF
+
+############################################################################
+Your RSpec on Rails plugin is incompatible with your installed RSpec.
+
+RSpec : #{Spec::VERSION::BUILD_TIME_UTC}
+RSpec on Rails : #{Spec::Rails::VERSION::BUILD_TIME_UTC}
+
+Make sure your RSpec on Rails plugin is compatible with your RSpec gem.
+See http://rspec.rubyforge.org/documentation/rails/install.html for details.
+############################################################################
+EOF
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/autotest/mappings_spec.rb b/vendor/plugins/rspec-rails/spec/rails/autotest/mappings_spec.rb
new file mode 100644
index 00000000..3ebf8909
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/autotest/mappings_spec.rb
@@ -0,0 +1,36 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.join(File.dirname(__FILE__), *%w[.. .. .. lib autotest rails_rspec])
+require File.join(File.dirname(__FILE__), *%w[.. .. .. .. rspec spec autotest_matchers])
+
+describe Autotest::RailsRspec, "file mapping" do
+ before(:each) do
+ @autotest = Autotest::RailsRspec.new
+ @autotest.hook :initialize
+ end
+
+ it "should map model example to model" do
+ @autotest.should map_specs(['spec/models/thing_spec.rb']).
+ to('app/models/thing.rb')
+ end
+
+ it "should map controller example to controller" do
+ @autotest.should map_specs(['spec/controllers/things_controller_spec.rb']).
+ to('app/controllers/things_controller.rb')
+ end
+
+ it "should map view.rhtml" do
+ @autotest.should map_specs(['spec/views/things/index.rhtml_spec.rb']).
+ to('app/views/things/index.rhtml')
+ end
+
+ it "should map view.rhtml with underscores in example filename" do
+ @autotest.should map_specs(['spec/views/things/index_rhtml_spec.rb']).
+ to('app/views/things/index.rhtml')
+ end
+
+ it "should map view.html.erb" do
+ @autotest.should map_specs(['spec/views/things/index.html.erb_spec.rb']).
+ to('app/views/things/index.html.erb')
+ end
+
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/autotest/rails_rspec_spec.rb b/vendor/plugins/rspec-rails/spec/rails/autotest/rails_rspec_spec.rb
new file mode 100644
index 00000000..148e0056
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/autotest/rails_rspec_spec.rb
@@ -0,0 +1,8 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "autotest", "rails_rspec")
+
+describe Autotest::RailsRspec do
+ it "should provide the correct spec_command" do
+ Autotest::RailsRspec.new.spec_command.should == "script/spec"
+ end
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/assigns_hash_proxy_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/assigns_hash_proxy_spec.rb
new file mode 100644
index 00000000..eab67f69
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/assigns_hash_proxy_spec.rb
@@ -0,0 +1,60 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe "AssignsHashProxy" do
+ before(:each) do
+ @object = Object.new
+ @assigns = Hash.new
+ @object.stub!(:assigns).and_return(@assigns)
+ @proxy = Spec::Rails::Example::AssignsHashProxy.new(@object)
+ end
+
+ it "has [] accessor" do
+ @proxy['foo'] = 'bar'
+ @assigns['foo'].should == 'bar'
+ @proxy['foo'].should == 'bar'
+ end
+
+ it "works for symbol key" do
+ @assigns[:foo] = 2
+ @proxy[:foo].should == 2
+ end
+
+ it "checks for string key before symbol key" do
+ @assigns['foo'] = false
+ @assigns[:foo] = 2
+ @proxy[:foo].should == false
+ end
+
+ it "each method iterates through each element like a Hash" do
+ values = {
+ 'foo' => 1,
+ 'bar' => 2,
+ 'baz' => 3
+ }
+ @proxy['foo'] = values['foo']
+ @proxy['bar'] = values['bar']
+ @proxy['baz'] = values['baz']
+
+ @proxy.each do |key, value|
+ key.should == key
+ value.should == values[key]
+ end
+ end
+
+ it "delete method deletes the element of passed in key" do
+ @proxy['foo'] = 'bar'
+ @proxy.delete('foo').should == 'bar'
+ @proxy['foo'].should be_nil
+ end
+
+ it "has_key? detects the presence of a key" do
+ @proxy['foo'] = 'bar'
+ @proxy.has_key?('foo').should == true
+ @proxy.has_key?('bar').should == false
+ end
+
+ it "should sets an instance var" do
+ @proxy['foo'] = 'bar'
+ @object.instance_eval { @foo }.should == 'bar'
+ end
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/configuration_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/configuration_spec.rb
new file mode 100644
index 00000000..91a1b265
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/configuration_spec.rb
@@ -0,0 +1,83 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ describe Configuration, :shared => true do
+ before(:each) { @config = Configuration.new }
+ end
+
+ describe Configuration, "#use_transactional_fixtures" do
+ it_should_behave_like "Spec::Example::Configuration"
+
+ it "should return Test::Unit::TestCase.use_transactional_fixtures" do
+ @config.use_transactional_fixtures.should == Test::Unit::TestCase.use_transactional_fixtures
+ end
+
+ it "should set Test::Unit::TestCase.use_transactional_fixtures to false" do
+ Configuration::EXAMPLE_GROUP_CLASSES.each do |example_group|
+ example_group.should_receive(:use_transactional_fixtures=).with(false)
+ end
+ @config.use_transactional_fixtures = false
+ end
+
+ it "should set Test::Unit::TestCase.use_transactional_fixtures to true" do
+ Configuration::EXAMPLE_GROUP_CLASSES.each do |example_group|
+ example_group.should_receive(:use_transactional_fixtures=).with(true)
+ end
+ @config.use_transactional_fixtures = true
+ end
+ end
+
+ describe Configuration, "#use_instantiated_fixtures" do
+ it_should_behave_like "Spec::Example::Configuration"
+
+ it "should return Test::Unit::TestCase.use_transactional_fixtures" do
+ @config.use_instantiated_fixtures.should == Test::Unit::TestCase.use_instantiated_fixtures
+ end
+
+ it "should set Test::Unit::TestCase.use_instantiated_fixtures to false" do
+ Configuration::EXAMPLE_GROUP_CLASSES.each do |example_group|
+ example_group.should_receive(:use_instantiated_fixtures=).with(false)
+ end
+ @config.use_instantiated_fixtures = false
+ end
+
+ it "should set Test::Unit::TestCase.use_instantiated_fixtures to true" do
+ Configuration::EXAMPLE_GROUP_CLASSES.each do |example_group|
+ example_group.should_receive(:use_instantiated_fixtures=).with(true)
+ end
+ @config.use_instantiated_fixtures = true
+ end
+ end
+
+ describe Configuration, "#fixture_path" do
+ it_should_behave_like "Spec::Example::Configuration"
+
+ it "should default to RAILS_ROOT + '/spec/fixtures'" do
+ @config.fixture_path.should == RAILS_ROOT + '/spec/fixtures'
+ Configuration::EXAMPLE_GROUP_CLASSES.each do |example_group|
+ example_group.fixture_path.should == RAILS_ROOT + '/spec/fixtures'
+ end
+ end
+
+ it "should set fixture_path" do
+ @config.fixture_path = "/new/path"
+ @config.fixture_path.should == "/new/path"
+ Configuration::EXAMPLE_GROUP_CLASSES.each do |example_group|
+ example_group.fixture_path.should == "/new/path"
+ end
+ end
+ end
+
+ describe Configuration, "#global_fixtures" do
+ it_should_behave_like "Spec::Example::Configuration"
+
+ it "should set fixtures on TestCase" do
+ Configuration::EXAMPLE_GROUP_CLASSES.each do |example_group|
+ example_group.should_receive(:fixtures).with(:blah)
+ end
+ @config.global_fixtures = [:blah]
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/controller_isolation_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/controller_isolation_spec.rb
new file mode 100644
index 00000000..9e40047a
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/controller_isolation_spec.rb
@@ -0,0 +1,62 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'controller_spec_controller'
+
+describe "a controller spec running in isolation mode", :type => :controller do
+ controller_name :controller_spec
+
+ it "should not care if the template doesn't exist" do
+ get 'some_action'
+ response.should be_success
+ response.should render_template("template/that/does/not/actually/exist")
+ end
+
+ it "should not care if the template has errors" do
+ get 'action_with_errors_in_template'
+ response.should be_success
+ response.should render_template("action_with_errors_in_template")
+ end
+end
+
+describe "a controller spec running in integration mode", :type => :controller do
+ controller_name :controller_spec
+ integrate_views
+
+ before(:each) do
+ controller.class.send(:define_method, :rescue_action) { |e| raise e }
+ end
+
+ it "should render a template" do
+ get 'action_with_template'
+ response.should be_success
+ response.should have_tag('div', 'This is action_with_template.rhtml')
+ end
+
+ it "should choke if the template doesn't exist" do
+ error = defined?(ActionController::MissingTemplate) ? ActionController::MissingTemplate : ActionView::MissingTemplate
+ lambda { get 'some_action' }.should raise_error(error)
+ response.should_not be_success
+ end
+
+ it "should choke if the template has errors" do
+ lambda { get 'action_with_errors_in_template' }.should raise_error(ActionView::TemplateError)
+ response.should_not be_success
+ end
+
+ describe "nested" do
+ it "should render a template" do
+ get 'action_with_template'
+ response.should be_success
+ response.should have_tag('div', 'This is action_with_template.rhtml')
+ end
+
+ describe "with integrate_views turned off" do
+ integrate_views false
+
+ it "should not care if the template doesn't exist" do
+ get 'some_action'
+ response.should be_success
+ response.should render_template("template/that/does/not/actually/exist")
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/controller_spec_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/controller_spec_spec.rb
new file mode 100644
index 00000000..afbb69f7
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/controller_spec_spec.rb
@@ -0,0 +1,206 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'controller_spec_controller'
+
+['integration', 'isolation'].each do |mode|
+ describe "A controller example running in #{mode} mode", :type => :controller do
+ controller_name :controller_spec
+ integrate_views if mode == 'integration'
+
+ it "should provide controller.session as session" do
+ get 'action_with_template'
+ session.should equal(controller.session)
+ end
+
+ it "should provide the same session object before and after the action" do
+ session_before = session
+ get 'action_with_template'
+ session.should equal(session_before)
+ end
+
+ it "should keep the same data in the session before and after the action" do
+ session[:foo] = :bar
+ get 'action_with_template'
+ session[:foo].should == :bar
+ end
+
+ it "should ensure controller.session is NOT nil before the action" do
+ controller.session.should_not be_nil
+ get 'action_with_template'
+ end
+
+ it "should ensure controller.session is NOT nil after the action" do
+ get 'action_with_template'
+ controller.session.should_not be_nil
+ end
+
+ it "should allow specifying a partial with partial name only" do
+ get 'action_with_partial'
+ response.should render_template("_partial")
+ end
+
+ it "should allow specifying a partial with expect_render" do
+ controller.expect_render(:partial => "controller_spec/partial")
+ get 'action_with_partial'
+ end
+
+ it "should allow specifying a partial with expect_render with object" do
+ controller.expect_render(:partial => "controller_spec/partial", :object => "something")
+ get 'action_with_partial_with_object', :thing => "something"
+ end
+
+ it "should allow specifying a partial with expect_render with locals" do
+ controller.expect_render(:partial => "controller_spec/partial", :locals => {:thing => "something"})
+ get 'action_with_partial_with_locals', :thing => "something"
+ end
+
+ it "should yield to render :update" do
+ template = stub("template")
+ controller.expect_render(:update).and_yield(template)
+ template.should_receive(:replace).with(:bottom, "replace_me", :partial => "non_existent_partial")
+ get 'action_with_render_update'
+ end
+
+ it "should allow a path relative to RAILS_ROOT/app/views/ when specifying a partial" do
+ get 'action_with_partial'
+ response.should render_template("controller_spec/_partial")
+ end
+
+ it "should provide access to flash" do
+ get 'action_which_sets_flash'
+ flash[:flash_key].should == "flash value"
+ end
+
+ it "should provide access to flash values set after a session reset" do
+ get 'action_setting_flash_after_session_reset'
+ flash[:after_reset].should == "available"
+ end
+
+ it "should not provide access to flash values set before a session reset" do
+ get 'action_setting_flash_before_session_reset'
+ flash[:before_reset].should_not == "available"
+ end
+
+ it "should provide access to session" do
+ session[:session_key] = "session value"
+ lambda do
+ get 'action_which_gets_session', :expected => "session value"
+ end.should_not raise_error
+ end
+
+ it "should support custom routes" do
+ route_for(:controller => "custom_route_spec", :action => "custom_route").should == "/custom_route"
+ end
+
+ it "should support existing routes" do
+ route_for(:controller => "controller_spec", :action => "some_action").should == "/controller_spec/some_action"
+ end
+
+ it "should generate params for custom routes" do
+ params_from(:get, '/custom_route').should == {:controller => "custom_route_spec", :action => "custom_route"}
+ end
+
+ it "should generate params for existing routes" do
+ params_from(:get, '/controller_spec/some_action').should == {:controller => "controller_spec", :action => "some_action"}
+ end
+
+ it "should expose instance vars through the assigns hash" do
+ get 'action_setting_the_assigns_hash'
+ assigns[:indirect_assigns_key].should == :indirect_assigns_key_value
+ end
+
+ it "should expose the assigns hash directly" do
+ get 'action_setting_the_assigns_hash'
+ assigns[:direct_assigns_key].should == :direct_assigns_key_value
+ end
+
+ it "should complain when calling should_receive(:render) on the controller" do
+ lambda {
+ controller.should_receive(:render)
+ }.should raise_error(RuntimeError, /should_receive\(:render\) has been disabled/)
+ end
+
+ it "should complain when calling stub!(:render) on the controller" do
+ controller.extend Spec::Mocks::Methods
+ lambda {
+ controller.stub!(:render)
+ }.should raise_error(RuntimeError, /stub!\(:render\) has been disabled/)
+ end
+
+ it "should NOT complain when calling should_receive with arguments other than :render" do
+ controller.should_receive(:anything_besides_render)
+ lambda {
+ controller.rspec_verify
+ }.should raise_error(Exception, /expected :anything_besides_render/)
+ end
+ end
+
+ describe "Given a controller spec for RedirectSpecController running in #{mode} mode", :type => :controller do
+ controller_name :redirect_spec
+ integrate_views if mode == 'integration'
+
+ it "a redirect should ignore the absence of a template" do
+ get 'action_with_redirect_to_somewhere'
+ response.should be_redirect
+ response.redirect_url.should == "http://test.host/redirect_spec/somewhere"
+ response.should redirect_to("http://test.host/redirect_spec/somewhere")
+ end
+
+ it "a call to response.should redirect_to should fail if no redirect" do
+ get 'action_with_no_redirect'
+ lambda {
+ response.redirect?.should be_true
+ }.should fail
+ lambda {
+ response.should redirect_to("http://test.host/redirect_spec/somewhere")
+ }.should fail_with("expected redirect to \"http://test.host/redirect_spec/somewhere\", got no redirect")
+ end
+ end
+
+ describe "Given a controller spec running in #{mode} mode" do
+ example_group = describe "A controller spec"
+ # , :type => :controller do
+ # integrate_views if mode == 'integration'
+ it "a spec in a context without controller_name set should fail with a useful warning" do
+ pending("need a new way to deal with examples that should_raise")
+ # ,
+ # :should_raise => [
+ # Spec::Expectations::ExpectationNotMetError,
+ # /You have to declare the controller name in controller specs/
+ # ] do
+ end
+ end
+
+end
+
+describe ControllerSpecController, :type => :controller do
+ it "should not require naming the controller if describe is passed a type" do
+ end
+end
+
+describe "A controller spec with controller_name set", :type => :controller do
+ controller_name :controller_spec
+
+ describe "nested" do
+ it "should inherit the controller name" do
+ get 'action_with_template'
+ response.should be_success
+ end
+ end
+end
+
+module Spec
+ module Rails
+ module Example
+ describe ControllerExampleGroup do
+ it "should clear its name from the description" do
+ group = describe("foo", :type => :controller) do
+ $nested_group = describe("bar") do
+ end
+ end
+ group.description.to_s.should == "foo"
+ $nested_group.description.to_s.should == "foo bar"
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/example_group_factory_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/example_group_factory_spec.rb
new file mode 100644
index 00000000..0803c2f2
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/example_group_factory_spec.rb
@@ -0,0 +1,112 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ describe ExampleGroupFactory do
+ it "should return a ModelExampleGroup when given :type => :model" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :type => :model
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ModelExampleGroup
+ end
+
+ it "should return a ModelExampleGroup when given :spec_path => '/blah/spec/models/'" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '/blah/spec/models/blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ModelExampleGroup
+ end
+
+ it "should return a ModelExampleGroup when given :spec_path => '\\blah\\spec\\models\\' (windows format)" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '\\blah\\spec\\models\\blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ModelExampleGroup
+ end
+
+ it "should return a RailsExampleGroup when given :spec_path => '/blah/spec/foo/' (anything other than controllers, views and helpers)" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '/blah/spec/foo/blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::RailsExampleGroup
+ end
+
+ it "should return a RailsExampleGroup when given :spec_path => '\\blah\\spec\\foo\\' (windows format) (anything other than controllers, views and helpers)" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '\\blah\\spec\\foo\\blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::RailsExampleGroup
+ end
+
+ it "should return a ViewExampleGroup when given :type => :model" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :type => :view
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ViewExampleGroup
+ end
+
+ it "should return a ViewExampleGroup when given :spec_path => '/blah/spec/views/'" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '/blah/spec/views/blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ViewExampleGroup
+ end
+
+ it "should return a ModelExampleGroup when given :spec_path => '\\blah\\spec\\views\\' (windows format)" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '\\blah\\spec\\views\\blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ViewExampleGroup
+ end
+
+ it "should return a HelperExampleGroup when given :type => :helper" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :type => :helper
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::HelperExampleGroup
+ end
+
+ it "should return a HelperExampleGroup when given :spec_path => '/blah/spec/helpers/'" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '/blah/spec/helpers/blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::HelperExampleGroup
+ end
+
+ it "should return a ModelExampleGroup when given :spec_path => '\\blah\\spec\\helpers\\' (windows format)" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '\\blah\\spec\\helpers\\blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::HelperExampleGroup
+ end
+
+ it "should return a ControllerExampleGroup when given :type => :controller" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :type => :controller
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ControllerExampleGroup
+ end
+
+ it "should return a ControllerExampleGroup when given :spec_path => '/blah/spec/controllers/'" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '/blah/spec/controllers/blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ControllerExampleGroup
+ end
+
+ it "should return a ModelExampleGroup when given :spec_path => '\\blah\\spec\\controllers\\' (windows format)" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '\\blah\\spec\\controllers\\blah.rb'
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ControllerExampleGroup
+ end
+
+ it "should favor the :type over the :spec_path" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '/blah/spec/models/blah.rb', :type => :controller
+ ) {}
+ example_group.superclass.should == Spec::Rails::Example::ControllerExampleGroup
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/helper_spec_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/helper_spec_spec.rb
new file mode 100755
index 00000000..58542c83
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/helper_spec_spec.rb
@@ -0,0 +1,161 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+Spec::Runner.configuration.global_fixtures = :people
+
+describe ExplicitHelper, :type => :helper do
+ include ExplicitHelper
+
+ it "should not require naming the helper if describe is passed a type" do
+ method_in_explicit_helper.should match(/text from a method/)
+ helper.method_in_explicit_helper.should match(/text from a method/)
+ end
+end
+
+module Spec
+ module Rails
+ module Example
+ describe HelperExampleGroup, :type => :helper do
+ helper_name :explicit
+
+ it "DEPRECATED should have direct access to methods defined in helpers" do
+ method_in_explicit_helper.should =~ /text from a method/
+ end
+
+ it "should expose the helper with the #helper method" do
+ helper.method_in_explicit_helper.should =~ /text from a method/
+ end
+
+ it "should have access to named routes" do
+ rspec_on_rails_specs_url.should == "http://test.host/rspec_on_rails_specs"
+ rspec_on_rails_specs_path.should == "/rspec_on_rails_specs"
+
+ helper.named_url.should == "http://test.host/rspec_on_rails_specs"
+ helper.named_path.should == "/rspec_on_rails_specs"
+ end
+
+ it "should fail if the helper method deson't exist" do
+ lambda { non_existent_helper_method }.should raise_error(NameError)
+ lambda { helper.non_existent_helper_method }.should raise_error(NameError)
+ end
+
+ it "should have access to session" do
+ session[:foo] = 'bar'
+ session_foo.should == 'bar'
+ helper.session_foo.should == 'bar'
+ end
+
+ it "should have access to params" do
+ params[:foo] = 'bar'
+ params_foo.should == 'bar'
+ helper.params_foo.should == 'bar'
+ end
+
+ it "should have access to request" do
+ request.stub!(:thing).and_return('bar')
+ request_thing.should == 'bar'
+ helper.request_thing.should == 'bar'
+ end
+
+ it "should have access to flash" do
+ flash[:thing] = 'camera'
+ flash_thing.should == 'camera'
+ helper.flash_thing.should == 'camera'
+ end
+ end
+
+ describe HelperExampleGroup, "#eval_erb", :type => :helper do
+ helper_name :explicit
+
+ it "should support methods that accept blocks" do
+ eval_erb("<% prepend 'foo' do %>bar<% end %>").should == "foobar"
+ end
+ end
+
+ describe HelperExampleGroup, ".fixtures", :type => :helper do
+ helper_name :explicit
+ fixtures :animals
+
+ it "should load fixtures" do
+ pig = animals(:pig)
+ pig.class.should == Animal
+ end
+
+ it "should load global fixtures" do
+ lachie = people(:lachie)
+ lachie.class.should == Person
+ end
+ end
+
+ describe "methods from standard helpers", :type => :helper do
+ helper_name :explicit
+ it "should be exposed to the helper" do
+ helper.link_to("Foo","http://bar").should have_tag("a")
+ end
+ end
+
+ describe HelperExampleGroup, "included modules", :type => :helper do
+ helpers = [
+ ActionView::Helpers::ActiveRecordHelper,
+ ActionView::Helpers::AssetTagHelper,
+ ActionView::Helpers::BenchmarkHelper,
+ ActionView::Helpers::CacheHelper,
+ ActionView::Helpers::CaptureHelper,
+ ActionView::Helpers::DateHelper,
+ ActionView::Helpers::DebugHelper,
+ ActionView::Helpers::FormHelper,
+ ActionView::Helpers::FormOptionsHelper,
+ ActionView::Helpers::FormTagHelper,
+ ActionView::Helpers::JavaScriptHelper,
+ ActionView::Helpers::NumberHelper,
+ ActionView::Helpers::PrototypeHelper,
+ ActionView::Helpers::ScriptaculousHelper,
+ ActionView::Helpers::TagHelper,
+ ActionView::Helpers::TextHelper,
+ ActionView::Helpers::UrlHelper
+ ]
+ helpers << ActionView::Helpers::PaginationHelper rescue nil #removed for 2.0
+ helpers << ActionView::Helpers::JavaScriptMacrosHelper rescue nil #removed for 2.0
+ helpers.each do |helper_module|
+ it "should include #{helper_module}" do
+ self.class.ancestors.should include(helper_module)
+ helper.class.ancestors.should include(helper_module)
+ end
+ end
+ end
+
+ # TODO: BT - Helper Examples should proxy method_missing to a Rails View instance.
+ # When that is done, remove this method
+ describe HelperExampleGroup, "#protect_against_forgery?", :type => :helper do
+ it "should return false" do
+ protect_against_forgery?.should be_false
+ helper.protect_against_forgery?.should be_false
+ end
+ end
+ end
+ end
+end
+
+module Bug11223
+ # see http://rubyforge.org/tracker/index.php?func=detail&aid=11223&group_id=797&atid=3149
+ describe 'Accessing flash from helper spec', :type => :helper do
+ it 'should not raise an error' do
+ lambda { flash['test'] }.should_not raise_error
+ end
+ end
+end
+
+module Spec
+ module Rails
+ module Example
+ describe HelperExampleGroup do
+ it "should clear its name from the description" do
+ group = describe("foo", :type => :helper) do
+ $nested_group = describe("bar") do
+ end
+ end
+ group.description.to_s.should == "foo"
+ $nested_group.description.to_s.should == "foo bar"
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/model_spec_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/model_spec_spec.rb
new file mode 100644
index 00000000..938744db
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/model_spec_spec.rb
@@ -0,0 +1,18 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Rails
+ module Example
+ describe ModelExampleGroup do
+ it "should clear its name from the description" do
+ group = describe("foo", :type => :model) do
+ $nested_group = describe("bar") do
+ end
+ end
+ group.description.to_s.should == "foo"
+ $nested_group.description.to_s.should == "foo bar"
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/shared_behaviour_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/shared_behaviour_spec.rb
new file mode 100755
index 00000000..ef19817d
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/shared_behaviour_spec.rb
@@ -0,0 +1,16 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe "A shared view example_group", :shared => true do
+ it "should have some tag with some text" do
+ response.should have_tag('div', 'This is text from a method in the ViewSpecHelper')
+ end
+end
+
+describe "A view example_group", :type => :view do
+ it_should_behave_like "A shared view example_group"
+
+ before(:each) do
+ render "view_spec/implicit_helper"
+ end
+end
+
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/test_unit_assertion_accessibility_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/test_unit_assertion_accessibility_spec.rb
new file mode 100644
index 00000000..b7a83869
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/test_unit_assertion_accessibility_spec.rb
@@ -0,0 +1,33 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe "assert_equal", :shared => true do
+ it "like assert_equal" do
+ assert_equal 1, 1
+ lambda {
+ assert_equal 1, 2
+ }.should raise_error(Test::Unit::AssertionFailedError)
+ end
+end
+
+describe "A model spec should be able to access 'test/unit' assertions", :type => :model do
+ it_should_behave_like "assert_equal"
+end
+
+describe "A view spec should be able to access 'test/unit' assertions", :type => :view do
+ it_should_behave_like "assert_equal"
+end
+
+describe "A helper spec should be able to access 'test/unit' assertions", :type => :helper do
+ it_should_behave_like "assert_equal"
+end
+
+describe "A controller spec with integrated views should be able to access 'test/unit' assertions", :type => :controller do
+ controller_name :controller_spec
+ integrate_views
+ it_should_behave_like "assert_equal"
+end
+
+describe "A controller spec should be able to access 'test/unit' assertions", :type => :controller do
+ controller_name :controller_spec
+ it_should_behave_like "assert_equal"
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/example/view_spec_spec.rb b/vendor/plugins/rspec-rails/spec/rails/example/view_spec_spec.rb
new file mode 100644
index 00000000..14159c65
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/example/view_spec_spec.rb
@@ -0,0 +1,272 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe "A template with an implicit helper", :type => :view do
+ before(:each) do
+ render "view_spec/implicit_helper"
+ end
+
+ it "should include the helper" do
+ response.should have_tag('div', :content => "This is text from a method in the ViewSpecHelper")
+ end
+
+ it "should include the application helper" do
+ response.should have_tag('div', :content => "This is text from a method in the ApplicationHelper")
+ end
+
+ it "should have access to named routes" do
+ rspec_on_rails_specs_url.should == "http://test.host/rspec_on_rails_specs"
+ rspec_on_rails_specs_path.should == "/rspec_on_rails_specs"
+ end
+end
+
+describe "A template requiring an explicit helper", :type => :view do
+ before(:each) do
+ render "view_spec/explicit_helper", :helper => 'explicit'
+ end
+
+ it "should include the helper if specified" do
+ response.should have_tag('div', :content => "This is text from a method in the ExplicitHelper")
+ end
+
+ it "should include the application helper" do
+ response.should have_tag('div', :content => "This is text from a method in the ApplicationHelper")
+ end
+end
+
+describe "A template requiring multiple explicit helpers", :type => :view do
+ before(:each) do
+ render "view_spec/multiple_helpers", :helpers => ['explicit', 'more_explicit']
+ end
+
+ it "should include all specified helpers" do
+ response.should have_tag('div', :content => "This is text from a method in the ExplicitHelper")
+ response.should have_tag('div', :content => "This is text from a method in the MoreExplicitHelper")
+ end
+
+ it "should include the application helper" do
+ response.should have_tag('div', :content => "This is text from a method in the ApplicationHelper")
+ end
+end
+
+describe "Message Expectations on helper methods", :type => :view do
+ it "should work" do
+ template.should_receive(:method_in_plugin_application_helper).and_return('alternate message 1')
+ render "view_spec/implicit_helper"
+ response.body.should =~ /alternate message 1/
+ end
+
+ it "should work twice" do
+ template.should_receive(:method_in_plugin_application_helper).and_return('alternate message 2')
+ render "view_spec/implicit_helper"
+ response.body.should =~ /alternate message 2/
+ end
+end
+
+describe "A template that includes a partial", :type => :view do
+ def render!
+ render "view_spec/template_with_partial"
+ end
+
+ it "should render the enclosing template" do
+ render!
+ response.should have_tag('div', "method_in_partial in ViewSpecHelper")
+ end
+
+ it "should render the partial" do
+ render!
+ response.should have_tag('div', "method_in_template_with_partial in ViewSpecHelper")
+ end
+
+ it "should include the application helper" do
+ render!
+ response.should have_tag('div', "This is text from a method in the ApplicationHelper")
+ end
+
+ it "should pass expect_render with the right partial" do
+ template.expect_render(:partial => 'partial')
+ render!
+ template.verify_rendered
+ end
+
+ it "should fail expect_render with the wrong partial" do
+ template.expect_render(:partial => 'non_existent')
+ render!
+ begin
+ template.verify_rendered
+ rescue Spec::Mocks::MockExpectationError => e
+ ensure
+ e.backtrace.find{|line| line =~ /view_spec_spec\.rb\:92/}.should_not be_nil
+ end
+ end
+
+ it "should pass expect_render when a partial is expected twice and happens twice" do
+ template.expect_render(:partial => 'partial_used_twice').twice
+ render!
+ template.verify_rendered
+ end
+
+ it "should pass expect_render when a partial is expected once and happens twice" do
+ template.expect_render(:partial => 'partial_used_twice')
+ render!
+ begin
+ template.verify_rendered
+ rescue Spec::Mocks::MockExpectationError => e
+ ensure
+ e.backtrace.find{|line| line =~ /view_spec_spec\.rb\:109/}.should_not be_nil
+ end
+ end
+
+ it "should fail expect_render with the right partial but wrong options" do
+ template.expect_render(:partial => 'partial', :locals => {:thing => Object.new})
+ render!
+ lambda {template.verify_rendered}.should raise_error(Spec::Mocks::MockExpectationError)
+ end
+end
+
+describe "A partial that includes a partial", :type => :view do
+ it "should support expect_render with nested partial" do
+ obj = Object.new
+ template.expect_render(:partial => 'partial', :object => obj)
+ render :partial => "view_spec/partial_with_sub_partial", :locals => { :partial => obj }
+ end
+end
+
+describe "A view that includes a partial using :collection and :spacer_template", :type => :view do
+ it "should render the partial w/ spacer_tamplate" do
+ render "view_spec/template_with_partial_using_collection"
+ response.should have_tag('div',/method_in_partial/)
+ response.should have_tag('div',/ApplicationHelper/)
+ response.should have_tag('div',/ViewSpecHelper/)
+ response.should have_tag('hr#spacer')
+ end
+
+ it "should render the partial" do
+ template.expect_render(:partial => 'partial',
+ :collection => ['Alice', 'Bob'],
+ :spacer_template => 'spacer')
+ render "view_spec/template_with_partial_using_collection"
+ end
+
+end
+
+describe "A view that includes a partial using an array as partial_path", :type => :view do
+ before(:each) do
+ module ActionView::Partials
+ def render_template_with_partial_with_array_support(partial_path, local_assigns = nil, deprecated_local_assigns = nil)
+ if partial_path.is_a?(Array)
+ "Array Partial"
+ else
+ render_partial_without_array_support(partial_path, local_assigns, deprecated_local_assigns)
+ end
+ end
+
+ alias :render_partial_without_array_support :render_partial
+ alias :render_partial :render_template_with_partial_with_array_support
+ end
+
+ @array = ['Alice', 'Bob']
+ assigns[:array] = @array
+ end
+
+ after(:each) do
+ module ActionView::Partials
+ alias :render_template_with_partial_with_array_support :render_partial
+ alias :render_partial :render_partial_without_array_support
+ undef render_template_with_partial_with_array_support
+ end
+ end
+
+ it "should render have the array passed through to render_partial without modification" do
+ render "view_spec/template_with_partial_with_array"
+ response.body.should match(/^Array Partial$/)
+ end
+end
+
+describe "Different types of renders (not :template)", :type => :view do
+ it "should render partial with local" do
+ render :partial => "view_spec/partial_with_local_variable", :locals => {:x => "Ender"}
+ response.should have_tag('div', :content => "Ender")
+ end
+end
+
+describe "A view", :type => :view do
+ before(:each) do
+ session[:key] = "session"
+ params[:key] = "params"
+ flash[:key] = "flash"
+ render "view_spec/accessor"
+ end
+
+ it "should have access to session data" do
+ response.should have_tag("div#session", "session")
+ end
+
+ specify "should have access to params data" do
+ response.should have_tag("div#params", "params")
+ end
+
+ it "should have access to flash data" do
+ response.should have_tag("div#flash", "flash")
+ end
+
+ it "should have a controller param" do
+ response.should have_tag("div#controller", "view_spec")
+ end
+
+ it "should have an action param" do
+ response.should have_tag("div#action", "accessor")
+ end
+end
+
+describe "A view with a form_tag", :type => :view do
+ it "should render the right action" do
+ render "view_spec/entry_form"
+ response.should have_tag("form[action=?]","/view_spec/entry_form")
+ end
+end
+
+describe "An instantiated ViewExampleGroupController", :type => :view do
+ before do
+ render "view_spec/foo/show"
+ end
+
+ it "should return the name of the real controller that it replaces" do
+ @controller.controller_name.should == 'foo'
+ end
+
+ it "should return the path of the real controller that it replaces" do
+ @controller.controller_path.should == 'view_spec/foo'
+ end
+end
+
+describe "render :inline => ...", :type => :view do
+ it "should render ERB right in the spec" do
+ render :inline => %|<%= text_field_tag('field_name', 'Value') %>|
+ response.should have_tag("input[type=?][name=?][value=?]","text","field_name","Value")
+ end
+end
+
+module Spec
+ module Rails
+ module Example
+ describe ViewExampleGroup do
+ it "should clear its name from the description" do
+ group = describe("foo", :type => :view) do
+ $nested_group = describe("bar") do
+ end
+ end
+ group.description.to_s.should == "foo"
+ $nested_group.description.to_s.should == "foo bar"
+ end
+
+ it "should clear ActionView::Base.base_view_path on teardown" do
+ group = describe("base_view_path_cleared flag", :type => :view) {}
+ example = group.it{}
+
+ ActionView::Base.should_receive(:base_view_path=).with(nil)
+ group.run_after_each(example)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/extensions/action_controller_rescue_action_spec.rb b/vendor/plugins/rspec-rails/spec/rails/extensions/action_controller_rescue_action_spec.rb
new file mode 100644
index 00000000..c2575458
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/extensions/action_controller_rescue_action_spec.rb
@@ -0,0 +1,54 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module ActionController
+ describe "Rescue", "#rescue_action in default mode" do
+ before(:each) do
+ @fixture = Object.new
+ @fixture.extend ActionController::Rescue
+ class << @fixture
+ public :rescue_action
+ end
+ end
+
+ it "should raise the passed in exception so examples fail fast" do
+ proc {@fixture.rescue_action(RuntimeError.new("Foobar"))}.should raise_error(RuntimeError, "Foobar")
+ end
+ end
+
+ class RescueOverriddenController < ActionController::Base
+ def rescue_action(error)
+ "successfully overridden"
+ end
+ end
+
+ describe "Rescue", "#rescue_action, when overridden" do
+ before(:each) do
+ @fixture = RescueOverriddenController.new
+ end
+
+ it "should do whatever the overridden method does" do
+ @fixture.rescue_action(RuntimeError.new("Foobar")).should == "successfully overridden"
+ end
+ end
+
+ class SearchController < ActionController::Base
+ end
+
+ describe "Rescue", "#rescue_action when told to use rails error handling" do
+ before(:each) do
+ @controller = SearchController.new
+ @controller.use_rails_error_handling!
+ class << @controller
+ public :rescue_action
+ end
+ end
+
+ it "should use Rails exception handling" do
+ exception = RuntimeError.new("The Error")
+ exception.stub!(:backtrace).and_return(caller)
+ @controller.should_receive(:rescue_action_locally).with(exception)
+
+ @controller.rescue_action(exception)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/extensions/action_view_base_spec.rb b/vendor/plugins/rspec-rails/spec/rails/extensions/action_view_base_spec.rb
new file mode 100644
index 00000000..599249f0
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/extensions/action_view_base_spec.rb
@@ -0,0 +1,48 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'spec/mocks/errors'
+
+describe ActionView::Base, "with RSpec extensions:", :type => :view do
+
+ describe "expect_render" do
+ it "should not raise when render has been received" do
+ template.expect_render(:partial => "name")
+ template.render :partial => "name"
+ end
+
+ it "should raise when render has NOT been received" do
+ template.expect_render(:partial => "name")
+ lambda {
+ template.verify_rendered
+ }.should raise_error
+ end
+
+ it "should return something (like a normal mock)" do
+ template.expect_render(:partial => "name").and_return("Little Johnny")
+ result = template.render :partial => "name"
+ result.should == "Little Johnny"
+ end
+ end
+
+ describe "stub_render" do
+ it "should not raise when stubbing and render has been received" do
+ template.stub_render(:partial => "name")
+ template.render :partial => "name"
+ end
+
+ it "should not raise when stubbing and render has NOT been received" do
+ template.stub_render(:partial => "name")
+ end
+
+ it "should not raise when stubbing and render has been received with different options" do
+ template.stub_render(:partial => "name")
+ template.render :partial => "view_spec/spacer"
+ end
+
+ it "should not raise when stubbing and expecting and render has been received" do
+ template.stub_render(:partial => "name")
+ template.expect_render(:partial => "name")
+ template.render(:partial => "name")
+ end
+ end
+
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/extensions/active_record_spec.rb b/vendor/plugins/rspec-rails/spec/rails/extensions/active_record_spec.rb
new file mode 100644
index 00000000..95d43b25
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/extensions/active_record_spec.rb
@@ -0,0 +1,14 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe "A model" do
+ fixtures :things
+ it "should tell you its required fields" do
+ Thing.new.should have(1).error_on(:name)
+ end
+
+ it "should tell you how many records it has" do
+ Thing.should have(:no).records
+ Thing.create(:name => "THE THING")
+ Thing.should have(1).record
+ end
+end
diff --git a/vendor/plugins/rspec-rails/spec/rails/matchers/assert_select_spec.rb b/vendor/plugins/rspec-rails/spec/rails/matchers/assert_select_spec.rb
new file mode 100644
index 00000000..85bd08e4
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec/rails/matchers/assert_select_spec.rb
@@ -0,0 +1,806 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+# assert_select plugins for Rails
+#
+# Copyright (c) 2006 Assaf Arkin, under Creative Commons Attribution and/or MIT License
+# Developed for http://co.mments.com
+# Code and documention: http://labnotes.org
+
+class AssertSelectController < ActionController::Base
+
+ def response=(content)
+ @content = content
+ end
+
+ #NOTE - this is commented because response is implemented in lib/spec/rails/context/controller
+ # def response(&block)
+ # @update = block
+ # end
+ #
+ def html()
+ render :text=>@content, :layout=>false, :content_type=>Mime::HTML
+ @content = nil
+ end
+
+ def rjs()
+ update = @update
+ render :update do |page|
+ update.call page
+ end
+ @update = nil
+ end
+
+ def xml()
+ render :text=>@content, :layout=>false, :content_type=>Mime::XML
+ @content = nil
+ end
+
+ def rescue_action(e)
+ raise e
+ end
+
+end
+
+class AssertSelectMailer < ActionMailer::Base
+
+ def test(html)
+ recipients "test \n"This is not a big problem," he said.\n
}
+ text = "\n\"This is not a big problem,\" he said.\n"
+ html = "\n\"This is not a big problem,\" he said.\n"
+ response.should have_tag("pre", text)
+ lambda { response.should have_tag("pre", html) }.should raise_error(SpecFailed)
+ response.should have_tag("pre", :html=>html)
+ lambda { response.should have_tag("pre", :html=>text) }.should raise_error(SpecFailed)
+ end
+
+ it "should match number of instances" do
+ render_html %Q{John
George
Paul
Ringo
Text
+ Another
+
diff --git a/vendor/plugins/rspec-rails/spec_resources/views/view_spec/accessor.rhtml b/vendor/plugins/rspec-rails/spec_resources/views/view_spec/accessor.rhtml
new file mode 100644
index 00000000..1d6f96b0
--- /dev/null
+++ b/vendor/plugins/rspec-rails/spec_resources/views/view_spec/accessor.rhtml
@@ -0,0 +1,5 @@
+== instead of .equal?).
+
+Lastly, should_be used to handle true and false differently from any other values. We've removed
+this special handling, so now actual.should_be true will fail for any value other than true (it
+used to pass for any non-nil, non-false value), and actual.should_be false will fail for any
+value other than false (it used to pass for nil or false).
+
+Here's what you'll need to do to update your specs:
+# search for "should_equal" and replace with "should_eql"
+# run specs
+
+If any specs still fail, they are probably related to should be_true or should_be_false using
+non-boolean values. Those you'll just have to inspect manually and adjust appropriately (sorry!).
+
+--------------------------------------------------
+Specifying multiple return values in mocks now works like this:
+
+mock.should_receive(:message).and_return(1,2,3)
+
+It used to work like this:
+
+mock.should_receive(:message).and_return([1,2,3])
+
+but we decided that was counter intuitive and otherwise lame.
+
+Here's what you'll need to do to update your specs:
+# search for "and_return(["
+# get rid of the "[" and "]"
+
+--------------------------------------------------
+RSpec on Rails now supports the following (thanks to ZenTest upon which it is built):
+
+# Separate specs for models, views, controllers and helpers
+# Controller specs are completely decoupled from the views by default (though you can tell them to couple themselves if you prefer)
+# View specs are completely decoupled from app-specific controllers
+
+See http://rspec.rubyforge.org/documentation/rails/index.html for more information
+--------------------------------------------------
+As usual, there are also other new features and bug fixes:
+
+* Added lots of documentation on mocks/stubs and the rails plugin.
+* Added support for assigns[key] syntax for controller specs (to align w/ pre-existing syntax for view specs)
+* Added support for controller.should_redirect_to
+* RSpec on Rails automatically checks whether it's compatible with the installed RSpec
+* Applied [#6393] rspec_on_rails uses deprecated '@response' instead of the accessor
+* RSpec now has 100% spec coverage(!)
+* Added support for stubbing and partial mocking
+* Progress (....F..F.) is now coloured. Tweaked patch from KAKUTANI Shintaro.
+* Backtrace now excludes the rcov runner (/usr/local/bin/rcov)
+* Fixed [#5539] predicates do not work w/ rails
+* Added [#6091] support for Regexp matching messages sent to should_raise
+* Added [#6333] support for Regexp matching in mock arguments
+* Applied [#6283] refactoring of diff support to allow selectable formats and custom differs
+* Fixed [#5564] "ruby spec_file.rb" doesn't work the same way as "spec spec_file.rb"
+* Fixed [#6056] Multiple output of failing-spec notice
+* Fixed [#6233] Colours in specdoc
+* Applied [#6207] Allows --diff option to diff target and expected's #inspect output (Patch by Lachie Cox)
+* Fixed [#6203] Failure messages are misleading - consider using inspect.
+* Added [#6334] subject.should_have_xyz will try to call subject.has_xyz? - use this for hash.should_have_key(key)
+* Fixed [#6017] Rake task should ignore empty or non-existent spec-dirs
+
+== Version 0.6.4
+
+In addition to a number of bug fixes and patches, this release begins to formalize the support for
+RSpec on Rails.
+
+* Added Christopher Petrilli's TextMate bundle to vendor/textmate/RSpec.tmbundle
+* Fixed [#5909], once again supporting multi_word_predicates
+* Applied [#5873] - response.should_have_rjs (initial patch from Jake Howerton, based on ARTS by Kevin Clark)
+* Added generation of view specs for rspec_on_rails
+* Applied [#5815] active_record_subclass.should_have(3).records
+* Added support in "rake stats" for view specs (in spec/views)
+* Applied [#5801] QuickRef.pdf should say RSpec, not rSpec
+* Applied [#5728] rails_spec_runner fails on Windows (Patch from Lindsay Evans).
+* Applied [#5708] RSpec Rails plugin rspec_controller generator makes specs that do not parse.
+* Cleaned up RSpec on Rails so it doesn't pollute as much during bootstrapping.
+* Added support for response.should_have_tag and response.should_not_have_tag (works just like assert_tag in rails)
+* Added new -c, --colour, --color option for colourful (red/green) output. Inspired from Pat Eyler's Redgreen gem.
+* Added examples for Watir and Selenium under the gem's vendor directory.
+* Renamed rails_spec_runner to rails_spec_server (as referred to in the docs)
+* Added support for trying a plural for arbitrary predicates. E.g. Album.should_exist(:name => "Hey Jude") will call Album.exists?(:name => "Hey Jude")
+* Added support for should_have to work with methods taking args returning a collection. E.g. @dave.should_have(3).albums_i_have_that_this_guy_doesnt(@aslak)
+* Added [#5570] should_not_receive(:msg).with(:specific, "args")
+* Applied [#5065] to support using define_method rather than method_missing to capture expected messages on mocks. Thanks to Eero Saynatkari for the tip that made it work.
+* Restructured directories and Modules in order to separate rspec into three distinct Modules: Spec::Expectations, Spec::Runner and Spec::Mocks. This will allow us to more easily integrate other mock frameworks and/or allow test/unit users to take advantage of the expectation API.
+* Applied [#5620] support any boolean method and arbitrary comparisons (5.should_be < 6) (Patch from Mike Williams)
+
+== Version 0.6.3
+
+This release fixes some minor bugs related to RSpec on Rails
+Note that if you upgrade a rails app with this version of the rspec_on_rails plugin
+you should remove your lib/tasks/rspec.rake if it exists.
+
+* Backtraces from drb (and other standard ruby libraries) are now stripped from backtraces.
+* Applied [#5557] Put rspec.rake into the task directory of the RSpec on Rails plugin (Patch from Daniel Siemssen)
+* Applied [#5556] rails_spec_server loads environment.rb twice (Patch from Daniel Siemssen)
+
+== Version 0.6.2
+This release fixes a couple of regressions with the rake task that were introduced in the previous version (0.6.1)
+
+* Fixed [#5518] ruby -w: warnings in 0.6.1
+* Applied [#5525] fix rake task path to spec tool for gem-installed rspec (patch from Riley Lynch)
+* Fixed a teensey regression with the rake task - introduced in 0.6.1. The spec command is now quoted so it works on windows.
+
+== Version 0.6.1
+This is the "fix the most annoying bugs release" of RSpec. There are 9 bugfixes this time.
+Things that may break backwards compatibility:
+1) Spec::Rake::SpecTask no longer has the options attribute. Use ruby_opts, spec_opts and rcov_opts instead.
+
+* Fixed [#4891] RCOV task failing on windows
+* Fixed [#4896] Shouldn't modify user's $LOAD_PATH (Tip from Gavin Sinclair)
+* Fixed [#5369] ruby -w: warnings in RSpec 0.5.16 (Tip from Suraj Kurapati)
+* Applied [#5141] ExampleMatcher doesn't escape strings before matching (Patch from Nikolai Weibull).
+* Fixed [#5224] Move 'require diff-lcs' from test_helper.rb to diff_test.rb (Tip from Chris Roos)
+* Applied [#5449] Rake stats for specs (Patch from Nick Sieger)
+* Applied [#5468, #5058] Fix spec runner to correctly run controller specs (Patch from Daniel Siemssen)
+* Applied fixes to rails_spec_server to improve its ability to run several times. (Patch from Daniel Siemssen)
+* Changed RCov::VerifyTask to fail if the coverage is above the threshold. This is to ensure it gets bumped when coverage improves.
+
+== Version 0.6.0
+This release makes an official commitment to underscore_syntax (with no more support for dot.syntax)
+
+* Fixed bug (5292) that caused mock argument matching to fail
+* Converted ALL tests to use underscore syntax
+* Fixed all remaining problems with underscores revealed by converting all the tests to underscores
+* Enhanced sugar to support combinations of methods (i.e. once.and_return)
+* Simplified helper structure taking advantage of dot/underscore combos (i.e. should.be.an_instance_of, which can be expressed as should be_an_instance_of)
+* Added support for at_most in mocks
+* Added support for should_not_receive(:msg) (will be removing should_receive(:msg).never some time soon)
+* Added support for should_have_exactly(5).items_in_collection
+
+== Version 0.5.16
+This release improves Rails support and test2spec translation.
+
+* Fixed underscore problems that occurred when RSpec was used in Rails
+* Simplified the Rails support by packaging it as a plugin instead of a generator gem.
+* Fixed [#5063] 'rspec_on_rails' require line in spec_helper.rb
+* Added pre_commit rake task to reduce risk of regressions. Useful for RSpec developers and patchers.
+* Added failure_message to RSpec Rake task
+* test2spec now defines converted helper methods outside of the setup block (bug #5057).
+
+== Version 0.5.15
+This release removes a prematurely added feature that shouldn't have been added.
+
+* Removed support for differences that was added in 0.5.14. The functionality is not aligned with RSpec's vision.
+
+== Version 0.5.14
+This release introduces better ways to extend specs, improves some of the core API and
+a experimental support for faster rails specs.
+
+* Added proc methods for specifying differences (increments and decrements). See difference_test.rb
+* Methods can now be defined alongside specs. This obsoletes the need for defining methods in setup. (Patch #5002 from Brian Takita)
+* Sugar (underscores) now works correctly with should be_a_kind_of and should be_an_instance_of
+* Added support for include and inherit in contexts. (Patch #4971 from Brian Takita)
+* Added rails_spec and rails_spec_server for faster specs on rails (still buggy - help needed)
+* Fixed bug that caused should_render to break if given a :symbol (in Rails)
+* Added support for comparing exception message in should_raise and should_not_raise
+
+== Version 0.5.13
+This release fixes some subtle bugs in the mock API.
+
+* Use fully-qualified class name of Exceptions in failure message. Easier to debug that way.
+* Fixed a bug that caused mocks to yield a one-element array (rather than the element) when one yield arg specified.
+* Mocks not raise AmbiguousReturnError if an explicit return is used at the same time as an expectation block.
+* Blocks passed to yielding mocks can now raise without causing mock verification to fail.
+
+== Version 0.5.12
+This release adds diff support for failure messages, a HTML formatter plus some other
+minor enhancements.
+
+* Added HTML formatter.
+* Added fail_on_error option to spectask.
+* Added support for diffing, using the diff-lcs Rubygem (#2648).
+* Remove RSpec on Rails files from backtrace (#4694).
+* All of RSpec's own tests run successfully after translation with test2spec.
+* Added --verbose mode for test2spec - useful for debugging when classes fail to translate.
+* Output of various formatters is now flushed - to get more continuous output.
+
+== Version 0.5.11
+This release makes test2spec usable with Rails (with some manual steps).
+See http://rspec.rubyforge.org/tools/rails.html for more details
+
+* test2spec now correctly translates bodies of helper methods (non- test_*, setup and teardown ones).
+* Added more documentation about how to get test2spec to work with Rails.
+
+== Version 0.5.10
+This version features a second rewrite of test2spec - hopefully better than the previous one.
+
+* Improved test2spec's internals. It now transforms the syntax tree before writing out the code.
+
+== Version 0.5.9
+This release improves test2spec by allowing more control over the output
+
+* Added --template option to test2spec, which allows for custom output driven by ERB
+* Added --quiet option to test2spec
+* Removed unnecessary dependency on RubyToC
+
+== Version 0.5.8
+This release features a new Test::Unit to RSpec translation tool.
+Also note that the RubyGem of the previous release (0.5.7) was corrupt.
+We're close to being able to translate all of RSpec's own Test::Unit
+tests and have them run successfully!
+
+* Updated test2spec documentation.
+* Replaced old test2rspec with a new test2spec, which is based on ParseTree and RubyInline.
+
+== Version 0.5.7
+This release changes examples and documentation to recommend underscores rather than dots,
+and addresses some bugfixes and changes to the spec commandline.
+
+* spec DIR now works correctly, recursing down and slurping all *.rb files
+* All documentation and examples are now using '_' instead of '.'
+* Custom external formatters can now be specified via --require and --format.
+
+== Version 0.5.6
+This release fixes a bug in the Rails controller generator
+
+* The controller generator did not write correct source code (missing 'do'). Fixed.
+
+== Version 0.5.5
+This release adds initial support for Ruby on Rails in the rspec_generator gem.
+
+* [Rails] Reorganised Lachie's original code to be a generator packaged as a gem rather than a plugin.
+* [Rails] Imported code from http://lachie.info/svn/projects/rails_plugins/rspec_on_rails (Written by Lachie Cox)
+* Remove stack trace lines from TextMate's Ruby bundle
+* Better error message from spectask when no spec files are found.
+
+== Version 0.5.4
+The "the tutorial is ahead of the gem" release
+
+* Support for running a single spec with --spec
+* Exitcode is now 1 unless all specs pass, in which case it's 0.
+* -v, --version now both mean the same thing
+* For what was verbose output (-v), use --format specdoc or -f s
+* --format rdoc always runs in dry-run mode
+* Removed --doc and added --format and --dry-run
+* Refactored towards more pluggable formatters
+* Use webgen's execute tag when generating website (more accurate)
+* Fixed incorrect quoting of spec_opts in SpecTask
+* Added patch to enable underscored shoulds like 1.should_equal(1) - patch from Rich Kilmer
+* Removed most inherited instance method from Mock, making more methods mockable.
+* Made the RCovVerify task part of the standard toolset.
+* Documented Rake task and how to use it with Rcov
+* Implemented tags for website (hooking into ERB, RedCloth and syntax)
+* RSpec Rake task now takes spec_opts and out params so it can be used for doc generation
+* RCov integration for RSpec Rake task (#4058)
+* Group all results instead of printing them several times (#4057)
+* Mocks can now yield
+* Various improvements to error reporting (including #4191)
+* backtrace excludes rspec code - use -b to include it
+* split examples into examples (passing) and failing_examples
+
+== Version 0.5.3
+The "hurry up, CoR is in two days" release.
+
+* Don't run rcov by default
+* Make separate task for running tests with RCov
+* Added Rake task to fail build if coverage drops below a certain threshold
+* Even more failure output cleanup (simplification)
+* Added duck_type constraint for mocks
+
+== Version 0.5.2
+This release has minor improvements to the commandline and fixes some gem warnings
+
+* Readded README to avoid RDoc warnings
+* Added --version switch to commandline
+* More changes to the mock API
+
+== Version 0.5.1
+This release is the first release of RSpec with a new website. It will look better soon.
+
+* Added initial documentation for API
+* Added website based on webgen
+* Modified test task to use rcov
+* Deleted unused code (thanks, rcov!)
+* Various changes to the mock API,
+* Various improvements to failure reporting
+
+== Version 0.5.0
+This release introduces a new API and obsolesces previous versions.
+
+* Moved source code to separate subfolders
+* Added new DSL runner based on instance_exec
+* Added spike for testdox/rdoc generation
+* merge Astels' and Chelimsky's work on ShouldHelper
+* this would be 0.5.0 if I updated the documentation
+* it breaks all of your existing specifications. We're not sorry.
+
+== Version 0.3.2
+
+The "srbaker is an idiot" release.
+
+* also forgot to update the path to the actual Subversion repository
+* this should be it
+
+== Version 0.3.1
+
+This is just 0.3.0, but with the TUTORIAL added to the documentation list.
+
+* forgot to include TUTORIAL in the documentation
+
+== Version 0.3.0
+
+It's been a while since last release, lots of new stuff is available. For instance:
+
+* improvements to the runners
+* addition of should_raise expectation (thanks to Brian Takita)
+* some documentation improvements
+* RSpec usable as a DSL
+
+== Version 0.2.0
+
+This release provides a tutorial for new users wishing to get started with
+RSpec, and many improvements.
+
+* improved reporting in the spec runner output
+* update the examples to the new mock api
+* added TUTORIAL, a getting started document for new users of RSpec
+
+== Version 0.1.7
+
+This release improves installation and documentation, mock integration and error reporting.
+
+* Comparison errors now print the class name too.
+* Mocks now take an optional +options+ parameter to specify behaviour.
+* Removed __expects in favour of should_receive
+* Added line number reporting in mock error messages for unreceived message expectations.
+* Added should_match and should_not_match.
+* Added a +mock+ method to Spec::Context which will create mocks that autoverify (no need to call __verify).
+* Mocks now require names in the constructor to ensure sensible error messages.
+* Made 'spec' executable and updated usage instructions in README accordingly.
+* Made more parts of the Spec::Context API private to avoid accidental usage.
+* Added more RDoc to Spec::Context.
+
+== Version 0.1.6
+
+More should methods.
+
+* Added should_match and should_not_match.
+
+== Version 0.1.5
+
+Included examples and tests in gem.
+
+== Version 0.1.4
+
+More tests on block based Mock expectations.
+
+== Version 0.1.3
+
+Improved mocking:
+
+* block based Mock expectations.
+
+== Version 0.1.2
+
+This release adds some improvements to the mock API and minor syntax improvements
+
+* Added Mock.should_expect for a more consistent DSL.
+* Added MockExpectation.and_returns for a better DSL.
+* Made Mock behave as a null object after a call to Mock.ignore_missing
+* Internal syntax improvements.
+* Improved exception trace by adding exception class name to error message.
+* Renamed some tests for better consistency.
+
+== Version 0.1.1
+
+This release adds some shoulds and improves error reporting
+
+* Added should be_same_as and should_not be_same_as.
+* Improved error reporting for comparison expectations.
+
+== Version 0.1.0
+
+This is the first preview release of RSpec, a Behaviour-Driven Development library for Ruby
+
+* Added Rake script with tasks for gems, rdoc etc.
+* Added an XForge task to make release go easier.
diff --git a/vendor/plugins/rspec/MIT-LICENSE b/vendor/plugins/rspec/MIT-LICENSE
new file mode 100644
index 00000000..336e52c9
--- /dev/null
+++ b/vendor/plugins/rspec/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2005-2008 The RSpec Development Team
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/plugins/rspec/README b/vendor/plugins/rspec/README
new file mode 100644
index 00000000..a532dca9
--- /dev/null
+++ b/vendor/plugins/rspec/README
@@ -0,0 +1,36 @@
+== RSpec
+
+RSpec is a Behaviour Driven Development framework with tools to express User Stories
+with Executable Scenarios and Executable Examples at the code level.
+
+RSpec ships with several modules:
+
+Spec::Story provides a framework for expressing User Stories and Scenarios
+
+Spec::Example provides a framework for expressing Isolated Examples
+
+Spec::Matchers provides Expression Matchers for use with Spec::Expectations
+and Spec::Mocks.
+
+Spec::Expectations supports setting expectations on your objects so you
+can do things like:
+
+ result.should equal(expected_result)
+
+Spec::Mocks supports creating Mock Objects, Stubs, and adding Mock/Stub
+behaviour to your existing objects.
+
+== Installation
+
+The simplest approach is to install the gem (as root in some environments):
+
+ gem install -r rspec
+
+== Building the RSpec gem
+
+If you prefer to build the gem locally:
+
+ git clone git://github.com/dchelimsky/rspec.git
+ cd rspec
+ rake gem
+ gem install pkg/rspec-0.x.x.gem #as root
diff --git a/vendor/plugins/rspec/Rakefile b/vendor/plugins/rspec/Rakefile
new file mode 100644
index 00000000..797e0424
--- /dev/null
+++ b/vendor/plugins/rspec/Rakefile
@@ -0,0 +1,262 @@
+$:.unshift('lib')
+require 'rubygems'
+require 'rake/gempackagetask'
+require 'rake/contrib/rubyforgepublisher'
+require 'rake/clean'
+require 'rake/rdoctask'
+require 'rake/testtask'
+require 'spec/version'
+dir = File.dirname(__FILE__)
+
+# Some of the tasks are in separate files since they are also part of the website documentation
+load File.dirname(__FILE__) + '/rake_tasks/examples.rake'
+load File.dirname(__FILE__) + '/rake_tasks/examples_with_rcov.rake'
+load File.dirname(__FILE__) + '/rake_tasks/failing_examples_with_html.rake'
+load File.dirname(__FILE__) + '/rake_tasks/verify_rcov.rake'
+
+PKG_NAME = "rspec"
+PKG_VERSION = Spec::VERSION::STRING
+PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
+PKG_FILES = FileList[
+ '[A-Z]*',
+ 'lib/**/*.rb',
+ 'spec/**/*',
+ 'examples/**/*',
+ 'failing_examples/**/*',
+ 'plugins/**/*',
+ 'stories/**/*',
+ 'rake_tasks/**/*'
+]
+
+task :default => [:verify_rcov]
+task :verify_rcov => [:spec, :stories]
+
+desc "Run all specs"
+Spec::Rake::SpecTask.new do |t|
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.spec_opts = ['--options', 'spec/spec.opts']
+ unless ENV['NO_RCOV']
+ t.rcov = true
+ t.rcov_dir = '../doc/output/coverage'
+ t.rcov_opts = ['--exclude', 'lib/spec.rb,lib/spec/runner.rb,spec\/spec,bin\/spec,examples,\/var\/lib\/gems,\/Library\/Ruby,\.autotest']
+ end
+end
+
+desc "Run all stories"
+task :stories do
+ html = 'story_server/prototype/rspec_stories.html'
+ ruby "stories/all.rb --colour --format plain --format html:#{html}"
+ unless IO.read(html) =~ //m
+ raise 'highlighted parameters are broken in story HTML'
+ end
+end
+
+desc "Run all specs and store html output in doc/output/report.html"
+Spec::Rake::SpecTask.new('spec_html') do |t|
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.spec_opts = ['--format html:../../../../doc/output/report.html', '--format progress','--backtrace']
+end
+
+desc "Run all failing examples"
+Spec::Rake::SpecTask.new('failing_examples') do |t|
+ t.spec_files = FileList['failing_examples/**/*_spec.rb']
+end
+
+desc 'Generate RDoc'
+rd = Rake::RDocTask.new do |rdoc|
+ rdoc.rdoc_dir = '../doc/output/rdoc'
+ rdoc.options << '--title' << 'RSpec' << '--line-numbers' << '--inline-source' << '--main' << 'README'
+ rdoc.rdoc_files.include('README', 'CHANGES', 'MIT-LICENSE', 'UPGRADE', 'lib/**/*.rb')
+end
+
+spec = Gem::Specification.new do |s|
+ s.name = PKG_NAME
+ s.version = PKG_VERSION
+ s.summary = Spec::VERSION::DESCRIPTION
+ s.description = <<-EOF
+ RSpec is a behaviour driven development (BDD) framework for Ruby. RSpec was
+ created in response to Dave Astels' article _A New Look at Test Driven Development_
+ which can be read at: http://daveastels.com/index.php?p=5 RSpec is intended to
+ provide the features discussed in Dave's article.
+ EOF
+
+ s.files = PKG_FILES.to_a
+ s.require_path = 'lib'
+
+ s.has_rdoc = true
+ s.rdoc_options = rd.options
+ s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$|^EXAMPLES.rd$/ }.to_a
+
+ s.bindir = 'bin'
+ s.executables = ['spec', 'spec_translator']
+ s.default_executable = 'spec'
+ s.author = "RSpec Development Team"
+ s.email = "rspec-devel@rubyforge.org"
+ s.homepage = "http://rspec.rubyforge.org"
+ s.platform = Gem::Platform::RUBY
+ s.rubyforge_project = "rspec"
+end
+
+Rake::GemPackageTask.new(spec) do |pkg|
+ pkg.need_zip = true
+ pkg.need_tar = true
+end
+
+def egrep(pattern)
+ Dir['**/*.rb'].each do |fn|
+ count = 0
+ open(fn) do |f|
+ while line = f.gets
+ count += 1
+ if line =~ pattern
+ puts "#{fn}:#{count}:#{line}"
+ end
+ end
+ end
+ end
+end
+
+desc "Look for TODO and FIXME tags in the code"
+task :todo do
+ egrep /(FIXME|TODO|TBD)/
+end
+
+task :release => [:verify_committed, :verify_user, :spec, :publish_packages, :tag, :publish_news]
+
+desc "Verifies that there is no uncommitted code"
+task :verify_committed do
+ IO.popen('git status') do |io|
+ io.each_line do |line|
+ raise "\n!!! Do a git commit first !!!\n\n" if line =~ /^#\s*modified:/
+ end
+ end
+end
+
+desc "Creates a tag in svn"
+task :tag do
+ # from = `svn info #{File.dirname(__FILE__)}`.match(/URL: (.*)\/rspec/n)[1]
+ # to = from.gsub(/trunk/, "tags/#{Spec::VERSION::TAG}")
+ # current = from.gsub(/trunk/, "tags/CURRENT")
+ #
+ # puts "Creating tag in SVN"
+ # tag_cmd = "svn cp #{from} #{to} -m \"Tag release #{Spec::VERSION::FULL_VERSION}\""
+ # `#{tag_cmd}` ; raise "ERROR: #{tag_cmd}" unless $? == 0
+ #
+ # puts "Removing CURRENT"
+ # remove_current_cmd = "svn rm #{current} -m \"Remove tags/CURRENT\""
+ # `#{remove_current_cmd}` ; raise "ERROR: #{remove_current_cmd}" unless $? == 0
+ #
+ # puts "Re-Creating CURRENT"
+ # create_current_cmd = "svn cp #{to} #{current} -m \"Copy #{Spec::VERSION::TAG} to tags/CURRENT\""
+ # `#{create_current_cmd}` ; "ERROR: #{create_current_cmd}" unless $? == 0
+end
+
+task :verify_user do
+ raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
+end
+
+desc "Upload Website to RubyForge"
+task :publish_website => [:verify_user, :website] do
+ unless Spec::VERSION::RELEASE_CANDIDATE
+ publisher = Rake::SshDirPublisher.new(
+ "rspec-website@rubyforge.org",
+ "/var/www/gforge-projects/#{PKG_NAME}",
+ "../doc/output"
+ )
+ publisher.upload
+ else
+ puts "** Not publishing packages to RubyForge - this is a prerelease"
+ end
+end
+
+desc "Upload Website archive to RubyForge"
+task :archive_website => [:verify_user, :website] do
+ publisher = Rake::SshDirPublisher.new(
+ "rspec-website@rubyforge.org",
+ "/var/www/gforge-projects/#{PKG_NAME}/#{Spec::VERSION::TAG}",
+ "../doc/output"
+ )
+ publisher.upload
+end
+
+desc "Package the Rails plugin"
+task :package_rspec_on_rails do
+ mkdir 'pkg' rescue nil
+ rm_rf "pkg/rspec-rails-#{PKG_VERSION}" rescue nil
+ `git clone ../rspec-rails pkg/rspec-rails-#{PKG_VERSION}`
+ rm_rf "pkg/rspec-rails-#{PKG_VERSION}/.git"
+ Dir.chdir 'pkg' do
+ `tar cvzf rspec-rails-#{PKG_VERSION}.tgz rspec-rails-#{PKG_VERSION}`
+ end
+end
+task :pkg => :package_rspec_on_rails
+
+desc "Package the RSpec.tmbundle"
+task :package_tmbundle do
+ mkdir 'pkg' rescue nil
+ rm_rf "pkg/RSpec-#{PKG_VERSION}.tmbundle" rescue nil
+ `git clone ../../../../RSpec.tmbundle pkg/RSpec-#{PKG_VERSION}.tmbundle`
+ rm_rf "pkg/RSpec-#{PKG_VERSION}.tmbundle/.git"
+ Dir.chdir 'pkg' do
+ `tar cvzf RSpec-#{PKG_VERSION}.tmbundle.tgz RSpec-#{PKG_VERSION}.tmbundle`
+ end
+end
+task :pkg => :package_tmbundle
+
+desc "Publish gem+tgz+zip on RubyForge. You must make sure lib/version.rb is aligned with the CHANGELOG file"
+task :publish_packages => [:verify_user, :package, :pkg] do
+ release_files = FileList[
+ "pkg/#{PKG_FILE_NAME}.gem",
+ "pkg/#{PKG_FILE_NAME}.tgz",
+ "pkg/rspec-rails-#{PKG_VERSION}.tgz",
+ "pkg/#{PKG_FILE_NAME}.zip",
+ "pkg/RSpec-#{PKG_VERSION}.tmbundle.tgz"
+ ]
+ unless Spec::VERSION::RELEASE_CANDIDATE
+ require 'meta_project'
+ require 'rake/contrib/xforge'
+
+ Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |xf|
+ # Never hardcode user name and password in the Rakefile!
+ xf.user_name = ENV['RUBYFORGE_USER']
+ xf.files = release_files.to_a
+ xf.release_name = "RSpec #{PKG_VERSION}"
+ end
+ else
+ puts "SINCE THIS IS A PRERELEASE, FILES ARE UPLOADED WITH SSH, NOT TO THE RUBYFORGE FILE SECTION"
+ puts "YOU MUST TYPE THE PASSWORD #{release_files.length} TIMES..."
+
+ host = "rspec-website@rubyforge.org"
+ remote_dir = "/var/www/gforge-projects/#{PKG_NAME}"
+
+ publisher = Rake::SshFilePublisher.new(
+ host,
+ remote_dir,
+ File.dirname(__FILE__),
+ *release_files
+ )
+ publisher.upload
+
+ puts "UPLADED THE FOLLOWING FILES:"
+ release_files.each do |file|
+ name = file.match(/pkg\/(.*)/)[1]
+ puts "* http://rspec.rubyforge.org/#{name}"
+ end
+
+ puts "They are not linked to anywhere, so don't forget to tell people!"
+ end
+end
+
+desc "Publish news on RubyForge"
+task :publish_news => [:verify_user] do
+ unless Spec::VERSION::RELEASE_CANDIDATE
+ require 'meta_project'
+ require 'rake/contrib/xforge'
+ Rake::XForge::NewsPublisher.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |news|
+ # Never hardcode user name and password in the Rakefile!
+ news.user_name = ENV['RUBYFORGE_USER']
+ end
+ else
+ puts "** Not publishing news to RubyForge - this is a prerelease"
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/TODO b/vendor/plugins/rspec/TODO
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/vendor/plugins/rspec/TODO
@@ -0,0 +1 @@
+
diff --git a/vendor/plugins/rspec/UPGRADE b/vendor/plugins/rspec/UPGRADE
new file mode 100644
index 00000000..923b3153
--- /dev/null
+++ b/vendor/plugins/rspec/UPGRADE
@@ -0,0 +1,7 @@
+== Spec::Rails
+
+ script/generate rspec
+
+Or modify spec_helper.rb based on the template, which can be found at:
+
+ vendor/plugins/rspec_on_rails/generators/rspec/templates/spec_helper.rb
\ No newline at end of file
diff --git a/vendor/plugins/rspec/bin/spec b/vendor/plugins/rspec/bin/spec
new file mode 100755
index 00000000..283176d7
--- /dev/null
+++ b/vendor/plugins/rspec/bin/spec
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
+require 'spec'
+exit ::Spec::Runner::CommandLine.run(rspec_options)
diff --git a/vendor/plugins/rspec/bin/spec_translator b/vendor/plugins/rspec/bin/spec_translator
new file mode 100755
index 00000000..abd50b74
--- /dev/null
+++ b/vendor/plugins/rspec/bin/spec_translator
@@ -0,0 +1,8 @@
+#!/usr/bin/env ruby
+raise "\n\nUsage: spec_translator from_dir to_dir\n\n" if ARGV.size != 2
+$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
+require 'spec/translator'
+t = ::Spec::Translator.new
+from = ARGV[0]
+to = ARGV[1]
+t.translate(from, to)
diff --git a/vendor/plugins/rspec/examples/pure/autogenerated_docstrings_example.rb b/vendor/plugins/rspec/examples/pure/autogenerated_docstrings_example.rb
new file mode 100644
index 00000000..a4928ef4
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/autogenerated_docstrings_example.rb
@@ -0,0 +1,19 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+# Run spec w/ -fs to see the output of this file
+
+describe "Examples with no descriptions" do
+
+ # description is auto-generated as "should equal(5)" based on the last #should
+ it do
+ 3.should equal(3)
+ 5.should equal(5)
+ end
+
+ it { 3.should be < 5 }
+
+ it { ["a"].should include("a") }
+
+ it { [1,2,3].should respond_to(:size) }
+
+end
diff --git a/vendor/plugins/rspec/examples/pure/before_and_after_example.rb b/vendor/plugins/rspec/examples/pure/before_and_after_example.rb
new file mode 100644
index 00000000..7db6274e
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/before_and_after_example.rb
@@ -0,0 +1,40 @@
+require File.dirname(__FILE__) + '/spec_helper'
+$global = 0
+
+describe "State created in before(:all)" do
+ before :all do
+ @sideeffect = 1
+ $global +=1
+ end
+
+ before :each do
+ @isolated = 1
+ end
+
+ it "should be accessible from example" do
+ @sideeffect.should == 1
+ $global.should == 1
+ @isolated.should == 1
+
+ @sideeffect += 1
+ @isolated += 1
+ end
+
+ it "should not have sideffects" do
+ @sideeffect.should == 1
+ $global.should == 2
+ @isolated.should == 1
+
+ @sideeffect += 1
+ @isolated += 1
+ end
+
+ after :each do
+ $global += 1
+ end
+
+ after :all do
+ $global.should == 3
+ $global = 0
+ end
+end
diff --git a/vendor/plugins/rspec/examples/pure/behave_as_example.rb b/vendor/plugins/rspec/examples/pure/behave_as_example.rb
new file mode 100755
index 00000000..e95d1469
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/behave_as_example.rb
@@ -0,0 +1,45 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+def behave_as_electric_musician
+ respond_to(:read_notes, :turn_down_amp)
+end
+
+def behave_as_musician
+ respond_to(:read_notes)
+end
+
+module BehaveAsExample
+
+ class BluesGuitarist
+ def read_notes; end
+ def turn_down_amp; end
+ end
+
+ class RockGuitarist
+ def read_notes; end
+ def turn_down_amp; end
+ end
+
+ class ClassicGuitarist
+ def read_notes; end
+ end
+
+ describe BluesGuitarist do
+ it "should behave as guitarist" do
+ BluesGuitarist.new.should behave_as_electric_musician
+ end
+ end
+
+ describe RockGuitarist do
+ it "should behave as guitarist" do
+ RockGuitarist.new.should behave_as_electric_musician
+ end
+ end
+
+ describe ClassicGuitarist do
+ it "should not behave as guitarist" do
+ ClassicGuitarist.new.should behave_as_musician
+ end
+ end
+
+end
diff --git a/vendor/plugins/rspec/examples/pure/custom_expectation_matchers.rb b/vendor/plugins/rspec/examples/pure/custom_expectation_matchers.rb
new file mode 100644
index 00000000..075bb542
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/custom_expectation_matchers.rb
@@ -0,0 +1,54 @@
+module AnimalSpecHelper
+ class Eat
+ def initialize(food)
+ @food = food
+ end
+
+ def matches?(animal)
+ @animal = animal
+ @animal.eats?(@food)
+ end
+
+ def failure_message
+ "expected #{@animal} to eat #{@food}, but it does not"
+ end
+
+ def negative_failure_message
+ "expected #{@animal} not to eat #{@food}, but it does"
+ end
+ end
+
+ def eat(food)
+ Eat.new(food)
+ end
+end
+
+module Animals
+ class Animal
+ def eats?(food)
+ return foods_i_eat.include?(food)
+ end
+ end
+
+ class Mouse < Animal
+ def foods_i_eat
+ [:cheese]
+ end
+ end
+
+ describe Mouse do
+ include AnimalSpecHelper
+ before(:each) do
+ @mouse = Animals::Mouse.new
+ end
+
+ it "should eat cheese" do
+ @mouse.should eat(:cheese)
+ end
+
+ it "should not eat cat" do
+ @mouse.should_not eat(:cat)
+ end
+ end
+
+end
diff --git a/vendor/plugins/rspec/examples/pure/custom_formatter.rb b/vendor/plugins/rspec/examples/pure/custom_formatter.rb
new file mode 100644
index 00000000..c449fdc2
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/custom_formatter.rb
@@ -0,0 +1,12 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require 'spec/runner/formatter/progress_bar_formatter'
+
+# Example of a formatter with custom bactrace printing. Run me with:
+# ruby bin/spec failing_examples -r examples/custom_formatter.rb -f CustomFormatter
+class CustomFormatter < Spec::Runner::Formatter::ProgressBarFormatter
+ def backtrace_line(line)
+ line.gsub(/([^:]*\.rb):(\d*)/) do
+ "#{$1}:#{$2} "
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/examples/pure/dynamic_spec.rb b/vendor/plugins/rspec/examples/pure/dynamic_spec.rb
new file mode 100644
index 00000000..15d473d6
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/dynamic_spec.rb
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "Some integers" do
+ (1..10).each do |n|
+ it "The root of #{n} square should be #{n}" do
+ Math.sqrt(n*n).should == n
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/examples/pure/file_accessor.rb b/vendor/plugins/rspec/examples/pure/file_accessor.rb
new file mode 100644
index 00000000..ff6fb743
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/file_accessor.rb
@@ -0,0 +1,19 @@
+require File.dirname(__FILE__) + '/spec_helper'
+class FileAccessor
+ def open_and_handle_with(pathname, processor)
+ pathname.open do |io|
+ processor.process(io)
+ end
+ end
+end
+
+if __FILE__ == $0
+ require File.dirname(__FILE__) + '/io_processor'
+ require 'pathname'
+
+ accessor = FileAccessor.new
+ io_processor = IoProcessor.new
+ file = Pathname.new ARGV[0]
+
+ accessor.open_and_handle_with(file, io_processor)
+end
diff --git a/vendor/plugins/rspec/examples/pure/file_accessor_spec.rb b/vendor/plugins/rspec/examples/pure/file_accessor_spec.rb
new file mode 100644
index 00000000..628d4c0b
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/file_accessor_spec.rb
@@ -0,0 +1,38 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + '/file_accessor'
+require 'stringio'
+
+describe "A FileAccessor" do
+ # This sequence diagram illustrates what this spec specifies.
+ #
+ # +--------------+ +----------+ +-------------+
+ # | FileAccessor | | Pathname | | IoProcessor |
+ # +--------------+ +----------+ +-------------+
+ # | | |
+ # open_and_handle_with | | |
+ # -------------------->| | open | |
+ # | |--------------->| | |
+ # | | io | | |
+ # | |<...............| | |
+ # | | | process(io) |
+ # | |---------------------------------->| |
+ # | | | | |
+ # | |<..................................| |
+ # | | |
+ #
+ it "should open a file and pass it to the processor's process method" do
+ # This is the primary actor
+ accessor = FileAccessor.new
+
+ # These are the primary actor's neighbours, which we mock.
+ file = mock "Pathname"
+ io_processor = mock "IoProcessor"
+
+ io = StringIO.new "whatever"
+ file.should_receive(:open).and_yield io
+ io_processor.should_receive(:process).with(io)
+
+ accessor.open_and_handle_with(file, io_processor)
+ end
+
+end
diff --git a/vendor/plugins/rspec/examples/pure/greeter_spec.rb b/vendor/plugins/rspec/examples/pure/greeter_spec.rb
new file mode 100644
index 00000000..ec7669dc
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/greeter_spec.rb
@@ -0,0 +1,31 @@
+require File.dirname(__FILE__) + '/spec_helper'
+# greeter.rb
+#
+# Based on http://glu.ttono.us/articles/2006/12/19/tormenting-your-tests-with-heckle
+#
+# Run with:
+#
+# spec greeter_spec.rb --heckle Greeter
+#
+class Greeter
+ def initialize(person = nil)
+ @person = person
+ end
+
+ def greet
+ @person.nil? ? "Hi there!" : "Hi #{@person}!"
+ end
+end
+
+describe "Greeter" do
+ it "should say Hi to person" do
+ greeter = Greeter.new("Kevin")
+ greeter.greet.should == "Hi Kevin!"
+ end
+
+ it "should say Hi to nobody" do
+ greeter = Greeter.new
+ # Uncomment the next line to make Heckle happy
+ #greeter.greet.should == "Hi there!"
+ end
+end
diff --git a/vendor/plugins/rspec/examples/pure/helper_method_example.rb b/vendor/plugins/rspec/examples/pure/helper_method_example.rb
new file mode 100644
index 00000000..d97f19e6
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/helper_method_example.rb
@@ -0,0 +1,14 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+module HelperMethodExample
+ describe "an example group with helper a method" do
+ def helper_method
+ "received call"
+ end
+
+ it "should make that method available to specs" do
+ helper_method.should == "received call"
+ end
+ end
+end
+
diff --git a/vendor/plugins/rspec/examples/pure/io_processor.rb b/vendor/plugins/rspec/examples/pure/io_processor.rb
new file mode 100644
index 00000000..6b15147b
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/io_processor.rb
@@ -0,0 +1,8 @@
+class DataTooShort < StandardError; end
+
+class IoProcessor
+ # Does some fancy stuff unless the length of +io+ is shorter than 32
+ def process(io)
+ raise DataTooShort if io.read.length < 32
+ end
+end
diff --git a/vendor/plugins/rspec/examples/pure/io_processor_spec.rb b/vendor/plugins/rspec/examples/pure/io_processor_spec.rb
new file mode 100644
index 00000000..5cab7bf3
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/io_processor_spec.rb
@@ -0,0 +1,21 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + '/io_processor'
+require 'stringio'
+
+describe "An IoProcessor" do
+ before(:each) do
+ @processor = IoProcessor.new
+ end
+
+ it "should raise nothing when the file is exactly 32 bytes" do
+ lambda {
+ @processor.process(StringIO.new("z"*32))
+ }.should_not raise_error
+ end
+
+ it "should raise an exception when the file length is less than 32 bytes" do
+ lambda {
+ @processor.process(StringIO.new("z"*31))
+ }.should raise_error(DataTooShort)
+ end
+end
diff --git a/vendor/plugins/rspec/examples/pure/legacy_spec.rb b/vendor/plugins/rspec/examples/pure/legacy_spec.rb
new file mode 100644
index 00000000..c8636951
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/legacy_spec.rb
@@ -0,0 +1,11 @@
+require File.dirname(__FILE__) + '/spec_helper'
+context "A legacy spec" do
+ setup do
+ end
+
+ specify "should work fine" do
+ end
+
+ teardown do
+ end
+end
diff --git a/vendor/plugins/rspec/examples/pure/mocking_example.rb b/vendor/plugins/rspec/examples/pure/mocking_example.rb
new file mode 100644
index 00000000..6adbef59
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/mocking_example.rb
@@ -0,0 +1,27 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "A consumer of a mock" do
+ it "should be able to send messages to the mock" do
+ mock = mock("poke me")
+ mock.should_receive(:poke)
+ mock.poke
+ end
+end
+
+describe "a mock" do
+ it "should be able to mock the same message twice w/ different args" do
+ mock = mock("mock")
+ mock.should_receive(:msg).with(:arg1).and_return(:val1)
+ mock.should_receive(:msg).with(:arg2).and_return(:val2)
+ mock.msg(:arg1).should eql(:val1)
+ mock.msg(:arg2).should eql(:val2)
+ end
+
+ it "should be able to mock the same message twice w/ different args in reverse order" do
+ mock = mock("mock")
+ mock.should_receive(:msg).with(:arg1).and_return(:val1)
+ mock.should_receive(:msg).with(:arg2).and_return(:val2)
+ mock.msg(:arg2).should eql(:val2)
+ mock.msg(:arg1).should eql(:val1)
+ end
+end
diff --git a/vendor/plugins/rspec/examples/pure/multi_threaded_behaviour_runner.rb b/vendor/plugins/rspec/examples/pure/multi_threaded_behaviour_runner.rb
new file mode 100644
index 00000000..36edcd49
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/multi_threaded_behaviour_runner.rb
@@ -0,0 +1,28 @@
+class MultiThreadedExampleGroupRunner < Spec::Runner::ExampleGroupRunner
+ def initialize(options, arg)
+ super(options)
+ # configure these
+ @thread_count = 4
+ @thread_wait = 0
+ end
+
+ def run
+ @threads = []
+ q = Queue.new
+ example_groups.each { |b| q << b}
+ success = true
+ @thread_count.times do
+ @threads << Thread.new(q) do |queue|
+ while not queue.empty?
+ example_group = queue.pop
+ success &= example_group.suite.run(nil)
+ end
+ end
+ sleep @thread_wait
+ end
+ @threads.each {|t| t.join}
+ success
+ end
+end
+
+MultiThreadedBehaviourRunner = MultiThreadedExampleGroupRunner
\ No newline at end of file
diff --git a/vendor/plugins/rspec/examples/pure/nested_classes_example.rb b/vendor/plugins/rspec/examples/pure/nested_classes_example.rb
new file mode 100644
index 00000000..abe43b0a
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/nested_classes_example.rb
@@ -0,0 +1,36 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + '/stack'
+
+class StackExamples < Spec::ExampleGroup
+ describe(Stack)
+ before(:each) do
+ @stack = Stack.new
+ end
+end
+
+class EmptyStackExamples < StackExamples
+ describe("when empty")
+ it "should be empty" do
+ @stack.should be_empty
+ end
+end
+
+class AlmostFullStackExamples < StackExamples
+ describe("when almost full")
+ before(:each) do
+ (1..9).each {|n| @stack.push n}
+ end
+ it "should be full" do
+ @stack.should_not be_full
+ end
+end
+
+class FullStackExamples < StackExamples
+ describe("when full")
+ before(:each) do
+ (1..10).each {|n| @stack.push n}
+ end
+ it "should be full" do
+ @stack.should be_full
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/examples/pure/partial_mock_example.rb b/vendor/plugins/rspec/examples/pure/partial_mock_example.rb
new file mode 100644
index 00000000..2af608b2
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/partial_mock_example.rb
@@ -0,0 +1,29 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+class MockableClass
+ def self.find id
+ return :original_return
+ end
+end
+
+describe "A partial mock" do
+
+ it "should work at the class level" do
+ MockableClass.should_receive(:find).with(1).and_return {:stub_return}
+ MockableClass.find(1).should equal(:stub_return)
+ end
+
+ it "should revert to the original after each spec" do
+ MockableClass.find(1).should equal(:original_return)
+ end
+
+ it "can be mocked w/ ordering" do
+ MockableClass.should_receive(:msg_1).ordered
+ MockableClass.should_receive(:msg_2).ordered
+ MockableClass.should_receive(:msg_3).ordered
+ MockableClass.msg_1
+ MockableClass.msg_2
+ MockableClass.msg_3
+ end
+
+end
diff --git a/vendor/plugins/rspec/examples/pure/pending_example.rb b/vendor/plugins/rspec/examples/pure/pending_example.rb
new file mode 100644
index 00000000..13f3d00c
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/pending_example.rb
@@ -0,0 +1,20 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "pending example (using pending method)" do
+ it %Q|should be reported as "PENDING: for some reason"| do
+ pending("for some reason")
+ end
+end
+
+describe "pending example (with no block)" do
+ it %Q|should be reported as "PENDING: Not Yet Implemented"|
+end
+
+describe "pending example (with block for pending)" do
+ it %Q|should have a failing block, passed to pending, reported as "PENDING: for some reason"| do
+ pending("for some reason") do
+ raise "some reason"
+ end
+ end
+end
+
diff --git a/vendor/plugins/rspec/examples/pure/predicate_example.rb b/vendor/plugins/rspec/examples/pure/predicate_example.rb
new file mode 100644
index 00000000..1202bb67
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/predicate_example.rb
@@ -0,0 +1,27 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+class BddFramework
+ def intuitive?
+ true
+ end
+
+ def adopted_quickly?
+ true
+ end
+end
+
+describe "BDD framework" do
+
+ before(:each) do
+ @bdd_framework = BddFramework.new
+ end
+
+ it "should be adopted quickly" do
+ @bdd_framework.should be_adopted_quickly
+ end
+
+ it "should be intuitive" do
+ @bdd_framework.should be_intuitive
+ end
+
+end
diff --git a/vendor/plugins/rspec/examples/pure/priority.txt b/vendor/plugins/rspec/examples/pure/priority.txt
new file mode 100644
index 00000000..5b00064e
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/priority.txt
@@ -0,0 +1 @@
+examples/custom_expectation_matchers.rb
\ No newline at end of file
diff --git a/vendor/plugins/rspec/examples/pure/shared_example_group_example.rb b/vendor/plugins/rspec/examples/pure/shared_example_group_example.rb
new file mode 100644
index 00000000..fb81af1e
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/shared_example_group_example.rb
@@ -0,0 +1,81 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+module SharedExampleGroupExample
+ class OneThing
+ def what_things_do
+ "stuff"
+ end
+ end
+
+ class AnotherThing
+ def what_things_do
+ "stuff"
+ end
+ end
+
+ class YetAnotherThing
+ def what_things_do
+ "stuff"
+ end
+ end
+
+ # A SharedExampleGroup is an example group that doesn't get run.
+ # You can create one like this:
+ share_examples_for "most things" do
+ def helper_method
+ "helper method"
+ end
+
+ it "should do what things do" do
+ @thing.what_things_do.should == "stuff"
+ end
+ end
+
+ # A SharedExampleGroup is also module. If you create one like this
+ # it gets assigned to the constant AllThings
+ share_as :MostThings do
+ def helper_method
+ "helper method"
+ end
+
+ it "should do what things do" do
+ @thing.what_things_do.should == "stuff"
+ end
+ end
+
+ describe OneThing do
+ # Now you can include the shared example group like this, which
+ # feels more like what you might say ...
+ it_should_behave_like "most things"
+
+ before(:each) { @thing = OneThing.new }
+
+ it "should have access to helper methods defined in the shared example group" do
+ helper_method.should == "helper method"
+ end
+ end
+
+ describe AnotherThing do
+ # ... or you can include the example group like this, which
+ # feels more like the programming language we love.
+ it_should_behave_like MostThings
+
+ before(:each) { @thing = AnotherThing.new }
+
+ it "should have access to helper methods defined in the shared example group" do
+ helper_method.should == "helper method"
+ end
+ end
+
+ describe YetAnotherThing do
+ # ... or you can include the example group like this, which
+ # feels more like the programming language we love.
+ include MostThings
+
+ before(:each) { @thing = AnotherThing.new }
+
+ it "should have access to helper methods defined in the shared example group" do
+ helper_method.should == "helper method"
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/examples/pure/shared_stack_examples.rb b/vendor/plugins/rspec/examples/pure/shared_stack_examples.rb
new file mode 100644
index 00000000..7a081625
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/shared_stack_examples.rb
@@ -0,0 +1,38 @@
+require File.join(File.dirname(__FILE__), *%w[spec_helper])
+
+shared_examples_for "non-empty Stack" do
+
+ it { @stack.should_not be_empty }
+
+ it "should return the top item when sent #peek" do
+ @stack.peek.should == @last_item_added
+ end
+
+ it "should NOT remove the top item when sent #peek" do
+ @stack.peek.should == @last_item_added
+ @stack.peek.should == @last_item_added
+ end
+
+ it "should return the top item when sent #pop" do
+ @stack.pop.should == @last_item_added
+ end
+
+ it "should remove the top item when sent #pop" do
+ @stack.pop.should == @last_item_added
+ unless @stack.empty?
+ @stack.pop.should_not == @last_item_added
+ end
+ end
+
+end
+
+shared_examples_for "non-full Stack" do
+
+ it { @stack.should_not be_full }
+
+ it "should add to the top when sent #push" do
+ @stack.push "newly added top item"
+ @stack.peek.should == "newly added top item"
+ end
+
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/examples/pure/spec_helper.rb b/vendor/plugins/rspec/examples/pure/spec_helper.rb
new file mode 100644
index 00000000..1e880796
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/spec_helper.rb
@@ -0,0 +1,3 @@
+lib_path = File.expand_path("#{File.dirname(__FILE__)}/../../lib")
+$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
+require 'spec'
diff --git a/vendor/plugins/rspec/examples/pure/stack.rb b/vendor/plugins/rspec/examples/pure/stack.rb
new file mode 100644
index 00000000..407173f7
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/stack.rb
@@ -0,0 +1,36 @@
+class StackUnderflowError < RuntimeError
+end
+
+class StackOverflowError < RuntimeError
+end
+
+class Stack
+
+ def initialize
+ @items = []
+ end
+
+ def push object
+ raise StackOverflowError if @items.length == 10
+ @items.push object
+ end
+
+ def pop
+ raise StackUnderflowError if @items.empty?
+ @items.delete @items.last
+ end
+
+ def peek
+ raise StackUnderflowError if @items.empty?
+ @items.last
+ end
+
+ def empty?
+ @items.empty?
+ end
+
+ def full?
+ @items.length == 10
+ end
+
+end
diff --git a/vendor/plugins/rspec/examples/pure/stack_spec.rb b/vendor/plugins/rspec/examples/pure/stack_spec.rb
new file mode 100644
index 00000000..2a769da0
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/stack_spec.rb
@@ -0,0 +1,63 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + "/stack"
+require File.dirname(__FILE__) + '/shared_stack_examples'
+
+describe Stack, " (empty)" do
+ before(:each) do
+ @stack = Stack.new
+ end
+
+ # NOTE that this one auto-generates the description "should be empty"
+ it { @stack.should be_empty }
+
+ it_should_behave_like "non-full Stack"
+
+ it "should complain when sent #peek" do
+ lambda { @stack.peek }.should raise_error(StackUnderflowError)
+ end
+
+ it "should complain when sent #pop" do
+ lambda { @stack.pop }.should raise_error(StackUnderflowError)
+ end
+end
+
+describe Stack, " (with one item)" do
+ before(:each) do
+ @stack = Stack.new
+ @stack.push 3
+ @last_item_added = 3
+ end
+
+ it_should_behave_like "non-empty Stack"
+ it_should_behave_like "non-full Stack"
+
+end
+
+describe Stack, " (with one item less than capacity)" do
+ before(:each) do
+ @stack = Stack.new
+ (1..9).each { |i| @stack.push i }
+ @last_item_added = 9
+ end
+
+ it_should_behave_like "non-empty Stack"
+ it_should_behave_like "non-full Stack"
+end
+
+describe Stack, " (full)" do
+ before(:each) do
+ @stack = Stack.new
+ (1..10).each { |i| @stack.push i }
+ @last_item_added = 10
+ end
+
+ # NOTE that this one auto-generates the description "should be full"
+ it { @stack.should be_full }
+
+ it_should_behave_like "non-empty Stack"
+
+ it "should complain on #push" do
+ lambda { @stack.push Object.new }.should raise_error(StackOverflowError)
+ end
+
+end
diff --git a/vendor/plugins/rspec/examples/pure/stack_spec_with_nested_example_groups.rb b/vendor/plugins/rspec/examples/pure/stack_spec_with_nested_example_groups.rb
new file mode 100644
index 00000000..05f6ad46
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/stack_spec_with_nested_example_groups.rb
@@ -0,0 +1,67 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + '/stack'
+require File.dirname(__FILE__) + '/shared_stack_examples'
+
+describe Stack do
+
+ before(:each) do
+ @stack = Stack.new
+ end
+
+ describe "(empty)" do
+
+ it { @stack.should be_empty }
+
+ it_should_behave_like "non-full Stack"
+
+ it "should complain when sent #peek" do
+ lambda { @stack.peek }.should raise_error(StackUnderflowError)
+ end
+
+ it "should complain when sent #pop" do
+ lambda { @stack.pop }.should raise_error(StackUnderflowError)
+ end
+
+ end
+
+ describe "(with one item)" do
+
+ before(:each) do
+ @stack.push 3
+ @last_item_added = 3
+ end
+
+ it_should_behave_like "non-empty Stack"
+ it_should_behave_like "non-full Stack"
+
+ end
+
+ describe "(with one item less than capacity)" do
+
+ before(:each) do
+ (1..9).each { |i| @stack.push i }
+ @last_item_added = 9
+ end
+
+ it_should_behave_like "non-empty Stack"
+ it_should_behave_like "non-full Stack"
+ end
+
+ describe "(full)" do
+
+ before(:each) do
+ (1..10).each { |i| @stack.push i }
+ @last_item_added = 10
+ end
+
+ it { @stack.should be_full }
+
+ it_should_behave_like "non-empty Stack"
+
+ it "should complain on #push" do
+ lambda { @stack.push Object.new }.should raise_error(StackOverflowError)
+ end
+
+ end
+
+end
diff --git a/vendor/plugins/rspec/examples/pure/stubbing_example.rb b/vendor/plugins/rspec/examples/pure/stubbing_example.rb
new file mode 100644
index 00000000..31354aec
--- /dev/null
+++ b/vendor/plugins/rspec/examples/pure/stubbing_example.rb
@@ -0,0 +1,69 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "A consumer of a stub" do
+ it "should be able to stub methods on any Object" do
+ obj = Object.new
+ obj.stub!(:foobar).and_return {:return_value}
+ obj.foobar.should equal(:return_value)
+ end
+end
+
+class StubbableClass
+ def self.find id
+ return :original_return
+ end
+end
+
+describe "A stubbed method on a class" do
+ it "should return the stubbed value" do
+ StubbableClass.stub!(:find).and_return(:stub_return)
+ StubbableClass.find(1).should equal(:stub_return)
+ end
+
+ it "should revert to the original method after each spec" do
+ StubbableClass.find(1).should equal(:original_return)
+ end
+
+ it "can stub! and mock the same message" do
+ StubbableClass.stub!(:msg).and_return(:stub_value)
+ StubbableClass.should_receive(:msg).with(:arg).and_return(:mock_value)
+
+ StubbableClass.msg.should equal(:stub_value)
+ StubbableClass.msg(:other_arg).should equal(:stub_value)
+ StubbableClass.msg(:arg).should equal(:mock_value)
+ StubbableClass.msg(:another_arg).should equal(:stub_value)
+ StubbableClass.msg(:yet_another_arg).should equal(:stub_value)
+ StubbableClass.msg.should equal(:stub_value)
+ end
+end
+
+describe "A mock" do
+ it "can stub!" do
+ mock = mock("stubbing mock")
+ mock.stub!(:msg).and_return(:value)
+ (1..10).each {mock.msg.should equal(:value)}
+ end
+
+ it "can stub! and mock" do
+ mock = mock("stubbing mock")
+ mock.stub!(:stub_message).and_return(:stub_value)
+ mock.should_receive(:mock_message).once.and_return(:mock_value)
+ (1..10).each {mock.stub_message.should equal(:stub_value)}
+ mock.mock_message.should equal(:mock_value)
+ (1..10).each {mock.stub_message.should equal(:stub_value)}
+ end
+
+ it "can stub! and mock the same message" do
+ mock = mock("stubbing mock")
+ mock.stub!(:msg).and_return(:stub_value)
+ mock.should_receive(:msg).with(:arg).and_return(:mock_value)
+ mock.msg.should equal(:stub_value)
+ mock.msg(:other_arg).should equal(:stub_value)
+ mock.msg(:arg).should equal(:mock_value)
+ mock.msg(:another_arg).should equal(:stub_value)
+ mock.msg(:yet_another_arg).should equal(:stub_value)
+ mock.msg.should equal(:stub_value)
+ end
+end
+
+
diff --git a/vendor/plugins/rspec/examples/stories/adder.rb b/vendor/plugins/rspec/examples/stories/adder.rb
new file mode 100644
index 00000000..0b027b0f
--- /dev/null
+++ b/vendor/plugins/rspec/examples/stories/adder.rb
@@ -0,0 +1,13 @@
+class Adder
+ def initialize
+ @addends = []
+ end
+
+ def <<(val)
+ @addends << val
+ end
+
+ def sum
+ @addends.inject(0) { |sum_so_far, val| sum_so_far + val }
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/examples/stories/addition b/vendor/plugins/rspec/examples/stories/addition
new file mode 100644
index 00000000..58f09299
--- /dev/null
+++ b/vendor/plugins/rspec/examples/stories/addition
@@ -0,0 +1,34 @@
+This is a story about a calculator. The text up here above the Story: declaration
+won't be processed, so you can write whatever you wish!
+
+Story: simple addition
+
+ As an accountant
+ I want to add numbers
+ So that I can count beans
+
+ Scenario: add one plus one
+ Given an addend of 1
+ And an addend of 1
+
+ When the addends are addeds
+
+ Then the sum should be 3
+ And the corks should be popped
+
+ Scenario: add two plus five
+ Given an addend of 2
+ And an addend of 5
+
+ When the addends are added
+
+ Then the sum should be 7
+ Then it should snow
+
+ Scenario: add three more
+ GivenScenario add two plus five
+ And an addend of 3
+
+ When the addends are added
+
+ Then the sum should be 10
diff --git a/vendor/plugins/rspec/examples/stories/addition.rb b/vendor/plugins/rspec/examples/stories/addition.rb
new file mode 100644
index 00000000..e43f5cf3
--- /dev/null
+++ b/vendor/plugins/rspec/examples/stories/addition.rb
@@ -0,0 +1,9 @@
+require File.join(File.dirname(__FILE__), "helper")
+require File.join(File.dirname(__FILE__), "adder")
+
+# with_steps_for :addition, :more_addition do
+with_steps_for :addition, :more_addition do
+ # Then("the corks should be popped") { }
+ run File.expand_path(__FILE__).gsub(".rb","")
+end
+
diff --git a/vendor/plugins/rspec/examples/stories/calculator.rb b/vendor/plugins/rspec/examples/stories/calculator.rb
new file mode 100644
index 00000000..d86fc7e5
--- /dev/null
+++ b/vendor/plugins/rspec/examples/stories/calculator.rb
@@ -0,0 +1,65 @@
+$:.push File.join(File.dirname(__FILE__), *%w[.. .. lib])
+require 'spec'
+
+class AdditionMatchers < Spec::Story::StepGroup
+ steps do |add|
+ add.given("an addend of $addend") do |addend|
+ @adder ||= Adder.new
+ @adder << addend.to_i
+ end
+ end
+end
+
+steps = AdditionMatchers.new do |add|
+ add.then("the sum should be $sum") do |sum|
+ @sum.should == sum.to_i
+ end
+end
+
+steps.when("they are added") do
+ @sum = @adder.sum
+end
+
+# This Story uses steps (see above) instead of blocks
+# passed to Given, When and Then
+
+Story "addition", %{
+ As an accountant
+ I want to add numbers
+ So that I can count some beans
+}, :steps_for => steps do
+ Scenario "2 + 3" do
+ Given "an addend of 2"
+ And "an addend of 3"
+ When "they are added"
+ Then "the sum should be 5"
+ end
+
+ # This scenario uses GivenScenario, which silently runs
+ # all the steps in a previous scenario.
+
+ Scenario "add 4 more" do
+ GivenScenario "2 + 3"
+ Given "an addend of 4"
+ When "they are added"
+ Then "the sum should be 9"
+ end
+end
+
+# And the class that makes the story pass
+
+class Adder
+ def << addend
+ addends << addend
+ end
+
+ def sum
+ @addends.inject(0) do |result, addend|
+ result + addend.to_i
+ end
+ end
+
+ def addends
+ @addends ||= []
+ end
+end
diff --git a/vendor/plugins/rspec/examples/stories/game-of-life/.loadpath b/vendor/plugins/rspec/examples/stories/game-of-life/.loadpath
new file mode 100644
index 00000000..9a622201
--- /dev/null
+++ b/vendor/plugins/rspec/examples/stories/game-of-life/.loadpath
@@ -0,0 +1,5 @@
+
+expected and target, passes them
+ # to the differ to append a diff message to the failure message.
+ def fail_with(message, expected=nil, target=nil) # :nodoc:
+ if Array === message && message.length == 3
+ message, expected, target = message[0], message[1], message[2]
+ end
+ unless (differ.nil? || expected.nil? || target.nil?)
+ if expected.is_a?(String)
+ message << "\nDiff:" << self.differ.diff_as_string(target.to_s, expected)
+ elsif !target.is_a?(Proc)
+ message << "\nDiff:" << self.differ.diff_as_object(target, expected)
+ end
+ end
+ Kernel::raise(Spec::Expectations::ExpectationNotMetError.new(message))
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/expectations/differs/default.rb b/vendor/plugins/rspec/lib/spec/expectations/differs/default.rb
new file mode 100644
index 00000000..74b59bbe
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/expectations/differs/default.rb
@@ -0,0 +1,66 @@
+begin
+ require 'rubygems'
+ require 'diff/lcs' #necessary due to loading bug on some machines - not sure why - DaC
+ require 'diff/lcs/hunk'
+rescue LoadError ; raise "You must gem install diff-lcs to use diffing" ; end
+
+require 'pp'
+
+module Spec
+ module Expectations
+ module Differs
+
+ # TODO add some rdoc
+ class Default
+ def initialize(options)
+ @options = options
+ end
+
+ # This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
+ def diff_as_string(data_new, data_old)
+ data_old = data_old.split(/\n/).map! { |e| e.chomp }
+ data_new = data_new.split(/\n/).map! { |e| e.chomp }
+ output = ""
+ diffs = Diff::LCS.diff(data_old, data_new)
+ return output if diffs.empty?
+ oldhunk = hunk = nil
+ file_length_difference = 0
+ diffs.each do |piece|
+ begin
+ hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, context_lines,
+ file_length_difference)
+ file_length_difference = hunk.file_length_difference
+ next unless oldhunk
+ # Hunks may overlap, which is why we need to be careful when our
+ # diff includes lines of context. Otherwise, we might print
+ # redundant lines.
+ if (context_lines > 0) and hunk.overlaps?(oldhunk)
+ hunk.unshift(oldhunk)
+ else
+ output << oldhunk.diff(format)
+ end
+ ensure
+ oldhunk = hunk
+ output << "\n"
+ end
+ end
+ #Handle the last remaining hunk
+ output << oldhunk.diff(format) << "\n"
+ end
+
+ def diff_as_object(target,expected)
+ diff_as_string(PP.pp(target,""), PP.pp(expected,""))
+ end
+
+ protected
+ def format
+ @options.diff_format
+ end
+
+ def context_lines
+ @options.context_lines
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/expectations/errors.rb b/vendor/plugins/rspec/lib/spec/expectations/errors.rb
new file mode 100644
index 00000000..1fabd105
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/expectations/errors.rb
@@ -0,0 +1,12 @@
+module Spec
+ module Expectations
+ # If Test::Unit is loaed, we'll use its error as baseclass, so that Test::Unit
+ # will report unmet RSpec expectations as failures rather than errors.
+ superclass = ['Test::Unit::AssertionFailedError', '::StandardError'].map do |c|
+ eval(c) rescue nil
+ end.compact.first
+
+ class ExpectationNotMetError < superclass
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/expectations/extensions.rb b/vendor/plugins/rspec/lib/spec/expectations/extensions.rb
new file mode 100644
index 00000000..60c9b9e7
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/expectations/extensions.rb
@@ -0,0 +1,2 @@
+require 'spec/expectations/extensions/object'
+require 'spec/expectations/extensions/string_and_symbol'
diff --git a/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb b/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb
new file mode 100644
index 00000000..2091c294
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb
@@ -0,0 +1,63 @@
+module Spec
+ module Expectations
+ # rspec adds #should and #should_not to every Object (and,
+ # implicitly, every Class).
+ module ObjectExpectations
+ # :call-seq:
+ # should(matcher)
+ # should == expected
+ # should === expected
+ # should =~ expected
+ #
+ # receiver.should(matcher)
+ # => Passes if matcher.matches?(receiver)
+ #
+ # receiver.should == expected #any value
+ # => Passes if (receiver == expected)
+ #
+ # receiver.should === expected #any value
+ # => Passes if (receiver === expected)
+ #
+ # receiver.should =~ regexp
+ # => Passes if (receiver =~ regexp)
+ #
+ # See Spec::Matchers for more information about matchers
+ #
+ # == Warning
+ #
+ # NOTE that this does NOT support receiver.should != expected.
+ # Instead, use receiver.should_not == expected
+ def should(matcher=:use_operator_matcher, &block)
+ ExpectationMatcherHandler.handle_matcher(self, matcher, &block)
+ end
+
+ # :call-seq:
+ # should_not(matcher)
+ # should_not == expected
+ # should_not === expected
+ # should_not =~ expected
+ #
+ # receiver.should_not(matcher)
+ # => Passes unless matcher.matches?(receiver)
+ #
+ # receiver.should_not == expected
+ # => Passes unless (receiver == expected)
+ #
+ # receiver.should_not === expected
+ # => Passes unless (receiver === expected)
+ #
+ # receiver.should_not =~ regexp
+ # => Passes unless (receiver =~ regexp)
+ #
+ # See Spec::Matchers for more information about matchers
+ def should_not(matcher=:use_operator_matcher, &block)
+ NegativeExpectationMatcherHandler.handle_matcher(self, matcher, &block)
+ end
+
+ end
+ end
+end
+
+class Object
+ include Spec::Expectations::ObjectExpectations
+end
diff --git a/vendor/plugins/rspec/lib/spec/expectations/extensions/string_and_symbol.rb b/vendor/plugins/rspec/lib/spec/expectations/extensions/string_and_symbol.rb
new file mode 100644
index 00000000..29cfbddf
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/expectations/extensions/string_and_symbol.rb
@@ -0,0 +1,17 @@
+module Spec
+ module Expectations
+ module StringHelpers
+ def starts_with?(prefix)
+ to_s[0..(prefix.to_s.length - 1)] == prefix.to_s
+ end
+ end
+ end
+end
+
+class String
+ include Spec::Expectations::StringHelpers
+end
+
+class Symbol
+ include Spec::Expectations::StringHelpers
+end
diff --git a/vendor/plugins/rspec/lib/spec/expectations/handler.rb b/vendor/plugins/rspec/lib/spec/expectations/handler.rb
new file mode 100644
index 00000000..2e5f2a62
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/expectations/handler.rb
@@ -0,0 +1,60 @@
+module Spec
+ module Expectations
+ class InvalidMatcherError < ArgumentError; end
+
+ module MatcherHandlerHelper
+ def describe_matcher(matcher)
+ matcher.respond_to?(:description) ? matcher.description : "[#{matcher.class.name} does not provide a description]"
+ end
+ end
+
+ class ExpectationMatcherHandler
+ class << self
+ include MatcherHandlerHelper
+ def handle_matcher(actual, matcher, &block)
+ if :use_operator_matcher == matcher
+ return Spec::Matchers::PositiveOperatorMatcher.new(actual)
+ end
+
+ unless matcher.respond_to?(:matches?)
+ raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
+ end
+
+ match = matcher.matches?(actual, &block)
+ ::Spec::Matchers.generated_description = "should #{describe_matcher(matcher)}"
+ Spec::Expectations.fail_with(matcher.failure_message) unless match
+ end
+ end
+ end
+
+ class NegativeExpectationMatcherHandler
+ class << self
+ include MatcherHandlerHelper
+ def handle_matcher(actual, matcher, &block)
+ if :use_operator_matcher == matcher
+ return Spec::Matchers::NegativeOperatorMatcher.new(actual)
+ end
+
+ unless matcher.respond_to?(:matches?)
+ raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
+ end
+
+ unless matcher.respond_to?(:negative_failure_message)
+ Spec::Expectations.fail_with(
+<<-EOF
+Matcher does not support should_not.
+See Spec::Matchers for more information
+about matchers.
+EOF
+)
+ end
+ match = matcher.matches?(actual, &block)
+ ::Spec::Matchers.generated_description = "should not #{describe_matcher(matcher)}"
+ Spec::Expectations.fail_with(matcher.negative_failure_message) if match
+ end
+ end
+ end
+
+ end
+end
+
diff --git a/vendor/plugins/rspec/lib/spec/extensions.rb b/vendor/plugins/rspec/lib/spec/extensions.rb
new file mode 100755
index 00000000..715bb49f
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/extensions.rb
@@ -0,0 +1,4 @@
+require 'spec/extensions/object'
+require 'spec/extensions/class'
+require 'spec/extensions/main'
+require 'spec/extensions/metaclass'
diff --git a/vendor/plugins/rspec/lib/spec/extensions/class.rb b/vendor/plugins/rspec/lib/spec/extensions/class.rb
new file mode 100644
index 00000000..30730f87
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/extensions/class.rb
@@ -0,0 +1,24 @@
+class Class
+ # Creates a new subclass of self, with a name "under" our own name.
+ # Example:
+ #
+ # x = Foo::Bar.subclass('Zap'){}
+ # x.name # => Foo::Bar::Zap_1
+ # x.superclass.name # => Foo::Bar
+ def subclass(base_name, &body)
+ klass = Class.new(self)
+ class_name = "#{base_name}_#{class_count!}"
+ instance_eval do
+ const_set(class_name, klass)
+ end
+ klass.instance_eval(&body)
+ klass
+ end
+
+ private
+ def class_count!
+ @class_count ||= 0
+ @class_count += 1
+ @class_count
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/extensions/main.rb b/vendor/plugins/rspec/lib/spec/extensions/main.rb
new file mode 100644
index 00000000..281cbf87
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/extensions/main.rb
@@ -0,0 +1,102 @@
+module Spec
+ module Extensions
+ module Main
+ # Creates and returns a class that includes the ExampleGroupMethods
+ # module. Which ExampleGroup type is created depends on the directory of the file
+ # calling this method. For example, Spec::Rails will use different
+ # classes for specs living in spec/models,
+ # spec/helpers, spec/views and
+ # spec/controllers.
+ #
+ # It is also possible to override autodiscovery of the example group
+ # type with an options Hash as the last argument:
+ #
+ # describe "name", :type => :something_special do ...
+ #
+ # The reason for using different behaviour classes is to have different
+ # matcher methods available from within the describe block.
+ #
+ # See Spec::Example::ExampleFactory#register for details about how to
+ # register special implementations.
+ #
+ def describe(*args, &block)
+ raise ArgumentError if args.empty?
+ raise ArgumentError unless block
+ args << {} unless Hash === args.last
+ args.last[:spec_path] = caller(0)[1]
+ Spec::Example::ExampleGroupFactory.create_example_group(*args, &block)
+ end
+ alias :context :describe
+
+ # Creates an example group that can be shared by other example groups
+ #
+ # == Examples
+ #
+ # share_examples_for "All Editions" do
+ # it "all editions behaviour" ...
+ # end
+ #
+ # describe SmallEdition do
+ # it_should_behave_like "All Editions"
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ def share_examples_for(name, &block)
+ describe(name, :shared => true, &block)
+ end
+
+ alias :shared_examples_for :share_examples_for
+
+ # Creates a Shared Example Group and assigns it to a constant
+ #
+ # share_as :AllEditions do
+ # it "should do all editions stuff" ...
+ # end
+ #
+ # describe SmallEdition do
+ # it_should_behave_like AllEditions
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ #
+ # And, for those of you who prefer to use something more like Ruby, you
+ # can just include the module directly
+ #
+ # describe SmallEdition do
+ # include AllEditions
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ def share_as(name, &block)
+ begin
+ Object.const_set(name, share_examples_for(name, &block))
+ rescue NameError => e
+ raise NameError.new(e.message + "\nThe first argument to share_as must be a legal name for a constant\n")
+ end
+ end
+
+ private
+
+ def rspec_options
+ $rspec_options ||= begin; \
+ parser = ::Spec::Runner::OptionParser.new(STDERR, STDOUT); \
+ parser.order!(ARGV); \
+ $rspec_options = parser.options; \
+ end
+ $rspec_options
+ end
+
+ def init_rspec_options(options)
+ $rspec_options = options if $rspec_options.nil?
+ end
+ end
+ end
+end
+
+include Spec::Extensions::Main
\ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/extensions/metaclass.rb b/vendor/plugins/rspec/lib/spec/extensions/metaclass.rb
new file mode 100644
index 00000000..acf9febe
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/extensions/metaclass.rb
@@ -0,0 +1,7 @@
+module Spec
+ module MetaClass
+ def metaclass
+ class << self; self; end
+ end
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/extensions/object.rb b/vendor/plugins/rspec/lib/spec/extensions/object.rb
new file mode 100755
index 00000000..0b8c26fa
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/extensions/object.rb
@@ -0,0 +1,6 @@
+class Object
+ def args_and_options(*args)
+ options = Hash === args.last ? args.pop : {}
+ return args, options
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/interop/test.rb b/vendor/plugins/rspec/lib/spec/interop/test.rb
new file mode 100644
index 00000000..afa16137
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/interop/test.rb
@@ -0,0 +1,12 @@
+require 'test/unit'
+require 'test/unit/testresult'
+
+require 'spec/interop/test/unit/testcase'
+require 'spec/interop/test/unit/testsuite_adapter'
+require 'spec/interop/test/unit/autorunner'
+require 'spec/interop/test/unit/testresult'
+require 'spec/interop/test/unit/ui/console/testrunner'
+
+Spec::Example::ExampleGroupFactory.default(Test::Unit::TestCase)
+
+Test::Unit.run = true
diff --git a/vendor/plugins/rspec/lib/spec/interop/test/unit/autorunner.rb b/vendor/plugins/rspec/lib/spec/interop/test/unit/autorunner.rb
new file mode 100644
index 00000000..3944e699
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/interop/test/unit/autorunner.rb
@@ -0,0 +1,6 @@
+class Test::Unit::AutoRunner
+ remove_method :process_args
+ def process_args(argv)
+ true
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/interop/test/unit/testcase.rb b/vendor/plugins/rspec/lib/spec/interop/test/unit/testcase.rb
new file mode 100644
index 00000000..b32a820c
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/interop/test/unit/testcase.rb
@@ -0,0 +1,61 @@
+require 'test/unit/testcase'
+
+module Test
+ module Unit
+ # This extension of the standard Test::Unit::TestCase makes RSpec
+ # available from within, so that you can do things like:
+ #
+ # require 'test/unit'
+ # require 'spec'
+ #
+ # class MyTest < Test::Unit::TestCase
+ # it "should work with Test::Unit assertions" do
+ # assert_equal 4, 2+1
+ # end
+ #
+ # def test_should_work_with_rspec_expectations
+ # (3+1).should == 5
+ # end
+ # end
+ #
+ # See also Spec::Example::ExampleGroup
+ class TestCase
+ extend Spec::Example::ExampleGroupMethods
+ include Spec::Example::ExampleMethods
+
+ before(:each) {setup}
+ after(:each) {teardown}
+
+ class << self
+ def suite
+ Test::Unit::TestSuiteAdapter.new(self)
+ end
+
+ def example_method?(method_name)
+ should_method?(method_name) || test_method?(method_name)
+ end
+
+ def test_method?(method_name)
+ method_name =~ /^test[_A-Z]./ && (
+ instance_method(method_name).arity == 0 ||
+ instance_method(method_name).arity == -1
+ )
+ end
+ end
+
+ def initialize(defined_description, &implementation)
+ @_defined_description = defined_description
+ @_implementation = implementation
+
+ @_result = ::Test::Unit::TestResult.new
+ # @method_name is important to set here because it "complies" with Test::Unit's interface.
+ # Some Test::Unit extensions depend on @method_name being present.
+ @method_name = @_defined_description
+ end
+
+ def run(ignore_this_argument=nil)
+ super()
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/interop/test/unit/testresult.rb b/vendor/plugins/rspec/lib/spec/interop/test/unit/testresult.rb
new file mode 100644
index 00000000..1386dc72
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/interop/test/unit/testresult.rb
@@ -0,0 +1,6 @@
+class Test::Unit::TestResult
+ alias_method :tu_passed?, :passed?
+ def passed?
+ return tu_passed? & ::Spec.run
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/interop/test/unit/testsuite_adapter.rb b/vendor/plugins/rspec/lib/spec/interop/test/unit/testsuite_adapter.rb
new file mode 100644
index 00000000..7c0ed092
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/interop/test/unit/testsuite_adapter.rb
@@ -0,0 +1,34 @@
+module Test
+ module Unit
+ class TestSuiteAdapter < TestSuite
+ attr_reader :example_group, :examples
+ alias_method :tests, :examples
+ def initialize(example_group)
+ @example_group = example_group
+ @examples = example_group.examples
+ end
+
+ def name
+ example_group.description
+ end
+
+ def run(*args)
+ return true unless args.empty?
+ example_group.run
+ end
+
+ def size
+ example_group.number_of_examples
+ end
+
+ def delete(example)
+ examples.delete example
+ end
+
+ def empty?
+ examples.empty?
+ end
+ end
+ end
+end
+
diff --git a/vendor/plugins/rspec/lib/spec/interop/test/unit/ui/console/testrunner.rb b/vendor/plugins/rspec/lib/spec/interop/test/unit/ui/console/testrunner.rb
new file mode 100644
index 00000000..8e9995e0
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/interop/test/unit/ui/console/testrunner.rb
@@ -0,0 +1,61 @@
+require 'test/unit/ui/console/testrunner'
+
+module Test
+ module Unit
+ module UI
+ module Console
+ class TestRunner
+
+ alias_method :started_without_rspec, :started
+ def started_with_rspec(result)
+ @result = result
+ @need_to_output_started = true
+ end
+ alias_method :started, :started_with_rspec
+
+ alias_method :test_started_without_rspec, :test_started
+ def test_started_with_rspec(name)
+ if @need_to_output_started
+ if @rspec_io
+ @rspec_io.rewind
+ output(@rspec_io.read)
+ end
+ output("Started")
+ @need_to_output_started = false
+ end
+ test_started_without_rspec(name)
+ end
+ alias_method :test_started, :test_started_with_rspec
+
+ alias_method :test_finished_without_rspec, :test_finished
+ def test_finished_with_rspec(name)
+ test_finished_without_rspec(name)
+ @ran_test = true
+ end
+ alias_method :test_finished, :test_finished_with_rspec
+
+ alias_method :finished_without_rspec, :finished
+ def finished_with_rspec(elapsed_time)
+ @ran_test ||= false
+ if @ran_test
+ finished_without_rspec(elapsed_time)
+ end
+ end
+ alias_method :finished, :finished_with_rspec
+
+ alias_method :setup_mediator_without_rspec, :setup_mediator
+ def setup_mediator_with_rspec
+ orig_io = @io
+ @io = StringIO.new
+ setup_mediator_without_rspec
+ ensure
+ @rspec_io = @io
+ @io = orig_io
+ end
+ alias_method :setup_mediator, :setup_mediator_with_rspec
+
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers.rb b/vendor/plugins/rspec/lib/spec/matchers.rb
new file mode 100644
index 00000000..afae5ae5
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers.rb
@@ -0,0 +1,156 @@
+require 'spec/matchers/simple_matcher'
+require 'spec/matchers/be'
+require 'spec/matchers/be_close'
+require 'spec/matchers/change'
+require 'spec/matchers/eql'
+require 'spec/matchers/equal'
+require 'spec/matchers/exist'
+require 'spec/matchers/has'
+require 'spec/matchers/have'
+require 'spec/matchers/include'
+require 'spec/matchers/match'
+require 'spec/matchers/raise_error'
+require 'spec/matchers/respond_to'
+require 'spec/matchers/satisfy'
+require 'spec/matchers/throw_symbol'
+require 'spec/matchers/operator_matcher'
+
+module Spec
+
+ # RSpec ships with a number of useful Expression Matchers. An Expression Matcher
+ # is any object that responds to the following methods:
+ #
+ # matches?(actual)
+ # failure_message
+ # negative_failure_message #optional
+ # description #optional
+ #
+ # See Spec::Expectations to learn how to use these as Expectation Matchers.
+ # See Spec::Mocks to learn how to use them as Mock Argument Constraints.
+ #
+ # == Predicates
+ #
+ # In addition to those Expression Matchers that are defined explicitly, RSpec will
+ # create custom Matchers on the fly for any arbitrary predicate, giving your specs
+ # a much more natural language feel.
+ #
+ # A Ruby predicate is a method that ends with a "?" and returns true or false.
+ # Common examples are +empty?+, +nil?+, and +instance_of?+.
+ #
+ # All you need to do is write +should be_+ followed by the predicate without
+ # the question mark, and RSpec will figure it out from there. For example:
+ #
+ # [].should be_empty => [].empty? #passes
+ # [].should_not be_empty => [].empty? #fails
+ #
+ # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
+ # and "be_an_", making your specs read much more naturally:
+ #
+ # "a string".should be_an_instance_of(String) =>"a string".instance_of?(String) #passes
+ #
+ # 3.should be_a_kind_of(Fixnum) => 3.kind_of?(Numeric) #passes
+ # 3.should be_a_kind_of(Numeric) => 3.kind_of?(Numeric) #passes
+ # 3.should be_an_instance_of(Fixnum) => 3.instance_of?(Fixnum) #passes
+ # 3.should_not be_instance_of(Numeric) => 3.instance_of?(Numeric) #fails
+ #
+ # RSpec will also create custom matchers for predicates like +has_key?+. To
+ # use this feature, just state that the object should have_key(:key) and RSpec will
+ # call has_key?(:key) on the target. For example:
+ #
+ # {:a => "A"}.should have_key(:a) => {:a => "A"}.has_key?(:a) #passes
+ # {:a => "A"}.should have_key(:b) => {:a => "A"}.has_key?(:b) #fails
+ #
+ # You can use this feature to invoke any predicate that begins with "has_", whether it is
+ # part of the Ruby libraries (like +Hash#has_key?+) or a method you wrote on your own class.
+ #
+ # == Custom Expectation Matchers
+ #
+ # When you find that none of the stock Expectation Matchers provide a natural
+ # feeling expectation, you can very easily write your own.
+ #
+ # For example, imagine that you are writing a game in which players can
+ # be in various zones on a virtual board. To specify that bob should
+ # be in zone 4, you could say:
+ #
+ # bob.current_zone.should eql(Zone.new("4"))
+ #
+ # But you might find it more expressive to say:
+ #
+ # bob.should be_in_zone("4")
+ #
+ # and/or
+ #
+ # bob.should_not be_in_zone("3")
+ #
+ # To do this, you would need to write a class like this:
+ #
+ # class BeInZone
+ # def initialize(expected)
+ # @expected = expected
+ # end
+ # def matches?(target)
+ # @target = target
+ # @target.current_zone.eql?(Zone.new(@expected))
+ # end
+ # def failure_message
+ # "expected #{@target.inspect} to be in Zone #{@expected}"
+ # end
+ # def negative_failure_message
+ # "expected #{@target.inspect} not to be in Zone #{@expected}"
+ # end
+ # end
+ #
+ # ... and a method like this:
+ #
+ # def be_in_zone(expected)
+ # BeInZone.new(expected)
+ # end
+ #
+ # And then expose the method to your specs. This is normally done
+ # by including the method and the class in a module, which is then
+ # included in your spec:
+ #
+ # module CustomGameMatchers
+ # class BeInZone
+ # ...
+ # end
+ #
+ # def be_in_zone(expected)
+ # ...
+ # end
+ # end
+ #
+ # describe "Player behaviour" do
+ # include CustomGameMatchers
+ # ...
+ # end
+ #
+ # or you can include in globally in a spec_helper.rb file required
+ # from your spec file(s):
+ #
+ # Spec::Runner.configure do |config|
+ # config.include(CustomGameMatchers)
+ # end
+ #
+ module Matchers
+ module ModuleMethods
+ attr_accessor :generated_description
+
+ def clear_generated_description
+ self.generated_description = nil
+ end
+ end
+
+ extend ModuleMethods
+
+ def method_missing(sym, *args, &block) # :nodoc:
+ return Matchers::Be.new(sym, *args) if sym.starts_with?("be_")
+ return Matchers::Has.new(sym, *args) if sym.starts_with?("have_")
+ super
+ end
+
+ class MatcherError < StandardError
+ end
+
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/be.rb b/vendor/plugins/rspec/lib/spec/matchers/be.rb
new file mode 100644
index 00000000..2b25b11f
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/be.rb
@@ -0,0 +1,224 @@
+module Spec
+ module Matchers
+
+ class Be #:nodoc:
+ def initialize(*args)
+ if args.empty?
+ @expected = :satisfy_if
+ else
+ @expected = parse_expected(args.shift)
+ end
+ @args = args
+ @comparison = ""
+ end
+
+ def matches?(actual)
+ @actual = actual
+ if handling_predicate?
+ begin
+ return @result = actual.__send__(predicate, *@args)
+ rescue => predicate_error
+ # This clause should be empty, but rcov will not report it as covered
+ # unless something (anything) is executed within the clause
+ rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
+ end
+
+ # This supports should_exist > target.exists? in the old world.
+ # We should consider deprecating that ability as in the new world
+ # you can't write "should exist" unless you have your own custom matcher.
+ begin
+ return @result = actual.__send__(present_tense_predicate, *@args)
+ rescue
+ raise predicate_error
+ end
+ else
+ return match_or_compare
+ end
+ end
+
+ def failure_message
+ return "expected #{@comparison}#{expected}, got #{@actual.inspect}" unless handling_predicate?
+ return "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}"
+ end
+
+ def negative_failure_message
+ return "expected not #{expected}, got #{@actual.inspect}" unless handling_predicate?
+ return "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
+ end
+
+ def expected
+ return "if to be satisfied" if @expected == :satisfy_if
+ return true if @expected == :true
+ return false if @expected == :false
+ return "nil" if @expected == :nil
+ return @expected.inspect
+ end
+
+ def match_or_compare
+ return @actual ? true : false if @expected == :satisfy_if
+ return @actual == true if @expected == :true
+ return @actual == false if @expected == :false
+ return @actual.nil? if @expected == :nil
+ return @actual < @expected if @less_than
+ return @actual <= @expected if @less_than_or_equal
+ return @actual >= @expected if @greater_than_or_equal
+ return @actual > @expected if @greater_than
+ return @actual == @expected if @double_equal
+ return @actual === @expected if @triple_equal
+ return @actual.equal?(@expected)
+ end
+
+ def ==(expected)
+ @prefix = "be "
+ @double_equal = true
+ @comparison = "== "
+ @expected = expected
+ self
+ end
+
+ def ===(expected)
+ @prefix = "be "
+ @triple_equal = true
+ @comparison = "=== "
+ @expected = expected
+ self
+ end
+
+ def <(expected)
+ @prefix = "be "
+ @less_than = true
+ @comparison = "< "
+ @expected = expected
+ self
+ end
+
+ def <=(expected)
+ @prefix = "be "
+ @less_than_or_equal = true
+ @comparison = "<= "
+ @expected = expected
+ self
+ end
+
+ def >=(expected)
+ @prefix = "be "
+ @greater_than_or_equal = true
+ @comparison = ">= "
+ @expected = expected
+ self
+ end
+
+ def >(expected)
+ @prefix = "be "
+ @greater_than = true
+ @comparison = "> "
+ @expected = expected
+ self
+ end
+
+ def description
+ "#{prefix_to_sentence}#{comparison}#{expected_to_sentence}#{args_to_sentence}"
+ end
+
+ private
+ def parse_expected(expected)
+ if Symbol === expected
+ @handling_predicate = true
+ ["be_an_","be_a_","be_"].each do |prefix|
+ if expected.starts_with?(prefix)
+ @prefix = prefix
+ return "#{expected.to_s.sub(@prefix,"")}".to_sym
+ end
+ end
+ end
+ @prefix = ""
+ return expected
+ end
+
+ def handling_predicate?
+ return false if [:true, :false, :nil].include?(@expected)
+ return @handling_predicate
+ end
+
+ def predicate
+ "#{@expected.to_s}?".to_sym
+ end
+
+ def present_tense_predicate
+ "#{@expected.to_s}s?".to_sym
+ end
+
+ def args_to_s
+ return "" if @args.empty?
+ inspected_args = @args.collect{|a| a.inspect}
+ return "(#{inspected_args.join(', ')})"
+ end
+
+ def comparison
+ @comparison
+ end
+
+ def expected_to_sentence
+ split_words(@expected)
+ end
+
+ def prefix_to_sentence
+ split_words(@prefix)
+ end
+
+ def split_words(sym)
+ sym.to_s.gsub(/_/,' ')
+ end
+
+ def args_to_sentence
+ case @args.length
+ when 0
+ ""
+ when 1
+ " #{@args[0]}"
+ else
+ " #{@args[0...-1].join(', ')} and #{@args[-1]}"
+ end
+ end
+
+ end
+
+ # :call-seq:
+ # should be
+ # should be_true
+ # should be_false
+ # should be_nil
+ # should be_arbitrary_predicate(*args)
+ # should_not be_nil
+ # should_not be_arbitrary_predicate(*args)
+ #
+ # Given true, false, or nil, will pass if actual is
+ # true, false or nil (respectively). Given no args means
+ # the caller should satisfy an if condition (to be or not to be).
+ #
+ # Predicates are any Ruby method that ends in a "?" and returns true or false.
+ # Given be_ followed by arbitrary_predicate (without the "?"), RSpec will match
+ # convert that into a query against the target object.
+ #
+ # The arbitrary_predicate feature will handle any predicate
+ # prefixed with "be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of)
+ # or "be_" (e.g. be_empty), letting you choose the prefix that best suits the predicate.
+ #
+ # == Examples
+ #
+ # target.should be
+ # target.should be_true
+ # target.should be_false
+ # target.should be_nil
+ # target.should_not be_nil
+ #
+ # collection.should be_empty #passes if target.empty?
+ # "this string".should be_an_intance_of(String)
+ #
+ # target.should_not be_empty #passes unless target.empty?
+ # target.should_not be_old_enough(16) #passes unless target.old_enough?(16)
+ def be(*args)
+ Matchers::Be.new(*args)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/be_close.rb b/vendor/plugins/rspec/lib/spec/matchers/be_close.rb
new file mode 100644
index 00000000..7763eb97
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/be_close.rb
@@ -0,0 +1,37 @@
+module Spec
+ module Matchers
+
+ class BeClose #:nodoc:
+ def initialize(expected, delta)
+ @expected = expected
+ @delta = delta
+ end
+
+ def matches?(actual)
+ @actual = actual
+ (@actual - @expected).abs < @delta
+ end
+
+ def failure_message
+ "expected #{@expected} +/- (< #{@delta}), got #{@actual}"
+ end
+
+ def description
+ "be close to #{@expected} (within +- #{@delta})"
+ end
+ end
+
+ # :call-seq:
+ # should be_close(expected, delta)
+ # should_not be_close(expected, delta)
+ #
+ # Passes if actual == expected +/- delta
+ #
+ # == Example
+ #
+ # result.should be_close(3.0, 0.5)
+ def be_close(expected, delta)
+ Matchers::BeClose.new(expected, delta)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/change.rb b/vendor/plugins/rspec/lib/spec/matchers/change.rb
new file mode 100644
index 00000000..8f4ecc18
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/change.rb
@@ -0,0 +1,144 @@
+module Spec
+ module Matchers
+
+ #Based on patch from Wilson Bilkovich
+ class Change #:nodoc:
+ def initialize(receiver=nil, message=nil, &block)
+ @receiver = receiver
+ @message = message
+ @block = block
+ end
+
+ def matches?(target, &block)
+ if block
+ raise MatcherError.new(<<-EOF
+block passed to should or should_not change must use {} instead of do/end
+EOF
+)
+ end
+ @target = target
+ execute_change
+ return false if @from && (@from != @before)
+ return false if @to && (@to != @after)
+ return (@before + @amount == @after) if @amount
+ return ((@after - @before) >= @minimum) if @minimum
+ return ((@after - @before) <= @maximum) if @maximum
+ return @before != @after
+ end
+
+ def execute_change
+ @before = @block.nil? ? @receiver.send(@message) : @block.call
+ @target.call
+ @after = @block.nil? ? @receiver.send(@message) : @block.call
+ end
+
+ def failure_message
+ if @to
+ "#{result} should have been changed to #{@to.inspect}, but is now #{@after.inspect}"
+ elsif @from
+ "#{result} should have initially been #{@from.inspect}, but was #{@before.inspect}"
+ elsif @amount
+ "#{result} should have been changed by #{@amount.inspect}, but was changed by #{actual_delta.inspect}"
+ elsif @minimum
+ "#{result} should have been changed by at least #{@minimum.inspect}, but was changed by #{actual_delta.inspect}"
+ elsif @maximum
+ "#{result} should have been changed by at most #{@maximum.inspect}, but was changed by #{actual_delta.inspect}"
+ else
+ "#{result} should have changed, but is still #{@before.inspect}"
+ end
+ end
+
+ def result
+ @message || "result"
+ end
+
+ def actual_delta
+ @after - @before
+ end
+
+ def negative_failure_message
+ "#{result} should not have changed, but did change from #{@before.inspect} to #{@after.inspect}"
+ end
+
+ def by(amount)
+ @amount = amount
+ self
+ end
+
+ def by_at_least(minimum)
+ @minimum = minimum
+ self
+ end
+
+ def by_at_most(maximum)
+ @maximum = maximum
+ self
+ end
+
+ def to(to)
+ @to = to
+ self
+ end
+
+ def from (from)
+ @from = from
+ self
+ end
+ end
+
+ # :call-seq:
+ # should change(receiver, message, &block)
+ # should change(receiver, message, &block).by(value)
+ # should change(receiver, message, &block).from(old).to(new)
+ # should_not change(receiver, message, &block)
+ #
+ # Allows you to specify that a Proc will cause some value to change.
+ #
+ # == Examples
+ #
+ # lambda {
+ # team.add_player(player)
+ # }.should change(roster, :count)
+ #
+ # lambda {
+ # team.add_player(player)
+ # }.should change(roster, :count).by(1)
+ #
+ # lambda {
+ # team.add_player(player)
+ # }.should change(roster, :count).by_at_least(1)
+ #
+ # lambda {
+ # team.add_player(player)
+ # }.should change(roster, :count).by_at_most(1)
+ #
+ # string = "string"
+ # lambda {
+ # string.reverse!
+ # }.should change { string }.from("string").to("gnirts")
+ #
+ # lambda {
+ # person.happy_birthday
+ # }.should change(person, :birthday).from(32).to(33)
+ #
+ # lambda {
+ # employee.develop_great_new_social_networking_app
+ # }.should change(employee, :title).from("Mail Clerk").to("CEO")
+ #
+ # Evaluates +receiver.message+ or +block+ before and
+ # after it evaluates the c object (generated by the lambdas in the examples above).
+ #
+ # Then compares the values before and after the +receiver.message+ and
+ # evaluates the difference compared to the expected difference.
+ #
+ # == Warning
+ # +should_not+ +change+ only supports the form with no subsequent calls to
+ # +by+, +by_at_least+, +by_at_most+, +to+ or +from+.
+ #
+ # blocks passed to +should+ +change+ and +should_not+ +change+
+ # must use the {} form (do/end is not supported)
+ def change(target=nil, message=nil, &block)
+ Matchers::Change.new(target, message, &block)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/eql.rb b/vendor/plugins/rspec/lib/spec/matchers/eql.rb
new file mode 100644
index 00000000..280ca545
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/eql.rb
@@ -0,0 +1,43 @@
+module Spec
+ module Matchers
+
+ class Eql #:nodoc:
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def matches?(actual)
+ @actual = actual
+ @actual.eql?(@expected)
+ end
+
+ def failure_message
+ return "expected #{@expected.inspect}, got #{@actual.inspect} (using .eql?)", @expected, @actual
+ end
+
+ def negative_failure_message
+ return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .eql?)", @expected, @actual
+ end
+
+ def description
+ "eql #{@expected.inspect}"
+ end
+ end
+
+ # :call-seq:
+ # should eql(expected)
+ # should_not eql(expected)
+ #
+ # Passes if actual and expected are of equal value, but not necessarily the same object.
+ #
+ # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
+ #
+ # == Examples
+ #
+ # 5.should eql(5)
+ # 5.should_not eql(3)
+ def eql(expected)
+ Matchers::Eql.new(expected)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/equal.rb b/vendor/plugins/rspec/lib/spec/matchers/equal.rb
new file mode 100644
index 00000000..4bfc7495
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/equal.rb
@@ -0,0 +1,43 @@
+module Spec
+ module Matchers
+
+ class Equal #:nodoc:
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def matches?(actual)
+ @actual = actual
+ @actual.equal?(@expected)
+ end
+
+ def failure_message
+ return "expected #{@expected.inspect}, got #{@actual.inspect} (using .equal?)", @expected, @actual
+ end
+
+ def negative_failure_message
+ return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .equal?)", @expected, @actual
+ end
+
+ def description
+ "equal #{@expected.inspect}"
+ end
+ end
+
+ # :call-seq:
+ # should equal(expected)
+ # should_not equal(expected)
+ #
+ # Passes if actual and expected are the same object (object identity).
+ #
+ # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
+ #
+ # == Examples
+ #
+ # 5.should equal(5) #Fixnums are equal
+ # "5".should_not equal("5") #Strings that look the same are not the same object
+ def equal(expected)
+ Matchers::Equal.new(expected)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/exist.rb b/vendor/plugins/rspec/lib/spec/matchers/exist.rb
new file mode 100644
index 00000000..a5a91113
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/exist.rb
@@ -0,0 +1,17 @@
+module Spec
+ module Matchers
+ class Exist
+ def matches? actual
+ @actual = actual
+ @actual.exist?
+ end
+ def failure_message
+ "expected #{@actual.inspect} to exist, but it doesn't."
+ end
+ def negative_failure_message
+ "expected #{@actual.inspect} to not exist, but it does."
+ end
+ end
+ def exist; Exist.new; end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/has.rb b/vendor/plugins/rspec/lib/spec/matchers/has.rb
new file mode 100644
index 00000000..60199f54
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/has.rb
@@ -0,0 +1,34 @@
+module Spec
+ module Matchers
+
+ class Has #:nodoc:
+ def initialize(sym, *args)
+ @sym = sym
+ @args = args
+ end
+
+ def matches?(target)
+ target.send(predicate, *@args)
+ end
+
+ def failure_message
+ "expected ##{predicate}(#{@args[0].inspect}) to return true, got false"
+ end
+
+ def negative_failure_message
+ "expected ##{predicate}(#{@args[0].inspect}) to return false, got true"
+ end
+
+ def description
+ "have key #{@args[0].inspect}"
+ end
+
+ private
+ def predicate
+ "#{@sym.to_s.sub("have_","has_")}?".to_sym
+ end
+
+ end
+
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/have.rb b/vendor/plugins/rspec/lib/spec/matchers/have.rb
new file mode 100644
index 00000000..20abcdd5
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/have.rb
@@ -0,0 +1,149 @@
+module Spec
+ module Matchers
+
+ class Have #:nodoc:
+ def initialize(expected, relativity=:exactly)
+ @expected = (expected == :no ? 0 : expected)
+ @relativity = relativity
+ end
+
+ def relativities
+ @relativities ||= {
+ :exactly => "",
+ :at_least => "at least ",
+ :at_most => "at most "
+ }
+ end
+
+ def method_missing(sym, *args, &block)
+ @collection_name = sym
+ if defined?(ActiveSupport::Inflector)
+ @plural_collection_name = ActiveSupport::Inflector.pluralize(sym.to_s)
+ elsif Object.const_defined?(:Inflector)
+ @plural_collection_name = Inflector.pluralize(sym.to_s)
+ end
+ @args = args
+ @block = block
+ self
+ end
+
+ def matches?(collection_owner)
+ if collection_owner.respond_to?(@collection_name)
+ collection = collection_owner.send(@collection_name, *@args, &@block)
+ elsif (@plural_collection_name && collection_owner.respond_to?(@plural_collection_name))
+ collection = collection_owner.send(@plural_collection_name, *@args, &@block)
+ elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size))
+ collection = collection_owner
+ else
+ collection_owner.send(@collection_name, *@args, &@block)
+ end
+ @actual = collection.size if collection.respond_to?(:size)
+ @actual = collection.length if collection.respond_to?(:length)
+ raise not_a_collection if @actual.nil?
+ return @actual >= @expected if @relativity == :at_least
+ return @actual <= @expected if @relativity == :at_most
+ return @actual == @expected
+ end
+
+ def not_a_collection
+ "expected #{@collection_name} to be a collection but it does not respond to #length or #size"
+ end
+
+ def failure_message
+ "expected #{relative_expectation} #{@collection_name}, got #{@actual}"
+ end
+
+ def negative_failure_message
+ if @relativity == :exactly
+ return "expected target not to have #{@expected} #{@collection_name}, got #{@actual}"
+ elsif @relativity == :at_most
+ return <<-EOF
+Isn't life confusing enough?
+Instead of having to figure out the meaning of this:
+ should_not have_at_most(#{@expected}).#{@collection_name}
+We recommend that you use this instead:
+ should have_at_least(#{@expected + 1}).#{@collection_name}
+EOF
+ elsif @relativity == :at_least
+ return <<-EOF
+Isn't life confusing enough?
+Instead of having to figure out the meaning of this:
+ should_not have_at_least(#{@expected}).#{@collection_name}
+We recommend that you use this instead:
+ should have_at_most(#{@expected - 1}).#{@collection_name}
+EOF
+ end
+ end
+
+ def description
+ "have #{relative_expectation} #{@collection_name}"
+ end
+
+ private
+
+ def relative_expectation
+ "#{relativities[@relativity]}#{@expected}"
+ end
+ end
+
+ # :call-seq:
+ # should have(number).named_collection__or__sugar
+ # should_not have(number).named_collection__or__sugar
+ #
+ # Passes if receiver is a collection with the submitted
+ # number of items OR if the receiver OWNS a collection
+ # with the submitted number of items.
+ #
+ # If the receiver OWNS the collection, you must use the name
+ # of the collection. So if a Team instance has a
+ # collection named #players, you must use that name
+ # to set the expectation.
+ #
+ # If the receiver IS the collection, you can use any name
+ # you like for named_collection. We'd recommend using
+ # either "elements", "members", or "items" as these are all
+ # standard ways of describing the things IN a collection.
+ #
+ # This also works for Strings, letting you set an expectation
+ # about its length
+ #
+ # == Examples
+ #
+ # # Passes if team.players.size == 11
+ # team.should have(11).players
+ #
+ # # Passes if [1,2,3].length == 3
+ # [1,2,3].should have(3).items #"items" is pure sugar
+ #
+ # # Passes if "this string".length == 11
+ # "this string".should have(11).characters #"characters" is pure sugar
+ def have(n)
+ Matchers::Have.new(n)
+ end
+ alias :have_exactly :have
+
+ # :call-seq:
+ # should have_at_least(number).items
+ #
+ # Exactly like have() with >=.
+ #
+ # == Warning
+ #
+ # +should_not+ +have_at_least+ is not supported
+ def have_at_least(n)
+ Matchers::Have.new(n, :at_least)
+ end
+
+ # :call-seq:
+ # should have_at_most(number).items
+ #
+ # Exactly like have() with <=.
+ #
+ # == Warning
+ #
+ # +should_not+ +have_at_most+ is not supported
+ def have_at_most(n)
+ Matchers::Have.new(n, :at_most)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/include.rb b/vendor/plugins/rspec/lib/spec/matchers/include.rb
new file mode 100644
index 00000000..5476f97d
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/include.rb
@@ -0,0 +1,70 @@
+module Spec
+ module Matchers
+
+ class Include #:nodoc:
+
+ def initialize(*expecteds)
+ @expecteds = expecteds
+ end
+
+ def matches?(actual)
+ @actual = actual
+ @expecteds.each do |expected|
+ return false unless actual.include?(expected)
+ end
+ true
+ end
+
+ def failure_message
+ _message
+ end
+
+ def negative_failure_message
+ _message("not ")
+ end
+
+ def description
+ "include #{_pretty_print(@expecteds)}"
+ end
+
+ private
+ def _message(maybe_not="")
+ "expected #{@actual.inspect} #{maybe_not}to include #{_pretty_print(@expecteds)}"
+ end
+
+ def _pretty_print(array)
+ result = ""
+ array.each_with_index do |item, index|
+ if index < (array.length - 2)
+ result << "#{item.inspect}, "
+ elsif index < (array.length - 1)
+ result << "#{item.inspect} and "
+ else
+ result << "#{item.inspect}"
+ end
+ end
+ result
+ end
+ end
+
+ # :call-seq:
+ # should include(expected)
+ # should_not include(expected)
+ #
+ # Passes if actual includes expected. This works for
+ # collections and Strings. You can also pass in multiple args
+ # and it will only pass if all args are found in collection.
+ #
+ # == Examples
+ #
+ # [1,2,3].should include(3)
+ # [1,2,3].should include(2,3) #would pass
+ # [1,2,3].should include(2,3,4) #would fail
+ # [1,2,3].should_not include(4)
+ # "spread".should include("read")
+ # "spread".should_not include("red")
+ def include(*expected)
+ Matchers::Include.new(*expected)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/match.rb b/vendor/plugins/rspec/lib/spec/matchers/match.rb
new file mode 100644
index 00000000..61ab5242
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/match.rb
@@ -0,0 +1,41 @@
+module Spec
+ module Matchers
+
+ class Match #:nodoc:
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def matches?(actual)
+ @actual = actual
+ return true if actual =~ @expected
+ return false
+ end
+
+ def failure_message
+ return "expected #{@actual.inspect} to match #{@expected.inspect}", @expected, @actual
+ end
+
+ def negative_failure_message
+ return "expected #{@actual.inspect} not to match #{@expected.inspect}", @expected, @actual
+ end
+
+ def description
+ "match #{@expected.inspect}"
+ end
+ end
+
+ # :call-seq:
+ # should match(regexp)
+ # should_not match(regexp)
+ #
+ # Given a Regexp, passes if actual =~ regexp
+ #
+ # == Examples
+ #
+ # email.should match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
+ def match(regexp)
+ Matchers::Match.new(regexp)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/operator_matcher.rb b/vendor/plugins/rspec/lib/spec/matchers/operator_matcher.rb
new file mode 100755
index 00000000..dd23a099
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/operator_matcher.rb
@@ -0,0 +1,73 @@
+module Spec
+ module Matchers
+ class BaseOperatorMatcher
+ attr_reader :generated_description
+
+ def initialize(target)
+ @target = target
+ end
+
+ def ==(expected)
+ @expected = expected
+ __delegate_method_missing_to_target("==", expected)
+ end
+
+ def ===(expected)
+ @expected = expected
+ __delegate_method_missing_to_target("===", expected)
+ end
+
+ def =~(expected)
+ @expected = expected
+ __delegate_method_missing_to_target("=~", expected)
+ end
+
+ def >(expected)
+ @expected = expected
+ __delegate_method_missing_to_target(">", expected)
+ end
+
+ def >=(expected)
+ @expected = expected
+ __delegate_method_missing_to_target(">=", expected)
+ end
+
+ def <(expected)
+ @expected = expected
+ __delegate_method_missing_to_target("<", expected)
+ end
+
+ def <=(expected)
+ @expected = expected
+ __delegate_method_missing_to_target("<=", expected)
+ end
+
+ def fail_with_message(message)
+ Spec::Expectations.fail_with(message, @expected, @target)
+ end
+
+ end
+
+ class PositiveOperatorMatcher < BaseOperatorMatcher #:nodoc:
+
+ def __delegate_method_missing_to_target(operator, expected)
+ ::Spec::Matchers.generated_description = "should #{operator} #{expected.inspect}"
+ return if @target.send(operator, expected)
+ return fail_with_message("expected: #{expected.inspect},\n got: #{@target.inspect} (using #{operator})") if ['==','===', '=~'].include?(operator)
+ return fail_with_message("expected: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{@target.inspect}")
+ end
+
+ end
+
+ class NegativeOperatorMatcher < BaseOperatorMatcher #:nodoc:
+
+ def __delegate_method_missing_to_target(operator, expected)
+ ::Spec::Matchers.generated_description = "should not #{operator} #{expected.inspect}"
+ return unless @target.send(operator, expected)
+ return fail_with_message("expected not: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{@target.inspect}")
+ end
+
+ end
+
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/raise_error.rb b/vendor/plugins/rspec/lib/spec/matchers/raise_error.rb
new file mode 100644
index 00000000..c003849b
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/raise_error.rb
@@ -0,0 +1,132 @@
+module Spec
+ module Matchers
+ class RaiseError #:nodoc:
+ def initialize(error_or_message=Exception, message=nil, &block)
+ @block = block
+ case error_or_message
+ when String, Regexp
+ @expected_error, @expected_message = Exception, error_or_message
+ else
+ @expected_error, @expected_message = error_or_message, message
+ end
+ end
+
+ def matches?(proc)
+ @raised_expected_error = false
+ @with_expected_message = false
+ @eval_block = false
+ @eval_block_passed = false
+ begin
+ proc.call
+ rescue @expected_error => @actual_error
+ @raised_expected_error = true
+ @with_expected_message = verify_message
+ rescue Exception => @actual_error
+ # This clause should be empty, but rcov will not report it as covered
+ # unless something (anything) is executed within the clause
+ rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
+ end
+
+ unless negative_expectation?
+ eval_block if @raised_expected_error && @with_expected_message && @block
+ end
+ ensure
+ return (@raised_expected_error && @with_expected_message) ? (@eval_block ? @eval_block_passed : true) : false
+ end
+
+ def eval_block
+ @eval_block = true
+ begin
+ @block[@actual_error]
+ @eval_block_passed = true
+ rescue Exception => err
+ @actual_error = err
+ end
+ end
+
+ def verify_message
+ case @expected_message
+ when nil
+ return true
+ when Regexp
+ return @expected_message =~ @actual_error.message
+ else
+ return @expected_message == @actual_error.message
+ end
+ end
+
+ def failure_message
+ if @eval_block
+ return @actual_error.message
+ else
+ return "expected #{expected_error}#{actual_error}"
+ end
+ end
+
+ def negative_failure_message
+ "expected no #{expected_error}#{actual_error}"
+ end
+
+ def description
+ "raise #{expected_error}"
+ end
+
+ private
+ def expected_error
+ case @expected_message
+ when nil
+ @expected_error
+ when Regexp
+ "#{@expected_error} with message matching #{@expected_message.inspect}"
+ else
+ "#{@expected_error} with #{@expected_message.inspect}"
+ end
+ end
+
+ def actual_error
+ @actual_error.nil? ? " but nothing was raised" : ", got #{@actual_error.inspect}"
+ end
+
+ def negative_expectation?
+ # YES - I'm a bad person... help me find a better way - ryand
+ caller.first(3).find { |s| s =~ /should_not/ }
+ end
+ end
+
+ # :call-seq:
+ # should raise_error()
+ # should raise_error(NamedError)
+ # should raise_error(NamedError, String)
+ # should raise_error(NamedError, Regexp)
+ # should raise_error() { |error| ... }
+ # should raise_error(NamedError) { |error| ... }
+ # should raise_error(NamedError, String) { |error| ... }
+ # should raise_error(NamedError, Regexp) { |error| ... }
+ # should_not raise_error()
+ # should_not raise_error(NamedError)
+ # should_not raise_error(NamedError, String)
+ # should_not raise_error(NamedError, Regexp)
+ #
+ # With no args, matches if any error is raised.
+ # With a named error, matches only if that specific error is raised.
+ # With a named error and messsage specified as a String, matches only if both match.
+ # With a named error and messsage specified as a Regexp, matches only if both match.
+ # Pass an optional block to perform extra verifications on the exception matched
+ #
+ # == Examples
+ #
+ # lambda { do_something_risky }.should raise_error
+ # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError)
+ # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError) { |error| error.data.should == 42 }
+ # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, "that was too risky")
+ # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, /oo ri/)
+ #
+ # lambda { do_something_risky }.should_not raise_error
+ # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError)
+ # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, "that was too risky")
+ # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, /oo ri/)
+ def raise_error(error=Exception, message=nil, &block)
+ Matchers::RaiseError.new(error, message, &block)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/respond_to.rb b/vendor/plugins/rspec/lib/spec/matchers/respond_to.rb
new file mode 100644
index 00000000..3d23422a
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/respond_to.rb
@@ -0,0 +1,45 @@
+module Spec
+ module Matchers
+
+ class RespondTo #:nodoc:
+ def initialize(*names)
+ @names = names
+ @names_not_responded_to = []
+ end
+
+ def matches?(target)
+ @names.each do |name|
+ unless target.respond_to?(name)
+ @names_not_responded_to << name
+ end
+ end
+ return @names_not_responded_to.empty?
+ end
+
+ def failure_message
+ "expected target to respond to #{@names_not_responded_to.collect {|name| name.inspect }.join(', ')}"
+ end
+
+ def negative_failure_message
+ "expected target not to respond to #{@names.collect {|name| name.inspect }.join(', ')}"
+ end
+
+ def description
+ "respond to ##{@names.to_s}"
+ end
+ end
+
+ # :call-seq:
+ # should respond_to(*names)
+ # should_not respond_to(*names)
+ #
+ # Matches if the target object responds to all of the names
+ # provided. Names can be Strings or Symbols.
+ #
+ # == Examples
+ #
+ def respond_to(*names)
+ Matchers::RespondTo.new(*names)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/satisfy.rb b/vendor/plugins/rspec/lib/spec/matchers/satisfy.rb
new file mode 100644
index 00000000..6c0ca95b
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/satisfy.rb
@@ -0,0 +1,47 @@
+module Spec
+ module Matchers
+
+ class Satisfy #:nodoc:
+ def initialize(&block)
+ @block = block
+ end
+
+ def matches?(actual, &block)
+ @block = block if block
+ @actual = actual
+ @block.call(actual)
+ end
+
+ def failure_message
+ "expected #{@actual} to satisfy block"
+ end
+
+ def negative_failure_message
+ "expected #{@actual} not to satisfy block"
+ end
+ end
+
+ # :call-seq:
+ # should satisfy {}
+ # should_not satisfy {}
+ #
+ # Passes if the submitted block returns true. Yields target to the
+ # block.
+ #
+ # Generally speaking, this should be thought of as a last resort when
+ # you can't find any other way to specify the behaviour you wish to
+ # specify.
+ #
+ # If you do find yourself in such a situation, you could always write
+ # a custom matcher, which would likely make your specs more expressive.
+ #
+ # == Examples
+ #
+ # 5.should satisfy { |n|
+ # n > 3
+ # }
+ def satisfy(&block)
+ Matchers::Satisfy.new(&block)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/simple_matcher.rb b/vendor/plugins/rspec/lib/spec/matchers/simple_matcher.rb
new file mode 100644
index 00000000..ac547d06
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/simple_matcher.rb
@@ -0,0 +1,29 @@
+module Spec
+ module Matchers
+ class SimpleMatcher
+ attr_reader :description
+
+ def initialize(description, &match_block)
+ @description = description
+ @match_block = match_block
+ end
+
+ def matches?(actual)
+ @actual = actual
+ return @match_block.call(@actual)
+ end
+
+ def failure_message()
+ return %[expected #{@description.inspect} but got #{@actual.inspect}]
+ end
+
+ def negative_failure_message()
+ return %[expected not to get #{@description.inspect}, but got #{@actual.inspect}]
+ end
+ end
+
+ def simple_matcher(message, &match_block)
+ SimpleMatcher.new(message, &match_block)
+ end
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/matchers/throw_symbol.rb b/vendor/plugins/rspec/lib/spec/matchers/throw_symbol.rb
new file mode 100644
index 00000000..c74d8443
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/throw_symbol.rb
@@ -0,0 +1,74 @@
+module Spec
+ module Matchers
+
+ class ThrowSymbol #:nodoc:
+ def initialize(expected=nil)
+ @expected = expected
+ @actual = nil
+ end
+
+ def matches?(proc)
+ begin
+ proc.call
+ rescue NameError => e
+ raise e unless e.message =~ /uncaught throw/
+ @actual = e.name.to_sym
+ ensure
+ if @expected.nil?
+ return @actual.nil? ? false : true
+ else
+ return @actual == @expected
+ end
+ end
+ end
+
+ def failure_message
+ if @actual
+ "expected #{expected}, got #{@actual.inspect}"
+ else
+ "expected #{expected} but nothing was thrown"
+ end
+ end
+
+ def negative_failure_message
+ if @expected
+ "expected #{expected} not to be thrown"
+ else
+ "expected no Symbol, got :#{@actual}"
+ end
+ end
+
+ def description
+ "throw #{expected}"
+ end
+
+ private
+
+ def expected
+ @expected.nil? ? "a Symbol" : @expected.inspect
+ end
+
+ end
+
+ # :call-seq:
+ # should throw_symbol()
+ # should throw_symbol(:sym)
+ # should_not throw_symbol()
+ # should_not throw_symbol(:sym)
+ #
+ # Given a Symbol argument, matches if a proc throws the specified Symbol.
+ #
+ # Given no argument, matches if a proc throws any Symbol.
+ #
+ # == Examples
+ #
+ # lambda { do_something_risky }.should throw_symbol
+ # lambda { do_something_risky }.should throw_symbol(:that_was_risky)
+ #
+ # lambda { do_something_risky }.should_not throw_symbol
+ # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky)
+ def throw_symbol(sym=nil)
+ Matchers::ThrowSymbol.new(sym)
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks.rb b/vendor/plugins/rspec/lib/spec/mocks.rb
new file mode 100644
index 00000000..678dd6aa
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks.rb
@@ -0,0 +1,211 @@
+require 'spec/mocks/framework'
+require 'spec/mocks/methods'
+require 'spec/mocks/argument_constraint_matchers'
+require 'spec/mocks/spec_methods'
+require 'spec/mocks/proxy'
+require 'spec/mocks/mock'
+require 'spec/mocks/argument_expectation'
+require 'spec/mocks/message_expectation'
+require 'spec/mocks/order_group'
+require 'spec/mocks/errors'
+require 'spec/mocks/error_generator'
+require 'spec/mocks/extensions/object'
+require 'spec/mocks/space'
+
+module Spec
+ # == Mocks and Stubs
+ #
+ # RSpec will create Mock Objects and Stubs for you at runtime, or attach stub/mock behaviour
+ # to any of your real objects (Partial Mock/Stub). Because the underlying implementation
+ # for mocks and stubs is the same, you can intermingle mock and stub
+ # behaviour in either dynamically generated mocks or your pre-existing classes.
+ # There is a semantic difference in how they are created, however,
+ # which can help clarify the role it is playing within a given spec.
+ #
+ # == Mock Objects
+ #
+ # Mocks are objects that allow you to set and verify expectations that they will
+ # receive specific messages during run time. They are very useful for specifying how the subject of
+ # the spec interacts with its collaborators. This approach is widely known as "interaction
+ # testing".
+ #
+ # Mocks are also very powerful as a design tool. As you are
+ # driving the implementation of a given class, Mocks provide an anonymous
+ # collaborator that can change in behaviour as quickly as you can write an expectation in your
+ # spec. This flexibility allows you to design the interface of a collaborator that often
+ # does not yet exist. As the shape of the class being specified becomes more clear, so do the
+ # requirements for its collaborators - often leading to the discovery of new types that are
+ # needed in your system.
+ #
+ # Read Endo-Testing[http://www.mockobjects.com/files/endotesting.pdf] for a much
+ # more in depth description of this process.
+ #
+ # == Stubs
+ #
+ # Stubs are objects that allow you to set "stub" responses to
+ # messages. As Martin Fowler points out on his site,
+ # mocks_arent_stubs[http://www.martinfowler.com/articles/mocksArentStubs.html].
+ # Paraphrasing Fowler's paraphrasing
+ # of Gerard Meszaros: Stubs provide canned responses to messages they might receive in a test, while
+ # mocks allow you to specify and, subsquently, verify that certain messages should be received during
+ # the execution of a test.
+ #
+ # == Partial Mocks/Stubs
+ #
+ # RSpec also supports partial mocking/stubbing, allowing you to add stub/mock behaviour
+ # to instances of your existing classes. This is generally
+ # something to be avoided, because changes to the class can have ripple effects on
+ # seemingly unrelated specs. When specs fail due to these ripple effects, the fact
+ # that some methods are being mocked can make it difficult to understand why a
+ # failure is occurring.
+ #
+ # That said, partials do allow you to expect and
+ # verify interactions with class methods such as +#find+ and +#create+
+ # on Ruby on Rails model classes.
+ #
+ # == Further Reading
+ #
+ # There are many different viewpoints about the meaning of mocks and stubs. If you are interested
+ # in learning more, here is some recommended reading:
+ #
+ # * Mock Objects: http://www.mockobjects.com/
+ # * Endo-Testing: http://www.mockobjects.com/files/endotesting.pdf
+ # * Mock Roles, Not Objects: http://www.mockobjects.com/files/mockrolesnotobjects.pdf
+ # * Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html
+ # * Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html
+ #
+ # == Creating a Mock
+ #
+ # You can create a mock in any specification (or setup) using:
+ #
+ # mock(name, options={})
+ #
+ # The optional +options+ argument is a +Hash+. Currently the only supported
+ # option is +:null_object+. Setting this to true instructs the mock to ignore
+ # any messages it hasn’t been told to expect – and quietly return itself. For example:
+ #
+ # mock("person", :null_object => true)
+ #
+ # == Creating a Stub
+ #
+ # You can create a stub in any specification (or setup) using:
+ #
+ # stub(name, stub_methods_and_values_hash)
+ #
+ # For example, if you wanted to create an object that always returns
+ # "More?!?!?!" to "please_sir_may_i_have_some_more" you would do this:
+ #
+ # stub("Mr Sykes", :please_sir_may_i_have_some_more => "More?!?!?!")
+ #
+ # == Creating a Partial Mock
+ #
+ # You don't really "create" a partial mock, you simply add method stubs and/or
+ # mock expectations to existing classes and objects:
+ #
+ # Factory.should_receive(:find).with(id).and_return(value)
+ # obj.stub!(:to_i).and_return(3)
+ # etc ...
+ #
+ # == Expecting Messages
+ #
+ # my_mock.should_receive(:sym)
+ # my_mock.should_not_receive(:sym)
+ #
+ # == Expecting Arguments
+ #
+ # my_mock.should_receive(:sym).with(*args)
+ # my_mock.should_not_receive(:sym).with(*args)
+ #
+ # == Argument Constraints using Expression Matchers
+ #
+ # Arguments that are passed to #with are compared with actual arguments received
+ # using == by default. In cases in which you want to specify things about the arguments
+ # rather than the arguments themselves, you can use any of the Expression Matchers.
+ # They don't all make syntactic sense (they were primarily designed for use with
+ # Spec::Expectations), but you are free to create your own custom Spec::Matchers.
+ #
+ # Spec::Mocks does provide one additional Matcher method named #ducktype.
+ #
+ # In addition, Spec::Mocks adds some keyword Symbols that you can use to
+ # specify certain kinds of arguments:
+ #
+ # my_mock.should_receive(:sym).with(no_args())
+ # my_mock.should_receive(:sym).with(any_args())
+ # my_mock.should_receive(:sym).with(1, an_instance_of(Numeric), "b") #2nd argument can any type of Numeric
+ # my_mock.should_receive(:sym).with(1, boolean(), "b") #2nd argument can true or false
+ # my_mock.should_receive(:sym).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp
+ # my_mock.should_receive(:sym).with(1, anything(), "b") #2nd argument can be anything at all
+ # my_mock.should_receive(:sym).with(1, ducktype(:abs, :div), "b")
+ # #2nd argument can be object that responds to #abs and #div
+ #
+ # == Receive Counts
+ #
+ # my_mock.should_receive(:sym).once
+ # my_mock.should_receive(:sym).twice
+ # my_mock.should_receive(:sym).exactly(n).times
+ # my_mock.should_receive(:sym).at_least(:once)
+ # my_mock.should_receive(:sym).at_least(:twice)
+ # my_mock.should_receive(:sym).at_least(n).times
+ # my_mock.should_receive(:sym).at_most(:once)
+ # my_mock.should_receive(:sym).at_most(:twice)
+ # my_mock.should_receive(:sym).at_most(n).times
+ # my_mock.should_receive(:sym).any_number_of_times
+ #
+ # == Ordering
+ #
+ # my_mock.should_receive(:sym).ordered
+ # my_mock.should_receive(:other_sym).ordered
+ # #This will fail if the messages are received out of order
+ #
+ # == Setting Reponses
+ #
+ # Whether you are setting a mock expectation or a simple stub, you can tell the
+ # object precisely how to respond:
+ #
+ # my_mock.should_receive(:sym).and_return(value)
+ # my_mock.should_receive(:sym).exactly(3).times.and_return(value1, value2, value3)
+ # # returns value1 the first time, value2 the second, etc
+ # my_mock.should_receive(:sym).and_return { ... } #returns value returned by the block
+ # my_mock.should_receive(:sym).and_raise(error)
+ # #error can be an instantiated object or a class
+ # #if it is a class, it must be instantiable with no args
+ # my_mock.should_receive(:sym).and_throw(:sym)
+ # my_mock.should_receive(:sym).and_yield(values,to,yield)
+ # my_mock.should_receive(:sym).and_yield(values,to,yield).and_yield(some,other,values,this,time)
+ # # for methods that yield to a block multiple times
+ #
+ # Any of these responses can be applied to a stub as well, but stubs do
+ # not support any qualifiers about the message received (i.e. you can't specify arguments
+ # or receive counts):
+ #
+ # my_mock.stub!(:sym).and_return(value)
+ # my_mock.stub!(:sym).and_return(value1, value2, value3)
+ # my_mock.stub!(:sym).and_raise(error)
+ # my_mock.stub!(:sym).and_throw(:sym)
+ # my_mock.stub!(:sym).and_yield(values,to,yield)
+ # my_mock.stub!(:sym).and_yield(values,to,yield).and_yield(some,other,values,this,time)
+ #
+ # == Arbitrary Handling
+ #
+ # Once in a while you'll find that the available expectations don't solve the
+ # particular problem you are trying to solve. Imagine that you expect the message
+ # to come with an Array argument that has a specific length, but you don't care
+ # what is in it. You could do this:
+ #
+ # my_mock.should_receive(:sym) do |arg|
+ # arg.should be_an_istance_of(Array)
+ # arg.length.should == 7
+ # end
+ #
+ # Note that this would fail if the number of arguments received was different from
+ # the number of block arguments (in this case 1).
+ #
+ # == Combining Expectation Details
+ #
+ # Combining the message name with specific arguments, receive counts and responses
+ # you can get quite a bit of detail in your expectations:
+ #
+ # my_mock.should_receive(:<<).with("illegal value").once.and_raise(ArgumentError)
+ module Mocks
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb b/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb
new file mode 100644
index 00000000..96ccf0f4
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb
@@ -0,0 +1,31 @@
+module Spec
+ module Mocks
+ module ArgumentConstraintMatchers
+
+ # Shortcut for creating an instance of Spec::Mocks::DuckTypeArgConstraint
+ def duck_type(*args)
+ DuckTypeArgConstraint.new(*args)
+ end
+
+ def any_args
+ AnyArgsConstraint.new
+ end
+
+ def anything
+ AnyArgConstraint.new(nil)
+ end
+
+ def boolean
+ BooleanArgConstraint.new(nil)
+ end
+
+ def hash_including(expected={})
+ HashIncludingConstraint.new(expected)
+ end
+
+ def no_args
+ NoArgsConstraint.new
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb
new file mode 100644
index 00000000..4f2e9538
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb
@@ -0,0 +1,216 @@
+module Spec
+ module Mocks
+
+ class MatcherConstraint
+ def initialize(matcher)
+ @matcher = matcher
+ end
+
+ def matches?(value)
+ @matcher.matches?(value)
+ end
+ end
+
+ class LiteralArgConstraint
+ def initialize(literal)
+ @literal_value = literal
+ end
+
+ def matches?(value)
+ @literal_value == value
+ end
+ end
+
+ class RegexpArgConstraint
+ def initialize(regexp)
+ @regexp = regexp
+ end
+
+ def matches?(value)
+ return value =~ @regexp unless value.is_a?(Regexp)
+ value == @regexp
+ end
+ end
+
+ class AnyArgConstraint
+ def initialize(ignore)
+ end
+
+ def ==(other)
+ true
+ end
+
+ # TODO - need this?
+ def matches?(value)
+ true
+ end
+ end
+
+ class AnyArgsConstraint
+ def description
+ "any args"
+ end
+ end
+
+ class NoArgsConstraint
+ def description
+ "no args"
+ end
+
+ def ==(args)
+ args == []
+ end
+ end
+
+ class NumericArgConstraint
+ def initialize(ignore)
+ end
+
+ def matches?(value)
+ value.is_a?(Numeric)
+ end
+ end
+
+ class BooleanArgConstraint
+ def initialize(ignore)
+ end
+
+ def ==(value)
+ matches?(value)
+ end
+
+ def matches?(value)
+ return true if value.is_a?(TrueClass)
+ return true if value.is_a?(FalseClass)
+ false
+ end
+ end
+
+ class StringArgConstraint
+ def initialize(ignore)
+ end
+
+ def matches?(value)
+ value.is_a?(String)
+ end
+ end
+
+ class DuckTypeArgConstraint
+ def initialize(*methods_to_respond_to)
+ @methods_to_respond_to = methods_to_respond_to
+ end
+
+ def matches?(value)
+ @methods_to_respond_to.all? { |sym| value.respond_to?(sym) }
+ end
+
+ def description
+ "duck_type"
+ end
+ end
+
+ class HashIncludingConstraint
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def ==(actual)
+ @expected.each do | key, value |
+ # check key for case that value evaluates to nil
+ return false unless actual.has_key?(key) && actual[key] == value
+ end
+ true
+ rescue NoMethodError => ex
+ return false
+ end
+
+ def matches?(value)
+ self == value
+ end
+
+ def description
+ "hash_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
+ end
+
+ end
+
+
+ class ArgumentExpectation
+ attr_reader :args
+ @@constraint_classes = Hash.new { |hash, key| LiteralArgConstraint}
+ @@constraint_classes[:anything] = AnyArgConstraint
+ @@constraint_classes[:numeric] = NumericArgConstraint
+ @@constraint_classes[:boolean] = BooleanArgConstraint
+ @@constraint_classes[:string] = StringArgConstraint
+
+ def initialize(args, &block)
+ @args = args
+ @constraints_block = block
+
+ if [:any_args] == args
+ @expected_params = nil
+ warn_deprecated(:any_args.inspect, "any_args()")
+ elsif args.length == 1 && args[0].is_a?(AnyArgsConstraint) then @expected_params = nil
+ elsif [:no_args] == args
+ @expected_params = []
+ warn_deprecated(:no_args.inspect, "no_args()")
+ elsif args.length == 1 && args[0].is_a?(NoArgsConstraint) then @expected_params = []
+ else @expected_params = process_arg_constraints(args)
+ end
+ end
+
+ def process_arg_constraints(constraints)
+ constraints.collect do |constraint|
+ convert_constraint(constraint)
+ end
+ end
+
+ def warn_deprecated(deprecated_method, instead)
+ Kernel.warn "The #{deprecated_method} constraint is deprecated. Use #{instead} instead."
+ end
+
+ def convert_constraint(constraint)
+ if [:anything, :numeric, :boolean, :string].include?(constraint)
+ case constraint
+ when :anything
+ instead = "anything()"
+ when :boolean
+ instead = "boolean()"
+ when :numeric
+ instead = "an_instance_of(Numeric)"
+ when :string
+ instead = "an_instance_of(String)"
+ end
+ warn_deprecated(constraint.inspect, instead)
+ return @@constraint_classes[constraint].new(constraint)
+ end
+ return MatcherConstraint.new(constraint) if is_matcher?(constraint)
+ return RegexpArgConstraint.new(constraint) if constraint.is_a?(Regexp)
+ return LiteralArgConstraint.new(constraint)
+ end
+
+ def is_matcher?(obj)
+ return obj.respond_to?(:matches?) && obj.respond_to?(:description)
+ end
+
+ def check_args(args)
+ if @constraints_block
+ @constraints_block.call(*args)
+ return true
+ end
+
+ return true if @expected_params.nil?
+ return true if @expected_params == args
+ return constraints_match?(args)
+ end
+
+ def constraints_match?(args)
+ return false if args.length != @expected_params.length
+ @expected_params.each_index { |i| return false unless @expected_params[i].matches?(args[i]) }
+ return true
+ end
+
+ end
+
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/error_generator.rb b/vendor/plugins/rspec/lib/spec/mocks/error_generator.rb
new file mode 100644
index 00000000..01d8f720
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/error_generator.rb
@@ -0,0 +1,84 @@
+module Spec
+ module Mocks
+ class ErrorGenerator
+ attr_writer :opts
+
+ def initialize(target, name)
+ @target = target
+ @name = name
+ end
+
+ def opts
+ @opts ||= {}
+ end
+
+ def raise_unexpected_message_error(sym, *args)
+ __raise "#{intro} received unexpected message :#{sym}#{arg_message(*args)}"
+ end
+
+ def raise_unexpected_message_args_error(expectation, *args)
+ expected_args = format_args(*expectation.expected_args)
+ actual_args = args.empty? ? "(no args)" : format_args(*args)
+ __raise "#{intro} expected #{expectation.sym.inspect} with #{expected_args} but received it with #{actual_args}"
+ end
+
+ def raise_expectation_error(sym, expected_received_count, actual_received_count, *args)
+ __raise "#{intro} expected :#{sym}#{arg_message(*args)} #{count_message(expected_received_count)}, but received it #{count_message(actual_received_count)}"
+ end
+
+ def raise_out_of_order_error(sym)
+ __raise "#{intro} received :#{sym} out of order"
+ end
+
+ def raise_block_failed_error(sym, detail)
+ __raise "#{intro} received :#{sym} but passed block failed with: #{detail}"
+ end
+
+ def raise_missing_block_error(args_to_yield)
+ __raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed"
+ end
+
+ def raise_wrong_arity_error(args_to_yield, arity)
+ __raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}"
+ end
+
+ private
+ def intro
+ @name ? "Mock '#{@name}'" : @target.inspect
+ end
+
+ def __raise(message)
+ message = opts[:message] unless opts[:message].nil?
+ Kernel::raise(Spec::Mocks::MockExpectationError, message)
+ end
+
+ def arg_message(*args)
+ " with " + format_args(*args)
+ end
+
+ def format_args(*args)
+ return "(no args)" if args.empty? || args == [:no_args]
+ return "(any args)" if args == [:any_args]
+ "(" + arg_list(*args) + ")"
+ end
+
+ def arg_list(*args)
+ args.collect do |arg|
+ arg.respond_to?(:description) ? arg.description : arg.inspect
+ end.join(", ")
+ end
+
+ def count_message(count)
+ return "at least #{pretty_print(count.abs)}" if count < 0
+ return pretty_print(count)
+ end
+
+ def pretty_print(count)
+ return "once" if count == 1
+ return "twice" if count == 2
+ return "#{count} times"
+ end
+
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/errors.rb b/vendor/plugins/rspec/lib/spec/mocks/errors.rb
new file mode 100644
index 00000000..68fdfe00
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/errors.rb
@@ -0,0 +1,10 @@
+module Spec
+ module Mocks
+ class MockExpectationError < StandardError
+ end
+
+ class AmbiguousReturnError < StandardError
+ end
+ end
+end
+
diff --git a/vendor/plugins/rspec/lib/spec/mocks/extensions.rb b/vendor/plugins/rspec/lib/spec/mocks/extensions.rb
new file mode 100644
index 00000000..6fd51a27
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/extensions.rb
@@ -0,0 +1 @@
+require 'spec/mocks/extensions/object'
diff --git a/vendor/plugins/rspec/lib/spec/mocks/extensions/object.rb b/vendor/plugins/rspec/lib/spec/mocks/extensions/object.rb
new file mode 100644
index 00000000..4b753106
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/extensions/object.rb
@@ -0,0 +1,3 @@
+class Object
+ include Spec::Mocks::Methods
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/framework.rb b/vendor/plugins/rspec/lib/spec/mocks/framework.rb
new file mode 100644
index 00000000..92089673
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/framework.rb
@@ -0,0 +1,15 @@
+# Require everything except the global extensions of class and object. This
+# supports wrapping rspec's mocking functionality without invading every
+# object in the system.
+
+require 'spec/mocks/methods'
+require 'spec/mocks/argument_constraint_matchers'
+require 'spec/mocks/spec_methods'
+require 'spec/mocks/proxy'
+require 'spec/mocks/mock'
+require 'spec/mocks/argument_expectation'
+require 'spec/mocks/message_expectation'
+require 'spec/mocks/order_group'
+require 'spec/mocks/errors'
+require 'spec/mocks/error_generator'
+require 'spec/mocks/space'
diff --git a/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb b/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb
new file mode 100644
index 00000000..d0189614
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb
@@ -0,0 +1,290 @@
+module Spec
+ module Mocks
+
+ class BaseExpectation
+ attr_reader :sym
+
+ def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={})
+ @error_generator = error_generator
+ @error_generator.opts = opts
+ @expected_from = expected_from
+ @sym = sym
+ @method_block = method_block
+ @return_block = nil
+ @actual_received_count = 0
+ @expected_received_count = expected_received_count
+ @args_expectation = ArgumentExpectation.new([AnyArgsConstraint.new])
+ @consecutive = false
+ @exception_to_raise = nil
+ @symbol_to_throw = nil
+ @order_group = expectation_ordering
+ @at_least = nil
+ @at_most = nil
+ @args_to_yield = []
+ end
+
+ def expected_args
+ @args_expectation.args
+ end
+
+ def and_return(*values, &return_block)
+ Kernel::raise AmbiguousReturnError unless @method_block.nil?
+ case values.size
+ when 0 then value = nil
+ when 1 then value = values[0]
+ else
+ value = values
+ @consecutive = true
+ @expected_received_count = values.size if !ignoring_args? &&
+ @expected_received_count < values.size
+ end
+ @return_block = block_given? ? return_block : lambda { value }
+ # Ruby 1.9 - see where this is used below
+ @ignore_args = !block_given?
+ end
+
+ # :call-seq:
+ # and_raise()
+ # and_raise(Exception) #any exception class
+ # and_raise(exception) #any exception object
+ #
+ # == Warning
+ #
+ # When you pass an exception class, the MessageExpectation will
+ # raise an instance of it, creating it with +new+. If the exception
+ # class initializer requires any parameters, you must pass in an
+ # instance and not the class.
+ def and_raise(exception=Exception)
+ @exception_to_raise = exception
+ end
+
+ def and_throw(symbol)
+ @symbol_to_throw = symbol
+ end
+
+ def and_yield(*args)
+ @args_to_yield << args
+ self
+ end
+
+ def matches(sym, args)
+ @sym == sym and @args_expectation.check_args(args)
+ end
+
+ def invoke(args, block)
+ if @expected_received_count == 0
+ @actual_received_count += 1
+ @error_generator.raise_expectation_error @sym, @expected_received_count, @actual_received_count, *args
+ end
+
+ @order_group.handle_order_constraint self
+
+ begin
+ Kernel::raise @exception_to_raise unless @exception_to_raise.nil?
+ Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil?
+
+
+ if !@method_block.nil?
+ default_return_val = invoke_method_block(args)
+ elsif @args_to_yield.size > 0
+ default_return_val = invoke_with_yield(block)
+ else
+ default_return_val = nil
+ end
+
+ if @consecutive
+ return invoke_consecutive_return_block(args, block)
+ elsif @return_block
+ return invoke_return_block(args, block)
+ else
+ return default_return_val
+ end
+ ensure
+ @actual_received_count += 1
+ end
+ end
+
+ protected
+
+ def invoke_method_block(args)
+ begin
+ @method_block.call(*args)
+ rescue => detail
+ @error_generator.raise_block_failed_error @sym, detail.message
+ end
+ end
+
+ def invoke_with_yield(block)
+ if block.nil?
+ @error_generator.raise_missing_block_error @args_to_yield
+ end
+ value = nil
+ @args_to_yield.each do |args_to_yield_this_time|
+ if block.arity > -1 && args_to_yield_this_time.length != block.arity
+ @error_generator.raise_wrong_arity_error args_to_yield_this_time, block.arity
+ end
+ value = block.call(*args_to_yield_this_time)
+ end
+ value
+ end
+
+ def invoke_consecutive_return_block(args, block)
+ args << block unless block.nil?
+ value = @return_block.call(*args)
+
+ index = [@actual_received_count, value.size-1].min
+ value[index]
+ end
+
+ def invoke_return_block(args, block)
+ args << block unless block.nil?
+ # Ruby 1.9 - when we set @return_block to return values
+ # regardless of arguments, any arguments will result in
+ # a "wrong number of arguments" error
+ if @ignore_args
+ @return_block.call()
+ else
+ @return_block.call(*args)
+ end
+ end
+ end
+
+ class MessageExpectation < BaseExpectation
+
+ def matches_name_but_not_args(sym, args)
+ @sym == sym and not @args_expectation.check_args(args)
+ end
+
+ def verify_messages_received
+ return if expected_messages_received?
+
+ generate_error
+ rescue Spec::Mocks::MockExpectationError => error
+ error.backtrace.insert(0, @expected_from)
+ Kernel::raise error
+ end
+
+ def expected_messages_received?
+ ignoring_args? || matches_exact_count? ||
+ matches_at_least_count? || matches_at_most_count?
+ end
+
+ def ignoring_args?
+ @expected_received_count == :any
+ end
+
+ def matches_at_least_count?
+ @at_least && @actual_received_count >= @expected_received_count
+ end
+
+ def matches_at_most_count?
+ @at_most && @actual_received_count <= @expected_received_count
+ end
+
+ def matches_exact_count?
+ @expected_received_count == @actual_received_count
+ end
+
+ def similar_messages
+ @similar_messages ||= []
+ end
+
+ def advise(args, block)
+ similar_messages << args
+ end
+
+ def generate_error
+ if similar_messages.empty?
+ @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args)
+ else
+ @error_generator.raise_unexpected_message_args_error(self, *@similar_messages.first)
+ end
+ end
+
+ def with(*args, &block)
+ @args_expectation = ArgumentExpectation.new(args, &block)
+ self
+ end
+
+ def exactly(n)
+ set_expected_received_count :exactly, n
+ self
+ end
+
+ def at_least(n)
+ set_expected_received_count :at_least, n
+ self
+ end
+
+ def at_most(n)
+ set_expected_received_count :at_most, n
+ self
+ end
+
+ def times(&block)
+ @method_block = block if block
+ self
+ end
+
+ def any_number_of_times(&block)
+ @method_block = block if block
+ @expected_received_count = :any
+ self
+ end
+
+ def never
+ @expected_received_count = 0
+ self
+ end
+
+ def once(&block)
+ @method_block = block if block
+ @expected_received_count = 1
+ self
+ end
+
+ def twice(&block)
+ @method_block = block if block
+ @expected_received_count = 2
+ self
+ end
+
+ def ordered(&block)
+ @method_block = block if block
+ @order_group.register(self)
+ @ordered = true
+ self
+ end
+
+ def negative_expectation_for?(sym)
+ return false
+ end
+
+ protected
+ def set_expected_received_count(relativity, n)
+ @at_least = (relativity == :at_least)
+ @at_most = (relativity == :at_most)
+ @expected_received_count = case n
+ when Numeric
+ n
+ when :once
+ 1
+ when :twice
+ 2
+ end
+ end
+
+ end
+
+ class NegativeMessageExpectation < MessageExpectation
+ def initialize(message, expectation_ordering, expected_from, sym, method_block)
+ super(message, expectation_ordering, expected_from, sym, method_block, 0)
+ end
+
+ def negative_expectation_for?(sym)
+ return @sym == sym
+ end
+ end
+
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/methods.rb b/vendor/plugins/rspec/lib/spec/mocks/methods.rb
new file mode 100644
index 00000000..d9fa324d
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/methods.rb
@@ -0,0 +1,39 @@
+module Spec
+ module Mocks
+ module Methods
+ def should_receive(sym, opts={}, &block)
+ __mock_proxy.add_message_expectation(opts[:expected_from] || caller(1)[0], sym.to_sym, opts, &block)
+ end
+
+ def should_not_receive(sym, &block)
+ __mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block)
+ end
+
+ def stub!(sym, opts={})
+ __mock_proxy.add_stub(caller(1)[0], sym.to_sym, opts)
+ end
+
+ def received_message?(sym, *args, &block) #:nodoc:
+ __mock_proxy.received_message?(sym.to_sym, *args, &block)
+ end
+
+ def rspec_verify #:nodoc:
+ __mock_proxy.verify
+ end
+
+ def rspec_reset #:nodoc:
+ __mock_proxy.reset
+ end
+
+ private
+
+ def __mock_proxy
+ if Mock === self
+ @mock_proxy ||= Proxy.new(self, @name, @options)
+ else
+ @mock_proxy ||= Proxy.new(self, self.class.name)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/mock.rb b/vendor/plugins/rspec/lib/spec/mocks/mock.rb
new file mode 100644
index 00000000..33549a49
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/mock.rb
@@ -0,0 +1,56 @@
+module Spec
+ module Mocks
+ class Mock
+ include Methods
+
+ # Creates a new mock with a +name+ (that will be used in error messages
+ # only) == Options:
+ # * :null_object - if true, the mock object acts as a forgiving
+ # null object allowing any message to be sent to it.
+ def initialize(name, stubs_and_options={})
+ @name = name
+ @options = parse_options(stubs_and_options)
+ assign_stubs(stubs_and_options)
+ end
+
+ # This allows for comparing the mock to other objects that proxy such as
+ # ActiveRecords belongs_to proxy objects By making the other object run
+ # the comparison, we're sure the call gets delegated to the proxy target
+ # This is an unfortunate side effect from ActiveRecord, but this should
+ # be safe unless the RHS redefines == in a nonsensical manner
+ def ==(other)
+ other == __mock_proxy
+ end
+
+ def method_missing(sym, *args, &block)
+ __mock_proxy.instance_eval {@messages_received << [sym, args, block]}
+ begin
+ return self if __mock_proxy.null_object?
+ super(sym, *args, &block)
+ rescue NameError
+ __mock_proxy.raise_unexpected_message_error sym, *args
+ end
+ end
+
+ def inspect
+ "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>"
+ end
+
+ def to_s
+ inspect.gsub('<','[').gsub('>',']')
+ end
+
+ private
+
+ def parse_options(options)
+ options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {}
+ end
+
+ def assign_stubs(stubs)
+ stubs.each_pair do |message, response|
+ stub!(message).and_return(response)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/order_group.rb b/vendor/plugins/rspec/lib/spec/mocks/order_group.rb
new file mode 100644
index 00000000..9983207e
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/order_group.rb
@@ -0,0 +1,29 @@
+module Spec
+ module Mocks
+ class OrderGroup
+ def initialize error_generator
+ @error_generator = error_generator
+ @ordering = Array.new
+ end
+
+ def register(expectation)
+ @ordering << expectation
+ end
+
+ def ready_for?(expectation)
+ return @ordering.first == expectation
+ end
+
+ def consume
+ @ordering.shift
+ end
+
+ def handle_order_constraint expectation
+ return unless @ordering.include? expectation
+ return consume if ready_for?(expectation)
+ @error_generator.raise_out_of_order_error expectation.sym
+ end
+
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/proxy.rb b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb
new file mode 100644
index 00000000..45b96a30
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb
@@ -0,0 +1,184 @@
+module Spec
+ module Mocks
+ class Proxy
+ DEFAULT_OPTIONS = {
+ :null_object => false,
+ }
+
+ def initialize(target, name, options={})
+ @target = target
+ @name = name
+ @error_generator = ErrorGenerator.new target, name
+ @expectation_ordering = OrderGroup.new @error_generator
+ @expectations = []
+ @messages_received = []
+ @stubs = []
+ @proxied_methods = []
+ @options = options ? DEFAULT_OPTIONS.dup.merge(options) : DEFAULT_OPTIONS
+ end
+
+ def null_object?
+ @options[:null_object]
+ end
+
+ def add_message_expectation(expected_from, sym, opts={}, &block)
+ __add sym
+ @expectations << MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts)
+ @expectations.last
+ end
+
+ def add_negative_message_expectation(expected_from, sym, &block)
+ __add sym
+ @expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil)
+ @expectations.last
+ end
+
+ def add_stub(expected_from, sym, opts={})
+ __add sym
+ @stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts)
+ @stubs.first
+ end
+
+ def verify #:nodoc:
+ verify_expectations
+ ensure
+ reset
+ end
+
+ def reset
+ clear_expectations
+ clear_stubs
+ reset_proxied_methods
+ clear_proxied_methods
+ end
+
+ def received_message?(sym, *args, &block)
+ @messages_received.any? {|array| array == [sym, args, block]}
+ end
+
+ def has_negative_expectation?(sym)
+ @expectations.detect {|expectation| expectation.negative_expectation_for?(sym)}
+ end
+
+ def message_received(sym, *args, &block)
+ if expectation = find_matching_expectation(sym, *args)
+ expectation.invoke(args, block)
+ elsif (stub = find_matching_method_stub(sym, *args))
+ if expectation = find_almost_matching_expectation(sym, *args)
+ expectation.advise(args, block) unless expectation.expected_messages_received?
+ end
+ stub.invoke([], block)
+ elsif expectation = find_almost_matching_expectation(sym, *args)
+ expectation.advise(args, block) if null_object? unless expectation.expected_messages_received?
+ raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(sym) or null_object?)
+ else
+ @target.send :method_missing, sym, *args, &block
+ end
+ end
+
+ def raise_unexpected_message_args_error(expectation, *args)
+ @error_generator.raise_unexpected_message_args_error expectation, *args
+ end
+
+ def raise_unexpected_message_error(sym, *args)
+ @error_generator.raise_unexpected_message_error sym, *args
+ end
+
+ private
+
+ def __add(sym)
+ $rspec_mocks.add(@target) unless $rspec_mocks.nil?
+ define_expected_method(sym)
+ end
+
+ def define_expected_method(sym)
+ visibility_string = "#{visibility(sym)} :#{sym}"
+ if target_responds_to?(sym) && !target_metaclass.method_defined?(munge(sym))
+ munged_sym = munge(sym)
+ target_metaclass.instance_eval do
+ alias_method munged_sym, sym if method_defined?(sym.to_s)
+ end
+ @proxied_methods << sym
+ end
+
+ target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
+ def #{sym}(*args, &block)
+ __mock_proxy.message_received :#{sym}, *args, &block
+ end
+ #{visibility_string}
+ EOF
+ end
+
+ def target_responds_to?(sym)
+ return @target.send(munge(:respond_to?),sym) if @already_proxied_respond_to
+ return @already_proxied_respond_to = true if sym == :respond_to?
+ return @target.respond_to?(sym)
+ end
+
+ def visibility(sym)
+ if Mock === @target
+ 'public'
+ elsif target_metaclass.private_method_defined?(sym)
+ 'private'
+ elsif target_metaclass.protected_method_defined?(sym)
+ 'protected'
+ else
+ 'public'
+ end
+ end
+
+ def munge(sym)
+ "proxied_by_rspec__#{sym.to_s}".to_sym
+ end
+
+ def clear_expectations
+ @expectations.clear
+ end
+
+ def clear_stubs
+ @stubs.clear
+ end
+
+ def clear_proxied_methods
+ @proxied_methods.clear
+ end
+
+ def target_metaclass
+ class << @target; self; end
+ end
+
+ def verify_expectations
+ @expectations.each do |expectation|
+ expectation.verify_messages_received
+ end
+ end
+
+ def reset_proxied_methods
+ @proxied_methods.each do |sym|
+ munged_sym = munge(sym)
+ target_metaclass.instance_eval do
+ if method_defined?(munged_sym.to_s)
+ alias_method sym, munged_sym
+ undef_method munged_sym
+ else
+ undef_method sym
+ end
+ end
+ end
+ end
+
+ def find_matching_expectation(sym, *args)
+ @expectations.find {|expectation| expectation.matches(sym, args)}
+ end
+
+ def find_almost_matching_expectation(sym, *args)
+ @expectations.find {|expectation| expectation.matches_name_but_not_args(sym, args)}
+ end
+
+ def find_matching_method_stub(sym, *args)
+ @stubs.find {|stub| stub.matches(sym, args)}
+ end
+
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/space.rb b/vendor/plugins/rspec/lib/spec/mocks/space.rb
new file mode 100644
index 00000000..3e13224c
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/space.rb
@@ -0,0 +1,28 @@
+module Spec
+ module Mocks
+ class Space
+ def add(obj)
+ mocks << obj unless mocks.detect {|m| m.equal? obj}
+ end
+
+ def verify_all
+ mocks.each do |mock|
+ mock.rspec_verify
+ end
+ end
+
+ def reset_all
+ mocks.each do |mock|
+ mock.rspec_reset
+ end
+ mocks.clear
+ end
+
+ private
+
+ def mocks
+ @mocks ||= []
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb b/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb
new file mode 100644
index 00000000..d92a4ced
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb
@@ -0,0 +1,38 @@
+module Spec
+ module Mocks
+ module ExampleMethods
+ include Spec::Mocks::ArgumentConstraintMatchers
+
+ # Shortcut for creating an instance of Spec::Mocks::Mock.
+ #
+ # +name+ is used for failure reporting, so you should use the
+ # role that the mock is playing in the example.
+ #
+ # +stubs_and_options+ lets you assign options and stub values
+ # at the same time. The only option available is :null_object.
+ # Anything else is treated as a stub value.
+ #
+ # == Examples
+ #
+ # stub_thing = mock("thing", :a => "A")
+ # stub_thing.a == "A" => true
+ #
+ # stub_person = stub("thing", :name => "Joe", :email => "joe@domain.com")
+ # stub_person.name => "Joe"
+ # stub_person.email => "joe@domain.com"
+ def mock(name, stubs_and_options={})
+ Spec::Mocks::Mock.new(name, stubs_and_options)
+ end
+
+ alias :stub :mock
+
+ # Shortcut for creating a mock object that will return itself in response
+ # to any message it receives that it hasn't been explicitly instructed
+ # to respond to.
+ def stub_everything(name = 'stub')
+ mock(name, :null_object => true)
+ end
+
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/rake/spectask.rb b/vendor/plugins/rspec/lib/spec/rake/spectask.rb
new file mode 100644
index 00000000..842e9615
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/rake/spectask.rb
@@ -0,0 +1,227 @@
+#!/usr/bin/env ruby
+
+# Define a task library for running RSpec contexts.
+
+require 'rake'
+require 'rake/tasklib'
+
+module Spec
+ module Rake
+
+ # A Rake task that runs a set of specs.
+ #
+ # Example:
+ #
+ # Spec::Rake::SpecTask.new do |t|
+ # t.warning = true
+ # t.rcov = true
+ # end
+ #
+ # This will create a task that can be run with:
+ #
+ # rake spec
+ #
+ # If rake is invoked with a "SPEC=filename" command line option,
+ # then the list of spec files will be overridden to include only the
+ # filename specified on the command line. This provides an easy way
+ # to run just one spec.
+ #
+ # If rake is invoked with a "SPEC_OPTS=options" command line option,
+ # then the given options will override the value of the +spec_opts+
+ # attribute.
+ #
+ # If rake is invoked with a "RCOV_OPTS=options" command line option,
+ # then the given options will override the value of the +rcov_opts+
+ # attribute.
+ #
+ # Examples:
+ #
+ # rake spec # run specs normally
+ # rake spec SPEC=just_one_file.rb # run just one spec file.
+ # rake spec SPEC_OPTS="--diff" # enable diffing
+ # rake spec RCOV_OPTS="--aggregate myfile.txt" # see rcov --help for details
+ #
+ # Each attribute of this task may be a proc. This allows for lazy evaluation,
+ # which is sometimes handy if you want to defer the evaluation of an attribute value
+ # until the task is run (as opposed to when it is defined).
+ #
+ # This task can also be used to run existing Test::Unit tests and get RSpec
+ # output, for example like this:
+ #
+ # require 'rubygems'
+ # require 'spec/rake/spectask'
+ # Spec::Rake::SpecTask.new do |t|
+ # t.ruby_opts = ['-rtest/unit']
+ # t.spec_files = FileList['test/**/*_test.rb']
+ # end
+ #
+ class SpecTask < ::Rake::TaskLib
+ class << self
+ def attr_accessor(*names)
+ super(*names)
+ names.each do |name|
+ module_eval "def #{name}() evaluate(@#{name}) end" # Allows use of procs
+ end
+ end
+ end
+
+ # Name of spec task. (default is :spec)
+ attr_accessor :name
+
+ # Array of directories to be added to $LOAD_PATH before running the
+ # specs. Defaults to ['before :each
+ # and after the last after :each. The use of these is generally discouraged, because it
+ # introduces dependencies between the examples. Still, it might prove useful for very expensive operations
+ # if you know what you are doing.
+ #
+ # == Local helper methods
+ #
+ # You can include local helper methods by simply expressing them within a context:
+ #
+ # describe "..." do
+ #
+ # it "..." do
+ # helper_method
+ # end
+ #
+ # def helper_method
+ # ...
+ # end
+ #
+ # end
+ #
+ # == Included helper methods
+ #
+ # You can include helper methods in multiple contexts by expressing them within
+ # a module, and then including that module in your context:
+ #
+ # module AccountExampleHelperMethods
+ # def helper_method
+ # ...
+ # end
+ # end
+ #
+ # describe "A new account" do
+ # include AccountExampleHelperMethods
+ # before do
+ # @account = Account.new
+ # end
+ #
+ # it "should have a balance of $0" do
+ # helper_method
+ # @account.balance.should eql(Money.new(0, :dollars))
+ # end
+ # end
+ #
+ # == Shared Example Groups
+ #
+ # You can define a shared Example Group, that may be used on other groups
+ #
+ # share_examples_for "All Editions" do
+ # it "all editions behaviour" ...
+ # end
+ #
+ # describe SmallEdition do
+ # it_should_behave_like "All Editions"
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ #
+ # You can also assign the shared group to a module and include that
+ #
+ # share_as :AllEditions do
+ # it "should do all editions stuff" ...
+ # end
+ #
+ # describe SmallEdition do
+ # it_should_behave_like AllEditions
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ #
+ # And, for those of you who prefer to use something more like Ruby, you
+ # can just include the module directly
+ #
+ # describe SmallEdition do
+ # include AllEditions
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ module Runner
+ class << self
+ def configuration # :nodoc:
+ @configuration ||= Spec::Example::Configuration.new
+ end
+
+ # Use this to configure various configurable aspects of
+ # RSpec:
+ #
+ # Spec::Runner.configure do |configuration|
+ # # Configure RSpec here
+ # end
+ #
+ # The yielded configuration object is a
+ # Spec::Example::Configuration instance. See its RDoc
+ # for details about what you can do with it.
+ #
+ def configure
+ yield configuration
+ end
+
+ def register_at_exit_hook # :nodoc:
+ $spec_runner_at_exit_hook_registered ||= nil
+ unless $spec_runner_at_exit_hook_registered
+ at_exit do
+ unless $! || Spec.run?
+ success = Spec.run
+ exit success if Spec.exit?
+ end
+ end
+ $spec_runner_at_exit_hook_registered = true
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb b/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb
new file mode 100644
index 00000000..587e57d9
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb
@@ -0,0 +1,57 @@
+module Spec
+ module Runner
+ class BacktraceTweaker
+ def clean_up_double_slashes(line)
+ line.gsub!('//','/')
+ end
+ end
+
+ class NoisyBacktraceTweaker < BacktraceTweaker
+ def tweak_backtrace(error)
+ return if error.backtrace.nil?
+ error.backtrace.each do |line|
+ clean_up_double_slashes(line)
+ end
+ end
+ end
+
+ # Tweaks raised Exceptions to mask noisy (unneeded) parts of the backtrace
+ class QuietBacktraceTweaker < BacktraceTweaker
+ unless defined?(IGNORE_PATTERNS)
+ root_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', '..'))
+ spec_files = Dir["#{root_dir}/lib/*"].map do |path|
+ subpath = path[root_dir.length..-1]
+ /#{subpath}/
+ end
+ IGNORE_PATTERNS = spec_files + [
+ /\/lib\/ruby\//,
+ /bin\/spec:/,
+ /bin\/rcov:/,
+ /lib\/rspec-rails/,
+ /vendor\/rails/,
+ # TextMate's Ruby and RSpec plugins
+ /Ruby\.tmbundle\/Support\/tmruby.rb:/,
+ /RSpec\.tmbundle\/Support\/lib/,
+ /temp_textmate\./,
+ /mock_frameworks\/rspec/,
+ /spec_server/
+ ]
+ end
+
+ def tweak_backtrace(error)
+ return if error.backtrace.nil?
+ error.backtrace.collect! do |line|
+ clean_up_double_slashes(line)
+ IGNORE_PATTERNS.each do |ignore|
+ if line =~ ignore
+ line = nil
+ break
+ end
+ end
+ line
+ end
+ error.backtrace.compact!
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/class_and_arguments_parser.rb b/vendor/plugins/rspec/lib/spec/runner/class_and_arguments_parser.rb
new file mode 100644
index 00000000..65dc4519
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/class_and_arguments_parser.rb
@@ -0,0 +1,16 @@
+module Spec
+ module Runner
+ class ClassAndArgumentsParser
+ class << self
+ def parse(s)
+ if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/
+ arg = $2 == "" ? nil : $2
+ [$1, arg]
+ else
+ raise "Couldn't parse #{s.inspect}"
+ end
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/runner/command_line.rb b/vendor/plugins/rspec/lib/spec/runner/command_line.rb
new file mode 100644
index 00000000..9849c485
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/command_line.rb
@@ -0,0 +1,28 @@
+require 'spec/runner/option_parser'
+
+module Spec
+ module Runner
+ # Facade to run specs without having to fork a new ruby process (using `spec ...`)
+ class CommandLine
+ class << self
+ # Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+
+ # and +out+ are the streams output will be written to.
+ def run(instance_rspec_options)
+ # NOTE - this call to init_rspec_options is not spec'd, but neither is any of this
+ # swapping of $rspec_options. That is all here to enable rspec to run against itself
+ # and maintain coverage in a single process. Therefore, DO NOT mess with this stuff
+ # unless you know what you are doing!
+ init_rspec_options(instance_rspec_options)
+ orig_rspec_options = rspec_options
+ begin
+ $rspec_options = instance_rspec_options
+ return $rspec_options.run_examples
+ ensure
+ ::Spec.run = true
+ $rspec_options = orig_rspec_options
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb b/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb
new file mode 100644
index 00000000..911c8689
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb
@@ -0,0 +1,20 @@
+require "drb/drb"
+
+module Spec
+ module Runner
+ # Facade to run specs by connecting to a DRB server
+ class DrbCommandLine
+ # Runs specs on a DRB server. Note that this API is similar to that of
+ # CommandLine - making it possible for clients to use both interchangeably.
+ def self.run(options)
+ begin
+ DRb.start_service
+ spec_server = DRbObject.new_with_uri("druby://127.0.0.1:8989")
+ spec_server.run(options.argv, options.error_stream, options.output_stream)
+ rescue DRb::DRbConnError => e
+ options.error_stream.puts "No server is running"
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb b/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb
new file mode 100644
index 00000000..7275c6a8
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb
@@ -0,0 +1,59 @@
+module Spec
+ module Runner
+ class ExampleGroupRunner
+ def initialize(options)
+ @options = options
+ end
+
+ def load_files(files)
+ # It's important that loading files (or choosing not to) stays the
+ # responsibility of the ExampleGroupRunner. Some implementations (like)
+ # the one using DRb may choose *not* to load files, but instead tell
+ # someone else to do it over the wire.
+ files.each do |file|
+ load file
+ end
+ end
+
+ def run
+ prepare
+ success = true
+ example_groups.each do |example_group|
+ success = success & example_group.run
+ end
+ return success
+ ensure
+ finish
+ end
+
+ protected
+ def prepare
+ reporter.start(number_of_examples)
+ example_groups.reverse! if reverse
+ end
+
+ def finish
+ reporter.end
+ reporter.dump
+ end
+
+ def reporter
+ @options.reporter
+ end
+
+ def reverse
+ @options.reverse
+ end
+
+ def example_groups
+ @options.example_groups
+ end
+
+ def number_of_examples
+ @options.number_of_examples
+ end
+ end
+ # TODO: BT - Deprecate BehaviourRunner?
+ BehaviourRunner = ExampleGroupRunner
+ end
+end
\ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb
new file mode 100644
index 00000000..a1269b51
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb
@@ -0,0 +1,77 @@
+module Spec
+ module Runner
+ module Formatter
+ # Baseclass for formatters that implements all required methods as no-ops.
+ class BaseFormatter
+ attr_accessor :example_group, :options, :where
+ def initialize(options, where)
+ @options = options
+ @where = where
+ end
+
+ # This method is invoked before any examples are run, right after
+ # they have all been collected. This can be useful for special
+ # formatters that need to provide progress on feedback (graphical ones)
+ #
+ # This method will only be invoked once, and the next one to be invoked
+ # is #add_example_group
+ def start(example_count)
+ end
+
+ # This method is invoked at the beginning of the execution of each example_group.
+ # +example_group+ is the example_group.
+ #
+ # The next method to be invoked after this is #example_failed or #example_finished
+ def add_example_group(example_group)
+ @example_group = example_group
+ end
+
+ # This method is invoked when an +example+ starts.
+ def example_started(example)
+ end
+
+ # This method is invoked when an +example+ passes.
+ def example_passed(example)
+ end
+
+ # This method is invoked when an +example+ fails, i.e. an exception occurred
+ # inside it (such as a failed should or other exception). +counter+ is the
+ # sequence number of the failure (starting at 1) and +failure+ is the associated
+ # Failure object.
+ def example_failed(example, counter, failure)
+ end
+
+ # This method is invoked when an example is not yet implemented (i.e. has not
+ # been provided a block), or when an ExamplePendingError is raised.
+ # +message+ is the message from the ExamplePendingError, if it exists, or the
+ # default value of "Not Yet Implemented"
+ def example_pending(example, message)
+ end
+
+ # This method is invoked after all of the examples have executed. The next method
+ # to be invoked after this one is #dump_failure (once for each failed example),
+ def start_dump
+ end
+
+ # Dumps detailed information about an example failure.
+ # This method is invoked for each failed example after all examples have run. +counter+ is the sequence number
+ # of the associated example. +failure+ is a Failure object, which contains detailed
+ # information about the failure.
+ def dump_failure(counter, failure)
+ end
+
+ # This method is invoked after the dumping of examples and failures.
+ def dump_summary(duration, example_count, failure_count, pending_count)
+ end
+
+ # This gets invoked after the summary if option is set to do so.
+ def dump_pending
+ end
+
+ # This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
+ def close
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb
new file mode 100644
index 00000000..bad023db
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb
@@ -0,0 +1,130 @@
+require 'spec/runner/formatter/base_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ # Baseclass for text-based formatters. Can in fact be used for
+ # non-text based ones too - just ignore the +output+ constructor
+ # argument.
+ class BaseTextFormatter < BaseFormatter
+ attr_reader :output, :pending_examples
+ # Creates a new instance that will write to +where+. If +where+ is a
+ # String, output will be written to the File with that name, otherwise
+ # +where+ is exected to be an IO (or an object that responds to #puts and #write).
+ def initialize(options, where)
+ super
+ if where.is_a?(String)
+ @output = File.open(where, 'w')
+ elsif where == STDOUT
+ @output = Kernel
+ def @output.flush
+ STDOUT.flush
+ end
+ else
+ @output = where
+ end
+ @pending_examples = []
+ end
+
+ def example_pending(example, message)
+ @pending_examples << [example.__full_description, message]
+ end
+
+ def dump_failure(counter, failure)
+ @output.puts
+ @output.puts "#{counter.to_s})"
+ @output.puts colourise("#{failure.header}\n#{failure.exception.message}", failure)
+ @output.puts format_backtrace(failure.exception.backtrace)
+ @output.flush
+ end
+
+ def colourise(s, failure)
+ if(failure.expectation_not_met?)
+ red(s)
+ elsif(failure.pending_fixed?)
+ blue(s)
+ else
+ magenta(s)
+ end
+ end
+
+ def dump_summary(duration, example_count, failure_count, pending_count)
+ return if dry_run?
+ @output.puts
+ @output.puts "Finished in #{duration} seconds"
+ @output.puts
+
+ summary = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}"
+ summary << ", #{pending_count} pending" if pending_count > 0
+
+ if failure_count == 0
+ if pending_count > 0
+ @output.puts yellow(summary)
+ else
+ @output.puts green(summary)
+ end
+ else
+ @output.puts red(summary)
+ end
+ @output.flush
+ end
+
+ def dump_pending
+ unless @pending_examples.empty?
+ @output.puts
+ @output.puts "Pending:"
+ @pending_examples.each do |pending_example|
+ @output.puts "#{pending_example[0]} (#{pending_example[1]})"
+ end
+ end
+ @output.flush
+ end
+
+ def close
+ if IO === @output
+ @output.close
+ end
+ end
+
+ def format_backtrace(backtrace)
+ return "" if backtrace.nil?
+ backtrace.map { |line| backtrace_line(line) }.join("\n")
+ end
+
+ protected
+
+ def colour?
+ @options.colour ? true : false
+ end
+
+ def dry_run?
+ @options.dry_run ? true : false
+ end
+
+ def backtrace_line(line)
+ line.sub(/\A([^:]+:\d+)$/, '\\1:')
+ end
+
+ def colour(text, colour_code)
+ return text unless colour? && output_to_tty?
+ "#{colour_code}#{text}\e[0m"
+ end
+
+ def output_to_tty?
+ begin
+ @output == Kernel || @output.tty?
+ rescue NoMethodError
+ false
+ end
+ end
+
+ def green(text); colour(text, "\e[32m"); end
+ def red(text); colour(text, "\e[31m"); end
+ def magenta(text); colour(text, "\e[35m"); end
+ def yellow(text); colour(text, "\e[33m"); end
+ def blue(text); colour(text, "\e[34m"); end
+
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb
new file mode 100644
index 00000000..8d39bc57
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb
@@ -0,0 +1,27 @@
+require 'spec/runner/formatter/base_text_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ class FailingExampleGroupsFormatter < BaseTextFormatter
+ def example_failed(example, counter, failure)
+ if @example_group
+ description_parts = @example_group.description_parts.collect do |description|
+ description =~ /(.*) \(druby.*\)$/ ? $1 : description
+ end
+ @output.puts ::Spec::Example::ExampleGroupMethods.description_text(*description_parts)
+
+ @output.flush
+ @example_group = nil
+ end
+ end
+
+ def dump_failure(counter, failure)
+ end
+
+ def dump_summary(duration, example_count, failure_count, pending_count)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb
new file mode 100644
index 00000000..e3a271c8
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb
@@ -0,0 +1,20 @@
+require 'spec/runner/formatter/base_text_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ class FailingExamplesFormatter < BaseTextFormatter
+ def example_failed(example, counter, failure)
+ @output.puts "#{example_group.description} #{example.description}"
+ @output.flush
+ end
+
+ def dump_failure(counter, failure)
+ end
+
+ def dump_summary(duration, example_count, failure_count, pending_count)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb
new file mode 100644
index 00000000..e5368f2c
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb
@@ -0,0 +1,337 @@
+require 'erb'
+require 'spec/runner/formatter/base_text_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ class HtmlFormatter < BaseTextFormatter
+ include ERB::Util # for the #h method
+
+ def initialize(options, output)
+ super
+ @example_group_number = 0
+ @example_number = 0
+ end
+
+ def method_missing(sym, *args)
+ # no-op
+ end
+
+ # The number of the currently running example_group
+ def example_group_number
+ @example_group_number
+ end
+
+ # The number of the currently running example (a global counter)
+ def example_number
+ @example_number
+ end
+
+ def start(example_count)
+ @example_count = example_count
+
+ @output.puts html_header
+ @output.puts report_header
+ @output.flush
+ end
+
+ def add_example_group(example_group)
+ super
+ @example_group_red = false
+ @example_group_red = false
+ @example_group_number += 1
+ unless example_group_number == 1
+ @output.puts " "
+ @output.puts ""
+ end
+ @output.puts ""
+ @output.puts "
"
+ @output.puts "#{format_backtrace(failure.exception.backtrace)}
"
+ end
+
+ def move_progress
+ @output.puts " "
+ @output.flush
+ end
+
+ def percent_done
+ result = 100.0
+ if @example_count != 0
+ result = ((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0
+ end
+ result
+ end
+
+ def dump_failure(counter, failure)
+ end
+
+ def dump_summary(duration, example_count, failure_count, pending_count)
+ if dry_run?
+ totals = "This was a dry-run"
+ else
+ totals = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}"
+ totals << ", #{pending_count} pending" if pending_count > 0
+ end
+ @output.puts ""
+ @output.puts ""
+ @output.puts ""
+ @output.puts ""
+ @output.puts "#{@snippet_extractor.snippet(failure.exception)}