diff options
39 files changed, 2336 insertions, 0 deletions
diff --git a/vendor/plugins/rspec_on_rails/generators/helpers/rails_identifier.rb b/vendor/plugins/rspec_on_rails/generators/helpers/rails_identifier.rb new file mode 100644 index 000000000..23668568f --- /dev/null +++ b/vendor/plugins/rspec_on_rails/generators/helpers/rails_identifier.rb @@ -0,0 +1,11 @@ +module RailsIdentifier + class << self + def using_legacy_templates? + if ActionView::Base.respond_to?(:handler_for_extension) && + ActionView::Base.handler_for_extension(:erb) == ActionView::TemplateHandlers::ERB + return false + end + true + end + end +end
\ No newline at end of file diff --git a/vendor/plugins/rspec_on_rails/generators/rspec/templates/all_stories.rb b/vendor/plugins/rspec_on_rails/generators/rspec/templates/all_stories.rb new file mode 100644 index 000000000..2e8f46a40 --- /dev/null +++ b/vendor/plugins/rspec_on_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_on_rails/generators/rspec/templates/rcov.opts b/vendor/plugins/rspec_on_rails/generators/rspec/templates/rcov.opts new file mode 100644 index 000000000..baf694c9c --- /dev/null +++ b/vendor/plugins/rspec_on_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_on_rails/generators/rspec/templates/stories_helper.rb b/vendor/plugins/rspec_on_rails/generators/rspec/templates/stories_helper.rb new file mode 100644 index 000000000..da7a13a69 --- /dev/null +++ b/vendor/plugins/rspec_on_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_on_rails/generators/rspec_scaffold/templates/routing_spec.rb b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/routing_spec.rb new file mode 100644 index 000000000..a6da04901 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/generators/rspec_scaffold/templates/routing_spec.rb @@ -0,0 +1,61 @@ +require 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
\ No newline at end of file diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example.rb new file mode 100644 index 000000000..64a72a9db --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example.rb @@ -0,0 +1,47 @@ +dir = File.dirname(__FILE__) + +require 'spec/rails/example/ivar_proxy' +require 'spec/rails/example/assigns_hash_proxy' + +require "spec/rails/example/render_observer" +require "spec/rails/example/rails_example_group" +require "spec/rails/example/model_example_group" +require "spec/rails/example/functional_example_group" +require "spec/rails/example/controller_example_group" +require "spec/rails/example/helper_example_group" +require "spec/rails/example/view_example_group" + +module Spec + module Rails + # Spec::Rails::Example extends Spec::Example (RSpec's core Example module) to provide + # Rails-specific contexts for describing Rails Models, Views, Controllers and Helpers. + # + # == Model Examples + # + # These are the equivalent of unit tests in Rails' built in testing. Ironically (for the traditional TDD'er) these are the only specs that we feel should actually interact with the database. + # + # See Spec::Rails::Example::ModelExampleGroup + # + # == Controller Examples + # + # These align somewhat with functional tests in rails, except that they do not actually render views (though you can force rendering of views if you prefer). Instead of setting expectations about what goes on a page, you set expectations about what templates get rendered. + # + # See Spec::Rails::Example::ControllerExampleGroup + # + # == View Examples + # + # This is the other half of Rails functional testing. View specs allow you to set up assigns and render + # a template. By assigning mock model data, you can specify view behaviour with no dependency on a database + # or your real models. + # + # See Spec::Rails::Example::ViewExampleGroup + # + # == Helper Examples + # + # These let you specify directly methods that live in your helpers. + # + # See Spec::Rails::Example::HelperExampleGroup + module Example + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example/assigns_hash_proxy.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/assigns_hash_proxy.rb new file mode 100644 index 000000000..1d121f70a --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/assigns_hash_proxy.rb @@ -0,0 +1,42 @@ +module Spec + module Rails + module Example + class AssignsHashProxy #:nodoc: + def initialize(object) + @object = object + end + + def [](ivar) + if assigns.include?(ivar.to_s) + assigns[ivar.to_s] + elsif assigns.include?(ivar) + assigns[ivar] + else + nil + end + end + + def []=(ivar, val) + assigns[ivar.to_s] = val + end + + def delete(name) + assigns.delete(name.to_s) + end + + def each(&block) + assigns.each &block + end + + def has_key?(key) + assigns.key?(key.to_s) + end + + protected + def assigns + @object.assigns + end + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example/controller_example_group.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/controller_example_group.rb new file mode 100644 index 000000000..eca06a403 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/controller_example_group.rb @@ -0,0 +1,245 @@ +module Spec + module Rails + module Example + # Controller Examples live in $RAILS_ROOT/spec/controllers/. + # + # Controller Examples use Spec::Rails::Example::ControllerExampleGroup, which supports running specs for + # Controllers in two modes, which represent the tension between the more granular + # testing common in TDD and the more high level testing built into + # rails. BDD sits somewhere in between: we want to a balance between + # specs that are close enough to the code to enable quick fault + # isolation and far enough away from the code to enable refactoring + # with minimal changes to the existing specs. + # + # == Isolation mode (default) + # + # No dependencies on views because none are ever rendered. The + # benefit of this mode is that can spec the controller completely + # independent of the view, allowing that responsibility to be + # handled later, or by somebody else. Combined w/ separate view + # specs, this also provides better fault isolation. + # + # == Integration mode + # + # To run in this mode, include the +integrate_views+ declaration + # in your controller context: + # + # describe ThingController do + # integrate_views + # ... + # + # In this mode, controller specs are run in the same way that + # rails functional tests run - one set of tests for both the + # controllers and the views. The benefit of this approach is that + # you get wider coverage from each spec. Experienced rails + # developers may find this an easier approach to begin with, however + # we encourage you to explore using the isolation mode and revel + # in its benefits. + # + # == Expecting Errors + # + # Rspec on Rails will raise errors that occur in controller actions. + # In contrast, Rails will swallow errors that are raised in controller + # actions and return an error code in the header. If you wish to override + # Rspec and have Rail's default behaviour,tell the controller to use + # rails error handling ... + # + # before(:each) do + # controller.use_rails_error_handling! + # end + # + # When using Rail's error handling, you can expect error codes in headers ... + # + # it "should return an error in the header" do + # response.should be_error + # end + # + # it "should return a 501" do + # response.response_code.should == 501 + # end + # + # it "should return a 501" do + # response.code.should == "501" + # end + class ControllerExampleGroup < FunctionalExampleGroup + class << self + + # Use this to instruct RSpec to render views in your controller examples (Integration Mode). + # + # describe ThingController do + # integrate_views + # ... + # + # See Spec::Rails::Example::ControllerExampleGroup for more information about + # Integration and Isolation modes. + def integrate_views + @integrate_views = true + end + def integrate_views? # :nodoc: + @integrate_views + end + + # You MUST provide a controller_name within the context of + # your controller specs: + # + # describe "ThingController" do + # controller_name :thing + # ... + def controller_name(name) + @controller_class_name = "#{name}_controller".camelize + end + attr_accessor :controller_class_name # :nodoc: + end + + before(:each) do + # Some Rails apps explicitly disable ActionMailer in environment.rb + if defined?(ActionMailer) + @deliveries = [] + ActionMailer::Base.deliveries = @deliveries + end + + unless @controller.class.ancestors.include?(ActionController::Base) + Spec::Expectations.fail_with <<-EOE + You have to declare the controller name in controller specs. For example: + describe "The ExampleController" do + controller_name "example" #invokes the ExampleController + end + EOE + end + @controller.metaclass.class_eval do + def controller_path #:nodoc: + self.class.name.underscore.gsub('_controller', '') + end + include ControllerInstanceMethods + end + @controller.integrate_views! if @integrate_views + @controller.session = session + end + + attr_reader :response, :request, :controller + + def initialize(defined_description, &implementation) #:nodoc: + super + controller_class_name = self.class.controller_class_name + if controller_class_name + @controller_class_name = controller_class_name.to_s + else + @controller_class_name = self.class.described_type.to_s + end + @integrate_views = self.class.integrate_views? + end + + # Uses ActionController::Routing::Routes to generate + # the correct route for a given set of options. + # == Example + # route_for(:controller => 'registrations', :action => 'edit', :id => 1) + # => '/registrations/1;edit' + def route_for(options) + ensure_that_routes_are_loaded + ActionController::Routing::Routes.generate(options) + end + + # Uses ActionController::Routing::Routes to parse + # an incoming path so the parameters it generates can be checked + # == Example + # params_from(:get, '/registrations/1;edit') + # => :controller => 'registrations', :action => 'edit', :id => 1 + def params_from(method, path) + ensure_that_routes_are_loaded + ActionController::Routing::Routes.recognize_path(path, :method => method) + end + + protected + def _controller_ivar_proxy + @controller_ivar_proxy ||= AssignsHashProxy.new @controller + end + + private + def ensure_that_routes_are_loaded + ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty? + end + + module ControllerInstanceMethods #:nodoc: + include Spec::Rails::Example::RenderObserver + + # === render(options = nil, deprecated_status = nil, &block) + # + # This gets added to the controller's singleton meta class, + # allowing Controller Examples to run in two modes, freely switching + # from context to context. + def render(options=nil, deprecated_status=nil, &block) + unless block_given? + unless integrate_views? + @template.metaclass.class_eval do + define_method :file_exists? do + true + end + define_method :render_file do |*args| + @first_render ||= args[0] + end + end + end + end + + if expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_expectation, :render, options) + expect_render_mock_proxy.render(options) + @performed_render = true + else + unless expect_render_mock_proxy.send(:__mock_proxy).send(:find_matching_method_stub, :render, options) + super(options, deprecated_status, &block) + end + end + end + + if self.respond_to?(:should_receive) && self.respond_to?(:stub!) + self.send :alias_method, :orig_should_receive, :should_receive + self.send :alias_method, :orig_stub!, :stub! + def raise_with_disable_message(old_method, new_method) + raise %Q| + controller.#{old_method}(:render) has been disabled because it + can often produce unexpected results. Instead, you should + use the following (before the action): + + controller.#{new_method}(*args) + + See the rdoc for #{new_method} for more information. + | + end + def should_receive(*args) + if args[0] == :render + raise_with_disable_message("should_receive", "expect_render") + else + orig_should_receive(*args) + end + end + def stub!(*args) + if args[0] == :render + raise_with_disable_message("stub!", "stub_render") + else + orig_stub!(*args) + end + end + end + + def response(&block) + # NOTE - we're setting @update for the assert_select_spec - kinda weird, huh? + @update = block + @_response || @response + end + + def integrate_views! + @integrate_views = true + end + + private + + def integrate_views? + @integrate_views + end + end + + Spec::Example::ExampleGroupFactory.register(:controller, self) + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example/functional_example_group.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/functional_example_group.rb new file mode 100644 index 000000000..6f5790cbf --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/functional_example_group.rb @@ -0,0 +1,66 @@ +module Spec + module Rails + module Example + class FunctionalExampleGroup < RailsExampleGroup + include ActionController::TestProcess + include ActionController::Assertions + + attr_reader :request, :response + before(:each) do + @controller_class = Object.path2class @controller_class_name + raise "Can't determine controller class for #{@controller_class_name}" if @controller_class.nil? + + @controller = @controller_class.new + + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + def params + request.parameters + end + + def flash + response.flash + end + + def session + request.session + end + + # :call-seq: + # assigns() + # + # Hash of instance variables to values that are made available to views. + # == Examples + # + # #in thing_controller.rb + # def new + # @thing = Thing.new + # end + # + # #in thing_controller_spec + # get 'new' + # assigns[:registration].should == Thing.new + #-- + # NOTE - Even though docs say only use assigns[:key] format, but allowing assigns(:key) + # in order to avoid breaking old specs. + #++ + def assigns(key = nil) + if key.nil? + @controller.assigns + _controller_ivar_proxy + else + @controller.assigns[key] + _controller_ivar_proxy[key] + end + end + + protected + def _controller_ivar_proxy + @controller_ivar_proxy ||= IvarProxy.new @controller + end + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example/helper_example_group.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/helper_example_group.rb new file mode 100644 index 000000000..10c1ab002 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/helper_example_group.rb @@ -0,0 +1,82 @@ +module Spec + module Rails + module Example + # Helper Specs live in $RAILS_ROOT/spec/helpers/. + # + # Helper Specs use Spec::Rails::Example::HelperExampleGroup, which allows you to + # include your Helper directly in the context and write specs directly + # against its methods. + # + # HelperExampleGroup also includes the standard lot of ActionView::Helpers in case your + # helpers rely on any of those. + # + # == Example + # + # class ThingHelper + # def number_of_things + # Thing.count + # end + # end + # + # describe "ThingHelper example_group" do + # include ThingHelper + # it "should tell you the number of things" do + # Thing.should_receive(:count).and_return(37) + # number_of_things.should == 37 + # end + # end + class HelperExampleGroup < FunctionalExampleGroup + class << self + # The helper name.... + def helper_name(name=nil) + send :include, "#{name}_helper".camelize.constantize + end + end + + # Reverse the load order so that custom helpers which + # are defined last are also loaded last. + ActionView::Base.included_modules.reverse.each do |mod| + include mod if mod.parents.include?(ActionView::Helpers) + end + + before(:all) do + @controller_class_name = 'Spec::Rails::Example::HelperBehaviourController' + end + + before(:each) do + @controller.request = @request + @controller.url = ActionController::UrlRewriter.new @request, {} # url_for + + @flash = ActionController::Flash::FlashHash.new + session['flash'] = @flash + + ActionView::Helpers::AssetTagHelper::reset_javascript_include_default + end + + def flash + @flash + end + + def eval_erb(text) + ERB.new(text).result(binding) + end + + + # TODO: BT - Helper Examples should proxy method_missing to a Rails View instance. + # When that is done, remove this method + def protect_against_forgery? + false + end + + Spec::Example::ExampleGroupFactory.register(:helper, self) + end + + class HelperBehaviourController < ApplicationController #:nodoc: + attr_accessor :request, :url + + # Re-raise errors + def rescue_action(e); raise e; end + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example/ivar_proxy.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/ivar_proxy.rb new file mode 100644 index 000000000..bf9b790b2 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/ivar_proxy.rb @@ -0,0 +1,62 @@ +## +# A wrapper that allows instance variables to be manipulated using +[]+ and +# +[]=+ + +module Spec + module Rails + module Example + class IvarProxy #:nodoc: + + ## + # Wraps +object+ allowing its instance variables to be manipulated. + + def initialize(object) + @object = object + end + + ## + # Retrieves +ivar+ from the wrapped object. + + def [](ivar) + get_variable "@#{ivar}" + end + + ## + # Sets +ivar+ to +val+ on the wrapped object. + + def []=(ivar, val) + set_variable "@#{ivar}", val + end + + def each + @object.instance_variables.each do |variable_full_name| + variable_name = variable_full_name[1...variable_full_name.length] + yield variable_name, get_variable(variable_full_name) + end + end + + def delete(key) + var_name = "@#{key}" + if @object.instance_variables.include?(var_name) + @object.send(:remove_instance_variable, var_name) + else + return nil + end + end + + def has_key?(key) + @object.instance_variables.include?("@#{key}") + end + + protected + def get_variable(name) + @object.instance_variable_get name + end + + def set_variable(name, value) + @object.instance_variable_set name, value + end + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example/model_example_group.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/model_example_group.rb new file mode 100644 index 000000000..3bdab2591 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/model_example_group.rb @@ -0,0 +1,14 @@ +module Spec + module Rails + module Example + # Model examples live in $RAILS_ROOT/spec/models/. + # + # Model examples use Spec::Rails::Example::ModelExampleGroup, which + # provides support for fixtures and some custom expectations via extensions + # to ActiveRecord::Base. + class ModelExampleGroup < RailsExampleGroup + Spec::Example::ExampleGroupFactory.register(:model, self) + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example/rails_example_group.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/rails_example_group.rb new file mode 100644 index 000000000..a3df05ab5 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/rails_example_group.rb @@ -0,0 +1,68 @@ +require 'spec/interop/test' + +ActionView::Base.cache_template_extensions = false + +module Spec + module Rails + module Example + class RailsExampleGroup < Test::Unit::TestCase + # Rails >= r8570 uses setup/teardown_fixtures explicitly + before(:each) do + setup_fixtures if self.respond_to?(:setup_fixtures) + end + after(:each) do + teardown_fixtures if self.respond_to?(:teardown_fixtures) + end + + include Spec::Rails::Matchers + + @@model_id = 1000 + # 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 = {}) + # null = options_and_stubs.delete(:null_object) + # stubs = options_and_stubs + id = @@model_id + @@model_id += 1 + options_and_stubs = { + :id => id, + :to_param => id.to_s, + :new_record? => false, + :errors => stub("errors", :count => 0) + }.merge(options_and_stubs) + m = mock("#{model_class.name}_#{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 + + #-- + # 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 <tt>method=>value</tt> + 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 + Spec::Example::ExampleGroupFactory.default(self) + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example/render_observer.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/render_observer.rb new file mode 100644 index 000000000..285e8b657 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/render_observer.rb @@ -0,0 +1,90 @@ +require 'spec/mocks' + +module Spec + module Rails + module Example + # Provides specialized mock-like behaviour for controller and view examples, + # allowing you to mock or stub calls to render with specific arguments while + # ignoring all other calls. + module RenderObserver + + # Similar to mocking +render+ with the exception that calls to +render+ with + # any other options are passed on to the receiver (i.e. controller in + # controller examples, template in view examples). + # + # This is necessary because Rails uses the +render+ method on both + # controllers and templates as a dispatcher to render different kinds of + # things, sometimes resulting in many calls to the render method within one + # request. This approach makes it impossible to use a normal mock object, which + # is designed to observe all incoming messages with a given name. + # + # +expect_render+ is auto-verifying, so failures will be reported without + # requiring you to explicitly request verification. + # + # Also, +expect_render+ uses parts of RSpec's mock expectation framework. Because + # it wraps only a subset of the framework, using this will create no conflict with + # other mock frameworks if you choose to use them. Additionally, the object returned + # by expect_render is an RSpec mock object, which means that you can call any of the + # chained methods available in RSpec's mocks. + # + # == Controller Examples + # + # controller.expect_render(:partial => 'thing', :object => thing) + # controller.expect_render(:partial => 'thing', :collection => things).once + # + # controller.stub_render(:partial => 'thing', :object => thing) + # controller.stub_render(:partial => 'thing', :collection => things).twice + # + # == View Examples + # + # template.expect_render(:partial => 'thing', :object => thing) + # template.expect_render(:partial => 'thing', :collection => things) + # + # template.stub_render(:partial => 'thing', :object => thing) + # template.stub_render(:partial => 'thing', :collection => things) + # + def expect_render(opts={}) + register_verify_after_each + expect_render_mock_proxy.should_receive(:render, :expected_from => caller(1)[0]).with(opts) + end + + # This is exactly like expect_render, with the exception that the call to render will not + # be verified. Use this if you are trying to isolate your example from a complicated render + # operation but don't care whether it is called or not. + def stub_render(opts={}) + register_verify_after_each + expect_render_mock_proxy.stub!(:render, :expected_from => caller(1)[0]).with(opts) + end + + def verify_rendered # :nodoc: + expect_render_mock_proxy.rspec_verify + end + + def unregister_verify_after_each #:nodoc: + proc = verify_rendered_proc + Spec::Example::ExampleGroup.remove_after(:each, &proc) + end + + protected + + def verify_rendered_proc #:nodoc: + template = self + @verify_rendered_proc ||= Proc.new do + template.verify_rendered + template.unregister_verify_after_each + end + end + + def register_verify_after_each #:nodoc: + proc = verify_rendered_proc + Spec::Example::ExampleGroup.after(:each, &proc) + end + + def expect_render_mock_proxy #:nodoc: + @expect_render_mock_proxy ||= Spec::Mocks::Mock.new("expect_render_mock_proxy") + end + + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/example/view_example_group.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/view_example_group.rb new file mode 100644 index 000000000..d7b567448 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/example/view_example_group.rb @@ -0,0 +1,172 @@ +module Spec + module Rails + module Example + # View Examples live in $RAILS_ROOT/spec/views/. + # + # View Specs use Spec::Rails::Example::ViewExampleGroup, + # which provides access to views without invoking any of your controllers. + # See Spec::Rails::Expectations::Matchers for information about specific + # expectations that you can set on views. + # + # == Example + # + # describe "login/login" do + # before do + # render 'login/login' + # end + # + # it "should display login form" do + # response.should have_tag("form[action=/login]") do + # with_tag("input[type=text][name=email]") + # with_tag("input[type=password][name=password]") + # with_tag("input[type=submit][value=Login]") + # end + # end + # end + class ViewExampleGroup < FunctionalExampleGroup + before(:each) do + ensure_that_flash_and_session_work_properly + end + + def initialize(defined_description, &implementation) #:nodoc: + super + @controller_class_name = "Spec::Rails::Example::ViewExampleGroupController" + end + + def ensure_that_flash_and_session_work_properly #:nodoc: + @controller.send :initialize_template_class, @response + @controller.send :assign_shortcuts, @request, @response + @session = @controller.session + @controller.class.send :public, :flash + end + + def teardown #:nodoc: + super + ensure_that_base_view_path_is_not_set_across_example_groups + end + + def ensure_that_base_view_path_is_not_set_across_example_groups #:nodoc: + ActionView::Base.base_view_path = nil + end + + def set_base_view_path(options) #:nodoc: + ActionView::Base.base_view_path = base_view_path(options) + end + + def base_view_path(options) #:nodoc: + "/#{derived_controller_name(options)}/" + end + + def derived_controller_name(options) #:nodoc: + parts = subject_of_render(options).split('/').reject { |part| part.empty? } + "#{parts[0..-2].join('/')}" + end + + def derived_action_name(options) #:nodoc: + parts = subject_of_render(options).split('/').reject { |part| part.empty? } + "#{parts.last}" + end + + def subject_of_render(options) #:nodoc: + [:template, :partial, :file].each do |render_type| + if options.has_key?(render_type) + return options[render_type] + end + end + raise Exception.new("Unhandled render type in view spec.") + end + + def add_helpers(options) #:nodoc: + @controller.add_helper("application") + @controller.add_helper(derived_controller_name(options)) + @controller.add_helper(options[:helper]) if options[:helper] + options[:helpers].each { |helper| @controller.add_helper(helper) } if options[:helpers] + end + + # Renders a template for a View Spec, which then provides access to the result + # through the +response+. + # + # == Examples + # + # render('/people/list') + # render('/people/list', :helper => MyHelper) + # render('/people/list', :helpers => [MyHelper, MyOtherHelper]) + # render(:partial => '/people/_address') + # + # See Spec::Rails::Example::ViewExampleGroup for more information. + def render(*args) + options = Hash === args.last ? args.pop : {} + options[:template] = args.first.to_s unless args.empty? + + set_base_view_path(options) + add_helpers(options) + + assigns[:action_name] = @action_name + + @request.path_parameters = { + :controller => derived_controller_name(options), + :action => derived_action_name(options) + } + + defaults = { :layout => false } + options = defaults.merge options + + @controller.instance_variable_set :@params, @request.parameters + + @controller.send :initialize_current_url + + @controller.class.instance_eval %{ + def controller_path + "#{derived_controller_name(options)}" + end + + def controller_name + "#{derived_controller_name(options).split('/').last}" + end + } + + @controller.send :forget_variables_added_to_assigns + @controller.send :render, options + @controller.send :process_cleanup + end + + # This provides the template. Use this to set mock + # expectations for dealing with partials + # + # == Example + # + # describe "/person/new" do + # it "should use the form partial" do + # template.should_receive(:render).with(:partial => 'form') + # render "/person/new" + # end + # end + def template + @controller.template + end + + Spec::Example::ExampleGroupFactory.register(:view, self) + end + + class ViewExampleGroupController < ApplicationController #:nodoc: + include Spec::Rails::Example::RenderObserver + attr_reader :template + + def add_helper_for(template_path) + add_helper(template_path.split('/')[0]) + end + + def add_helper(name) + begin + helper_module = "#{name}_helper".camelize.constantize + rescue + return + end + template.metaclass.class_eval do + include helper_module + end + end + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/example/configuration.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/example/configuration.rb new file mode 100644 index 000000000..06e322637 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/example/configuration.rb @@ -0,0 +1,66 @@ +require 'spec/example/configuration' + +module Spec + module Example + class Configuration + # Rails 1.2.3 does a copy of the @inheritable_attributes to the subclass when the subclass is + # created. This causes an ordering issue when setting state on Configuration because the data is + # already copied. + # Iterating over EXAMPLE_GROUP_CLASSES causes the base ExampleGroup classes to have their + # @inheritable_attributes updated. + # TODO: BT - When we no longer support Rails 1.2.3, we can remove this functionality + EXAMPLE_GROUP_CLASSES = [ + ::Test::Unit::TestCase, + ::Spec::Rails::Example::RailsExampleGroup, + ::Spec::Rails::Example::FunctionalExampleGroup, + ::Spec::Rails::Example::ControllerExampleGroup, + ::Spec::Rails::Example::ViewExampleGroup, + ::Spec::Rails::Example::HelperExampleGroup, + ::Spec::Rails::Example::ModelExampleGroup + ] + # All of this is ActiveRecord related and makes no sense if it's not used by the app + if defined?(ActiveRecord::Base) + def initialize + super + self.fixture_path = RAILS_ROOT + '/spec/fixtures' + end + + def use_transactional_fixtures + Test::Unit::TestCase.use_transactional_fixtures + end + def use_transactional_fixtures=(value) + EXAMPLE_GROUP_CLASSES.each do |example_group| + example_group.use_transactional_fixtures = value + end + end + + def use_instantiated_fixtures + Test::Unit::TestCase.use_instantiated_fixtures + end + def use_instantiated_fixtures=(value) + EXAMPLE_GROUP_CLASSES.each do |example_group| + example_group.use_instantiated_fixtures = value + end + end + + def fixture_path + Test::Unit::TestCase.fixture_path + end + def fixture_path=(path) + EXAMPLE_GROUP_CLASSES.each do |example_group| + example_group.fixture_path = path + end + end + + def global_fixtures + ::Test::Unit::TestCase.fixture_table_names + end + def global_fixtures=(fixtures) + EXAMPLE_GROUP_CLASSES.each do |example_group| + example_group.fixtures(*fixtures) + end + end + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/matchers/have.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/matchers/have.rb new file mode 100644 index 000000000..dc01e4009 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/lib/spec/rails/extensions/spec/matchers/have.rb @@ -0,0 +1,21 @@ +require 'spec/matchers/have' + +module Spec #:nodoc: + module Matchers #:nodoc: + class Have #:nodoc: + alias_method :__original_failure_message, :failure_message + def failure_message + return "expected #{relativities[@relativity]}#{@expected} errors on :#{@args[0]}, got #{@actual}" if @collection_name == :errors_on + return "expected #{relativities[@relativity]}#{@expected} error on :#{@args[0]}, got #{@actual}" if @collection_name == :error_on + return __original_failure_message + end + + alias_method :__original_description, :description + def description + return "should have #{relativities[@relativity]}#{@expected} errors on :#{@args[0]}" if @collection_name == :errors_on + return "should have #{relativities[@relativity]}#{@expected} error on :#{@args[0]}" if @collection_name == :error_on + return __original_description + end + end + end +end diff --git a/vendor/plugins/rspec_on_rails/lib/spec/rails/story_adapter.rb b/vendor/plugins/rspec_on_rails/lib/spec/rails/story_adapter.rb new file mode 100644 index 000000000..66124afe4 --- /dev/null +++ b/vendor/plugins/rspec_on_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_on_rails/spec/rails/example/assigns_hash_proxy_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/assigns_hash_proxy_spec.rb new file mode 100644 index 000000000..400fb829d --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/example/assigns_hash_proxy_spec.rb @@ -0,0 +1,55 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +describe "An 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 +end diff --git a/vendor/plugins/rspec_on_rails/spec/rails/example/configuration_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/configuration_spec.rb new file mode 100644 index 000000000..91a1b265c --- /dev/null +++ b/vendor/plugins/rspec_on_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_on_rails/spec/rails/example/controller_isolation_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/controller_isolation_spec.rb new file mode 100644 index 000000000..204db15d6 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/example/controller_isolation_spec.rb @@ -0,0 +1,43 @@ +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 + lambda { get 'some_action' }.should raise_error(ActionController::MissingTemplate) + 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 +end diff --git a/vendor/plugins/rspec_on_rails/spec/rails/example/controller_spec_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/controller_spec_spec.rb new file mode 100644 index 000000000..3cc861d83 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/example/controller_spec_spec.rb @@ -0,0 +1,179 @@ +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 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 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_with_template' + 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 + get 'action_with_template' + session[:session_key].should == "session value" + 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 + 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 + +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_on_rails/spec/rails/example/example_group_factory_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/example_group_factory_spec.rb new file mode 100644 index 000000000..0803c2f29 --- /dev/null +++ b/vendor/plugins/rspec_on_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_on_rails/spec/rails/example/helper_spec_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/helper_spec_spec.rb new file mode 100644 index 000000000..50defecc5 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/example/helper_spec_spec.rb @@ -0,0 +1,118 @@ +require File.dirname(__FILE__) + '/../../spec_helper' +Spec::Runner.configuration.global_fixtures = :people + +describe ExplicitHelper, :type => :helper do + it "should not require naming the helper if describe is passed a type" do + 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 "should have direct access to methods defined in helpers" do + 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" + end + + it "should fail if the helper method deson't exist" do + lambda { non_existant_helper_method }.should raise_error(NameError) + 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 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) + 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 + 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_on_rails/spec/rails/example/ivar_proxy_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/ivar_proxy_spec.rb new file mode 100644 index 000000000..af6729333 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/example/ivar_proxy_spec.rb @@ -0,0 +1,64 @@ +require File.dirname(__FILE__) + '/../../spec_helper' + +describe "IvarProxy setup", :shared => true do + before do + @object = Object.new + @proxy = Spec::Rails::Example::IvarProxy.new(@object) + end +end + +describe "IvarProxy" do + it_should_behave_like "IvarProxy setup" + + it "has [] accessor" do + @proxy['foo'] = 'bar' + @object.instance_variable_get(:@foo).should == 'bar' + @proxy['foo'].should == 'bar' + end + + it "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 "detects the presence of a key" do + @proxy['foo'] = 'bar' + @proxy.has_key?('foo').should == true + @proxy.has_key?('bar').should == false + end +end + +describe "IvarProxy", "#delete" do + it_should_behave_like "IvarProxy setup" + + it "deletes the element with key" do + @proxy['foo'] = 'bar' + @proxy.delete('foo').should == 'bar' + @proxy['foo'].should be_nil + end + + it "deletes nil instance variables" do + @proxy['foo'] = nil + @object.instance_variables.should include("@foo") + @proxy.delete('foo').should == nil + @proxy['foo'].should be_nil + @object.instance_variables.should_not include("@foo") + end + + it "returns nil when key does not exist" do + @proxy['foo'].should be_nil + @proxy.delete('foo').should == nil + @proxy['foo'].should be_nil + end +end diff --git a/vendor/plugins/rspec_on_rails/spec/rails/example/model_spec_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/model_spec_spec.rb new file mode 100644 index 000000000..938744dbb --- /dev/null +++ b/vendor/plugins/rspec_on_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_on_rails/spec/rails/example/shared_behaviour_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/shared_behaviour_spec.rb new file mode 100644 index 000000000..ef19817d8 --- /dev/null +++ b/vendor/plugins/rspec_on_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_on_rails/spec/rails/example/test_unit_assertion_accessibility_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/test_unit_assertion_accessibility_spec.rb new file mode 100644 index 000000000..b7a838691 --- /dev/null +++ b/vendor/plugins/rspec_on_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_on_rails/spec/rails/example/view_spec_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/example/view_spec_spec.rb new file mode 100644 index 000000000..17e47eee8 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/example/view_spec_spec.rb @@ -0,0 +1,249 @@ +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 +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 + +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 + end + end + end +end
\ No newline at end of file diff --git a/vendor/plugins/rspec_on_rails/spec/rails/matchers/have_text_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/matchers/have_text_spec.rb new file mode 100644 index 000000000..93a1ef059 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/matchers/have_text_spec.rb @@ -0,0 +1,62 @@ +require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') + +describe "have_text" do + + describe "where target is a Regexp" do + it 'should should match submitted text using a regexp' do + string = 'foo' + string.should have_text(/fo*/) + end + end + + describe "where target is a String" do + it 'should match submitted text using a string' do + string = 'foo' + string.should have_text('foo') + end + end + +end + +describe "have_text", + :type => :controller do + ['isolation','integration'].each do |mode| + if mode == 'integration' + integrate_views + end + + describe "where target is a response (in #{mode} mode)" do + controller_name :render_spec + + it "should pass with exactly matching text" do + post 'text_action' + response.should have_text("this is the text for this action") + end + + it "should pass with matching text (using Regexp)" do + post 'text_action' + response.should have_text(/is the text/) + end + + it "should fail with matching text" do + post 'text_action' + lambda { + response.should have_text("this is NOT the text for this action") + }.should fail_with("expected \"this is NOT the text for this action\", got \"this is the text for this action\"") + end + + it "should fail when a template is rendered" do + post 'some_action' + lambda { + response.should have_text("this is the text for this action") + }.should fail_with(/expected \"this is the text for this action\", got .*/) + end + + it "should pass using should_not with incorrect text" do + post 'text_action' + response.should_not have_text("the accordian guy") + end + end + end +end + diff --git a/vendor/plugins/rspec_on_rails/spec/rails/sample_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/sample_spec.rb new file mode 100644 index 000000000..7cd1d4e81 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/sample_spec.rb @@ -0,0 +1,7 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe "A sample spec" do + it "should pass" do + true.should === true + end +end
\ No newline at end of file diff --git a/vendor/plugins/rspec_on_rails/spec/rails/spec_server_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/spec_server_spec.rb new file mode 100644 index 000000000..957bd1089 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/spec_server_spec.rb @@ -0,0 +1,89 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe "script/spec_server file", :shared => true do + attr_accessor :tmbundle_install_directory + + after do + system "kill -9 #{@pid}" + end + + it "runs a spec" do + dir = File.dirname(__FILE__) + output = "" + Timeout.timeout(10) do + loop do + output = `#{RAILS_ROOT}/script/spec #{dir}/sample_spec.rb --drb 2>&1` + break unless output.include?("No server is running") + end + end + + unless $?.exitstatus == 0 + flunk "command 'script/spec spec/sample_spec' failed\n#{output}" + end + end + + def start_spec_server + create_spec_server_pid_file + start_spec_server_process + end + + def create_spec_server_pid_file + current_dir = File.dirname(__FILE__) + pid_dir = "#{Dir.tmpdir}/#{Time.now.to_i}" + @spec_server_pid_file = "#{pid_dir}/spec_server.pid" + FileUtils.mkdir_p pid_dir + system "touch #{@spec_server_pid_file}" + @rspec_path = File.expand_path("#{current_dir}/../../../rspec/lib") + end + + def start_spec_server_process + dir = File.dirname(__FILE__) + spec_server_cmd = %Q|export HOME=#{Dir.tmpdir}; | + spec_server_cmd << %Q|ruby -e 'system("echo " + Process.pid.to_s + " > #{@spec_server_pid_file}"); | + spec_server_cmd << %Q|$LOAD_PATH.unshift("#{@rspec_path}"); require "spec"; | + spec_server_cmd << %Q|load "#{RAILS_ROOT}/script/spec_server"' &| + system spec_server_cmd + + file_content = "" + Timeout.timeout(5) do + loop do + file_content = File.read(@spec_server_pid_file) + break unless file_content.blank? + end + end + @pid = Integer(File.read(@spec_server_pid_file)) + end +end + +describe "script/spec_server file without TextMate bundle" do + it_should_behave_like "script/spec_server file" + before do + start_spec_server + end +end + +describe "script/spec_server file with TextMate bundle" do + it_should_behave_like "script/spec_server file" + before do + dir = File.dirname(__FILE__) + @tmbundle_install_directory = File.expand_path("#{Dir.tmpdir}/Library/Application Support/TextMate/Bundles") + @bundle_name = "RSpec.tmbundle" + FileUtils.mkdir_p(tmbundle_install_directory) + bundle_dir = File.expand_path("#{dir}/../../../../../../#{@bundle_name}") + File.directory?(bundle_dir).should be_true + unless system(%Q|ln -s #{bundle_dir} "#{tmbundle_install_directory}"|) + raise "Creating link to Textmate Bundle" + end + start_spec_server + end + + after do + bundle_file_to_remove = "#{tmbundle_install_directory}/#{@bundle_name}" + if bundle_file_to_remove == "/" + raise "bundle file path resolved to '/' - could not call rm" + end + unless system(%Q|rm "#{bundle_file_to_remove}"|) + raise "Removing Textmate bundle link failed" + end + end +end diff --git a/vendor/plugins/rspec_on_rails/spec/rails/spec_spec.rb b/vendor/plugins/rspec_on_rails/spec/rails/spec_spec.rb new file mode 100644 index 000000000..ea258c7d8 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails/spec_spec.rb @@ -0,0 +1,11 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +describe "script/spec file" do + it "should run a spec" do + dir = File.dirname(__FILE__) + output = `#{RAILS_ROOT}/script/spec #{dir}/sample_spec.rb` + unless $?.exitstatus == 0 + flunk "command 'script/spec spec/sample_spec' failed\n#{output}" + end + end +end
\ No newline at end of file diff --git a/vendor/plugins/rspec_on_rails/spec/rails_suite.rb b/vendor/plugins/rspec_on_rails/spec/rails_suite.rb new file mode 100644 index 000000000..15effae1c --- /dev/null +++ b/vendor/plugins/rspec_on_rails/spec/rails_suite.rb @@ -0,0 +1,7 @@ +dir = File.dirname(__FILE__) +Dir["#{dir}/**/*_example.rb"].each do |file| + require file +end +Dir["#{dir}/**/*_spec.rb"].each do |file| + require file +end diff --git a/vendor/plugins/rspec_on_rails/stories/all.rb b/vendor/plugins/rspec_on_rails/stories/all.rb new file mode 100644 index 000000000..7e55f8afa --- /dev/null +++ b/vendor/plugins/rspec_on_rails/stories/all.rb @@ -0,0 +1,10 @@ +require File.join(File.dirname(__FILE__), *%w[helper]) +require File.join(File.dirname(__FILE__), *%w[steps people]) + +# Run transactions_should_rollback in Ruby +require File.join(File.dirname(__FILE__), *%w[transactions_should_rollback]) + +# Run transactions_should_rollback in Plain Text +with_steps_for :people do + run File.join(File.dirname(__FILE__), *%w[transactions_should_rollback]), :type => RailsStory +end
\ No newline at end of file diff --git a/vendor/plugins/rspec_on_rails/stories/helper.rb b/vendor/plugins/rspec_on_rails/stories/helper.rb new file mode 100644 index 000000000..50c6ee694 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/stories/helper.rb @@ -0,0 +1,5 @@ +dir = File.dirname(__FILE__) +$LOAD_PATH.unshift File.expand_path("#{dir}/../lib") +require File.expand_path("#{dir}/../../../../spec/spec_helper") + +require 'spec/rails/story_adapter'
\ No newline at end of file diff --git a/vendor/plugins/rspec_on_rails/stories/steps/people.rb b/vendor/plugins/rspec_on_rails/stories/steps/people.rb new file mode 100644 index 000000000..a3bf25e9e --- /dev/null +++ b/vendor/plugins/rspec_on_rails/stories/steps/people.rb @@ -0,0 +1,8 @@ +steps_for :people do + When "I add a Person" do + Person.create!(:name => "Foo") + end + Then "there should be one person" do + Person.count.should == 1 + end +end
\ No newline at end of file diff --git a/vendor/plugins/rspec_on_rails/stories/transactions_should_rollback b/vendor/plugins/rspec_on_rails/stories/transactions_should_rollback new file mode 100644 index 000000000..9367676a4 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/stories/transactions_should_rollback @@ -0,0 +1,15 @@ +Story: transactions should rollback in plain text + As an RSpec/Rails Story author + I want transactions to roll back between scenarios in plain text + So that I can have confidence in the state of the database + + Scenario: add one Person + When I add a Person + + Scenario: add another person + GivenScenario: add one Person + Then there should be one person + + Scenario: add yet another person + GivenScenario: add one Person + Then there should be one person diff --git a/vendor/plugins/rspec_on_rails/stories/transactions_should_rollback.rb b/vendor/plugins/rspec_on_rails/stories/transactions_should_rollback.rb new file mode 100644 index 000000000..3e2bdda75 --- /dev/null +++ b/vendor/plugins/rspec_on_rails/stories/transactions_should_rollback.rb @@ -0,0 +1,25 @@ +require File.join(File.dirname(__FILE__), *%w[helper]) + +Story "transactions should rollback", %{ + As an RSpec/Rails Story author + I want transactions to roll back between scenarios + So that I can have confidence in the state of the database +}, :type => RailsStory do + Scenario "add one Person" do + When "I add a Person" do + Person.create!(:name => "Foo") + end + end + + Scenario "add another person" do + GivenScenario "add one Person" + Then "there should be one person" do + Person.count.should == 1 + end + end + + Scenario "add yet another person" do + GivenScenario "add one Person" + Then "there should be one person" + end +end
\ No newline at end of file |