aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/plugins/rspec/lib/spec/dsl
diff options
context:
space:
mode:
authorlouise <louise>2007-10-16 19:10:21 +0000
committerlouise <louise>2007-10-16 19:10:21 +0000
commitd350850897a5ee7a994d3c618529cf5beecf71ea (patch)
tree39de7013d0a3377f063fbd53da7c89f207eeedd0 /vendor/plugins/rspec/lib/spec/dsl
parent3b1d8bfdeea68da1ad083a305d0df8f458c362a0 (diff)
Adding rspec plugin
Diffstat (limited to 'vendor/plugins/rspec/lib/spec/dsl')
-rw-r--r--vendor/plugins/rspec/lib/spec/dsl/behaviour.rb220
-rw-r--r--vendor/plugins/rspec/lib/spec/dsl/behaviour_callbacks.rb82
-rw-r--r--vendor/plugins/rspec/lib/spec/dsl/behaviour_eval.rb231
-rwxr-xr-xvendor/plugins/rspec/lib/spec/dsl/behaviour_factory.rb42
-rw-r--r--vendor/plugins/rspec/lib/spec/dsl/composite_proc_builder.rb33
-rwxr-xr-xvendor/plugins/rspec/lib/spec/dsl/configuration.rb135
-rwxr-xr-xvendor/plugins/rspec/lib/spec/dsl/description.rb76
-rw-r--r--vendor/plugins/rspec/lib/spec/dsl/errors.rb9
-rw-r--r--vendor/plugins/rspec/lib/spec/dsl/example.rb135
-rwxr-xr-xvendor/plugins/rspec/lib/spec/dsl/example_matcher.rb40
-rw-r--r--vendor/plugins/rspec/lib/spec/dsl/example_should_raise_handler.rb74
11 files changed, 1077 insertions, 0 deletions
diff --git a/vendor/plugins/rspec/lib/spec/dsl/behaviour.rb b/vendor/plugins/rspec/lib/spec/dsl/behaviour.rb
new file mode 100644
index 000000000..5158bb673
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/behaviour.rb
@@ -0,0 +1,220 @@
+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
new file mode 100644
index 000000000..8b69ad9e5
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/behaviour_callbacks.rb
@@ -0,0 +1,82 @@
+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
new file mode 100644
index 000000000..9f7b8281e
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/behaviour_eval.rb
@@ -0,0 +1,231 @@
+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
new file mode 100755
index 000000000..44b60c641
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/behaviour_factory.rb
@@ -0,0 +1,42 @@
+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
new file mode 100644
index 000000000..373f44953
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/composite_proc_builder.rb
@@ -0,0 +1,33 @@
+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
new file mode 100755
index 000000000..709574ded
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/configuration.rb
@@ -0,0 +1,135 @@
+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
new file mode 100755
index 000000000..fe8c9b0c9
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/description.rb
@@ -0,0 +1,76 @@
+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
new file mode 100644
index 000000000..ba7046a89
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/errors.rb
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 000000000..d04073f7e
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/example.rb
@@ -0,0 +1,135 @@
+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
new file mode 100755
index 000000000..18cc47409
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/example_matcher.rb
@@ -0,0 +1,40 @@
+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
new file mode 100644
index 000000000..942327317
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/dsl/example_should_raise_handler.rb
@@ -0,0 +1,74 @@
+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