aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/plugins/rspec/lib
diff options
context:
space:
mode:
authorfrancis <francis>2008-09-04 06:10:25 +0000
committerfrancis <francis>2008-09-04 06:10:25 +0000
commit5bde1025dc4d43ea53f63107b88711ebf8942408 (patch)
tree962c8b1fb32186fbd1ab15050ede8e560d9a63f6 /vendor/plugins/rspec/lib
parentce2cf5ed73d81180e9f88d590daaa23989ee9472 (diff)
rspec for rails 2.1
Diffstat (limited to 'vendor/plugins/rspec/lib')
-rw-r--r--vendor/plugins/rspec/lib/autotest/rspec.rb62
-rw-r--r--vendor/plugins/rspec/lib/spec.rb7
-rw-r--r--vendor/plugins/rspec/lib/spec/example.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/example/configuration.rb46
-rw-r--r--vendor/plugins/rspec/lib/spec/example/example_group.rb3
-rw-r--r--vendor/plugins/rspec/lib/spec/example/example_group_factory.rb44
-rw-r--r--vendor/plugins/rspec/lib/spec/example/example_group_methods.rb37
-rw-r--r--vendor/plugins/rspec/lib/spec/example/example_methods.rb10
-rw-r--r--vendor/plugins/rspec/lib/spec/example/module_inclusion_warnings.rb37
-rw-r--r--vendor/plugins/rspec/lib/spec/expectations/differs/default.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb16
-rw-r--r--vendor/plugins/rspec/lib/spec/expectations/handler.rb8
-rwxr-xr-xvendor/plugins/rspec/lib/spec/extensions.rb1
-rw-r--r--vendor/plugins/rspec/lib/spec/extensions/metaclass.rb7
-rwxr-xr-xvendor/plugins/rspec/lib/spec/extensions/object.rb4
-rw-r--r--vendor/plugins/rspec/lib/spec/interop/test.rb4
-rw-r--r--vendor/plugins/rspec/lib/spec/interop/test/unit/ui/console/testrunner.rb1
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/change.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/has.rb12
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/raise_error.rb95
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb6
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb26
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/extensions.rb1
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/framework.rb15
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb34
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/mock.rb16
-rw-r--r--vendor/plugins/rspec/lib/spec/mocks/proxy.rb38
-rw-r--r--vendor/plugins/rspec/lib/spec/rake/spectask.rb10
-rw-r--r--vendor/plugins/rspec/lib/spec/runner.rb14
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb5
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb4
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb12
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb32
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/nested_text_formatter.rb65
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb4
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb6
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb3
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb30
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/option_parser.rb70
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/options.rb118
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/reporter.rb26
-rw-r--r--vendor/plugins/rspec/lib/spec/runner/spec_parser.rb80
-rw-r--r--vendor/plugins/rspec/lib/spec/story/extensions/regexp.rb4
-rw-r--r--vendor/plugins/rspec/lib/spec/story/extensions/string.rb4
-rw-r--r--vendor/plugins/rspec/lib/spec/story/runner.rb16
-rw-r--r--vendor/plugins/rspec/lib/spec/story/runner/plain_text_story_runner.rb4
-rw-r--r--vendor/plugins/rspec/lib/spec/story/runner/scenario_runner.rb8
-rw-r--r--vendor/plugins/rspec/lib/spec/story/runner/story_mediator.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/story/runner/story_runner.rb4
-rw-r--r--vendor/plugins/rspec/lib/spec/story/step.rb20
-rw-r--r--vendor/plugins/rspec/lib/spec/story/story.rb19
-rw-r--r--vendor/plugins/rspec/lib/spec/story/world.rb2
-rw-r--r--vendor/plugins/rspec/lib/spec/version.rb44
56 files changed, 742 insertions, 406 deletions
diff --git a/vendor/plugins/rspec/lib/autotest/rspec.rb b/vendor/plugins/rspec/lib/autotest/rspec.rb
index cf7421ee1..164f298f5 100644
--- a/vendor/plugins/rspec/lib/autotest/rspec.rb
+++ b/vendor/plugins/rspec/lib/autotest/rspec.rb
@@ -18,35 +18,18 @@ end
class RspecCommandError < StandardError; end
class Autotest::Rspec < Autotest
-
- def tests_for_file(filename)
- super.select { |f| @files.has_key? f }
- end
-
- alias :specs_for_file :tests_for_file
-
- def failed_results(results)
- results.scan(/^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m)
- end
- def handle_results(results)
- @files_to_test = consolidate_failures failed_results(results)
- unless @files_to_test.empty? then
- hook :red
- else
- hook :green
- end unless $TESTING
- @tainted = true unless @files_to_test.empty?
+ def initialize
+ super
+ self.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m
+ self.completed_re = /\n(?:\e\[\d*m)?\d* examples?/m
end
-
+
def consolidate_failures(failed)
- filters = Hash.new { |h,k| h[k] = [] }
- failed.each do |spec, failed_trace|
- @files.keys.select{|f| f =~ /spec\//}.each do |f|
- if failed_trace =~ Regexp.new(f)
- filters[f] << spec
- break
- end
+ filters = new_hash_of_arrays
+ failed.each do |spec, trace|
+ if trace =~ /\n(\.\/)?(.*\.rb):[\d]+:\Z?/
+ filters[$2] << spec
end
end
return filters
@@ -56,23 +39,25 @@ class Autotest::Rspec < Autotest
return "#{ruby} -S #{spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
end
- def add_options_if_present
+ def add_options_if_present # :nodoc:
File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : ""
end
- # Finds the proper spec command to use. Precendence
- # is set in the lazily-evaluated method spec_commands. Alias + Override
- # that in ~/.autotest to provide a different spec command
- # then the default paths provided.
- def spec_command
- @spec_command ||= spec_commands.each do |command|
- if File.exists?(command)
- return @alt_separator ? (command.gsub @separator, @alt_separator) : command
- end
+ # Finds the proper spec command to use. Precendence is set in the
+ # lazily-evaluated method spec_commands. Alias + Override that in
+ # ~/.autotest to provide a different spec command then the default
+ # paths provided.
+ def spec_command(separator=File::ALT_SEPARATOR)
+ unless defined? @spec_command then
+ @spec_command = spec_commands.find { |cmd| File.exists? cmd }
+
+ raise RspecCommandError, "No spec command could be found!" unless @spec_command
+
+ @spec_command.gsub! File::SEPARATOR, separator if separator
end
- raise RspecCommandError, "No spec command could be found!"
+ @spec_command
end
-
+
# Autotest will look for spec commands in the following
# locations, in this order:
#
@@ -84,5 +69,4 @@ class Autotest::Rspec < Autotest
File.join(Config::CONFIG['bindir'], 'spec')
]
end
-
end
diff --git a/vendor/plugins/rspec/lib/spec.rb b/vendor/plugins/rspec/lib/spec.rb
index a0fc64750..c143aa885 100644
--- a/vendor/plugins/rspec/lib/spec.rb
+++ b/vendor/plugins/rspec/lib/spec.rb
@@ -27,11 +27,4 @@ module Spec
!Object.const_defined?(:Test) || Test::Unit.run?; \
end
end
-end
-
-at_exit do \
- unless $! || Spec.run?; \
- success = Spec.run; \
- exit success if Spec.exit?; \
- end \
end \ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/example.rb b/vendor/plugins/rspec/lib/spec/example.rb
index 39ff76b99..16ce12261 100644
--- a/vendor/plugins/rspec/lib/spec/example.rb
+++ b/vendor/plugins/rspec/lib/spec/example.rb
@@ -1,7 +1,7 @@
require 'timeout'
-require 'forwardable'
require 'spec/example/pending'
require 'spec/example/module_reopening_fix'
+require 'spec/example/module_inclusion_warnings'
require 'spec/example/example_group_methods'
require 'spec/example/example_methods'
require 'spec/example/example_group'
diff --git a/vendor/plugins/rspec/lib/spec/example/configuration.rb b/vendor/plugins/rspec/lib/spec/example/configuration.rb
index 674184727..cd3f46909 100644
--- a/vendor/plugins/rspec/lib/spec/example/configuration.rb
+++ b/vendor/plugins/rspec/lib/spec/example/configuration.rb
@@ -7,14 +7,20 @@ module Spec
# config.mock_with :rspec, :mocha, :flexmock, or :rr
# end
#
- # To use any other mock framework, you'll have to provide
- # your own adapter. This is simply a module that responds to
- # setup_mocks_for_rspec, verify_mocks_for_rspec and teardown_mocks_for_rspec.
+ # To use any other mock framework, you'll have to provide your own
+ # adapter. This is simply a module that responds to the following
+ # methods:
+ #
+ # setup_mocks_for_rspec
+ # verify_mocks_for_rspec
+ # teardown_mocks_for_rspec.
+ #
# These are your hooks into the lifecycle of a given example. RSpec will
- # call setup_mocks_for_rspec before running anything else in each Example.
- # After executing the #after methods, RSpec will then call verify_mocks_for_rspec
- # and teardown_mocks_for_rspec (this is guaranteed to run even if there are
- # failures in verify_mocks_for_rspec).
+ # call setup_mocks_for_rspec before running anything else in each
+ # Example. After executing the #after methods, RSpec will then call
+ # verify_mocks_for_rspec and teardown_mocks_for_rspec (this is
+ # guaranteed to run even if there are failures in
+ # verify_mocks_for_rspec).
#
# Once you've defined this module, you can pass that to mock_with:
#
@@ -35,12 +41,18 @@ module Spec
@mock_framework ||= mock_framework_path("rspec")
end
- # Declares modules to be included in all example groups (<tt>describe</tt> blocks).
- #
- # config.include(My::Bottle, My::Cup)
- #
- # If you want to restrict the inclusion to a subset of all the example groups then
- # specify this in a Hash as the last argument:
+ # :call-seq:
+ # include(Some::Helpers)
+ # include(Some::Helpers, More::Helpers)
+ # include(My::Helpers, :type => :key)
+ #
+ # Declares modules to be included in multiple example groups
+ # (<tt>describe</tt> blocks). With no :type, the modules listed will be
+ # included in all example groups. Use :type to restrict the inclusion to
+ # a subset of example groups. The value assigned to :type should be a
+ # key that maps to a class that is either a subclass of
+ # Spec::Example::ExampleGroup or extends Spec::Example::ExampleGroupMethods
+ # and includes Spec::Example::ExampleMethods
#
# config.include(My::Pony, My::Horse, :type => :farm)
#
@@ -70,7 +82,7 @@ module Spec
#
# This makes it possible to say:
#
- # person.should swim # passes if person.should_swim? returns true
+ # person.should swim # passes if person.can_swim? returns true
#
def predicate_matchers
@predicate_matchers ||= {}
@@ -85,10 +97,11 @@ module Spec
)
example_group.prepend_before(scope, &proc)
end
+
# Appends a global <tt>before</tt> block to all example groups.
#
- # If you want to restrict the block to a subset of all the example groups then
- # specify this in a Hash as the last argument:
+ # If you want to restrict the block to a subset of all the example
+ # groups then specify this in a Hash as the last argument:
#
# config.prepend_before(:all, :type => :farm)
#
@@ -115,6 +128,7 @@ module Spec
example_group.prepend_after(scope, &proc)
end
alias_method :after, :prepend_after
+
# Appends a global <tt>after</tt> block to all example groups.
# See #append_before for filtering semantics.
def append_after(*args, &proc)
diff --git a/vendor/plugins/rspec/lib/spec/example/example_group.rb b/vendor/plugins/rspec/lib/spec/example/example_group.rb
index d6e156f93..35997f0c4 100644
--- a/vendor/plugins/rspec/lib/spec/example/example_group.rb
+++ b/vendor/plugins/rspec/lib/spec/example/example_group.rb
@@ -1,6 +1,7 @@
module Spec
module Example
- # The superclass for all regular RSpec examples.
+ # Base class for customized example groups. Use this if you
+ # want to make a custom example group.
class ExampleGroup
extend Spec::Example::ExampleGroupMethods
include Spec::Example::ExampleMethods
diff --git a/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb b/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb
index 0414a3b96..c5caf4c9c 100644
--- a/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb
+++ b/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb
@@ -7,52 +7,54 @@ module Spec
default(ExampleGroup)
end
- # Registers an example group class +klass+ with the symbol
- # +type+. For example:
+ # Registers an example group class +klass+ with the symbol +type+. For
+ # example:
#
- # Spec::Example::ExampleGroupFactory.register(:farm, Spec::Farm::Example::FarmExampleGroup)
+ # Spec::Example::ExampleGroupFactory.register(:farm, FarmExampleGroup)
#
- # This will cause Main#describe from a file living in
- # <tt>spec/farm</tt> to create example group instances of type
- # Spec::Farm::Example::FarmExampleGroup.
- def register(id, example_group_class)
- @example_group_types[id] = example_group_class
+ # With that you can append a hash with :type => :farm to the describe
+ # method and it will load an instance of FarmExampleGroup.
+ #
+ # describe Pig, :type => :farm do
+ # ...
+ #
+ # If you don't use the hash explicitly, <tt>describe</tt> will
+ # implicitly use an instance of FarmExampleGroup for any file loaded
+ # from the <tt>./spec/farm</tt> directory.
+ def register(key, example_group_class)
+ @example_group_types[key] = example_group_class
end
# Sets the default ExampleGroup class
def default(example_group_class)
old = @example_group_types
@example_group_types = Hash.new(example_group_class)
- @example_group_types.merge(old) if old
+ @example_group_types.merge!(old) if old
end
- def get(id=nil)
- if @example_group_types.values.include?(id)
- id
+ def get(key=nil)
+ if @example_group_types.values.include?(key)
+ key
else
- @example_group_types[id]
+ @example_group_types[key]
end
end
def create_example_group(*args, &block)
opts = Hash === args.last ? args.last : {}
- if opts[:shared]
- SharedExampleGroup.new(*args, &block)
- else
- superclass = determine_superclass(opts)
- superclass.describe(*args, &block)
- end
+ superclass = determine_superclass(opts)
+ superclass.describe(*args, &block)
end
protected
def determine_superclass(opts)
- id = if opts[:type]
+ key = if opts[:type]
opts[:type]
elsif opts[:spec_path] =~ /spec(\\|\/)(#{@example_group_types.keys.join('|')})/
$2 == '' ? nil : $2.to_sym
end
- get(id)
+ get(key)
end
end
diff --git a/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb b/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb
index 8f73a9853..64e90cdb2 100644
--- a/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb
+++ b/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb
@@ -11,13 +11,14 @@ module Spec
end
end
- attr_reader :description_text, :description_args, :description_options, :spec_path
+ attr_reader :description_text, :description_args, :description_options, :spec_path, :registration_binding_block
def inherited(klass)
super
- klass.register
+ klass.register {}
+ Spec::Runner.register_at_exit_hook
end
-
+
# Makes the describe/it syntax available from a class. For example:
#
# class StackSpec < Spec::ExampleGroup
@@ -33,10 +34,17 @@ module Spec
# end
#
def describe(*args, &example_group_block)
+ args << {} unless Hash === args.last
if example_group_block
- self.subclass("Subclass") do
- describe(*args)
- module_eval(&example_group_block)
+ params = args.last
+ params[:spec_path] = eval("caller(0)[1]", example_group_block) unless params[:spec_path]
+ if params[:shared]
+ SharedExampleGroup.new(*args, &example_group_block)
+ else
+ self.subclass("Subclass") do
+ describe(*args)
+ module_eval(&example_group_block)
+ end
end
else
set_description(*args)
@@ -44,6 +52,7 @@ module Spec
self
end
end
+ alias :context :describe
# Use this to pull in examples from shared example groups.
# See Spec::Runner for information about shared example groups.
@@ -106,11 +115,12 @@ module Spec
def xit(description=nil, opts={}, &block)
Kernel.warn("Example disabled: #{description}")
end
+ alias_method :xspecify, :xit
def run
examples = examples_to_run
- return true if examples.empty?
reporter.add_example_group(self)
+ return true if examples.empty?
return dry_run(examples) if dry_run?
plugin_mock_framework
@@ -149,10 +159,12 @@ module Spec
@description_text = ExampleGroupMethods.description_text(*args)
@spec_path = File.expand_path(options[:spec_path]) if options[:spec_path]
if described_type.class == Module
- include described_type
+ @described_module = described_type
end
self
end
+
+ attr_reader :described_module
def examples #:nodoc:
examples = example_objects.dup
@@ -236,7 +248,8 @@ module Spec
@after_each_parts = nil
end
- def register
+ def register(&registration_binding_block)
+ @registration_binding_block = registration_binding_block
rspec_options.add_example_group self
end
@@ -244,6 +257,10 @@ module Spec
rspec_options.remove_example_group self
end
+ def registration_backtrace
+ eval("caller", registration_binding_block.binding)
+ end
+
def run_before_each(example)
execute_in_class_hierarchy do |example_group|
example.eval_each_fail_fast(example_group.before_each_parts)
@@ -378,6 +395,7 @@ module Spec
case scope
when :each; before_each_parts
when :all; before_all_parts
+ when :suite; rspec_options.before_suite_parts
end
end
@@ -385,6 +403,7 @@ module Spec
case scope
when :each; after_each_parts
when :all; after_all_parts
+ when :suite; rspec_options.after_suite_parts
end
end
diff --git a/vendor/plugins/rspec/lib/spec/example/example_methods.rb b/vendor/plugins/rspec/lib/spec/example/example_methods.rb
index 6dd4c9c72..d4d716c2d 100644
--- a/vendor/plugins/rspec/lib/spec/example/example_methods.rb
+++ b/vendor/plugins/rspec/lib/spec/example/example_methods.rb
@@ -3,6 +3,8 @@ module Spec
module ExampleMethods
extend ExampleGroupMethods
extend ModuleReopeningFix
+ include ModuleInclusionWarnings
+
PENDING_EXAMPLE_BLOCK = lambda {
raise Spec::Example::ExamplePendingError.new("Not Yet Implemented")
@@ -63,6 +65,10 @@ module Spec
def description
@_defined_description || @_matcher_description || "NO NAME"
end
+
+ def __full_description
+ "#{self.class.description} #{self.description}"
+ end
def set_instance_variables_from_hash(ivars)
ivars.each do |variable_name, value|
@@ -81,6 +87,10 @@ module Spec
Spec::Matchers.clear_generated_description
end
end
+
+ def implementation_backtrace
+ eval("caller", @_implementation)
+ end
protected
include Matchers
diff --git a/vendor/plugins/rspec/lib/spec/example/module_inclusion_warnings.rb b/vendor/plugins/rspec/lib/spec/example/module_inclusion_warnings.rb
new file mode 100644
index 000000000..c65faf2dd
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/example/module_inclusion_warnings.rb
@@ -0,0 +1,37 @@
+module Spec
+ module Example
+ # In the future, modules will no longer be automatically included
+ # in the Example Group (based on the description name); when that
+ # time comes, this code should be removed.
+ module ModuleInclusionWarnings
+ # Thanks, Francis Hwang.
+ class MethodDispatcher
+ def initialize(mod, target=nil)
+ @mod = mod
+ @target = target
+ end
+
+ def respond_to?(sym)
+ @mod && @mod.instance_methods.include?(sym.to_s)
+ end
+
+ def call(sym, *args, &blk)
+ Kernel.warn("Modules will no longer be automatically included in RSpec version 1.1.4. Called from #{caller[2]}")
+ @target.extend @mod
+ @target.send(sym, *args, &blk)
+ end
+ end
+
+ def respond_to?(sym)
+ MethodDispatcher.new(self.class.described_module).respond_to?(sym) ? true : super
+ end
+
+ private
+
+ def method_missing(sym, *args, &blk)
+ md = MethodDispatcher.new(self.class.described_module, self)
+ self.respond_to?(sym) ? md.call(sym, *args, &blk) : super
+ 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
index a5eb1bb89..74b59bbe3 100644
--- a/vendor/plugins/rspec/lib/spec/expectations/differs/default.rb
+++ b/vendor/plugins/rspec/lib/spec/expectations/differs/default.rb
@@ -17,7 +17,7 @@ module Spec
end
# This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
- def diff_as_string(data_old, data_new)
+ 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 = ""
diff --git a/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb b/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb
index a3925bbee..2091c2947 100644
--- a/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb
+++ b/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb
@@ -27,12 +27,8 @@ module Spec
#
# NOTE that this does NOT support receiver.should != expected.
# Instead, use receiver.should_not == expected
- def should(matcher = :default_parameter, &block)
- if :default_parameter == matcher
- Spec::Matchers::PositiveOperatorMatcher.new(self)
- else
- ExpectationMatcherHandler.handle_matcher(self, matcher, &block)
- end
+ def should(matcher=:use_operator_matcher, &block)
+ ExpectationMatcherHandler.handle_matcher(self, matcher, &block)
end
# :call-seq:
@@ -54,12 +50,8 @@ module Spec
# => Passes unless (receiver =~ regexp)
#
# See Spec::Matchers for more information about matchers
- def should_not(matcher = :default_parameter, &block)
- if :default_parameter == matcher
- Spec::Matchers::NegativeOperatorMatcher.new(self)
- else
- NegativeExpectationMatcherHandler.handle_matcher(self, matcher, &block)
- end
+ def should_not(matcher=:use_operator_matcher, &block)
+ NegativeExpectationMatcherHandler.handle_matcher(self, matcher, &block)
end
end
diff --git a/vendor/plugins/rspec/lib/spec/expectations/handler.rb b/vendor/plugins/rspec/lib/spec/expectations/handler.rb
index e6dce0846..2e5f2a621 100644
--- a/vendor/plugins/rspec/lib/spec/expectations/handler.rb
+++ b/vendor/plugins/rspec/lib/spec/expectations/handler.rb
@@ -12,6 +12,10 @@ module Spec
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
@@ -27,6 +31,10 @@ module Spec
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
diff --git a/vendor/plugins/rspec/lib/spec/extensions.rb b/vendor/plugins/rspec/lib/spec/extensions.rb
index 9a313d0e7..715bb49f2 100755
--- a/vendor/plugins/rspec/lib/spec/extensions.rb
+++ b/vendor/plugins/rspec/lib/spec/extensions.rb
@@ -1,3 +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/metaclass.rb b/vendor/plugins/rspec/lib/spec/extensions/metaclass.rb
new file mode 100644
index 000000000..acf9febea
--- /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
index e9f6364e2..0b8c26fa2 100755
--- a/vendor/plugins/rspec/lib/spec/extensions/object.rb
+++ b/vendor/plugins/rspec/lib/spec/extensions/object.rb
@@ -3,8 +3,4 @@ class Object
options = Hash === args.last ? args.pop : {}
return args, options
end
-
- def metaclass
- class << self; self; end
- end
end
diff --git a/vendor/plugins/rspec/lib/spec/interop/test.rb b/vendor/plugins/rspec/lib/spec/interop/test.rb
index 5c9543398..afa16137b 100644
--- a/vendor/plugins/rspec/lib/spec/interop/test.rb
+++ b/vendor/plugins/rspec/lib/spec/interop/test.rb
@@ -7,4 +7,6 @@ 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) \ No newline at end of file
+Spec::Example::ExampleGroupFactory.default(Test::Unit::TestCase)
+
+Test::Unit.run = true
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
index 663dd4722..8e9995e02 100644
--- 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
@@ -36,6 +36,7 @@ module Test
alias_method :finished_without_rspec, :finished
def finished_with_rspec(elapsed_time)
+ @ran_test ||= false
if @ran_test
finished_without_rspec(elapsed_time)
end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/change.rb b/vendor/plugins/rspec/lib/spec/matchers/change.rb
index 784e516ed..8f4ecc187 100644
--- a/vendor/plugins/rspec/lib/spec/matchers/change.rb
+++ b/vendor/plugins/rspec/lib/spec/matchers/change.rb
@@ -114,7 +114,7 @@ EOF
#
# string = "string"
# lambda {
- # string.reverse
+ # string.reverse!
# }.should change { string }.from("string").to("gnirts")
#
# lambda {
diff --git a/vendor/plugins/rspec/lib/spec/matchers/has.rb b/vendor/plugins/rspec/lib/spec/matchers/has.rb
index cc5a250b8..60199f54d 100644
--- a/vendor/plugins/rspec/lib/spec/matchers/has.rb
+++ b/vendor/plugins/rspec/lib/spec/matchers/has.rb
@@ -8,24 +8,14 @@ module Spec
end
def matches?(target)
- @target = target
- begin
- return target.send(predicate, *@args)
- rescue => @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
- return false
+ target.send(predicate, *@args)
end
def failure_message
- raise @error if @error
"expected ##{predicate}(#{@args[0].inspect}) to return true, got false"
end
def negative_failure_message
- raise @error if @error
"expected ##{predicate}(#{@args[0].inspect}) to return false, got true"
end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/raise_error.rb b/vendor/plugins/rspec/lib/spec/matchers/raise_error.rb
index b45dcf65c..c003849b6 100644
--- a/vendor/plugins/rspec/lib/spec/matchers/raise_error.rb
+++ b/vendor/plugins/rspec/lib/spec/matchers/raise_error.rb
@@ -1,50 +1,66 @@
module Spec
module Matchers
-
class RaiseError #:nodoc:
- def initialize(error_or_message=Exception, message=nil)
- if String === error_or_message
- @expected_error = Exception
- @expected_message = error_or_message
+ 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 = error_or_message
- @expected_message = message
+ @expected_error, @expected_message = error_or_message, message
end
end
-
+
def matches?(proc)
@raised_expected_error = false
- @raised_other = false
+ @with_expected_message = false
+ @eval_block = false
+ @eval_block_passed = false
begin
proc.call
rescue @expected_error => @actual_error
- if @expected_message.nil?
- @raised_expected_error = true
- else
- case @expected_message
- when Regexp
- if @expected_message =~ @actual_error.message
- @raised_expected_error = true
- else
- @raised_other = true
- end
- else
- if @expected_message == @actual_error.message
- @raised_expected_error = true
- else
- @raised_other = true
- end
- end
- end
- rescue => @actual_error
- @raised_other = true
- ensure
- return @raised_expected_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
- return "expected #{expected_error}#{actual_error}" if @raised_other || !@raised_expected_error
+ if @eval_block
+ return @actual_error.message
+ else
+ return "expected #{expected_error}#{actual_error}"
+ end
end
def negative_failure_message
@@ -70,6 +86,11 @@ module Spec
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:
@@ -77,6 +98,10 @@ module Spec
# 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)
@@ -86,11 +111,13 @@ module Spec
# 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/)
#
@@ -98,8 +125,8 @@ module Spec
# 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)
- Matchers::RaiseError.new(error, message)
+ 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/mocks.rb b/vendor/plugins/rspec/lib/spec/mocks.rb
index 9f9cd215b..678dd6aae 100644
--- a/vendor/plugins/rspec/lib/spec/mocks.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks.rb
@@ -1,3 +1,4 @@
+require 'spec/mocks/framework'
require 'spec/mocks/methods'
require 'spec/mocks/argument_constraint_matchers'
require 'spec/mocks/spec_methods'
@@ -11,7 +12,6 @@ require 'spec/mocks/error_generator'
require 'spec/mocks/extensions/object'
require 'spec/mocks/space'
-
module Spec
# == Mocks and Stubs
#
diff --git a/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb b/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb
index 0e4777082..96ccf0f4a 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/argument_constraint_matchers.rb
@@ -1,7 +1,7 @@
module Spec
module Mocks
module ArgumentConstraintMatchers
-
+
# Shortcut for creating an instance of Spec::Mocks::DuckTypeArgConstraint
def duck_type(*args)
DuckTypeArgConstraint.new(*args)
@@ -19,6 +19,10 @@ module Spec
BooleanArgConstraint.new(nil)
end
+ def hash_including(expected={})
+ HashIncludingConstraint.new(expected)
+ end
+
def no_args
NoArgsConstraint.new
end
diff --git a/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb
index 34a1d4d03..b3fdcc80d 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb
@@ -108,6 +108,32 @@ module Spec
"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
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 000000000..6fd51a272
--- /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/framework.rb b/vendor/plugins/rspec/lib/spec/mocks/framework.rb
new file mode 100644
index 000000000..92089673a
--- /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
index 6bd2f1c32..0b10290b3 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb
@@ -72,12 +72,18 @@ module Spec
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
@@ -112,12 +118,14 @@ module Spec
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
- block.call(*args_to_yield_this_time)
+ value = block.call(*args_to_yield_this_time)
end
+ value
end
def invoke_consecutive_return_block(args, block)
@@ -147,9 +155,8 @@ module Spec
@sym == sym and not @args_expectation.check_args(args)
end
- def verify_messages_received
- return if ignoring_args? || matches_exact_count? ||
- matches_at_least_count? || matches_at_most_count?
+ def verify_messages_received
+ return if expected_messages_received?
generate_error
rescue Spec::Mocks::MockExpectationError => error
@@ -157,6 +164,11 @@ module Spec
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
@@ -173,8 +185,20 @@ module Spec
@expected_received_count == @actual_received_count
end
+ def similar_messages
+ @similar_messages ||= []
+ end
+
+ def advise(args, block)
+ similar_messages << args
+ end
+
def generate_error
- @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args)
+ 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)
diff --git a/vendor/plugins/rspec/lib/spec/mocks/mock.rb b/vendor/plugins/rspec/lib/spec/mocks/mock.rb
index f029b1b8f..d0b5f204d 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/mock.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/mock.rb
@@ -3,19 +3,21 @@ module Spec
class Mock
include Methods
- # Creates a new mock with a +name+ (that will be used in error messages only)
- # == Options:
- # * <tt>:null_object</tt> - if true, the mock object acts as a forgiving null object allowing any message to be sent to it.
+ # Creates a new mock with a +name+ (that will be used in error messages
+ # only) == Options:
+ # * <tt>:null_object</tt> - 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
+ # 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
diff --git a/vendor/plugins/rspec/lib/spec/mocks/proxy.rb b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb
index 03db3b113..45b96a30b 100644
--- a/vendor/plugins/rspec/lib/spec/mocks/proxy.rb
+++ b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb
@@ -63,10 +63,14 @@ module Spec
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)
+ 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)
- raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(sym) unless null_object?
+ 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
@@ -88,18 +92,20 @@ module Spec
end
def define_expected_method(sym)
- if target_responds_to?(sym) && !metaclass.method_defined?(munge(sym))
+ visibility_string = "#{visibility(sym)} :#{sym}"
+ if target_responds_to?(sym) && !target_metaclass.method_defined?(munge(sym))
munged_sym = munge(sym)
- metaclass.instance_eval do
+ target_metaclass.instance_eval do
alias_method munged_sym, sym if method_defined?(sym.to_s)
end
@proxied_methods << sym
end
- metaclass_eval(<<-EOF, __FILE__, __LINE__)
+ target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
def #{sym}(*args, &block)
__mock_proxy.message_received :#{sym}, *args, &block
end
+ #{visibility_string}
EOF
end
@@ -109,6 +115,18 @@ module Spec
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
@@ -125,12 +143,8 @@ module Spec
@proxied_methods.clear
end
- def metaclass_eval(str, filename, lineno)
- metaclass.class_eval(str, filename, lineno)
- end
-
- def metaclass
- (class << @target; self; end)
+ def target_metaclass
+ class << @target; self; end
end
def verify_expectations
@@ -142,7 +156,7 @@ module Spec
def reset_proxied_methods
@proxied_methods.each do |sym|
munged_sym = munge(sym)
- metaclass.instance_eval do
+ target_metaclass.instance_eval do
if method_defined?(munged_sym.to_s)
alias_method sym, munged_sym
undef_method munged_sym
diff --git a/vendor/plugins/rspec/lib/spec/rake/spectask.rb b/vendor/plugins/rspec/lib/spec/rake/spectask.rb
index c59e226f5..ecf39506d 100644
--- a/vendor/plugins/rspec/lib/spec/rake/spectask.rb
+++ b/vendor/plugins/rspec/lib/spec/rake/spectask.rb
@@ -11,7 +11,7 @@ module Spec
# A Rake task that runs a set of specs.
#
# Example:
- #
+ #
# Spec::Rake::SpecTask.new do |t|
# t.warning = true
# t.rcov = true
@@ -87,7 +87,7 @@ module Spec
# Whether or not to use RCov (default is false)
# See http://eigenclass.org/hiki.rb?rcov
attr_accessor :rcov
-
+
# Array of commandline options to pass to RCov. Defaults to ['--exclude', 'lib\/spec,bin\/spec'].
# Ignored if rcov=false
# Setting the RCOV_OPTS environment variable overrides this.
@@ -117,7 +117,7 @@ module Spec
# used, then the list of spec files is the union of the two.
# Setting the SPEC environment variable overrides this.
attr_accessor :spec_files
-
+
# Use verbose output. If this is set to true, the task will print
# the executed spec command to stdout. Defaults to false.
attr_accessor :verbose
@@ -155,7 +155,7 @@ module Spec
# ruby [ruby_opts] -Ilib -S rcov [rcov_opts] bin/spec -- examples [spec_opts]
# or
# ruby [ruby_opts] -Ilib bin/spec examples [spec_opts]
- cmd = "ruby "
+ cmd = "#{File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])} "
rb_opts = ruby_opts.clone
rb_opts << "-I\"#{lib_path}\""
@@ -210,7 +210,7 @@ module Spec
STDERR.puts "RSPECOPTS is DEPRECATED and will be removed in a future version. Use SPEC_OPTS instead." if ENV['RSPECOPTS']
ENV['SPEC_OPTS'] || ENV['RSPECOPTS'] || spec_opts.join(" ") || ""
end
-
+
def evaluate(o) # :nodoc:
case o
when Proc then o.call
diff --git a/vendor/plugins/rspec/lib/spec/runner.rb b/vendor/plugins/rspec/lib/spec/runner.rb
index 1a9373fee..97ef95bd2 100644
--- a/vendor/plugins/rspec/lib/spec/runner.rb
+++ b/vendor/plugins/rspec/lib/spec/runner.rb
@@ -183,6 +183,20 @@ module Spec
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
index 5fd2fb99f..587e57d90 100644
--- a/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb
@@ -27,7 +27,7 @@ module Spec
/\/lib\/ruby\//,
/bin\/spec:/,
/bin\/rcov:/,
- /lib\/rspec_on_rails/,
+ /lib\/rspec-rails/,
/vendor\/rails/,
# TextMate's Ruby and RSpec plugins
/Ruby\.tmbundle\/Support\/tmruby.rb:/,
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb
index c8647cf50..a1269b513 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb
@@ -19,8 +19,7 @@ module Spec
end
# This method is invoked at the beginning of the execution of each example_group.
- # +name+ is the name of the example_group and +first+ is true if it is the
- # first example_group - otherwise it's false.
+ # +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)
@@ -46,7 +45,7 @@ module Spec
# 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_group_description, example, message)
+ def example_pending(example, message)
end
# This method is invoked after all of the examples have executed. The next method
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
index 859b2641d..bad023db7 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/base_text_formatter.rb
@@ -26,8 +26,8 @@ module Spec
@pending_examples = []
end
- def example_pending(example_group_description, example, message)
- @pending_examples << ["#{example_group_description} #{example.description}", message]
+ def example_pending(example, message)
+ @pending_examples << [example.__full_description, message]
end
def dump_failure(counter, failure)
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
index 5a4607983..8d39bc572 100644
--- 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
@@ -4,19 +4,15 @@ module Spec
module Runner
module Formatter
class FailingExampleGroupsFormatter < BaseTextFormatter
- def add_example_group(example_group)
- super
- @example_group_description_parts = example_group.description_parts
- end
-
def example_failed(example, counter, failure)
- if @example_group_description_parts
- description_parts = @example_group_description_parts.collect do |description|
+ 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_description_parts = nil
+ @example_group = nil
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
index ad153c8dc..e5368f2cb 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb
@@ -9,18 +9,22 @@ module Spec
def initialize(options, output)
super
- @current_example_group_number = 0
- @current_example_number = 0
+ @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 current_example_group_number
- @current_example_group_number
+ def example_group_number
+ @example_group_number
end
# The number of the currently running example (a global counter)
- def current_example_number
- @current_example_number
+ def example_number
+ @example_number
end
def start(example_count)
@@ -35,14 +39,14 @@ module Spec
super
@example_group_red = false
@example_group_red = false
- @current_example_group_number += 1
- unless current_example_group_number == 1
+ @example_group_number += 1
+ unless example_group_number == 1
@output.puts " </dl>"
@output.puts "</div>"
end
@output.puts "<div class=\"example_group\">"
@output.puts " <dl>"
- @output.puts " <dt id=\"example_group_#{current_example_group_number}\">#{h(example_group.description)}</dt>"
+ @output.puts " <dt id=\"example_group_#{example_group_number}\">#{h(example_group.description)}</dt>"
@output.flush
end
@@ -53,7 +57,7 @@ module Spec
end
def example_started(example)
- @current_example_number += 1
+ @example_number += 1
end
def example_passed(example)
@@ -67,7 +71,7 @@ module Spec
failure_style = failure.pending_fixed? ? 'pending_fixed' : 'failed'
@output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>" unless @header_red
@header_red = true
- @output.puts " <script type=\"text/javascript\">makeRed('example_group_#{current_example_group_number}');</script>" unless @example_group_red
+ @output.puts " <script type=\"text/javascript\">makeRed('example_group_#{example_group_number}');</script>" unless @example_group_red
@example_group_red = true
move_progress
@output.puts " <dd class=\"spec #{failure_style}\">"
@@ -81,9 +85,9 @@ module Spec
@output.flush
end
- def example_pending(example_group_description, example, message)
+ def example_pending(example, message)
@output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>" unless @header_red
- @output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{current_example_group_number}');</script>" unless @example_group_red
+ @output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{example_group_number}');</script>" unless @example_group_red
move_progress
@output.puts " <dd class=\"spec not_implemented\"><span class=\"not_implemented_spec_name\">#{h(example.description)} (PENDING: #{h(message)})</span></dd>"
@output.flush
@@ -106,7 +110,7 @@ module Spec
def percent_done
result = 100.0
if @example_count != 0
- result = ((current_example_number).to_f / @example_count.to_f * 1000).to_i / 10.0
+ result = ((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0
end
result
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/nested_text_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/nested_text_formatter.rb
new file mode 100644
index 000000000..f9aa5f67c
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/nested_text_formatter.rb
@@ -0,0 +1,65 @@
+require 'spec/runner/formatter/base_text_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ class NestedTextFormatter < BaseTextFormatter
+ attr_reader :previous_nested_example_groups
+ def initialize(options, where)
+ super
+ @previous_nested_example_groups = []
+ end
+
+ def add_example_group(example_group)
+ super
+
+ current_nested_example_groups = described_example_group_chain
+ current_nested_example_groups.each_with_index do |nested_example_group, i|
+ unless nested_example_group == previous_nested_example_groups[i]
+ output.puts "#{' ' * i}#{nested_example_group.description_args}"
+ end
+ end
+
+ @previous_nested_example_groups = described_example_group_chain
+ end
+
+ def example_failed(example, counter, failure)
+ message = if failure.expectation_not_met?
+ "#{current_indentation}#{example.description} (FAILED - #{counter})"
+ else
+ "#{current_indentation}#{example.description} (ERROR - #{counter})"
+ end
+
+ output.puts(failure.expectation_not_met? ? red(message) : magenta(message))
+ output.flush
+ end
+
+ def example_passed(example)
+ message = "#{current_indentation}#{example.description}"
+ output.puts green(message)
+ output.flush
+ end
+
+ def example_pending(example, message)
+ super
+ output.puts yellow("#{current_indentation}#{example.description} (PENDING: #{message})")
+ output.flush
+ end
+
+ def current_indentation
+ ' ' * previous_nested_example_groups.length
+ end
+
+ def described_example_group_chain
+ example_group_chain = []
+ example_group.send(:execute_in_class_hierarchy) do |parent_example_group|
+ if parent_example_group.description_args && !parent_example_group.description_args.empty?
+ example_group_chain << parent_example_group
+ end
+ end
+ example_group_chain
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb
index 3784f3ac7..8671d721e 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/profile_formatter.rb
@@ -41,6 +41,10 @@ module Spec
end
@output.flush
end
+
+ def method_missing(sym, *args)
+ # ignore
+ end
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb
index 8d0e50432..032a2872d 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb
@@ -14,7 +14,7 @@ module Spec
@output.flush
end
- def example_pending(example_group_description, example, message)
+ def example_pending(example, message)
super
@output.print yellow('P')
@output.flush
@@ -24,6 +24,10 @@ module Spec
@output.puts
@output.flush
end
+
+ def method_missing(sym, *args)
+ # ignore
+ end
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb
index f426dc948..facf1a65a 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb
@@ -28,7 +28,7 @@ module Spec
output.flush
end
- def example_pending(example_group_description, example, message)
+ def example_pending(example, message)
super
output.puts yellow("- #{example.description} (PENDING: #{message})")
output.flush
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb
index b70ac153a..5a8134683 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/story/html_formatter.rb
@@ -98,6 +98,9 @@ EOF
scenario_ended
end
+ def step_upcoming(type, description, *args)
+ end
+
def step_succeeded(type, description, *args)
print_step('passed', type, description, *args) # TODO: uses succeeded CSS class
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb
index 424e27cc6..31cd614cb 100644
--- a/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb
@@ -38,6 +38,7 @@ module Spec
@scenario_already_failed = false
@output.print "\n\n Scenario: #{scenario_name}"
@scenario_ok = true
+ @scenario_pending = false
end
def scenario_succeeded(story_title, scenario_name)
@@ -52,6 +53,7 @@ module Spec
def scenario_pending(story_title, scenario_name, msg)
@pending_scenario_count += 1 unless @scenario_already_failed
+ @scenario_pending = true
@scenario_already_failed = true
end
@@ -76,21 +78,29 @@ module Spec
end
end
end
-
+
+ def step_upcoming(type, description, *args)
+ end
+
def step_succeeded(type, description, *args)
- found_step(type, description, false, *args)
+ found_step(type, description, false, false, *args)
end
def step_pending(type, description, *args)
- found_step(type, description, false, *args)
+ found_step(type, description, false, true, *args)
@pending_steps << [@current_story_title, @current_scenario_name, description]
- @output.print " (PENDING)"
+ @output.print yellow(" (PENDING)")
+ @scenario_pending = true
@scenario_ok = false
end
def step_failed(type, description, *args)
- found_step(type, description, true, *args)
- @output.print red(@scenario_ok ? " (FAILED)" : " (SKIPPED)")
+ found_step(type, description, true, @scenario_pending, *args)
+ if @scenario_pending
+ @output.print yellow(" (SKIPPED)")
+ else
+ @output.print red(@scenario_ok ? " (FAILED)" : " (SKIPPED)")
+ end
@scenario_ok = false
end
@@ -103,7 +113,7 @@ module Spec
private
- def found_step(type, description, failed, *args)
+ def found_step(type, description, failed, pending, *args)
desc_string = description.step_name
arg_regexp = description.arg_regexp
text = if(type == @previous_type)
@@ -113,7 +123,11 @@ module Spec
end
i = -1
text << desc_string.gsub(arg_regexp) { |param| args[i+=1] }
- @output.print(failed ? red(text) : green(text))
+ if pending
+ @output.print yellow(text)
+ else
+ @output.print(failed ? red(text) : green(text))
+ end
if type == :'given scenario'
@previous_type = :given
diff --git a/vendor/plugins/rspec/lib/spec/runner/option_parser.rb b/vendor/plugins/rspec/lib/spec/runner/option_parser.rb
index 09cedccac..91525e089 100644
--- a/vendor/plugins/rspec/lib/spec/runner/option_parser.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/option_parser.rb
@@ -15,7 +15,11 @@ module Spec
attr_reader :options
OPTIONS = {
- :diff => ["-D", "--diff [FORMAT]", "Show diff of objects that are expected to be equal when they are not",
+ :pattern => ["-p", "--pattern [PATTERN]","Limit files loaded to those matching this pattern. Defaults to '**/*_spec.rb'",
+ "Separate multiple patterns with commas.",
+ "Applies only to directories named on the command line (files",
+ "named explicitly on the command line will be loaded regardless)."],
+ :diff => ["-D", "--diff [FORMAT]","Show diff of objects that are expected to be equal when they are not",
"Builtin formats: unified|u|context|c",
"You can also specify a custom differ class",
"(in which case you should also specify --require)"],
@@ -32,7 +36,7 @@ module Spec
:specification => ["-s", "--specification [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)"],
:line => ["-l", "--line LINE_NUMBER", Integer, "Execute behaviout or specification at given line.",
"(does not work for dynamically generated specs)"],
- :format => ["-f", "--format FORMAT[:WHERE]", "Specifies what format to use for output. Specify WHERE to tell",
+ :format => ["-f", "--format FORMAT[:WHERE]","Specifies what format to use for output. Specify WHERE to tell",
"the formatter where to write the output. All built-in formats",
"expect WHERE to be a file name, and will write to STDOUT if it's",
"not specified. The --format option may be specified several times",
@@ -42,6 +46,7 @@ module Spec
"progress|p : Text progress",
"profile|o : Text progress with profiling of 10 slowest examples",
"specdoc|s : Example doc as text",
+ "indented|i : Example doc as indented text",
"html|h : A nice HTML report",
"failing_examples|e : Write all failing examples - input for --example",
"failing_example_groups|g : Write all failing example groups - input for --example",
@@ -53,13 +58,13 @@ module Spec
"FORMAT can also be the name of a custom formatter class",
"(in which case you should also specify --require to load it)"],
:require => ["-r", "--require FILE", "Require FILE before running specs",
- "Useful for loading custom formatters or other extensions.",
- "If this option is used it must come before the others"],
+ "Useful for loading custom formatters or other extensions.",
+ "If this option is used it must come before the others"],
:backtrace => ["-b", "--backtrace", "Output full backtrace"],
:loadby => ["-L", "--loadby STRATEGY", "Specify the strategy by which spec files should be loaded.",
- "STRATEGY can currently only be 'mtime' (File modification time)",
- "By default, spec files are loaded in alphabetical order if --loadby",
- "is not specified."],
+ "STRATEGY can currently only be 'mtime' (File modification time)",
+ "By default, spec files are loaded in alphabetical order if --loadby",
+ "is not specified."],
:reverse => ["-R", "--reverse", "Run examples in reverse order"],
:timeout => ["-t", "--timeout FLOAT", "Interrupt and fail each example that doesn't complete in the",
"specified time"],
@@ -84,11 +89,11 @@ module Spec
@out_stream = out
@options = Options.new(@error_stream, @out_stream)
- @spec_parser = SpecParser.new
@file_factory = File
self.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
self.separator ""
+ on(*OPTIONS[:pattern]) {|pattern| @options.filename_pattern = pattern}
on(*OPTIONS[:diff]) {|diff| @options.parse_diff(diff)}
on(*OPTIONS[:colour]) {@options.colour = true}
on(*OPTIONS[:example]) {|example| @options.parse_example(example)}
@@ -103,11 +108,8 @@ module Spec
on(*OPTIONS[:heckle]) {|heckle| @options.load_heckle_runner(heckle)}
on(*OPTIONS[:dry_run]) {@options.dry_run = true}
on(*OPTIONS[:options_file]) {|options_file| parse_options_file(options_file)}
- on(*OPTIONS[:generate_options]) do |options_file|
- end
- on(*OPTIONS[:runner]) do |runner|
- @options.user_input_for_runner = runner
- end
+ on(*OPTIONS[:generate_options]) {|options_file|}
+ on(*OPTIONS[:runner]) {|runner| @options.user_input_for_runner = runner}
on(*OPTIONS[:drb]) {}
on(*OPTIONS[:version]) {parse_version}
on_tail(*OPTIONS[:help]) {parse_help}
@@ -124,10 +126,6 @@ module Spec
blk.call(file) if blk
end
- if @options.line_number
- set_spec_from_line_number
- end
-
@options
end
@@ -141,6 +139,10 @@ module Spec
def parse_options_file(options_file)
option_file_args = IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten
@argv.push(*option_file_args)
+ # TODO - this is a brute force solution to http://rspec.lighthouseapp.com/projects/5645/tickets/293.
+ # Let's look for a cleaner way. Might not be one. But let's look. If not, perhaps
+ # this can be moved to a different method to indicate the special handling for drb?
+ parse_drb(@argv)
end
def parse_generate_options
@@ -170,12 +172,12 @@ module Spec
@options.examples_should_not_be_run
end
- def parse_drb
+ def parse_drb(argv = nil)
+ argv ||= @options.argv # TODO - see note about about http://rspec.lighthouseapp.com/projects/5645/tickets/293
is_drb = false
- argv = @options.argv
is_drb ||= argv.delete(OPTIONS[:drb][0])
is_drb ||= argv.delete(OPTIONS[:drb][1])
- return nil unless is_drb
+ return false unless is_drb
@options.examples_should_not_be_run
DrbCommandLine.run(
self.class.parse(argv, @error_stream, @out_stream)
@@ -193,37 +195,9 @@ module Spec
exit if stdout?
end
- def set_spec_from_line_number
- if @options.examples.empty?
- if @options.files.length == 1
- if @file_factory.file?(@options.files[0])
- source = @file_factory.open(@options.files[0])
- example = @spec_parser.spec_name_for(source, @options.line_number)
- @options.parse_example(example)
- elsif @file_factory.directory?(@options.files[0])
- @error_stream.puts "You must specify one file, not a directory when using the --line option"
- exit(1) if stderr?
- else
- @error_stream.puts "#{@options.files[0]} does not exist"
- exit(2) if stderr?
- end
- else
- @error_stream.puts "Only one file can be specified when using the --line option: #{@options.files.inspect}"
- exit(3) if stderr?
- end
- else
- @error_stream.puts "You cannot use both --line and --example"
- exit(4) if stderr?
- end
- end
-
def stdout?
@out_stream == $stdout
end
-
- def stderr?
- @error_stream == $stderr
- end
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/options.rb b/vendor/plugins/rspec/lib/spec/runner/options.rb
index a5a07548d..6716464af 100644
--- a/vendor/plugins/rspec/lib/spec/runner/options.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/options.rb
@@ -8,6 +8,8 @@ module Spec
EXAMPLE_FORMATTERS = { # Load these lazily for better speed
'specdoc' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'],
's' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'],
+ 'nested' => ['spec/runner/formatter/nested_text_formatter', 'Formatter::NestedTextFormatter'],
+ 'n' => ['spec/runner/formatter/nested_text_formatter', 'Formatter::NestedTextFormatter'],
'html' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'],
'h' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'],
'progress' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'],
@@ -29,6 +31,7 @@ module Spec
}
attr_accessor(
+ :filename_pattern,
:backtrace_tweaker,
:context_lines,
:diff_format,
@@ -45,6 +48,8 @@ module Spec
:user_input_for_runner,
:error_stream,
:output_stream,
+ :before_suite_parts,
+ :after_suite_parts,
# TODO: BT - Figure out a better name
:argv
)
@@ -53,6 +58,7 @@ module Spec
def initialize(error_stream, output_stream)
@error_stream = error_stream
@output_stream = output_stream
+ @filename_pattern = "**/*_spec.rb"
@backtrace_tweaker = QuietBacktraceTweaker.new
@examples = []
@colour = false
@@ -63,9 +69,12 @@ module Spec
@diff_format = :unified
@files = []
@example_groups = []
+ @result = nil
@examples_run = false
@examples_should_be_run = nil
@user_input_for_runner = nil
+ @before_suite_parts = []
+ @after_suite_parts = []
end
def add_example_group(example_group)
@@ -78,16 +87,31 @@ module Spec
def run_examples
return true unless examples_should_be_run?
- runner = custom_runner || ExampleGroupRunner.new(self)
+ success = true
+ begin
+ before_suite_parts.each do |part|
+ part.call
+ end
+ runner = custom_runner || ExampleGroupRunner.new(self)
- runner.load_files(files_to_load)
- if example_groups.empty?
- true
- else
- success = runner.run
- @examples_run = true
- heckle if heckle_runner
- success
+ unless @files_loaded
+ runner.load_files(files_to_load)
+ @files_loaded = true
+ end
+
+ if example_groups.empty?
+ true
+ else
+ set_spec_from_line_number if line_number
+ success = runner.run
+ @examples_run = true
+ heckle if heckle_runner
+ success
+ end
+ ensure
+ after_suite_parts.each do |part|
+ part.call(success)
+ end
end
end
@@ -101,10 +125,14 @@ module Spec
def colour=(colour)
@colour = colour
- begin; \
- require 'Win32/Console/ANSI' if @colour && PLATFORM =~ /win32/; \
- rescue LoadError ; \
- raise "You must gem install win32console to use colour on Windows" ; \
+ if @colour && RUBY_PLATFORM =~ /win32/ ;\
+ begin ;\
+ require 'rubygems' ;\
+ require 'Win32/Console/ANSI' ;\
+ rescue LoadError ;\
+ warn "You must 'gem install win32console' to use colour on Windows" ;\
+ @colour = false ;\
+ end
end
end
@@ -170,11 +198,29 @@ module Spec
end
def number_of_examples
- @example_groups.inject(0) do |sum, example_group|
- sum + example_group.number_of_examples
+ total = 0
+ @example_groups.each do |example_group|
+ total += example_group.number_of_examples
end
+ total
end
+ def files_to_load
+ result = []
+ sorted_files.each do |file|
+ if File.directory?(file)
+ filename_pattern.split(",").each do |pattern|
+ result += Dir[File.expand_path("#{file}/#{pattern.strip}")]
+ end
+ elsif File.file?(file)
+ result << file
+ else
+ raise "File or directory not found: #{file}"
+ end
+ end
+ result
+ end
+
protected
def examples_should_be_run?
return @examples_should_be_run unless @examples_should_be_run.nil?
@@ -205,20 +251,6 @@ module Spec
end
end
- def files_to_load
- result = []
- sorted_files.each do |file|
- if test ?d, file
- result += Dir[File.expand_path("#{file}/**/*.rb")]
- elsif test ?f, file
- result << file
- else
- raise "File or directory not found: #{file}"
- end
- end
- result
- end
-
def custom_runner
return nil unless custom_runner?
klass_name, arg = ClassAndArgumentsParser.parse(user_input_for_runner)
@@ -231,9 +263,9 @@ module Spec
end
def heckle
- returns = self.heckle_runner.heckle_with
+ heckle_runner = self.heckle_runner
self.heckle_runner = nil
- returns
+ heckle_runner.heckle_with
end
def sorted_files
@@ -248,6 +280,30 @@ module Spec
require 'spec/expectations/differs/default'
self.differ_class = Spec::Expectations::Differs::Default
end
+
+ def set_spec_from_line_number
+ if examples.empty?
+ if files.length == 1
+ if File.directory?(files[0])
+ error_stream.puts "You must specify one file, not a directory when using the --line option"
+ exit(1) if stderr?
+ else
+ example = SpecParser.new.spec_name_for(files[0], line_number)
+ @examples = [example]
+ end
+ else
+ error_stream.puts "Only one file can be specified when using the --line option: #{files.inspect}"
+ exit(3) if stderr?
+ end
+ else
+ error_stream.puts "You cannot use both --line and --example"
+ exit(4) if stderr?
+ end
+ end
+
+ def stderr?
+ @error_stream == $stderr
+ end
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/reporter.rb b/vendor/plugins/rspec/lib/spec/runner/reporter.rb
index cfc511baf..66db38406 100644
--- a/vendor/plugins/rspec/lib/spec/runner/reporter.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/reporter.rb
@@ -26,7 +26,7 @@ module Spec
if error.nil?
example_passed(example)
elsif Spec::Example::ExamplePendingError === error
- example_pending(example_groups.last, example, error.message)
+ example_pending(example, error.message)
else
example_failed(example, error)
end
@@ -34,8 +34,7 @@ module Spec
def failure(example, error)
backtrace_tweaker.tweak_backtrace(error)
- example_name = "#{example_groups.last.description} #{example.description}"
- failure = Failure.new(example_name, error)
+ failure = Failure.new(example, error)
@failures << failure
formatters.each do |f|
f.example_failed(example, @failures.length, failure)
@@ -91,6 +90,7 @@ module Spec
index + 1
end
end
+
def dump_pending
formatters.each{|f| f.dump_pending}
end
@@ -104,28 +104,28 @@ module Spec
formatters.each{|f| f.example_passed(example)}
end
- def example_pending(example_group, example, message="Not Yet Implemented")
+ def example_pending(example, message="Not Yet Implemented")
@pending_count += 1
formatters.each do |f|
- f.example_pending(example_group.description, example, message)
+ f.example_pending(example, message)
end
end
class Failure
- attr_reader :exception
+ attr_reader :example, :exception
- def initialize(example_name, exception)
- @example_name = example_name
+ def initialize(example, exception)
+ @example = example
@exception = exception
end
def header
if expectation_not_met?
- "'#{@example_name}' FAILED"
+ "'#{example_name}' FAILED"
elsif pending_fixed?
- "'#{@example_name}' FIXED"
+ "'#{example_name}' FIXED"
else
- "#{@exception.class.name} in '#{@example_name}'"
+ "#{@exception.class.name} in '#{example_name}'"
end
end
@@ -137,6 +137,10 @@ module Spec
@exception.is_a?(Spec::Expectations::ExpectationNotMetError)
end
+ protected
+ def example_name
+ @example.__full_description
+ end
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb b/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb
index 5ce51e3b2..8beb384e9 100644
--- a/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb
+++ b/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb
@@ -2,14 +2,28 @@ module Spec
module Runner
# Parses a spec file and finds the nearest example for a given line number.
class SpecParser
- def spec_name_for(io, line_number)
- source = io.read
- example_group, example_group_line = example_group_at_line(source, line_number)
- example, example_line = example_at_line(source, line_number)
- if example_group && example && (example_group_line < example_line)
- "#{example_group} #{example}"
- elsif example_group
- example_group
+ attr_reader :best_match
+
+ def initialize
+ @best_match = {}
+ end
+
+ def spec_name_for(file, line_number)
+ best_match.clear
+ file = File.expand_path(file)
+ rspec_options.example_groups.each do |example_group|
+ consider_example_groups_for_best_match example_group, file, line_number
+
+ example_group.examples.each do |example|
+ consider_example_for_best_match example, example_group, file, line_number
+ end
+ end
+ if best_match[:example_group]
+ if best_match[:example]
+ "#{best_match[:example_group].description} #{best_match[:example].description}"
+ else
+ best_match[:example_group].description
+ end
else
nil
end
@@ -17,36 +31,40 @@ module Spec
protected
- def example_group_at_line(source, line_number)
- find_above(source, line_number, /^\s*(context|describe)\s+(.*)\s+do/)
- end
-
- def example_at_line(source, line_number)
- find_above(source, line_number, /^\s*(specify|it)\s+(.*)\s+do/)
+ def consider_example_groups_for_best_match(example_group, file, line_number)
+ parsed_backtrace = parse_backtrace(example_group.registration_backtrace)
+ parsed_backtrace.each do |example_file, example_line|
+ if is_best_match?(file, line_number, example_file, example_line)
+ best_match.clear
+ best_match[:example_group] = example_group
+ best_match[:line] = example_line
+ end
+ end
end
- # Returns the context/describe or specify/it name and the line number
- def find_above(source, line_number, pattern)
- lines_above_reversed(source, line_number).each_with_index do |line, n|
- return [parse_description($2), line_number-n] if line =~ pattern
+ def consider_example_for_best_match(example, example_group, file, line_number)
+ parsed_backtrace = parse_backtrace(example.implementation_backtrace)
+ parsed_backtrace.each do |example_file, example_line|
+ if is_best_match?(file, line_number, example_file, example_line)
+ best_match.clear
+ best_match[:example_group] = example_group
+ best_match[:example] = example
+ best_match[:line] = example_line
+ end
end
- nil
end
- def lines_above_reversed(source, line_number)
- lines = source.split("\n")
- lines[0...line_number].reverse
+ def is_best_match?(file, line_number, example_file, example_line)
+ file == File.expand_path(example_file) &&
+ example_line <= line_number &&
+ example_line > best_match[:line].to_i
end
-
- def parse_description(str)
- return str[1..-2] if str =~ /^['"].*['"]$/
- if matches = /^['"](.*)['"](,.*)?$/.match(str)
- return ::Spec::Example::ExampleGroupMethods.description_text(matches[1])
- end
- if matches = /^(.*)\s*,\s*['"](.*)['"](,.*)?$/.match(str)
- return ::Spec::Example::ExampleGroupMethods.description_text(matches[1], matches[2])
+
+ def parse_backtrace(backtrace)
+ backtrace.collect do |trace_line|
+ split_line = trace_line.split(':')
+ [split_line[0], Integer(split_line[1])]
end
- return str
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/story/extensions/regexp.rb b/vendor/plugins/rspec/lib/spec/story/extensions/regexp.rb
index 7955b4c33..8ee338605 100644
--- a/vendor/plugins/rspec/lib/spec/story/extensions/regexp.rb
+++ b/vendor/plugins/rspec/lib/spec/story/extensions/regexp.rb
@@ -1,9 +1,9 @@
class Regexp
def step_name
- self.source
+ self.source.gsub '\\$', '$$'
end
def arg_regexp
::Spec::Story::Step::PARAM_OR_GROUP_PATTERN
end
-end \ No newline at end of file
+end
diff --git a/vendor/plugins/rspec/lib/spec/story/extensions/string.rb b/vendor/plugins/rspec/lib/spec/story/extensions/string.rb
index 896578def..0e4ec1d68 100644
--- a/vendor/plugins/rspec/lib/spec/story/extensions/string.rb
+++ b/vendor/plugins/rspec/lib/spec/story/extensions/string.rb
@@ -4,6 +4,6 @@ class String
end
def arg_regexp
- ::Spec::Story::Step::PARAM_PATTERN
+ ::Spec::Story::Step::PARAM_OR_GROUP_PATTERN
end
-end \ No newline at end of file
+end
diff --git a/vendor/plugins/rspec/lib/spec/story/runner.rb b/vendor/plugins/rspec/lib/spec/story/runner.rb
index 2dd36fbc6..3d7ed59b5 100644
--- a/vendor/plugins/rspec/lib/spec/story/runner.rb
+++ b/vendor/plugins/rspec/lib/spec/story/runner.rb
@@ -10,16 +10,17 @@ module Spec
module Runner
class << self
def run_options # :nodoc:
- @run_options ||= ::Spec::Runner::OptionParser.parse(ARGV, $stderr, $stdout)
+ rspec_options
+ # @run_options ||= ::Spec::Runner::OptionParser.parse(ARGV, $stderr, $stdout)
end
def story_runner # :nodoc:
unless @story_runner
- @story_runner = StoryRunner.new(scenario_runner, world_creator)
+ @story_runner = create_story_runner
run_options.story_formatters.each do |formatter|
register_listener(formatter)
end
- Runner.register_exit_hook
+ self.register_exit_hook
end
@story_runner
end
@@ -32,6 +33,10 @@ module Spec
@world_creator ||= World
end
+ def create_story_runner
+ StoryRunner.new(scenario_runner, world_creator)
+ end
+
# Use this to register a customer output formatter.
def register_listener(listener)
story_runner.add_listener(listener) # run_started, story_started, story_ended, #run_ended
@@ -40,12 +45,9 @@ module Spec
end
def register_exit_hook # :nodoc:
- # TODO - when story runner uses test/unit runners like example runner does we can kill
- # this and also the assorted Kernel.stub!(:at_exit) in examples
at_exit do
- Runner.story_runner.run_stories unless $!
+ exit Runner.story_runner.run_stories unless $!
end
- # TODO exit with non-zero status if run fails
end
def dry_run
diff --git a/vendor/plugins/rspec/lib/spec/story/runner/plain_text_story_runner.rb b/vendor/plugins/rspec/lib/spec/story/runner/plain_text_story_runner.rb
index 8d34ea2d2..a1bfbda4f 100644
--- a/vendor/plugins/rspec/lib/spec/story/runner/plain_text_story_runner.rb
+++ b/vendor/plugins/rspec/lib/spec/story/runner/plain_text_story_runner.rb
@@ -26,9 +26,9 @@ module Spec
@story_file = path
end
- def run
+ def run(story_runner=Spec::Story::Runner.story_runner)
raise "You must set a path to the file with the story. See the RDoc." if @story_file.nil?
- mediator = Spec::Story::Runner::StoryMediator.new(steps, Spec::Story::Runner.story_runner, @options)
+ mediator = Spec::Story::Runner::StoryMediator.new(steps, story_runner, @options)
parser = Spec::Story::Runner::StoryParser.new(mediator)
story_text = File.read(@story_file)
diff --git a/vendor/plugins/rspec/lib/spec/story/runner/scenario_runner.rb b/vendor/plugins/rspec/lib/spec/story/runner/scenario_runner.rb
index aee52e412..2d7c58d03 100644
--- a/vendor/plugins/rspec/lib/spec/story/runner/scenario_runner.rb
+++ b/vendor/plugins/rspec/lib/spec/story/runner/scenario_runner.rb
@@ -11,6 +11,12 @@ module Spec
run_story_ignoring_scenarios(scenario.story, world)
world.start_collecting_errors
+
+ unless scenario.body
+ @listeners.each { |l| l.scenario_pending(scenario.story.title, scenario.name, '') }
+ return true
+ end
+
world.instance_eval(&scenario.body)
if world.errors.empty?
@listeners.each { |l| l.scenario_succeeded(scenario.story.title, scenario.name) }
@@ -19,8 +25,10 @@ module Spec
@listeners.each { |l| l.scenario_pending(scenario.story.title, scenario.name, e.message) }
else
@listeners.each { |l| l.scenario_failed(scenario.story.title, scenario.name, e) }
+ return false
end
end
+ true
end
def add_listener(listener)
diff --git a/vendor/plugins/rspec/lib/spec/story/runner/story_mediator.rb b/vendor/plugins/rspec/lib/spec/story/runner/story_mediator.rb
index 1f4744b9f..826f322ee 100644
--- a/vendor/plugins/rspec/lib/spec/story/runner/story_mediator.rb
+++ b/vendor/plugins/rspec/lib/spec/story/runner/story_mediator.rb
@@ -64,7 +64,7 @@
title = @title
narrative = @narrative
scenarios = @scenarios.collect { |scenario| scenario.to_proc }
- options = @options.merge(:steps => @step_group)
+ options = @options.merge(:steps_for => @step_group)
lambda do
Story title, narrative, options do
scenarios.each { |scenario| instance_eval(&scenario) }
diff --git a/vendor/plugins/rspec/lib/spec/story/runner/story_runner.rb b/vendor/plugins/rspec/lib/spec/story/runner/story_runner.rb
index f9eeb9ac1..a63479783 100644
--- a/vendor/plugins/rspec/lib/spec/story/runner/story_runner.rb
+++ b/vendor/plugins/rspec/lib/spec/story/runner/story_runner.rb
@@ -36,6 +36,7 @@ module Spec
def run_stories
return if @stories.empty?
@listeners.each { |l| l.run_started(scenarios.size) }
+ success = true
@stories.each do |story|
story.assign_steps_to(World)
@current_story = story
@@ -45,7 +46,7 @@ module Spec
type = story[:type] || Object
args = story[:args] || []
world = @world_creator.create(type, *args)
- @scenario_runner.run(scenario, world)
+ success = success & @scenario_runner.run(scenario, world)
end
@listeners.each { |l| l.story_ended(story.title, story.narrative) }
World.step_mother.clear
@@ -53,6 +54,7 @@ module Spec
unique_steps = (World.step_names.collect {|n| Regexp === n ? n.source : n.to_s}).uniq.sort
@listeners.each { |l| l.collected_steps(unique_steps) }
@listeners.each { |l| l.run_ended }
+ return success
end
def add_listener(listener)
diff --git a/vendor/plugins/rspec/lib/spec/story/step.rb b/vendor/plugins/rspec/lib/spec/story/step.rb
index 1d596e92c..5cd8765d6 100644
--- a/vendor/plugins/rspec/lib/spec/story/step.rb
+++ b/vendor/plugins/rspec/lib/spec/story/step.rb
@@ -1,8 +1,8 @@
module Spec
module Story
class Step
- PARAM_PATTERN = /(\$\w*)/
- PARAM_OR_GROUP_PATTERN = /(\$\w*)|\(.*?\)/
+ PARAM_PATTERN = /([^\\]|^)(\$(?!\$)\w*)/
+ PARAM_OR_GROUP_PATTERN = /(\$(?!\$)\w*)|\(.*?\)/
attr_reader :name
def initialize(name, &block)
@@ -39,18 +39,20 @@ module Spec
private
- def assign_expression(name)
- expression = name.dup
- if String === expression
+ def assign_expression(string_or_regexp)
+ if String === string_or_regexp
+ expression = string_or_regexp.dup
expression.gsub! '(', '\('
expression.gsub! ')', '\)'
- while expression =~ PARAM_PATTERN
- expression.gsub!($1, "(.*?)")
- end
+ elsif Regexp === string_or_regexp
+ expression = string_or_regexp.source
+ end
+ while expression =~ PARAM_PATTERN
+ expression.gsub!($2, "(.*?)")
end
@expression = Regexp.new("^#{expression}$")
end
end
end
-end \ No newline at end of file
+end
diff --git a/vendor/plugins/rspec/lib/spec/story/story.rb b/vendor/plugins/rspec/lib/spec/story/story.rb
index 112e9414b..9cd1a0fec 100644
--- a/vendor/plugins/rspec/lib/spec/story/story.rb
+++ b/vendor/plugins/rspec/lib/spec/story/story.rb
@@ -19,17 +19,14 @@ module Spec
end
def assign_steps_to(assignee)
- if @params[:steps]
- assignee.use(@params[:steps])
- else
- case keys = @params[:steps_for]
- when Symbol
- keys = [keys]
- when nil
- keys = []
- end
- keys.each do |key|
- assignee.use(steps_for(key))
+ if steps=@params[:steps_for]
+ steps = [steps] unless steps.is_a?(Array)
+ steps.each do |step|
+ if step.is_a?(StepGroup)
+ assignee.use(step)
+ else
+ assignee.use(steps_for(step))
+ end
end
end
end
diff --git a/vendor/plugins/rspec/lib/spec/story/world.rb b/vendor/plugins/rspec/lib/spec/story/world.rb
index 6296537b8..a27d3dda9 100644
--- a/vendor/plugins/rspec/lib/spec/story/world.rb
+++ b/vendor/plugins/rspec/lib/spec/story/world.rb
@@ -1,4 +1,3 @@
-require 'rubygems'
require 'spec/expectations'
require 'spec/matchers'
require 'spec/example/pending'
@@ -70,6 +69,7 @@ module Spec
# story_server/prototype/rspec_stories.html (generated by rake stories)
args = step.parse_args(name) if args.empty?
begin
+ listeners.each { |l| l.step_upcoming(type, step_name, *args) }
step.perform(world, *args) unless ::Spec::Story::Runner.dry_run
listeners.each { |l| l.step_succeeded(type, step_name, *args) }
rescue Exception => e
diff --git a/vendor/plugins/rspec/lib/spec/version.rb b/vendor/plugins/rspec/lib/spec/version.rb
index f83a4c697..959bf5189 100644
--- a/vendor/plugins/rspec/lib/spec/version.rb
+++ b/vendor/plugins/rspec/lib/spec/version.rb
@@ -1,22 +1,22 @@
-module Spec
- module VERSION
- unless defined? MAJOR
- MAJOR = 1
- MINOR = 1
- TINY = 2
- RELEASE_CANDIDATE = nil
-
- BUILD_TIME_UTC = 20080114022430
-
- STRING = [MAJOR, MINOR, TINY].join('.')
- TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_')
- FULL_VERSION = "#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('.')} (build #{BUILD_TIME_UTC})"
-
- NAME = "RSpec"
- URL = "http://rspec.rubyforge.org/"
-
- DESCRIPTION = "#{NAME}-#{FULL_VERSION} - BDD for Ruby\n#{URL}"
- end
- end
-end
-
+module Spec
+ module VERSION
+ unless defined? MAJOR
+ MAJOR = 1
+ MINOR = 1
+ TINY = 4
+ RELEASE_CANDIDATE = nil
+
+ BUILD_TIME_UTC = 20080526202855
+
+ STRING = [MAJOR, MINOR, TINY].join('.')
+ TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_')
+ FULL_VERSION = "#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('.')} (build #{BUILD_TIME_UTC})"
+
+ NAME = "RSpec"
+ URL = "http://rspec.rubyforge.org/"
+
+ DESCRIPTION = "#{NAME}-#{FULL_VERSION} - BDD for Ruby\n#{URL}"
+ end
+ end
+end
+