diff options
author | francis <francis> | 2008-01-23 01:54:49 +0000 |
---|---|---|
committer | francis <francis> | 2008-01-23 01:54:49 +0000 |
commit | fdaa98e06ba6d6f8b62480a83e9ecffdbcb21402 (patch) | |
tree | 40b8b0d7602a7a17bead44e0fd3a2ea101b18bd6 /vendor/plugins/rspec/lib | |
parent | 60eaae4f7df1f1dae91defb87d3707451c359cf4 (diff) |
Upgrade to rspec 1.1.2
Diffstat (limited to 'vendor/plugins/rspec/lib')
59 files changed, 884 insertions, 1938 deletions
diff --git a/vendor/plugins/rspec/lib/autotest/rspec.rb b/vendor/plugins/rspec/lib/autotest/rspec.rb index d4b77ea6b..cf7421ee1 100644 --- a/vendor/plugins/rspec/lib/autotest/rspec.rb +++ b/vendor/plugins/rspec/lib/autotest/rspec.rb @@ -1,30 +1,24 @@ require 'autotest' +Autotest.add_hook :initialize do |at| + at.clear_mappings + # watch out: Ruby bug (1.8.6): + # %r(/) != /\// + at.add_mapping(%r%^spec/.*\.rb$%) { |filename, _| + filename + } + at.add_mapping(%r%^lib/(.*)\.rb$%) { |_, m| + ["spec/#{m[1]}_spec.rb"] + } + at.add_mapping(%r%^spec/(spec_helper|shared/.*)\.rb$%) { + at.files_matching %r%^spec/.*_spec\.rb$% + } +end + class RspecCommandError < StandardError; end class Autotest::Rspec < Autotest - def initialize(kernel=Kernel, separator=File::SEPARATOR, alt_separator=File::ALT_SEPARATOR) # :nodoc: - super() - @kernel, @separator, @alt_separator = kernel, separator, alt_separator - @spec_command = spec_command - - # watch out: Ruby bug (1.8.6): - # %r(/) != /\// - # since Ruby compares the REGEXP source, not the resulting pattern - @test_mappings = { - %r%^spec/.*\.rb$% => kernel.proc { |filename, _| - filename - }, - %r%^lib/(.*)\.rb$% => kernel.proc { |_, m| - ["spec/#{m[1]}_spec.rb"] - }, - %r%^spec/(spec_helper|shared/.*)\.rb$% => kernel.proc { - files_matching %r%^spec/.*_spec\.rb$% - } - } - end - def tests_for_file(filename) super.select { |f| @files.has_key? f } end @@ -59,7 +53,7 @@ class Autotest::Rspec < Autotest end def make_test_cmd(files_to_test) - return "#{ruby} -S #{@spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}" + return "#{ruby} -S #{spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}" end def add_options_if_present @@ -71,12 +65,11 @@ class Autotest::Rspec < Autotest # that in ~/.autotest to provide a different spec command # then the default paths provided. def spec_command - spec_commands.each do |command| + @spec_command ||= spec_commands.each do |command| if File.exists?(command) return @alt_separator ? (command.gsub @separator, @alt_separator) : command end end - raise RspecCommandError, "No spec command could be found!" end @@ -87,7 +80,7 @@ class Autotest::Rspec < Autotest # * default spec bin/loader installed in Rubygems def spec_commands [ - File.join('bin', 'spec'), + File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'spec')), File.join(Config::CONFIG['bindir'], 'spec') ] end diff --git a/vendor/plugins/rspec/lib/spec.rb b/vendor/plugins/rspec/lib/spec.rb index 48c12595c..a0fc64750 100644 --- a/vendor/plugins/rspec/lib/spec.rb +++ b/vendor/plugins/rspec/lib/spec.rb @@ -1,13 +1,37 @@ -require 'spec/extensions' require 'spec/version' require 'spec/matchers' require 'spec/expectations' -require 'spec/translator' -require 'spec/dsl' +require 'spec/example' +require 'spec/extensions' require 'spec/runner' -class Object - def metaclass - class << self; self; end +if Object.const_defined?(:Test); \ + require 'spec/interop/test'; \ +end + +module Spec + class << self + def run? + @run || rspec_options.examples_run? + end + + def run; \ + return true if run?; \ + result = rspec_options.run_examples; \ + @run = true; \ + result; \ + end + attr_writer :run + + def exit?; \ + !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/dsl.rb b/vendor/plugins/rspec/lib/spec/dsl.rb deleted file mode 100644 index f960eb907..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'spec/dsl/description' -require 'spec/dsl/errors' -require 'spec/dsl/configuration' -require 'spec/dsl/behaviour_callbacks' -require 'spec/dsl/behaviour' -require 'spec/dsl/behaviour_eval' -require 'spec/dsl/composite_proc_builder' -require 'spec/dsl/example' -require 'spec/dsl/example_matcher' -require 'spec/dsl/example_should_raise_handler' -require 'spec/dsl/behaviour_factory' diff --git a/vendor/plugins/rspec/lib/spec/dsl/behaviour.rb b/vendor/plugins/rspec/lib/spec/dsl/behaviour.rb deleted file mode 100644 index 5158bb673..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/behaviour.rb +++ /dev/null @@ -1,220 +0,0 @@ -module Spec - module DSL - class EvalModule < Module; end - class Behaviour - extend BehaviourCallbacks - - class << self - def add_shared_behaviour(behaviour) - return if behaviour.equal?(found_behaviour = find_shared_behaviour(behaviour.description)) - return if found_behaviour and File.expand_path(behaviour.description[:spec_path]) == File.expand_path(found_behaviour.description[:spec_path]) - raise ArgumentError.new("Shared Behaviour '#{behaviour.description}' already exists") if found_behaviour - shared_behaviours << behaviour - end - - def find_shared_behaviour(behaviour_description) - shared_behaviours.find { |b| b.description == behaviour_description } - end - - def shared_behaviours - # TODO - this needs to be global, or at least accessible from - # from subclasses of Behaviour in a centralized place. I'm not loving - # this as a solution, but it works for now. - $shared_behaviours ||= [] - end - end - - def initialize(*args, &behaviour_block) - init_description(*args) - init_eval_module - before_eval - eval_behaviour(&behaviour_block) - end - - private - - def init_description(*args) - unless self.class == Behaviour - args << {} unless Hash === args.last - args.last[:behaviour_class] = self.class - end - @description = Description.new(*args) - end - - def init_eval_module - @eval_module = EvalModule.new - @eval_module.extend BehaviourEval::ModuleMethods - @eval_module.include BehaviourEval::InstanceMethods - @eval_module.include described_type if described_type.class == Module - @eval_module.behaviour = self - @eval_module.description = @description - end - - def eval_behaviour(&behaviour_block) - @eval_module.class_eval(&behaviour_block) - end - - protected - - def before_eval - end - - public - - def run(reporter, dry_run=false, reverse=false, timeout=nil) - raise "shared behaviours should never run" if shared? - # TODO - change add_behaviour to add_description ?????? - reporter.add_behaviour(@description) - prepare_execution_context_class - before_all_errors = run_before_all(reporter, dry_run) - - exs = reverse ? examples.reverse : examples - example_execution_context = nil - - if before_all_errors.empty? - exs.each do |example| - example_execution_context = execution_context(example) - example_execution_context.copy_instance_variables_from(@before_and_after_all_context_instance) unless before_all_proc(behaviour_type).nil? - - befores = before_each_proc(behaviour_type) {|e| raise e} - afters = after_each_proc(behaviour_type) - example.run(reporter, befores, afters, dry_run, example_execution_context, timeout) - end - end - - @before_and_after_all_context_instance.copy_instance_variables_from(example_execution_context) unless after_all_proc(behaviour_type).nil? - run_after_all(reporter, dry_run) - end - - def number_of_examples - examples.length - end - - def matches?(specified_examples) - matcher ||= ExampleMatcher.new(description) - - examples.each do |example| - return true if example.matches?(matcher, specified_examples) - end - return false - end - - def shared? - @description[:shared] - end - - def retain_examples_matching!(specified_examples) - return if specified_examples.index(description) - matcher = ExampleMatcher.new(description) - examples.reject! do |example| - !example.matches?(matcher, specified_examples) - end - end - - def methods - my_methods = super - my_methods |= @eval_module.methods - my_methods - end - - # Includes modules in the Behaviour (the <tt>describe</tt> block). - def include(*args) - @eval_module.include(*args) - end - - def behaviour_type #:nodoc: - @description[:behaviour_type] - end - - # Sets the #number on each Example and returns the next number - def set_sequence_numbers(number, reverse) #:nodoc: - exs = reverse ? examples.reverse : examples - exs.each do |example| - example.number = number - number += 1 - end - number - end - - protected - - # Messages that this class does not understand - # are passed directly to the @eval_module. - def method_missing(sym, *args, &block) - @eval_module.send(sym, *args, &block) - end - - def prepare_execution_context_class - plugin_mock_framework - weave_in_included_modules - define_predicate_matchers #this is in behaviour_eval - execution_context_class - end - - def weave_in_included_modules - mods = [@eval_module] - mods << included_modules.dup - mods << Spec::Runner.configuration.modules_for(behaviour_type) - execution_context_class.class_eval do - # WARNING - the following can be executed in the context of any - # class, and should never pass more than one module to include - # even though we redefine include in this class. This is NOT - # tested anywhere, hence this comment. - mods.flatten.each {|mod| include mod} - end - end - - def execution_context(example) - execution_context_class.new(example) - end - - def run_before_all(reporter, dry_run) - errors = [] - unless dry_run - begin - @before_and_after_all_context_instance = execution_context(nil) - @before_and_after_all_context_instance.instance_eval(&before_all_proc(behaviour_type)) - rescue Exception => e - errors << e - location = "before(:all)" - # The easiest is to report this as an example failure. We don't have an Example - # at this point, so we'll just create a placeholder. - reporter.example_finished(Example.new(location), e, location) if reporter - end - end - errors - end - - def run_after_all(reporter, dry_run) - unless dry_run - begin - @before_and_after_all_context_instance ||= execution_context(nil) - @before_and_after_all_context_instance.instance_eval(&after_all_proc(behaviour_type)) - rescue Exception => e - location = "after(:all)" - reporter.example_finished(Example.new(location), e, location) if reporter - end - end - end - - def plugin_mock_framework - case mock_framework = Spec::Runner.configuration.mock_framework - when Module - include mock_framework - else - require Spec::Runner.configuration.mock_framework - include Spec::Plugins::MockFramework - end - end - - def description - @description.to_s - end - - def described_type - @description.described_type - end - - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/behaviour_callbacks.rb b/vendor/plugins/rspec/lib/spec/dsl/behaviour_callbacks.rb deleted file mode 100644 index 8b69ad9e5..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/behaviour_callbacks.rb +++ /dev/null @@ -1,82 +0,0 @@ -module Spec - module DSL - # See http://rspec.rubyforge.org/documentation/before_and_after.html - module BehaviourCallbacks - def prepend_before(*args, &block) - scope, options = scope_and_options(*args) - add(scope, options, :before, :unshift, &block) - end - def append_before(*args, &block) - scope, options = scope_and_options(*args) - add(scope, options, :before, :<<, &block) - end - alias_method :before, :append_before - - def prepend_after(*args, &block) - scope, options = scope_and_options(*args) - add(scope, options, :after, :unshift, &block) - end - alias_method :after, :prepend_after - def append_after(*args, &block) - scope, options = scope_and_options(*args) - add(scope, options, :after, :<<, &block) - end - - def scope_and_options(*args) - args, options = args_and_options(*args) - scope = (args[0] || :each), options - end - - def add(scope, options, where, how, &block) - scope ||= :each - options ||= {} - behaviour_type = options[:behaviour_type] - case scope - when :each; self.__send__("#{where}_each_parts", behaviour_type).__send__(how, block) - when :all; self.__send__("#{where}_all_parts", behaviour_type).__send__(how, block) - end - end - - def remove_after(scope, &block) - after_each_parts.delete(block) - end - - # Deprecated. Use before(:each) - def setup(&block) - before(:each, &block) - end - - # Deprecated. Use after(:each) - def teardown(&block) - after(:each, &block) - end - - def before_all_parts(behaviour_type=nil) # :nodoc: - @before_all_parts ||= {} - @before_all_parts[behaviour_type] ||= [] - end - - def after_all_parts(behaviour_type=nil) # :nodoc: - @after_all_parts ||= {} - @after_all_parts[behaviour_type] ||= [] - end - - def before_each_parts(behaviour_type=nil) # :nodoc: - @before_each_parts ||= {} - @before_each_parts[behaviour_type] ||= [] - end - - def after_each_parts(behaviour_type=nil) # :nodoc: - @after_each_parts ||= {} - @after_each_parts[behaviour_type] ||= [] - end - - def clear_before_and_after! # :nodoc: - @before_all_parts = nil - @after_all_parts = nil - @before_each_parts = nil - @after_each_parts = nil - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/behaviour_eval.rb b/vendor/plugins/rspec/lib/spec/dsl/behaviour_eval.rb deleted file mode 100644 index 9f7b8281e..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/behaviour_eval.rb +++ /dev/null @@ -1,231 +0,0 @@ -module Spec - module DSL - module BehaviourEval - module ModuleMethods - include BehaviourCallbacks - - attr_writer :behaviour - attr_accessor :description - - # RSpec runs every example in a new instance of Object, mixing in - # the behaviour necessary to run examples. Because this behaviour gets - # mixed in, it can get mixed in to an instance of any class at all. - # - # This is something that you would hardly ever use, but there is one - # common use case for it - inheriting from Test::Unit::TestCase. RSpec's - # Rails plugin uses this feature to provide access to all of the features - # that are available for Test::Unit within RSpec examples. - def inherit(klass) - raise ArgumentError.new("Shared behaviours cannot inherit from classes") if @behaviour.shared? - @behaviour_superclass = klass - derive_execution_context_class_from_behaviour_superclass - end - - # You can pass this one or many modules. Each module will subsequently - # be included in the each object in which an example is run. Use this - # to provide global helper methods to your examples. - # - # == Example - # - # module HelperMethods - # def helper_method - # ... - # end - # end - # - # describe Thing do - # include HelperMethods - # it "should do stuff" do - # helper_method - # end - # end - def include(*mods) - mods.each do |mod| - included_modules << mod - mod.send :included, self - end - end - - # Use this to pull in examples from shared behaviours. - # See Spec::Runner for information about shared behaviours. - def it_should_behave_like(behaviour_description) - behaviour = @behaviour.class.find_shared_behaviour(behaviour_description) - if behaviour.nil? - raise RuntimeError.new("Shared Behaviour '#{behaviour_description}' can not be found") - end - behaviour.copy_to(self) - end - - def copy_to(eval_module) # :nodoc: - examples.each { |e| eval_module.examples << e; } - before_each_parts.each { |p| eval_module.before_each_parts << p } - after_each_parts.each { |p| eval_module.after_each_parts << p } - before_all_parts.each { |p| eval_module.before_all_parts << p } - after_all_parts.each { |p| eval_module.after_all_parts << p } - included_modules.each { |m| eval_module.included_modules << m } - eval_module.included_modules << self - end - - # :call-seq: - # predicate_matchers[matcher_name] = method_on_object - # predicate_matchers[matcher_name] = [method1_on_object, method2_on_object] - # - # Dynamically generates a custom matcher that will match - # a predicate on your class. RSpec provides a couple of these - # out of the box: - # - # exist (or state expectations) - # File.should exist("path/to/file") - # - # an_instance_of (for mock argument constraints) - # mock.should_receive(:message).with(an_instance_of(String)) - # - # == Examples - # - # class Fish - # def can_swim? - # true - # end - # end - # - # describe Fish do - # predicate_matchers[:swim] = :can_swim? - # it "should swim" do - # Fish.new.should swim - # end - # end - def predicate_matchers - @predicate_matchers ||= {:exist => :exist?, :an_instance_of => :is_a?} - end - - def define_predicate_matchers(hash=nil) # :nodoc: - if hash.nil? - define_predicate_matchers(predicate_matchers) - define_predicate_matchers(Spec::Runner.configuration.predicate_matchers) - else - hash.each_pair do |matcher_method, method_on_object| - define_method matcher_method do |*args| - eval("be_#{method_on_object.to_s.gsub('?','')}(*args)") - end - end - end - end - - # Creates an instance of Spec::DSL::Example and adds - # it to a collection of examples of the current behaviour. - def it(description=:__generate_description, opts={}, &block) - examples << Example.new(description, opts, &block) - end - - # Alias for it. - def specify(description=:__generate_description, opts={}, &block) - it(description, opts, &block) - end - - def methods # :nodoc: - my_methods = super - my_methods |= behaviour_superclass.methods - my_methods - end - - protected - - def method_missing(method_name, *args) - if behaviour_superclass.respond_to?(method_name) - return execution_context_class.send(method_name, *args) - end - super - end - - def before_each_proc(behaviour_type, &error_handler) - parts = [] - parts.push(*Behaviour.before_each_parts(nil)) - parts.push(*Behaviour.before_each_parts(behaviour_type)) unless behaviour_type.nil? - parts.push(*before_each_parts(nil)) - parts.push(*before_each_parts(behaviour_type)) unless behaviour_type.nil? - CompositeProcBuilder.new(parts).proc(&error_handler) - end - - def before_all_proc(behaviour_type, &error_handler) - parts = [] - parts.push(*Behaviour.before_all_parts(nil)) - parts.push(*Behaviour.before_all_parts(behaviour_type)) unless behaviour_type.nil? - parts.push(*before_all_parts(nil)) - parts.push(*before_all_parts(behaviour_type)) unless behaviour_type.nil? - CompositeProcBuilder.new(parts).proc(&error_handler) - end - - def after_all_proc(behaviour_type) - parts = [] - parts.push(*after_all_parts(behaviour_type)) unless behaviour_type.nil? - parts.push(*after_all_parts(nil)) - parts.push(*Behaviour.after_all_parts(behaviour_type)) unless behaviour_type.nil? - parts.push(*Behaviour.after_all_parts(nil)) - CompositeProcBuilder.new(parts).proc - end - - def after_each_proc(behaviour_type) - parts = [] - parts.push(*after_each_parts(behaviour_type)) unless behaviour_type.nil? - parts.push(*after_each_parts(nil)) - parts.push(*Behaviour.after_each_parts(behaviour_type)) unless behaviour_type.nil? - parts.push(*Behaviour.after_each_parts(nil)) - CompositeProcBuilder.new(parts).proc - end - - private - - def execution_context_class - @execution_context_class ||= derive_execution_context_class_from_behaviour_superclass - end - - def derive_execution_context_class_from_behaviour_superclass - @execution_context_class = Class.new(behaviour_superclass) - behaviour_superclass.spec_inherited(self) if behaviour_superclass.respond_to?(:spec_inherited) - @execution_context_class - end - - def behaviour_superclass - @behaviour_superclass ||= Object - end - - protected - def included_modules - @included_modules ||= [::Spec::Matchers] - end - - def examples - @examples ||= [] - end - end - - module InstanceMethods - def initialize(*args, &block) #:nodoc: - # TODO - inheriting from TestUnit::TestCase fails without this - # - let's figure out why and move this somewhere else - end - - def violated(message="") - raise Spec::Expectations::ExpectationNotMetError.new(message) - end - - def inspect - "[RSpec example]" - end - - def pending(message) - if block_given? - begin - yield - rescue Exception => e - raise Spec::DSL::ExamplePendingError.new(message) - end - raise Spec::DSL::PendingFixedError.new("Expected pending '#{message}' to fail. No Error was raised.") - else - raise Spec::DSL::ExamplePendingError.new(message) - end - end - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/behaviour_factory.rb b/vendor/plugins/rspec/lib/spec/dsl/behaviour_factory.rb deleted file mode 100755 index 44b60c641..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/behaviour_factory.rb +++ /dev/null @@ -1,42 +0,0 @@ -module Spec - module DSL - class BehaviourFactory - - class << self - - BEHAVIOUR_CLASSES = {:default => Spec::DSL::Behaviour} - - # Registers a behaviour class +klass+ with the symbol - # +behaviour_type+. For example: - # - # Spec::DSL::BehaviourFactory.add_behaviour_class(:farm, Spec::Farm::DSL::FarmBehaviour) - # - # This will cause Kernel#describe from a file living in - # <tt>spec/farm</tt> to create behaviour instances of type - # Spec::Farm::DSL::FarmBehaviour. - def add_behaviour_class(behaviour_type, klass) - BEHAVIOUR_CLASSES[behaviour_type] = klass - end - - def remove_behaviour_class(behaviour_type) - BEHAVIOUR_CLASSES.delete(behaviour_type) - end - - def create(*args, &block) - opts = Hash === args.last ? args.last : {} - if opts[:shared] - behaviour_type = :default - elsif opts[:behaviour_type] - behaviour_type = opts[:behaviour_type] - elsif opts[:spec_path] =~ /spec(\\|\/)(#{BEHAVIOUR_CLASSES.keys.join('|')})/ - behaviour_type = $2.to_sym - else - behaviour_type = :default - end - return BEHAVIOUR_CLASSES[behaviour_type].new(*args, &block) - end - - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/composite_proc_builder.rb b/vendor/plugins/rspec/lib/spec/dsl/composite_proc_builder.rb deleted file mode 100644 index 373f44953..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/composite_proc_builder.rb +++ /dev/null @@ -1,33 +0,0 @@ -module Spec - module DSL - class CompositeProcBuilder < Array - def initialize(callbacks=[]) - push(*callbacks) - end - - def proc(&error_handler) - parts = self - errors = [] - Proc.new do - result = parts.collect do |part| - begin - if part.is_a?(UnboundMethod) - part.bind(self).call - else - instance_eval(&part) - end - rescue Exception => e - if error_handler - error_handler.call(e) - else - errors << e - end - end - end - raise errors.first unless errors.empty? - result - end - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/configuration.rb b/vendor/plugins/rspec/lib/spec/dsl/configuration.rb deleted file mode 100755 index 709574ded..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/configuration.rb +++ /dev/null @@ -1,135 +0,0 @@ -module Spec - module DSL - class Configuration - - # Chooses what mock framework to use. Example: - # - # Spec::Runner.configure do |config| - # 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. - # 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). - # - # Once you've defined this module, you can pass that to mock_with: - # - # Spec::Runner.configure do |config| - # config.mock_with MyMockFrameworkAdapter - # end - # - def mock_with(mock_framework) - @mock_framework = case mock_framework - when Symbol - mock_framework_path(mock_framework.to_s) - else - mock_framework - end - end - - def mock_framework # :nodoc: - @mock_framework ||= mock_framework_path("rspec") - end - - # Declares modules to be included in all behaviours (<tt>describe</tt> blocks). - # - # config.include(My::Bottle, My::Cup) - # - # If you want to restrict the inclusion to a subset of all the behaviours then - # specify this in a Hash as the last argument: - # - # config.include(My::Pony, My::Horse, :behaviour_type => :farm) - # - # Only behaviours that have that type will get the modules included: - # - # describe "Downtown", :behaviour_type => :city do - # # Will *not* get My::Pony and My::Horse included - # end - # - # describe "Old Mac Donald", :behaviour_type => :farm do - # # *Will* get My::Pony and My::Horse included - # end - # - def include(*args) - args << {} unless Hash === args.last - modules, options = args_and_options(*args) - required_behaviour_type = options[:behaviour_type] - required_behaviour_type = required_behaviour_type.to_sym unless required_behaviour_type.nil? - @modules ||= {} - @modules[required_behaviour_type] ||= [] - @modules[required_behaviour_type] += modules - end - - def modules_for(required_behaviour_type) #:nodoc: - @modules ||= {} - modules = @modules[nil] || [] # general ones - modules << @modules[required_behaviour_type.to_sym] unless required_behaviour_type.nil? - modules.uniq.compact - end - - # This is just for cleanup in RSpec's own examples - def exclude(*modules) #:nodoc: - @modules.each do |behaviour_type, mods| - modules.each{|m| mods.delete(m)} - end - end - - # Defines global predicate matchers. Example: - # - # config.predicate_matchers[:swim] = :can_swim? - # - # This makes it possible to say: - # - # person.should swim # passes if person.should_swim? returns true - # - def predicate_matchers - @predicate_matchers ||= {} - end - - # Prepends a global <tt>before</tt> block to all behaviours. - # See #append_before for filtering semantics. - def prepend_before(*args, &proc) - Behaviour.prepend_before(*args, &proc) - end - # Appends a global <tt>before</tt> block to all behaviours. - # - # If you want to restrict the block to a subset of all the behaviours then - # specify this in a Hash as the last argument: - # - # config.prepend_before(:all, :behaviour_type => :farm) - # - # or - # - # config.prepend_before(:behaviour_type => :farm) - # - def append_before(*args, &proc) - Behaviour.append_before(*args, &proc) - end - alias_method :before, :append_before - - # Prepends a global <tt>after</tt> block to all behaviours. - # See #append_before for filtering semantics. - def prepend_after(*args, &proc) - Behaviour.prepend_after(*args, &proc) - end - alias_method :after, :prepend_after - # Appends a global <tt>after</tt> block to all behaviours. - # See #append_before for filtering semantics. - def append_after(*args, &proc) - Behaviour.append_after(*args, &proc) - end - - private - - def mock_framework_path(framework_name) - File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "plugins", "mock_frameworks", framework_name)) - end - - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/description.rb b/vendor/plugins/rspec/lib/spec/dsl/description.rb deleted file mode 100755 index fe8c9b0c9..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/description.rb +++ /dev/null @@ -1,76 +0,0 @@ -module Spec - module DSL - class Description - module ClassMethods - def generate_description(*args) - description = args.shift.to_s - unless args.empty? - suffix = args.shift.to_s - description << " " unless suffix =~ /^\s|\.|#/ - description << suffix - end - description - end - end - extend ClassMethods - - attr_reader :description, :described_type - - def initialize(*args) - args, @options = args_and_options(*args) - init_behaviour_type(@options) - init_spec_path(@options) - init_described_type(args) - init_description(*args) - end - - def [](key) - @options[key] - end - - def []=(key, value) - @options[key] = value - end - - def to_s; @description; end - - def ==(value) - case value - when Description - @description == value.description - else - @description == value - end - end - - private - def init_behaviour_type(options) - # NOTE - BE CAREFUL IF CHANGING THIS NEXT LINE: - # this line is as it is to satisfy JRuby - the original version - # read, simply: "if options[:behaviour_class]", which passed against ruby, but failed against jruby - if options[:behaviour_class] && options[:behaviour_class].ancestors.include?(Behaviour) - options[:behaviour_type] = parse_behaviour_type(@options[:behaviour_class]) - end - end - - def init_spec_path(options) - if options.has_key?(:spec_path) - options[:spec_path] = File.expand_path(@options[:spec_path]) - end - end - - def init_description(*args) - @description = self.class.generate_description(*args) - end - - def init_described_type(args) - @described_type = args.first unless args.first.is_a?(String) - end - - def parse_behaviour_type(behaviour_class) - behaviour_class.to_s.split("::").reverse[0].gsub!('Behaviour', '').downcase.to_sym - end - - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/errors.rb b/vendor/plugins/rspec/lib/spec/dsl/errors.rb deleted file mode 100644 index ba7046a89..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/errors.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Spec - module DSL - class ExamplePendingError < StandardError - end - - class PendingFixedError < StandardError - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/example.rb b/vendor/plugins/rspec/lib/spec/dsl/example.rb deleted file mode 100644 index d04073f7e..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/example.rb +++ /dev/null @@ -1,135 +0,0 @@ -require 'timeout' - -module Spec - module DSL - class Example - # The global sequence number of this example - attr_accessor :number - - def initialize(description, options={}, &example_block) - @from = caller(0)[3] - @options = options - @example_block = example_block - @description = description - @description_generated_proc = lambda { |desc| @generated_description = desc } - end - - def run(reporter, before_each_block, after_each_block, dry_run, execution_context, timeout=nil) - @dry_run = dry_run - reporter.example_started(self) - return reporter.example_finished(self) if dry_run - - errors = [] - location = nil - Timeout.timeout(timeout) do - before_each_ok = before_example(execution_context, errors, &before_each_block) - example_ok = run_example(execution_context, errors) if before_each_ok - after_each_ok = after_example(execution_context, errors, &after_each_block) - location = failure_location(before_each_ok, example_ok, after_each_ok) - end - - ExampleShouldRaiseHandler.new(@from, @options).handle(errors) - reporter.example_finished(self, errors.first, location, @example_block.nil?) if reporter - end - - def matches?(matcher, specified_examples) - matcher.example_desc = description - matcher.matches?(specified_examples) - end - - def description - @description == :__generate_description ? generated_description : @description - end - - def to_s - description - end - - private - - def generated_description - return @generated_description if @generated_description - if @dry_run - "NO NAME (Because of --dry-run)" - else - if @failed - "NO NAME (Because of Error raised in matcher)" - else - "NO NAME (Because there were no expectations)" - end - end - end - - def before_example(execution_context, errors, &behaviour_before_block) - setup_mocks(execution_context) - Spec::Matchers.description_generated(@description_generated_proc) - - builder = CompositeProcBuilder.new - before_proc = builder.proc(&append_errors(errors)) - execution_context.instance_eval(&before_proc) - - execution_context.instance_eval(&behaviour_before_block) if behaviour_before_block - return errors.empty? - rescue Exception => e - @failed = true - errors << e - return false - end - - def run_example(execution_context, errors) - begin - execution_context.instance_eval(&@example_block) if @example_block - return true - rescue Exception => e - @failed = true - errors << e - return false - end - end - - def after_example(execution_context, errors, &behaviour_after_each) - execution_context.instance_eval(&behaviour_after_each) if behaviour_after_each - - begin - verify_mocks(execution_context) - ensure - teardown_mocks(execution_context) - end - - Spec::Matchers.unregister_description_generated(@description_generated_proc) - - builder = CompositeProcBuilder.new - after_proc = builder.proc(&append_errors(errors)) - execution_context.instance_eval(&after_proc) - - return errors.empty? - rescue Exception => e - @failed = true - errors << e - return false - end - - def setup_mocks(execution_context) - execution_context.setup_mocks_for_rspec if execution_context.respond_to?(:setup_mocks_for_rspec) - end - - def verify_mocks(execution_context) - execution_context.verify_mocks_for_rspec if execution_context.respond_to?(:verify_mocks_for_rspec) - end - - def teardown_mocks(execution_context) - execution_context.teardown_mocks_for_rspec if execution_context.respond_to?(:teardown_mocks_for_rspec) - end - - def append_errors(errors) - proc {|error| errors << error} - end - - def failure_location(before_each_ok, example_ok, after_each_ok) - return 'before(:each)' unless before_each_ok - return description unless example_ok - return 'after(:each)' unless after_each_ok - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/example_matcher.rb b/vendor/plugins/rspec/lib/spec/dsl/example_matcher.rb deleted file mode 100755 index 18cc47409..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/example_matcher.rb +++ /dev/null @@ -1,40 +0,0 @@ -module Spec - module DSL - class ExampleMatcher - - attr_writer :example_desc - def initialize(behaviour_desc, example_desc=nil) - @behaviour_desc = behaviour_desc - @example_desc = example_desc - end - - def matches?(specified_examples) - specified_examples.each do |specified_example| - return true if matches_literal_example?(specified_example) || matches_example_not_considering_modules?(specified_example) - end - false - end - - private - def matches_literal_example?(specified_example) - specified_example =~ /(^#{context_regexp} #{example_regexp}$|^#{context_regexp}$|^#{example_regexp}$)/ - end - - def matches_example_not_considering_modules?(specified_example) - specified_example =~ /(^#{context_regexp_not_considering_modules} #{example_regexp}$|^#{context_regexp_not_considering_modules}$|^#{example_regexp}$)/ - end - - def context_regexp - Regexp.escape(@behaviour_desc) - end - - def context_regexp_not_considering_modules - Regexp.escape(@behaviour_desc.split('::').last) - end - - def example_regexp - Regexp.escape(@example_desc) - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/dsl/example_should_raise_handler.rb b/vendor/plugins/rspec/lib/spec/dsl/example_should_raise_handler.rb deleted file mode 100644 index 942327317..000000000 --- a/vendor/plugins/rspec/lib/spec/dsl/example_should_raise_handler.rb +++ /dev/null @@ -1,74 +0,0 @@ -module Spec - module DSL - class ExampleShouldRaiseHandler - def initialize(file_and_line_number, opts) - @file_and_line_number = file_and_line_number - @options = opts - @expected_error_class = determine_error_class(opts) - @expected_error_message = determine_error_message(opts) - end - - def determine_error_class(opts) - if candidate = opts[:should_raise] - if candidate.is_a?(Class) - return candidate - elsif candidate.is_a?(Array) - return candidate[0] - else - return Exception - end - end - end - - def determine_error_message(opts) - if candidate = opts[:should_raise] - if candidate.is_a?(Array) - return candidate[1] - end - end - return nil - end - - def build_message(exception=nil) - if @expected_error_message.nil? - message = "example block expected #{@expected_error_class.to_s}" - else - message = "example block expected #{@expected_error_class.new(@expected_error_message.to_s).inspect}" - end - message << " but raised #{exception.inspect}" if exception - message << " but nothing was raised" unless exception - message << "\n" - message << @file_and_line_number - end - - def error_matches?(error) - return false unless error.kind_of?(@expected_error_class) - unless @expected_error_message.nil? - if @expected_error_message.is_a?(Regexp) - return false unless error.message =~ @expected_error_message - else - return false unless error.message == @expected_error_message - end - end - return true - end - - def handle(errors) - if @expected_error_class - if errors.empty? - errors << Spec::Expectations::ExpectationNotMetError.new(build_message) - else - error_to_remove = errors.detect do |error| - error_matches?(error) - end - if error_to_remove.nil? - errors.insert(0,Spec::Expectations::ExpectationNotMetError.new(build_message(errors[0]))) - else - errors.delete(error_to_remove) - end - end - end - 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 87e59b3a6..a5eb1bb89 100644 --- a/vendor/plugins/rspec/lib/spec/expectations/differs/default.rb +++ b/vendor/plugins/rspec/lib/spec/expectations/differs/default.rb @@ -12,12 +12,8 @@ module Spec # TODO add some rdoc class Default - def initialize(format=:unified,context_lines=nil,colour=nil) - - context_lines ||= 3 - colour ||= false - - @format,@context_lines,@colour = format,context_lines,colour + def initialize(options) + @options = options end # This is snagged from diff/lcs/ldiff.rb (which is a commandline tool) @@ -31,17 +27,17 @@ module Spec file_length_difference = 0 diffs.each do |piece| begin - hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @context_lines, + hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, context_lines, file_length_difference) file_length_difference = hunk.file_length_difference next unless oldhunk # Hunks may overlap, which is why we need to be careful when our # diff includes lines of context. Otherwise, we might print # redundant lines. - if (@context_lines > 0) and hunk.overlaps?(oldhunk) + if (context_lines > 0) and hunk.overlaps?(oldhunk) hunk.unshift(oldhunk) else - output << oldhunk.diff(@format) + output << oldhunk.diff(format) end ensure oldhunk = hunk @@ -49,12 +45,21 @@ module Spec end end #Handle the last remaining hunk - output << oldhunk.diff(@format) << "\n" + output << oldhunk.diff(format) << "\n" end def diff_as_object(target,expected) diff_as_string(PP.pp(target,""), PP.pp(expected,"")) end + + protected + def format + @options.diff_format + end + + def context_lines + @options.context_lines + end end end end diff --git a/vendor/plugins/rspec/lib/spec/expectations/errors.rb b/vendor/plugins/rspec/lib/spec/expectations/errors.rb index 03e81a064..1fabd105d 100644 --- a/vendor/plugins/rspec/lib/spec/expectations/errors.rb +++ b/vendor/plugins/rspec/lib/spec/expectations/errors.rb @@ -1,6 +1,12 @@ module Spec module Expectations - class ExpectationNotMetError < StandardError + # If Test::Unit is loaed, we'll use its error as baseclass, so that Test::Unit + # will report unmet RSpec expectations as failures rather than errors. + superclass = ['Test::Unit::AssertionFailedError', '::StandardError'].map do |c| + eval(c) rescue nil + end.compact.first + + class ExpectationNotMetError < superclass end end end diff --git a/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb b/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb index f59af722e..a3925bbee 100644 --- a/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb +++ b/vendor/plugins/rspec/lib/spec/expectations/extensions/object.rb @@ -3,7 +3,6 @@ module Spec # rspec adds #should and #should_not to every Object (and, # implicitly, every Class). module ObjectExpectations - # :call-seq: # should(matcher) # should == expected @@ -28,9 +27,12 @@ module Spec # # NOTE that this does NOT support receiver.should != expected. # Instead, use receiver.should_not == expected - def should(matcher=nil, &block) - return ExpectationMatcherHandler.handle_matcher(self, matcher, &block) if matcher - Spec::Matchers::PositiveOperatorMatcher.new(self) + def should(matcher = :default_parameter, &block) + if :default_parameter == matcher + Spec::Matchers::PositiveOperatorMatcher.new(self) + else + ExpectationMatcherHandler.handle_matcher(self, matcher, &block) + end end # :call-seq: @@ -52,9 +54,12 @@ module Spec # => Passes unless (receiver =~ regexp) # # See Spec::Matchers for more information about matchers - def should_not(matcher=nil, &block) - return NegativeExpectationMatcherHandler.handle_matcher(self, matcher, &block) if matcher - Spec::Matchers::NegativeOperatorMatcher.new(self) + def should_not(matcher = :default_parameter, &block) + if :default_parameter == matcher + Spec::Matchers::NegativeOperatorMatcher.new(self) + else + NegativeExpectationMatcherHandler.handle_matcher(self, matcher, &block) + end end end diff --git a/vendor/plugins/rspec/lib/spec/expectations/handler.rb b/vendor/plugins/rspec/lib/spec/expectations/handler.rb index 4caa321e4..e6dce0846 100644 --- a/vendor/plugins/rspec/lib/spec/expectations/handler.rb +++ b/vendor/plugins/rspec/lib/spec/expectations/handler.rb @@ -1,18 +1,23 @@ module Spec module Expectations + class InvalidMatcherError < ArgumentError; end module MatcherHandlerHelper - def describe(matcher) + def describe_matcher(matcher) matcher.respond_to?(:description) ? matcher.description : "[#{matcher.class.name} does not provide a description]" end end - class ExpectationMatcherHandler + class ExpectationMatcherHandler class << self include MatcherHandlerHelper def handle_matcher(actual, matcher, &block) + unless matcher.respond_to?(:matches?) + raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}." + end + match = matcher.matches?(actual, &block) - ::Spec::Matchers.generated_description = "should #{describe(matcher)}" + ::Spec::Matchers.generated_description = "should #{describe_matcher(matcher)}" Spec::Expectations.fail_with(matcher.failure_message) unless match end end @@ -22,6 +27,10 @@ module Spec class << self include MatcherHandlerHelper def handle_matcher(actual, matcher, &block) + unless matcher.respond_to?(:matches?) + raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}." + end + unless matcher.respond_to?(:negative_failure_message) Spec::Expectations.fail_with( <<-EOF @@ -32,7 +41,7 @@ EOF ) end match = matcher.matches?(actual, &block) - ::Spec::Matchers.generated_description = "should not #{describe(matcher)}" + ::Spec::Matchers.generated_description = "should not #{describe_matcher(matcher)}" Spec::Expectations.fail_with(matcher.negative_failure_message) if match end end diff --git a/vendor/plugins/rspec/lib/spec/extensions.rb b/vendor/plugins/rspec/lib/spec/extensions.rb index 824f03bfb..9a313d0e7 100755 --- a/vendor/plugins/rspec/lib/spec/extensions.rb +++ b/vendor/plugins/rspec/lib/spec/extensions.rb @@ -1 +1,3 @@ require 'spec/extensions/object' +require 'spec/extensions/class' +require 'spec/extensions/main' diff --git a/vendor/plugins/rspec/lib/spec/extensions/object.rb b/vendor/plugins/rspec/lib/spec/extensions/object.rb index 6218aa770..e9f6364e2 100755 --- a/vendor/plugins/rspec/lib/spec/extensions/object.rb +++ b/vendor/plugins/rspec/lib/spec/extensions/object.rb @@ -3,4 +3,8 @@ class Object options = Hash === args.last ? args.pop : {} return args, options end -end + + def metaclass + class << self; self; end + end +end diff --git a/vendor/plugins/rspec/lib/spec/matchers.rb b/vendor/plugins/rspec/lib/spec/matchers.rb index fd208d628..afae5ae5f 100644 --- a/vendor/plugins/rspec/lib/spec/matchers.rb +++ b/vendor/plugins/rspec/lib/spec/matchers.rb @@ -1,8 +1,10 @@ +require 'spec/matchers/simple_matcher' require 'spec/matchers/be' require 'spec/matchers/be_close' require 'spec/matchers/change' require 'spec/matchers/eql' require 'spec/matchers/equal' +require 'spec/matchers/exist' require 'spec/matchers/has' require 'spec/matchers/have' require 'spec/matchers/include' @@ -132,27 +134,15 @@ module Spec # module Matchers module ModuleMethods - def description_generated(callback) - description_generated_callbacks << callback - end - - def unregister_description_generated(callback) - description_generated_callbacks.delete(callback) - end - - def generated_description=(name) - description_generated_callbacks.each do |callback| - callback.call(name) - end - end + attr_accessor :generated_description - private - def description_generated_callbacks - @description_generated_callbacks ||= [] + def clear_generated_description + self.generated_description = nil end end + extend ModuleMethods - + def method_missing(sym, *args, &block) # :nodoc: return Matchers::Be.new(sym, *args) if sym.starts_with?("be_") return Matchers::Has.new(sym, *args) if sym.starts_with?("have_") diff --git a/vendor/plugins/rspec/lib/spec/matchers/be.rb b/vendor/plugins/rspec/lib/spec/matchers/be.rb index 0eb1629a6..2b25b11f4 100644 --- a/vendor/plugins/rspec/lib/spec/matchers/be.rb +++ b/vendor/plugins/rspec/lib/spec/matchers/be.rb @@ -3,14 +3,17 @@ module Spec class Be #:nodoc: def initialize(*args) - @expected = parse_expected(args.shift) + if args.empty? + @expected = :satisfy_if + else + @expected = parse_expected(args.shift) + end @args = args @comparison = "" end def matches?(actual) @actual = actual - return true if match_or_compare unless handling_predicate? if handling_predicate? begin return @result = actual.__send__(predicate, *@args) @@ -28,8 +31,9 @@ module Spec rescue raise predicate_error end + else + return match_or_compare end - return false end def failure_message @@ -43,6 +47,7 @@ module Spec end def expected + return "if to be satisfied" if @expected == :satisfy_if return true if @expected == :true return false if @expected == :false return "nil" if @expected == :nil @@ -50,6 +55,7 @@ module Spec end def match_or_compare + return @actual ? true : false if @expected == :satisfy_if return @actual == true if @expected == :true return @actual == false if @expected == :false return @actual.nil? if @expected == :nil @@ -63,6 +69,7 @@ module Spec end def ==(expected) + @prefix = "be " @double_equal = true @comparison = "== " @expected = expected @@ -70,6 +77,7 @@ module Spec end def ===(expected) + @prefix = "be " @triple_equal = true @comparison = "=== " @expected = expected @@ -77,6 +85,7 @@ module Spec end def <(expected) + @prefix = "be " @less_than = true @comparison = "< " @expected = expected @@ -84,6 +93,7 @@ module Spec end def <=(expected) + @prefix = "be " @less_than_or_equal = true @comparison = "<= " @expected = expected @@ -91,6 +101,7 @@ module Spec end def >=(expected) + @prefix = "be " @greater_than_or_equal = true @comparison = ">= " @expected = expected @@ -98,6 +109,7 @@ module Spec end def >(expected) + @prefix = "be " @greater_than = true @comparison = "> " @expected = expected @@ -112,11 +124,14 @@ module Spec def parse_expected(expected) if Symbol === expected @handling_predicate = true - ["be_an_","be_a_","be_"].each do |@prefix| - return "#{expected.to_s.sub(@prefix,"")}".to_sym if expected.starts_with?(@prefix) + ["be_an_","be_a_","be_"].each do |prefix| + if expected.starts_with?(prefix) + @prefix = prefix + return "#{expected.to_s.sub(@prefix,"")}".to_sym + end end end - @prefix = "be " + @prefix = "" return expected end @@ -169,6 +184,7 @@ module Spec end # :call-seq: + # should be # should be_true # should be_false # should be_nil @@ -177,7 +193,8 @@ module Spec # should_not be_arbitrary_predicate(*args) # # Given true, false, or nil, will pass if actual is - # true, false or nil (respectively). + # true, false or nil (respectively). Given no args means + # the caller should satisfy an if condition (to be or not to be). # # Predicates are any Ruby method that ends in a "?" and returns true or false. # Given be_ followed by arbitrary_predicate (without the "?"), RSpec will match @@ -189,6 +206,7 @@ module Spec # # == Examples # + # target.should be # target.should be_true # target.should be_false # target.should be_nil diff --git a/vendor/plugins/rspec/lib/spec/matchers/change.rb b/vendor/plugins/rspec/lib/spec/matchers/change.rb index 41a718aca..784e516ed 100644 --- a/vendor/plugins/rspec/lib/spec/matchers/change.rb +++ b/vendor/plugins/rspec/lib/spec/matchers/change.rb @@ -21,6 +21,8 @@ EOF return false if @from && (@from != @before) return false if @to && (@to != @after) return (@before + @amount == @after) if @amount + return ((@after - @before) >= @minimum) if @minimum + return ((@after - @before) <= @maximum) if @maximum return @before != @after end @@ -37,6 +39,10 @@ EOF "#{result} should have initially been #{@from.inspect}, but was #{@before.inspect}" elsif @amount "#{result} should have been changed by #{@amount.inspect}, but was changed by #{actual_delta.inspect}" + elsif @minimum + "#{result} should have been changed by at least #{@minimum.inspect}, but was changed by #{actual_delta.inspect}" + elsif @maximum + "#{result} should have been changed by at most #{@maximum.inspect}, but was changed by #{actual_delta.inspect}" else "#{result} should have changed, but is still #{@before.inspect}" end @@ -59,6 +65,16 @@ EOF self end + def by_at_least(minimum) + @minimum = minimum + self + end + + def by_at_most(maximum) + @maximum = maximum + self + end + def to(to) @to = to self @@ -88,6 +104,14 @@ EOF # team.add_player(player) # }.should change(roster, :count).by(1) # + # lambda { + # team.add_player(player) + # }.should change(roster, :count).by_at_least(1) + # + # lambda { + # team.add_player(player) + # }.should change(roster, :count).by_at_most(1) + # # string = "string" # lambda { # string.reverse @@ -109,7 +133,7 @@ EOF # # == Warning # +should_not+ +change+ only supports the form with no subsequent calls to - # +be+, +to+ or +from+. + # +by+, +by_at_least+, +by_at_most+, +to+ or +from+. # # blocks passed to +should+ +change+ and +should_not+ +change+ # must use the <tt>{}</tt> form (<tt>do/end</tt> is not supported) diff --git a/vendor/plugins/rspec/lib/spec/matchers/have.rb b/vendor/plugins/rspec/lib/spec/matchers/have.rb index f28b86ad3..47454e3be 100644 --- a/vendor/plugins/rspec/lib/spec/matchers/have.rb +++ b/vendor/plugins/rspec/lib/spec/matchers/have.rb @@ -17,6 +17,7 @@ module Spec def method_missing(sym, *args, &block) @collection_name = sym + @plural_collection_name = Inflector.pluralize(sym.to_s) if Object.const_defined?(:Inflector) @args = args @block = block self @@ -25,6 +26,8 @@ module Spec def matches?(collection_owner) if collection_owner.respond_to?(@collection_name) collection = collection_owner.send(@collection_name, *@args, &@block) + elsif (@plural_collection_name && collection_owner.respond_to?(@plural_collection_name)) + collection = collection_owner.send(@plural_collection_name, *@args, &@block) elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size)) collection = collection_owner else diff --git a/vendor/plugins/rspec/lib/spec/matchers/operator_matcher.rb b/vendor/plugins/rspec/lib/spec/matchers/operator_matcher.rb index 2d47ea85a..dd23a0994 100755 --- a/vendor/plugins/rspec/lib/spec/matchers/operator_matcher.rb +++ b/vendor/plugins/rspec/lib/spec/matchers/operator_matcher.rb @@ -1,6 +1,7 @@ module Spec module Matchers class BaseOperatorMatcher + attr_reader :generated_description def initialize(target) @target = target diff --git a/vendor/plugins/rspec/lib/spec/matchers/throw_symbol.rb b/vendor/plugins/rspec/lib/spec/matchers/throw_symbol.rb index 6d047bc39..c74d84436 100644 --- a/vendor/plugins/rspec/lib/spec/matchers/throw_symbol.rb +++ b/vendor/plugins/rspec/lib/spec/matchers/throw_symbol.rb @@ -4,12 +4,14 @@ module Spec class ThrowSymbol #:nodoc: def initialize(expected=nil) @expected = expected + @actual = nil end def matches?(proc) begin proc.call rescue NameError => e + raise e unless e.message =~ /uncaught throw/ @actual = e.name.to_sym ensure if @expected.nil? diff --git a/vendor/plugins/rspec/lib/spec/mocks.rb b/vendor/plugins/rspec/lib/spec/mocks.rb index 66cbafb3c..9f9cd215b 100644 --- a/vendor/plugins/rspec/lib/spec/mocks.rb +++ b/vendor/plugins/rspec/lib/spec/mocks.rb @@ -170,7 +170,9 @@ module Spec # #error can be an instantiated object or a class # #if it is a class, it must be instantiable with no args # my_mock.should_receive(:sym).and_throw(:sym) - # my_mock.should_receive(:sym).and_yield([array,of,values,to,yield]) + # my_mock.should_receive(:sym).and_yield(values,to,yield) + # my_mock.should_receive(:sym).and_yield(values,to,yield).and_yield(some,other,values,this,time) + # # for methods that yield to a block multiple times # # Any of these responses can be applied to a stub as well, but stubs do # not support any qualifiers about the message received (i.e. you can't specify arguments @@ -180,7 +182,8 @@ module Spec # my_mock.stub!(:sym).and_return(value1, value2, value3) # my_mock.stub!(:sym).and_raise(error) # my_mock.stub!(:sym).and_throw(:sym) - # my_mock.stub!(:sym).and_yield([array,of,values,to,yield]) + # my_mock.stub!(:sym).and_yield(values,to,yield) + # my_mock.stub!(:sym).and_yield(values,to,yield).and_yield(some,other,values,this,time) # # == Arbitrary Handling # diff --git a/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb index 5da069b87..34a1d4d03 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/argument_expectation.rb @@ -138,7 +138,7 @@ module Spec end def warn_deprecated(deprecated_method, instead) - STDERR.puts "The #{deprecated_method} constraint is deprecated. Use #{instead} instead." + Kernel.warn "The #{deprecated_method} constraint is deprecated. Use #{instead} instead." end def convert_constraint(constraint) diff --git a/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb b/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb index 74ade3c58..6bd2f1c32 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/message_expectation.rb @@ -10,8 +10,8 @@ module Spec @expected_from = expected_from @sym = sym @method_block = method_block - @return_block = lambda {} - @received_count = 0 + @return_block = nil + @actual_received_count = 0 @expected_received_count = expected_received_count @args_expectation = ArgumentExpectation.new([AnyArgsConstraint.new]) @consecutive = false @@ -20,7 +20,7 @@ module Spec @order_group = expectation_ordering @at_least = nil @at_most = nil - @args_to_yield = nil + @args_to_yield = [] end def expected_args @@ -29,17 +29,18 @@ module Spec def and_return(*values, &return_block) Kernel::raise AmbiguousReturnError unless @method_block.nil? - if values.size == 0 - value = nil - elsif values.size == 1 - value = values[0] + case values.size + when 0 then value = nil + when 1 then value = values[0] else value = values @consecutive = true - @expected_received_count = values.size if @expected_received_count != :any && + @expected_received_count = values.size if !ignoring_args? && @expected_received_count < values.size end @return_block = block_given? ? return_block : lambda { value } + # Ruby 1.9 - see where this is used below + @ignore_args = !block_given? end # :call-seq: @@ -62,7 +63,8 @@ module Spec end def and_yield(*args) - @args_to_yield = args + @args_to_yield << args + self end def matches(sym, args) @@ -73,25 +75,26 @@ module Spec @order_group.handle_order_constraint self begin - if @exception_to_raise.class == Class - @exception_instance_to_raise = @exception_to_raise.new - else - @exception_instance_to_raise = @exception_to_raise - end Kernel::raise @exception_to_raise unless @exception_to_raise.nil? Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil? - + if !@method_block.nil? - return invoke_method_block(args) - elsif !@args_to_yield.nil? - return invoke_with_yield(block) - elsif @consecutive - return invoke_consecutive_return_block(args, block) + default_return_val = invoke_method_block(args) + elsif @args_to_yield.size > 0 + default_return_val = invoke_with_yield(block) else + default_return_val = nil + end + + if @consecutive + return invoke_consecutive_return_block(args, block) + elsif @return_block return invoke_return_block(args, block) + else + return default_return_val end ensure - @received_count += 1 + @actual_received_count += 1 end end @@ -109,25 +112,32 @@ module Spec if block.nil? @error_generator.raise_missing_block_error @args_to_yield end - if block.arity > -1 && @args_to_yield.length != block.arity - @error_generator.raise_wrong_arity_error @args_to_yield, block.arity + @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) end - block.call(*@args_to_yield) end def invoke_consecutive_return_block(args, block) args << block unless block.nil? value = @return_block.call(*args) - index = [@received_count, value.size-1].min + index = [@actual_received_count, value.size-1].min value[index] end def invoke_return_block(args, block) args << block unless block.nil? - value = @return_block.call(*args) - - value + # Ruby 1.9 - when we set @return_block to return values + # regardless of arguments, any arguments will result in + # a "wrong number of arguments" error + if @ignore_args + @return_block.call() + else + @return_block.call(*args) + end end end @@ -138,17 +148,33 @@ module Spec end def verify_messages_received - return if @expected_received_count == :any - return if (@at_least) && (@received_count >= @expected_received_count) - return if (@at_most) && (@received_count <= @expected_received_count) - return if @expected_received_count == @received_count + return if ignoring_args? || matches_exact_count? || + matches_at_least_count? || matches_at_most_count? - begin - @error_generator.raise_expectation_error(@sym, @expected_received_count, @received_count, *@args_expectation.args) - rescue => error - error.backtrace.insert(0, @expected_from) - Kernel::raise error - end + generate_error + rescue Spec::Mocks::MockExpectationError => error + error.backtrace.insert(0, @expected_from) + Kernel::raise error + end + + def ignoring_args? + @expected_received_count == :any + end + + def matches_at_least_count? + @at_least && @actual_received_count >= @expected_received_count + end + + def matches_at_most_count? + @at_most && @actual_received_count <= @expected_received_count + end + + def matches_exact_count? + @expected_received_count == @actual_received_count + end + + def generate_error + @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args) end def with(*args, &block) @@ -215,9 +241,14 @@ module Spec def set_expected_received_count(relativity, n) @at_least = (relativity == :at_least) @at_most = (relativity == :at_most) - @expected_received_count = 1 if n == :once - @expected_received_count = 2 if n == :twice - @expected_received_count = n if n.kind_of? Numeric + @expected_received_count = case n + when Numeric + n + when :once + 1 + when :twice + 2 + end end end @@ -232,11 +263,5 @@ module Spec end end - class MethodStub < BaseExpectation - def initialize(message, expectation_ordering, expected_from, sym, method_block) - super(message, expectation_ordering, expected_from, sym, method_block, 0) - @expected_received_count = :any - end - end end end diff --git a/vendor/plugins/rspec/lib/spec/mocks/methods.rb b/vendor/plugins/rspec/lib/spec/mocks/methods.rb index 3d898cf31..d9fa324d3 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/methods.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/methods.rb @@ -9,8 +9,8 @@ module Spec __mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block) end - def stub!(sym) - __mock_proxy.add_stub(caller(1)[0], sym.to_sym) + def stub!(sym, opts={}) + __mock_proxy.add_stub(caller(1)[0], sym.to_sym, opts) end def received_message?(sym, *args, &block) #:nodoc: diff --git a/vendor/plugins/rspec/lib/spec/mocks/mock.rb b/vendor/plugins/rspec/lib/spec/mocks/mock.rb index aa380e0af..f029b1b8f 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/mock.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/mock.rb @@ -6,9 +6,18 @@ module Spec # 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, options={}) + def initialize(name, stubs_and_options={}) @name = name - @options = options + @options = parse_options(stubs_and_options) + assign_stubs(stubs_and_options) + end + + # This allows for comparing the mock to other objects that proxy + # such as ActiveRecords belongs_to proxy objects + # By making the other object run the comparison, we're sure the call gets delegated to the proxy target + # This is an unfortunate side effect from ActiveRecord, but this should be safe unless the RHS redefines == in a nonsensical manner + def ==(other) + other == __mock_proxy end def method_missing(sym, *args, &block) @@ -16,7 +25,7 @@ module Spec begin return self if __mock_proxy.null_object? super(sym, *args, &block) - rescue NoMethodError + rescue NameError __mock_proxy.raise_unexpected_message_error sym, *args end end @@ -24,6 +33,18 @@ module Spec def inspect "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>" end + + private + + def parse_options(options) + options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {} + end + + def assign_stubs(stubs) + stubs.each_pair do |message, response| + stub!(message).and_return(response) + end + end end end end diff --git a/vendor/plugins/rspec/lib/spec/mocks/proxy.rb b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb index 6c79d1068..03db3b113 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/proxy.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/proxy.rb @@ -22,29 +22,27 @@ module Spec end def add_message_expectation(expected_from, sym, opts={}, &block) - __add sym, block + __add sym @expectations << MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts) @expectations.last end def add_negative_message_expectation(expected_from, sym, &block) - __add sym, block + __add sym @expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil) @expectations.last end - def add_stub(expected_from, sym) - __add sym, nil - @stubs.unshift MethodStub.new(@error_generator, @expectation_ordering, expected_from, sym, nil) + def add_stub(expected_from, sym, opts={}) + __add sym + @stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts) @stubs.first end def verify #:nodoc: - begin - verify_expectations - ensure - reset - end + verify_expectations + ensure + reset end def reset @@ -55,8 +53,7 @@ module Spec end def received_message?(sym, *args, &block) - return true if @messages_received.find {|array| array == [sym, args, block]} - return false + @messages_received.any? {|array| array == [sym, args, block]} end def has_negative_expectation?(sym) @@ -66,7 +63,7 @@ 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) + elsif stub = find_matching_method_stub(sym, *args) 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? @@ -85,14 +82,17 @@ module Spec private - def __add(sym, block) + def __add(sym) $rspec_mocks.add(@target) unless $rspec_mocks.nil? define_expected_method(sym) end def define_expected_method(sym) - if target_responds_to?(sym) && !@proxied_methods.include?(sym) - metaclass.__send__(:alias_method, munge(sym), sym) if metaclass.instance_methods.include?(sym.to_s) + if target_responds_to?(sym) && !metaclass.method_defined?(munge(sym)) + munged_sym = munge(sym) + metaclass.instance_eval do + alias_method munged_sym, sym if method_defined?(sym.to_s) + end @proxied_methods << sym end @@ -141,11 +141,14 @@ module Spec def reset_proxied_methods @proxied_methods.each do |sym| - if metaclass.instance_methods.include?(munge(sym).to_s) - metaclass.__send__(:alias_method, sym, munge(sym)) - metaclass.__send__(:undef_method, munge(sym)) - else - metaclass.__send__(:undef_method, sym) + munged_sym = munge(sym) + metaclass.instance_eval do + if method_defined?(munged_sym.to_s) + alias_method sym, munged_sym + undef_method munged_sym + else + undef_method sym + end end end end @@ -158,8 +161,8 @@ module Spec @expectations.find {|expectation| expectation.matches_name_but_not_args(sym, args)} end - def find_matching_method_stub(sym) - @stubs.find {|stub| stub.matches(sym, [])} + def find_matching_method_stub(sym, *args) + @stubs.find {|stub| stub.matches(sym, args)} end end diff --git a/vendor/plugins/rspec/lib/spec/mocks/space.rb b/vendor/plugins/rspec/lib/spec/mocks/space.rb index e04bc5ccb..3e13224c7 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/space.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/space.rb @@ -2,7 +2,7 @@ module Spec module Mocks class Space def add(obj) - mocks << obj unless mocks.include?(obj) + mocks << obj unless mocks.detect {|m| m.equal? obj} end def verify_all diff --git a/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb b/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb index fd67fd210..d92a4cedd 100644 --- a/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb +++ b/vendor/plugins/rspec/lib/spec/mocks/spec_methods.rb @@ -1,30 +1,38 @@ module Spec module Mocks - module SpecMethods + module ExampleMethods include Spec::Mocks::ArgumentConstraintMatchers # Shortcut for creating an instance of Spec::Mocks::Mock. - def mock(name, options={}) - Spec::Mocks::Mock.new(name, options) - end - - # Shortcut for creating an instance of Spec::Mocks::Mock with - # predefined method stubs. + # + # +name+ is used for failure reporting, so you should use the + # role that the mock is playing in the example. + # + # +stubs_and_options+ lets you assign options and stub values + # at the same time. The only option available is :null_object. + # Anything else is treated as a stub value. # # == Examples # - # stub_thing = stub("thing", :a => "A") + # stub_thing = mock("thing", :a => "A") # stub_thing.a == "A" => true # # stub_person = stub("thing", :name => "Joe", :email => "joe@domain.com") # stub_person.name => "Joe" # stub_person.email => "joe@domain.com" - def stub(name, stubs={}) - object_stub = mock(name) - stubs.each { |key, value| object_stub.stub!(key).and_return(value) } - object_stub + def mock(name, stubs_and_options={}) + Spec::Mocks::Mock.new(name, stubs_and_options) end + alias :stub :mock + + # Shortcut for creating a mock object that will return itself in response + # to any message it receives that it hasn't been explicitly instructed + # to respond to. + def stub_everything(name = 'stub') + mock(name, :null_object => true) + end + end end end diff --git a/vendor/plugins/rspec/lib/spec/rake/spectask.rb b/vendor/plugins/rspec/lib/spec/rake/spectask.rb index f8c6809a9..c59e226f5 100644 --- a/vendor/plugins/rspec/lib/spec/rake/spectask.rb +++ b/vendor/plugins/rspec/lib/spec/rake/spectask.rb @@ -8,7 +8,7 @@ require 'rake/tasklib' module Spec module Rake - # A Rake task that runs a set of RSpec contexts. + # A Rake task that runs a set of specs. # # Example: # @@ -44,6 +44,17 @@ module Spec # Each attribute of this task may be a proc. This allows for lazy evaluation, # which is sometimes handy if you want to defer the evaluation of an attribute value # until the task is run (as opposed to when it is defined). + # + # This task can also be used to run existing Test::Unit tests and get RSpec + # output, for example like this: + # + # require 'rubygems' + # require 'spec/rake/spectask' + # Spec::Rake::SpecTask.new do |t| + # t.ruby_opts = ['-rtest/unit'] + # t.spec_files = FileList['test/**/*_test.rb'] + # end + # class SpecTask < ::Rake::TaskLib class << self def attr_accessor(*names) @@ -106,6 +117,10 @@ 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 # Defines a new task, using the name +name+. def initialize(name=:spec) @@ -161,6 +176,9 @@ module Spec cmd << %Q| > "#{out}"| STDERR.puts "The Spec::Rake::SpecTask#out attribute is DEPRECATED and will be removed in a future version. Use --format FORMAT:WHERE instead." end + if verbose + puts cmd + end unless system(cmd) STDERR.puts failure_message if failure_message raise("Command #{cmd} failed") if fail_on_error diff --git a/vendor/plugins/rspec/lib/spec/rake/verify_rcov.rb b/vendor/plugins/rspec/lib/spec/rake/verify_rcov.rb index 9715744e9..3328f9e9a 100644 --- a/vendor/plugins/rspec/lib/spec/rake/verify_rcov.rb +++ b/vendor/plugins/rspec/lib/spec/rake/verify_rcov.rb @@ -38,7 +38,7 @@ module RCov total_coverage = nil File.open(index_html).each_line do |line| - if line =~ /<tt.*>(\d+\.\d+)%<\/tt> <\/td>/ + if line =~ /<tt class='coverage_total'>(\d+\.\d+)%<\/tt>/ total_coverage = eval($1) break end diff --git a/vendor/plugins/rspec/lib/spec/runner.rb b/vendor/plugins/rspec/lib/spec/runner.rb index 9d801adc3..1a9373fee 100644 --- a/vendor/plugins/rspec/lib/spec/runner.rb +++ b/vendor/plugins/rspec/lib/spec/runner.rb @@ -1,22 +1,20 @@ -require 'spec/runner/formatter' -require 'spec/runner/behaviour_runner' require 'spec/runner/options' require 'spec/runner/option_parser' +require 'spec/runner/example_group_runner' require 'spec/runner/command_line' require 'spec/runner/drb_command_line' require 'spec/runner/backtrace_tweaker' require 'spec/runner/reporter' -require 'spec/runner/extensions/object' -require 'spec/runner/extensions/kernel' require 'spec/runner/spec_parser' +require 'spec/runner/class_and_arguments_parser' module Spec - # == Behaviours and Examples + # == ExampleGroups and Examples # - # Rather than expressing examples in classes, RSpec uses a custom domain specific language to - # describe Behaviours and Examples of those behaviours. + # Rather than expressing examples in classes, RSpec uses a custom DSLL (DSL light) to + # describe groups of examples. # - # A Behaviour is the equivalent of a fixture in xUnit-speak. It is a metaphor for the context + # A ExampleGroup is the equivalent of a fixture in xUnit-speak. It is a metaphor for the context # in which you will run your executable example - a set of known objects in a known starting state. # We begin be describing # @@ -32,7 +30,7 @@ module Spec # # end # - # We use the before block to set up the Behaviour (given), and then the #it method to + # We use the before block to set up the Example (given), and then the #it method to # hold the example code that expresses the event (when) and the expected outcome (then). # # == Helper Methods @@ -47,7 +45,7 @@ module Spec # # == Setup and Teardown # - # You can use before and after within a Behaviour. Both methods take an optional + # You can use before and after within a Example. Both methods take an optional # scope argument so you can run the block before :each example or before :all examples # # describe "..." do @@ -125,11 +123,11 @@ module Spec # end # end # - # == Shared behaviour + # == Shared Example Groups # - # You can define a shared behaviour, that may be used on other behaviours + # You can define a shared Example Group, that may be used on other groups # - # describe "All Editions", :shared => true do + # share_examples_for "All Editions" do # it "all editions behaviour" ... # end # @@ -140,10 +138,35 @@ module Spec # ... # end # end + # + # You can also assign the shared group to a module and include that + # + # share_as :AllEditions do + # it "should do all editions stuff" ... + # end + # + # describe SmallEdition do + # it_should_behave_like AllEditions + # + # it "should do small edition stuff" do + # ... + # end + # end + # + # And, for those of you who prefer to use something more like Ruby, you + # can just include the module directly + # + # describe SmallEdition do + # include AllEditions + # + # it "should do small edition stuff" do + # ... + # end + # end module Runner class << self def configuration # :nodoc: - @configuration ||= Spec::DSL::Configuration.new + @configuration ||= Spec::Example::Configuration.new end # Use this to configure various configurable aspects of @@ -154,11 +177,11 @@ module Spec # end # # The yielded <tt>configuration</tt> object is a - # Spec::DSL::Configuration instance. See its RDoc + # Spec::Example::Configuration instance. See its RDoc # for details about what you can do with it. # def configure - yield configuration if @configuration.nil? + yield configuration 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 aacc2c8b8..5fd2fb99f 100644 --- a/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb +++ b/vendor/plugins/rspec/lib/spec/runner/backtrace_tweaker.rb @@ -7,7 +7,7 @@ module Spec end class NoisyBacktraceTweaker < BacktraceTweaker - def tweak_backtrace(error, spec_name) + def tweak_backtrace(error) return if error.backtrace.nil? error.backtrace.each do |line| clean_up_double_slashes(line) @@ -19,7 +19,7 @@ module Spec class QuietBacktraceTweaker < BacktraceTweaker unless defined?(IGNORE_PATTERNS) root_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', '..')) - spec_files = Dir["#{root_dir}/lib/spec/*"].map do |path| + spec_files = Dir["#{root_dir}/lib/*"].map do |path| subpath = path[root_dir.length..-1] /#{subpath}/ end @@ -38,7 +38,7 @@ module Spec ] end - def tweak_backtrace(error, spec_name) + def tweak_backtrace(error) return if error.backtrace.nil? error.backtrace.collect! do |line| clean_up_double_slashes(line) diff --git a/vendor/plugins/rspec/lib/spec/runner/behaviour_runner.rb b/vendor/plugins/rspec/lib/spec/runner/behaviour_runner.rb deleted file mode 100644 index 1ac891f3c..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/behaviour_runner.rb +++ /dev/null @@ -1,123 +0,0 @@ -module Spec - module Runner - class BehaviourRunner - - def initialize(options, arg=nil) - @behaviours = [] - @options = options - end - - def add_behaviour(behaviour) - if !specified_examples.nil? && !specified_examples.empty? - behaviour.retain_examples_matching!(specified_examples) - end - @behaviours << behaviour if behaviour.number_of_examples != 0 && !behaviour.shared? - end - - # Runs all behaviours and returns the number of failures. - def run(paths, exit_when_done) - prepare!(paths) - begin - run_behaviours - rescue Interrupt - ensure - report_end - end - failure_count = report_dump - - heckle if(failure_count == 0 && !@options.heckle_runner.nil?) - - if(exit_when_done) - exit_code = (failure_count == 0) ? 0 : 1 - exit(exit_code) - end - failure_count - end - - def report_end - @options.reporter.end - end - - def report_dump - @options.reporter.dump - end - - def prepare!(paths) - unless paths.nil? # It's nil when running single specs with ruby - paths = find_paths(paths) - sorted_paths = sort_paths(paths) - load_specs(sorted_paths) # This will populate @behaviours via callbacks to add_behaviour - end - @options.reporter.start(number_of_examples) - @behaviours.reverse! if @options.reverse - set_sequence_numbers - end - - def run_behaviours - @behaviours.each do |behaviour| - behaviour.run(@options.reporter, @options.dry_run, @options.reverse, @options.timeout) - end - end - - def number_of_examples - @behaviours.inject(0) {|sum, behaviour| sum + behaviour.number_of_examples} - end - - FILE_SORTERS = { - 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)} - } - - def sorter(paths) - FILE_SORTERS[@options.loadby] - end - - def sort_paths(paths) - sorter = sorter(paths) - paths = paths.sort(&sorter) unless sorter.nil? - paths - end - - private - - # Sets the #number on each Example - def set_sequence_numbers - number = 0 - @behaviours.each do |behaviour| - number = behaviour.set_sequence_numbers(number, @options.reverse) - end - end - - def find_paths(paths) - result = [] - paths.each do |path| - if File.directory?(path) - result += Dir["#{path}/**/*.rb"] - elsif File.file?(path) - result << path - else - raise "File or directory not found: #{path}" - end - end - result - end - - def load_specs(paths) - paths.each do |path| - load path - end - end - - def specified_examples - @options.examples - end - - def heckle - heckle_runner = @options.heckle_runner - @options.heckle_runner = nil - behaviour_runner = self.class.new(@options) - behaviour_runner.instance_variable_set(:@behaviours, @behaviours) - heckle_runner.heckle_with(behaviour_runner) - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/runner/command_line.rb b/vendor/plugins/rspec/lib/spec/runner/command_line.rb index 0d70337e1..9849c4853 100644 --- a/vendor/plugins/rspec/lib/spec/runner/command_line.rb +++ b/vendor/plugins/rspec/lib/spec/runner/command_line.rb @@ -4,18 +4,24 @@ module Spec module Runner # Facade to run specs without having to fork a new ruby process (using `spec ...`) class CommandLine - # Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+ - # and +out+ are the streams output will be written to. +exit+ tells whether or - # not a system exit should be called after the specs are run and - # +warn_if_no_files+ tells whether or not a warning (the help message) - # should be printed to +err+ in case no files are specified. - def self.run(argv, err, out, exit=true, warn_if_no_files=true) - old_behaviour_runner = defined?($behaviour_runner) ? $behaviour_runner : nil - $behaviour_runner = OptionParser.new.create_behaviour_runner(argv, err, out, warn_if_no_files) - return if $behaviour_runner.nil? # This is the case if we use --drb - - $behaviour_runner.run(argv, exit) - $behaviour_runner = old_behaviour_runner + class << self + # Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+ + # and +out+ are the streams output will be written to. + def run(instance_rspec_options) + # NOTE - this call to init_rspec_options is not spec'd, but neither is any of this + # swapping of $rspec_options. That is all here to enable rspec to run against itself + # and maintain coverage in a single process. Therefore, DO NOT mess with this stuff + # unless you know what you are doing! + init_rspec_options(instance_rspec_options) + orig_rspec_options = rspec_options + begin + $rspec_options = instance_rspec_options + return $rspec_options.run_examples + ensure + ::Spec.run = true + $rspec_options = orig_rspec_options + end + end end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb b/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb index 7e745fb71..6c340cfea 100644 --- a/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb +++ b/vendor/plugins/rspec/lib/spec/runner/drb_command_line.rb @@ -6,14 +6,13 @@ module Spec class DrbCommandLine # Runs specs on a DRB server. Note that this API is similar to that of # CommandLine - making it possible for clients to use both interchangeably. - def self.run(argv, stderr, stdout, exit=true, warn_if_no_files=true) + def self.run(options) begin DRb.start_service spec_server = DRbObject.new_with_uri("druby://localhost:8989") - spec_server.run(argv, stderr, stdout) - rescue DRb::DRbConnError - stderr.puts "No server is running" - exit 1 if exit + spec_server.run(options.argv, options.error_stream, options.output_stream) + rescue DRb::DRbConnError => e + options.error_stream.puts "No server is running" end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/extensions/kernel.rb b/vendor/plugins/rspec/lib/spec/runner/extensions/kernel.rb deleted file mode 100644 index 75f2c335e..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/extensions/kernel.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Kernel - # Creates and registers an instance of a Spec::DSL::Behaviour (or a subclass). - # The instantiated behaviour class depends on the directory of the file - # calling this method. For example, Spec::Rails will use different - # classes for specs living in <tt>spec/models</tt>, <tt>spec/helpers</tt>, - # <tt>spec/views</tt> and <tt>spec/controllers</tt>. - # - # It is also possible to override autodiscovery of the behaviour class - # with an options Hash as the last argument: - # - # describe "name", :behaviour_type => :something_special do ... - # - # The reason for using different behaviour classes is to have - # different matcher methods available from within the <tt>describe</tt> - # block. - # - # See Spec::DSL::BehaviourFactory#add_behaviour_class for details about - # how to register special Spec::DSL::Behaviour implementations. - # - def describe(*args, &block) - raise ArgumentError if args.empty? - args << {} unless Hash === args.last - args.last[:spec_path] = caller(0)[1] - register_behaviour(Spec::DSL::BehaviourFactory.create(*args, &block)) - end - alias :context :describe - - def respond_to(*names) - Spec::Matchers::RespondTo.new(*names) - end - -private - - def register_behaviour(behaviour) - if behaviour.shared? - Spec::DSL::Behaviour.add_shared_behaviour(behaviour) - else - behaviour_runner.add_behaviour(behaviour) - end - end - - def behaviour_runner - # TODO: Figure out a better way to get this considered "covered" and keep this statement on multiple lines - unless $behaviour_runner; \ - $behaviour_runner = ::Spec::Runner::OptionParser.new.create_behaviour_runner(ARGV.dup, STDERR, STDOUT, false); \ - at_exit { $behaviour_runner.run(nil, false) }; \ - end - $behaviour_runner - end -end diff --git a/vendor/plugins/rspec/lib/spec/runner/extensions/object.rb b/vendor/plugins/rspec/lib/spec/runner/extensions/object.rb deleted file mode 100644 index 49745352f..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/extensions/object.rb +++ /dev/null @@ -1,32 +0,0 @@ -# The following copyright applies to Object#copy_instance_variables_from, -# which we borrowed from active_support. -# -# Copyright (c) 2004 David Heinemeier Hansson -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -class Object - # From active_support - def copy_instance_variables_from(object, exclude = []) # :nodoc: - exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables - - instance_variables = object.instance_variables - exclude.map { |name| name.to_s } - instance_variables.each { |name| instance_variable_set(name, object.instance_variable_get(name)) } - end -end diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter.rb deleted file mode 100644 index 17512d958..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/formatter.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'spec/runner/formatter/base_formatter' -require 'spec/runner/formatter/base_text_formatter' -require 'spec/runner/formatter/progress_bar_formatter' -require 'spec/runner/formatter/rdoc_formatter' -require 'spec/runner/formatter/specdoc_formatter' -require 'spec/runner/formatter/html_formatter' -require 'spec/runner/formatter/failing_examples_formatter' -require 'spec/runner/formatter/failing_behaviours_formatter' -require 'spec/runner/formatter/snippet_extractor' 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 7cc43ef0e..c8647cf50 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/base_formatter.rb @@ -3,7 +3,9 @@ module Spec module Formatter # Baseclass for formatters that implements all required methods as no-ops. class BaseFormatter - def initialize(where) + attr_accessor :example_group, :options, :where + def initialize(options, where) + @options = options @where = where end @@ -12,16 +14,17 @@ module Spec # formatters that need to provide progress on feedback (graphical ones) # # This method will only be invoked once, and the next one to be invoked - # is #add_behaviour + # is #add_example_group def start(example_count) end - # This method is invoked at the beginning of the execution of each behaviour. - # +name+ is the name of the behaviour and +first+ is true if it is the - # first behaviour - otherwise it's false. + # 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. # # The next method to be invoked after this is #example_failed or #example_finished - def add_behaviour(name) + def add_example_group(example_group) + @example_group = example_group end # This method is invoked when an +example+ starts. @@ -41,10 +44,9 @@ module Spec # This method is invoked when an example is not yet implemented (i.e. has not # been provided a block), or when an ExamplePendingError is raised. - # +name+ is the name of the example. # +message+ is the message from the ExamplePendingError, if it exists, or the # default value of "Not Yet Implemented" - def example_pending(behaviour_name, example_name, message) + def example_pending(example_group_description, 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 c3cf01b76..859b2641d 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 @@ -1,3 +1,5 @@ +require 'spec/runner/formatter/base_formatter' + module Spec module Runner module Formatter @@ -5,13 +7,12 @@ module Spec # non-text based ones too - just ignore the +output+ constructor # argument. class BaseTextFormatter < BaseFormatter - attr_writer :dry_run - + attr_reader :output, :pending_examples # Creates a new instance that will write to +where+. If +where+ is a # String, output will be written to the File with that name, otherwise # +where+ is exected to be an IO (or an object that responds to #puts and #write). - def initialize(where) - super(where) + def initialize(options, where) + super if where.is_a?(String) @output = File.open(where, 'w') elsif where == STDOUT @@ -22,21 +23,13 @@ module Spec else @output = where end - @colour = false - @dry_run = false - @snippet_extractor = SnippetExtractor.new @pending_examples = [] end - def example_pending(behaviour_name, example_name, message) - @pending_examples << ["#{behaviour_name} #{example_name}", message] + def example_pending(example_group_description, example, message) + @pending_examples << ["#{example_group_description} #{example.description}", message] end - 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" ; end - end - def dump_failure(counter, failure) @output.puts @output.puts "#{counter.to_s})" @@ -56,7 +49,7 @@ module Spec end def dump_summary(duration, example_count, failure_count, pending_count) - return if @dry_run + return if dry_run? @output.puts @output.puts "Finished in #{duration} seconds" @output.puts @@ -74,7 +67,6 @@ module Spec @output.puts red(summary) end @output.flush - dump_pending end def dump_pending @@ -100,13 +92,21 @@ module Spec end protected - + + def colour? + @options.colour ? true : false + end + + def dry_run? + @options.dry_run ? true : false + end + def backtrace_line(line) line.sub(/\A([^:]+:\d+)$/, '\\1:') end def colour(text, colour_code) - return text unless @colour && output_to_tty? + return text unless colour? && output_to_tty? "#{colour_code}#{text}\e[0m" end diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_behaviours_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_behaviours_formatter.rb deleted file mode 100644 index 2b3940fd3..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_behaviours_formatter.rb +++ /dev/null @@ -1,29 +0,0 @@ -module Spec - module Runner - module Formatter - class FailingBehavioursFormatter < BaseTextFormatter - def add_behaviour(behaviour_name) - if behaviour_name =~ /(.*) \(druby.*\)$/ - @behaviour_name = $1 - else - @behaviour_name = behaviour_name - end - end - - def example_failed(example, counter, failure) - unless @behaviour_name.nil? - @output.puts @behaviour_name - @behaviour_name = nil - @output.flush - end - end - - def dump_failure(counter, failure) - end - - def dump_summary(duration, example_count, failure_count, pending_count) - end - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb index 9728deaf0..e3a271c8b 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb @@ -1,13 +1,11 @@ +require 'spec/runner/formatter/base_text_formatter' + module Spec module Runner module Formatter class FailingExamplesFormatter < BaseTextFormatter - def add_behaviour(behaviour_name) - @behaviour_name = behaviour_name - end - def example_failed(example, counter, failure) - @output.puts "#{@behaviour_name} #{example.description}" + @output.puts "#{example_group.description} #{example.description}" @output.flush 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 d9c422e55..ad153c8dc 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/html_formatter.rb @@ -1,4 +1,5 @@ require 'erb' +require 'spec/runner/formatter/base_text_formatter' module Spec module Runner @@ -6,15 +7,15 @@ module Spec class HtmlFormatter < BaseTextFormatter include ERB::Util # for the #h method - def initialize(output) + def initialize(options, output) super - @current_behaviour_number = 0 + @current_example_group_number = 0 @current_example_number = 0 end - # The number of the currently running behaviour - def current_behaviour_number - @current_behaviour_number + # The number of the currently running example_group + def current_example_group_number + @current_example_group_number end # The number of the currently running example (a global counter) @@ -30,17 +31,18 @@ module Spec @output.flush end - def add_behaviour(name) - @behaviour_red = false - @behaviour_red = false - @current_behaviour_number += 1 - unless current_behaviour_number == 1 + def add_example_group(example_group) + super + @example_group_red = false + @example_group_red = false + @current_example_group_number += 1 + unless current_example_group_number == 1 @output.puts " </dl>" @output.puts "</div>" end - @output.puts "<div class=\"behaviour\">" + @output.puts "<div class=\"example_group\">" @output.puts " <dl>" - @output.puts " <dt id=\"behaviour_#{current_behaviour_number}\">#{h(name)}</dt>" + @output.puts " <dt id=\"example_group_#{current_example_group_number}\">#{h(example_group.description)}</dt>" @output.flush end @@ -51,7 +53,7 @@ module Spec end def example_started(example) - @current_example_number = example.number + @current_example_number += 1 end def example_passed(example) @@ -65,8 +67,8 @@ 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('behaviour_#{current_behaviour_number}');</script>" unless @behaviour_red - @behaviour_red = true + @output.puts " <script type=\"text/javascript\">makeRed('example_group_#{current_example_group_number}');</script>" unless @example_group_red + @example_group_red = true move_progress @output.puts " <dd class=\"spec #{failure_style}\">" @output.puts " <span class=\"failed_spec_name\">#{h(example.description)}</span>" @@ -79,11 +81,11 @@ module Spec @output.flush end - def example_pending(behaviour_name, example_name, message) + def example_pending(example_group_description, example, message) @output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>" unless @header_red - @output.puts " <script type=\"text/javascript\">makeYellow('behaviour_#{current_behaviour_number}');</script>" unless @behaviour_red + @output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{current_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_name)}</span></dd>" + @output.puts " <dd class=\"spec not_implemented\"><span class=\"not_implemented_spec_name\">#{h(example.description)} (PENDING: #{h(message)})</span></dd>" @output.flush end @@ -91,20 +93,29 @@ module Spec # could output links to images or other files produced during the specs. # def extra_failure_content(failure) + require 'spec/runner/formatter/snippet_extractor' + @snippet_extractor ||= SnippetExtractor.new " <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(failure.exception)}</code></pre>" end def move_progress - percent_done = @example_count == 0 ? 100.0 : ((current_example_number + 1).to_f / @example_count.to_f * 1000).to_i / 10.0 @output.puts " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>" @output.flush end + 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 + end + result + end + def dump_failure(counter, failure) end def dump_summary(duration, example_count, failure_count, pending_count) - if @dry_run + if dry_run? totals = "This was a dry-run" else totals = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}" @@ -121,15 +132,14 @@ module Spec def html_header <<-EOF -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>RSpec results</title> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Expires" content="-1" /> <meta http-equiv="Pragma" content="no-cache" /> <style type="text/css"> @@ -225,7 +235,7 @@ EOF font-size: 1.2em; } -.behaviour { +.example_group { margin: 0 10px 5px; background: #fff; } 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 624f06e7c..8d0e50432 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 @@ -1,10 +1,9 @@ +require 'spec/runner/formatter/base_text_formatter' + module Spec module Runner module Formatter class ProgressBarFormatter < BaseTextFormatter - def add_behaviour(name) - end - def example_failed(example, counter, failure) @output.print colourise('F', failure) @output.flush @@ -15,7 +14,7 @@ module Spec @output.flush end - def example_pending(behaviour_name, example_name, message) + def example_pending(example_group_description, example, message) super @output.print yellow('P') @output.flush diff --git a/vendor/plugins/rspec/lib/spec/runner/formatter/rdoc_formatter.rb b/vendor/plugins/rspec/lib/spec/runner/formatter/rdoc_formatter.rb deleted file mode 100644 index 0fd22ba6c..000000000 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/rdoc_formatter.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Spec - module Runner - module Formatter - class RdocFormatter < BaseTextFormatter - def add_behaviour(name) - @output.puts "# #{name}" - end - - def example_passed(example) - @output.puts "# * #{example.description}" - @output.flush - end - - def example_failed(example, counter, failure) - @output.puts "# * #{example.description} [#{counter} - FAILED]" - end - - def example_pending(behaviour_name, example_name, message) - @output.puts "# * #{behaviour_name} #{example_name} [PENDING: #{message}]" - end - 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 ad794b238..f426dc948 100644 --- a/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/formatter/specdoc_formatter.rb @@ -1,27 +1,37 @@ +require 'spec/runner/formatter/base_text_formatter' + module Spec module Runner module Formatter - class SpecdocFormatter < BaseTextFormatter - def add_behaviour(name) - @output.puts - @output.puts name - @output.flush + class SpecdocFormatter < BaseTextFormatter + def add_example_group(example_group) + super + output.puts + output.puts example_group.description + output.flush end def example_failed(example, counter, failure) - @output.puts failure.expectation_not_met? ? red("- #{example.description} (FAILED - #{counter})") : magenta("- #{example.description} (ERROR - #{counter})") - @output.flush + message = if failure.expectation_not_met? + "- #{example.description} (FAILED - #{counter})" + else + "- #{example.description} (ERROR - #{counter})" + end + + output.puts(failure.expectation_not_met? ? red(message) : magenta(message)) + output.flush end - + def example_passed(example) - @output.puts green("- #{example.description}") - @output.flush + message = "- #{example.description}" + output.puts green(message) + output.flush end - def example_pending(behaviour_name, example_name, message) + def example_pending(example_group_description, example, message) super - @output.puts yellow("- #{example_name} (PENDING: #{message})") - @output.flush + output.puts yellow("- #{example.description} (PENDING: #{message})") + output.flush end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb b/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb index b6de4ef73..7695fe794 100644 --- a/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb +++ b/vendor/plugins/rspec/lib/spec/runner/heckle_runner.rb @@ -13,9 +13,9 @@ module Spec @heckle_class = heckle_class end - # Runs all the contexts held by +behaviour_runner+ once for each of the + # Runs all the example groups held by +rspec_options+ once for each of the # methods in the matched classes. - def heckle_with(behaviour_runner) + def heckle_with if @filter =~ /(.*)[#\.](.*)/ heckle_method($1, $2) else @@ -25,7 +25,7 @@ module Spec def heckle_method(class_name, method_name) verify_constant(class_name) - heckle = @heckle_class.new(class_name, method_name, behaviour_runner) + heckle = @heckle_class.new(class_name, method_name, rspec_options) heckle.validate end @@ -39,7 +39,7 @@ module Spec classes.each do |klass| klass.instance_methods(false).each do |method_name| - heckle = @heckle_class.new(klass.name, method_name, behaviour_runner) + heckle = @heckle_class.new(klass.name, method_name, rspec_options) heckle.validate end end @@ -57,16 +57,16 @@ module Spec #Supports Heckle 1.2 and prior (earlier versions used Heckle::Base) class Heckler < (Heckle.const_defined?(:Base) ? Heckle::Base : Heckle) - def initialize(klass_name, method_name, behaviour_runner) + def initialize(klass_name, method_name, rspec_options) super(klass_name, method_name) - @behaviour_runner = behaviour_runner + @rspec_options = rspec_options end def tests_pass? - paths = [] # We can pass an empty array of paths - our specs are already loaded. - failure_count = @behaviour_runner.run(paths, false) - failure_count == 0 + success = @rspec_options.run_examples + success end + end end end diff --git a/vendor/plugins/rspec/lib/spec/runner/option_parser.rb b/vendor/plugins/rspec/lib/spec/runner/option_parser.rb index 1facb85a8..09cedccac 100644 --- a/vendor/plugins/rspec/lib/spec/runner/option_parser.rb +++ b/vendor/plugins/rspec/lib/spec/runner/option_parser.rb @@ -3,23 +3,18 @@ require 'stringio' module Spec module Runner - class OptionParser - BUILT_IN_FORMATTERS = { - 'specdoc' => Formatter::SpecdocFormatter, - 's' => Formatter::SpecdocFormatter, - 'html' => Formatter::HtmlFormatter, - 'h' => Formatter::HtmlFormatter, - 'rdoc' => Formatter::RdocFormatter, - 'r' => Formatter::RdocFormatter, - 'progress' => Formatter::ProgressBarFormatter, - 'p' => Formatter::ProgressBarFormatter, - 'failing_examples' => Formatter::FailingExamplesFormatter, - 'e' => Formatter::FailingExamplesFormatter, - 'failing_behaviours' => Formatter::FailingBehavioursFormatter, - 'b' => Formatter::FailingBehavioursFormatter - } + class OptionParser < ::OptionParser + class << self + def parse(args, err, out) + parser = new(err, out) + parser.parse(args) + parser.options + end + end + + attr_reader :options - COMMAND_LINE = { + OPTIONS = { :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", @@ -43,13 +38,17 @@ module Spec "not specified. The --format option may be specified several times", "if you want several outputs", " ", - "Builtin formats: ", - "progress|p : Text progress", - "specdoc|s : Behaviour doc as text", - "rdoc|r : Behaviour doc as RDoc", + "Builtin formats for examples: ", + "progress|p : Text progress", + "profile|o : Text progress with profiling of 10 slowest examples", + "specdoc|s : Example doc as 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", + " ", + "Builtin formats for stories: ", + "plain|p : Plain Text", "html|h : A nice HTML report", - "failing_examples|e : Write all failing examples - input for --example", - "failing_behaviours|b : Write all failing behaviours - input for --example", " ", "FORMAT can also be the name of a custom formatter class", "(in which case you should also specify --require to load it)"], @@ -73,155 +72,158 @@ module Spec :dry_run => ["-d", "--dry-run", "Invokes formatters without executing the examples."], :options_file => ["-O", "--options PATH", "Read options from a file"], :generate_options => ["-G", "--generate-options PATH", "Generate an options file for --options"], - :runner => ["-U", "--runner RUNNER", "Use a custom BehaviourRunner."], + :runner => ["-U", "--runner RUNNER", "Use a custom Runner."], :drb => ["-X", "--drb", "Run examples via DRb. (For example against script/spec_server)"], :version => ["-v", "--version", "Show version"], :help => ["-h", "--help", "You're looking at it"] } - def initialize + def initialize(err, out) + super() + @error_stream = err + @out_stream = out + @options = Options.new(@error_stream, @out_stream) + @spec_parser = SpecParser.new @file_factory = File - end - - def create_behaviour_runner(args, err, out, warn_if_no_files) - options = parse(args, err, out, warn_if_no_files) - # Some exit points in parse (--generate-options, --drb) don't return the options, - # but hand over control. In that case we don't want to continue. - return nil unless options.is_a?(Options) - options.configure - options.behaviour_runner - end - - def parse(args, err, out, warn_if_no_files) - options_file = nil - args_copy = args.dup - options = Options.new(err, out) - - opts = ::OptionParser.new do |opts| - opts.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]" - opts.separator "" - - def opts.rspec_on(name, &block) - on(*COMMAND_LINE[name], &block) - end - - opts.rspec_on(:diff) {|diff| options.parse_diff(diff)} - - opts.rspec_on(:colour) {options.colour = true} - - opts.rspec_on(:example) {|example| options.parse_example(example)} - - opts.rspec_on(:specification) {|example| options.parse_example(example)} - - opts.rspec_on(:line) {|line_number| options.line_number = line_number.to_i} - - opts.rspec_on(:format) {|format| options.parse_format(format)} - - opts.rspec_on(:require) {|req| options.parse_require(req)} - - opts.rspec_on(:backtrace) {options.backtrace_tweaker = NoisyBacktraceTweaker.new} - - opts.rspec_on(:loadby) {|loadby| options.loadby = loadby} - - opts.rspec_on(:reverse) {options.reverse = true} - - opts.rspec_on(:timeout) {|timeout| options.timeout = timeout.to_f} - - opts.rspec_on(:heckle) {|heckle| options.parse_heckle(heckle)} - - opts.rspec_on(:dry_run) {options.dry_run = true} - opts.rspec_on(:options_file) do |options_file| - return parse_options_file(options_file, out, err, args_copy, warn_if_no_files) - end - - opts.rspec_on(:generate_options) do |options_file| - options.parse_generate_options(options_file, args_copy, out) - end - - opts.rspec_on(:runner) do |runner| - options.runner_arg = runner - end - - opts.rspec_on(:drb) do - return parse_drb(args_copy, out, err, warn_if_no_files) - end - - opts.rspec_on(:version) {parse_version(out)} - - opts.on_tail(*COMMAND_LINE[:help]) {parse_help(opts, out)} + self.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]" + self.separator "" + on(*OPTIONS[:diff]) {|diff| @options.parse_diff(diff)} + on(*OPTIONS[:colour]) {@options.colour = true} + on(*OPTIONS[:example]) {|example| @options.parse_example(example)} + on(*OPTIONS[:specification]) {|example| @options.parse_example(example)} + on(*OPTIONS[:line]) {|line_number| @options.line_number = line_number.to_i} + on(*OPTIONS[:format]) {|format| @options.parse_format(format)} + on(*OPTIONS[:require]) {|requires| invoke_requires(requires)} + on(*OPTIONS[:backtrace]) {@options.backtrace_tweaker = NoisyBacktraceTweaker.new} + on(*OPTIONS[:loadby]) {|loadby| @options.loadby = loadby} + on(*OPTIONS[:reverse]) {@options.reverse = true} + on(*OPTIONS[:timeout]) {|timeout| @options.timeout = timeout.to_f} + 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 - opts.parse!(args) - - if args.empty? && warn_if_no_files - err.puts "No files specified." - err.puts opts - exit(6) if err == $stderr + on(*OPTIONS[:runner]) do |runner| + @options.user_input_for_runner = runner end + on(*OPTIONS[:drb]) {} + on(*OPTIONS[:version]) {parse_version} + on_tail(*OPTIONS[:help]) {parse_help} + end - if options.line_number - set_spec_from_line_number(options, args, err) + def order!(argv, &blk) + @argv = argv + @options.argv = @argv.dup + return if parse_generate_options + return if parse_drb + + super(@argv) do |file| + @options.files << file + blk.call(file) if blk end - if options.formatters.empty? - options.formatters << Formatter::ProgressBarFormatter.new(out) + if @options.line_number + set_spec_from_line_number end - options + @options end - def parse_options_file(options_file, out_stream, error_stream, args_copy, warn_if_no_files) - # Remove the --options option and the argument before writing to file - index = args_copy.index("-O") || args_copy.index("--options") - args_copy.delete_at(index) - args_copy.delete_at(index) - - new_args = args_copy + IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten - return CommandLine.run(new_args, error_stream, out_stream, true, warn_if_no_files) + protected + def invoke_requires(requires) + requires.split(",").each do |file| + require file + end + end + + def parse_options_file(options_file) + option_file_args = IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten + @argv.push(*option_file_args) end - def parse_drb(args_copy, out_stream, error_stream, warn_if_no_files) - # Remove the --drb option - index = args_copy.index("-X") || args_copy.index("--drb") - args_copy.delete_at(index) + def parse_generate_options + # Remove the --generate-options option and the argument before writing to file + options_file = nil + ['-G', '--generate-options'].each do |option| + if index = @argv.index(option) + @argv.delete_at(index) + options_file = @argv.delete_at(index) + end + end + + if options_file + write_generated_options(options_file) + return true + else + return false + end + end + + def write_generated_options(options_file) + File.open(options_file, 'w') do |io| + io.puts @argv.join("\n") + end + @out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:" + @out_stream.puts "spec --options #{options_file}" + @options.examples_should_not_be_run + end - return DrbCommandLine.run(args_copy, error_stream, out_stream, true, warn_if_no_files) + def parse_drb + 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 + @options.examples_should_not_be_run + DrbCommandLine.run( + self.class.parse(argv, @error_stream, @out_stream) + ) + true end - def parse_version(out_stream) - out_stream.puts ::Spec::VERSION::DESCRIPTION - exit if out_stream == $stdout + def parse_version + @out_stream.puts ::Spec::VERSION::DESCRIPTION + exit if stdout? end - def parse_help(opts, out_stream) - out_stream.puts opts - exit if out_stream == $stdout + def parse_help + @out_stream.puts self + exit if stdout? end - def set_spec_from_line_number(options, args, err) - if options.examples.empty? - if args.length == 1 - if @file_factory.file?(args[0]) - source = @file_factory.open(args[0]) - example = @spec_parser.spec_name_for(source, options.line_number) - options.parse_example(example) - elsif @file_factory.directory?(args[0]) - err.puts "You must specify one file, not a directory when using the --line option" - exit(1) if err == $stderr + 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 - err.puts "#{args[0]} does not exist" - exit(2) if err == $stderr + @error_stream.puts "#{@options.files[0]} does not exist" + exit(2) if stderr? end else - err.puts "Only one file can be specified when using the --line option: #{args.inspect}" - exit(3) if err == $stderr + @error_stream.puts "Only one file can be specified when using the --line option: #{@options.files.inspect}" + exit(3) if stderr? end else - err.puts "You cannot use both --line and --example" - exit(4) if err == $stderr + @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 a940133eb..a5a07548d 100644 --- a/vendor/plugins/rspec/lib/spec/runner/options.rb +++ b/vendor/plugins/rspec/lib/spec/runner/options.rb @@ -1,32 +1,40 @@ module Spec module Runner class Options - BUILT_IN_FORMATTERS = { - 'specdoc' => Formatter::SpecdocFormatter, - 's' => Formatter::SpecdocFormatter, - 'html' => Formatter::HtmlFormatter, - 'h' => Formatter::HtmlFormatter, - 'rdoc' => Formatter::RdocFormatter, - 'r' => Formatter::RdocFormatter, - 'progress' => Formatter::ProgressBarFormatter, - 'p' => Formatter::ProgressBarFormatter, - 'failing_examples' => Formatter::FailingExamplesFormatter, - 'e' => Formatter::FailingExamplesFormatter, - 'failing_behaviours' => Formatter::FailingBehavioursFormatter, - 'b' => Formatter::FailingBehavioursFormatter + FILE_SORTERS = { + 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)} } - + + EXAMPLE_FORMATTERS = { # Load these lazily for better speed + 'specdoc' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'], + 's' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'], + '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'], + 'p' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'], + 'failing_examples' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'], + 'e' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'], +'failing_example_groups' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'], + 'g' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'], + 'profile' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'], + 'o' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'], + 'textmate' => ['spec/runner/formatter/text_mate_formatter', 'Formatter::TextMateFormatter'] + } + + STORY_FORMATTERS = { + 'plain' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'], + 'p' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'], + 'html' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter'], + 'h' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter'] + } + attr_accessor( :backtrace_tweaker, - :colour, :context_lines, :diff_format, - :differ_class, :dry_run, + :profile, :examples, - :failure_file, - :formatters, - :generate, :heckle_runner, :line_number, :loadby, @@ -34,69 +42,83 @@ module Spec :reverse, :timeout, :verbose, - :runner_arg, - :behaviour_runner + :user_input_for_runner, + :error_stream, + :output_stream, + # TODO: BT - Figure out a better name + :argv ) + attr_reader :colour, :differ_class, :files, :example_groups - def initialize(err, out) - @err, @out = err, out + def initialize(error_stream, output_stream) + @error_stream = error_stream + @output_stream = output_stream @backtrace_tweaker = QuietBacktraceTweaker.new @examples = [] - @formatters = [] @colour = false + @profile = false @dry_run = false + @reporter = Reporter.new(self) + @context_lines = 3 + @diff_format = :unified + @files = [] + @example_groups = [] + @examples_run = false + @examples_should_be_run = nil + @user_input_for_runner = nil end - def configure - configure_formatters - create_reporter - configure_differ - create_behaviour_runner + def add_example_group(example_group) + @example_groups << example_group end - def create_behaviour_runner - return nil if @generate - @behaviour_runner = if @runner_arg - klass_name, arg = split_at_colon(@runner_arg) - runner_type = load_class(klass_name, 'behaviour runner', '--runner') - runner_type.new(self, arg) - else - BehaviourRunner.new(self) - end + def remove_example_group(example_group) + @example_groups.delete(example_group) end - def configure_formatters - @formatters.each do |formatter| - formatter.colour = @colour if formatter.respond_to?(:colour=) - formatter.dry_run = @dry_run if formatter.respond_to?(:dry_run=) + def run_examples + return true unless examples_should_be_run? + 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 end end - def create_reporter - @reporter = Reporter.new(@formatters, @backtrace_tweaker) + def examples_run? + @examples_run end - def configure_differ - if @differ_class - Spec::Expectations.differ = @differ_class.new(@diff_format, @context_lines, @colour) + def examples_should_not_be_run + @examples_should_be_run = false + end + + 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" ; \ end end def parse_diff(format) - @context_lines = 3 case format - when :context, 'context', 'c' - @diff_format = :context - when :unified, 'unified', 'u', '', nil - @diff_format = :unified - end - - if [:context,:unified].include? @diff_format - require 'spec/expectations/differs/default' - @differ_class = Spec::Expectations::Differs::Default + when :context, 'context', 'c' + @diff_format = :context + default_differ + when :unified, 'unified', 'u', '', nil + @diff_format = :unified + default_differ else @diff_format = :custom - @differ_class = load_class(format, 'differ', '--diff') + self.differ_class = load_class(format, 'differ', '--diff') end end @@ -109,67 +131,123 @@ module Spec end def parse_format(format_arg) - format, where = split_at_colon(format_arg) - # This funky regexp checks whether we have a FILE_NAME or not - if where.nil? + format, where = ClassAndArgumentsParser.parse(format_arg) + unless where raise "When using several --format options only one of them can be without a file" if @out_used - where = @out + where = @output_stream @out_used = true end - - formatter_type = BUILT_IN_FORMATTERS[format] || load_class(format, 'formatter', '--format') - @formatters << formatter_type.new(where) + @format_options ||= [] + @format_options << [format, where] + end + + def formatters + @format_options ||= [['progress', @output_stream]] + @formatters ||= load_formatters(@format_options, EXAMPLE_FORMATTERS) end - def parse_require(req) - req.split(",").each{|file| require file} + def story_formatters + @format_options ||= [['plain', @output_stream]] + @formatters ||= load_formatters(@format_options, STORY_FORMATTERS) + end + + def load_formatters(format_options, formatters) + format_options.map do |format, where| + formatter_type = if formatters[format] + require formatters[format][0] + eval(formatters[format][1], binding, __FILE__, __LINE__) + else + load_class(format, 'formatter', '--format') + end + formatter_type.new(self, where) + end end - def parse_heckle(heckle) - heckle_require = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? 'spec/runner/heckle_runner_unsupported' : 'spec/runner/heckle_runner' - require heckle_require + def load_heckle_runner(heckle) + suffix = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? '_unsupported' : '' + require "spec/runner/heckle_runner#{suffix}" @heckle_runner = HeckleRunner.new(heckle) end - def parse_generate_options(options_file, args_copy, out_stream) - # Remove the --generate-options option and the argument before writing to file - index = args_copy.index("-G") || args_copy.index("--generate-options") - args_copy.delete_at(index) - args_copy.delete_at(index) - File.open(options_file, 'w') do |io| - io.puts args_copy.join("\n") + def number_of_examples + @example_groups.inject(0) do |sum, example_group| + sum + example_group.number_of_examples end - out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:" - out_stream.puts "spec --options #{options_file}" - @generate = true end - def split_at_colon(s) - if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/ - arg = $2 == "" ? nil : $2 - [$1, arg] - else - raise "Couldn't parse #{s.inspect}" - end + protected + def examples_should_be_run? + return @examples_should_be_run unless @examples_should_be_run.nil? + @examples_should_be_run = true end + def differ_class=(klass) + return unless klass + @differ_class = klass + Spec::Expectations.differ = self.differ_class.new(self) + end + def load_class(name, kind, option) if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ arg = $2 == "" ? nil : $2 [$1, arg] else m = "#{name.inspect} is not a valid class name" - @err.puts m + @error_stream.puts m raise m end begin eval(name, binding, __FILE__, __LINE__) rescue NameError => e - @err.puts "Couldn't find #{kind} class #{name}" - @err.puts "Make sure the --require option is specified *before* #{option}" + @error_stream.puts "Couldn't find #{kind} class #{name}" + @error_stream.puts "Make sure the --require option is specified *before* #{option}" if $_spec_spec ; raise e ; else exit(1) ; end 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) + runner_type = load_class(klass_name, 'behaviour runner', '--runner') + return runner_type.new(self, arg) + end + + def custom_runner? + return user_input_for_runner ? true : false + end + + def heckle + returns = self.heckle_runner.heckle_with + self.heckle_runner = nil + returns + end + + def sorted_files + return sorter ? files.sort(&sorter) : files + end + + def sorter + FILE_SORTERS[loadby] + end + + def default_differ + require 'spec/expectations/differs/default' + self.differ_class = Spec::Expectations::Differs::Default + 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 b1dc2a27a..cfc511baf 100644 --- a/vendor/plugins/rspec/lib/spec/runner/reporter.rb +++ b/vendor/plugins/rspec/lib/spec/runner/reporter.rb @@ -1,40 +1,52 @@ module Spec module Runner class Reporter + attr_reader :options, :example_groups - def initialize(formatters, backtrace_tweaker) - @formatters = formatters - @backtrace_tweaker = backtrace_tweaker - clear! + def initialize(options) + @options = options + @options.reporter = self + clear end - def add_behaviour(name) - @formatters.each{|f| f.add_behaviour(name)} - @behaviour_names << name + def add_example_group(example_group) + formatters.each do |f| + f.add_example_group(example_group) + end + example_groups << example_group end - def example_started(name) - @formatters.each{|f| f.example_started(name)} + def example_started(example) + formatters.each{|f| f.example_started(example)} end - def example_finished(name, error=nil, failure_location=nil, not_implemented = false) - @example_names << name + def example_finished(example, error=nil) + @examples << example - if not_implemented - example_pending(@behaviour_names.last, name) - elsif error.nil? - example_passed(name) - elsif Spec::DSL::ExamplePendingError === error - example_pending(@behaviour_names.last, name, error.message) + if error.nil? + example_passed(example) + elsif Spec::Example::ExamplePendingError === error + example_pending(example_groups.last, example, error.message) else - example_failed(name, error, failure_location) + example_failed(example, error) + end + end + + def failure(example, error) + backtrace_tweaker.tweak_backtrace(error) + example_name = "#{example_groups.last.description} #{example.description}" + failure = Failure.new(example_name, error) + @failures << failure + formatters.each do |f| + f.example_failed(example, @failures.length, failure) end end + alias_method :example_failed, :failure def start(number_of_examples) - clear! + clear @start_time = Time.new - @formatters.each{|f| f.start(number_of_examples)} + formatters.each{|f| f.start(number_of_examples)} end def end @@ -43,22 +55,31 @@ module Spec # Dumps the summary and returns the total number of failures def dump - @formatters.each{|f| f.start_dump} + formatters.each{|f| f.start_dump} + dump_pending dump_failures - @formatters.each do |f| - f.dump_summary(duration, @example_names.length, @failures.length, @pending_count) + formatters.each do |f| + f.dump_summary(duration, @examples.length, @failures.length, @pending_count) f.close end @failures.length end private + + def formatters + @options.formatters + end + + def backtrace_tweaker + @options.backtrace_tweaker + end - def clear! - @behaviour_names = [] + def clear + @example_groups = [] @failures = [] @pending_count = 0 - @example_names = [] + @examples = [] @start_time = nil @end_time = nil end @@ -66,31 +87,28 @@ module Spec def dump_failures return if @failures.empty? @failures.inject(1) do |index, failure| - @formatters.each{|f| f.dump_failure(index, failure)} + formatters.each{|f| f.dump_failure(index, failure)} index + 1 end end + def dump_pending + formatters.each{|f| f.dump_pending} + end def duration return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?) return "0.0" end - def example_passed(name) - @formatters.each{|f| f.example_passed(name)} - end - - def example_failed(name, error, failure_location) - @backtrace_tweaker.tweak_backtrace(error, failure_location) - example_name = "#{@behaviour_names.last} #{name}" - failure = Failure.new(example_name, error) - @failures << failure - @formatters.each{|f| f.example_failed(name, @failures.length, failure)} + def example_passed(example) + formatters.each{|f| f.example_passed(example)} end - def example_pending(behaviour_name, example_name, message="Not Yet Implemented") + def example_pending(example_group, example, message="Not Yet Implemented") @pending_count += 1 - @formatters.each{|f| f.example_pending(behaviour_name, example_name, message)} + formatters.each do |f| + f.example_pending(example_group.description, example, message) + end end class Failure @@ -112,7 +130,7 @@ module Spec end def pending_fixed? - @exception.is_a?(Spec::DSL::PendingFixedError) + @exception.is_a?(Spec::Example::PendingExampleFixedError) end def expectation_not_met? diff --git a/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb b/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb index bc9170065..5ce51e3b2 100644 --- a/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb +++ b/vendor/plugins/rspec/lib/spec/runner/spec_parser.rb @@ -4,12 +4,12 @@ module Spec class SpecParser def spec_name_for(io, line_number) source = io.read - behaviour, behaviour_line = behaviour_at_line(source, line_number) + example_group, example_group_line = example_group_at_line(source, line_number) example, example_line = example_at_line(source, line_number) - if behaviour && example && (behaviour_line < example_line) - "#{behaviour} #{example}" - elsif behaviour - behaviour + if example_group && example && (example_group_line < example_line) + "#{example_group} #{example}" + elsif example_group + example_group else nil end @@ -17,7 +17,7 @@ module Spec protected - def behaviour_at_line(source, line_number) + def example_group_at_line(source, line_number) find_above(source, line_number, /^\s*(context|describe)\s+(.*)\s+do/) end @@ -40,8 +40,11 @@ module Spec def parse_description(str) return str[1..-2] if str =~ /^['"].*['"]$/ - if matches = /^(.*)\s*,\s*['"](.*)['"]$/.match(str) - return ::Spec::DSL::Description.generate_description(matches[1], matches[2]) + 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]) end return str end diff --git a/vendor/plugins/rspec/lib/spec/test_case_adapter.rb b/vendor/plugins/rspec/lib/spec/test_case_adapter.rb deleted file mode 100755 index 992e098fd..000000000 --- a/vendor/plugins/rspec/lib/spec/test_case_adapter.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'spec/expectations' -require 'spec/matchers' - -module Test - module Unit - class TestCase - include Spec::Matchers - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/version.rb b/vendor/plugins/rspec/lib/spec/version.rb index 5b1db9b37..f83a4c697 100644 --- a/vendor/plugins/rspec/lib/spec/version.rb +++ b/vendor/plugins/rspec/lib/spec/version.rb @@ -2,16 +2,15 @@ module Spec module VERSION unless defined? MAJOR MAJOR = 1 - MINOR = 0 - TINY = 8 + MINOR = 1 + TINY = 2 RELEASE_CANDIDATE = nil - # RANDOM_TOKEN: 0.510454315029681 - REV = "$LastChangedRevision: 2338 $".match(/LastChangedRevision: (\d+)/)[1] + 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('.')} (r#{REV})" + FULL_VERSION = "#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('.')} (build #{BUILD_TIME_UTC})" NAME = "RSpec" URL = "http://rspec.rubyforge.org/" |