diff --git a/app/views/notes/_notes.rhtml b/app/views/notes/_notes.rhtml index 3a020010..9391d108 100644 --- a/app/views/notes/_notes.rhtml +++ b/app/views/notes/_notes.rhtml @@ -10,12 +10,13 @@ :title =>"Delete this note", :class=>"delete_item", :id => "delete_note_"+note.id.to_s), - :update => dom_id(note), + {:update => dom_id(note), :loading => visual_effect(:fade, dom_id(note, 'container')), :complete => "Element.remove('#{dom_id(note, 'container')}');", :url => note_path(note), :method => :delete, - :confirm => "Are you sure that you want to delete the note \'#{note.id.to_s}\'?" ) + " " -%> + :confirm => "Are you sure that you want to delete the note \'#{note.id.to_s}\'?" }, + { :class => 'delete_note' }) -%> <%= link_to_function(image_tag( "blank.png", :title => "Edit item", :class=>"edit_item"), "Element.toggle('#{dom_id(note)}'); Element.toggle('#{dom_id(note, 'edit')}'); Effect.Appear('#{dom_id(note, 'edit')}'); Form.focusFirstElement('#{dom_id(note, 'edit_form')}');" ) + " | " %> <%= link_to("In: " + note.project.name, project_path(note.project), :class=>"footer_link" ) %> | diff --git a/config/environment.rb.tmpl b/config/environment.rb.tmpl index c7c7f780..903df142 100644 --- a/config/environment.rb.tmpl +++ b/config/environment.rb.tmpl @@ -97,4 +97,4 @@ end MOBILE_CONTENT_TYPE = 'tracks/mobile' Mime::Type.register(MOBILE_CONTENT_TYPE, :m) -TRACKS_VERSION='1.6' +TRACKS_VERSION='1.7-devel' diff --git a/doc/README_DEVELOPERS b/doc/README_DEVELOPERS index e8f9bde0..5e48875a 100644 --- a/doc/README_DEVELOPERS +++ b/doc/README_DEVELOPERS @@ -12,8 +12,10 @@ To avoid showing the migrations as tests are run, add the following to your data If you want to run tests using another database, that's fine, too. Just change your database.yml accordingly. -3. SELENIUM TESTS +3. SELENIUM TESTS (Selenium on Rails) +This testing style is deprecated and are being moved over to Selenium via RSpec stories by lukemelia (See #4 below for the new style). + To run selenium tests, start Tracks in test mode using script/server -e test @@ -24,4 +26,25 @@ Then open a browser to and interact with the test runner. -For more information about Selenium on Rails, see vendor/plugins/selenium-on-rails/README \ No newline at end of file +For more information about Selenium on Rails, see vendor/plugins/selenium-on-rails/README + +4. RSPEC STORY RUNNER TESTS + +To run the stories, which are browser tests using selenium, start Tracks in test mode using + + rake db:test:prepare + script/server -e test + +Then start Selenium by running + + selenium + +which is a script installed with the Selenium gem (sudo gem install Selenium) + +Once the site and selenium server are running, then run all stories with + + script/story + +or a specific set with + + script/story stories/login/*.story 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..db0c50ca --- /dev/null +++ b/stories/helper.rb @@ -0,0 +1,136 @@ +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' +require 'action_controller/test_process' + +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 should_not_see(text_or_regexp) + if text_or_regexp.is_a?(Regexp) + response.should_not have_tag("*", text_or_regexp) + else + response.should_not have_tag("*", /#{Regexp.escape(text_or_regexp)}/i) + end + end + + def response + webrat_session.response_body + end + + def logged_in_as(user) + visits("/selenium_helper/login?as=#{user.login}") + end + + def selenium + SeleniumDriverManager.instance.running_selenium_driver + end + + def badge_count_should_show(count) + response.should have_tag('#badge_count', count.to_s) + 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 method_missing sym, *args, &block + # ignore all messages you don't care about + end +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 method_missing sym, *args, &block + # ignore all messages you don't care about + end +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/notes/view_add_remove.story b/stories/notes/view_add_remove.story new file mode 100644 index 00000000..34e519fe --- /dev/null +++ b/stories/notes/view_add_remove.story @@ -0,0 +1,41 @@ +Story: View, add, remove notes + + As a Tracks user + I want to view, add, and remove notes + So that I can keep important information easily accessible + + Scenario: View and toggle notes + + Given a logged in user Luis + And Luis has two projects with one note each + When Luis visits the notes page + Then two notes should be visible + And the badge should show 2 + When Luis clicks Toggle Notes + Then the body of the notes should be shown + + Scenario: Add a new note + + Given a logged in user Luis + And Luis has one project Pass Final Exam with no notes + When Luis adds a note from the Pass Final Exam project page + Then Luis should see the note on the Pass Final Exam project page + And Luis should see the note on the notes page + And the badge on the notes page should show 1 + + Scenario: Delete note from notes page + + Given a logged in user Luis + And Luis has one project Pass Final Exam with 2 notes + When Luis visits the notes page + And Luis deletes the first note + Then the first note should disappear + Then the badge should show 1 + + Scenario: Link to note + Given a logged in user Luis + And Luis has one project Pass Final Exam with 1 note + When Luis visits the Pass Final Exam project page + And clicks the icon next to the note + Then he should see the note text + \ No newline at end of file diff --git a/stories/steps/login.rb b/stories/steps/login.rb new file mode 100644 index 00000000..8729a5e8 --- /dev/null +++ b/stories/steps/login.rb @@ -0,0 +1,55 @@ +steps_for :login do + include_steps_for :users + + 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/stories/steps/notes.rb b/stories/steps/notes.rb new file mode 100644 index 00000000..aa17722a --- /dev/null +++ b/stories/steps/notes.rb @@ -0,0 +1,94 @@ +steps_for :notes do + include_steps_for :users + + Given "Luis has two projects with one note each" do + project_a = @luis.projects.create!(:name => 'project A') + project_a.notes.create!(:user_id => @luis.id, :body => 'note for project A') + project_b = @luis.projects.create!(:name => 'project B') + project_b.notes.create!(:user_id => @luis.id, :body => 'note for project B') + end + + Given "Luis has one project Pass Final Exam with no notes" do + @exam_project = @luis.projects.create!(:name => 'Pass Final Exam') + end + + Given "Luis has one project Pass Final Exam with 1 note" do + Given "Luis has one project Pass Final Exam with no notes" + @exam_project.notes.create!(:user_id => @luis.id, :body => 'exam note 1') + end + + Given "Luis has one project Pass Final Exam with 2 notes" do + Given "Luis has one project Pass Final Exam with 1 note" + @exam_project.notes.create!(:user_id => @luis.id, :body => 'exam note 2') + end + + When "Luis visits the notes page" do + visits '/notes' + end + + When "Luis adds a note from the Pass Final Exam project page" do + When "Luis visits the Pass Final Exam project page" + clicks_link 'Add a note', :wait => :ajax + fills_in 'new_note_body', :with => 'new exam note' + clicks_button 'Add note', :wait => :ajax + end + + When "Luis visits the Pass Final Exam project page" do + visits "/projects/#{@exam_project.to_param}" + end + + When "Luis deletes the first note" do + selenium.click "css=a.delete_note" + selenium.get_confirmation.should =~ /delete/ + end + + When "clicks the icon next to the note" do + selenium.click "css=a.link_to_notes" + wait_for_page_to_load + end + + When "Luis clicks Toggle Notes" do + clicks_link 'Toggle notes', :wait => :effects + end + + Then "the body of the notes should be shown" do + wait_for_effects + selenium.is_visible("css=body.notes").should be_true + end + + Then "Luis should see the note on the Pass Final Exam project page" do + should_see "new exam note" + end + + Then "Luis should see the note on the notes page" do + visits '/notes' + should_see "new exam note" + end + + Then "the badge on the notes page should show 1" do + badge_count_should_show(1) + end + + Then "the first note should disappear" do + wait_for_ajax_and_effects + should_not_see 'exam note 1' + end + + Then "the badge should show 1" do + wait_for_ajax_and_effects + badge_count_should_show(1) + end + + Then "the badge should show 2" do + badge_count_should_show(2) + end + + Then "two notes should be visible" do + should_see 'note for project A' + should_see 'note for project B' + end + + Then "he should see the note text" do + should_see 'exam note 1' + end +end \ No newline at end of file diff --git a/stories/steps/users.rb b/stories/steps/users.rb new file mode 100644 index 00000000..834c41d0 --- /dev/null +++ b/stories/steps/users.rb @@ -0,0 +1,30 @@ +steps_for :users 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 "an admin user Reinier" do + Given "an admin user Reinier with the password abracadabra" + end + + Given "a logged in user Luis" do + @luis = User.create!(:login => 'luis', :password => 'sesame', :password_confirmation => 'sesame', :is_admin => false) + @luis.create_preference + logged_in_as @luis + end + + Given "no users exist" do + User.delete_all + end + + Given "Reinier is not logged in" do + #nothing to do + end + + Given "a visitor named Reinier" do + #nothing to do + 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/test/selenium/notes/badge_count.rsel b/test/selenium/notes/badge_count.rsel deleted file mode 100644 index ace3d85d..00000000 --- a/test/selenium/notes/badge_count.rsel +++ /dev/null @@ -1,27 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/notes/" -assert_text 'badge_count', '2' - -# add new note -open "/projects/1" -click "css=#add_note_href" -type "css=#new_note_body", "new note" -click "add-new-note" - -# wait until new note is saved -wait_for_text_not_present "new note" -wait_for_text_present "new note" - -# check badge count is one more -open "/notes/" -assert_text 'badge_count', '3' - -# delete note -click "css=#delete_note_1" -assert_confirmation "Are you sure that you want to delete the note '1'?" - -# check badge decreased -wait_for_visible "flash" -wait_for_element_not_present "container_note_1" -assert_text 'badge_count', '2' diff --git a/test/selenium/notes/link_to_note.rsel b/test/selenium/notes/link_to_note.rsel deleted file mode 100644 index a9a3ae7e..00000000 --- a/test/selenium/notes/link_to_note.rsel +++ /dev/null @@ -1,5 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/projects/1" -click_and_wait "css=#note_1 .link_to_notes" -assert_element_present "note_1" diff --git a/test/selenium/notes/see_all_notes.rsel b/test/selenium/notes/see_all_notes.rsel deleted file mode 100644 index 83b9f52c..00000000 --- a/test/selenium/notes/see_all_notes.rsel +++ /dev/null @@ -1,5 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/notes/" -assert_element_present "note_1" -assert_element_present "note_2" diff --git a/test/selenium/notes/toggle_notes.rsel b/test/selenium/notes/toggle_notes.rsel deleted file mode 100644 index c7551b32..00000000 --- a/test/selenium/notes/toggle_notes.rsel +++ /dev/null @@ -1,5 +0,0 @@ -setup :fixtures => :all -login :as => 'admin' -open "/notes" -click "css=#toggle-notes-nav" -wait_for_element_present "css=body.notes" diff --git a/vendor/plugins/resource_feeder/lib/resource_feeder/atom.rb b/vendor/plugins/resource_feeder/lib/resource_feeder/atom.rb index 315f1d3a..62d15370 100644 --- a/vendor/plugins/resource_feeder/lib/resource_feeder/atom.rb +++ b/vendor/plugins/resource_feeder/lib/resource_feeder/atom.rb @@ -3,6 +3,7 @@ require 'resource_feeder/common' module ResourceFeeder module Atom include ResourceFeeder::Common + include ActionController::Routing extend self def render_atom_feed_for(resources, options = {}) @@ -25,14 +26,14 @@ module ResourceFeeder options[:feed][:title] ||= klass.name.pluralize options[:feed][:id] ||= "tag:#{request.host_with_port}:#{klass.name.pluralize}" - options[:feed][:link] ||= SimplyHelpful::PolymorphicRoutes.polymorphic_url(new_record, options[:url_writer]) + options[:feed][:link] ||= polymorphic_url(new_record, :controller => options[:url_writer]) options[:item][:title] ||= [ :title, :subject, :headline, :name ] options[:item][:description] ||= [ :description, :body, :content ] options[:item][:pub_date] ||= [ :updated_at, :updated_on, :created_at, :created_on ] options[:item][:author] ||= [ :author, :creator ] - resource_link = lambda { |r| SimplyHelpful::PolymorphicRoutes.polymorphic_url(r, options[:url_writer]) } + resource_link = lambda { |r| polymorphic_url(r, :controller => options[:url_writer]) } xml.instruct! xml.feed "xml:lang" => "en-US", "xmlns" => 'http://www.w3.org/2005/Atom' do diff --git a/vendor/plugins/resource_feeder/lib/resource_feeder/rss.rb b/vendor/plugins/resource_feeder/lib/resource_feeder/rss.rb index 1053f427..bcbe7598 100644 --- a/vendor/plugins/resource_feeder/lib/resource_feeder/rss.rb +++ b/vendor/plugins/resource_feeder/lib/resource_feeder/rss.rb @@ -3,6 +3,7 @@ require 'resource_feeder/common' module ResourceFeeder module Rss include ResourceFeeder::Common + include ActionController::Routing extend self def render_rss_feed_for(resources, options = {}) @@ -25,7 +26,7 @@ module ResourceFeeder use_content_encoded = options[:item].has_key?(:content_encoded) options[:feed][:title] ||= klass.name.pluralize - options[:feed][:link] ||= SimplyHelpful::PolymorphicRoutes.polymorphic_url(new_record, options[:url_writer]) + options[:feed][:link] ||= polymorphic_url(new_record, :controller => options[:url_writer]) options[:feed][:language] ||= "en-us" options[:feed][:ttl] ||= "40" @@ -33,7 +34,7 @@ module ResourceFeeder options[:item][:description] ||= [ :description, :body, :content ] options[:item][:pub_date] ||= [ :updated_at, :updated_on, :created_at, :created_on ] - resource_link = lambda { |r| SimplyHelpful::PolymorphicRoutes.polymorphic_url(r, options[:url_writer]) } + resource_link = lambda { |r| polymorphic_url(r, :controller => options[:url_writer]) } rss_root_attributes = { :version => 2.0 } rss_root_attributes.merge!("xmlns:content" => "http://purl.org/rss/1.0/modules/content/") if use_content_encoded 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)}