diff options
author | Francis Irving <francis@mysociety.org> | 2009-12-02 17:56:17 +0000 |
---|---|---|
committer | Francis Irving <francis@mysociety.org> | 2009-12-02 17:56:17 +0000 |
commit | 1bbb3f950f8bee92bf8a39e6f18c3278f1bab11d (patch) | |
tree | 5d0312d5d00446cd1454a5e1c799cd89d57b10d6 /vendor/plugins/rspec/lib/spec/example | |
parent | 5f3139b538d1ff58b719a72d7c7cf05a5b6136b5 (diff) |
Changing rspec / rspec_on_rails version
Diffstat (limited to 'vendor/plugins/rspec/lib/spec/example')
11 files changed, 362 insertions, 625 deletions
diff --git a/vendor/plugins/rspec/lib/spec/example/configuration.rb b/vendor/plugins/rspec/lib/spec/example/configuration.rb deleted file mode 100644 index cd3f46909..000000000 --- a/vendor/plugins/rspec/lib/spec/example/configuration.rb +++ /dev/null @@ -1,158 +0,0 @@ -module Spec - module Example - 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 the following - # methods: - # - # setup_mocks_for_rspec - # verify_mocks_for_rspec - # teardown_mocks_for_rspec. - # - # These are your hooks into the lifecycle of a given example. RSpec will - # call setup_mocks_for_rspec before running anything else in each - # Example. After executing the #after methods, RSpec will then call - # verify_mocks_for_rspec and teardown_mocks_for_rspec (this is - # guaranteed to run even if there are failures in - # verify_mocks_for_rspec). - # - # 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 - - # :call-seq: - # include(Some::Helpers) - # include(Some::Helpers, More::Helpers) - # include(My::Helpers, :type => :key) - # - # Declares modules to be included in multiple example groups - # (<tt>describe</tt> blocks). With no :type, the modules listed will be - # included in all example groups. Use :type to restrict the inclusion to - # a subset of example groups. The value assigned to :type should be a - # key that maps to a class that is either a subclass of - # Spec::Example::ExampleGroup or extends Spec::Example::ExampleGroupMethods - # and includes Spec::Example::ExampleMethods - # - # config.include(My::Pony, My::Horse, :type => :farm) - # - # Only example groups that have that type will get the modules included: - # - # describe "Downtown", :type => :city do - # # Will *not* get My::Pony and My::Horse included - # end - # - # describe "Old Mac Donald", :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_example_group = get_type_from_options(options) - required_example_group = required_example_group.to_sym if required_example_group - modules.each do |mod| - ExampleGroupFactory.get(required_example_group).send(:include, mod) - 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.can_swim? returns true - # - def predicate_matchers - @predicate_matchers ||= {} - end - - # Prepends a global <tt>before</tt> block to all example groups. - # See #append_before for filtering semantics. - def prepend_before(*args, &proc) - scope, options = scope_and_options(*args) - example_group = ExampleGroupFactory.get( - get_type_from_options(options) - ) - example_group.prepend_before(scope, &proc) - end - - # Appends a global <tt>before</tt> block to all example groups. - # - # If you want to restrict the block to a subset of all the example - # groups then specify this in a Hash as the last argument: - # - # config.prepend_before(:all, :type => :farm) - # - # or - # - # config.prepend_before(:type => :farm) - # - def append_before(*args, &proc) - scope, options = scope_and_options(*args) - example_group = ExampleGroupFactory.get( - get_type_from_options(options) - ) - example_group.append_before(scope, &proc) - end - alias_method :before, :append_before - - # Prepends a global <tt>after</tt> block to all example groups. - # See #append_before for filtering semantics. - def prepend_after(*args, &proc) - scope, options = scope_and_options(*args) - example_group = ExampleGroupFactory.get( - get_type_from_options(options) - ) - example_group.prepend_after(scope, &proc) - end - alias_method :after, :prepend_after - - # Appends a global <tt>after</tt> block to all example groups. - # See #append_before for filtering semantics. - def append_after(*args, &proc) - scope, options = scope_and_options(*args) - example_group = ExampleGroupFactory.get( - get_type_from_options(options) - ) - example_group.append_after(scope, &proc) - end - - private - - def scope_and_options(*args) - args, options = args_and_options(*args) - scope = (args[0] || :each), options - end - - def get_type_from_options(options) - options[:type] || options[:behaviour_type] - end - - 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/example/errors.rb b/vendor/plugins/rspec/lib/spec/example/errors.rb index c6cb22453..157b669b0 100644 --- a/vendor/plugins/rspec/lib/spec/example/errors.rb +++ b/vendor/plugins/rspec/lib/spec/example/errors.rb @@ -1,9 +1,25 @@ module Spec module Example - class ExamplePendingError < StandardError + class ExamplePendingError < StandardError; end + + class NotYetImplementedError < ExamplePendingError + MESSAGE = "Not Yet Implemented" + def initialize + super(MESSAGE) + end end - class PendingExampleFixedError < StandardError + class PendingExampleFixedError < StandardError; end + + class NoDescriptionError < ArgumentError + class << self + def message(kind, location) + "No description supplied for #{kind} declared on #{location}" + end + end + def initialize(kind, location) + super(self.class.message(kind, location)) + end end end end diff --git a/vendor/plugins/rspec/lib/spec/example/example_group.rb b/vendor/plugins/rspec/lib/spec/example/example_group.rb index 35997f0c4..983be9a24 100644 --- a/vendor/plugins/rspec/lib/spec/example/example_group.rb +++ b/vendor/plugins/rspec/lib/spec/example/example_group.rb @@ -5,13 +5,6 @@ module Spec class ExampleGroup extend Spec::Example::ExampleGroupMethods include Spec::Example::ExampleMethods - - def initialize(defined_description, &implementation) - @_defined_description = defined_description - @_implementation = implementation - end end end end - -Spec::ExampleGroup = Spec::Example::ExampleGroup diff --git a/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb b/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb index c5caf4c9c..1d662782a 100644 --- a/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb +++ b/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb @@ -1,12 +1,36 @@ module Spec module Example + class ExampleGroupFactory - class << self + module ClassMethods + include Spec::Example::ArgsAndOptions + def reset @example_group_types = nil default(ExampleGroup) end + def example_group_creation_listeners + @example_group_creation_listeners ||= [] + end + + def register_example_group(klass) + example_group_creation_listeners.each do |listener| + listener.register_example_group(klass) + end + end + + def create_shared_example_group(*args, &example_group_block) # :nodoc: + ::Spec::Example::SharedExampleGroup.register(*args, &example_group_block) + end + + def create_example_group(*args, &block) + raise ArgumentError if args.empty? || block.nil? + add_options(args) + superclass = determine_superclass(args.last) + superclass.describe(*args, &block) + end + # Registers an example group class +klass+ with the symbol +type+. For # example: # @@ -22,42 +46,36 @@ module Spec # implicitly use an instance of FarmExampleGroup for any file loaded # from the <tt>./spec/farm</tt> directory. def register(key, example_group_class) - @example_group_types[key] = example_group_class + @example_group_types[key.to_sym] = example_group_class end - + # Sets the default ExampleGroup class def default(example_group_class) + Spec.__send__ :remove_const, :ExampleGroup if Spec.const_defined?(:ExampleGroup) + Spec.const_set(:ExampleGroup, example_group_class) old = @example_group_types @example_group_types = Hash.new(example_group_class) @example_group_types.merge!(old) if old end - def get(key=nil) - if @example_group_types.values.include?(key) - key - else - @example_group_types[key] - end - end - - def create_example_group(*args, &block) - opts = Hash === args.last ? args.last : {} - superclass = determine_superclass(opts) - superclass.describe(*args, &block) + def [](key) + @example_group_types[key] end - protected + protected def determine_superclass(opts) - key = if opts[:type] - opts[:type] - elsif opts[:spec_path] =~ /spec(\\|\/)(#{@example_group_types.keys.join('|')})/ - $2 == '' ? nil : $2.to_sym + if type = opts[:type] + self[type] + elsif opts[:location] =~ /spec(\\|\/)(#{@example_group_types.keys.sort_by{|k| k.to_s.length}.reverse.join('|')})/ + self[$2 == '' ? nil : $2.to_sym] + else + self[nil] end - get(key) end end + extend ClassMethods self.reset end end diff --git a/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb b/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb index 64e90cdb2..3862fdef6 100644 --- a/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb +++ b/vendor/plugins/rspec/lib/spec/example/example_group_methods.rb @@ -3,22 +3,33 @@ module Spec module ExampleGroupMethods class << self - def description_text(*args) - args.inject("") do |result, arg| - result << " " unless (result == "" || arg.to_s =~ /^(\s|\.|#)/) - result << arg.to_s + attr_accessor :matcher_class + + def build_description_from(*args) + text = args.inject("") do |description, arg| + description << " " unless (description == "" || arg.to_s =~ /^(\s|\.|#)/) + description << arg.to_s end + text == "" ? nil : text end end - attr_reader :description_text, :description_args, :description_options, :spec_path, :registration_binding_block + include Spec::Example::BeforeAndAfterHooks + include Spec::Example::Subject::ExampleGroupMethods + include Spec::Example::PredicateMatchers + include Spec::Example::ArgsAndOptions + + attr_reader :location + + def options # :nodoc: + @options ||= {} + end - def inherited(klass) + def inherited(klass) # :nodoc: super - klass.register {} - Spec::Runner.register_at_exit_hook + ExampleGroupFactory.register_example_group(klass) end - + # Makes the describe/it syntax available from a class. For example: # # class StackSpec < Spec::ExampleGroup @@ -34,390 +45,214 @@ module Spec # end # def describe(*args, &example_group_block) - args << {} unless Hash === args.last + raise Spec::Example::NoDescriptionError.new("example group", caller(0)[1]) if args.empty? if example_group_block - params = args.last - params[:spec_path] = eval("caller(0)[1]", example_group_block) unless params[:spec_path] - if params[:shared] - SharedExampleGroup.new(*args, &example_group_block) + options = add_options(args) + set_location(options, caller(0)[1]) + if options[:shared] + ExampleGroupFactory.create_shared_example_group(*args, &example_group_block) else - self.subclass("Subclass") do - describe(*args) - module_eval(&example_group_block) - end + subclass(*args, &example_group_block) end else set_description(*args) - before_eval - self end end alias :context :describe # Use this to pull in examples from shared example groups. - # See Spec::Runner for information about shared example groups. - def it_should_behave_like(shared_example_group) - case shared_example_group - when SharedExampleGroup - include shared_example_group - else - example_group = SharedExampleGroup.find_shared_example_group(shared_example_group) - unless example_group - raise RuntimeError.new("Shared Example Group '#{shared_example_group}' can not be found") - end - include(example_group) + def it_should_behave_like(*shared_example_groups) + shared_example_groups.each do |group| + include_shared_example_group(group) end 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 ||= {:an_instance_of => :is_a?} + # Creates an instance of the current example group class and adds it to + # a collection of examples of the current example group. + def example(description=nil, options={}, backtrace=nil, &implementation) + example_proxy = ExampleProxy.new(description, options, backtrace || caller(0)[1]) + example_proxies << example_proxy + example_implementations[example_proxy] = implementation || pending_implementation + example_proxy end - # Creates an instance of Spec::Example::Example and adds - # it to a collection of examples of the current example group. - def it(description=nil, &implementation) - e = new(description, &implementation) - example_objects << e - e + def pending_implementation + lambda { raise(Spec::Example::NotYetImplementedError) } end - alias_method :specify, :it + alias_method :it, :example + alias_method :specify, :example # Use this to temporarily disable an example. - def xit(description=nil, opts={}, &block) + def xexample(description=nil, opts={}, &block) Kernel.warn("Example disabled: #{description}") end - alias_method :xspecify, :xit - def run - examples = examples_to_run - reporter.add_example_group(self) + alias_method :xit, :xexample + alias_method :xspecify, :xexample + + def run(run_options) + examples = examples_to_run(run_options) + notify(run_options.reporter) unless examples.empty? return true if examples.empty? - return dry_run(examples) if dry_run? + return dry_run(examples, run_options) if run_options.dry_run? - plugin_mock_framework define_methods_from_predicate_matchers - success, before_all_instance_variables = run_before_all - success, after_all_instance_variables = execute_examples(success, before_all_instance_variables, examples) - success = run_after_all(success, after_all_instance_variables) - end - - def description - result = ExampleGroupMethods.description_text(*description_parts) - if result.nil? || result == "" - return to_s - else - result - end - end - - def described_type - description_parts.find {|part| part.is_a?(Module)} - end - - def description_parts #:nodoc: - parts = [] - execute_in_class_hierarchy do |example_group| - parts << example_group.description_args - end - parts.flatten.compact + success, before_all_instance_variables = run_before_all(run_options) + success, after_all_instance_variables = run_examples(success, before_all_instance_variables, examples, run_options) + success = run_after_all(success, after_all_instance_variables, run_options) end def set_description(*args) - args, options = args_and_options(*args) - @description_args = args - @description_options = options - @description_text = ExampleGroupMethods.description_text(*args) - @spec_path = File.expand_path(options[:spec_path]) if options[:spec_path] - if described_type.class == Module - @described_module = described_type - end + @description_args, @options = args_and_options(*args) + @backtrace = caller(1) + @location = File.expand_path(options[:location]) if options[:location] self end - - attr_reader :described_module - - def examples #:nodoc: - examples = example_objects.dup - add_method_examples(examples) - rspec_options.reverse ? examples.reverse : examples - end - - def number_of_examples #:nodoc: - examples.length - end - - # Registers a block to be executed before each example. - # This method prepends +block+ to existing before blocks. - def prepend_before(*args, &block) - scope, options = scope_and_options(*args) - parts = before_parts_from_scope(scope) - parts.unshift(block) - end - # Registers a block to be executed before each example. - # This method appends +block+ to existing before blocks. - def append_before(*args, &block) - scope, options = scope_and_options(*args) - parts = before_parts_from_scope(scope) - parts << block + def notify(reporter) # :nodoc: + reporter.example_group_started(ExampleGroupProxy.new(self)) end - alias_method :before, :append_before - # Registers a block to be executed after each example. - # This method prepends +block+ to existing after blocks. - def prepend_after(*args, &block) - scope, options = scope_and_options(*args) - parts = after_parts_from_scope(scope) - parts.unshift(block) - end - alias_method :after, :prepend_after - - # Registers a block to be executed after each example. - # This method appends +block+ to existing after blocks. - def append_after(*args, &block) - scope, options = scope_and_options(*args) - parts = after_parts_from_scope(scope) - parts << block + def description + @description ||= ExampleGroupMethods.build_description_from(*description_parts) || to_s end - def remove_after(scope, &block) - after_each_parts.delete(block) + def described_type + @described_type ||= description_parts.reverse.find {|part| part.is_a?(Module)} end - # Deprecated. Use before(:each) - def setup(&block) - before(:each, &block) + def described_class + @described_class ||= Class === described_type ? described_type : nil end - # Deprecated. Use after(:each) - def teardown(&block) - after(:each, &block) + def description_args + @description_args ||= [] end - def before_all_parts # :nodoc: - @before_all_parts ||= [] + def description_parts #:nodoc: + @description_parts ||= example_group_hierarchy.inject([]) do |parts, example_group_class| + [parts << example_group_class.description_args].flatten + end end - def after_all_parts # :nodoc: - @after_all_parts ||= [] + def example_proxies # :nodoc: + @example_proxies ||= [] end - def before_each_parts # :nodoc: - @before_each_parts ||= [] + def example_implementations # :nodoc: + @example_implementations ||= {} end - def after_each_parts # :nodoc: - @after_each_parts ||= [] + def examples(run_options=nil) #:nodoc: + (run_options && run_options.reverse) ? example_proxies.reverse : example_proxies end - # Only used from RSpec's own examples - def reset # :nodoc: - @before_all_parts = nil - @after_all_parts = nil - @before_each_parts = nil - @after_each_parts = nil + def number_of_examples #:nodoc: + example_proxies.length end - def register(®istration_binding_block) - @registration_binding_block = registration_binding_block - rspec_options.add_example_group self + def example_group_hierarchy + @example_group_hierarchy ||= ExampleGroupHierarchy.new(self) end - def unregister #:nodoc: - rspec_options.remove_example_group self + def nested_descriptions + example_group_hierarchy.nested_descriptions end - def registration_backtrace - eval("caller", registration_binding_block.binding) + def include_constants_in(mod) + include mod if (Spec::Ruby.version.to_f >= 1.9) & (Module === mod) & !(Class === mod) end - def run_before_each(example) - execute_in_class_hierarchy do |example_group| - example.eval_each_fail_fast(example_group.before_each_parts) + def let(name, &block) + define_method name do + @assignments ||= {} + @assignments[name] ||= instance_eval(&block) end end - def run_after_each(example) - execute_in_class_hierarchy(:superclass_first) do |example_group| - example.eval_each_fail_slow(example_group.after_each_parts) - end + private + + def subclass(*args, &example_group_block) + @class_count ||= 0 + @class_count += 1 + klass = const_set("Subclass_#{@class_count}", Class.new(self)) + klass.set_description(*args) + klass.include_constants_in(args.last[:scope]) + klass.module_eval(&example_group_block) + klass end - private - def dry_run(examples) + def dry_run(examples, run_options) examples.each do |example| - rspec_options.reporter.example_started(example) - rspec_options.reporter.example_finished(example) + run_options.reporter.example_started(example) + run_options.reporter.example_finished(example) end - return true end - def run_before_all - before_all = new("before(:all)") + def run_before_all(run_options) + return [true,{}] if example_group_hierarchy.before_all_parts.empty? + example_proxy = ExampleProxy.new("before(:all)") + before_all = new(example_proxy) begin - execute_in_class_hierarchy do |example_group| - before_all.eval_each_fail_fast(example_group.before_all_parts) - end + example_group_hierarchy.run_before_all(before_all) return [true, before_all.instance_variable_hash] rescue Exception => e - reporter.failure(before_all, e) + run_options.reporter.example_failed(example_proxy, e) return [false, before_all.instance_variable_hash] end end - def execute_examples(success, instance_variables, examples) + def run_examples(success, instance_variables, examples, run_options) return [success, instance_variables] unless success after_all_instance_variables = instance_variables - examples.each do |example_group_instance| - success &= example_group_instance.execute(rspec_options, instance_variables) + + examples.each do |example| + example_group_instance = new(example, &example_implementations[example]) + success &= example_group_instance.execute(run_options, instance_variables) after_all_instance_variables = example_group_instance.instance_variable_hash end + return [success, after_all_instance_variables] end - def run_after_all(success, instance_variables) - after_all = new("after(:all)") + def run_after_all(success, instance_variables, run_options) + return success if example_group_hierarchy.after_all_parts.empty? + example_proxy = ExampleProxy.new("after(:all)") + after_all = new(example_proxy) after_all.set_instance_variables_from_hash(instance_variables) - execute_in_class_hierarchy(:superclass_first) do |example_group| - after_all.eval_each_fail_slow(example_group.after_all_parts) - end - return success + example_group_hierarchy.run_after_all(after_all) + success rescue Exception => e - reporter.failure(after_all, e) - return false - end - - def examples_to_run - all_examples = examples - return all_examples unless specified_examples? - all_examples.reject do |example| - matcher = ExampleMatcher.new(description.to_s, example.description) - !matcher.matches?(specified_examples) - end - end - - def specified_examples? - specified_examples && !specified_examples.empty? - end - - def specified_examples - rspec_options.examples - end - - def reporter - rspec_options.reporter - end - - def dry_run? - rspec_options.dry_run - end - - def example_objects - @example_objects ||= [] - end - - def execute_in_class_hierarchy(superclass_last=false) - classes = [] - current_class = self - while is_example_group?(current_class) - superclass_last ? classes << current_class : classes.unshift(current_class) - current_class = current_class.superclass - end - superclass_last ? classes << ExampleMethods : classes.unshift(ExampleMethods) - - classes.each do |example_group| - yield example_group - end - end - - def is_example_group?(klass) - Module === klass && klass.kind_of?(ExampleGroupMethods) + run_options.reporter.example_failed(example_proxy, e) + false end - def plugin_mock_framework - case mock_framework = Spec::Runner.configuration.mock_framework - when Module - include mock_framework + def examples_to_run(run_options) + return example_proxies unless examples_were_specified?(run_options) + if run_options.line_number_requested? + if location =~ /:#{run_options.example_line}:?/ + example_proxies + else + example_proxies.select {|proxy| proxy.location =~ /:#{run_options.example_line}:?/} + end else - require Spec::Runner.configuration.mock_framework - include Spec::Plugins::MockFramework - end - end - - def define_methods_from_predicate_matchers # :nodoc: - all_predicate_matchers = predicate_matchers.merge( - Spec::Runner.configuration.predicate_matchers - ) - all_predicate_matchers.each_pair do |matcher_method, method_on_object| - define_method matcher_method do |*args| - eval("be_#{method_on_object.to_s.gsub('?','')}(*args)") + example_proxies.reject do |proxy| + matcher = ExampleGroupMethods.matcher_class. + new(description.to_s, proxy.description) + !matcher.matches?(run_options.examples) end end end - def scope_and_options(*args) - args, options = args_and_options(*args) - scope = (args[0] || :each), options - end - - def before_parts_from_scope(scope) - case scope - when :each; before_each_parts - when :all; before_all_parts - when :suite; rspec_options.before_suite_parts - end - end - - def after_parts_from_scope(scope) - case scope - when :each; after_each_parts - when :all; after_all_parts - when :suite; rspec_options.after_suite_parts - end - end - - def before_eval + def examples_were_specified?(run_options) + !run_options.examples.empty? end - def add_method_examples(examples) - instance_methods.sort.each do |method_name| - if example_method?(method_name) - examples << new(method_name) do - __send__(method_name) - end - end - end + def method_added(name) # :nodoc: + example(name.to_s, {}, caller(0)[1]) {__send__ name.to_s} if example_method?(name.to_s) end def example_method?(method_name) @@ -426,10 +261,20 @@ module Spec def should_method?(method_name) !(method_name =~ /^should(_not)?$/) && - method_name =~ /^should/ && ( - instance_method(method_name).arity == 0 || - instance_method(method_name).arity == -1 - ) + method_name =~ /^should/ && + instance_method(method_name).arity < 1 + end + + def include_shared_example_group(shared_example_group) + case shared_example_group + when SharedExampleGroup + include shared_example_group + else + unless example_group = SharedExampleGroup.find(shared_example_group) + raise RuntimeError.new("Shared Example Group '#{shared_example_group}' can not be found") + end + include(example_group) + end end end diff --git a/vendor/plugins/rspec/lib/spec/example/example_matcher.rb b/vendor/plugins/rspec/lib/spec/example/example_matcher.rb index 435eabf52..3acd7e14a 100644 --- a/vendor/plugins/rspec/lib/spec/example/example_matcher.rb +++ b/vendor/plugins/rspec/lib/spec/example/example_matcher.rb @@ -5,14 +5,13 @@ module Spec @example_group_description = example_group_description @example_name = example_name 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) + specified_examples.any? do |specified_example| + matches_literal_example?(specified_example) || matches_example_not_considering_modules?(specified_example) end - false end - + protected def matches_literal_example?(specified_example) specified_example =~ /(^#{example_group_regex} #{example_regexp}$|^#{example_group_regex}$|^#{example_group_with_before_all_regexp}$|^#{example_regexp}$)/ @@ -35,8 +34,10 @@ module Spec end def example_regexp - Regexp.escape(@example_name) + Regexp.escape(@example_name) if @example_name end end + + ExampleGroupMethods.matcher_class = ExampleMatcher end end diff --git a/vendor/plugins/rspec/lib/spec/example/example_methods.rb b/vendor/plugins/rspec/lib/spec/example/example_methods.rb index d4d716c2d..ca81a9379 100644 --- a/vendor/plugins/rspec/lib/spec/example/example_methods.rb +++ b/vendor/plugins/rspec/lib/spec/example/example_methods.rb @@ -1,60 +1,80 @@ module Spec module Example module ExampleMethods - extend ExampleGroupMethods - extend ModuleReopeningFix - include ModuleInclusionWarnings - - PENDING_EXAMPLE_BLOCK = lambda { - raise Spec::Example::ExamplePendingError.new("Not Yet Implemented") - } + extend Spec::Example::ModuleReopeningFix + include Spec::Example::Subject::ExampleMethods + + def violated(message="") + raise Spec::Expectations::ExpectationNotMetError.new(message) + end + + # Declared description for this example: + # + # describe Account do + # it "should start with a balance of 0" do + # ... + # + # description + # => "should start with a balance of 0" + def description + if description = @_proxy.description || ::Spec::Matchers.generated_description + description + else + Spec.warn Spec::Example::NoDescriptionError.message("example", @_proxy.location) + end + end + + def options # :nodoc: + @_proxy.options + end - def execute(options, instance_variables) - options.reporter.example_started(self) + def execute(run_options, instance_variables) # :nodoc: + run_options.reporter.example_started(@_proxy) set_instance_variables_from_hash(instance_variables) - + execution_error = nil - Timeout.timeout(options.timeout) do + Timeout.timeout(run_options.timeout) do begin - before_example - run_with_description_capturing + before_each_example + instance_eval(&@_implementation) rescue Exception => e execution_error ||= e end begin - after_example + after_each_example rescue Exception => e execution_error ||= e end end - options.reporter.example_finished(self, execution_error) + run_options.reporter.example_finished(@_proxy.update(description), execution_error) success = execution_error.nil? || ExamplePendingError === execution_error end - def instance_variable_hash - instance_variables.inject({}) do |variable_hash, variable_name| - variable_hash[variable_name] = instance_variable_get(variable_name) - variable_hash - end + module BlockAliases + alias_method :to, :should + alias_method :to_not, :should_not end - def violated(message="") - raise Spec::Expectations::ExpectationNotMetError.new(message) + # Extends the submitted block with aliases to and to_not + # for should and should_not. Allows expectations like this: + # + # expect { this_block }.to change{this.expression}.from(old_value).to(new_value) + # expect { this_block }.to raise_error + def expect(&block) + block.extend BlockAliases end - def eval_each_fail_fast(procs) #:nodoc: - procs.each do |proc| - instance_eval(&proc) - end + def eval_each_fail_fast(blocks) # :nodoc: + blocks.each {|block| instance_eval(&block)} end - def eval_each_fail_slow(procs) #:nodoc: + def eval_each_fail_slow(blocks) # :nodoc: first_exception = nil - procs.each do |proc| + blocks.each do |block| begin - instance_eval(&proc) + instance_eval(&block) rescue Exception => e first_exception ||= e end @@ -62,51 +82,67 @@ module Spec raise first_exception if first_exception end - def description - @_defined_description || @_matcher_description || "NO NAME" + def instance_variable_hash # :nodoc: + instance_variables.inject({}) do |variable_hash, variable_name| + variable_hash[variable_name] = instance_variable_get(variable_name) + variable_hash + end end - def __full_description - "#{self.class.description} #{self.description}" - end - - def set_instance_variables_from_hash(ivars) + def set_instance_variables_from_hash(ivars) # :nodoc: ivars.each do |variable_name, value| # Ruby 1.9 requires variable.to_s on the next line - unless ['@_implementation', '@_defined_description', '@_matcher_description', '@method_name'].include?(variable_name.to_s) + unless ['@_proxy', '@_implementation', '@method_name'].include?(variable_name.to_s) instance_variable_set variable_name, value end end end - def run_with_description_capturing - begin - return instance_eval(&(@_implementation || PENDING_EXAMPLE_BLOCK)) - ensure - @_matcher_description = Spec::Matchers.generated_description - Spec::Matchers.clear_generated_description - end + # Run all the before(:each) blocks for this example + def run_before_each + example_group_hierarchy.run_before_each(self) end - def implementation_backtrace - eval("caller", @_implementation) + # Run all the after(:each) blocks for this example + def run_after_each + example_group_hierarchy.run_after_each(self) + end + + def initialize(example_proxy, &implementation) + @_proxy = example_proxy + @_implementation = implementation + @_backtrace = caller end - protected + private + include Matchers include Pending - - def before_example + + def before_each_example setup_mocks_for_rspec - self.class.run_before_each(self) + run_before_each end - def after_example - self.class.run_after_each(self) + def after_each_example + run_after_each verify_mocks_for_rspec ensure teardown_mocks_for_rspec end + + def described_class + self.class.described_class + end + + def description_args + self.class.description_args + end + + def example_group_hierarchy + self.class.example_group_hierarchy + end + end end -end
\ No newline at end of file +end diff --git a/vendor/plugins/rspec/lib/spec/example/module_inclusion_warnings.rb b/vendor/plugins/rspec/lib/spec/example/module_inclusion_warnings.rb deleted file mode 100644 index c65faf2dd..000000000 --- a/vendor/plugins/rspec/lib/spec/example/module_inclusion_warnings.rb +++ /dev/null @@ -1,37 +0,0 @@ -module Spec - module Example - # In the future, modules will no longer be automatically included - # in the Example Group (based on the description name); when that - # time comes, this code should be removed. - module ModuleInclusionWarnings - # Thanks, Francis Hwang. - class MethodDispatcher - def initialize(mod, target=nil) - @mod = mod - @target = target - end - - def respond_to?(sym) - @mod && @mod.instance_methods.include?(sym.to_s) - end - - def call(sym, *args, &blk) - Kernel.warn("Modules will no longer be automatically included in RSpec version 1.1.4. Called from #{caller[2]}") - @target.extend @mod - @target.send(sym, *args, &blk) - end - end - - def respond_to?(sym) - MethodDispatcher.new(self.class.described_module).respond_to?(sym) ? true : super - end - - private - - def method_missing(sym, *args, &blk) - md = MethodDispatcher.new(self.class.described_module, self) - self.respond_to?(sym) ? md.call(sym, *args, &blk) : super - end - end - end -end diff --git a/vendor/plugins/rspec/lib/spec/example/module_reopening_fix.rb b/vendor/plugins/rspec/lib/spec/example/module_reopening_fix.rb index dc01dd666..9ea088a2e 100644 --- a/vendor/plugins/rspec/lib/spec/example/module_reopening_fix.rb +++ b/vendor/plugins/rspec/lib/spec/example/module_reopening_fix.rb @@ -1,6 +1,28 @@ module Spec module Example - # This is a fix for ...Something in Ruby 1.8.6??... (Someone fill in here please - Aslak) + # When you reopen a module that is included in another module that is included in a class, + # the new material you define does not make it to the class. This fixes that. + # + # == Example + # + # module M1; end + # + # module M2 + # def foo; "FOO"; end + # end + # + # class C + # include M1 + # end + # + # module M1 + # include M2 + # end + # + # c = C.new + # c.foo + # NoMethodError: undefined method `foo' for #<C:0x5e89a4> + # from (irb):12 module ModuleReopeningFix def child_modules @child_modules ||= [] @@ -18,4 +40,4 @@ module Spec end end end -end
\ No newline at end of file +end diff --git a/vendor/plugins/rspec/lib/spec/example/pending.rb b/vendor/plugins/rspec/lib/spec/example/pending.rb index b1f27c866..9aad1aab0 100644 --- a/vendor/plugins/rspec/lib/spec/example/pending.rb +++ b/vendor/plugins/rspec/lib/spec/example/pending.rb @@ -1,11 +1,11 @@ module Spec - module Example + module Example module Pending def pending(message = "TODO") if block_given? begin yield - rescue Exception => e + rescue Exception raise Spec::Example::ExamplePendingError.new(message) end raise Spec::Example::PendingExampleFixedError.new("Expected pending '#{message}' to fail. No Error was raised.") diff --git a/vendor/plugins/rspec/lib/spec/example/shared_example_group.rb b/vendor/plugins/rspec/lib/spec/example/shared_example_group.rb index a6fd6211c..336944914 100644 --- a/vendor/plugins/rspec/lib/spec/example/shared_example_group.rb +++ b/vendor/plugins/rspec/lib/spec/example/shared_example_group.rb @@ -1,58 +1,59 @@ module Spec module Example class SharedExampleGroup < Module - class << self - def add_shared_example_group(new_example_group) - guard_against_redefining_existing_example_group(new_example_group) - shared_example_groups << new_example_group + module ClassMethods + def register(*args, &block) + new_example_group = new(*args, &block) + shared_example_groups << new_example_group unless already_registered?(new_example_group) + new_example_group end - def find_shared_example_group(example_group_description) - shared_example_groups.find do |b| - b.description == example_group_description - end + def find(example_group_description) + shared_example_groups.find {|b| b.description == example_group_description} end + def clear + shared_example_groups.clear + end + + def include?(group) + shared_example_groups.include?(group) + end + + def count + shared_example_groups.length + end + + private + def shared_example_groups - # TODO - this needs to be global, or at least accessible from - # from subclasses of Example in a centralized place. I'm not loving - # this as a solution, but it works for now. - $shared_example_groups ||= [] - end - - private - def guard_against_redefining_existing_example_group(new_example_group) - existing_example_group = find_shared_example_group(new_example_group.description) - return unless existing_example_group - return if new_example_group.equal?(existing_example_group) - return if spec_path(new_example_group) == spec_path(existing_example_group) + @shared_example_groups ||= [] + end + + def already_registered?(new_example_group) + existing_example_group = find(new_example_group.description) + return false unless existing_example_group + return true if new_example_group.equal?(existing_example_group) + return true if expanded_path(new_example_group) == expanded_path(existing_example_group) raise ArgumentError.new("Shared Example '#{existing_example_group.description}' already exists") end - def spec_path(example_group) - File.expand_path(example_group.spec_path) + def expanded_path(example_group) + File.expand_path(example_group.location) end end + + extend ClassMethods include ExampleGroupMethods - public :include def initialize(*args, &example_group_block) - describe(*args) + set_description(*args) @example_group_block = example_group_block - self.class.add_shared_example_group(self) end def included(mod) # :nodoc: mod.module_eval(&@example_group_block) end - - def execute_in_class_hierarchy(superclass_last=false) - classes = [self] - superclass_last ? classes << ExampleMethods : classes.unshift(ExampleMethods) - classes.each do |example_group| - yield example_group - end - end end end end |