From 79f9af625cbdb91916d3077440cc6a0cf7e77125 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 6 Feb 2011 13:51:55 -0600 Subject: [PATCH 001/151] date typo --- features/Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/Changelog.md b/features/Changelog.md index 777e0b4c5a..d9f611ce4c 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,4 +1,4 @@ -### 2.5.1 / 2011-02-05 +### 2.5.1 / 2011-02-06 [full changelog](http://github.com/rspec/rspec-core/compare/v2.5.0...v2.5.1) From 5a2b75b16b796e15ca054afae042a67bec93dfba Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 6 Feb 2011 23:27:22 -0600 Subject: [PATCH 002/151] docs/nav --- features/.nav | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/features/.nav b/features/.nav index 4490080001..a27f7901c3 100644 --- a/features/.nav +++ b/features/.nav @@ -28,11 +28,12 @@ - command_line: - configure.feature - example_name_option.feature - - exit_status.feature - - line_number_appended_to_path.feature + - format_option.feature - line_number_option.feature - - rake_task.feature - tag.feature + - line_number_appended_to_path.feature + - exit_status.feature + - rake_task.feature - configuration: - read_options_from_file.feature - fail_fast.feature @@ -49,3 +50,5 @@ - custom_formatter.feature - spec_files: - arbitrary_file_suffix.feature + + From 57007dc3d7af2eede107f4fcdeb875771357ddb4 Mon Sep 17 00:00:00 2001 From: Jo Liss Date: Thu, 10 Feb 2011 20:35:29 +0100 Subject: [PATCH 003/151] better error message if no block given for hook - Closes #309. --- lib/rspec/core/hooks.rb | 4 ++++ spec/rspec/core/hooks_spec.rb | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/rspec/core/hooks.rb b/lib/rspec/core/hooks.rb index c2601dff79..96e17cf1af 100644 --- a/lib/rspec/core/hooks.rb +++ b/lib/rspec/core/hooks.rb @@ -7,6 +7,7 @@ class Hook def initialize(options, &block) @options = options + raise "no block given for '#{self.class::TYPE}' hook" unless block @block = block end @@ -24,6 +25,7 @@ def call end class BeforeHook < Hook + TYPE = 'before' def run_in(example_group_instance) if example_group_instance example_group_instance.instance_eval(&self) @@ -34,6 +36,7 @@ def run_in(example_group_instance) end class AfterHook < Hook + TYPE = 'after' def run_in(example_group_instance) if example_group_instance example_group_instance.instance_eval_with_rescue(&self) @@ -44,6 +47,7 @@ def run_in(example_group_instance) end class AroundHook < Hook + TYPE = 'around' def call(wrapped_example) @block.call(wrapped_example) end diff --git a/spec/rspec/core/hooks_spec.rb b/spec/rspec/core/hooks_spec.rb index 7e66d41bb1..6063a6d19f 100644 --- a/spec/rspec/core/hooks_spec.rb +++ b/spec/rspec/core/hooks_spec.rb @@ -52,6 +52,14 @@ def yielder examples.should have(1).example end end + + describe Hooks::Hook do + it "requires a block" do + lambda { + Hooks::BeforeHook.new :foo => :bar + }.should raise_error "no block given for 'before' hook" + end + end end end end From 8bfc602335a1f9c569088bab3ee89cd7d0bc24ba Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 10 Feb 2011 17:49:31 -0600 Subject: [PATCH 004/151] remove quotes (less noise) --- lib/rspec/core/hooks.rb | 2 +- spec/rspec/core/hooks_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rspec/core/hooks.rb b/lib/rspec/core/hooks.rb index 96e17cf1af..b878cb17fe 100644 --- a/lib/rspec/core/hooks.rb +++ b/lib/rspec/core/hooks.rb @@ -7,7 +7,7 @@ class Hook def initialize(options, &block) @options = options - raise "no block given for '#{self.class::TYPE}' hook" unless block + raise "no block given for #{self.class::TYPE} hook" unless block @block = block end diff --git a/spec/rspec/core/hooks_spec.rb b/spec/rspec/core/hooks_spec.rb index 6063a6d19f..12d4f93570 100644 --- a/spec/rspec/core/hooks_spec.rb +++ b/spec/rspec/core/hooks_spec.rb @@ -57,7 +57,7 @@ def yielder it "requires a block" do lambda { Hooks::BeforeHook.new :foo => :bar - }.should raise_error "no block given for 'before' hook" + }.should raise_error "no block given for before hook" end end end From d832c614a2a2cfedcf820107c128f711b26e2cac Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 14 Feb 2011 01:56:07 -0200 Subject: [PATCH 005/151] doc tweaks --- features/Autotest.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/Autotest.md b/features/Autotest.md index 352edc6998..ab64d196c5 100644 --- a/features/Autotest.md +++ b/features/Autotest.md @@ -12,3 +12,11 @@ root directory or your home directory: # in .autotest require "autotest/bundler" + +### Upgrading from previous versions of rspec + +Previous versions of RSpec used a different mechanism for telling autotest to +invoke RSpec's autotest extension: generating autotest/discover.rb in the +project's root directory. This is no longer necessary with the new approach of +RSpec looking for a `.rspec` file, so feel free to delete the +`autotest/discover.rb` file in the project root if you have one. From 79273a74a83ea3210c7abc219d840da4f1fdb0d0 Mon Sep 17 00:00:00 2001 From: Damian Nurzynski Date: Mon, 7 Feb 2011 17:48:43 +0100 Subject: [PATCH 006/151] Fix exit_status after Exception raised in before :all hook - Closes #301. - Closes #302. --- lib/rspec/core/example_group.rb | 1 + spec/rspec/core/example_group_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 5cdc45a50a..4d80c939ac 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -248,6 +248,7 @@ def self.fail_filtered_examples(exception, reporter) child.fail_filtered_examples(exception, reporter) reporter.example_group_finished(child) end + false end def self.fail_fast? diff --git a/spec/rspec/core/example_group_spec.rb b/spec/rspec/core/example_group_spec.rb index 84de9a2458..d9f067eb78 100644 --- a/spec/rspec/core/example_group_spec.rb +++ b/spec/rspec/core/example_group_spec.rb @@ -387,7 +387,7 @@ module RSpec::Core group = ExampleGroup.describe group.before(:each) { raise "error in before each" } example = group.example("equality") { 1.should == 2} - group.run + group.run.should == false example.metadata[:execution_result][:exception].message.should == "error in before each" end @@ -396,7 +396,7 @@ module RSpec::Core group = ExampleGroup.describe group.before(:all) { raise "error in before all" } example = group.example("equality") { 1.should == 2} - group.run + group.run.should == false example.metadata.should_not be_nil example.metadata[:execution_result].should_not be_nil From ff18091e16c0c2aa237cc9d0865807345edf0ce1 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 15 Feb 2011 16:19:12 -0200 Subject: [PATCH 007/151] clear ivars declared before(:all) after a group is run --- lib/rspec/core/example_group.rb | 1 + spec/rspec/core/example_group_spec.rb | 54 +++++++++++++++++---------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 4d80c939ac..3c76cf15b2 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -236,6 +236,7 @@ def self.run(reporter) fail_filtered_examples(ex, reporter) ensure eval_after_alls(new) + before_all_ivars.clear reporter.example_group_finished(self) end end diff --git a/spec/rspec/core/example_group_spec.rb b/spec/rspec/core/example_group_spec.rb index d9f067eb78..0a0e382e21 100644 --- a/spec/rspec/core/example_group_spec.rb +++ b/spec/rspec/core/example_group_spec.rb @@ -189,8 +189,6 @@ module RSpec::Core group.run.should be_true, "expected examples in group to pass" end end - - end describe '#described_class' do @@ -200,16 +198,13 @@ module RSpec::Core end describe '#description' do - it "grabs the description from the metadata" do group = ExampleGroup.describe(Object, "my desc") { } group.description.should == group.metadata[:example_group][:description] end - end describe '#metadata' do - it "adds the third parameter to the metadata" do ExampleGroup.describe(Object, nil, 'foo' => 'bar') { }.metadata.should include({ "foo" => 'bar' }) end @@ -225,7 +220,6 @@ module RSpec::Core it "adds the line_number to metadata" do ExampleGroup.describe(Object) { }.metadata[:example_group][:line_number].should == __LINE__ end - end [:focus, :focused].each do |example_alias| @@ -255,7 +249,7 @@ module RSpec::Core group.run - order.should == [1,2,3] + order.should eq([1,2,3]) end it "runs the before eachs in order" do @@ -268,7 +262,7 @@ module RSpec::Core group.run - order.should == [1,2,3] + order.should eq([1,2,3]) end it "runs the after eachs in reverse order" do @@ -281,7 +275,7 @@ module RSpec::Core group.run - order.should == [3,2,1] + order.should eq([3,2,1]) end it "runs the after alls in reverse order" do @@ -294,7 +288,7 @@ module RSpec::Core group.run - order.should == [3,2,1] + order.should eq([3,2,1]) end it "only runs before/after(:all) hooks from example groups that have specs that run" do @@ -325,7 +319,7 @@ module RSpec::Core unfiltered_group.run filtered_group.run - hooks_run.should == [:filtered_before_all, :filtered_after_all] + hooks_run.should eq([:filtered_before_all, :filtered_after_all]) end it "runs before_all_defined_in_config, before all, before each, example, after each, after all, after_all_defined_in_config in that order" do @@ -372,15 +366,37 @@ module RSpec::Core ] end - it "accesses before(:all) state in after(:all)" do - group = ExampleGroup.describe - group.before(:all) { @ivar = "value" } - group.after(:all) { @ivar.should eq("value") } - group.example("ignore") { } + context "after(:all)" do + let(:outer) { ExampleGroup.describe } + let(:inner) { outer.describe } - expect do - group.run - end.to_not raise_error + it "has access to state defined before(:all)" do + outer.before(:all) { @outer = "outer" } + inner.before(:all) { @inner = "inner" } + + outer.after(:all) do + @outer.should eq("outer") + @inner.should eq("inner") + end + inner.after(:all) do + @inner.should eq("inner") + @outer.should eq("outer") + end + + outer.run + end + + it "cleans up ivars in after(:all)" do + outer.before(:all) { @outer = "outer" } + inner.before(:all) { @inner = "inner" } + + outer.run + + inner.before_all_ivars[:@inner].should be_nil + inner.before_all_ivars[:@outer].should be_nil + outer.before_all_ivars[:@inner].should be_nil + outer.before_all_ivars[:@outer].should be_nil + end end it "treats an error in before(:each) as a failure" do From dd8b9e42f7cdca2c0ca291e1b4ce078411482452 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 15 Feb 2011 16:27:20 -0200 Subject: [PATCH 008/151] docs --- features/Autotest.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/features/Autotest.md b/features/Autotest.md index ab64d196c5..97633dd7ac 100644 --- a/features/Autotest.md +++ b/features/Autotest.md @@ -1,14 +1,15 @@ -RSpec ships with a specialized subclass of Autotest. To tell RSpec to tell -Autotest to use RSpec's extension, just add a `.rspec` file to your project's -root directory. Then, just type: +RSpec ships with a specialized subclass of Autotest. To use it, just add a +`.rspec` file to your project's root directory, and run the `autotest` command +as normal: $ autotest ### Bundler -If you are using Bundler in your app, and you want the shell command to include -`bundle exec`, require the Autotest bundler plugin in a `.autotest` file in the project's -root directory or your home directory: +The `autotest` command generates a shell command that runs your specs. If you +are using Bundler, and you want the shell command to include `bundle exec`, +require the Autotest bundler plugin in a `.autotest` file in the project's root +directory or your home directory: # in .autotest require "autotest/bundler" @@ -16,7 +17,7 @@ root directory or your home directory: ### Upgrading from previous versions of rspec Previous versions of RSpec used a different mechanism for telling autotest to -invoke RSpec's autotest extension: generating autotest/discover.rb in the -project's root directory. This is no longer necessary with the new approach of -RSpec looking for a `.rspec` file, so feel free to delete the +invoke RSpec's Autotest extension: it generated an `autotest/discover.rb` file +in the project's root directory. This is no longer necessary with the new +approach of RSpec looking for a `.rspec` file, so feel free to delete the `autotest/discover.rb` file in the project root if you have one. From 011b1ce34016e15bd5f2ae1fce4679f3f948a4f4 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 16 Feb 2011 06:01:08 -0200 Subject: [PATCH 009/151] docs --- features/Autotest.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/features/Autotest.md b/features/Autotest.md index 97633dd7ac..e30c382538 100644 --- a/features/Autotest.md +++ b/features/Autotest.md @@ -4,7 +4,7 @@ as normal: $ autotest -### Bundler +## Bundler The `autotest` command generates a shell command that runs your specs. If you are using Bundler, and you want the shell command to include `bundle exec`, @@ -14,10 +14,25 @@ directory or your home directory: # in .autotest require "autotest/bundler" -### Upgrading from previous versions of rspec +## Upgrading from previous versions of rspec Previous versions of RSpec used a different mechanism for telling autotest to invoke RSpec's Autotest extension: it generated an `autotest/discover.rb` file in the project's root directory. This is no longer necessary with the new approach of RSpec looking for a `.rspec` file, so feel free to delete the `autotest/discover.rb` file in the project root if you have one. + +## Gotchas + +### Invalid Option: --tty + +The `--tty` option was [added in rspec-core-2.2.1](changelog), and is used +internally by RSpec. If you see an error citing it as an invalid option, you'll +probably see there are two or more versions of rspec-core in the backtrace: one +< 2.2.1 and one >= 2.2.1. + +This usually happens because you have a newer rspec-core installed, and an +older rspec-core specified in a Bundler Gemfile. If this is the case, you can: + +1. specify the newer version in the Gemfile (recommended) +2. prefix the `autotest` command with `bundle exec` From 6a12e37dfac301c9bd39b5798866db50ff90f416 Mon Sep 17 00:00:00 2001 From: Hans Hasselberg Date: Mon, 21 Feb 2011 11:40:15 -0600 Subject: [PATCH 010/151] don't stumble over an exception without a message. - Closes #308. --- lib/rspec/core/formatters/base_text_formatter.rb | 2 +- spec/rspec/core/formatters/base_text_formatter_spec.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/rspec/core/formatters/base_text_formatter.rb b/lib/rspec/core/formatters/base_text_formatter.rb index 1137ad219e..3c6cfccb69 100644 --- a/lib/rspec/core/formatters/base_text_formatter.rb +++ b/lib/rspec/core/formatters/base_text_formatter.rb @@ -148,7 +148,7 @@ def dump_failure(example, index) output.puts "#{short_padding}#{index.next}) #{example.full_description}" output.puts "#{long_padding}#{red("Failure/Error:")} #{red(read_failed_line(exception, example).strip)}" output.puts "#{long_padding}#{red(exception.class.name << ":")}" unless exception.class.name =~ /RSpec/ - exception.message.split("\n").each { |line| output.puts "#{long_padding} #{red(line)}" } + exception.message.split("\n").each { |line| output.puts "#{long_padding} #{red(line)}" } if exception.message example.example_group.ancestors.push(example.example_group).each do |group| if group.metadata[:shared_group_name] diff --git a/spec/rspec/core/formatters/base_text_formatter_spec.rb b/spec/rspec/core/formatters/base_text_formatter_spec.rb index d45cfe91a8..59ee65c84e 100644 --- a/spec/rspec/core/formatters/base_text_formatter_spec.rb +++ b/spec/rspec/core/formatters/base_text_formatter_spec.rb @@ -46,6 +46,15 @@ def run_all_and_dump_failures output.string.should =~ /(\s+)expected \"that\"\n\1 got \"this\"/m end + context "with an exception without a message" do + it "does not throw NoMethodError" do + exception_without_message = Exception.new() + exception_without_message.stub(:message) { nil } + group.example("example name") { raise exception_without_message } + expect { run_all_and_dump_failures }.not_to raise_error(NoMethodError) + end + end + context "with an exception class other than RSpec" do it "does not show the error class" do group.example("example name") { raise NameError.new('foo') } From 1a09d44529f9d2c3de64eb497593673dcb211d2a Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 21 Feb 2011 11:42:05 -0600 Subject: [PATCH 011/151] changelog --- features/Changelog.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/Changelog.md b/features/Changelog.md index d9f611ce4c..7c014232d6 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,3 +1,10 @@ +### dev + +[full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...master) + +* Bug fixes + * don't stumble over an exception without a message (Hans Hasselberg) + ### 2.5.1 / 2011-02-06 [full changelog](http://github.com/rspec/rspec-core/compare/v2.5.0...v2.5.1) From 4f0a131e27493eed052b7fe3686511ca9cc567e8 Mon Sep 17 00:00:00 2001 From: Geoffrey Byers Date: Fri, 18 Feb 2011 01:45:44 -0800 Subject: [PATCH 012/151] Removed non-ascii characters from comments - Closes #315. --- lib/rspec/core/subject.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rspec/core/subject.rb b/lib/rspec/core/subject.rb index c63039b23a..2eaace2cd8 100644 --- a/lib/rspec/core/subject.rb +++ b/lib/rspec/core/subject.rb @@ -108,14 +108,14 @@ module ClassMethods # # describe "a configuration Hash" do # subject do - # { :max_users => 3, + # { :max_users => 3, # 'admin' => :all_permissions } # end # # its([:max_users]) { should == 3 } # its(['admin']) { should == :all_permissions } # - # # You can still access to its regular methods this way: + # # You can still access to its regular methods this way: # its(:keys) { should include(:max_users) } # its(:count) { should == 2 } # end From 9557f985347708dc2ff0ac3a1ade6ae99f3622e7 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 21 Feb 2011 12:04:06 -0600 Subject: [PATCH 013/151] changelog --- features/Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/Changelog.md b/features/Changelog.md index 7c014232d6..2d5f698930 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -4,6 +4,8 @@ * Bug fixes * don't stumble over an exception without a message (Hans Hasselberg) + * remove non-ascii characters from comments that were choking rcov (Geoffrey + Byers) ### 2.5.1 / 2011-02-06 From f0dc666305fea2305e364b2f1e0915ab840a0ea5 Mon Sep 17 00:00:00 2001 From: Damian Nurzynski Date: Mon, 21 Feb 2011 13:02:53 -0600 Subject: [PATCH 014/151] Add config.for_groups_matching - extend groups matching specific metadata with: - method definitions - subject declarations - let/let! declarations - etc (anything you can do in a group) - Closes #300. --- .../configuration/for_groups_matching.feature | 37 ++++++++++++++ lib/rspec/core/configuration.rb | 20 ++++++++ spec/rspec/core/configuration_spec.rb | 51 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 features/configuration/for_groups_matching.feature diff --git a/features/configuration/for_groups_matching.feature b/features/configuration/for_groups_matching.feature new file mode 100644 index 0000000000..bde354586b --- /dev/null +++ b/features/configuration/for_groups_matching.feature @@ -0,0 +1,37 @@ +Feature: #for_groups_matching + + User can define block evaluated in the context of any example group matching filters given. + + Scenario: define new subject method and use let for models example groups + Given a file named "for_groups_matching_spec.rb" with: + """ + + class User + end + + class Factory + end + + RSpec.configure do |c| + c.for_groups_matching :type => :model do + subject { Factory described_class.to_s.downcase } + let(:valid_attributes) { Factory.attributes_for described_class.to_s } + end + end + + describe User, :type => :model do + it "uses new defined methods for subject" do + self.should_receive(:Factory).with('user') + subject + end + + it "allows to use defined let" do + Factory.should_receive(:attributes_for).with('User') + valid_attributes + end + end + """ + When I run "rspec ./for_groups_matching_spec.rb" + Then the examples should all pass + + diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 4a79598402..2005588ec3 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -372,6 +372,26 @@ def configure_group(group) end end + # Allows user to define a block evaluated in the context of any + # example group that match filters given. + # + # Example: + # + # RSpec.configure do |c| + # c.for_matching_groups :type => :model do + # subject { Factory described_class.to_s.underscore } + # let(:valid_attributes) { Factory.attributes_for described_class.to_sym } + # end + # end + # + def for_groups_matching(filters = {}, &block) + mod = Module.new + (class << mod; self; end).send(:define_method, :included) do |base| + base.instance_eval(&block) + end + self.include(mod, filters) + end + def configure_mock_framework RSpec::Core::ExampleGroup.send(:include, mock_framework) end diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 76b86f93bd..679f4c4833 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -712,5 +712,56 @@ def self.included(host) group.included_modules.should include(mod2) end end + + describe "#for_groups_matching" do + let(:group) { ExampleGroup.describe(Array, :factory => true) } + let(:different_group) { ExampleGroup.describe(Array) } + + before do + config.for_groups_matching :factory => true do + def new_method + 'new_method' + end + + subject { metadata[:example_group][:description].upcase } + let(:factory) { 'Factory' } + end + [group, different_group].each {|g| config.configure_group(g) } + end + + context "for groups matching filters" do + it "defines methods" do + group.new_method.should == 'new_method' + end + + it "defines subject" do + group.subject.call.should == 'ARRAY' + end + + it "defines let" do + group.example('let') { factory.should eql('Factory') } + group.context('child').example('let') { factory.should eql('Factory') } + group.run.should be_true, 'defined let should equal "Factory" for matching groups' + end + end + + context "for groups not matching filters given" do + it "doesn't define new methods" do + expect { different_group.new_method }.to raise_error(NoMethodError) + end + + it "doesn't change the subject" do + different_group.subject.call.should == [] + end + + it "doesn't define let" do + different_group.example('let') do + expect { factory }.to raise_error(NameError) + end + different_group.run.should be_true, 'defined let should raise NameError for not matching group' + end + end + end + end end From dc24065dbb447e6be6a1c134b6b9dc6de1afefe0 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 21 Feb 2011 13:29:40 -0600 Subject: [PATCH 015/151] change log --- features/Changelog.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/features/Changelog.md b/features/Changelog.md index 2d5f698930..7a80062c99 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -2,6 +2,15 @@ [full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...master) +* Enhancements + * `config.for_groups_matching` (Damian Nurzynski) + * extend groups matching specific metadata with: + * method definitions + * subject declarations + * let/let! declarations + * etc (anything you can do in a group) + + * Bug fixes * don't stumble over an exception without a message (Hans Hasselberg) * remove non-ascii characters from comments that were choking rcov (Geoffrey From 08889b440cb85aa0567f9f98621260ade06737cf Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 21 Feb 2011 14:20:14 -0600 Subject: [PATCH 016/151] Modify config.for_groups_matching to add methods using def as instance methods instead of class methods. This exposes them to the examples rather than the example groups. Also updated the specs and cukes to make them more generic (less rails specific). --- features/.nav | 3 +- .../configuration/for_groups_matching.feature | 60 +++++++++++++------ lib/rspec/core/configuration.rb | 24 ++++---- spec/rspec/core/configuration_spec.rb | 49 +++++++++------ 4 files changed, 85 insertions(+), 51 deletions(-) diff --git a/features/.nav b/features/.nav index a27f7901c3..ffaa6a905b 100644 --- a/features/.nav +++ b/features/.nav @@ -38,6 +38,7 @@ - read_options_from_file.feature - fail_fast.feature - custom_settings.feature + - for_groups_matching.feature - expectation_framework_integration: - configure_expectation_framework.feature - mock_framework_integration: @@ -50,5 +51,3 @@ - custom_formatter.feature - spec_files: - arbitrary_file_suffix.feature - - diff --git a/features/configuration/for_groups_matching.feature b/features/configuration/for_groups_matching.feature index bde354586b..8d9c41939a 100644 --- a/features/configuration/for_groups_matching.feature +++ b/features/configuration/for_groups_matching.feature @@ -1,37 +1,59 @@ -Feature: #for_groups_matching +Feature: for groups matching - User can define block evaluated in the context of any example group matching filters given. + Define block evaluated in the context of any example group matching filters given. - Scenario: define new subject method and use let for models example groups + Scenario: define method for groups matching metadata Given a file named "for_groups_matching_spec.rb" with: """ - - class User + RSpec.configure do |c| + c.for_groups_matching :type => :special do + def method_defined_in_config + "it works" + end + end end - class Factory + describe "something", :type => :special do + it "access methods defined in configuration" do + method_defined_in_config.should eq("it works") + end end + """ + When I run "rspec for_groups_matching_spec.rb" + Then the examples should all pass + Scenario: define method using let for groups matching metadata + Given a file named "for_groups_matching_spec.rb" with: + """ RSpec.configure do |c| - c.for_groups_matching :type => :model do - subject { Factory described_class.to_s.downcase } - let(:valid_attributes) { Factory.attributes_for described_class.to_s } + c.for_groups_matching :type => :special do + let(:method_defined_by_let_in_config) { "it works" } end end - describe User, :type => :model do - it "uses new defined methods for subject" do - self.should_receive(:Factory).with('user') - subject - end - - it "allows to use defined let" do - Factory.should_receive(:attributes_for).with('User') - valid_attributes + describe "something", :type => :special do + it "access methods defined using let in configuration" do + method_defined_by_let_in_config.should eq("it works") end end """ - When I run "rspec ./for_groups_matching_spec.rb" + When I run "rspec for_groups_matching_spec.rb" Then the examples should all pass + Scenario: define subject for groups matching metadata + Given a file named "for_groups_matching_spec.rb" with: + """ + RSpec.configure do |c| + c.for_groups_matching :type => :special do + subject { :subject_defined_in_configuration } + end + end + describe "something", :type => :special do + it "uses the subject defined in configuration" do + subject.should be(:subject_defined_in_configuration) + end + end + """ + When I run "rspec for_groups_matching_spec.rb" + Then the examples should all pass diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 2005588ec3..08a5eace77 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -372,24 +372,26 @@ def configure_group(group) end end - # Allows user to define a block evaluated in the context of any - # example group that match filters given. + # Extend groups matching submitted metadata with methods, subject declarations + # and let/let! declarations. # # Example: # - # RSpec.configure do |c| - # c.for_matching_groups :type => :model do - # subject { Factory described_class.to_s.underscore } - # let(:valid_attributes) { Factory.attributes_for described_class.to_sym } + # RSpec.configure do |c| + # c.for_matching_groups :type => :model do + # def a_method + # "a value" + # end + # subject { Factory described_class.to_s.underscore } + # let(:valid_attributes) { Factory.attributes_for described_class.to_sym } + # end # end - # end - # def for_groups_matching(filters = {}, &block) mod = Module.new - (class << mod; self; end).send(:define_method, :included) do |base| - base.instance_eval(&block) + (class << mod; self; end).send(:define_method, :extended) do |host| + host.class_eval(&block) end - self.include(mod, filters) + self.extend(mod, filters) end def configure_mock_framework diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 679f4c4833..6c044f7290 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -714,51 +714,62 @@ def self.included(host) end describe "#for_groups_matching" do - let(:group) { ExampleGroup.describe(Array, :factory => true) } - let(:different_group) { ExampleGroup.describe(Array) } + let(:matching_group) { ExampleGroup.describe(Array, :extended => true) } + let(:non_matching_group) { ExampleGroup.describe(Array) } before do - config.for_groups_matching :factory => true do - def new_method - 'new_method' + config.for_groups_matching :extended => true do + def method_defined_in_config + 'method defined in config' end - - subject { metadata[:example_group][:description].upcase } - let(:factory) { 'Factory' } + subject { "subject defined in config" } + let(:let_declaration_in_config) { 'value returned by let declared in config' } + let(:let_bang_declaration_in_config) { 'value returned by let bang declared in config' } end - [group, different_group].each {|g| config.configure_group(g) } + [matching_group, non_matching_group].each {|g| config.configure_group(g) } end context "for groups matching filters" do it "defines methods" do - group.new_method.should == 'new_method' + matching_group.new.method_defined_in_config.should == 'method defined in config' end it "defines subject" do - group.subject.call.should == 'ARRAY' + matching_group.subject.call.should eq("subject defined in config") end it "defines let" do - group.example('let') { factory.should eql('Factory') } - group.context('child').example('let') { factory.should eql('Factory') } - group.run.should be_true, 'defined let should equal "Factory" for matching groups' + matching_group.example('let') { let_declaration_in_config.should eq('value returned by let declared in config') } + matching_group.run.should be_true, "expected method declared with let to be accessible in example group" + end + + it "defines let!" do + matching_group.example('let!') { let_bang_declaration_in_config.should eq('value returned by let bang declared in config') } + matching_group.run.should be_true, "expected method declared with let! to be accessible in example group" end end context "for groups not matching filters given" do it "doesn't define new methods" do - expect { different_group.new_method }.to raise_error(NoMethodError) + expect { non_matching_group.new.method_defined_in_config }.to raise_error(NoMethodError) end it "doesn't change the subject" do - different_group.subject.call.should == [] + non_matching_group.subject.call.should eq([]) end it "doesn't define let" do - different_group.example('let') do - expect { factory }.to raise_error(NameError) + non_matching_group.example('let') do + expect { let_declaration_in_config }.to raise_error(NameError) + end + non_matching_group.run.should be_true, 'defined let should raise NameError for not matching group' + end + + it "doesn't define let!" do + non_matching_group.example('let') do + expect { let_bang_declaration_in_config }.to raise_error(NameError) end - different_group.run.should be_true, 'defined let should raise NameError for not matching group' + non_matching_group.run.should be_true, 'defined let should raise NameError for not matching group' end end end From 4ac234e583cdc0aad22a61d9f4f524451b4a0636 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 21 Feb 2011 16:57:46 -0600 Subject: [PATCH 017/151] Refactor peding declared in an example to raise and capture an exception instead of throwing/catching a symbol. This fixes a bug in which post-example processing in an around hook would be skipped if the example was declared pending from within the example. - Closes #322. --- lib/rspec/core/example.rb | 27 +++++++------------ lib/rspec/core/pending.rb | 6 +++-- spec/rspec/core/example_spec.rb | 13 +++++++++ .../core/formatters/html_formatted-1.8.6.html | 10 +++---- .../core/formatters/html_formatted-1.8.7.html | 10 +++---- .../core/formatters/html_formatted-1.9.2.html | 10 +++---- .../formatters/text_mate_formatted-1.8.6.html | 10 +++---- .../formatters/text_mate_formatted-1.8.7.html | 10 +++---- .../formatters/text_mate_formatted-1.9.2.html | 10 +++---- 9 files changed, 57 insertions(+), 49 deletions(-) diff --git a/lib/rspec/core/example.rb b/lib/rspec/core/example.rb index 8d965ecccf..3ddf060bf2 100644 --- a/lib/rspec/core/example.rb +++ b/lib/rspec/core/example.rb @@ -42,16 +42,16 @@ def run(example_group_instance, reporter) begin unless pending - with_pending_capture do - with_around_hooks do - begin - run_before_each - @example_group_instance.instance_eval(&@example_block) - rescue Exception => e - set_exception(e) - ensure - run_after_each - end + with_around_hooks do + begin + run_before_each + @example_group_instance.instance_eval(&@example_block) + rescue Pending::PendingDeclaredInExample => e + @pending_declared_in_example = e.message + rescue Exception => e + set_exception(e) + ensure + run_after_each end end end @@ -94,13 +94,6 @@ def with(metadata) private - def with_pending_capture - @pending_declared_in_example = catch(:pending_declared_in_example) do - yield - throw :pending_declared_in_example, false - end - end - def with_around_hooks(&block) if around_hooks.empty? yield diff --git a/lib/rspec/core/pending.rb b/lib/rspec/core/pending.rb index cc9816eb59..f99efaf547 100644 --- a/lib/rspec/core/pending.rb +++ b/lib/rspec/core/pending.rb @@ -1,6 +1,8 @@ module RSpec module Core module Pending + class PendingDeclaredInExample < StandardError; end + DEFAULT_MESSAGE = 'No reason given' def pending(*args) @@ -19,11 +21,11 @@ def pending(*args) begin result = yield example.metadata[:pending] = false - rescue Exception => e + rescue Exception end raise RSpec::Core::PendingExampleFixedError.new if result end - throw :pending_declared_in_example, message + raise PendingDeclaredInExample.new(message) end end end diff --git a/spec/rspec/core/example_spec.rb b/spec/rspec/core/example_spec.rb index 589a24ab8f..ed2b89d7a6 100644 --- a/spec/rspec/core/example_spec.rb +++ b/spec/rspec/core/example_spec.rb @@ -119,6 +119,19 @@ group.run group.examples.first.should be_pending end + + it "allows post-example processing in around hooks (see https://github.com/rspec/rspec-core/issues/322)" do + blah = nil + group = RSpec::Core::ExampleGroup.describe do + around do |example| + example.run + blah = :success + end + example { pending } + end + group.run + blah.should be(:success) + end end context "in before(:each)" do diff --git a/spec/rspec/core/formatters/html_formatted-1.8.6.html b/spec/rspec/core/formatters/html_formatted-1.8.6.html index 64219f4ba3..cae22540f0 100644 --- a/spec/rspec/core/formatters/html_formatted-1.8.6.html +++ b/spec/rspec/core/formatters/html_formatted-1.8.6.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46 ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' ./spec/rspec/core/formatters/html_formatter_spec.rb:45 -
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/html_formatted-1.8.7.html b/spec/rspec/core/formatters/html_formatted-1.8.7.html index 64219f4ba3..cae22540f0 100644 --- a/spec/rspec/core/formatters/html_formatted-1.8.7.html +++ b/spec/rspec/core/formatters/html_formatted-1.8.7.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46 ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' ./spec/rspec/core/formatters/html_formatter_spec.rb:45 -
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/html_formatted-1.9.2.html b/spec/rspec/core/formatters/html_formatted-1.9.2.html index aa765eeaf2..bb02f09a07 100644 --- a/spec/rspec/core/formatters/html_formatted-1.9.2.html +++ b/spec/rspec/core/formatters/html_formatted-1.9.2.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46:in `block (4 levels) in ' ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `block (3 levels) in ' -
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html b/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html index 9ce0c55004..a3cb2a4752 100644 --- a/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html +++ b/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `chdir' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 -
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html b/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html index 9ce0c55004..a3cb2a4752 100644 --- a/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +++ b/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `chdir' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 -
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html b/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html index 7df0f2ef70..4c408b42d3 100644 --- a/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +++ b/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 :in `block (4 levels) in ' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `chdir' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `block (3 levels) in ' -
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
From fda4a122e35ae6d9659e8959c15e173cd656e3e8 Mon Sep 17 00:00:00 2001 From: Peter Jaros Date: Mon, 21 Feb 2011 19:23:51 -0600 Subject: [PATCH 018/151] `its([:key]) {}` works for any subject with #[]. - Closes #323. - Closes #296. --- features/subject/attribute_of_subject.feature | 20 +++++++++ lib/rspec/core/subject.rb | 4 +- spec/rspec/core/subject_spec.rb | 42 ++++++++++++++----- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/features/subject/attribute_of_subject.feature b/features/subject/attribute_of_subject.feature index 813da76cde..bf4c5070d2 100644 --- a/features/subject/attribute_of_subject.feature +++ b/features/subject/attribute_of_subject.feature @@ -100,3 +100,23 @@ Feature: attribute of subject """ When I run "rspec example_spec.rb" Then the examples should all pass + + Scenario: specify value for key in a hash-like object + Given a file named "example_spec.rb" with: + """ + require 'matrix' + + describe Matrix do + context "with values [[1, 2], [3, 4]]" do + subject do + Matrix[[1, 2], [3, 4]] + end + + its([0, 1]) { should eq(2) } + its([1, 0]) { should eq(3) } + its([1, 2]) { should be_nil } + end + end + """ + When I run "rspec example_spec.rb" + Then the examples should all pass diff --git a/lib/rspec/core/subject.rb b/lib/rspec/core/subject.rb index 2eaace2cd8..055a81b6ba 100644 --- a/lib/rspec/core/subject.rb +++ b/lib/rspec/core/subject.rb @@ -124,8 +124,8 @@ def its(attribute, &block) example do self.class.class_eval do define_method(:subject) do - @_subject ||= if super().is_a?(Hash) && attribute.is_a?(Array) - OpenStruct.new(super()).send(attribute.first) + @_subject ||= if attribute.is_a?(Array) + super()[*attribute] else attribute.to_s.split('.').inject(super()) do |target, method| target.send(method) diff --git a/spec/rspec/core/subject_spec.rb b/spec/rspec/core/subject_spec.rb index 5394dbd905..c4ee602210 100644 --- a/spec/rspec/core/subject_spec.rb +++ b/spec/rspec/core/subject_spec.rb @@ -134,27 +134,47 @@ def name its("name.size.class") { should eq(Fixnum) } end - context "when it is a Hash" do + context "when it responds to #[]" do subject do - { :attribute => 'value', - 'another_attribute' => 'another_value' } - end - its([:attribute]) { should == 'value' } - its([:attribute]) { should_not == 'another_value' } - its([:another_attribute]) { should == 'another_value' } - its([:another_attribute]) { should_not == 'value' } - its(:keys) { should =~ ['another_attribute', :attribute] } + Class.new do + def [](*objects) + objects.map do |object| + "#{object.class}: #{object.to_s}" + end.join("; ") + end + + def name + "George" + end + end.new + end + its([:a]) { should == 'Symbol: a' } + its(['a']) { should == 'String: a' } + its([:b, 'c', 4]) { should == 'Symbol: b; String: c; Fixnum: 4' } + its(:name) { should = "George" } context "when referring to an attribute without the proper array syntax" do context "it raises an error" do - its(:attribute) do + its(:age) do expect do - should eq('value') + should eq(64) end.to raise_error(NoMethodError) end end end end + context "when it does not respond to #[]" do + subject { Object.new } + + context "it raises an error" do + its([:a]) do + expect do + should == 'Symbol: a' + end.to raise_error(NoMethodError) + end + end + end + context "calling and overriding super" do it "calls to the subject defined in the parent group" do group = ExampleGroup.describe(Array) do From 696ef3ee98c629ea0fa07d592465ac6b38ffefa5 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 21 Feb 2011 20:57:10 -0600 Subject: [PATCH 019/151] change log --- features/Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/Changelog.md b/features/Changelog.md index 7a80062c99..b94ab8deba 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -9,7 +9,7 @@ * subject declarations * let/let! declarations * etc (anything you can do in a group) - + * `its([:key])` works for any subject with #[]. (Peter Jaros) * Bug fixes * don't stumble over an exception without a message (Hans Hasselberg) From d0218cd1640ddb8d4f273bdca815c11ec519b90c Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 22 Feb 2011 06:41:34 -0600 Subject: [PATCH 020/151] Require file from spec that is not autoloaded (so the spec file can be run individually). - Closes #318. --- lib/rspec/core/formatters/helpers.rb | 4 ---- spec/rspec/core/formatters/helpers_spec.rb | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/rspec/core/formatters/helpers.rb b/lib/rspec/core/formatters/helpers.rb index 7be839860a..916706d947 100644 --- a/lib/rspec/core/formatters/helpers.rb +++ b/lib/rspec/core/formatters/helpers.rb @@ -1,7 +1,5 @@ module RSpec - module Core - module Formatters module Helpers @@ -22,7 +20,5 @@ def strip_trailing_zeroes(string) end end - end - end diff --git a/spec/rspec/core/formatters/helpers_spec.rb b/spec/rspec/core/formatters/helpers_spec.rb index d1e3b05995..b86d0ab141 100644 --- a/spec/rspec/core/formatters/helpers_spec.rb +++ b/spec/rspec/core/formatters/helpers_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require 'rspec/core/formatters/helpers' require 'stringio' describe RSpec::Core::Formatters::Helpers do From e4b8f5cedc1d2f29abf5d32ab1594770fb0cc01f Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Fri, 3 Sep 2010 15:40:06 -0700 Subject: [PATCH 021/151] Fixed backtrace so it doesn't include lines from before the autorun at_exit hook. - Closes #101. --- features/Changelog.md | 2 + features/formatters/text_formatter.feature | 45 +++++++++++++++++++ .../step_definitions/additional_cli_steps.rb | 10 +++++ lib/rspec/core/formatters/base_formatter.rb | 5 +++ lib/rspec/core/runner.rb | 1 + .../core/formatters/base_formatter_spec.rb | 20 +++++++++ 6 files changed, 83 insertions(+) create mode 100644 features/formatters/text_formatter.feature diff --git a/features/Changelog.md b/features/Changelog.md index b94ab8deba..37382c8376 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -15,6 +15,8 @@ * don't stumble over an exception without a message (Hans Hasselberg) * remove non-ascii characters from comments that were choking rcov (Geoffrey Byers) + * fixed backtrace so it doesn't include lines from before the autorun at_exit + hook (Myron Marston) ### 2.5.1 / 2011-02-06 diff --git a/features/formatters/text_formatter.feature b/features/formatters/text_formatter.feature new file mode 100644 index 0000000000..a34e9fddc3 --- /dev/null +++ b/features/formatters/text_formatter.feature @@ -0,0 +1,45 @@ +Feature: text formatter + + In order to easily see the result of running my specs + As an RSpec user + I want clear, concise, well-formatted output + + Scenario: Backtrace formatting for failing specs in multiple files + Given a file named "string_spec.rb" with: + """ + require 'rspec/core' + + describe String do + it "has a failing example" do + "foo".reverse.should == "ofo" + end + end + """ + And a file named "integer_spec.rb" with: + """ + require 'rspec/core' + + describe Integer do + it "has a failing example" do + (7 + 5).should == 11 + end + end + """ + When I run "ruby ./integer_spec.rb ./string_spec.rb" + Then the backtrace-normalized output should contain: + """ + Failures: + + 1) Integer has a failing example + Failure/Error: (7 + 5).should == 11 + expected: 11 + got: 12 (using ==) + # ./integer_spec.rb:5 + + 2) String has a failing example + Failure/Error: "foo".reverse.should == "ofo" + expected: "ofo" + got: "oof" (using ==) + # ./string_spec.rb:5 + """ + diff --git a/features/step_definitions/additional_cli_steps.rb b/features/step_definitions/additional_cli_steps.rb index 51e1e6a470..ddf0e38bee 100644 --- a/features/step_definitions/additional_cli_steps.rb +++ b/features/step_definitions/additional_cli_steps.rb @@ -18,3 +18,13 @@ Then /^the file "([^"]*)" should contain:$/ do |file, partial_content| check_file_content(file, partial_content, true) end + +Then /^the backtrace\-normalized output should contain:$/ do |partial_output| + # ruby 1.9 includes additional stuff in the backtrace, + # so we need to normalize it to compare it with our expected output. + normalized_output = combined_output.split("\n").map do |line| + line =~ /(^\s+# [^:]+:\d+)/ ? $1 : line # http://rubular.com/r/zDD7DdWyzF + end.join("\n") + + normalized_output.should =~ compile_and_escape(partial_output) +end diff --git a/lib/rspec/core/formatters/base_formatter.rb b/lib/rspec/core/formatters/base_formatter.rb index 497a4a62f2..410a338738 100644 --- a/lib/rspec/core/formatters/base_formatter.rb +++ b/lib/rspec/core/formatters/base_formatter.rb @@ -95,6 +95,11 @@ def close def format_backtrace(backtrace, example) return "" unless backtrace return backtrace if example.metadata[:full_backtrace] == true + + if at_exit_index = backtrace.index(RSpec::Core::Runner::AT_EXIT_HOOK_BACKTRACE_LINE) + backtrace = backtrace[0, at_exit_index] + end + cleansed = backtrace.map { |line| backtrace_line(line) }.compact cleansed.empty? ? backtrace : cleansed end diff --git a/lib/rspec/core/runner.rb b/lib/rspec/core/runner.rb index dc54debf81..860d2d6727 100644 --- a/lib/rspec/core/runner.rb +++ b/lib/rspec/core/runner.rb @@ -9,6 +9,7 @@ def self.autorun @installed_at_exit = true at_exit { run(ARGV, $stderr, $stdout) ? exit(0) : exit(1) } end + AT_EXIT_HOOK_BACKTRACE_LINE = "#{__FILE__}:#{__LINE__ - 2}:in `autorun'" def self.autorun_disabled? @autorun_disabled ||= false diff --git a/spec/rspec/core/formatters/base_formatter_spec.rb b/spec/rspec/core/formatters/base_formatter_spec.rb index 56b39430a1..de5f647889 100644 --- a/spec/rspec/core/formatters/base_formatter_spec.rb +++ b/spec/rspec/core/formatters/base_formatter_spec.rb @@ -56,4 +56,24 @@ class String end end + describe "#format_backtrace" do + let(:rspec_expectations_dir) { "/path/to/rspec-expectations/lib" } + let(:rspec_core_dir) { "/path/to/rspec-core/lib" } + let(:backtrace) do + [ + "#{rspec_expectations_dir}/rspec/matchers/operator_matcher.rb:51:in `eval_match'", + "#{rspec_expectations_dir}/rspec/matchers/operator_matcher.rb:29:in `=='", + "./my_spec.rb:5", + "#{rspec_core_dir}/rspec/core/example.rb:52:in `run'", + "#{rspec_core_dir}/rspec/core/runner.rb:37:in `run'", + RSpec::Core::Runner::AT_EXIT_HOOK_BACKTRACE_LINE, + "./my_spec.rb:3" + ] + end + + it "removes lines from rspec and lines that come before the invocation of the at_exit autorun hook" do + formatter.format_backtrace(backtrace, stub.as_null_object).should == ["./my_spec.rb:5"] + end + end + end From ebc4bffaeb6144334f66cbb67366628ae7a12877 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sun, 20 Feb 2011 17:10:22 -0800 Subject: [PATCH 022/151] Add cuke for user-defined metadata. --- features/.nav | 1 + features/metadata/user_defined.feature | 72 ++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 features/metadata/user_defined.feature diff --git a/features/.nav b/features/.nav index ffaa6a905b..7a34ed2cb3 100644 --- a/features/.nav +++ b/features/.nav @@ -20,6 +20,7 @@ - arbitrary_methods.feature - metadata: - described_class.feature + - user_defined.feature - filtering: - inclusion_filters.feature - exclusion_filters.feature diff --git a/features/metadata/user_defined.feature b/features/metadata/user_defined.feature new file mode 100644 index 0000000000..ea99832d4a --- /dev/null +++ b/features/metadata/user_defined.feature @@ -0,0 +1,72 @@ +Feature: User-defined metadata + + You can attach user-defined metadata to any example group or example. + Pass a hash as the last argument (before the block) to `describe`, + `context` or `it`. RSpec supports many configuration options that apply + only to certain examples or groups based on the metadata. + + Metadata defined on an example group is available (and can be overriden) + by any sub-group or from any example in that group or a sub-group. + + Scenario: define group metadata using a hash + Given a file named "define_group_metadata_with_hash_spec.rb" with: + """ + describe "a group with user-defined metadata", :foo => 17 do + it 'has access to the metadata in the example' do + example.metadata[:foo].should == 17 + end + + it 'does not have access to metadata defined on sub-groups' do + example.metadata.should_not include(:bar) + end + + describe 'a sub-group with user-defined metadata', :bar => 12 do + it 'has access to the sub-group metadata' do + example.metadata[:foo].should == 17 + end + + it 'also has access to metadata defined on parent groups' do + example.metadata[:bar].should == 12 + end + end + end + """ + When I run "rspec define_group_metadata_with_hash_spec.rb" + Then the examples should all pass + + Scenario: define example metadata using a hash + Given a file named "define_example_metadata_with_hash_spec.rb" with: + """ + describe "a group with no user-defined metadata" do + it 'has an example with metadata', :foo => 17 do + example.metadata[:foo].should == 17 + example.metadata.should_not include(:bar) + end + + it 'has another example with metadata', :bar => 12, :bazz => 33 do + example.metadata[:bar].should == 12 + example.metadata[:bazz].should == 33 + example.metadata.should_not include(:foo) + end + end + """ + When I run "rspec define_example_metadata_with_hash_spec.rb" + Then the examples should all pass + + Scenario: override user-defined metadata + Given a file named "override_metadata_spec.rb" with: + """ + describe "a group with user-defined metadata", :foo => 'bar' do + it 'can be overriden by an example', :foo => 'bazz' do + example.metadata[:foo].should == 'bazz' + end + + describe "a sub-group with an override", :foo => 'goo' do + it 'can be overriden by a sub-group' do + example.metadata[:foo].should == 'goo' + end + end + end + """ + When I run "rspec override_metadata_spec.rb" + Then the examples should all pass From 41d11e2da3566cd6e3fc208b92993ef1b9a72d98 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 22 Feb 2011 09:14:55 -0800 Subject: [PATCH 023/151] Add new treat_symbols_as_metadata_keys_with_true_values option. Closes #304. --- features/metadata/user_defined.feature | 39 ++++++++++++++++++ lib/rspec/core.rb | 1 + lib/rspec/core/configuration.rb | 1 + lib/rspec/core/example_group.rb | 7 +++- lib/rspec/core/metadata_hash_builder.rb | 54 +++++++++++++++++++++++++ spec/rspec/core/configuration_spec.rb | 11 +++++ spec/rspec/core/example_group_spec.rb | 38 +++++++++++++++++ spec/rspec/core/example_spec.rb | 7 ++++ spec/support/shared_example_groups.rb | 41 +++++++++++++++++++ 9 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 lib/rspec/core/metadata_hash_builder.rb create mode 100644 spec/support/shared_example_groups.rb diff --git a/features/metadata/user_defined.feature b/features/metadata/user_defined.feature index ea99832d4a..5730a9c321 100644 --- a/features/metadata/user_defined.feature +++ b/features/metadata/user_defined.feature @@ -8,6 +8,17 @@ Feature: User-defined metadata Metadata defined on an example group is available (and can be overriden) by any sub-group or from any example in that group or a sub-group. + In addition, there is a configuration option (which will be the default + behavior in RSpec 3) that allows you to specify metadata using just + symbols: + + RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true + end + + Each symbol passed as an argument to `describe`, `context` or `it` will + be a key in the metadata hash, with a corresponding value of `true`. + Scenario: define group metadata using a hash Given a file named "define_group_metadata_with_hash_spec.rb" with: """ @@ -70,3 +81,31 @@ Feature: User-defined metadata """ When I run "rspec override_metadata_spec.rb" Then the examples should all pass + + Scenario: less verbose metadata + Given a file named "less_verbose_metadata_spec.rb" with: + """ + RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true + end + + describe "a group with simple metadata", :fast, :simple, :bug => 73 do + it 'has `:fast => true` metadata' do + example.metadata[:fast].should == true + end + + it 'has `:simple => true` metadata' do + example.metadata[:simple].should == true + end + + it 'can still use a hash for metadata' do + example.metadata[:bug].should == 73 + end + + it 'can define simple metadata on an example', :special do + example.metadata[:special].should == true + end + end + """ + When I run "rspec less_verbose_metadata_spec.rb" + Then the examples should all pass diff --git a/lib/rspec/core.rb b/lib/rspec/core.rb index 2e18a5f965..b747e3ab77 100644 --- a/lib/rspec/core.rb +++ b/lib/rspec/core.rb @@ -9,6 +9,7 @@ require 'rspec/core/let' require 'rspec/core/metadata' require 'rspec/core/pending' +require 'rspec/core/metadata_hash_builder' require 'rspec/core/world' require 'rspec/core/configuration' diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 08a5eace77..7f20b4ff08 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -33,6 +33,7 @@ def self.add_setting(name, opts={}) add_setting :include_or_extend_modules add_setting :backtrace_clean_patterns add_setting :tty + add_setting :treat_symbols_as_metadata_keys_with_true_values, :default => false def initialize @color_enabled = false diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 3c76cf15b2..398bbb5e91 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -8,6 +8,7 @@ class ExampleGroup include Subject::InstanceMethods include Let include Pending + extend MetadataHashBuilder attr_accessor :example @@ -41,7 +42,8 @@ def self.delegate_to_metadata(*names) def self.define_example_method(name, extra_options={}) module_eval(<<-END_RUBY, __FILE__, __LINE__) - def self.#{name}(desc=nil, options={}, &block) + def self.#{name}(desc=nil, *args, &block) + options = build_metadata_hash_from(args) options.update(:pending => true) unless block options.update(#{extra_options.inspect}) examples << RSpec::Core::Example.new(self, desc, options, block) @@ -150,6 +152,9 @@ def self.top_level? end def self.set_it_up(*args) + symbol_description = args.shift if args.first.is_a?(Symbol) + args << build_metadata_hash_from(args) + args.unshift(symbol_description) if symbol_description @metadata = RSpec::Core::Metadata.new(superclass_metadata).process(*args) world.configure_group(self) end diff --git a/lib/rspec/core/metadata_hash_builder.rb b/lib/rspec/core/metadata_hash_builder.rb new file mode 100644 index 0000000000..a7d3ba2f64 --- /dev/null +++ b/lib/rspec/core/metadata_hash_builder.rb @@ -0,0 +1,54 @@ +module RSpec + module Core + module MetadataHashBuilder + def build_metadata_hash_from(args) + metadata = args.last.is_a?(Hash) ? args.pop : {} + + if RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values? + add_symbols_to_hash(metadata, args) + else + warn_about_deprecated_symbol_usage(args) + end + + metadata + end + + private + + def add_symbols_to_hash(hash, args) + while args.last.is_a?(Symbol) + hash[args.pop] = true + end + end + + def warn_about_deprecated_symbol_usage(args) + symbols = args.select { |a| a.is_a?(Symbol) } + return if symbols.empty? + + Kernel.warn <<-NOTICE + +***************************************************************** +DEPRECATION WARNING: you are using deprecated behaviour that will +be removed from RSpec 3.0. + +You have passed symbols (#{symbols.inspect}) as additional +arguments for a doc string. + +In RSpec 3.0, these symbols will be treated as metadata keys with +a value of `true`. To get this behavior now (and prevent this +warning), you can set a configuration option: + +RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true +end + +Alternately, if your intention is to use the symbol as part of the +doc string (i.e. to specify a method name), you can change it to +a string such as "#method_name" to remove this warning. +***************************************************************** + +NOTICE + end + end + end +end diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 6c044f7290..a57d378cc8 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -30,6 +30,17 @@ module RSpec::Core end end + describe "#treat_symbols_as_metadata_keys_with_true_values?" do + it 'can be set to true' do + config.treat_symbols_as_metadata_keys_with_true_values = true + config.treat_symbols_as_metadata_keys_with_true_values?.should be_true + end + + it 'defaults to false' do + config.treat_symbols_as_metadata_keys_with_true_values?.should be_false + end + end + describe "#mock_framework" do it "defaults to :rspec" do config.should_receive(:require).with('rspec/core/mocking/with_rspec') diff --git a/spec/rspec/core/example_group_spec.rb b/spec/rspec/core/example_group_spec.rb index 0a0e382e21..35050262c1 100644 --- a/spec/rspec/core/example_group_spec.rb +++ b/spec/rspec/core/example_group_spec.rb @@ -13,6 +13,44 @@ def initialize module RSpec::Core describe ExampleGroup do + it_behaves_like "metadata hash builder" do + def metadata_hash(*args) + group = ExampleGroup.describe('example description', *args) + group.metadata + end + end + + context 'when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false' do + before(:each) do + RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = false } + Kernel.stub(:warn) + end + + it 'processes string args as part of the description' do + group = ExampleGroup.describe("some", "separate", "strings") + group.description.should == "some separate strings" + end + + it 'processes symbol args as part of the description' do + group = ExampleGroup.describe(:some, :separate, :symbols) + group.description.should == "some separate symbols" + end + end + + context 'when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true' do + let(:group) { ExampleGroup.describe(:symbol) } + before(:each) do + RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = true } + end + + it 'does not treat the first argument as a metadata key even if it is a symbol' do + group.metadata.should_not include(:symbol) + end + + it 'treats the first argument as part of the description when it is a symbol' do + group.description.should == "symbol" + end + end describe "top level group" do it "runs its children" do diff --git a/spec/rspec/core/example_spec.rb b/spec/rspec/core/example_spec.rb index ed2b89d7a6..38c887daeb 100644 --- a/spec/rspec/core/example_spec.rb +++ b/spec/rspec/core/example_spec.rb @@ -9,6 +9,13 @@ example_group.example('example description') end + it_behaves_like "metadata hash builder" do + def metadata_hash(*args) + example = example_group.example('example description', *args) + example.metadata + end + end + describe '#described_class' do it "returns the class (if any) of the outermost example group" do described_class.should == RSpec::Core::Example diff --git a/spec/support/shared_example_groups.rb b/spec/support/shared_example_groups.rb new file mode 100644 index 0000000000..f53b318685 --- /dev/null +++ b/spec/support/shared_example_groups.rb @@ -0,0 +1,41 @@ +shared_examples_for "metadata hash builder" do + context "when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true" do + let(:hash) { metadata_hash(:foo, :bar, :bazz => 23) } + + before(:each) do + RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = true } + end + + it 'treats symbols as metadata keys with a true value' do + hash[:foo].should == true + hash[:bar].should == true + end + + it 'still processes hash values normally' do + hash[:bazz].should == 23 + end + end + + context "when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false" do + let(:warning_receiver) { Kernel } + + before(:each) do + RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = false } + warning_receiver.stub(:warn) + end + + it 'prints a deprecation warning about any symbols given as arguments' do + warning_receiver.should_receive(:warn).with(/you have passed symbols \(\[:foo, :bar\]\) as additional\s+arguments for a doc string/i) + metadata_hash(:foo, :bar, :key => 'value') + end + + it 'does not treat symbols as metadata keys' do + metadata_hash(:foo, :bar, :key => 'value').should_not include(:foo, :bar) + end + + it 'does not print a warning if there are no symbol arguments' do + warning_receiver.should_not_receive(:warn) + metadata_hash(:foo => 23, :bar => 17) + end + end +end From d6e84c3896436d4df5f112eb8998dcc9a5e543cb Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Fri, 25 Feb 2011 05:31:59 -0800 Subject: [PATCH 024/151] Removed unused matcher. --- spec/support/matchers.rb | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 3791b11c2a..4c9d188010 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -19,26 +19,3 @@ def prepare(autotest) autotest end end - -RSpec::Matchers.define :have_interface_for do |method| - match do |object| - @method = method - @object = object - object.respond_to?(method) && actual_arity == @expected_arity - end - - chain :with do |arity| - @expected_arity = arity - end - - chain(:argument) {} - chain(:arguments) {} - - failure_message_for_should do - "#{@object} should have method :#{@method} with #{@expected_arity} argument(s), but it had #{actual_arity}" - end - - def actual_arity - @object.method(@method).arity - end -end From da49bee71428f1b3804c64dc8622c7b0d1b918af Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sat, 26 Feb 2011 11:53:51 -0800 Subject: [PATCH 025/151] Move custom matchers into spec/support/matchers.rb. --- spec/rspec/core/pending_example_spec.rb | 49 ------------------------ spec/support/matchers.rb | 50 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/spec/rspec/core/pending_example_spec.rb b/spec/rspec/core/pending_example_spec.rb index 915896ce6f..f68fe1f6ab 100644 --- a/spec/rspec/core/pending_example_spec.rb +++ b/spec/rspec/core/pending_example_spec.rb @@ -1,54 +1,5 @@ require 'spec_helper' -RSpec::Matchers.define :be_pending_with do |message| - match do |example| - example.metadata[:pending] && example.metadata[:execution_result][:pending_message] == message - end - - failure_message_for_should do |example| - "expected example to pending with #{message.inspect}, got #{example.metadata[:execution_result][:pending_message].inspect}" - end -end - -RSpec::Matchers.define :fail_with do |exception_klass| - match do |example| - failure_reason(example, exception_klass).nil? - end - - failure_message_for_should do |example| - "expected example to fail with a #{exception_klass} exception, but #{failure_reason(example, exception_klass)}" - end - - def failure_reason(example, exception_klass) - result = example.metadata[:execution_result] - case - when example.metadata[:pending] then "was pending" - when result[:status] != 'failed' then result[:status] - when !result[:exception].is_a?(exception_klass) then "failed with a #{result[:exception].class}" - else nil - end - end -end - -RSpec::Matchers.define :pass do - match do |example| - failure_reason(example).nil? - end - - failure_message_for_should do |example| - "expected example to pass, but #{failure_reason(example)}" - end - - def failure_reason(example) - result = example.metadata[:execution_result] - case - when example.metadata[:pending] then "was pending" - when result[:status] != 'passed' then result[:status] - else nil - end - end -end - describe "an example" do context "with no block" do it "is listed as pending with 'Not Yet Implemented'" do diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 4c9d188010..648a776ff5 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -19,3 +19,53 @@ def prepare(autotest) autotest end end + +RSpec::Matchers.define :be_pending_with do |message| + match do |example| + example.metadata[:pending] && example.metadata[:execution_result][:pending_message] == message + end + + failure_message_for_should do |example| + "expected example to pending with #{message.inspect}, got #{example.metadata[:execution_result][:pending_message].inspect}" + end +end + +RSpec::Matchers.define :fail_with do |exception_klass| + match do |example| + failure_reason(example, exception_klass).nil? + end + + failure_message_for_should do |example| + "expected example to fail with a #{exception_klass} exception, but #{failure_reason(example, exception_klass)}" + end + + def failure_reason(example, exception_klass) + result = example.metadata[:execution_result] + case + when example.metadata[:pending] then "was pending" + when result[:status] != 'failed' then result[:status] + when !result[:exception].is_a?(exception_klass) then "failed with a #{result[:exception].class}" + else nil + end + end +end + +RSpec::Matchers.define :pass do + match do |example| + failure_reason(example).nil? + end + + failure_message_for_should do |example| + "expected example to pass, but #{failure_reason(example)}" + end + + def failure_reason(example) + result = example.metadata[:execution_result] + case + when example.metadata[:pending] then "was pending" + when result[:status] != 'passed' then result[:status] + else nil + end + end +end + From d37bc380d2e3b7809728f08b855e276843d9b678 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sat, 26 Feb 2011 12:50:06 -0800 Subject: [PATCH 026/151] Downgrade flexmock to last version that is compatible with 1.8.6 so our cukes pass on 1.8.6. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3562ae0005..81a2da7b8f 100644 --- a/Gemfile +++ b/Gemfile @@ -46,7 +46,7 @@ end ### rspec-core only gem "mocha", "~> 0.9.10" gem "rr", "~> 1.0.2" -gem "flexmock", "~> 0.8.11" +gem "flexmock", "0.8.8" ### optional runtime deps gem "syntax", "1.0.0" From 91d1b0af4e6202c096a3d122a1fdda9a849679b7 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sat, 26 Feb 2011 13:15:13 -0800 Subject: [PATCH 027/151] Fix specs on 1.9.1p378. I have no idea why, but on 1.9.1p378, I was getting errors like "undefined method `to_int' for class `#::String'". This fixes it. Apparently `class String` was creating a new class rather than re-opening the existing String class. `String.class_eval do` ensures we run the alias/undef code in the context of the existing string class. Yes, this does make no sense whatsoever. Must be a weird 1.9.1 bug. --- spec/rspec/core/formatters/base_formatter_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/rspec/core/formatters/base_formatter_spec.rb b/spec/rspec/core/formatters/base_formatter_spec.rb index de5f647889..7cfb85b982 100644 --- a/spec/rspec/core/formatters/base_formatter_spec.rb +++ b/spec/rspec/core/formatters/base_formatter_spec.rb @@ -34,13 +34,13 @@ context "when String alias to_int to_i" do before do - class String + String.class_eval do alias :to_int :to_i end end after do - class String + String.class_eval do undef to_int end end From bc046aa304fdbfcc948f18a955e44cf896cb5eb0 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sat, 26 Feb 2011 13:20:20 -0800 Subject: [PATCH 028/151] Regenerated html fixtures for 1.9.1. The specs that use them were failing. --- .../core/formatters/html_formatted-1.9.1.html | 10 ++-- .../formatters/text_mate_formatted-1.9.1.html | 52 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/spec/rspec/core/formatters/html_formatted-1.9.1.html b/spec/rspec/core/formatters/html_formatted-1.9.1.html index aa765eeaf2..bb02f09a07 100644 --- a/spec/rspec/core/formatters/html_formatted-1.9.1.html +++ b/spec/rspec/core/formatters/html_formatted-1.9.1.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46:in `block (4 levels) in ' ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `block (3 levels) in ' -
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html b/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html index 7df0f2ef70..a43768e66a 100644 --- a/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html +++ b/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html @@ -312,18 +312,18 @@

RSpec Code Examples

fails
RSpec::Core::PendingExampleFixedError
- -
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+ +
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
@@ -350,13 +350,13 @@

RSpec Code Examples

(compared using ==) - +
27        end
 28
 29        raise(RSpec::Expectations::ExpectationNotMetError.new(message))
@@ -376,13 +376,13 @@ 

RSpec Code Examples

-1# Couldn't get snippet for (erb)
From aa0d179ccef6fa2ff8c95d711eb3b02e5d7bcadb Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sat, 26 Feb 2011 10:03:50 -0800 Subject: [PATCH 029/151] Remove coupling to rspec-expectations. Generated example descriptions only work when using rspec-expectations and the code should not use RSpec::Matchers when configured to use :stdlib. --- .../configure_expectation_framework.feature | 13 ++++- lib/rspec/core/configuration.rb | 10 ++-- lib/rspec/core/example.rb | 18 +++++- spec/rspec/core/example_spec.rb | 58 +++++++++++++++++++ spec/rspec/core/subject_spec.rb | 1 + spec/support/matchers.rb | 4 ++ 6 files changed, 95 insertions(+), 9 deletions(-) diff --git a/features/expectation_framework_integration/configure_expectation_framework.feature b/features/expectation_framework_integration/configure_expectation_framework.feature index 055267d8b3..682ac80eed 100644 --- a/features/expectation_framework_integration/configure_expectation_framework.feature +++ b/features/expectation_framework_integration/configure_expectation_framework.feature @@ -9,6 +9,10 @@ Feature: configure expectation framework * minitest assertions in ruby 1.9 * rspec/expecations _and_ stlib assertions + Note that when you do not use rspec-expectations, you must explicitly + provide a description to every example. You cannot rely on the generated + descriptions provided by rspec-expectations. + Scenario: configure rspec-expectations (explicitly) Given a file named "example_spec.rb" with: """ @@ -36,10 +40,17 @@ Feature: configure expectation framework it "is greater than 4" do assert 5 > 4, "expected 5 to be greater than 4" end + + specify { assert 5 < 6 } end """ When I run "rspec example_spec.rb" - Then the examples should all pass + Then the output should contain "2 examples, 1 failure" + And the output should contain: + """ + NotImplementedError: + Generated descriptions are only supported when you use rspec-expectations. + """ Scenario: configure rspec/expecations AND test/unit assertions Given a file named "example_spec.rb" with: diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 7f20b4ff08..ec1204a54a 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -34,6 +34,7 @@ def self.add_setting(name, opts={}) add_setting :backtrace_clean_patterns add_setting :tty add_setting :treat_symbols_as_metadata_keys_with_true_values, :default => false + add_setting :expecting_with_rspec def initialize @color_enabled = false @@ -170,13 +171,11 @@ def mock_framework=(framework) # Returns the configured expectation framework adapter module(s) def expectation_frameworks - settings[:expectation_frameworks] ||= begin - require 'rspec/core/expecting/with_rspec' - [RSpec::Core::ExpectationFrameworkAdapter] - end + expect_with :rspec unless settings[:expectation_frameworks] + settings[:expectation_frameworks] end - # Delegates to expect_with=([framework]) + # Delegates to expect_with([framework]) def expectation_framework=(framework) expect_with([framework]) end @@ -196,6 +195,7 @@ def expect_with(*frameworks) case framework when :rspec require 'rspec/core/expecting/with_rspec' + self.expecting_with_rspec = true when :stdlib require 'rspec/core/expecting/with_stdlib' else diff --git a/lib/rspec/core/example.rb b/lib/rspec/core/example.rb index 3ddf060bf2..c49eae9aaa 100644 --- a/lib/rspec/core/example.rb +++ b/lib/rspec/core/example.rb @@ -59,7 +59,12 @@ def run(example_group_instance, reporter) set_exception(e) ensure @example_group_instance.example = nil - assign_auto_description + + begin + assign_auto_description + rescue Exception => e + set_exception(e) + end end finish(reporter) @@ -146,8 +151,15 @@ def run_after_each def assign_auto_description if description.empty? and !pending? - metadata[:description] = RSpec::Matchers.generated_description - RSpec::Matchers.clear_generated_description + if RSpec.configuration.expecting_with_rspec? + metadata[:description] = RSpec::Matchers.generated_description + RSpec::Matchers.clear_generated_description + else + raise NotImplementedError.new( + "Generated descriptions are only supported when you use rspec-expectations. " + + "You must give every example an explicit description." + ) + end end end diff --git a/spec/rspec/core/example_spec.rb b/spec/rspec/core/example_spec.rb index 38c887daeb..f4d765c503 100644 --- a/spec/rspec/core/example_spec.rb +++ b/spec/rspec/core/example_spec.rb @@ -16,6 +16,64 @@ def metadata_hash(*args) end end + describe "auto-generated example descriptions" do + let(:generated_description) { "the generated description" } + let(:rspec_example) { example_group.specify { 5.should == 5 } } + before(:each) { RSpec::Matchers.stub(:generated_description => generated_description) } + + def expect_with(*frameworks) + # this is stubbed to prevent us from actually including stdlib assertions, + # as the additional methods have naming conflicts with some of our custom + # matchers + RSpec.configuration.stub(:require).with(%r|rspec/core/expecting/|) + RSpec.configure { |c| c.expect_with *frameworks } + RSpec.configuration.configure_expectation_framework + + if frameworks.include?(:stdlib) + example_group.class_eval do + def assert(val) + raise "Expected #{val} to be true" unless val + end + end + end + end + + context "when `expect_with :rspec` is configured" do + before(:each) { expect_with :rspec } + + it "generates a description for an example with no description" do + expect { + example_group.run + }.to change { rspec_example.metadata[:description] }.from("").to(generated_description) + end + end + + context "when `expect_with :rspec, :stdlib` is configured" do + before(:each) { expect_with :rspec, :stdlib } + + it "generates a description for an example with no description" do + expect { + example_group.run + }.to change { rspec_example.metadata[:description] }.from("").to(generated_description) + end + end + + context "when `expect_with :stdlib` is configured" do + let!(:stdlib_example) { example_group.specify { assert 5 == 5 } } + before(:each) { expect_with :stdlib } + + it "does not attempt to get the generated description from RSpec::Matchers" do + RSpec::Matchers.should_not_receive(:generated_description) + example_group.run + end + + it "fails an example with no description" do + example_group.run + stdlib_example.should have_failed_with(NotImplementedError) + end + end + end + describe '#described_class' do it "returns the class (if any) of the outermost example group" do described_class.should == RSpec::Core::Example diff --git a/spec/rspec/core/subject_spec.rb b/spec/rspec/core/subject_spec.rb index c4ee602210..9b9c22afa1 100644 --- a/spec/rspec/core/subject_spec.rb +++ b/spec/rspec/core/subject_spec.rb @@ -3,6 +3,7 @@ module RSpec::Core describe Subject do + before(:each) { RSpec.configuration.configure_expectation_framework } describe "implicit subject" do describe "with a class" do diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 648a776ff5..f27e367e41 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -69,3 +69,7 @@ def failure_reason(example) end end +RSpec::Matchers.module_eval do + alias have_failed_with fail_with + alias have_passed pass +end From dbe818b9624d34368a25d667619ada67b48db46a Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 27 Feb 2011 09:53:18 -0600 Subject: [PATCH 030/151] gemspec tweaks --- rspec-core.gemspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rspec-core.gemspec b/rspec-core.gemspec index 50c4214dae..fc4aa62f3e 100644 --- a/rspec-core.gemspec +++ b/rspec-core.gemspec @@ -7,10 +7,10 @@ Gem::Specification.new do |s| s.version = RSpec::Core::Version::STRING s.platform = Gem::Platform::RUBY s.authors = ["Chad Humphries", "David Chelimsky"] - s.email = "dchelimsky@gmail.com;chad.humphries@gmail.com" - s.homepage = "http://github.com/rspec/rspec-core" + s.email = "rspec-users@rubyforge.org;" + s.homepage = "http://github.com/rspec" s.summary = "rspec-core-#{RSpec::Core::Version::STRING}" - s.description = "RSpec runner and example groups" + s.description = "BDD for Ruby. RSpec runner and example groups." s.rubygems_version = "1.3.7" s.rubyforge_project = "rspec" From b8011607e40057de1ec3e95cc949fdab0f3055da Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 2 Mar 2011 07:50:54 -0600 Subject: [PATCH 031/151] changelog --- features/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/features/Changelog.md b/features/Changelog.md index 37382c8376..c27126b424 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -10,6 +10,7 @@ * let/let! declarations * etc (anything you can do in a group) * `its([:key])` works for any subject with #[]. (Peter Jaros) + * `treat_symbols_as_metadata_keys_with_true_values` (Myron Marston) * Bug fixes * don't stumble over an exception without a message (Hans Hasselberg) From 0394f4a89fed04f81f1ccd74d51199c928fb94a0 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sat, 5 Mar 2011 20:09:55 -0800 Subject: [PATCH 032/151] Remove unused local variable. --- lib/rspec/core/configuration.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index ec1204a54a..7158222732 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -362,11 +362,6 @@ def extend(mod, filters={}) end def configure_group(group) - modules = { - :include => group.included_modules.dup, - :extend => group.ancestors.dup - } - include_or_extend_modules.each do |include_or_extend, mod, filters| next unless filters.empty? || group.apply?(:any?, filters) group.send(include_or_extend, mod) From 56616ec2e2df5d2d2ffaf41ff387fe9377f7c9c8 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 6 Mar 2011 10:37:51 -0600 Subject: [PATCH 033/151] no need to include matchers in spec helper --- spec/spec_helper.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0baee647a4..fbcc2d1f98 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,7 +15,6 @@ def sandboxed(&block) @orig_config = RSpec.configuration @orig_world = RSpec.world new_config = RSpec::Core::Configuration.new - new_config.include(RSpec::Matchers) new_world = RSpec::Core::World.new(new_config) RSpec.instance_variable_set(:@configuration, new_config) RSpec.instance_variable_set(:@world, new_world) From cfa9837e48619252dd585ec8f86c16fa4fd97611 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 6 Mar 2011 10:38:52 -0600 Subject: [PATCH 034/151] point Gemfile to git instead of published gems --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 81a2da7b8f..8c847a9cae 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ source "http://rubygems.org" if File.exist?(library_path) gem lib, :path => library_path else - gem lib + gem lib, :git => "https://github.com/rspec/#{lib}.git" end end From 622a4b7ac41e0ab6a4786070cca3ff866b72b57c Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sun, 6 Mar 2011 09:34:34 -0800 Subject: [PATCH 035/151] Fix how RSpec::Matchers is included in RSpec::Core::Example group to prevent SystemStackError on 1.9. --- lib/rspec/core/command_line.rb | 2 -- lib/rspec/core/example_group.rb | 17 ++++++++++ spec/rspec/core/command_line_spec.rb | 2 -- spec/rspec/core/rspec_matchers_spec.rb | 45 ++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 spec/rspec/core/rspec_matchers_spec.rb diff --git a/lib/rspec/core/command_line.rb b/lib/rspec/core/command_line.rb index 34af8b1d66..297358b8f5 100644 --- a/lib/rspec/core/command_line.rb +++ b/lib/rspec/core/command_line.rb @@ -16,8 +16,6 @@ def run(err, out) @configuration.output_stream ||= out @options.configure(@configuration) @configuration.load_spec_files - @configuration.configure_mock_framework - @configuration.configure_expectation_framework @world.announce_inclusion_filter @world.announce_exclusion_filter diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 398bbb5e91..1b80f08464 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -151,7 +151,24 @@ def self.top_level? @top_level ||= superclass == ExampleGroup end + def self.ensure_example_groups_are_configured + unless @example_groups_configured + RSpec.configuration.configure_mock_framework + RSpec.configuration.configure_expectation_framework + @example_groups_configured = true + end + end + def self.set_it_up(*args) + # Ruby 1.9 has a bug that can lead to infinite recursion and a + # SystemStackError if you include a module in a superclass after + # including it in a subclass: https://gist.github.com/845896 + # To prevent this, we must include any modules in RSpec::Core::ExampleGroup + # before users create example groups and have a chance to include + # the same module in a subclass of RSpec::Core::ExampleGroup. + # So we need to configure example groups here. + ensure_example_groups_are_configured + symbol_description = args.shift if args.first.is_a?(Symbol) args << build_metadata_hash_from(args) args.unshift(symbol_description) if symbol_description diff --git a/spec/rspec/core/command_line_spec.rb b/spec/rspec/core/command_line_spec.rb index 4e35973f24..5889ecae1f 100644 --- a/spec/rspec/core/command_line_spec.rb +++ b/spec/rspec/core/command_line_spec.rb @@ -50,8 +50,6 @@ module RSpec::Core config.stub(:run_hook) config.should_receive(:load_spec_files) - config.should_receive(:configure_mock_framework) - config.should_receive(:configure_expectation_framework) world.should_receive(:announce_inclusion_filter) world.should_receive(:announce_exclusion_filter) diff --git a/spec/rspec/core/rspec_matchers_spec.rb b/spec/rspec/core/rspec_matchers_spec.rb new file mode 100644 index 0000000000..128de47673 --- /dev/null +++ b/spec/rspec/core/rspec_matchers_spec.rb @@ -0,0 +1,45 @@ +require 'spec_helper' + +module RSpec::Matchers + def __method_with_super + super + end + + module ModThatIncludesMatchers + include RSpec::Matchers + end + + RSpec.configure do |c| + c.include RSpec::Matchers, :include_rspec_matchers => true + c.include ModThatIncludesMatchers, :include_mod_that_includes_rspec_matchers => true + end + + describe self do + shared_examples_for "a normal module with a method that supers" do + it "raises the expected error (and not SystemStackError)" do + expect { __method_with_super }.to raise_error(NoMethodError) # there is no __method_with_super in an ancestor + end + end + + it_behaves_like "a normal module with a method that supers" + + context "when RSpec::Matchers has been included in an example group" do + include RSpec::Matchers + it_behaves_like "a normal module with a method that supers" + end + + context "when a module that includes RSpec::Matchers has been included in an example group" do + include RSpec::Matchers::ModThatIncludesMatchers + it_behaves_like "a normal module with a method that supers" + end + + context "when RSpec::Matchers is included via configuration", :include_rspec_matchers => true do + it_behaves_like "a normal module with a method that supers" + end + + context "when RSpec::Matchers is included in a module that is included via configuration", :include_mod_that_includes_rspec_matchers => true do + it_behaves_like "a normal module with a method that supers" + end + end +end + From ab861a7228b7ad9cf888eed434444b55a0e8fd28 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sun, 6 Mar 2011 18:39:32 -0800 Subject: [PATCH 036/151] Fix how we spec expect_with so its not so fragile. --- spec/rspec/core/configuration_spec.rb | 22 ++++++++++++++++++++++ spec/rspec/core/example_spec.rb | 7 +------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index a57d378cc8..66d235fb43 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -111,6 +111,28 @@ module RSpec::Core end end + describe "#expecting_with_rspec?" do + before(:each) do + # prevent minitest assertions from being required and included, + # as that causes problems in some of our specs. + config.stub(:require) + end + + it "returns false by default" do + config.should_not be_expecting_with_rspec + end + + it "returns true when `expect_with :rspec` has been configured" do + config.expect_with :rspec + config.should be_expecting_with_rspec + end + + it "returns false when `expect_with :stdlib` has been configured" do + config.expect_with :stdlib + config.should_not be_expecting_with_rspec + end + end + context "setting the files to run" do it "loads files not following pattern if named explicitly" do diff --git a/spec/rspec/core/example_spec.rb b/spec/rspec/core/example_spec.rb index f4d765c503..c5104de2ee 100644 --- a/spec/rspec/core/example_spec.rb +++ b/spec/rspec/core/example_spec.rb @@ -22,12 +22,7 @@ def metadata_hash(*args) before(:each) { RSpec::Matchers.stub(:generated_description => generated_description) } def expect_with(*frameworks) - # this is stubbed to prevent us from actually including stdlib assertions, - # as the additional methods have naming conflicts with some of our custom - # matchers - RSpec.configuration.stub(:require).with(%r|rspec/core/expecting/|) - RSpec.configure { |c| c.expect_with *frameworks } - RSpec.configuration.configure_expectation_framework + RSpec.configuration.stub(:expecting_with_rspec?).and_return(frameworks.include?(:rspec)) if frameworks.include?(:stdlib) example_group.class_eval do From fc70cee014689a947bfdea1ab04d91191327946f Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sun, 6 Mar 2011 21:12:54 -0800 Subject: [PATCH 037/151] Print a warning when users configure RSpec after defining an example group. --- lib/rspec/core.rb | 21 +++++++++++++++++++++ spec/rspec/core_spec.rb | 28 ++++++++++++++++++++++++++++ spec/spec_helper.rb | 21 +++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/lib/rspec/core.rb b/lib/rspec/core.rb index b747e3ab77..d3bfe461e5 100644 --- a/lib/rspec/core.rb +++ b/lib/rspec/core.rb @@ -54,12 +54,33 @@ def self.configuration end def self.configure + warn_about_deprecated_configure if RSpec.world.example_groups.any? yield configuration if block_given? end def self.clear_remaining_example_groups world.example_groups.clear end + + private + + def self.warn_about_deprecated_configure + warn <<-NOTICE + +***************************************************************** +DEPRECATION WARNING: you are using deprecated behaviour that will +be removed from RSpec 3. + +You have set some configuration options after an example group has +already been defined. In RSpec 3, this will not be allowed. All +configuration should happen before the first example group is +defined. The configuration is happening at: + + #{caller[1]} +***************************************************************** + +NOTICE + end end require 'rspec/core/backward_compatibility' diff --git a/spec/rspec/core_spec.rb b/spec/rspec/core_spec.rb index b685b28271..b9437d462b 100644 --- a/spec/rspec/core_spec.rb +++ b/spec/rspec/core_spec.rb @@ -11,6 +11,13 @@ end describe "#configure" do + around(:each) do |example| + RSpec.allowing_configure_warning(&example) + end + + before(:each) do + RSpec.stub(:warn) + end it "yields the current configuration" do RSpec.configure do |config| @@ -18,6 +25,27 @@ end end + context "when an example group has already been defined" do + before(:each) do + RSpec.world.stub(:example_groups).and_return([stub.as_null_object]) + end + + it "prints a deprecation warning" do + RSpec.should_receive(:warn).with(/configuration should happen before the first example group/) + RSpec.configure { |c| } + end + end + + context "when no examples have been defined yet" do + before(:each) do + RSpec.world.stub(:example_groups).and_return([]) + end + + it "does not print a deprecation warning" do + RSpec.should_not_receive(:warn) + RSpec.configure { |c| } + end + end end describe "#world" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index fbcc2d1f98..739374eda1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -50,6 +50,27 @@ def in_editor? ENV.has_key?('TM_MODE') || ENV.has_key?('EMACS') || ENV.has_key?('VIM') end +class << RSpec + alias_method :original_warn_about_deprecated_configure, :warn_about_deprecated_configure + + def warn_about_deprecated_configure + # no-op: in our specs we don't want to see the warning. + end + + alias_method :null_warn_about_deprecated_configure, :warn_about_deprecated_configure + + def allowing_configure_warning + (class << self; self; end).class_eval do + alias_method :warn_about_deprecated_configure, :original_warn_about_deprecated_configure + begin + yield + ensure + alias_method :warn_about_deprecated_configure, :null_warn_about_deprecated_configure + end + end + end +end + RSpec.configure do |c| c.color_enabled = !in_editor? c.filter_run :focus => true From 62c9f033f19c63bda884b227d9d21843eab14b5f Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sun, 6 Mar 2011 21:18:59 -0800 Subject: [PATCH 038/151] Update changelog. --- features/Changelog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/Changelog.md b/features/Changelog.md index c27126b424..e56ee76939 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -11,6 +11,9 @@ * etc (anything you can do in a group) * `its([:key])` works for any subject with #[]. (Peter Jaros) * `treat_symbols_as_metadata_keys_with_true_values` (Myron Marston) + * Print a deprecation warning when you configure RSpec after defining + an example. All configuration should happen before any examples are + defined. (Myron Marston) * Bug fixes * don't stumble over an exception without a message (Hans Hasselberg) @@ -18,6 +21,9 @@ Byers) * fixed backtrace so it doesn't include lines from before the autorun at_exit hook (Myron Marston) + * Include RSpec::Matchers when first example group is defined, rather + than just before running the examples. This works around an obscure + bug in ruby 1.9 that can cause infinite recursion. (Myron Marston) ### 2.5.1 / 2011-02-06 From e3eb542b4d22b3d91c049200d7eda6bb3ee60a38 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Mon, 7 Mar 2011 10:55:32 -0800 Subject: [PATCH 039/151] Use #double as #mock and #stub will be deprecated in the future --- spec/rspec/core_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/rspec/core_spec.rb b/spec/rspec/core_spec.rb index b9437d462b..b3d451e2ed 100644 --- a/spec/rspec/core_spec.rb +++ b/spec/rspec/core_spec.rb @@ -27,7 +27,7 @@ context "when an example group has already been defined" do before(:each) do - RSpec.world.stub(:example_groups).and_return([stub.as_null_object]) + RSpec.world.stub(:example_groups).and_return([double.as_null_object]) end it "prints a deprecation warning" do From d90f1c158ec7fad462b36f4c042a89a63cad299f Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sun, 6 Mar 2011 08:50:22 -0800 Subject: [PATCH 040/151] Rewrite hook filtering cukes so they are more clear. Making assertions on the output of `puts` in the hooks interleaved with the documentation formatter output is a poor way to demonstrate this feature. --- features/hooks/filtering.feature | 245 +++++++++++++++---------------- 1 file changed, 119 insertions(+), 126 deletions(-) diff --git a/features/hooks/filtering.feature b/features/hooks/filtering.feature index 6470dd03fc..fc2da5a5ca 100644 --- a/features/hooks/filtering.feature +++ b/features/hooks/filtering.feature @@ -9,183 +9,176 @@ Feature: filters Given a file named "filter_before_each_hooks_spec.rb" with: """ RSpec.configure do |config| - config.before(:each, :foo => :bar) { puts "In hook" } + config.before(:each, :foo => :bar) do + invoked_hooks << :before_each_foo_bar + end end - describe "group 1" do - it("example 1") { } - it("example 2", :foo => :bar) { } - end + describe "a filtered before :each hook" do + let(:invoked_hooks) { [] } + + describe "group without matching metadata" do + it "does not run the hook" do + invoked_hooks.should be_empty + end + + it "runs the hook for an example with matching metadata", :foo => :bar do + invoked_hooks.should == [:before_each_foo_bar] + end + end - describe "group 2", :foo => :bar do - it("example 1") { } - it("example 2", :foo => :bar) { } + describe "group with matching metadata", :foo => :bar do + it "runs the hook" do + invoked_hooks.should == [:before_each_foo_bar] + end + end end """ - When I run "rspec filter_before_each_hooks_spec.rb --format documentation" - Then the output should contain: - """ - group 1 - example 1 - In hook - example 2 - - group 2 - In hook - example 1 - In hook - example 2 - """ + When I run "rspec filter_before_each_hooks_spec.rb" + Then the examples should all pass Scenario: filter `after(:each)` hooks using arbitrary metadata Given a file named "filter_after_each_hooks_spec.rb" with: """ RSpec.configure do |config| - config.after(:each, :foo => :bar) { puts "In hook" } + config.after(:each, :foo => :bar) do + raise "boom!" + end end - describe "group 1" do - it("example 1") { } - it("example 2", :foo => :bar) { } - end + describe "a filtered after :each hook" do + describe "group without matching metadata" do + it "does not run the hook" do + # should pass + end + + it "runs the hook for an example with matching metadata", :foo => :bar do + # should fail + end + end - describe "group 2", :foo => :bar do - it("example 1") { } - it("example 2", :foo => :bar) { } + describe "group with matching metadata", :foo => :bar do + it "runs the hook" do + # should fail + end + end end """ - When I run "rspec filter_after_each_hooks_spec.rb --format documentation" - Then the output should contain: - """ - group 1 - example 1 - In hook - example 2 - - group 2 - In hook - example 1 - In hook - example 2 - """ + When I run "rspec filter_after_each_hooks_spec.rb" + Then the output should contain "3 examples, 2 failures" Scenario: filter around(:each) hooks using arbitrary metadata Given a file named "filter_around_each_hooks_spec.rb" with: """ RSpec.configure do |config| config.around(:each, :foo => :bar) do |example| - puts "Start hook" + order << :before_around_each_foo_bar example.run - puts "End hook" + order.should == [:before_around_each_foo_bar, :example] end end - describe "group 1" do - it("example 1") { } - it("example 2", :foo => :bar) { } - end + describe "a filtered around(:each) hook" do + let(:order) { [] } + + describe "a group without matching metadata" do + it "does not run the hook" do + order.should be_empty + end - describe "group 2", :foo => :bar do - it("example 1") { } - it("example 2", :foo => :bar) { } + it "runs the hook for an example with matching metadata", :foo => :bar do + order.should == [:before_around_each_foo_bar] + order << :example + end + end + + describe "a group with matching metadata", :foo => :bar do + it "runs the hook for an example with matching metadata", :foo => :bar do + order.should == [:before_around_each_foo_bar] + order << :example + end + end end """ - When I run "rspec filter_around_each_hooks_spec.rb --format documentation" - Then the output should contain: - """ - group 1 - example 1 - Start hook - End hook - example 2 - - group 2 - Start hook - End hook - example 1 - Start hook - End hook - example 2 - """ + When I run "rspec filter_around_each_hooks_spec.rb" + Then the examples should all pass Scenario: filter before(:all) hooks using arbitrary metadata Given a file named "filter_before_all_hooks_spec.rb" with: """ RSpec.configure do |config| - config.before(:all, :foo => :bar) { puts "In hook" } + config.before(:all, :foo => :bar) { @hook = :before_all_foo_bar } end - describe "group 1" do - it("example 1") { } - it("example 2") { } - end + describe "a filtered before(:all) hook" do + describe "a group without matching metadata" do + it "does not run the hook" do + @hook.should be_nil + end - describe "group 2", :foo => :bar do - it("example 1") { } - it("example 2") { } - end + describe "a nested subgroup with matching metadata", :foo => :bar do + it "runs the hook" do + @hook.should == :before_all_foo_bar + end + end + end + + describe "a group with matching metadata", :foo => :bar do + it "runs the hook" do + @hook.should == :before_all_foo_bar + end - describe "group 3" do - describe "subgroup 1", :foo => :bar do - it("example 1") { } + describe "a nested subgroup" do + it "runs the hook" do + @hook.should == :before_all_foo_bar + end + end end end """ - When I run "rspec filter_before_all_hooks_spec.rb --format documentation" - Then the output should contain: - """ - group 1 - example 1 - example 2 - - group 2 - In hook - example 1 - example 2 - - group 3 - subgroup 1 - In hook - example 1 - """ + When I run "rspec filter_before_all_hooks_spec.rb" + Then the examples should all pass Scenario: filter after(:all) hooks using arbitrary metadata Given a file named "filter_after_all_hooks_spec.rb" with: """ + example_msgs = [] + RSpec.configure do |config| - config.after(:all, :foo => :bar) { puts "In hook" } + config.after(:all, :foo => :bar) do + puts "after :all" + end end - describe "group 1" do - it("example 1") { } - it("example 2") { } - end + describe "a filtered after(:all) hook" do + describe "a group without matching metadata" do + it "does not run the hook" do + puts "unfiltered" + end + end - describe "group 2", :foo => :bar do - it("example 1") { } - it("example 2") { } - end + describe "a group with matching metadata", :foo => :bar do + it "runs the hook" do + puts "filtered 1" + end + end - describe "group 3" do - describe "subgroup 1", :foo => :bar do - it("example 1") { } + describe "another group without matching metadata" do + describe "a nested subgroup with matching metadata", :foo => :bar do + it "runs the hook" do + puts "filtered 2" + end + end end end """ - When I run "rspec filter_after_all_hooks_spec.rb --format documentation" - Then the output should contain: + When I run "rspec filter_after_all_hooks_spec.rb" + Then the examples should all pass + And the output should contain: """ - group 1 - example 1 - example 2 - - group 2 - example 1 - example 2 - In hook - - group 3 - subgroup 1 - example 1 - In hook + unfiltered + .filtered 1 + .after :all + filtered 2 + .after :all """ From 2b2ef40e5cdeb879950beeaeaf833dcb0518b2dc Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 8 Mar 2011 06:45:52 -0600 Subject: [PATCH 041/151] Change class level instance var to class's class var so the block is only executed once per suite. --- lib/rspec/core/example_group.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 1b80f08464..288e7c933d 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -152,10 +152,10 @@ def self.top_level? end def self.ensure_example_groups_are_configured - unless @example_groups_configured + unless defined?(@@example_groups_configured) RSpec.configuration.configure_mock_framework RSpec.configuration.configure_expectation_framework - @example_groups_configured = true + @@example_groups_configured = true end end From 24ec6c836b7417c545e25cdbf62deb0dd040a980 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 06:02:41 -0800 Subject: [PATCH 042/151] Add additional examples. --- spec/rspec/core/configuration_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 66d235fb43..9bd5452797 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -127,6 +127,16 @@ module RSpec::Core config.should be_expecting_with_rspec end + it "returns true when `expect_with :rspec, :stdlib` has been configured" do + config.expect_with :rspec, :stdlib + config.should be_expecting_with_rspec + end + + it "returns true when `expect_with :stdlib, :rspec` has been configured" do + config.expect_with :stdlib, :rspec + config.should be_expecting_with_rspec + end + it "returns false when `expect_with :stdlib` has been configured" do config.expect_with :stdlib config.should_not be_expecting_with_rspec From 51cb0161f2a27dc0cba3de561aebc9f27a7f123b Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 08:44:24 -0800 Subject: [PATCH 043/151] Add cuke documenting how to include/extend a module in your example groups. --- features/helper_methods/modules.feature | 114 ++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 features/helper_methods/modules.feature diff --git a/features/helper_methods/modules.feature b/features/helper_methods/modules.feature new file mode 100644 index 0000000000..4db9af95f9 --- /dev/null +++ b/features/helper_methods/modules.feature @@ -0,0 +1,114 @@ +Feature: Define helper methods in a module + + You can define helper methods in a module and include it in + your example groups using the `config.include` configuration + option. `config.extend` can be used to extend the module onto + your example groups so that the methods in the module are available + in the example groups themselves (but not in the actual examples). + + You can also include or extend the module onto only certain example + groups by passing a metadata hash as the last argument. Only groups + that match the given metadata will include or extend the module. + + Background: + Given a file named "helpers.rb" with: + """ + module Helpers + def help + :available + end + end + """ + + Scenario: include a module in all example groups + Given a file named "include_module_spec.rb" with: + """ + require './helpers' + + RSpec.configure do |c| + c.include Helpers + end + + describe "an example group" do + it "has access the helper methods defined in the module" do + help.should be(:available) + end + end + """ + When I run "rspec include_module_spec.rb" + Then the examples should all pass + + Scenario: extend a module in all example groups + Given a file named "extend_module_spec.rb" with: + """ + require './helpers' + + RSpec.configure do |c| + c.extend Helpers + end + + describe "an example group" do + puts "Help is #{help}" + + it "does not have access to the helper methods defined in the module" do + expect { help }.to raise_error(NameError) + end + end + """ + When I run "rspec extend_module_spec.rb" + Then the examples should all pass + And the output should contain "Help is available" + + Scenario: include a module in only some example groups + Given a file named "include_module_in_some_groups_spec.rb" with: + """ + require './helpers' + + RSpec.configure do |c| + c.include Helpers, :foo => :bar + end + + describe "an example group with matching metadata", :foo => :bar do + it "has access the helper methods defined in the module" do + help.should be(:available) + end + end + + describe "an example group without matching metadata" do + it "does not have access to the helper methods defined in the module" do + expect { help }.to raise_error(NameError) + end + end + """ + When I run "rspec include_module_in_some_groups_spec.rb" + Then the examples should all pass + + Scenario: extend a module in only some example groups + Given a file named "extend_module_in_only_some_groups_spec.rb" with: + """ + require './helpers' + + RSpec.configure do |c| + c.extend Helpers, :foo => :bar + end + + describe "an example group with matching metadata", :foo => :bar do + puts "In a matching group, help is #{help}" + + it "does not have access to the helper methods defined in the module" do + expect { help }.to raise_error(NameError) + end + end + + describe "an example group without matching metadata" do + puts "In a non-matching group, help is #{help rescue 'not available'}" + + it "does not have access to the helper methods defined in the module" do + expect { help }.to raise_error(NameError) + end + end + """ + When I run "rspec extend_module_in_only_some_groups_spec.rb" + Then the examples should all pass + And the output should contain "In a matching group, help is available" + And the output should contain "In a non-matching group, help is not available" From 734aa81ddb7ba1b6b311d50fc7c0c859dc3a6940 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 8 Mar 2011 19:53:09 -0600 Subject: [PATCH 044/151] move require to right file --- lib/rspec/core/configuration_options.rb | 3 --- lib/rspec/core/option_parser.rb | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/rspec/core/configuration_options.rb b/lib/rspec/core/configuration_options.rb index e82f335e6a..468e6b5367 100644 --- a/lib/rspec/core/configuration_options.rb +++ b/lib/rspec/core/configuration_options.rb @@ -1,6 +1,3 @@ -# http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html -require 'optparse' - module RSpec module Core diff --git a/lib/rspec/core/option_parser.rb b/lib/rspec/core/option_parser.rb index 02255dd8a6..016c73523a 100644 --- a/lib/rspec/core/option_parser.rb +++ b/lib/rspec/core/option_parser.rb @@ -1,3 +1,6 @@ +# http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html +require 'optparse' + module RSpec::Core class Parser def self.parse!(args) From 9e8c7f4a22557fb9cbb3d23e025bac92de73f9ca Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 8 Mar 2011 20:11:00 -0600 Subject: [PATCH 045/151] Change --debug option to --debugger - --debug was not working for reasons unknown. - Closes #282. --- lib/rspec/core/option_parser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rspec/core/option_parser.rb b/lib/rspec/core/option_parser.rb index 016c73523a..5e099124b0 100644 --- a/lib/rspec/core/option_parser.rb +++ b/lib/rspec/core/option_parser.rb @@ -36,7 +36,7 @@ def parser(options) options[:color_enabled] = o end - parser.on('-d', '--debug', 'Enable debugging') do |o| + parser.on('-d', '--debugger', 'Enable debugging') do |o| options[:debug] = true end From ba0422785cad4891bc283b315148c8495ffea649 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 8 Mar 2011 20:26:54 -0600 Subject: [PATCH 046/151] require 'stringio' - Closes #328. --- lib/rspec/core/formatters/base_formatter.rb | 1 + spec/rspec/core/formatters/helpers_spec.rb | 1 - spec/rspec/core/formatters/progress_formatter_spec.rb | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/rspec/core/formatters/base_formatter.rb b/lib/rspec/core/formatters/base_formatter.rb index 410a338738..f00e1916d3 100644 --- a/lib/rspec/core/formatters/base_formatter.rb +++ b/lib/rspec/core/formatters/base_formatter.rb @@ -1,4 +1,5 @@ require 'rspec/core/formatters/helpers' +require 'stringio' module RSpec module Core diff --git a/spec/rspec/core/formatters/helpers_spec.rb b/spec/rspec/core/formatters/helpers_spec.rb index b86d0ab141..7ccef7757c 100644 --- a/spec/rspec/core/formatters/helpers_spec.rb +++ b/spec/rspec/core/formatters/helpers_spec.rb @@ -1,6 +1,5 @@ require 'spec_helper' require 'rspec/core/formatters/helpers' -require 'stringio' describe RSpec::Core::Formatters::Helpers do let(:helper) { helper = Object.new.extend(RSpec::Core::Formatters::Helpers) } diff --git a/spec/rspec/core/formatters/progress_formatter_spec.rb b/spec/rspec/core/formatters/progress_formatter_spec.rb index 61ebd3dfdc..e8a5922c18 100644 --- a/spec/rspec/core/formatters/progress_formatter_spec.rb +++ b/spec/rspec/core/formatters/progress_formatter_spec.rb @@ -1,6 +1,5 @@ require 'spec_helper' require 'rspec/core/formatters/progress_formatter' -require 'stringio' describe RSpec::Core::Formatters::ProgressFormatter do From b6544953d3b797713b53cf587359a26c5ca1849e Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sun, 6 Mar 2011 08:01:27 -0800 Subject: [PATCH 047/151] Abstract out the metadata symbol deprecation warning. The current message won't make sense for config options that use symbol metadata so this provides an easy way to define another module with a different warning message for use by configuration. --- lib/rspec/core/example_group.rb | 2 +- lib/rspec/core/metadata_hash_builder.rb | 47 +++++++++++++++---------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 288e7c933d..554978b53f 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -8,7 +8,7 @@ class ExampleGroup include Subject::InstanceMethods include Let include Pending - extend MetadataHashBuilder + extend MetadataHashBuilder::WithDeprecationWarning attr_accessor :example diff --git a/lib/rspec/core/metadata_hash_builder.rb b/lib/rspec/core/metadata_hash_builder.rb index a7d3ba2f64..baa3f39258 100644 --- a/lib/rspec/core/metadata_hash_builder.rb +++ b/lib/rspec/core/metadata_hash_builder.rb @@ -1,31 +1,41 @@ module RSpec module Core module MetadataHashBuilder - def build_metadata_hash_from(args) - metadata = args.last.is_a?(Hash) ? args.pop : {} + module Common + def build_metadata_hash_from(args) + metadata = args.last.is_a?(Hash) ? args.pop : {} - if RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values? - add_symbols_to_hash(metadata, args) - else - warn_about_deprecated_symbol_usage(args) + if RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values? + add_symbols_to_hash(metadata, args) + else + warn_about_symbol_usage(args) + end + + metadata end - metadata - end + private - private + def add_symbols_to_hash(hash, args) + while args.last.is_a?(Symbol) + hash[args.pop] = true + end + end - def add_symbols_to_hash(hash, args) - while args.last.is_a?(Symbol) - hash[args.pop] = true + def warn_about_symbol_usage(args) + symbols = args.select { |a| a.is_a?(Symbol) } + return if symbols.empty? + Kernel.warn symbol_metadata_warning(symbols) end - end + end + + module WithDeprecationWarning + include Common - def warn_about_deprecated_symbol_usage(args) - symbols = args.select { |a| a.is_a?(Symbol) } - return if symbols.empty? + private - Kernel.warn <<-NOTICE + def symbol_metadata_warning(symbols) + <<-NOTICE ***************************************************************** DEPRECATION WARNING: you are using deprecated behaviour that will @@ -48,7 +58,8 @@ def warn_about_deprecated_symbol_usage(args) ***************************************************************** NOTICE + end end - end + end end end From 5c5aa52b13706d85b431c4adc6db2c0730aca064 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Mon, 7 Mar 2011 22:35:42 -0800 Subject: [PATCH 048/151] Allow symbols to be treated as metadata filters for hooks. --- features/hooks/filtering.feature | 43 ++++++++++++++++++++++ lib/rspec/core.rb | 2 +- lib/rspec/core/hooks.rb | 12 ++++-- lib/rspec/core/metadata_hash_builder.rb | 29 ++++++++++++++- spec/rspec/core/hooks_spec.rb | 49 +++++++++++++++++++++++++ spec/support/shared_example_groups.rb | 2 +- 6 files changed, 129 insertions(+), 8 deletions(-) diff --git a/features/hooks/filtering.feature b/features/hooks/filtering.feature index fc2da5a5ca..e4d29a3cca 100644 --- a/features/hooks/filtering.feature +++ b/features/hooks/filtering.feature @@ -5,6 +5,9 @@ Feature: filters or example group, and used to make a hook only apply to examples with the given metadata. + If you set the `treat_symbols_as_metadata_keys_with_true_values` config option + to `true`, you can specify metadata using only symbols. + Scenario: filter `before(:each)` hooks using arbitrary metadata Given a file named "filter_before_each_hooks_spec.rb" with: """ @@ -182,3 +185,43 @@ Feature: filters filtered 2 .after :all """ + + Scenario: Use symbols as metadata + Given a file named "less_verbose_metadata_filter.rb" with: + """ + RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true + c.before(:each, :before_each) { puts "before each" } + c.after(:each, :after_each) { puts "after each" } + c.around(:each, :around_each) do |example| + puts "around each (before)" + example.run + puts "around each (after)" + end + c.before(:all, :before_all) { puts "before all" } + c.after(:all, :after_all) { puts "after all" } + end + + describe "group 1", :before_all, :after_all do + it("") { puts "example 1" } + it("", :before_each) { puts "example 2" } + it("", :after_each) { puts "example 3" } + it("", :around_each) { puts "example 4" } + end + """ + When I run "rspec less_verbose_metadata_filter.rb" + Then the examples should all pass + And the output should contain: + """ + before all + example 1 + .before each + example 2 + .example 3 + after each + .around each (before) + example 4 + around each (after) + .after all + """ + diff --git a/lib/rspec/core.rb b/lib/rspec/core.rb index d3bfe461e5..da570123c0 100644 --- a/lib/rspec/core.rb +++ b/lib/rspec/core.rb @@ -4,12 +4,12 @@ require 'rspec/core/backward_compatibility' require 'rspec/core/reporter' +require 'rspec/core/metadata_hash_builder' require 'rspec/core/hooks' require 'rspec/core/subject' require 'rspec/core/let' require 'rspec/core/metadata' require 'rspec/core/pending' -require 'rspec/core/metadata_hash_builder' require 'rspec/core/world' require 'rspec/core/configuration' diff --git a/lib/rspec/core/hooks.rb b/lib/rspec/core/hooks.rb index b878cb17fe..0014443190 100644 --- a/lib/rspec/core/hooks.rb +++ b/lib/rspec/core/hooks.rb @@ -1,6 +1,7 @@ module RSpec module Core module Hooks + include MetadataHashBuilder::WithConfigWarning class Hook attr_reader :options @@ -141,11 +142,14 @@ def find_hook(hook, scope, example_group_class, example = nil) private - def scope_and_options_from(scope=:each, options={}) - if Hash === scope - options = scope - scope = :each + def scope_and_options_from(*args) + scope = if [:each, :all, :suite].include?(args.first) + args.shift + else + :each end + + options = build_metadata_hash_from(args) return scope, options end end diff --git a/lib/rspec/core/metadata_hash_builder.rb b/lib/rspec/core/metadata_hash_builder.rb index baa3f39258..bedf1b8835 100644 --- a/lib/rspec/core/metadata_hash_builder.rb +++ b/lib/rspec/core/metadata_hash_builder.rb @@ -29,6 +29,31 @@ def warn_about_symbol_usage(args) end end + module WithConfigWarning + include Common + + private + + def symbol_metadata_warning(symbols) + <<-NOTICE + +***************************************************************** +WARNING: You have passed symbols (#{symbols.inspect}) as metadata +arguments to a configuration option. + +In RSpec 3, these symbols will be treated as metadata keys with +a value of `true`. To get this behavior now (and prevent this +warning), you can set a configuration option: + +RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true +end +***************************************************************** + +NOTICE + end + end + module WithDeprecationWarning include Common @@ -39,12 +64,12 @@ def symbol_metadata_warning(symbols) ***************************************************************** DEPRECATION WARNING: you are using deprecated behaviour that will -be removed from RSpec 3.0. +be removed from RSpec 3. You have passed symbols (#{symbols.inspect}) as additional arguments for a doc string. -In RSpec 3.0, these symbols will be treated as metadata keys with +In RSpec 3, these symbols will be treated as metadata keys with a value of `true`. To get this behavior now (and prevent this warning), you can set a configuration option: diff --git a/spec/rspec/core/hooks_spec.rb b/spec/rspec/core/hooks_spec.rb index 12d4f93570..7910110a70 100644 --- a/spec/rspec/core/hooks_spec.rb +++ b/spec/rspec/core/hooks_spec.rb @@ -2,6 +2,55 @@ module RSpec::Core describe Hooks do + class HooksHost + include Hooks + end + + [:before, :after, :around].each do |type| + [nil, :each, :all].each do |scope| + next if type == :around && scope == :all + + describe "##{type}(#{scope ? scope.inspect : 'default scope' })" do + it_behaves_like "metadata hash builder" do + define_method :metadata_hash do |*args| + instance = HooksHost.new + args.unshift scope if scope + hooks = instance.send(type, *args) { } + hooks.first.options + end + end + end + end + end + + [:before, :after].each do |type| + [:each, :all, :suite].each do |scope| + [true, false].each do |config_value| + context "when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to #{config_value}" do + before(:each) do + RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = config_value } + end + + describe "##{type}(#{scope.inspect})" do + let(:instance) { HooksHost.new } + let!(:hook) do + hooks = instance.send(type, scope) { } + hooks.first + end + + it "does not make #{scope.inspect} a metadata key" do + hook.options.should be_empty + end + + it "is scoped to #{scope.inspect}" do + instance.hooks[type][scope].should include(hook) + end + end + end + end + end + end + describe "#around" do context "when not running the example within the around block" do it "does not run the example" do diff --git a/spec/support/shared_example_groups.rb b/spec/support/shared_example_groups.rb index f53b318685..6ee8600fa5 100644 --- a/spec/support/shared_example_groups.rb +++ b/spec/support/shared_example_groups.rb @@ -25,7 +25,7 @@ end it 'prints a deprecation warning about any symbols given as arguments' do - warning_receiver.should_receive(:warn).with(/you have passed symbols \(\[:foo, :bar\]\) as additional\s+arguments for a doc string/i) + warning_receiver.should_receive(:warn).with(/In RSpec 3, these symbols will be treated as metadata keys/) metadata_hash(:foo, :bar, :key => 'value') end From 3de3b32a4fdaf66893a8a242b6fe234e410d38ae Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 05:57:06 -0800 Subject: [PATCH 049/151] Allow symbols to be treated as metadata for the inclusion filter. --- features/filtering/inclusion_filters.feature | 23 ++++++++++++++++++++ lib/rspec/core/configuration.rb | 10 ++++++++- spec/rspec/core/configuration_spec.rb | 7 ++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/features/filtering/inclusion_filters.feature b/features/filtering/inclusion_filters.feature index fec3a1f769..ff8caf27a4 100644 --- a/features/filtering/inclusion_filters.feature +++ b/features/filtering/inclusion_filters.feature @@ -4,6 +4,9 @@ Feature: inclusion filters most common use case is to focus on a subset of examples as you're focused on a particular problem. + If you set the `treat_symbols_as_metadata_keys_with_true_values` config option + to `true`, you can specify metadata using only symbols. + Background: Given a file named "spec/spec_helper.rb" with: """ @@ -81,3 +84,23 @@ Feature: inclusion filters And the output should contain "after all in focused group" And the output should not contain "before all in unfocused group" And the output should not contain "after all in unfocused group" + + Scenario: Use symbols as metadata + Given a file named "symbols_as_metadata_spec.rb" with: + """ + RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true + c.filter_run :current_example + end + + describe "something" do + it "does one thing" do + end + + it "does another thing", :current_example do + end + end + """ + When I run "rspec symbols_as_metadata_spec.rb --format doc" + Then the output should contain "does another thing" + And the output should not contain "does one thing" diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 7158222732..8a141ade86 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -334,7 +334,15 @@ def alias_it_should_behave_like_to(new_name, report_label = '') RSpec::Core::ExampleGroup.alias_it_should_behave_like_to(new_name, report_label) end - def filter_run_including(options={}, force_overwrite = false) + def filter_run_including(*args) + force_overwrite = if args.last.is_a?(Hash) || args.last.is_a?(Symbol) + false + else + args.pop + end + + options = build_metadata_hash_from(args) + if filter and filter[:line_number] || filter[:full_description] warn "Filtering by #{options.inspect} is not possible since " \ "you are already filtering by #{filter.inspect}" diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 9bd5452797..3412bdc125 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -464,6 +464,13 @@ def that_thing end describe "#filter_run" do + it_behaves_like "metadata hash builder" do + def metadata_hash(*args) + config.filter_run *args + config.filter + end + end + it "sets the filter" do config.filter_run :focus => true config.filter[:focus].should == true From 5e0ac37a798ed03cbf7866cf33e07fad285f1f42 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 07:56:52 -0800 Subject: [PATCH 050/151] Allow symbols to be treated as metadata for the exclusion filter. --- features/filtering/exclusion_filters.feature | 24 ++++++++++++++++++++ lib/rspec/core/configuration.rb | 7 +++--- spec/rspec/core/configuration_spec.rb | 7 ++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/features/filtering/exclusion_filters.feature b/features/filtering/exclusion_filters.feature index 392cdbdfa5..ab13559622 100644 --- a/features/filtering/exclusion_filters.feature +++ b/features/filtering/exclusion_filters.feature @@ -2,6 +2,9 @@ Feature: exclusion filters You can exclude examples from a run by declaring an exclusion filter and then tagging examples, or entire groups, with that filter. + + If you set the `treat_symbols_as_metadata_keys_with_true_values` config option + to `true`, you can specify metadata using only symbols. Scenario: exclude an example Given a file named "spec/sample_spec.rb" with: @@ -113,3 +116,24 @@ Feature: exclusion filters And the output should contain "after all in included group" And the output should not contain "before all in excluded group" And the output should not contain "after all in excluded group" + + Scenario: Use symbols as metadata + Given a file named "symbols_as_metadata_spec.rb" with: + """ + RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true + c.filter_run_excluding :broken + end + + describe "something" do + it "does one thing" do + end + + # tag example for exclusion by adding metadata + it "does another thing", :broken do + end + end + """ + When I run "rspec symbols_as_metadata_spec.rb --format doc" + Then the output should contain "does one thing" + And the output should not contain "does another thing" diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 8a141ade86..4c4629f7fa 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -48,10 +48,10 @@ def initialize /lib\/rspec\/(core|expectations|matchers|mocks)/ ] - filter_run_excluding( + self.exclusion_filter = { :if => lambda { |value, metadata| metadata.has_key?(:if) && !value }, :unless => lambda { |value| value } - ) + } end # :call-seq: @@ -357,7 +357,8 @@ def filter_run_including(*args) alias_method :filter_run, :filter_run_including - def filter_run_excluding(options={}) + def filter_run_excluding(*args) + options = build_metadata_hash_from(args) self.exclusion_filter = (exclusion_filter || {}).merge(options) end diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 3412bdc125..7cfcbe195e 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -504,6 +504,13 @@ def metadata_hash(*args) end describe "#filter_run_excluding" do + it_behaves_like "metadata hash builder" do + def metadata_hash(*args) + config.filter_run_excluding *args + config.exclusion_filter + end + end + it "sets the filter" do config.filter_run_excluding :slow => true config.exclusion_filter[:slow].should == true From c38394d44c2ce21949f54bb5a250544ec7568922 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Mon, 7 Mar 2011 23:21:19 -0800 Subject: [PATCH 051/151] Allow symbols to be treated as metadata for config.include/config.extend. --- features/helper_methods/modules.feature | 35 +++++++++++++++++++++++++ lib/rspec/core/configuration.rb | 6 +++-- spec/rspec/core/configuration_spec.rb | 14 ++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/features/helper_methods/modules.feature b/features/helper_methods/modules.feature index 4db9af95f9..a06a5cee0d 100644 --- a/features/helper_methods/modules.feature +++ b/features/helper_methods/modules.feature @@ -10,6 +10,9 @@ Feature: Define helper methods in a module groups by passing a metadata hash as the last argument. Only groups that match the given metadata will include or extend the module. + If you set the `treat_symbols_as_metadata_keys_with_true_values` config option + to `true`, you can specify metadata using only symbols. + Background: Given a file named "helpers.rb" with: """ @@ -112,3 +115,35 @@ Feature: Define helper methods in a module Then the examples should all pass And the output should contain "In a matching group, help is available" And the output should contain "In a non-matching group, help is not available" + + Scenario: use symbols as metadata + Given a file named "symbols_as_metadata_spec.rb" with: + """ + require './helpers' + + RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true + c.include Helpers, :include_helpers + c.extend Helpers, :extend_helpers + end + + describe "an example group with matching include metadata", :include_helpers do + puts "In a group not matching the extend filter, help is #{help rescue 'not available'}" + + it "has access the helper methods defined in the module" do + help.should be(:available) + end + end + + describe "an example group with matching extend metadata", :extend_helpers do + puts "In a group matching the extend filter, help is #{help}" + + it "does not have access to the helper methods defined in the module" do + expect { help }.to raise_error(NameError) + end + end + """ + When I run "rspec symbols_as_metadata_spec.rb" + Then the examples should all pass + And the output should contain "In a group not matching the extend filter, help is not available" + And the output should contain "In a group matching the extend filter, help is available" diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 4c4629f7fa..e469a9e731 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -362,11 +362,13 @@ def filter_run_excluding(*args) self.exclusion_filter = (exclusion_filter || {}).merge(options) end - def include(mod, filters={}) + def include(mod, *args) + filters = build_metadata_hash_from(args) include_or_extend_modules << [:include, mod, filters] end - def extend(mod, filters={}) + def extend(mod, *args) + filters = build_metadata_hash_from(args) include_or_extend_modules << [:extend, mod, filters] end diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 7cfcbe195e..7c1d85e8de 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -248,6 +248,13 @@ def you_call_this_a_blt? end end + it_behaves_like "metadata hash builder" do + def metadata_hash(*args) + config.include(InstanceLevelMethods, *args) + config.include_or_extend_modules.last.last + end + end + context "with no filter" do it "includes the given module into each example group" do RSpec.configure do |c| @@ -281,6 +288,13 @@ def that_thing end end + it_behaves_like "metadata hash builder" do + def metadata_hash(*args) + config.extend(ThatThingISentYou, *args) + config.include_or_extend_modules.last.last + end + end + it "extends the given module into each matching example group" do RSpec.configure do |c| c.extend(ThatThingISentYou, :magic_key => :extend) From 75dd47f4455d4d8a4e414ff4f86450b281e328d8 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 22:10:44 -0800 Subject: [PATCH 052/151] Add new feature to nav. --- features/.nav | 1 + 1 file changed, 1 insertion(+) diff --git a/features/.nav b/features/.nav index 7a34ed2cb3..ed0e3a3101 100644 --- a/features/.nav +++ b/features/.nav @@ -18,6 +18,7 @@ - helper_methods: - let.feature - arbitrary_methods.feature + - modules.feature - metadata: - described_class.feature - user_defined.feature From 750fe1424a867e4be86335b3c8fe517b7e6a581a Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 22:11:14 -0800 Subject: [PATCH 053/151] Add cuke documenting `config.alias_example_to`. --- features/.nav | 1 + .../configuration/alias_example_to.feature | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 features/configuration/alias_example_to.feature diff --git a/features/.nav b/features/.nav index ed0e3a3101..ddcecca790 100644 --- a/features/.nav +++ b/features/.nav @@ -41,6 +41,7 @@ - fail_fast.feature - custom_settings.feature - for_groups_matching.feature + - alias_example_to.feature - expectation_framework_integration: - configure_expectation_framework.feature - mock_framework_integration: diff --git a/features/configuration/alias_example_to.feature b/features/configuration/alias_example_to.feature new file mode 100644 index 0000000000..a7fcd897f4 --- /dev/null +++ b/features/configuration/alias_example_to.feature @@ -0,0 +1,24 @@ +Feature: alias_example_to + + Use `config.alias_example_to` to create new example group methods + that define examples with the configured metadata. + + Scenario: Use alias_example_to to define focused example + Given a file named "alias_example_to_spec.rb" with: + """ + RSpec.configure do |c| + c.alias_example_to :fit, :focused => true + c.filter_run :focused => true + end + + describe "an example group" do + it "does one thing" do + end + + fit "does another thing" do + end + end + """ + When I run "rspec alias_example_to_spec.rb --format doc" + Then the output should contain "does another thing" + And the output should not contain "does one thing" From 253b2724fe379a6f48b9a04cb38c4454a41bcd34 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 22:25:47 -0800 Subject: [PATCH 054/151] Allow symbols to be treated as metadata for `config.alias_example_to`. --- .../configuration/alias_example_to.feature | 24 +++++++++++++++++++ lib/rspec/core/configuration.rb | 3 ++- spec/rspec/core/configuration_spec.rb | 11 +++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/features/configuration/alias_example_to.feature b/features/configuration/alias_example_to.feature index a7fcd897f4..dcd54e6e52 100644 --- a/features/configuration/alias_example_to.feature +++ b/features/configuration/alias_example_to.feature @@ -3,6 +3,9 @@ Feature: alias_example_to Use `config.alias_example_to` to create new example group methods that define examples with the configured metadata. + If you set the `treat_symbols_as_metadata_keys_with_true_values` config option + to `true`, you can specify metadata using only symbols. + Scenario: Use alias_example_to to define focused example Given a file named "alias_example_to_spec.rb" with: """ @@ -22,3 +25,24 @@ Feature: alias_example_to When I run "rspec alias_example_to_spec.rb --format doc" Then the output should contain "does another thing" And the output should not contain "does one thing" + + Scenario: use symbols as metadata + Given a file named "use_symbols_as_metadata_spec.rb" with: + """ + RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true + c.alias_example_to :fit, :focused + c.filter_run :focused + end + + describe "an example group" do + it "does one thing" do + end + + fit "does another thing" do + end + end + """ + When I run "rspec use_symbols_as_metadata_spec.rb --format doc" + Then the output should contain "does another thing" + And the output should not contain "does one thing" diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index e469a9e731..18f0bf6048 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -305,7 +305,8 @@ def files_or_directories_to_run=(*files) # E.g. alias_example_to :crazy_slow, :speed => 'crazy_slow' defines # crazy_slow as an example variant that has the crazy_slow speed option - def alias_example_to(new_name, extra_options={}) + def alias_example_to(new_name, *args) + extra_options = build_metadata_hash_from(args) RSpec::Core::ExampleGroup.alias_example_to(new_name, extra_options) end diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 7c1d85e8de..e3457f4130 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -784,6 +784,17 @@ def self.included(host) end end + describe "#alias_example_to" do + it_behaves_like "metadata hash builder" do + def metadata_hash(*args) + config.alias_example_to :my_example, *args + group = ExampleGroup.describe("group") + example = group.my_example("description") + example.metadata + end + end + end + describe "#for_groups_matching" do let(:matching_group) { ExampleGroup.describe(Array, :extended => true) } let(:non_matching_group) { ExampleGroup.describe(Array) } From 6fe8316f226736b644a9644d018b23300ff4f325 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 22:36:03 -0800 Subject: [PATCH 055/151] Clarify warning. --- lib/rspec/core/metadata_hash_builder.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/rspec/core/metadata_hash_builder.rb b/lib/rspec/core/metadata_hash_builder.rb index bedf1b8835..8a58d7400a 100644 --- a/lib/rspec/core/metadata_hash_builder.rb +++ b/lib/rspec/core/metadata_hash_builder.rb @@ -48,6 +48,9 @@ def symbol_metadata_warning(symbols) RSpec.configure do |c| c.treat_symbols_as_metadata_keys_with_true_values = true end + +Note that this config setting should go before your other config +settings so that they can use symbols as metadata. ***************************************************************** NOTICE From 1dea59366a9f71b15c578dbfd50d56eac7ae3a87 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 22:40:08 -0800 Subject: [PATCH 056/151] Reword cuke narative. --- features/configuration/for_groups_matching.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/configuration/for_groups_matching.feature b/features/configuration/for_groups_matching.feature index 8d9c41939a..0a31c75272 100644 --- a/features/configuration/for_groups_matching.feature +++ b/features/configuration/for_groups_matching.feature @@ -1,6 +1,7 @@ Feature: for groups matching - Define block evaluated in the context of any example group matching filters given. + Use `for_groups_matching` to define a block that will be evaluated + in the context of any example groups that have matching metadata. Scenario: define method for groups matching metadata Given a file named "for_groups_matching_spec.rb" with: From 9cee5e286a768be34c7bceda48d2d806e7b445bc Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Tue, 8 Mar 2011 22:53:03 -0800 Subject: [PATCH 057/151] Allow symbols to be treated as metadata for `config.for_groups_matching`. --- .../configuration/for_groups_matching.feature | 28 +++++++++++++++++++ lib/rspec/core/configuration.rb | 4 +-- spec/rspec/core/configuration_spec.rb | 9 ++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/features/configuration/for_groups_matching.feature b/features/configuration/for_groups_matching.feature index 0a31c75272..9dc3a45a9f 100644 --- a/features/configuration/for_groups_matching.feature +++ b/features/configuration/for_groups_matching.feature @@ -3,6 +3,9 @@ Feature: for groups matching Use `for_groups_matching` to define a block that will be evaluated in the context of any example groups that have matching metadata. + If you set the `treat_symbols_as_metadata_keys_with_true_values` config option + to `true`, you can specify metadata using only symbols. + Scenario: define method for groups matching metadata Given a file named "for_groups_matching_spec.rb" with: """ @@ -58,3 +61,28 @@ Feature: for groups matching """ When I run "rspec for_groups_matching_spec.rb" Then the examples should all pass + + Scenario: Use symbols as metadata + Given a file named "use_symbols_as_metadata_spec.rb" with: + """ + RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true + c.for_groups_matching :special do + let(:help) { :available } + end + end + + describe "something", :special do + it "accesses helper methods defined using `let` in the configuration" do + help.should be(:available) + end + end + + describe "something else" do + it "cannot access helper methods defined using `let` in the configuration" do + expect { help }.to raise_error(NameError) + end + end + """ + When I run "rspec use_symbols_as_metadata_spec.rb" + Then the examples should all pass diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 18f0bf6048..c34ad57112 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -394,12 +394,12 @@ def configure_group(group) # let(:valid_attributes) { Factory.attributes_for described_class.to_sym } # end # end - def for_groups_matching(filters = {}, &block) + def for_groups_matching(*args, &block) mod = Module.new (class << mod; self; end).send(:define_method, :extended) do |host| host.class_eval(&block) end - self.extend(mod, filters) + self.extend(mod, *args) end def configure_mock_framework diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index e3457f4130..136f906c91 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -795,6 +795,15 @@ def metadata_hash(*args) end end + describe "#for_groups_matching" do + it_behaves_like "metadata hash builder" do + def metadata_hash(*args) + config.for_groups_matching(*args) { } + config.include_or_extend_modules.last.last + end + end + end + describe "#for_groups_matching" do let(:matching_group) { ExampleGroup.describe(Array, :extended => true) } let(:non_matching_group) { ExampleGroup.describe(Array) } From d8cb6287deff16b0d31b3ea29bf3c246f1fe3866 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Wed, 9 Mar 2011 18:49:03 -0800 Subject: [PATCH 058/151] Force users to explicitly specify hook scope when using symbols as metadata for hooks. --- lib/rspec/core/hooks.rb | 2 ++ spec/rspec/core/hooks_spec.rb | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/rspec/core/hooks.rb b/lib/rspec/core/hooks.rb index 0014443190..5348dcdcb1 100644 --- a/lib/rspec/core/hooks.rb +++ b/lib/rspec/core/hooks.rb @@ -145,6 +145,8 @@ def find_hook(hook, scope, example_group_class, example = nil) def scope_and_options_from(*args) scope = if [:each, :all, :suite].include?(args.first) args.shift + elsif args.any? { |a| a.is_a?(Symbol) } + raise ArgumentError.new("You must explicitly give a scope (:each, :all, or :suite) when using symbols as metadata for a hook.") else :each end diff --git a/spec/rspec/core/hooks_spec.rb b/spec/rspec/core/hooks_spec.rb index 7910110a70..ff59502f81 100644 --- a/spec/rspec/core/hooks_spec.rb +++ b/spec/rspec/core/hooks_spec.rb @@ -7,10 +7,10 @@ class HooksHost end [:before, :after, :around].each do |type| - [nil, :each, :all].each do |scope| + [:each, :all].each do |scope| next if type == :around && scope == :all - describe "##{type}(#{scope ? scope.inspect : 'default scope' })" do + describe "##{type}(#{scope})" do it_behaves_like "metadata hash builder" do define_method :metadata_hash do |*args| instance = HooksHost.new @@ -21,6 +21,35 @@ class HooksHost end end end + + [true, false].each do |config_value| + context "when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to #{config_value}" do + before(:each) do + Kernel.stub(:warn) + RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = config_value } + end + + describe "##{type}(no scope)" do + let(:instance) { HooksHost.new } + + it "defaults to :each scope if no arguments are given" do + hooks = instance.send(type) { } + hook = hooks.first + instance.hooks[type][:each].should include(hook) + end + + it "defaults to :each scope if the only argument is a metadata hash" do + hooks = instance.send(type, :foo => :bar) { } + hook = hooks.first + instance.hooks[type][:each].should include(hook) + end + + it "raises an error if only metadata symbols are given as arguments" do + expect { instance.send(type, :foo, :bar) { } }.to raise_error(ArgumentError) + end + end + end + end end [:before, :after].each do |type| From 0dea1af1a370ded5461f807628d6c184fe3c54b2 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 13 Mar 2011 09:17:03 -0500 Subject: [PATCH 059/151] docs --- .../example_groups/basic_structure.feature | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/features/example_groups/basic_structure.feature b/features/example_groups/basic_structure.feature index 58c4d3cc8f..fccf01360a 100644 --- a/features/example_groups/basic_structure.feature +++ b/features/example_groups/basic_structure.feature @@ -4,21 +4,17 @@ Feature: basic structure (describe/it) behave, organized in groups. It uses the words "describe" and "it" so we can express concepts like a conversation: - "Describe an account when it is first opened." - "It has a balance of zero." + "Describe an account when it is first opened." + "It has a balance of zero." - The describe() method creates a subclass of RSpec::Core::ExampleGroup. The - block passed to describe() is evaluated in the context of that class, so any - class methods of ExampleGroup are at your disposal within that block. - - Within a group, you can declare nested groups using the describe() or - context() methods. A nested group is actually a subclass of the outer group, - so it has access to same methods as the outer group, as well as any class - methods defined in the outer group. - - The it() method accepts a block, which is later executed in the context of - an instance of the group in which it is declared. + The `describe` method creates an example group. Within the block passed to + `describe` you can declare nested groups using the `describe` or `context` + methods, or you can declare examples using the `it` or `specify` methods. + Under the hood, an example group is a class in which the block passed to + `describe` or `context` is evaluated. The blocks passed to `it` are evaluated + in the context of an _instance_ of that class. + Scenario: one group, one example Given a file named "sample_spec.rb" with: """ From 00d842be8ef6902dfb1bc44a6227a5a9230f28a9 Mon Sep 17 00:00:00 2001 From: Ilkka Laukkanen Date: Wed, 9 Mar 2011 10:17:44 +0200 Subject: [PATCH 060/151] Pass exit status of DRb run to invoking process This change causes rspec to exit with a non-zero exit status when specs fail, even when running with DRb. Failover to local run is done by not catching DRb::DRbConnError exceptions in RSpec::Core::DRbCommandLine, instead letting them come up to Runner.run. --- lib/rspec/core/drb_command_line.rb | 16 +++++----------- lib/rspec/core/runner.rb | 7 ++++++- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/rspec/core/drb_command_line.rb b/lib/rspec/core/drb_command_line.rb index 9e35b9307a..9dd2ca2890 100644 --- a/lib/rspec/core/drb_command_line.rb +++ b/lib/rspec/core/drb_command_line.rb @@ -11,18 +11,12 @@ def drb_port def run(err, out) begin - begin - DRb.start_service("druby://localhost:0") - rescue SocketError, Errno::EADDRNOTAVAIL - DRb.start_service("druby://:0") - end - spec_server = DRbObject.new_with_uri("druby://127.0.0.1:#{drb_port}") - spec_server.run(@options.drb_argv, err, out) - true - rescue DRb::DRbConnError - err.puts "No DRb server is running. Running in local process instead ..." - false + DRb.start_service("druby://localhost:0") + rescue SocketError, Errno::EADDRNOTAVAIL + DRb.start_service("druby://:0") end + spec_server = DRbObject.new_with_uri("druby://127.0.0.1:#{drb_port}") + spec_server.run(@options.drb_argv, err, out) end end end diff --git a/lib/rspec/core/runner.rb b/lib/rspec/core/runner.rb index 860d2d6727..5168283168 100644 --- a/lib/rspec/core/runner.rb +++ b/lib/rspec/core/runner.rb @@ -42,7 +42,12 @@ def self.run(args, err, out) options.parse_options if options.options[:drb] - run_over_drb(options, err, out) || run_in_process(options, err, out) + begin + run_over_drb(options, err, out) + rescue DRb::DRbConnError + err.puts "No DRb server is running. Running in local process instead ..." + run_in_process(options, err, out) + end else run_in_process(options, err, out) end From 38d43c3d3b34ae765a544fb4b5291580db29ed8c Mon Sep 17 00:00:00 2001 From: Ilkka Laukkanen Date: Sat, 12 Mar 2011 13:43:45 +0200 Subject: [PATCH 061/151] Fix specs to reflect new DRb behaviour expectations DRbCommandLine.run no longer outputs a connection error message, instead it lets raised DRbConnError exceptions pass through. Also it returns false for the dummy spec because of the raise() therein. --- spec/rspec/core/drb_command_line_spec.rb | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/spec/rspec/core/drb_command_line_spec.rb b/spec/rspec/core/drb_command_line_spec.rb index d856cf1f4f..921a767984 100644 --- a/spec/rspec/core/drb_command_line_spec.rb +++ b/spec/rspec/core/drb_command_line_spec.rb @@ -20,16 +20,8 @@ def run_with(args) end context "without server running" do - it "prints error" do - run_with [] - - err.rewind - err.read.should =~ /No DRb server is running/ - end - - it "returns false" do - result = run_with [] - result.should be_false + it "raises an error" do + lambda { run_with [] }.should raise_error(DRb::DRbConnError) end end @@ -136,7 +128,7 @@ def create_dummy_spec_file it "integrates via Runner.new.run" do err, out = StringIO.new, StringIO.new result = RSpec::Core::Runner.run(%W[ --drb --drb-port #{@drb_port} #{dummy_spec_filename}], err, out) - result.should be_true + result.should be_false end def run_spec_via_druby From e322223738725a1cf447d2408ced86f837102791 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Sun, 13 Mar 2011 15:17:46 -0700 Subject: [PATCH 062/151] More detailed spec for running your specs with DRb. --- spec/rspec/core/runner_spec.rb | 45 ++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/spec/rspec/core/runner_spec.rb b/spec/rspec/core/runner_spec.rb index 4092de1161..21e3f599f5 100644 --- a/spec/rspec/core/runner_spec.rb +++ b/spec/rspec/core/runner_spec.rb @@ -22,24 +22,49 @@ module RSpec::Core describe "#run" do context "with --drb or -X" do - before(:each) do - @err = @out = StringIO.new + let(:err) { StringIO.new } + let(:out) { StringIO.new } + before(:each) do @options = RSpec::Core::ConfigurationOptions.new(%w[--drb --drb-port 8181 --color]) RSpec::Core::ConfigurationOptions.stub(:new) { @options } + end - @drb_proxy = double(RSpec::Core::DRbCommandLine, :run => true) - RSpec::Core::DRbCommandLine.stub(:new => @drb_proxy) + def run_specs + RSpec::Core::Runner.run(%w[ --drb ], err, out) end - it "builds a DRbCommandLine" do - RSpec::Core::DRbCommandLine.should_receive(:new) - RSpec::Core::Runner.run(%w[ --drb ], @err, @out) + context 'and a DRb server is running' do + it "builds a DRbCommandLine and runs the specs" do + drb_proxy = double(RSpec::Core::DRbCommandLine, :run => true) + drb_proxy.should_receive(:run).with(err, out) + + RSpec::Core::DRbCommandLine.should_receive(:new).and_return(drb_proxy) + + run_specs + end end - it "runs specs over the proxy" do - @drb_proxy.should_receive(:run).with(@err, @out) - RSpec::Core::Runner.run(%w[ --drb ], @err, @out) + context 'and a DRb server is not running' do + before(:each) do + RSpec::Core::DRbCommandLine.should_receive(:new).and_raise(DRb::DRbConnError) + end + + it "outputs a message" do + err.should_receive(:puts).with( + "No DRb server is running. Running in local process instead ..." + ) + run_specs + end + + it "builds a CommandLine and runs the specs" do + process_proxy = double(RSpec::Core::CommandLine, :run => true) + process_proxy.should_receive(:run).with(err, out) + + RSpec::Core::CommandLine.should_receive(:new).and_return(process_proxy) + + run_specs + end end end end From d31338466b608278c94b358bb607461d406c6675 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sun, 13 Mar 2011 21:48:11 -0700 Subject: [PATCH 063/151] Fix indentation. --- spec/rspec/core/metadata_spec.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/rspec/core/metadata_spec.rb b/spec/rspec/core/metadata_spec.rb index 984b8ff7d0..8274217b0b 100644 --- a/spec/rspec/core/metadata_spec.rb +++ b/spec/rspec/core/metadata_spec.rb @@ -240,13 +240,13 @@ module Core %w[# . ::].each do |char| context "with a nested description starting with #{char}" do - it "removes the space" do - parent = Metadata.new - parent.process("Object") - child = Metadata.new(parent) - child.process("#{char}method") - child[:example_group][:full_description].should eq("Object#{char}method") - end + it "removes the space" do + parent = Metadata.new + parent.process("Object") + child = Metadata.new(parent) + child.process("#{char}method") + child[:example_group][:full_description].should eq("Object#{char}method") + end end end end From 548dda492937d26f81810adfec63116b8750c5c0 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Tue, 15 Mar 2011 09:29:47 -0700 Subject: [PATCH 064/151] changelog --- features/Changelog.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index e56ee76939..e798bec563 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -14,6 +14,8 @@ * Print a deprecation warning when you configure RSpec after defining an example. All configuration should happen before any examples are defined. (Myron Marston) + * Pass the exit status of a DRb run to the invoking process. This causes + specs run via DRb to not just return true or false. (Ilkka Laukkanen) * Bug fixes * don't stumble over an exception without a message (Hans Hasselberg) @@ -95,7 +97,7 @@ If you don't want 'bundle exec', there is nothing you have to do. * Bug fixes * send debugger warning message to $stdout if RSpec.configuration.error_stream - has not been defined yet. + has not been defined yet. * HTML Formatter _finally_ properly displays nested groups (Jarmo Pertman) * eliminate some warnings when running RSpec's own suite (Jarmo Pertman) @@ -123,7 +125,7 @@ If you don't want 'bundle exec', there is nothing you have to do. * Bug fixes * alias_method instead of override Kernel#method_missing (John Wilger) - * changed --autotest to --tty in generated command (MIKAMI Yoshiyuki) + * changed --autotest to --tty in generated command (MIKAMI Yoshiyuki) * revert change to debugger (had introduced conflict with Rails) * also restored --debugger/-debug option From 1758f81020238ba585c894acda3d1d1178e6bf06 Mon Sep 17 00:00:00 2001 From: Andy Lindeman Date: Mon, 14 Mar 2011 10:37:26 -0500 Subject: [PATCH 065/151] Since fda4a122, ostruct is no longer used. Remove the require. Closes #336 --- lib/rspec/core/subject.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/rspec/core/subject.rb b/lib/rspec/core/subject.rb index 055a81b6ba..cbda7974f3 100644 --- a/lib/rspec/core/subject.rb +++ b/lib/rspec/core/subject.rb @@ -1,5 +1,3 @@ -require 'ostruct' - module RSpec module Core module Subject From 40758a1435e31216e4d500591d6b6570d4c5298e Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 21 Mar 2011 20:21:45 -0500 Subject: [PATCH 066/151] Don't call example_group_[started|finished] unless the group or any of its children have at least one example to run. - Closes #317. --- features/Changelog.md | 1 + lib/rspec/core/reporter.rb | 4 ++-- spec/rspec/core/reporter_spec.rb | 22 +++++++++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index e798bec563..3bf0760998 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -26,6 +26,7 @@ * Include RSpec::Matchers when first example group is defined, rather than just before running the examples. This works around an obscure bug in ruby 1.9 that can cause infinite recursion. (Myron Marston) + * Don't send example_group_[started|finished] to formatters for empty groups. ### 2.5.1 / 2011-02-06 diff --git a/lib/rspec/core/reporter.rb b/lib/rspec/core/reporter.rb index 0433a27ccf..79c0493c34 100644 --- a/lib/rspec/core/reporter.rb +++ b/lib/rspec/core/reporter.rb @@ -39,11 +39,11 @@ def message(message) end def example_group_started(group) - notify :example_group_started, group + notify :example_group_started, group unless group.descendant_filtered_examples.empty? end def example_group_finished(group) - notify :example_group_finished, group + notify :example_group_finished, group unless group.descendant_filtered_examples.empty? end def example_started(example) diff --git a/spec/rspec/core/reporter_spec.rb b/spec/rspec/core/reporter_spec.rb index a47c989fbe..2705aa8e6f 100644 --- a/spec/rspec/core/reporter_spec.rb +++ b/spec/rspec/core/reporter_spec.rb @@ -30,13 +30,17 @@ module RSpec::Core it "passes example_group_started and example_group_finished messages to that formatter in that order" do order = [] - formatter = stub("formatter") + formatter = stub("formatter").as_null_object formatter.stub(:example_group_started) { |group| order << "Started: #{group.description}" } formatter.stub(:example_group_finished) { |group| order << "Finished: #{group.description}" } group = ExampleGroup.describe("root") - group.describe("context 1") - group.describe("context 2") + group.describe("context 1") do + example("ignore") {} + end + group.describe("context 2") do + example("ignore") {} + end group.run(Reporter.new(formatter)) @@ -51,6 +55,18 @@ module RSpec::Core end end + context "given an example group with no examples" do + it "does not pass example_group_started or example_group_finished to formatter" do + formatter = stub("formatter").as_null_object + formatter.should_not_receive(:example_group_started) + formatter.should_not_receive(:example_group_finished) + + group = ExampleGroup.describe("root") + + group.run(Reporter.new(formatter)) + end + end + context "given multiple formatters" do it "passes messages to all formatters" do formatters = [double("formatter"), double("formatter")] From d0e5fa2caf39aabdb6d6461c76078db66b4a65d8 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 21 Mar 2011 20:47:34 -0500 Subject: [PATCH 067/151] fix cuke i broke last commit :( --- features/hooks/before_and_after_hooks.feature | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/hooks/before_and_after_hooks.feature b/features/hooks/before_and_after_hooks.feature index 3ddd5e7545..c28e8ef490 100644 --- a/features/hooks/before_and_after_hooks.feature +++ b/features/hooks/before_and_after_hooks.feature @@ -145,9 +145,6 @@ Feature: before and after hooks """ an error in before(:all) fails this example, too (FAILED - 1) - nested group - yet another level deep - after all ran """ Scenario: failure in after(:all) block From 3260cb5b0d434d46895dbfa44865d0f3936520c7 Mon Sep 17 00:00:00 2001 From: Sidu Ponnappa Date: Wed, 23 Mar 2011 01:08:00 +0530 Subject: [PATCH 068/151] Fix `:ruby => "!jruby"` metadata logic. Fixes #338 Fixes #339 --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 739374eda1..a1485b6629 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -78,7 +78,7 @@ def allowing_configure_warning c.filter_run_excluding :ruby => lambda {|version| case version.to_s when "!jruby" - RUBY_ENGINE != "jruby" + RUBY_ENGINE == "jruby" when /^> (.*)/ !(RUBY_VERSION.to_s > $1) else From a1064cf279251a02f888f7f0469e95e38e26a162 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 21 Mar 2011 21:08:24 -0500 Subject: [PATCH 069/151] remove comment in feature --- features/hooks/before_and_after_hooks.feature | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/features/hooks/before_and_after_hooks.feature b/features/hooks/before_and_after_hooks.feature index c28e8ef490..d47e360d6b 100644 --- a/features/hooks/before_and_after_hooks.feature +++ b/features/hooks/before_and_after_hooks.feature @@ -52,7 +52,7 @@ Feature: before and after hooks end end """ - When I run "rspec ./before_each_spec.rb" + When I run "rspec before_each_spec.rb" Then the examples should all pass Scenario: define before(:all) block in example group @@ -86,10 +86,10 @@ Feature: before and after hooks end end """ - When I run "rspec ./before_all_spec.rb" + When I run "rspec before_all_spec.rb" Then the examples should all pass - When I run "rspec ./before_all_spec.rb:15" + When I run "rspec before_all_spec.rb:15" Then the examples should all pass Scenario: failure in before(:all) block @@ -124,7 +124,7 @@ Feature: before and after hooks end end """ - When I run "rspec ./before_all_spec.rb --format documentation" + When I run "rspec before_all_spec.rb --format documentation" Then the output should contain "5 examples, 5 failures" And the output should contain: """ @@ -139,7 +139,7 @@ Feature: before and after hooks after all ran """ - When I run "rspec ./before_all_spec.rb:9 --format documentation" + When I run "rspec before_all_spec.rb:9 --format documentation" Then the output should contain "1 example, 1 failure" And the output should contain: """ @@ -197,7 +197,7 @@ Feature: before and after hooks end end """ - When I run "rspec ./befores_in_configuration_spec.rb" + When I run "rspec befores_in_configuration_spec.rb" Then the examples should all pass Scenario: before/after blocks are run in order @@ -227,7 +227,7 @@ Feature: before and after hooks end end """ - When I run "rspec ./ensure_block_order_spec.rb" + When I run "rspec ensure_block_order_spec.rb" Then the output should contain: """ before all @@ -313,7 +313,7 @@ Feature: before and after hooks end """ - When I run "rspec ./before_and_after_all_spec.rb" + When I run "rspec before_and_after_all_spec.rb" Then the examples should all pass And the output should contain: """ @@ -323,7 +323,7 @@ Feature: before and after hooks outer after all """ - When I run "rspec ./before_and_after_all_spec.rb:14" + When I run "rspec before_and_after_all_spec.rb:14" Then the examples should all pass And the output should contain: """ @@ -333,7 +333,7 @@ Feature: before and after hooks outer after all """ - When I run "rspec ./before_and_after_all_spec.rb:6" + When I run "rspec before_and_after_all_spec.rb:6" Then the examples should all pass And the output should contain: """ @@ -399,12 +399,11 @@ Feature: before and after hooks end after(:all) do - # p @outer_state.nil? @outer_state.should eq("set in outer before all") end end """ - When I run "rspec ./before_and_after_all_spec.rb" + When I run "rspec before_and_after_all_spec.rb" Then the examples should all pass Scenario: exception in before(:each) is captured and reported as failure @@ -419,6 +418,6 @@ Feature: before and after hooks end end """ - When I run "rspec ./error_in_before_each_spec.rb" + When I run "rspec error_in_before_each_spec.rb" Then the output should contain "1 example, 1 failure" And the output should contain "this error" From bd3aac8af610905a46d1a6b7fc8e67146b761175 Mon Sep 17 00:00:00 2001 From: Sidu Ponnappa Date: Wed, 23 Mar 2011 22:27:32 -0500 Subject: [PATCH 070/151] Get build to pass on jruby. - Closes #341. --- Gemfile | 2 +- .../core/formatters/base_formatter_spec.rb | 1 + .../formatters/html_formatted-1.8.7-jruby.html | 18 ++++++++---------- .../text_mate_formatted-1.8.7-jruby.html | 18 ++++++++---------- spec/rspec/core/resources/formatter_specs.rb | 8 +++++++- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Gemfile b/Gemfile index 8c847a9cae..8f899411ee 100644 --- a/Gemfile +++ b/Gemfile @@ -26,7 +26,7 @@ if RUBY_PLATFORM =~ /darwin/ gem "autotest-growl", "~> 0.2.9" end -gem "ruby-debug", :platforms => :mri_18 +gem "ruby-debug", :platforms => [:mri_18, :jruby] gem "ruby-debug19", "~> 0.11.6", :platforms => :mri_19 case RUBY_VERSION diff --git a/spec/rspec/core/formatters/base_formatter_spec.rb b/spec/rspec/core/formatters/base_formatter_spec.rb index 7cfb85b982..ae67fce60f 100644 --- a/spec/rspec/core/formatters/base_formatter_spec.rb +++ b/spec/rspec/core/formatters/base_formatter_spec.rb @@ -46,6 +46,7 @@ end it "doesn't hang when file exists" do + pending("This issue still exists on JRuby, but should be resolved shortly: https://github.com/rspec/rspec-core/issues/295", :if => RUBY_ENGINE == 'jruby') exception = mock(:Exception, :backtrace => [ "#{__FILE__}:#{__LINE__}"]) example = mock(:Example, :file_path => __FILE__) diff --git a/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html b/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html index c5787dc8a3..cae22540f0 100644 --- a/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +++ b/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html @@ -318,13 +318,12 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46:in `open' ./spec/rspec/core/formatters/html_formatter_spec.rb:46 ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' -./spec/rspec/core/formatters/html_formatter_spec.rb:45 -:1 -
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+./spec/rspec/core/formatters/html_formatter_spec.rb:45 +
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
@@ -357,8 +356,7 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46:in `open' ./spec/rspec/core/formatters/html_formatter_spec.rb:46 ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' -./spec/rspec/core/formatters/html_formatter_spec.rb:45 -:1 +./spec/rspec/core/formatters/html_formatter_spec.rb:45
27        end
 28
 29        raise(RSpec::Expectations::ExpectationNotMetError.new(message))
@@ -385,7 +383,7 @@ 

RSpec Code Examples

fails with a backtrace containing an erb file
-
#<Class:01xf45673>
+
Exception
/foo.html.erb:1:in `
': foo (RuntimeError)
-1# Couldn't get snippet for /foo.html.erb
diff --git a/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html b/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html index fe042f57d2..a3cb2a4752 100644 --- a/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +++ b/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html @@ -318,13 +318,12 @@

RSpec Code Examples

./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 :in `open' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `chdir' -./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 -:1
-
22          rescue Exception => e
-23          end
-24          raise RSpec::Core::PendingExampleFixedError.new if result
-25        end
-26        throw :pending_declared_in_example, message
+./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 +
24          rescue Exception
+25          end
+26          raise RSpec::Core::PendingExampleFixedError.new if result
+27        end
+28        raise PendingDeclaredInExample.new(message)
@@ -357,8 +356,7 @@

RSpec Code Examples

./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 :in `open' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `chdir' -./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 -:1 +./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46
27        end
 28
 29        raise(RSpec::Expectations::ExpectationNotMetError.new(message))
@@ -385,7 +383,7 @@ 

RSpec Code Examples

fails with a backtrace containing an erb file
-
#<Class:01x1150b68>
+
Exception
/foo.html.erb:1 :in `
': foo (RuntimeError)
-1# Couldn't get snippet for /foo.html.erb
diff --git a/spec/rspec/core/resources/formatter_specs.rb b/spec/rspec/core/resources/formatter_specs.rb index f4902d7d54..3c129a877b 100644 --- a/spec/rspec/core/resources/formatter_specs.rb +++ b/spec/rspec/core/resources/formatter_specs.rb @@ -48,7 +48,13 @@ def e.backtrace ["/foo.html.erb:1:in `
': foo (RuntimeError)", " from /lib/ruby/1.9.1/erb.rb:753:in `eval'"] end - + + def e.message + # Redefining message steps around this behaviour + # on JRuby: http://jira.codehaus.org/browse/JRUBY-5637 + self.class.name + end + raise e end end From 36b0a1fe5cd39159a85a75ddb19319cec000c201 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 23 Mar 2011 22:56:53 -0500 Subject: [PATCH 071/151] Don't run rr spec in jruby (failure coming from rr itself). - Closes #3. --- cucumber.yml | 2 +- features/mock_framework_integration/use_flexmock.feature | 1 - features/mock_framework_integration/use_mocha.feature | 1 - features/mock_framework_integration/use_rr.feature | 4 ++-- features/mock_framework_integration/use_rspec.feature | 1 - 5 files changed, 3 insertions(+), 6 deletions(-) diff --git a/cucumber.yml b/cucumber.yml index 8ec0d62434..2e4ae778d9 100644 --- a/cucumber.yml +++ b/cucumber.yml @@ -1,2 +1,2 @@ -default: --require features --strict --format progress --tags ~@wip features +default: --require features --strict --format progress --tags ~@wip<%= RUBY_PLATFORM === 'jruby' ? ' --tags ~@no-jruby' : '' %> features wip: --require features --tags @wip:3 --wip features diff --git a/features/mock_framework_integration/use_flexmock.feature b/features/mock_framework_integration/use_flexmock.feature index 2bf257e2c8..f3eb6ca1c6 100644 --- a/features/mock_framework_integration/use_flexmock.feature +++ b/features/mock_framework_integration/use_flexmock.feature @@ -20,4 +20,3 @@ Feature: mock with flexmock """ When I run "rspec ./flexmock_example_spec.rb" Then the examples should all pass - And the exit status should be 0 diff --git a/features/mock_framework_integration/use_mocha.feature b/features/mock_framework_integration/use_mocha.feature index b929d18481..e3159908e8 100644 --- a/features/mock_framework_integration/use_mocha.feature +++ b/features/mock_framework_integration/use_mocha.feature @@ -20,4 +20,3 @@ Feature: mock with mocha """ When I run "rspec ./mocha_example_spec.rb" Then the examples should all pass - And the exit status should be 0 diff --git a/features/mock_framework_integration/use_rr.feature b/features/mock_framework_integration/use_rr.feature index 16646899ae..48f225b340 100644 --- a/features/mock_framework_integration/use_rr.feature +++ b/features/mock_framework_integration/use_rr.feature @@ -1,3 +1,4 @@ +@no-jruby Feature: mock with rr As an RSpec user who likes to mock @@ -18,6 +19,5 @@ Feature: mock with rr end end """ - When I run "rspec ./rr_example_spec.rb" + When I run "rspec rr_example_spec.rb" Then the examples should all pass - And the exit status should be 0 diff --git a/features/mock_framework_integration/use_rspec.feature b/features/mock_framework_integration/use_rspec.feature index 40f2ad9a7e..491eb875d2 100644 --- a/features/mock_framework_integration/use_rspec.feature +++ b/features/mock_framework_integration/use_rspec.feature @@ -20,4 +20,3 @@ Feature: mock with rspec """ When I run "rspec ./rspec_example_spec.rb" Then the examples should all pass - And the exit status should be 0 From 8fd03d29eafe210efeae40670f52256bb106e6d5 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 23 Mar 2011 23:03:37 -0500 Subject: [PATCH 072/151] same as last time, only this time it actually works --- cucumber.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cucumber.yml b/cucumber.yml index 2e4ae778d9..86ee7a2f8d 100644 --- a/cucumber.yml +++ b/cucumber.yml @@ -1,2 +1,2 @@ -default: --require features --strict --format progress --tags ~@wip<%= RUBY_PLATFORM === 'jruby' ? ' --tags ~@no-jruby' : '' %> features +default: --require features --strict --format progress --tags ~@wip<%= RUBY_PLATFORM == 'java' ? ' --tags ~@no-jruby' : '' %> features wip: --require features --tags @wip:3 --wip features From a368a1ab2b0bfce1cc0ad3bde446038f96207e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Ma=C5=82ecki?= Date: Wed, 23 Mar 2011 20:01:55 +0100 Subject: [PATCH 073/151] Fix bug where mixing nested groups and outer-level examples gave unpredictable :line_number behavior - Closes #337. - Closes #340. --- lib/rspec/core/world.rb | 2 +- spec/rspec/core/world_spec.rb | 53 +++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/lib/rspec/core/world.rb b/lib/rspec/core/world.rb index 9e31300e4e..78910aab83 100644 --- a/lib/rspec/core/world.rb +++ b/lib/rspec/core/world.rb @@ -54,7 +54,7 @@ def apply_exclusion_filters(examples, conditions={}) end def preceding_declaration_line(filter_line) - declaration_line_numbers.inject(nil) do |highest_prior_declaration_line, line| + declaration_line_numbers.sort.inject(nil) do |highest_prior_declaration_line, line| line <= filter_line ? line : highest_prior_declaration_line end end diff --git a/spec/rspec/core/world_spec.rb b/spec/rspec/core/world_spec.rb index 81d9fde96f..9ccad9823b 100644 --- a/spec/rspec/core/world_spec.rb +++ b/spec/rspec/core/world_spec.rb @@ -138,7 +138,15 @@ module RSpec::Core let(:group) do RSpec::Core::ExampleGroup.describe("group") do - example("example") {} + example("example") {} + + end + end + + let(:second_group) do + RSpec::Core::ExampleGroup.describe("second_group") do + + example("second_example") {} end end @@ -146,26 +154,41 @@ module RSpec::Core let(:group_declaration_line) { group.metadata[:example_group][:line_number] } let(:example_declaration_line) { group_declaration_line + 2 } - before { world.register(group) } + context "with one example" do + before { world.register(group) } - it "returns nil if no example or group precedes the line" do - world.preceding_declaration_line(group_declaration_line - 1).should be_nil - end + it "returns nil if no example or group precedes the line" do + world.preceding_declaration_line(group_declaration_line - 1).should be_nil + end - it "returns the argument line number if a group starts on that line" do - world.preceding_declaration_line(group_declaration_line).should eq(group_declaration_line) - end + it "returns the argument line number if a group starts on that line" do + world.preceding_declaration_line(group_declaration_line).should eq(group_declaration_line) + end - it "returns the argument line number if an example starts on that line" do - world.preceding_declaration_line(example_declaration_line).should eq(example_declaration_line) - end + it "returns the argument line number if an example starts on that line" do + world.preceding_declaration_line(example_declaration_line).should eq(example_declaration_line) + end - it "returns line number of a group that immediately precedes the argument line" do - world.preceding_declaration_line(group_declaration_line + 1).should eq(group_declaration_line) + it "returns line number of a group that immediately precedes the argument line" do + world.preceding_declaration_line(group_declaration_line + 1).should eq(group_declaration_line) + end + + it "returns line number of an example that immediately precedes the argument line" do + world.preceding_declaration_line(example_declaration_line + 1).should eq(example_declaration_line) + end end - it "returns line number of an example that immediately precedes the argument line" do - world.preceding_declaration_line(example_declaration_line + 1).should eq(example_declaration_line) + context "with two exaples and the second example is registre first" do + let(:second_group_declaration_line) { second_group.metadata[:example_group][:line_number] } + + before do + world.register(second_group) + world.register(group) + end + + it 'return line number of group if a group start on that line' do + world.preceding_declaration_line(second_group_declaration_line).should eq(second_group_declaration_line) + end end end From a9ed36a587ae158c019ec62adfff608f9fc5f057 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 23 Mar 2011 23:14:48 -0500 Subject: [PATCH 074/151] changelog --- features/Changelog.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index 3bf0760998..64d753e0f0 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -18,15 +18,18 @@ specs run via DRb to not just return true or false. (Ilkka Laukkanen) * Bug fixes - * don't stumble over an exception without a message (Hans Hasselberg) - * remove non-ascii characters from comments that were choking rcov (Geoffrey + * Don't stumble over an exception without a message (Hans Hasselberg) + * Remove non-ascii characters from comments that were choking rcov (Geoffrey Byers) - * fixed backtrace so it doesn't include lines from before the autorun at_exit + * Fixed backtrace so it doesn't include lines from before the autorun at_exit hook (Myron Marston) * Include RSpec::Matchers when first example group is defined, rather than just before running the examples. This works around an obscure bug in ruby 1.9 that can cause infinite recursion. (Myron Marston) * Don't send example_group_[started|finished] to formatters for empty groups. + * Get specs passing on jruby (Sidu Ponnappa) + * Fix bug where mixing nested groups and outer-level examples gave + unpredictable :line_number behavior (Artur Małecki) ### 2.5.1 / 2011-02-06 From b00736221aeecd3b3a44888517ff0037a63a6b65 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 23 Mar 2011 23:33:43 -0500 Subject: [PATCH 075/151] add cuke for accessing example from within the example --- features/metadata/current_example.feature | 17 +++++++++++++++++ features/metadata/described_class.feature | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 features/metadata/current_example.feature diff --git a/features/metadata/current_example.feature b/features/metadata/current_example.feature new file mode 100644 index 0000000000..63a3f48cf2 --- /dev/null +++ b/features/metadata/current_example.feature @@ -0,0 +1,17 @@ +Feature: current example + + You can reference the example object, and access its metadata, using + the `example` method within an example. + + Scenario: access the example object from within an example + Given a file named "spec/example_spec.rb" with: + """ + describe "an example" do + it "knows itself as example" do + example.description.should eq("knows itself as example") + end + end + """ + When I run "rspec spec/example_spec.rb" + Then the example should pass + diff --git a/features/metadata/described_class.feature b/features/metadata/described_class.feature index a3d1232dd2..a59b3ac98d 100644 --- a/features/metadata/described_class.feature +++ b/features/metadata/described_class.feature @@ -12,6 +12,6 @@ Feature: described class end end """ - When I run "rspec ./spec/example_spec.rb" - Then the examples should all pass + When I run "rspec spec/example_spec.rb" + Then the example should pass From 4ee93699c6aec1ea470b39c246ac4d531513d6df Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 23 Mar 2011 23:35:59 -0500 Subject: [PATCH 076/151] rename feature and tweak nav --- features/.nav | 3 ++- .../{implicit_filters.feature => if_and_unless.feature} | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) rename features/filtering/{implicit_filters.feature => if_and_unless.feature} (99%) diff --git a/features/.nav b/features/.nav index ddcecca790..54c47dd555 100644 --- a/features/.nav +++ b/features/.nav @@ -20,12 +20,13 @@ - arbitrary_methods.feature - modules.feature - metadata: + - current_example.feature - described_class.feature - user_defined.feature - filtering: - inclusion_filters.feature - exclusion_filters.feature - - implicit_filters.feature + - if_and_unless.feature - run_all_when_everything_filtered.feature - command_line: - configure.feature diff --git a/features/filtering/implicit_filters.feature b/features/filtering/if_and_unless.feature similarity index 99% rename from features/filtering/implicit_filters.feature rename to features/filtering/if_and_unless.feature index 657c8abe12..17ecc11179 100644 --- a/features/filtering/implicit_filters.feature +++ b/features/filtering/if_and_unless.feature @@ -1,4 +1,4 @@ -Feature: implicit filters +Feature: :if and :unless The `:if` and `:unless` metadata keys can be used to filter examples without needing to configure an exclusion filter. From 8f7461465a1424943fd21bde2dc2afb8ddf03853 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 24 Mar 2011 21:31:14 -0500 Subject: [PATCH 077/151] upgrade cucumber and aruba --- Gemfile | 4 +-- features/command_line/configure.feature | 4 +-- .../command_line/example_name_option.feature | 20 ++++++------- features/command_line/exit_status.feature | 8 ++--- features/command_line/format_option.feature | 8 ++--- .../line_number_appended_to_path.feature | 22 +++++++------- .../command_line/line_number_option.feature | 4 +-- features/command_line/rake_task.feature | 6 ++-- features/command_line/tag.feature | 18 +++++------ .../configuration/alias_example_to.feature | 4 +-- .../configuration/custom_settings.feature | 6 ++-- features/configuration/fail_fast.feature | 6 ++-- .../configuration/for_groups_matching.feature | 8 ++--- .../read_options_from_file.feature | 8 ++--- .../example_groups/basic_structure.feature | 4 +-- .../shared_example_group.feature | 8 ++--- .../configure_expectation_framework.feature | 6 ++-- features/filtering/exclusion_filters.feature | 10 +++---- features/filtering/if_and_unless.feature | 10 +++---- features/filtering/inclusion_filters.feature | 8 ++--- .../run_all_when_everything_filtered.feature | 2 +- features/formatters/custom_formatter.feature | 2 +- features/formatters/text_formatter.feature | 2 +- .../helper_methods/arbitrary_methods.feature | 4 +-- features/helper_methods/let.feature | 4 +-- features/helper_methods/modules.feature | 10 +++---- features/hooks/around_hooks.feature | 22 +++++++------- features/hooks/before_and_after_hooks.feature | 30 +++++++++---------- features/hooks/filtering.feature | 12 ++++---- features/metadata/current_example.feature | 2 +- features/metadata/described_class.feature | 2 +- features/metadata/user_defined.feature | 8 ++--- .../use_any_framework.feature | 2 +- .../use_flexmock.feature | 2 +- .../use_mocha.feature | 2 +- .../mock_framework_integration/use_rr.feature | 2 +- .../use_rspec.feature | 2 +- features/pending/pending_examples.feature | 16 +++++----- .../spec_files/arbitrary_file_suffix.feature | 2 +- .../step_definitions/additional_cli_steps.rb | 6 ++-- features/subject/attribute_of_subject.feature | 10 +++---- features/subject/explicit_subject.feature | 10 +++---- features/subject/implicit_receiver.feature | 4 +-- features/subject/implicit_subject.feature | 4 +-- features/support/env.rb | 7 ++++- 45 files changed, 173 insertions(+), 168 deletions(-) diff --git a/Gemfile b/Gemfile index 8f899411ee..b0365646c1 100644 --- a/Gemfile +++ b/Gemfile @@ -12,8 +12,8 @@ end ### dev dependencies gem "rake", "0.8.7" -gem "cucumber", "0.9.4" -gem "aruba", "0.2.2" +gem "cucumber", "~> 0.10.2" +gem "aruba", "~> 0.3.5" gem "rcov", "0.9.9", :platforms => :mri gem "relish", "0.2.0" gem "guard-rspec", "0.1.9" diff --git a/features/command_line/configure.feature b/features/command_line/configure.feature index 8dc5afe54f..3ab4df3a8f 100644 --- a/features/command_line/configure.feature +++ b/features/command_line/configure.feature @@ -8,7 +8,7 @@ Feature: --configure option to load RSpec's Autotest subclass. Scenario: generate .rspec file for autotest - When I run "rspec --configure autotest" + When I run `rspec --configure autotest` Then the following files should exist: | .rspec | And the output should contain ".rspec file did not exist, so it was created." @@ -18,5 +18,5 @@ Feature: --configure option """ --color """ - When I run "rspec --configure autotest" + When I run `rspec --configure autotest` Then the output should contain ".rspec file already exists, so nothing was changed." diff --git a/features/command_line/example_name_option.feature b/features/command_line/example_name_option.feature index 0b05ad106a..2e2e98092a 100644 --- a/features/command_line/example_name_option.feature +++ b/features/command_line/example_name_option.feature @@ -46,41 +46,41 @@ Feature: --example option """ Scenario: no matches - When I run "rspec . --example nothing_like_this" + When I run `rspec . --example nothing_like_this` Then the examples should all pass Scenario: match on one word - When I run "rspec . --example example" + When I run `rspec . --example example` Then the examples should all pass Scenario: one match in each context - When I run "rspec . --example 'first example'" + When I run `rspec . --example 'first example'` Then the examples should all pass Scenario: one match in one file using just the example name - When I run "rspec . --example 'first example in first group'" + When I run `rspec . --example 'first example in first group'` Then the examples should all pass Scenario: one match in one file using the example name and the group name - When I run "rspec . --example 'first group first example in first group'" + When I run `rspec . --example 'first group first example in first group'` Then the examples should all pass Scenario: one match in one file using regexp - When I run "rspec . --example 'first .* first example'" + When I run `rspec . --example 'first .* first example'` Then the examples should all pass Scenario: all examples in one group - When I run "rspec . --example 'first group'" + When I run `rspec . --example 'first group'` Then the examples should all pass Scenario: one match in one file with group name - When I run "rspec . --example 'second group first example'" + When I run `rspec . --example 'second group first example'` Then the examples should all pass Scenario: all examples in one group including examples in nested groups - When I run "rspec . --example 'third group'" + When I run `rspec . --example 'third group'` Then the examples should all pass Scenario: Object#method - When I run "rspec . --example 'Array#length'" + When I run `rspec . --example 'Array#length'` Then the examples should all pass diff --git a/features/command_line/exit_status.feature b/features/command_line/exit_status.feature index a82036501a..53650f67e8 100644 --- a/features/command_line/exit_status.feature +++ b/features/command_line/exit_status.feature @@ -11,7 +11,7 @@ Feature: exit status end end """ - When I run "rspec ok_spec.rb" + When I run `rspec ok_spec.rb` Then the exit status should be 0 And the examples should all pass @@ -24,7 +24,7 @@ Feature: exit status end end """ - When I run "rspec ko_spec.rb" + When I run `rspec ko_spec.rb` Then the exit status should be 1 And the output should contain "1 example, 1 failure" @@ -39,7 +39,7 @@ Feature: exit status end end """ - When I run "rspec nested_ko_spec.rb" + When I run `rspec nested_ko_spec.rb` Then the exit status should be 1 And the output should contain "1 example, 1 failure" @@ -47,6 +47,6 @@ Feature: exit status Given a file named "a_no_examples_spec.rb" with: """ """ - When I run "rspec a_no_examples_spec.rb" + When I run `rspec a_no_examples_spec.rb` Then the exit status should be 0 And the output should contain "0 examples" diff --git a/features/command_line/format_option.feature b/features/command_line/format_option.feature index df47fbcd18..d2092657ae 100644 --- a/features/command_line/format_option.feature +++ b/features/command_line/format_option.feature @@ -38,11 +38,11 @@ Feature: --format option """ Scenario: progress bar format (default) - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain ".F*" Scenario: documentation format - When I run "rspec example_spec.rb --format documentation" + When I run `rspec example_spec.rb --format documentation` Then the output should contain: """ something @@ -52,7 +52,7 @@ Feature: --format option """ Scenario: documentation format saved to a file - When I run "rspec example_spec.rb --format documentation --out rspec.txt" + When I run `rspec example_spec.rb --format documentation --out rspec.txt` Then the file "rspec.txt" should contain: """ something @@ -62,7 +62,7 @@ Feature: --format option """ Scenario: multiple formats - When I run "rspec example_spec.rb --format progress --format documentation --out rspec.txt" + When I run `rspec example_spec.rb --format progress --format documentation --out rspec.txt` Then the output should contain ".F*" And the file "rspec.txt" should contain: """ diff --git a/features/command_line/line_number_appended_to_path.feature b/features/command_line/line_number_appended_to_path.feature index 5dbbafe566..7b0afff231 100644 --- a/features/command_line/line_number_appended_to_path.feature +++ b/features/command_line/line_number_appended_to_path.feature @@ -29,77 +29,77 @@ Feature: line number appended to file path """ Scenario: nested groups - outer group on declaration line - When I run "rspec example_spec.rb:1 --format doc" + When I run `rspec example_spec.rb:1 --format doc` Then the examples should all pass And the output should contain "second example in outer group" And the output should contain "first example in outer group" And the output should contain "example in nested group" Scenario: nested groups - outer group inside block before example - When I run "rspec example_spec.rb:2 --format doc" + When I run `rspec example_spec.rb:2 --format doc` Then the examples should all pass And the output should contain "second example in outer group" And the output should contain "first example in outer group" And the output should contain "example in nested group" Scenario: nested groups - inner group on declaration line - When I run "rspec example_spec.rb:11 --format doc" + When I run `rspec example_spec.rb:11 --format doc` Then the examples should all pass And the output should contain "example in nested group" And the output should not contain "second example in outer group" And the output should not contain "first example in outer group" Scenario: nested groups - inner group inside block before example - When I run "rspec example_spec.rb:12 --format doc" + When I run `rspec example_spec.rb:12 --format doc` Then the examples should all pass And the output should contain "example in nested group" And the output should not contain "second example in outer group" And the output should not contain "first example in outer group" Scenario: two examples - first example on declaration line - When I run "rspec example_spec.rb:3 --format doc" + When I run `rspec example_spec.rb:3 --format doc` Then the examples should all pass And the output should contain "first example in outer group" But the output should not contain "second example in outer group" And the output should not contain "example in nested group" Scenario: two examples - first example inside block - When I run "rspec example_spec.rb:4 --format doc" + When I run `rspec example_spec.rb:4 --format doc` Then the examples should all pass And the output should contain "first example in outer group" But the output should not contain "second example in outer group" And the output should not contain "example in nested group" Scenario: two examples - first example on end - When I run "rspec example_spec.rb:5 --format doc" + When I run `rspec example_spec.rb:5 --format doc` Then the examples should all pass And the output should contain "first example in outer group" But the output should not contain "second example in outer group" And the output should not contain "example in nested group" Scenario: two examples - first example after end but before next example - When I run "rspec example_spec.rb:6 --format doc" + When I run `rspec example_spec.rb:6 --format doc` Then the examples should all pass And the output should contain "first example in outer group" But the output should not contain "second example in outer group" And the output should not contain "example in nested group" Scenario: two examples - second example on declaration line - When I run "rspec example_spec.rb:7 --format doc" + When I run `rspec example_spec.rb:7 --format doc` Then the examples should all pass And the output should contain "second example in outer group" But the output should not contain "first example in outer group" And the output should not contain "example in nested group" Scenario: two examples - second example inside block - When I run "rspec example_spec.rb:7 --format doc" + When I run `rspec example_spec.rb:7 --format doc` Then the examples should all pass And the output should contain "second example in outer group" But the output should not contain "first example in outer group" And the output should not contain "example in nested group" Scenario: two examples - second example on end - When I run "rspec example_spec.rb:7 --format doc" + When I run `rspec example_spec.rb:7 --format doc` Then the examples should all pass And the output should contain "second example in outer group" But the output should not contain "first example in outer group" diff --git a/features/command_line/line_number_option.feature b/features/command_line/line_number_option.feature index 4bd9a13957..faf541634d 100644 --- a/features/command_line/line_number_option.feature +++ b/features/command_line/line_number_option.feature @@ -21,7 +21,7 @@ Feature: --line_number option end """ - When I run "rspec example_spec.rb --line_number 5 --format doc" + When I run `rspec example_spec.rb --line_number 5 --format doc` Then the examples should all pass Then the output should contain "should be > 8" But the output should not contain "should be < 10" @@ -39,7 +39,7 @@ Feature: --line_number option end """ - When I run "rspec example_spec.rb --line_number 5 --format doc" + When I run `rspec example_spec.rb --line_number 5 --format doc` Then the examples should all pass Then the output should contain "should be > 8" But the output should not contain "should be < 10" diff --git a/features/command_line/rake_task.feature b/features/command_line/rake_task.feature index 4ba315f4fe..b7ae824c53 100644 --- a/features/command_line/rake_task.feature +++ b/features/command_line/rake_task.feature @@ -19,7 +19,7 @@ Feature: rake task end end """ - When I run "rake" + When I run `rake` Then the stderr should contain "ruby -S rspec" Then the exit status should be 0 @@ -40,7 +40,7 @@ Feature: rake task end end """ - When I run "rake" + When I run `rake` Then the exit status should be 1 Scenario: fail_on_error = false with failing spec (exit status is 0) @@ -62,7 +62,7 @@ Feature: rake task end end """ - When I run "rake" + When I run `rake` Then the exit status should be 0 diff --git a/features/command_line/tag.feature b/features/command_line/tag.feature index 1e8e29d4f0..aaa05467e0 100644 --- a/features/command_line/tag.feature +++ b/features/command_line/tag.feature @@ -27,21 +27,21 @@ Feature: --tag option """ Scenario: filter examples with non-existent tag - When I run "rspec . --tag mytag" + When I run `rspec . --tag mytag` And the examples should all pass Scenario: filter examples with a simple tag - When I run "rspec . --tag focus" + When I run `rspec . --tag focus` Then the output should contain "Run filtered using {:focus=>true}" And the examples should all pass Scenario: filter examples with a simple tag and @ - When I run "rspec . --tag @focus" + When I run `rspec . --tag @focus` Then the output should contain "Run filtered using {:focus=>true}" Then the examples should all pass Scenario: filter examples with a name:value tag - When I run "rspec . --tag type:special" + When I run `rspec . --tag type:special` Then the output should contain: """ Run filtered using {:type=>"special"} @@ -49,7 +49,7 @@ Feature: --tag option And the examples should all pass Scenario: filter examples with a name:value tag and @ - When I run "rspec . --tag @type:special" + When I run `rspec . --tag @type:special` Then the output should contain: """ Run filtered using {:type=>"special"} @@ -57,18 +57,18 @@ Feature: --tag option And the examples should all pass Scenario: exclude examples with a simple tag - When I run "rspec . --tag ~skip" + When I run `rspec . --tag ~skip` Then the examples should all pass Scenario: exclude examples with a simple tag and @ - When I run "rspec . --tag ~@skip" + When I run `rspec . --tag ~@skip` Then the examples should all pass Scenario: exclude examples with a name:value tag - When I run "rspec . --tag ~speed:slow" + When I run `rspec . --tag ~speed:slow` Then the examples should all pass Scenario: exclude examples with a name:value tag and @ - When I run "rspec . --tag ~@speed:slow" + When I run `rspec . --tag ~@speed:slow` Then the examples should all pass diff --git a/features/configuration/alias_example_to.feature b/features/configuration/alias_example_to.feature index dcd54e6e52..5fe274f07d 100644 --- a/features/configuration/alias_example_to.feature +++ b/features/configuration/alias_example_to.feature @@ -22,7 +22,7 @@ Feature: alias_example_to end end """ - When I run "rspec alias_example_to_spec.rb --format doc" + When I run `rspec alias_example_to_spec.rb --format doc` Then the output should contain "does another thing" And the output should not contain "does one thing" @@ -43,6 +43,6 @@ Feature: alias_example_to end end """ - When I run "rspec use_symbols_as_metadata_spec.rb --format doc" + When I run `rspec use_symbols_as_metadata_spec.rb --format doc` Then the output should contain "does another thing" And the output should not contain "does one thing" diff --git a/features/configuration/custom_settings.feature b/features/configuration/custom_settings.feature index 95bcb9858e..d3ad97812b 100644 --- a/features/configuration/custom_settings.feature +++ b/features/configuration/custom_settings.feature @@ -29,7 +29,7 @@ Feature: custom settings end end """ - When I run "rspec ./additional_setting_spec.rb" + When I run `rspec ./additional_setting_spec.rb` Then the examples should all pass Scenario: default to true @@ -55,7 +55,7 @@ Feature: custom settings end end """ - When I run "rspec ./additional_setting_spec.rb" + When I run `rspec ./additional_setting_spec.rb` Then the examples should all pass Scenario: overridden in a subsequent RSpec.configure block @@ -79,6 +79,6 @@ Feature: custom settings end end """ - When I run "rspec ./additional_setting_spec.rb" + When I run `rspec ./additional_setting_spec.rb` Then the examples should all pass diff --git a/features/configuration/fail_fast.feature b/features/configuration/fail_fast.feature index 2b16020215..a0deff28a1 100644 --- a/features/configuration/fail_fast.feature +++ b/features/configuration/fail_fast.feature @@ -21,7 +21,7 @@ Feature: fail fast end end """ - When I run "rspec spec/example_spec.rb" + When I run `rspec spec/example_spec.rb` Then the examples should all pass Scenario: fail_fast with first example failing (only runs the one example) @@ -37,7 +37,7 @@ Feature: fail fast end end """ - When I run "rspec spec/example_spec.rb -fd" + When I run `rspec spec/example_spec.rb -fd` Then the output should contain "1 example, 1 failure" Scenario: fail_fast with multiple files, second example failing (only runs the first two examples) @@ -73,5 +73,5 @@ Feature: fail fast end end """ - When I run "rspec spec" + When I run `rspec spec` Then the output should contain "2 examples, 1 failure" diff --git a/features/configuration/for_groups_matching.feature b/features/configuration/for_groups_matching.feature index 9dc3a45a9f..0eecb12a42 100644 --- a/features/configuration/for_groups_matching.feature +++ b/features/configuration/for_groups_matching.feature @@ -23,7 +23,7 @@ Feature: for groups matching end end """ - When I run "rspec for_groups_matching_spec.rb" + When I run `rspec for_groups_matching_spec.rb` Then the examples should all pass Scenario: define method using let for groups matching metadata @@ -41,7 +41,7 @@ Feature: for groups matching end end """ - When I run "rspec for_groups_matching_spec.rb" + When I run `rspec for_groups_matching_spec.rb` Then the examples should all pass Scenario: define subject for groups matching metadata @@ -59,7 +59,7 @@ Feature: for groups matching end end """ - When I run "rspec for_groups_matching_spec.rb" + When I run `rspec for_groups_matching_spec.rb` Then the examples should all pass Scenario: Use symbols as metadata @@ -84,5 +84,5 @@ Feature: for groups matching end end """ - When I run "rspec use_symbols_as_metadata_spec.rb" + When I run `rspec use_symbols_as_metadata_spec.rb` Then the examples should all pass diff --git a/features/configuration/read_options_from_file.feature b/features/configuration/read_options_from_file.feature index f38aaba85b..08211e239b 100644 --- a/features/configuration/read_options_from_file.feature +++ b/features/configuration/read_options_from_file.feature @@ -30,7 +30,7 @@ Feature: read command line configuration options from files end end """ - When I run "rspec ./spec/example_spec.rb" + When I run `rspec ./spec/example_spec.rb` Then the examples should all pass Scenario: custom options file @@ -47,7 +47,7 @@ Feature: read command line configuration options from files end end """ - When I run "rspec spec/example_spec.rb --options my.options" + When I run `rspec spec/example_spec.rb --options my.options` Then the examples should all pass Scenario: RSpec ignores ./.rspec when custom options file is used @@ -67,7 +67,7 @@ Feature: read command line configuration options from files end end """ - When I run "rspec spec/example_spec.rb --options my.options" + When I run `rspec spec/example_spec.rb --options my.options` Then the examples should all pass Scenario: using ERB in .rspec @@ -83,5 +83,5 @@ Feature: read command line configuration options from files end end """ - When I run "rspec ./spec/example_spec.rb" + When I run `rspec ./spec/example_spec.rb` Then the examples should all pass diff --git a/features/example_groups/basic_structure.feature b/features/example_groups/basic_structure.feature index fccf01360a..3d3ca65d46 100644 --- a/features/example_groups/basic_structure.feature +++ b/features/example_groups/basic_structure.feature @@ -23,7 +23,7 @@ Feature: basic structure (describe/it) end end """ - When I run "rspec sample_spec.rb -fn" + When I run `rspec sample_spec.rb -fn` Then the output should contain: """ something @@ -44,7 +44,7 @@ Feature: basic structure (describe/it) end end """ - When I run "rspec nested_example_groups_spec.rb -fdoc" + When I run `rspec nested_example_groups_spec.rb -fdoc` Then the output should contain: """ something diff --git a/features/example_groups/shared_example_group.feature b/features/example_groups/shared_example_group.feature index e111184ac3..303bfbacc6 100644 --- a/features/example_groups/shared_example_group.feature +++ b/features/example_groups/shared_example_group.feature @@ -45,7 +45,7 @@ Feature: shared example group it_behaves_like "a collection" end """ - When I run "rspec collection_spec.rb --format documentation" + When I run `rspec collection_spec.rb --format documentation` Then the examples should all pass And the output should contain: """ @@ -97,7 +97,7 @@ Feature: shared example group end end """ - When I run "rspec shared_example_group_spec.rb --format documentation" + When I run `rspec shared_example_group_spec.rb --format documentation` Then the examples should all pass And the output should contain: """ @@ -133,7 +133,7 @@ Feature: shared example group it_should_behave_like "a measurable object", 6, [:size, :length] end """ - When I run "rspec shared_example_group_params_spec.rb --format documentation" + When I run `rspec shared_example_group_params_spec.rb --format documentation` Then the examples should all pass And the output should contain: """ @@ -167,7 +167,7 @@ Feature: shared example group end end """ - When I run "rspec shared_example_group_spec.rb --format documentation" + When I run `rspec shared_example_group_spec.rb --format documentation` Then the examples should all pass And the output should contain: """ diff --git a/features/expectation_framework_integration/configure_expectation_framework.feature b/features/expectation_framework_integration/configure_expectation_framework.feature index 682ac80eed..225c9ecb5e 100644 --- a/features/expectation_framework_integration/configure_expectation_framework.feature +++ b/features/expectation_framework_integration/configure_expectation_framework.feature @@ -26,7 +26,7 @@ Feature: configure expectation framework end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the examples should all pass Scenario: configure test/unit assertions @@ -44,7 +44,7 @@ Feature: configure expectation framework specify { assert 5 < 6 } end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain "2 examples, 1 failure" And the output should contain: """ @@ -69,5 +69,5 @@ Feature: configure expectation framework end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the examples should all pass diff --git a/features/filtering/exclusion_filters.feature b/features/filtering/exclusion_filters.feature index ab13559622..72687a44be 100644 --- a/features/filtering/exclusion_filters.feature +++ b/features/filtering/exclusion_filters.feature @@ -23,7 +23,7 @@ Feature: exclusion filters end end """ - When I run "rspec ./spec/sample_spec.rb --format doc" + When I run `rspec ./spec/sample_spec.rb --format doc` Then the output should contain "does one thing" And the output should not contain "does another thing" @@ -47,7 +47,7 @@ Feature: exclusion filters end end """ - When I run "rspec ./spec/sample_spec.rb --format doc" + When I run `rspec ./spec/sample_spec.rb --format doc` Then the output should contain "group 2 example 1" And the output should not contain "group 1 example 1" And the output should not contain "group 1 example 2" @@ -80,7 +80,7 @@ Feature: exclusion filters end end """ - When I run "rspec ./spec/sample_spec.rb --format doc" + When I run `rspec ./spec/sample_spec.rb --format doc` Then the output should match /No examples were matched. Perhaps \{.*:broken=>true.*\} is excluding everything?/ And the examples should all pass And the output should not contain "group 1" @@ -111,7 +111,7 @@ Feature: exclusion filters end end """ - When I run "rspec ./spec/before_after_all_exclusion_filter_spec.rb" + When I run `rspec ./spec/before_after_all_exclusion_filter_spec.rb` Then the output should contain "before all in included group" And the output should contain "after all in included group" And the output should not contain "before all in excluded group" @@ -134,6 +134,6 @@ Feature: exclusion filters end end """ - When I run "rspec symbols_as_metadata_spec.rb --format doc" + When I run `rspec symbols_as_metadata_spec.rb --format doc` Then the output should contain "does one thing" And the output should not contain "does another thing" diff --git a/features/filtering/if_and_unless.feature b/features/filtering/if_and_unless.feature index 17ecc11179..4ee772da84 100644 --- a/features/filtering/if_and_unless.feature +++ b/features/filtering/if_and_unless.feature @@ -24,7 +24,7 @@ Feature: :if and :unless it("no :if group no :if example") { } end """ - When I run "rspec implicit_if_filter_spec.rb --format doc" + When I run `rspec implicit_if_filter_spec.rb --format doc` Then the output should contain all of these: | :if => true group :if => true example | | :if => true group no :if example | @@ -58,7 +58,7 @@ Feature: :if and :unless it("no :unless group no :unless example") { } end """ - When I run "rspec implicit_unless_filter_spec.rb --format doc" + When I run `rspec implicit_unless_filter_spec.rb --format doc` Then the output should contain all of these: | :unless => true group :unless => false example | | :unless => false group :unless => false example | @@ -94,7 +94,7 @@ Feature: :if and :unless it("unfocused :unless => false example", :unless => false) { } end """ - When I run "rspec explicit_inclusion_filter_spec.rb --format doc" + When I run `rspec explicit_inclusion_filter_spec.rb --format doc` Then the output should contain all of these: | focused example | | focused :if => true example | @@ -127,7 +127,7 @@ Feature: :if and :unless it("excluded :unless => false example", :unless => false) { } end """ - When I run "rspec explicit_exclusion_filter_spec.rb --format doc" + When I run `rspec explicit_exclusion_filter_spec.rb --format doc` Then the output should contain all of these: | included example | | included :if => true example | @@ -156,7 +156,7 @@ Feature: :if and :unless it(":unless => :exclude_me_for_unless example", :unless => :exclude_me_for_unless) { } end """ - When I run "rspec override_implicit_filters_spec.rb --format doc" + When I run `rspec override_implicit_filters_spec.rb --format doc` Then the output should contain all of these: | :if => true example | | :if => false example | diff --git a/features/filtering/inclusion_filters.feature b/features/filtering/inclusion_filters.feature index ff8caf27a4..28dc45794f 100644 --- a/features/filtering/inclusion_filters.feature +++ b/features/filtering/inclusion_filters.feature @@ -29,7 +29,7 @@ Feature: inclusion filters end end """ - When I run "rspec spec/sample_spec.rb --format doc" + When I run `rspec spec/sample_spec.rb --format doc` Then the output should contain "does another thing" And the output should not contain "does one thing" @@ -51,7 +51,7 @@ Feature: inclusion filters end end """ - When I run "rspec spec/sample_spec.rb --format doc" + When I run `rspec spec/sample_spec.rb --format doc` Then the output should contain "group 1 example 1" And the output should contain "group 1 example 2" And the output should not contain "group 2 example 1" @@ -79,7 +79,7 @@ Feature: inclusion filters end end """ - When I run "rspec ./spec/before_after_all_inclusion_filter_spec.rb" + When I run `rspec ./spec/before_after_all_inclusion_filter_spec.rb` Then the output should contain "before all in focused group" And the output should contain "after all in focused group" And the output should not contain "before all in unfocused group" @@ -101,6 +101,6 @@ Feature: inclusion filters end end """ - When I run "rspec symbols_as_metadata_spec.rb --format doc" + When I run `rspec symbols_as_metadata_spec.rb --format doc` Then the output should contain "does another thing" And the output should not contain "does one thing" diff --git a/features/filtering/run_all_when_everything_filtered.feature b/features/filtering/run_all_when_everything_filtered.feature index 37ad8c96b1..a4fee4d77a 100644 --- a/features/filtering/run_all_when_everything_filtered.feature +++ b/features/filtering/run_all_when_everything_filtered.feature @@ -31,7 +31,7 @@ Feature: run all when everything filtered end end """ - When I run "rspec spec/sample_spec.rb --format doc" + When I run `rspec spec/sample_spec.rb --format doc` Then the output should contain "No examples were matched by {:focus=>true}, running all" And the examples should all pass And the output should contain: diff --git a/features/formatters/custom_formatter.feature b/features/formatters/custom_formatter.feature index 210fa1b8c5..a9157443f0 100644 --- a/features/formatters/custom_formatter.feature +++ b/features/formatters/custom_formatter.feature @@ -31,6 +31,6 @@ Feature: custom formatters end end """ - When I run "rspec example_spec.rb --require ./custom_formatter.rb --format CustomFormatter" + When I run `rspec example_spec.rb --require ./custom_formatter.rb --format CustomFormatter` Then the output should contain "example: my example" And the exit status should be 0 diff --git a/features/formatters/text_formatter.feature b/features/formatters/text_formatter.feature index a34e9fddc3..d751b349ac 100644 --- a/features/formatters/text_formatter.feature +++ b/features/formatters/text_formatter.feature @@ -25,7 +25,7 @@ Feature: text formatter end end """ - When I run "ruby ./integer_spec.rb ./string_spec.rb" + When I run `ruby ./integer_spec.rb ./string_spec.rb` Then the backtrace-normalized output should contain: """ Failures: diff --git a/features/helper_methods/arbitrary_methods.feature b/features/helper_methods/arbitrary_methods.feature index 463a5d0431..1b6105e7c8 100644 --- a/features/helper_methods/arbitrary_methods.feature +++ b/features/helper_methods/arbitrary_methods.feature @@ -18,7 +18,7 @@ Feature: arbitrary helper methods end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the examples should all pass Scenario: use a method defined in a parent group @@ -36,5 +36,5 @@ Feature: arbitrary helper methods end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the examples should all pass diff --git a/features/helper_methods/let.feature b/features/helper_methods/let.feature index 3bf72e853b..b9b0ddfb0a 100644 --- a/features/helper_methods/let.feature +++ b/features/helper_methods/let.feature @@ -24,7 +24,7 @@ Feature: let and let! end end """ - When I run "rspec let_spec.rb" + When I run `rspec let_spec.rb` Then the examples should all pass Scenario: use let! to define a memoized helper method that is called in a before hook @@ -46,5 +46,5 @@ Feature: let and let! end end """ - When I run "rspec let_bang_spec.rb" + When I run `rspec let_bang_spec.rb` Then the examples should all pass diff --git a/features/helper_methods/modules.feature b/features/helper_methods/modules.feature index a06a5cee0d..4537b4f5f8 100644 --- a/features/helper_methods/modules.feature +++ b/features/helper_methods/modules.feature @@ -38,7 +38,7 @@ Feature: Define helper methods in a module end end """ - When I run "rspec include_module_spec.rb" + When I run `rspec include_module_spec.rb` Then the examples should all pass Scenario: extend a module in all example groups @@ -58,7 +58,7 @@ Feature: Define helper methods in a module end end """ - When I run "rspec extend_module_spec.rb" + When I run `rspec extend_module_spec.rb` Then the examples should all pass And the output should contain "Help is available" @@ -83,7 +83,7 @@ Feature: Define helper methods in a module end end """ - When I run "rspec include_module_in_some_groups_spec.rb" + When I run `rspec include_module_in_some_groups_spec.rb` Then the examples should all pass Scenario: extend a module in only some example groups @@ -111,7 +111,7 @@ Feature: Define helper methods in a module end end """ - When I run "rspec extend_module_in_only_some_groups_spec.rb" + When I run `rspec extend_module_in_only_some_groups_spec.rb` Then the examples should all pass And the output should contain "In a matching group, help is available" And the output should contain "In a non-matching group, help is not available" @@ -143,7 +143,7 @@ Feature: Define helper methods in a module end end """ - When I run "rspec symbols_as_metadata_spec.rb" + When I run `rspec symbols_as_metadata_spec.rb` Then the examples should all pass And the output should contain "In a group not matching the extend filter, help is not available" And the output should contain "In a group matching the extend filter, help is available" diff --git a/features/hooks/around_hooks.feature b/features/hooks/around_hooks.feature index 4d20fec81a..8d293e150a 100644 --- a/features/hooks/around_hooks.feature +++ b/features/hooks/around_hooks.feature @@ -30,7 +30,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain: """ open transaction @@ -53,7 +53,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain: """ around each before @@ -74,7 +74,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain "this should show up in the output" Scenario: define a global around hook @@ -94,7 +94,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain: """ around each before @@ -125,7 +125,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain: """ around each before @@ -158,7 +158,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain: """ before all @@ -189,7 +189,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain "1 example, 0 failure" Scenario: implicitly pending examples are detected as Not Yet Implemented @@ -203,7 +203,7 @@ Feature: around hooks it "should be detected as Not Yet Implemented" end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain "1 example, 0 failures, 1 pending" And the output should contain: """ @@ -226,7 +226,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain "1 example, 0 failures, 1 pending" And the output should contain: """ @@ -256,7 +256,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain "1 example, 0 failure" And the output should contain: """ @@ -316,7 +316,7 @@ Feature: around hooks end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the output should contain "1 example, 0 failure" And the output should contain: """ diff --git a/features/hooks/before_and_after_hooks.feature b/features/hooks/before_and_after_hooks.feature index d47e360d6b..8a529f5538 100644 --- a/features/hooks/before_and_after_hooks.feature +++ b/features/hooks/before_and_after_hooks.feature @@ -52,7 +52,7 @@ Feature: before and after hooks end end """ - When I run "rspec before_each_spec.rb" + When I run `rspec before_each_spec.rb` Then the examples should all pass Scenario: define before(:all) block in example group @@ -86,10 +86,10 @@ Feature: before and after hooks end end """ - When I run "rspec before_all_spec.rb" + When I run `rspec before_all_spec.rb` Then the examples should all pass - When I run "rspec before_all_spec.rb:15" + When I run `rspec before_all_spec.rb:15` Then the examples should all pass Scenario: failure in before(:all) block @@ -124,7 +124,7 @@ Feature: before and after hooks end end """ - When I run "rspec before_all_spec.rb --format documentation" + When I run `rspec before_all_spec.rb --format documentation` Then the output should contain "5 examples, 5 failures" And the output should contain: """ @@ -139,7 +139,7 @@ Feature: before and after hooks after all ran """ - When I run "rspec before_all_spec.rb:9 --format documentation" + When I run `rspec before_all_spec.rb:9 --format documentation` Then the output should contain "1 example, 1 failure" And the output should contain: """ @@ -162,7 +162,7 @@ Feature: before and after hooks end end """ - When I run "rspec after_all_spec.rb" + When I run `rspec after_all_spec.rb` Then the examples should all pass And the output should contain: """ @@ -197,7 +197,7 @@ Feature: before and after hooks end end """ - When I run "rspec befores_in_configuration_spec.rb" + When I run `rspec befores_in_configuration_spec.rb` Then the examples should all pass Scenario: before/after blocks are run in order @@ -227,7 +227,7 @@ Feature: before and after hooks end end """ - When I run "rspec ensure_block_order_spec.rb" + When I run `rspec ensure_block_order_spec.rb` Then the output should contain: """ before all @@ -272,7 +272,7 @@ Feature: before and after hooks end end """ - When I run "rspec configuration_spec.rb" + When I run `rspec configuration_spec.rb` Then the output should contain: """ before suite @@ -313,7 +313,7 @@ Feature: before and after hooks end """ - When I run "rspec before_and_after_all_spec.rb" + When I run `rspec before_and_after_all_spec.rb` Then the examples should all pass And the output should contain: """ @@ -323,7 +323,7 @@ Feature: before and after hooks outer after all """ - When I run "rspec before_and_after_all_spec.rb:14" + When I run `rspec before_and_after_all_spec.rb:14` Then the examples should all pass And the output should contain: """ @@ -333,7 +333,7 @@ Feature: before and after hooks outer after all """ - When I run "rspec before_and_after_all_spec.rb:6" + When I run `rspec before_and_after_all_spec.rb:6` Then the examples should all pass And the output should contain: """ @@ -368,7 +368,7 @@ Feature: before and after hooks end end """ - When I run "rspec before_all_spec.rb" + When I run `rspec before_all_spec.rb` Then the examples should all pass Scenario: before/after all blocks have access to state @@ -403,7 +403,7 @@ Feature: before and after hooks end end """ - When I run "rspec before_and_after_all_spec.rb" + When I run `rspec before_and_after_all_spec.rb` Then the examples should all pass Scenario: exception in before(:each) is captured and reported as failure @@ -418,6 +418,6 @@ Feature: before and after hooks end end """ - When I run "rspec error_in_before_each_spec.rb" + When I run `rspec error_in_before_each_spec.rb` Then the output should contain "1 example, 1 failure" And the output should contain "this error" diff --git a/features/hooks/filtering.feature b/features/hooks/filtering.feature index e4d29a3cca..2676bda66e 100644 --- a/features/hooks/filtering.feature +++ b/features/hooks/filtering.feature @@ -37,7 +37,7 @@ Feature: filters end end """ - When I run "rspec filter_before_each_hooks_spec.rb" + When I run `rspec filter_before_each_hooks_spec.rb` Then the examples should all pass Scenario: filter `after(:each)` hooks using arbitrary metadata @@ -67,7 +67,7 @@ Feature: filters end end """ - When I run "rspec filter_after_each_hooks_spec.rb" + When I run `rspec filter_after_each_hooks_spec.rb` Then the output should contain "3 examples, 2 failures" Scenario: filter around(:each) hooks using arbitrary metadata @@ -103,7 +103,7 @@ Feature: filters end end """ - When I run "rspec filter_around_each_hooks_spec.rb" + When I run `rspec filter_around_each_hooks_spec.rb` Then the examples should all pass Scenario: filter before(:all) hooks using arbitrary metadata @@ -139,7 +139,7 @@ Feature: filters end end """ - When I run "rspec filter_before_all_hooks_spec.rb" + When I run `rspec filter_before_all_hooks_spec.rb` Then the examples should all pass Scenario: filter after(:all) hooks using arbitrary metadata @@ -175,7 +175,7 @@ Feature: filters end end """ - When I run "rspec filter_after_all_hooks_spec.rb" + When I run `rspec filter_after_all_hooks_spec.rb` Then the examples should all pass And the output should contain: """ @@ -209,7 +209,7 @@ Feature: filters it("", :around_each) { puts "example 4" } end """ - When I run "rspec less_verbose_metadata_filter.rb" + When I run `rspec less_verbose_metadata_filter.rb` Then the examples should all pass And the output should contain: """ diff --git a/features/metadata/current_example.feature b/features/metadata/current_example.feature index 63a3f48cf2..bac8c702e4 100644 --- a/features/metadata/current_example.feature +++ b/features/metadata/current_example.feature @@ -12,6 +12,6 @@ Feature: current example end end """ - When I run "rspec spec/example_spec.rb" + When I run `rspec spec/example_spec.rb` Then the example should pass diff --git a/features/metadata/described_class.feature b/features/metadata/described_class.feature index a59b3ac98d..7a2675be13 100644 --- a/features/metadata/described_class.feature +++ b/features/metadata/described_class.feature @@ -12,6 +12,6 @@ Feature: described class end end """ - When I run "rspec spec/example_spec.rb" + When I run `rspec spec/example_spec.rb` Then the example should pass diff --git a/features/metadata/user_defined.feature b/features/metadata/user_defined.feature index 5730a9c321..25a1be5faf 100644 --- a/features/metadata/user_defined.feature +++ b/features/metadata/user_defined.feature @@ -42,7 +42,7 @@ Feature: User-defined metadata end end """ - When I run "rspec define_group_metadata_with_hash_spec.rb" + When I run `rspec define_group_metadata_with_hash_spec.rb` Then the examples should all pass Scenario: define example metadata using a hash @@ -61,7 +61,7 @@ Feature: User-defined metadata end end """ - When I run "rspec define_example_metadata_with_hash_spec.rb" + When I run `rspec define_example_metadata_with_hash_spec.rb` Then the examples should all pass Scenario: override user-defined metadata @@ -79,7 +79,7 @@ Feature: User-defined metadata end end """ - When I run "rspec override_metadata_spec.rb" + When I run `rspec override_metadata_spec.rb` Then the examples should all pass Scenario: less verbose metadata @@ -107,5 +107,5 @@ Feature: User-defined metadata end end """ - When I run "rspec less_verbose_metadata_spec.rb" + When I run `rspec less_verbose_metadata_spec.rb` Then the examples should all pass diff --git a/features/mock_framework_integration/use_any_framework.feature b/features/mock_framework_integration/use_any_framework.feature index 20dfcb6827..ab4a4d1224 100644 --- a/features/mock_framework_integration/use_any_framework.feature +++ b/features/mock_framework_integration/use_any_framework.feature @@ -100,7 +100,7 @@ Feature: mock with an alternative framework end end """ - When I run "rspec example_spec.rb --format doc" + When I run `rspec example_spec.rb --format doc` Then the exit status should be 1 And the output should contain "2 examples, 1 failure" And the output should contain "fails when message is received (FAILED - 1)" diff --git a/features/mock_framework_integration/use_flexmock.feature b/features/mock_framework_integration/use_flexmock.feature index f3eb6ca1c6..3c8882681f 100644 --- a/features/mock_framework_integration/use_flexmock.feature +++ b/features/mock_framework_integration/use_flexmock.feature @@ -18,5 +18,5 @@ Feature: mock with flexmock end end """ - When I run "rspec ./flexmock_example_spec.rb" + When I run `rspec ./flexmock_example_spec.rb` Then the examples should all pass diff --git a/features/mock_framework_integration/use_mocha.feature b/features/mock_framework_integration/use_mocha.feature index e3159908e8..f9825e3ddb 100644 --- a/features/mock_framework_integration/use_mocha.feature +++ b/features/mock_framework_integration/use_mocha.feature @@ -18,5 +18,5 @@ Feature: mock with mocha end end """ - When I run "rspec ./mocha_example_spec.rb" + When I run `rspec ./mocha_example_spec.rb` Then the examples should all pass diff --git a/features/mock_framework_integration/use_rr.feature b/features/mock_framework_integration/use_rr.feature index 48f225b340..ffcc3e9789 100644 --- a/features/mock_framework_integration/use_rr.feature +++ b/features/mock_framework_integration/use_rr.feature @@ -19,5 +19,5 @@ Feature: mock with rr end end """ - When I run "rspec rr_example_spec.rb" + When I run `rspec rr_example_spec.rb` Then the examples should all pass diff --git a/features/mock_framework_integration/use_rspec.feature b/features/mock_framework_integration/use_rspec.feature index 491eb875d2..0131266682 100644 --- a/features/mock_framework_integration/use_rspec.feature +++ b/features/mock_framework_integration/use_rspec.feature @@ -18,5 +18,5 @@ Feature: mock with rspec end end """ - When I run "rspec ./rspec_example_spec.rb" + When I run `rspec ./rspec_example_spec.rb` Then the examples should all pass diff --git a/features/pending/pending_examples.feature b/features/pending/pending_examples.feature index 2a52569c70..7942e2d2a5 100644 --- a/features/pending/pending_examples.feature +++ b/features/pending/pending_examples.feature @@ -10,7 +10,7 @@ Feature: pending examples it "is a pending example" end """ - When I run "rspec example_without_block_spec.rb" + When I run `rspec example_without_block_spec.rb` Then the exit status should be 0 And the output should contain "1 example, 0 failures, 1 pending" And the output should contain "Not Yet Implemented" @@ -26,7 +26,7 @@ Feature: pending examples end end """ - When I run "rspec pending_without_block_spec.rb" + When I run `rspec pending_without_block_spec.rb` Then the exit status should be 0 And the output should contain "1 example, 0 failures, 1 pending" And the output should contain: @@ -48,7 +48,7 @@ Feature: pending examples end end """ - When I run "rspec pending_with_failing_block_spec.rb" + When I run `rspec pending_with_failing_block_spec.rb` Then the exit status should be 0 And the output should contain "1 example, 0 failures, 1 pending" And the output should contain: @@ -70,7 +70,7 @@ Feature: pending examples end end """ - When I run "rspec pending_with_passing_block_spec.rb" + When I run `rspec pending_with_passing_block_spec.rb` Then the exit status should not be 0 And the output should contain "1 example, 1 failure" And the output should contain "FIXED" @@ -86,7 +86,7 @@ Feature: pending examples end end """ - When I run "rspec pending_with_xit_spec.rb" + When I run `rspec pending_with_xit_spec.rb` Then the exit status should be 0 And the output should contain "1 example, 0 failures, 1 pending" And the output should contain: @@ -107,7 +107,7 @@ Feature: pending examples end end """ - When I run "rspec pending_with_no_docstring_spec.rb --format documentation" + When I run `rspec pending_with_no_docstring_spec.rb --format documentation` Then the exit status should be 0 And the output should contain "2 examples, 0 failures, 1 pending" And the output should contain: @@ -129,7 +129,7 @@ Feature: pending examples end end """ - When I run "rspec pending_with_no_docstring_spec.rb --format documentation" + When I run `rspec pending_with_no_docstring_spec.rb --format documentation` Then the exit status should be 0 And the output should contain "2 examples, 0 failures, 1 pending" And the output should contain: @@ -182,7 +182,7 @@ Feature: pending examples end end """ - When I run "rspec ./conditionally_pending_spec.rb" + When I run `rspec ./conditionally_pending_spec.rb` Then the output should contain "8 examples, 4 failures, 2 pending" And the output should contain: """ diff --git a/features/spec_files/arbitrary_file_suffix.feature b/features/spec_files/arbitrary_file_suffix.feature index d9183158df..915d05fbbc 100644 --- a/features/spec_files/arbitrary_file_suffix.feature +++ b/features/spec_files/arbitrary_file_suffix.feature @@ -9,5 +9,5 @@ Feature: arbitrary file suffix end end """ - When I run "rspec a.spec" + When I run `rspec a.spec` Then the examples should all pass diff --git a/features/step_definitions/additional_cli_steps.rb b/features/step_definitions/additional_cli_steps.rb index ddf0e38bee..a693145ba6 100644 --- a/features/step_definitions/additional_cli_steps.rb +++ b/features/step_definitions/additional_cli_steps.rb @@ -6,7 +6,7 @@ Then /^the output should not contain any of these:$/ do |table| table.raw.flatten.each do |string| - combined_output.should_not =~ compile_and_escape(string) + all_output.should_not =~ regexp(string) end end @@ -22,9 +22,9 @@ Then /^the backtrace\-normalized output should contain:$/ do |partial_output| # ruby 1.9 includes additional stuff in the backtrace, # so we need to normalize it to compare it with our expected output. - normalized_output = combined_output.split("\n").map do |line| + normalized_output = all_output.split("\n").map do |line| line =~ /(^\s+# [^:]+:\d+)/ ? $1 : line # http://rubular.com/r/zDD7DdWyzF end.join("\n") - normalized_output.should =~ compile_and_escape(partial_output) + normalized_output.should =~ regexp(partial_output) end diff --git a/features/subject/attribute_of_subject.feature b/features/subject/attribute_of_subject.feature index bf4c5070d2..7d7b0350a3 100644 --- a/features/subject/attribute_of_subject.feature +++ b/features/subject/attribute_of_subject.feature @@ -28,7 +28,7 @@ Feature: attribute of subject end end """ - When I run "rspec example_spec.rb --format documentation" + When I run `rspec example_spec.rb --format documentation` Then the output should contain: """ Array @@ -59,7 +59,7 @@ Feature: attribute of subject end end """ - When I run "rspec example_spec.rb --format documentation" + When I run `rspec example_spec.rb --format documentation` Then the output should contain: """ Person @@ -81,7 +81,7 @@ Feature: attribute of subject end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the examples should all pass Scenario: specify value for key in a hash @@ -98,7 +98,7 @@ Feature: attribute of subject end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the examples should all pass Scenario: specify value for key in a hash-like object @@ -118,5 +118,5 @@ Feature: attribute of subject end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the examples should all pass diff --git a/features/subject/explicit_subject.feature b/features/subject/explicit_subject.feature index 87f2edd38f..19cf52a566 100644 --- a/features/subject/explicit_subject.feature +++ b/features/subject/explicit_subject.feature @@ -13,7 +13,7 @@ Feature: explicit subject end end """ - When I run "rspec top_level_subject_spec.rb" + When I run `rspec top_level_subject_spec.rb` Then the examples should all pass Scenario: subject in a nested group @@ -28,7 +28,7 @@ Feature: explicit subject end end """ - When I run "rspec nested_subject_spec.rb" + When I run `rspec nested_subject_spec.rb` Then the examples should all pass Scenario: access subject from before block @@ -42,7 +42,7 @@ Feature: explicit subject end end """ - When I run "rspec top_level_subject_spec.rb" + When I run `rspec top_level_subject_spec.rb` Then the examples should all pass Scenario: invoke helper method from subject block @@ -58,7 +58,7 @@ Feature: explicit subject end end """ - When I run "rspec helper_subject_spec.rb" + When I run `rspec helper_subject_spec.rb` Then the examples should all pass Scenario: subject block is invoked at most once per example @@ -74,5 +74,5 @@ Feature: explicit subject end end """ - When I run "rspec nil_subject_spec.rb" + When I run `rspec nil_subject_spec.rb` Then the examples should all pass diff --git a/features/subject/implicit_receiver.feature b/features/subject/implicit_receiver.feature index 6187c6a06f..4f5730f0e8 100644 --- a/features/subject/implicit_receiver.feature +++ b/features/subject/implicit_receiver.feature @@ -12,7 +12,7 @@ Feature: implicit receiver end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the examples should all pass Scenario: explicit subject @@ -25,5 +25,5 @@ Feature: implicit receiver end end """ - When I run "rspec example_spec.rb" + When I run `rspec example_spec.rb` Then the examples should all pass diff --git a/features/subject/implicit_subject.feature b/features/subject/implicit_subject.feature index 52a8d585ee..398f6bca36 100644 --- a/features/subject/implicit_subject.feature +++ b/features/subject/implicit_subject.feature @@ -12,7 +12,7 @@ Feature: implicit subject end end """ - When I run "rspec ./top_level_subject_spec.rb" + When I run `rspec ./top_level_subject_spec.rb` Then the examples should all pass Scenario: subject in a nested group @@ -26,5 +26,5 @@ Feature: implicit subject end end """ - When I run "rspec nested_subject_spec.rb" + When I run `rspec nested_subject_spec.rb` Then the examples should all pass diff --git a/features/support/env.rb b/features/support/env.rb index 0afa4960fb..6661cf79ac 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -1 +1,6 @@ -require 'aruba' +require 'aruba/cucumber' + +Before do + @aruba_timeout_seconds = 3 +end + From d57065d7162e49483d8f4810efee96c43d5c38c2 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 27 Mar 2011 11:59:24 -0500 Subject: [PATCH 078/151] Change config.for_groups_matching to shared_context - not in the context of config - aligns with shared_examples_for API - also add `include_context` method to example group - so shared context can be included ... - using include_context - by matching metadata --- features/.nav | 2 +- features/Changelog.md | 2 +- .../configuration/for_groups_matching.feature | 88 ------------ .../example_groups/shared_context.feature | 127 ++++++++++++++++++ lib/rspec/core/configuration.rb | 22 --- lib/rspec/core/example_group.rb | 10 +- lib/rspec/core/shared_example_group.rb | 20 ++- spec/rspec/core/configuration_spec.rb | 80 +---------- spec/rspec/core/example_group_spec.rb | 19 ++- spec/rspec/core/shared_example_group_spec.rb | 78 ++++++++--- 10 files changed, 233 insertions(+), 215 deletions(-) delete mode 100644 features/configuration/for_groups_matching.feature create mode 100644 features/example_groups/shared_context.feature diff --git a/features/.nav b/features/.nav index 54c47dd555..dec7aac88d 100644 --- a/features/.nav +++ b/features/.nav @@ -4,6 +4,7 @@ - example_groups: - basic_structure.feature - shared_example_group.feature + - shared_context.feature - pending: - pending_examples.feature - hooks: @@ -41,7 +42,6 @@ - read_options_from_file.feature - fail_fast.feature - custom_settings.feature - - for_groups_matching.feature - alias_example_to.feature - expectation_framework_integration: - configure_expectation_framework.feature diff --git a/features/Changelog.md b/features/Changelog.md index 64d753e0f0..5893ccd19e 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -3,7 +3,7 @@ [full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...master) * Enhancements - * `config.for_groups_matching` (Damian Nurzynski) + * `shared_context` (Damian Nurzynski) * extend groups matching specific metadata with: * method definitions * subject declarations diff --git a/features/configuration/for_groups_matching.feature b/features/configuration/for_groups_matching.feature deleted file mode 100644 index 0eecb12a42..0000000000 --- a/features/configuration/for_groups_matching.feature +++ /dev/null @@ -1,88 +0,0 @@ -Feature: for groups matching - - Use `for_groups_matching` to define a block that will be evaluated - in the context of any example groups that have matching metadata. - - If you set the `treat_symbols_as_metadata_keys_with_true_values` config option - to `true`, you can specify metadata using only symbols. - - Scenario: define method for groups matching metadata - Given a file named "for_groups_matching_spec.rb" with: - """ - RSpec.configure do |c| - c.for_groups_matching :type => :special do - def method_defined_in_config - "it works" - end - end - end - - describe "something", :type => :special do - it "access methods defined in configuration" do - method_defined_in_config.should eq("it works") - end - end - """ - When I run `rspec for_groups_matching_spec.rb` - Then the examples should all pass - - Scenario: define method using let for groups matching metadata - Given a file named "for_groups_matching_spec.rb" with: - """ - RSpec.configure do |c| - c.for_groups_matching :type => :special do - let(:method_defined_by_let_in_config) { "it works" } - end - end - - describe "something", :type => :special do - it "access methods defined using let in configuration" do - method_defined_by_let_in_config.should eq("it works") - end - end - """ - When I run `rspec for_groups_matching_spec.rb` - Then the examples should all pass - - Scenario: define subject for groups matching metadata - Given a file named "for_groups_matching_spec.rb" with: - """ - RSpec.configure do |c| - c.for_groups_matching :type => :special do - subject { :subject_defined_in_configuration } - end - end - - describe "something", :type => :special do - it "uses the subject defined in configuration" do - subject.should be(:subject_defined_in_configuration) - end - end - """ - When I run `rspec for_groups_matching_spec.rb` - Then the examples should all pass - - Scenario: Use symbols as metadata - Given a file named "use_symbols_as_metadata_spec.rb" with: - """ - RSpec.configure do |c| - c.treat_symbols_as_metadata_keys_with_true_values = true - c.for_groups_matching :special do - let(:help) { :available } - end - end - - describe "something", :special do - it "accesses helper methods defined using `let` in the configuration" do - help.should be(:available) - end - end - - describe "something else" do - it "cannot access helper methods defined using `let` in the configuration" do - expect { help }.to raise_error(NameError) - end - end - """ - When I run `rspec use_symbols_as_metadata_spec.rb` - Then the examples should all pass diff --git a/features/example_groups/shared_context.feature b/features/example_groups/shared_context.feature new file mode 100644 index 0000000000..b99f385528 --- /dev/null +++ b/features/example_groups/shared_context.feature @@ -0,0 +1,127 @@ +Feature: shared context + + Use `shared_context` to define a block that will be evaluated in the context + of example groups either explicitly, using `include_context`, or implicitly by + matching metdata. + + Scenario: declare and use shared context with a string name + Given a file named "shared_context_spec.rb" with: + """ + shared_context "shared stuff", :a => :b do + before { @some_var = :some_value } + def shared_method + "it works" + end + let(:shared_let) { {'arbitrary' => 'object'} } + subject do + 'this is the subject' + end + end + + shared_examples_for "group including shared context" do + it "has access to methods defined in shared context" do + shared_method.should eq("it works") + end + + it "has access to methods defined with let in shared context" do + shared_let['arbitrary'].should eq('object') + end + + it "runs the before hooks defined in the shared context" do + @some_var.should be(:some_value) + end + + it "accesses the subject defined in the shared context" do + subject.should eq('this is the subject') + end + end + + describe "group that includes a shared context using 'include_context'" do + include_context "shared stuff" + it_behaves_like "group including shared context" + end + + describe "group that includes a shared context using metadata", :a => :b do + it_behaves_like "group including shared context" + end + """ + When I run `rspec shared_context_spec.rb` + Then the output should contain "8 examples" + And the examples should all pass + + Scenario: share a method + Given a file named "shared_context_spec.rb" with: + """ + shared_context :type => :special do + def shared_method + "it works" + end + end + + describe "something", :type => :special do + it "access methods defined in configuration" do + shared_method.should eq("it works") + end + end + """ + When I run `rspec shared_context_spec.rb` + Then the examples should all pass + + Scenario: share a `let` declaration + Given a file named "shared_context_spec.rb" with: + """ + shared_context :type => :special do + let(:method_defined_by_let_in_config) { "it works" } + end + + describe "something", :type => :special do + it "access methods defined using let in configuration" do + method_defined_by_let_in_config.should eq("it works") + end + end + """ + When I run `rspec shared_context_spec.rb` + Then the examples should all pass + + Scenario: share a subject + Given a file named "shared_context_spec.rb" with: + """ + shared_context :type => :special do + subject { :subject_defined_in_configuration } + end + + describe "something", :type => :special do + it "uses the subject defined in configuration" do + subject.should be(:subject_defined_in_configuration) + end + end + """ + When I run `rspec shared_context_spec.rb` + Then the examples should all pass + + @wip + Scenario: Use symbols as metadata + Given a file named "use_symbols_as_metadata_spec.rb" with: + """ + RSpec.configure do |c| + c.treat_symbols_as_metadata_keys_with_true_values = true + end + + shared_context :special do + let(:help) { :available } + end + + describe "something", :special do + it "accesses helper methods defined using `let` in the configuration" do + help.should be(:available) + end + end + + describe "something else" do + it "cannot access helper methods defined using `let` in the configuration" do + expect { help }.to raise_error(NameError) + end + end + """ + When I run `rspec use_symbols_as_metadata_spec.rb` + Then the examples should all pass diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index c34ad57112..cc19d1ce36 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -380,28 +380,6 @@ def configure_group(group) end end - # Extend groups matching submitted metadata with methods, subject declarations - # and let/let! declarations. - # - # Example: - # - # RSpec.configure do |c| - # c.for_matching_groups :type => :model do - # def a_method - # "a value" - # end - # subject { Factory described_class.to_s.underscore } - # let(:valid_attributes) { Factory.attributes_for described_class.to_sym } - # end - # end - def for_groups_matching(*args, &block) - mod = Module.new - (class << mod; self; end).send(:define_method, :extended) do |host| - host.class_eval(&block) - end - self.extend(mod, *args) - end - def configure_mock_framework RSpec::Core::ExampleGroup.send(:include, mock_framework) end diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 554978b53f..8b0089e6fb 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -65,7 +65,7 @@ class << self alias_example_to :pending, :pending => true alias_example_to :xit, :pending => true - def self.define_shared_group_method(new_name, report_label=nil) + def self.define_nested_shared_group_method(new_name, report_label=nil) module_eval(<<-END_RUBY, __FILE__, __LINE__) def self.#{new_name}(name, *args, &customization_block) shared_block = world.shared_example_groups[name] @@ -81,14 +81,18 @@ def self.#{new_name}(name, *args, &customization_block) END_RUBY end - define_shared_group_method :it_should_behave_like + define_nested_shared_group_method :it_should_behave_like class << self - alias_method :alias_it_should_behave_like_to, :define_shared_group_method + alias_method :alias_it_should_behave_like_to, :define_nested_shared_group_method end alias_it_should_behave_like_to :it_behaves_like, "behaves like" + def self.include_context(name) + module_eval(&world.shared_example_groups[name]) + end + def self.examples @examples ||= [] end diff --git a/lib/rspec/core/shared_example_group.rb b/lib/rspec/core/shared_example_group.rb index c961ea0dc6..a96f48f87c 100644 --- a/lib/rspec/core/shared_example_group.rb +++ b/lib/rspec/core/shared_example_group.rb @@ -2,12 +2,26 @@ module RSpec module Core module SharedExampleGroup - def share_examples_for(name, &block) - ensure_shared_example_group_name_not_taken(name) - RSpec.world.shared_example_groups[name] = block + def share_examples_for(*args, &block) + if String === args.first || Symbol === args.first + name = args.shift + ensure_shared_example_group_name_not_taken(name) + RSpec.world.shared_example_groups[name] = block + end + + unless args.empty? + mod = Module.new + (class << mod; self; end).send(:define_method, :extended) do |host| + host.class_eval(&block) + end + RSpec.configuration.extend(mod, *args) + else + end end alias :shared_examples_for :share_examples_for + alias :shared_examples :share_examples_for + alias :shared_context :share_examples_for def share_as(name, &block) if Object.const_defined?(name) diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 136f906c91..37bb71814d 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -5,7 +5,7 @@ module RSpec::Core describe Configuration do - let(:config) { subject } + let(:config) { Configuration.new } describe "#load_spec_files" do @@ -31,14 +31,14 @@ module RSpec::Core end describe "#treat_symbols_as_metadata_keys_with_true_values?" do + it 'defaults to false' do + config.treat_symbols_as_metadata_keys_with_true_values?.should be_false + end + it 'can be set to true' do config.treat_symbols_as_metadata_keys_with_true_values = true config.treat_symbols_as_metadata_keys_with_true_values?.should be_true end - - it 'defaults to false' do - config.treat_symbols_as_metadata_keys_with_true_values?.should be_false - end end describe "#mock_framework" do @@ -795,75 +795,5 @@ def metadata_hash(*args) end end - describe "#for_groups_matching" do - it_behaves_like "metadata hash builder" do - def metadata_hash(*args) - config.for_groups_matching(*args) { } - config.include_or_extend_modules.last.last - end - end - end - - describe "#for_groups_matching" do - let(:matching_group) { ExampleGroup.describe(Array, :extended => true) } - let(:non_matching_group) { ExampleGroup.describe(Array) } - - before do - config.for_groups_matching :extended => true do - def method_defined_in_config - 'method defined in config' - end - subject { "subject defined in config" } - let(:let_declaration_in_config) { 'value returned by let declared in config' } - let(:let_bang_declaration_in_config) { 'value returned by let bang declared in config' } - end - [matching_group, non_matching_group].each {|g| config.configure_group(g) } - end - - context "for groups matching filters" do - it "defines methods" do - matching_group.new.method_defined_in_config.should == 'method defined in config' - end - - it "defines subject" do - matching_group.subject.call.should eq("subject defined in config") - end - - it "defines let" do - matching_group.example('let') { let_declaration_in_config.should eq('value returned by let declared in config') } - matching_group.run.should be_true, "expected method declared with let to be accessible in example group" - end - - it "defines let!" do - matching_group.example('let!') { let_bang_declaration_in_config.should eq('value returned by let bang declared in config') } - matching_group.run.should be_true, "expected method declared with let! to be accessible in example group" - end - end - - context "for groups not matching filters given" do - it "doesn't define new methods" do - expect { non_matching_group.new.method_defined_in_config }.to raise_error(NoMethodError) - end - - it "doesn't change the subject" do - non_matching_group.subject.call.should eq([]) - end - - it "doesn't define let" do - non_matching_group.example('let') do - expect { let_declaration_in_config }.to raise_error(NameError) - end - non_matching_group.run.should be_true, 'defined let should raise NameError for not matching group' - end - - it "doesn't define let!" do - non_matching_group.example('let') do - expect { let_bang_declaration_in_config }.to raise_error(NameError) - end - non_matching_group.run.should be_true, 'defined let should raise NameError for not matching group' - end - end - end - end end diff --git a/spec/rspec/core/example_group_spec.rb b/spec/rspec/core/example_group_spec.rb index 35050262c1..42bdee1df1 100644 --- a/spec/rspec/core/example_group_spec.rb +++ b/spec/rspec/core/example_group_spec.rb @@ -276,7 +276,6 @@ def metadata_hash(*args) end describe "#before, after, and around hooks" do - it "runs the before alls in order" do group = ExampleGroup.describe order = [] @@ -803,5 +802,23 @@ def metadata_hash(*args) end end + describe "#include_context" do + before do + shared_context "named this" do + def foo; 'foo'; end + end + end + + it "includes the named context" do + group = ExampleGroup.describe do + include_context "named this" + it "accesses foo" do + foo.should eq('foo') + end + end + group.run.should be_true + end + end + end end diff --git a/spec/rspec/core/shared_example_group_spec.rb b/spec/rspec/core/shared_example_group_spec.rb index 4bdf9d7b76..a1b2848f07 100644 --- a/spec/rspec/core/shared_example_group_spec.rb +++ b/spec/rspec/core/shared_example_group_spec.rb @@ -6,7 +6,6 @@ module RSpec::Core %w[share_examples_for shared_examples_for].each do |method_name| describe method_name do - it "is exposed to the global namespace" do Kernel.should respond_to(method_name) end @@ -19,32 +18,49 @@ module RSpec::Core end.should raise_error(ArgumentError, "Shared example group 'shared group' already exists") end - it "captures the given name and block in the Worlds collection of shared example groups" do - implementation = lambda {} - RSpec.world.shared_example_groups.should_receive(:[]=).with(:foo, implementation) - send(method_name, :foo, &implementation) + context "given a string" do + it "captures the given string and block in the World's collection of shared example groups" do + implementation = lambda {} + RSpec.world.shared_example_groups.should_receive(:[]=).with("name", implementation) + send(method_name, "name", &implementation) + end end - end - end + context "given a symbol" do + it "captures the given symbol and block in the World's collection of shared example groups" do + implementation = lambda {} + RSpec.world.shared_example_groups.should_receive(:[]=).with(:name, implementation) + send(method_name, :name, &implementation) + end + end - describe "#share_as" do - it "is exposed to the global namespace" do - Kernel.should respond_to("share_as") - end + context "given a hash" do + it "delegates extend on configuration" do + implementation = Proc.new { def bar; 'bar'; end } + send(method_name, :foo => :bar, &implementation) + a = RSpec.configuration.include_or_extend_modules.first + a[0].should eq(:extend) + Class.new.extend(a[1]).new.bar.should eq('bar') + a[2].should eq(:foo => :bar) + end + end - it "adds examples to current example_group using include", :compat => 'rspec-1.2' do - share_as('Cornucopia') do - it "is plentiful" do - 5.should == 4 + context "given a string and a hash" do + it "captures the given string and block in the World's collection of shared example groups" do + implementation = lambda {} + RSpec.world.shared_example_groups.should_receive(:[]=).with("name", implementation) + send(method_name, "name", :foo => :bar, &implementation) + end + + it "delegates extend on configuration" do + implementation = Proc.new { def bar; 'bar'; end } + send(method_name, "name", :foo => :bar, &implementation) + a = RSpec.configuration.include_or_extend_modules.first + a[0].should eq(:extend) + Class.new.extend(a[1]).new.bar.should eq('bar') + a[2].should eq(:foo => :bar) end end - group = ExampleGroup.describe('group') { include Cornucopia } - phantom_group = group.children.first - phantom_group.description.should eql("") - phantom_group.metadata[:shared_group_name].should eql('Cornucopia') - phantom_group.examples.length.should == 1 - phantom_group.examples.first.metadata[:description].should == "is plentiful" end end @@ -148,5 +164,25 @@ def foo; end end.should raise_error(/Could not find shared example group named/) end end + + describe "#share_as" do + it "is exposed to the global namespace" do + Kernel.should respond_to("share_as") + end + + it "adds examples to current example_group using include", :compat => 'rspec-1.2' do + share_as('Cornucopia') do + it "is plentiful" do + 5.should == 4 + end + end + group = ExampleGroup.describe('group') { include Cornucopia } + phantom_group = group.children.first + phantom_group.description.should eql("") + phantom_group.metadata[:shared_group_name].should eql('Cornucopia') + phantom_group.examples.length.should == 1 + phantom_group.examples.first.metadata[:description].should == "is plentiful" + end + end end end From 95458f14382697c2bb559c19175803c8be363bb6 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sat, 26 Mar 2011 08:52:42 -0700 Subject: [PATCH 079/151] Add travis config file. --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..7ca1606c4e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +script: "rake" +rvm: + - 1.8.7 + - 1.9.2 From ddaf0af282f332df1266db7350f2c32d8f505061 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Mon, 28 Mar 2011 09:55:48 -0700 Subject: [PATCH 080/151] Use git protocol rather than https for bundled rspec gems. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The https url failed when travis-ci tried to build rspec-core. This might fix it. Fetching https://github.com/rspec/rspec-expectations.git error: while accessing https://github.com/rspec/rspec-expectations.git/info/refs fatal: HTTP request failed An error has occurred in git when running `git clone "https://github.com/rspec/rspec-expectations.git" "/home/travis/.rvm/gems/ruby-1.8.7-p330/cache/bundler/git/rspec-expectations-1c518ec8c1880aa81941a7a8c7fa04b29ec74c91" --bare --no-hardlinks`. Cannot complete bundling. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index b0365646c1..a3c0f34027 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ source "http://rubygems.org" if File.exist?(library_path) gem lib, :path => library_path else - gem lib, :git => "https://github.com/rspec/#{lib}.git" + gem lib, :git => "git://github.com/rspec/#{lib}.git" end end From 96ca109bf7e0085b31b699584a9c35fb7e6fda21 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Mon, 28 Mar 2011 10:03:28 -0700 Subject: [PATCH 081/151] Use RUBY_PLATFORM rather than RUBY_ENGINE to detect jruby. RUBY_ENGINE is not defined when using MRI. RUBY_PLATFORM is. --- spec/rspec/core/formatters/base_formatter_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/rspec/core/formatters/base_formatter_spec.rb b/spec/rspec/core/formatters/base_formatter_spec.rb index ae67fce60f..167640a59b 100644 --- a/spec/rspec/core/formatters/base_formatter_spec.rb +++ b/spec/rspec/core/formatters/base_formatter_spec.rb @@ -46,7 +46,7 @@ end it "doesn't hang when file exists" do - pending("This issue still exists on JRuby, but should be resolved shortly: https://github.com/rspec/rspec-core/issues/295", :if => RUBY_ENGINE == 'jruby') + pending("This issue still exists on JRuby, but should be resolved shortly: https://github.com/rspec/rspec-core/issues/295", :if => RUBY_PLATFORM == 'java') exception = mock(:Exception, :backtrace => [ "#{__FILE__}:#{__LINE__}"]) example = mock(:Example, :file_path => __FILE__) From 37d97f9384905535948788e7b8f6128c11c320bf Mon Sep 17 00:00:00 2001 From: Sidu Ponnappa Date: Fri, 25 Mar 2011 17:35:47 +0530 Subject: [PATCH 082/151] All tests now green on jruby. 6 failing cukes to go before we're all green. - Closes #343. --- spec/autotest/failed_results_re_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/autotest/failed_results_re_spec.rb b/spec/autotest/failed_results_re_spec.rb index ea04333a44..8fb4428883 100644 --- a/spec/autotest/failed_results_re_spec.rb +++ b/spec/autotest/failed_results_re_spec.rb @@ -19,7 +19,7 @@ it "matches a failure" do re = Autotest::Rspec2.new.failed_results_re example_output.should =~ re - example_output[re, 2].should == __FILE__.sub(File.expand_path('.'),'.') + example_output.should include(__FILE__.sub(File.expand_path('.'),'.')) end end @@ -31,7 +31,7 @@ it "matches a failure" do re = Autotest::Rspec2.new.failed_results_re example_output.should =~ re - example_output[re, 2].should == __FILE__.sub(File.expand_path('.'),'.') + example_output.should include(__FILE__.sub(File.expand_path('.'),'.')) end end end From d0ee3dfb0dcf7ab9e2ed495eaaf96a0b919eb34b Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 28 Mar 2011 19:07:17 -0500 Subject: [PATCH 083/151] Regexp.escape the argument to --example. - Closes #299. - Thanks to Elliot Winkler for the suggestion. --- features/Changelog.md | 1 + lib/rspec/core/option_parser.rb | 2 +- spec/rspec/core/option_parser_spec.rb | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/features/Changelog.md b/features/Changelog.md index 5893ccd19e..311f8afb7e 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -30,6 +30,7 @@ * Get specs passing on jruby (Sidu Ponnappa) * Fix bug where mixing nested groups and outer-level examples gave unpredictable :line_number behavior (Artur Małecki) + * Regexp.escape the argument to --example (tip from Elliot Winkler) ### 2.5.1 / 2011-02-06 diff --git a/lib/rspec/core/option_parser.rb b/lib/rspec/core/option_parser.rb index 5e099124b0..c09d58a797 100644 --- a/lib/rspec/core/option_parser.rb +++ b/lib/rspec/core/option_parser.rb @@ -42,7 +42,7 @@ def parser(options) parser.on('-e', '--example PATTERN', "Run examples whose full descriptions match this pattern", "(PATTERN is compiled into a Ruby regular expression)") do |o| - options[:full_description] = /#{o}/ + options[:full_description] = Regexp.compile(Regexp.escape(o)) end parser.on('-f', '--format FORMATTER', 'Choose a formatter', diff --git a/spec/rspec/core/option_parser_spec.rb b/spec/rspec/core/option_parser_spec.rb index 157da2ad82..ce49c092fd 100644 --- a/spec/rspec/core/option_parser_spec.rb +++ b/spec/rspec/core/option_parser_spec.rb @@ -71,5 +71,13 @@ module RSpec::Core end end end + + describe "--example" do + it "escapes the arg" do + options = Parser.parse!(["--example", "this (and that)"]) + "this (and that)".should match(options[:full_description]) + end + end + end end From 096e5867014154a517d8de762806f7d4c0e04a78 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Mon, 28 Mar 2011 22:20:09 -0700 Subject: [PATCH 084/151] Looks like more rubies are installed on travis, so let's build on some more. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7ca1606c4e..b2e71f4c52 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,7 @@ script: "rake" rvm: + - 1.8.6 - 1.8.7 + - 1.9.1 - 1.9.2 + - jruby From dff001d9b58535721eafba54090b9f20be3db85a Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 29 Mar 2011 06:39:24 -0500 Subject: [PATCH 085/151] clean const_missing backtraces --- lib/rspec/core/backward_compatibility.rb | 18 ++++++++++++++++-- spec/rspec/core/deprecations_spec.rb | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/rspec/core/backward_compatibility.rb b/lib/rspec/core/backward_compatibility.rb index 689d11dfa3..3b73569e76 100644 --- a/lib/rspec/core/backward_compatibility.rb +++ b/lib/rspec/core/backward_compatibility.rb @@ -17,7 +17,14 @@ def const_missing(name) WARNING RSpec else - super(name) + begin + super + rescue Exception => e + while e.backtrace.first =~ /lib\/rspec\/(.*)\/backward_compatibility\.rb/ + e.backtrace.shift + end + raise e + end end end end @@ -38,7 +45,14 @@ def self.const_missing(name) require 'rspec/core/rake_task' RSpec::Core::RakeTask else - super(name) + begin + super + rescue Exception => e + while e.backtrace.first =~ /(lib\/rspec\/(.*)\/backward_compatibility\.rb|lib\/rake\.rb)/ + e.backtrace.shift + end + raise e + end end end diff --git a/spec/rspec/core/deprecations_spec.rb b/spec/rspec/core/deprecations_spec.rb index 4399363f6e..b27f0f254d 100644 --- a/spec/rspec/core/deprecations_spec.rb +++ b/spec/rspec/core/deprecations_spec.rb @@ -11,6 +11,16 @@ RSpec.stub(:warn_deprecation) Spec.should == RSpec end + + it "doesn't include backward compatibility in const_missing backtrace" do + RSpec.stub(:warn_deprecation) + exception = nil + begin + ConstantThatDoesNotExist + rescue Exception => exception + end + exception.backtrace[0].should =~ Regexp.compile("#{__FILE__}:#{__LINE__ - 3}") + end end describe RSpec::Core::ExampleGroup do @@ -41,5 +51,16 @@ RSpec.should_receive(:deprecate) Spec::Rake::SpecTask end + + it "doesn't include backward compatibility in const_missing backtrace" do + RSpec.stub(:warn_deprecation) + exception = nil + begin + Spec::Rake::ConstantThatDoesNotExist + rescue Exception => exception + end + exception.backtrace[0].should =~ Regexp.compile("#{__FILE__}:#{__LINE__ - 3}") + end end + end From 0ff66c4bc82efbe3f38c8c38aec5b0e4fc2c3c2b Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 29 Mar 2011 07:04:38 -0500 Subject: [PATCH 086/151] cleaner backtrace cleansing --- lib/rspec/core/backward_compatibility.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/rspec/core/backward_compatibility.rb b/lib/rspec/core/backward_compatibility.rb index 3b73569e76..6f47ff3c26 100644 --- a/lib/rspec/core/backward_compatibility.rb +++ b/lib/rspec/core/backward_compatibility.rb @@ -20,7 +20,10 @@ def const_missing(name) begin super rescue Exception => e - while e.backtrace.first =~ /lib\/rspec\/(.*)\/backward_compatibility\.rb/ + while e.backtrace.first !~ Regexp.compile(__FILE__) + e.backtrace.shift + end + while e.backtrace.first =~ Regexp.compile(__FILE__) e.backtrace.shift end raise e @@ -48,7 +51,10 @@ def self.const_missing(name) begin super rescue Exception => e - while e.backtrace.first =~ /(lib\/rspec\/(.*)\/backward_compatibility\.rb|lib\/rake\.rb)/ + while e.backtrace.first !~ Regexp.compile(__FILE__) + e.backtrace.shift + end + while e.backtrace.first =~ Regexp.compile(__FILE__) e.backtrace.shift end raise e From 1ffd47deb8aa26ab3d976407e985e3f0127db6a5 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Tue, 29 Mar 2011 07:15:32 -0500 Subject: [PATCH 087/151] less invasive cleansing of const_missing backtrace --- lib/rspec/core/backward_compatibility.rb | 14 ++------------ spec/rspec/core/deprecations_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/lib/rspec/core/backward_compatibility.rb b/lib/rspec/core/backward_compatibility.rb index 6f47ff3c26..a7b5813394 100644 --- a/lib/rspec/core/backward_compatibility.rb +++ b/lib/rspec/core/backward_compatibility.rb @@ -20,12 +20,7 @@ def const_missing(name) begin super rescue Exception => e - while e.backtrace.first !~ Regexp.compile(__FILE__) - e.backtrace.shift - end - while e.backtrace.first =~ Regexp.compile(__FILE__) - e.backtrace.shift - end + e.backtrace.reject! {|l| l =~ Regexp.compile(__FILE__) } raise e end end @@ -51,12 +46,7 @@ def self.const_missing(name) begin super rescue Exception => e - while e.backtrace.first !~ Regexp.compile(__FILE__) - e.backtrace.shift - end - while e.backtrace.first =~ Regexp.compile(__FILE__) - e.backtrace.shift - end + e.backtrace.reject! {|l| l =~ Regexp.compile(__FILE__) } raise e end end diff --git a/spec/rspec/core/deprecations_spec.rb b/spec/rspec/core/deprecations_spec.rb index b27f0f254d..d0f139b173 100644 --- a/spec/rspec/core/deprecations_spec.rb +++ b/spec/rspec/core/deprecations_spec.rb @@ -19,7 +19,7 @@ ConstantThatDoesNotExist rescue Exception => exception end - exception.backtrace[0].should =~ Regexp.compile("#{__FILE__}:#{__LINE__ - 3}") + exception.backtrace.find { |l| l =~ /lib\/rspec\/core\/backward_compatibility/ }.should be_nil end end @@ -59,7 +59,7 @@ Spec::Rake::ConstantThatDoesNotExist rescue Exception => exception end - exception.backtrace[0].should =~ Regexp.compile("#{__FILE__}:#{__LINE__ - 3}") + exception.backtrace.find { |l| l =~ /lib\/rspec\/core\/backward_compatibility/ }.should be_nil end end From 622505d616d950ed53d12c6e82dbb953ba6241b4 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Fri, 1 Apr 2011 14:07:48 -0700 Subject: [PATCH 088/151] Define a `framework_name` class method on all mocking adapter modules so we can get `RSpec.configuration.mock_framework.framework_name` --- lib/rspec/core/mocking/with_flexmock.rb | 2 ++ lib/rspec/core/mocking/with_mocha.rb | 2 ++ lib/rspec/core/mocking/with_rr.rb | 2 ++ lib/rspec/core/mocking/with_rspec.rb | 4 +++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/rspec/core/mocking/with_flexmock.rb b/lib/rspec/core/mocking/with_flexmock.rb index 3cd50454f7..9e3e6d1625 100644 --- a/lib/rspec/core/mocking/with_flexmock.rb +++ b/lib/rspec/core/mocking/with_flexmock.rb @@ -8,6 +8,8 @@ module RSpec module Core module MockFrameworkAdapter + + def self.framework_name; :flexmock end include FlexMock::MockContainer def setup_mocks_for_rspec diff --git a/lib/rspec/core/mocking/with_mocha.rb b/lib/rspec/core/mocking/with_mocha.rb index 7fcf5fd8d4..6147c72904 100644 --- a/lib/rspec/core/mocking/with_mocha.rb +++ b/lib/rspec/core/mocking/with_mocha.rb @@ -4,6 +4,8 @@ module RSpec module Core module MockFrameworkAdapter + + def self.framework_name; :mocha end # Mocha::Standalone was deprecated as of Mocha 0.9.7. begin diff --git a/lib/rspec/core/mocking/with_rr.rb b/lib/rspec/core/mocking/with_rr.rb index 456c99a95f..975ebc73da 100644 --- a/lib/rspec/core/mocking/with_rr.rb +++ b/lib/rspec/core/mocking/with_rr.rb @@ -5,6 +5,8 @@ module RSpec module Core module MockFrameworkAdapter + + def self.framework_name; :rr end include RR::Extensions::InstanceMethods diff --git a/lib/rspec/core/mocking/with_rspec.rb b/lib/rspec/core/mocking/with_rspec.rb index 78a343e255..f7c4694317 100644 --- a/lib/rspec/core/mocking/with_rspec.rb +++ b/lib/rspec/core/mocking/with_rspec.rb @@ -3,7 +3,9 @@ module RSpec module Core module MockFrameworkAdapter - + + def self.framework_name; :rspec end + def setup_mocks_for_rspec RSpec::Mocks::setup(self) end From 398c74ce8e1860e876ba71f91de6d79a2ded7c4a Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Fri, 1 Apr 2011 14:49:17 -0700 Subject: [PATCH 089/151] Cukes for RSpec.configuration.mock_framework.framework_name --- features/mock_framework_integration/use_flexmock.feature | 6 ++++++ features/mock_framework_integration/use_mocha.feature | 6 ++++++ features/mock_framework_integration/use_rr.feature | 6 ++++++ features/mock_framework_integration/use_rspec.feature | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/features/mock_framework_integration/use_flexmock.feature b/features/mock_framework_integration/use_flexmock.feature index 3c8882681f..f6da8274c6 100644 --- a/features/mock_framework_integration/use_flexmock.feature +++ b/features/mock_framework_integration/use_flexmock.feature @@ -16,6 +16,12 @@ Feature: mock with flexmock flexmock(target).should_receive(:foo).once target.foo end + + describe "RSpec.configuration.mock_framework.framework_name" do + it "returns :flexmock" do + RSpec.configuration.mock_framework.framework_name.should eq(:flexmock) + end + end end """ When I run `rspec ./flexmock_example_spec.rb` diff --git a/features/mock_framework_integration/use_mocha.feature b/features/mock_framework_integration/use_mocha.feature index f9825e3ddb..75972e8cac 100644 --- a/features/mock_framework_integration/use_mocha.feature +++ b/features/mock_framework_integration/use_mocha.feature @@ -16,6 +16,12 @@ Feature: mock with mocha target.expects(:foo).once target.foo end + + describe "RSpec.configuration.mock_framework.framework_name" do + it "returns :mocha" do + RSpec.configuration.mock_framework.framework_name.should eq(:mocha) + end + end end """ When I run `rspec ./mocha_example_spec.rb` diff --git a/features/mock_framework_integration/use_rr.feature b/features/mock_framework_integration/use_rr.feature index ffcc3e9789..e279f9d6b3 100644 --- a/features/mock_framework_integration/use_rr.feature +++ b/features/mock_framework_integration/use_rr.feature @@ -17,6 +17,12 @@ Feature: mock with rr mock(target).foo target.foo end + + describe "RSpec.configuration.mock_framework.framework_name" do + it "returns :rr" do + RSpec.configuration.mock_framework.framework_name.should eq(:rr) + end + end end """ When I run `rspec rr_example_spec.rb` diff --git a/features/mock_framework_integration/use_rspec.feature b/features/mock_framework_integration/use_rspec.feature index 0131266682..c3da137e03 100644 --- a/features/mock_framework_integration/use_rspec.feature +++ b/features/mock_framework_integration/use_rspec.feature @@ -16,6 +16,12 @@ Feature: mock with rspec target.should_receive(:foo) target.foo end + + describe "RSpec.configuration.mock_framework.framework_name" do + it "returns :rspec" do + RSpec.configuration.mock_framework.framework_name.should eq(:rspec) + end + end end """ When I run `rspec ./rspec_example_spec.rb` From 875cb059c0bc81f71bca86a35847e363e05f0cb2 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Sun, 3 Apr 2011 08:43:38 -0700 Subject: [PATCH 090/151] Only build the rubies travis has available. --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b2e71f4c52..50d8cc2eb3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,4 @@ script: "rake" rvm: - - 1.8.6 - 1.8.7 - - 1.9.1 - - 1.9.2 - - jruby + - ree From 7070a1545b78e43e5e3510d8363723c088903a51 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sat, 2 Apr 2011 09:57:36 -0500 Subject: [PATCH 091/151] remove deprecated default_executable from gemspec --- rspec-core.gemspec | 1 - 1 file changed, 1 deletion(-) diff --git a/rspec-core.gemspec b/rspec-core.gemspec index fc4aa62f3e..bcee7f7a01 100644 --- a/rspec-core.gemspec +++ b/rspec-core.gemspec @@ -14,7 +14,6 @@ Gem::Specification.new do |s| s.rubygems_version = "1.3.7" s.rubyforge_project = "rspec" - s.default_executable = "rspec" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {spec,features}/*`.split("\n") From b51be2c42b5cd281549ee0af2af455d304b92b04 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 7 Apr 2011 08:46:39 -0500 Subject: [PATCH 092/151] Address memory leaks. - set each example's instance of the group to nil after processing. This dereferences the example group instance which contains all of the example's state, thereby releasing each example for garbage collection after processing. Note that this does not dereference state initialized in before(:all), but those instance variables are cleared out in a separate process. 2. nullify ivars after each example - Closes #321. --- lib/rspec/core/example.rb | 5 ++++- spec/rspec/core/example_spec.rb | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/rspec/core/example.rb b/lib/rspec/core/example.rb index c49eae9aaa..e5eddd62ff 100644 --- a/lib/rspec/core/example.rb +++ b/lib/rspec/core/example.rb @@ -58,7 +58,10 @@ def run(example_group_instance, reporter) rescue Exception => e set_exception(e) ensure - @example_group_instance.example = nil + @example_group_instance.instance_variables.each do |ivar| + @example_group_instance.instance_variable_set(ivar, nil) + end + @example_group_instance = nil begin assign_auto_description diff --git a/spec/rspec/core/example_spec.rb b/spec/rspec/core/example_spec.rb index c5104de2ee..bc21860e13 100644 --- a/spec/rspec/core/example_spec.rb +++ b/spec/rspec/core/example_spec.rb @@ -93,6 +93,14 @@ def assert(val) end describe "#run" do + it "sets its reference to the example group instance to nil" do + group = RSpec::Core::ExampleGroup.describe do + example('example') { 1.should eq(1) } + end + group.run + group.examples.first.instance_variable_get("@example_group_instance").should be_nil + end + it "runs after(:each) when the example passes" do after_run = false group = RSpec::Core::ExampleGroup.describe do @@ -168,6 +176,35 @@ def assert(val) "around (after)" ]) end + + context "clearing ivars" do + it "sets ivars to nil to prep them for GC" do + group = RSpec::Core::ExampleGroup.describe do + before(:all) { @before_all = :before_all } + before(:each) { @before_each = :before_each } + after(:each) { @after_each = :after_each } + after(:all) { @after_all = :after_all } + end + example = group.example("does something") do + @in_example = :in_example + end + example_group_instance = group.new + example.run(example_group_instance, double('reporter').as_null_object) + + %w[@before_all @before_each @after_each @after_all].each do |ivar| + example_group_instance.instance_variable_get(ivar).should be_nil + end + end + + it "does not impact the before_all_ivars which are copied to each example" do + group = RSpec::Core::ExampleGroup.describe do + before(:all) { @before_all = "abc" } + example("first") { @before_all.should_not be_nil } + example("second") { @before_all.should_not be_nil } + end + group.run.should be_true + end + end end describe "#pending" do From a7b7afeb9c0a65980f26b9d28bcd7e5f7c47f3de Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Fri, 8 Apr 2011 08:11:58 -0500 Subject: [PATCH 093/151] add spec output --- spec.txt | 1126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1126 insertions(+) create mode 100644 spec.txt diff --git a/spec.txt b/spec.txt new file mode 100644 index 0000000000..77b0e135df --- /dev/null +++ b/spec.txt @@ -0,0 +1,1126 @@ +autotest/discover.rb + with /.rspec present + adds 'rspec2' to the list of discoveries + with /.rspec absent + does not add 'rspec2' to the list of discoveries + +failed_results_re for autotest + output does not have color enabled + matches a failure + output has color enabled + matches a failure + +Autotest::Rspec2 + uses autotest's prefix + commands + makes the appropriate test command + returns a blank command for no files + quotes the paths of files to test + gives '--tty' to /Users/david/projects/ruby/rspec2/repos/rspec-core/bin/rspec, not '--autotest' + mappings + finds the spec file for a given lib file + finds the spec file if given a spec file + ignores files in spec dir that aren't specs + ignores untracked files (in @file) + consolidating failures + returns no failures if no failures were given in the output + returns a hash with the spec filename => spec name for each failure or error + when subject file appears before the spec file in the backtrace + excludes the subject file + includes the spec file + normalizing file names + ensures that a single file appears in files_to_test only once + +RSpec::Core::CommandLineConfiguration + #run + given autotest command + calls Autotest.generate + given unsupported command + raises ArgumentError + +RSpec::Core::CommandLine + given an Array of options + assigns ConfigurationOptions built from Array to @options + given a ConfigurationOptions object + assigns it to @options + #run + configures streams before command line options + runs before suite hooks + runs after suite hooks + runs after suite hooks even after an error + #run with custom output + doesn't override output_stream + +RSpec::Core::ConfigurationOptions + #configure + sends libs before requires + sends requires before formatter + -c, --color, and --colour + sets :color_enabled => true + --no-color + sets :color_enabled => false + -I + adds to :libs + can be used more than once + --require + requires files + can be used more than once + --format, -f + sets :formatter + can accept a class name + --profile, -p + sets :profile_examples => true + --line_number + sets :line_number + --example + sets :full_description + --backtrace, -b + sets full_backtrace on config + --debug, -d + sets :debug => true + --fail-fast + defaults to false + sets fail_fast on config + --options + sets :custom_options_file + --drb, -X + does not send --drb back to the parser after parsing options + combined with --debug + turns off the debugger if --drb is specified first + turns off the debugger option if --drb is specified later + turns off the debugger option if --drb is specified in the options file + turns off the debugger option if --debug is specified in the options file + files_or_directories_to_run + parses files from '-c file.rb dir/file.rb' + parses dir from 'dir' + parses dir and files from 'spec/file1_spec.rb, spec/file2_spec.rb' + provides no files or directories if spec directory does not exist + parses dir and files from 'spec/file1_spec.rb, spec/file2_spec.rb' + #drb_argv + preserves extra arguments + includes --fail-fast + includes --options + with tags + includes the tags + leaves tags intact + with formatters + includes the formatters + leaves formatters intact + leaves output intact + --drb specified in ARGV + renders all the original arguments except --drb + --drb specified in the options file + renders all the original arguments except --drb + --drb specified in ARGV and the options file + renders all the original arguments except --drb + --drb specified in ARGV and in as ARGV-specified --options file + renders all the original arguments except --drb and --options + sources: ~/.rspec, ./.rspec, custom, CLI, and SPEC_OPTS + merges global, local, SPEC_OPTS, and CLI + prefers SPEC_OPTS over CLI + prefers CLI over file options + prefers local file options over global + with custom options file + ignores local and global options files + +RSpec::Core::Configuration + #load_spec_files + loads files using load + with rspec-1 loaded + raises with a helpful message + #treat_symbols_as_metadata_keys_with_true_values? + defaults to false + can be set to true + #mock_framework + defaults to :rspec + #mock_framework= + uses the null adapter when set to any unknown key + with rspec + requires the adapter for :rspec + with mocha + requires the adapter for :mocha + with rr + requires the adapter for :rr + with flexmock + requires the adapter for :flexmock + with a module + sets the mock_framework_adapter to that module + #mock_with + delegates to mock_framework= + #expectation_framework + defaults to :rspec + #expectation_framework= + delegates to expect_with= + #expect_with + raises ArgumentError if framework is not supported + with rspec + requires the adapter for :rspec + with stdlib + requires the adapter for :stdlib + #expecting_with_rspec? + returns false by default + returns true when `expect_with :rspec` has been configured + returns true when `expect_with :rspec, :stdlib` has been configured + returns true when `expect_with :stdlib, :rspec` has been configured + returns false when `expect_with :stdlib` has been configured + setting the files to run + loads files not following pattern if named explicitly + with default --pattern + loads files named _spec.rb + loads files in Windows + with explicit pattern (single) + loads files following pattern + loads files in directories following pattern + does not load files in directories not following pattern + with explicit pattern (comma,separated,values) + supports comma separated values + supports comma separated values with spaces + with line number + assigns the line number as the filter + with full_description + overrides :focused + assigns the example name as the filter on description + #include + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + with no filter + includes the given module into each example group + with a filter + includes the given module into each matching example group + #extend + extends the given module into each matching example group + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + run_all_when_everything_filtered? + defaults to false + can be queried with question method + #color_enabled= + given true + with non-tty output and no autotest + does not set color_enabled + with tty output + does not set color_enabled + with tty set + does not set color_enabled + on windows + with ANSICON available + enables colors + leaves output stream intact + with ANSICON NOT available + warns to install ANSICON + sets color_enabled to false + formatter= + delegates to add_formatter (better API for user-facing configuration) + add_formatter + adds to the list of formatters + finds a formatter by name (w/ Symbol) + finds a formatter by name (w/ String) + finds a formatter by class + finds a formatter by class name + finds a formatter by class fully qualified name + requires a formatter file based on its fully qualified name + raises NameError if class is unresolvable + raises ArgumentError if formatter is unknown + with a 2nd arg defining the output + creates a file at that path and sets it as the output + #filter_run + sets the filter + merges with existing filters + warns if :line_number is already a filter + warns if :full_description is already a filter + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + #filter_run_excluding + sets the filter + merges with existing filters + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + #exclusion_filter + the default :if filter + does not exclude a spec with no :if metadata + does not exclude a spec with { :if => true } metadata + excludes a spec with { :if => false } metadata + excludes a spec with { :if => nil } metadata + the default :unless filter + excludes a spec with { :unless => true } metadata + does not exclude a spec with { :unless => false } metadata + does not exclude a spec with { :unless => nil } metadata + line_number= + sets the line number + overrides :focused + prevents :focused + #full_backtrace= + clears the backtrace clean patterns + doesn't impact other instances of config + #debug=true + requires 'ruby-debug' + starts the debugger + #debug=false + does not require 'ruby-debug' + #output= + sets the output + #libs= + adds directories to the LOAD_PATH + #requires= + requires paths + #add_setting + with no modifiers + with no additional options + defaults to nil + adds a predicate + can be overridden + with :default => 'a value' + defaults to 'a value' + returns true for the predicate + can be overridden with a truthy value + can be overridden with nil + can be overridden with false + with :alias => + delegates the getter to the other option + delegates the setter to the other option + delegates the predicate to the other option + #configure_group + extends with 'extend' + extends with 'module' + requires only one matching filter + includes each one before deciding whether to include the next + #alias_example_to + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + +deprecations + Spec + is deprecated + returns RSpec + doesn't include backward compatibility in const_missing backtrace + RSpec::Core::ExampleGroup + running_example + is deprecated + delegates to example + Spec::Runner.configure + is deprecated + Spec::Rake::SpecTask + is deprecated + doesn't include backward compatibility in const_missing backtrace + +::DRbCommandLine + without server running + raises an error + --drb-port + without RSPEC_DRB environment variable set + defaults to 8989 + sets the DRb port + with RSPEC_DRB environment variable set + without config variable set + uses RSPEC_DRB value + and config variable set + uses configured value + with server running + returns true + integrates via Runner.new.run + outputs green colorized text when running with --colour option (PENDING: figure out a way to properly sandbox this) + outputs red colorized text when running with -c option (PENDING: figure out a way to properly sandbox this) + +RSpec::Core::ExampleGroup + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + processes string args as part of the description + processes symbol args as part of the description + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + does not treat the first argument as a metadata key even if it is a symbol + treats the first argument as part of the description when it is a symbol + top level group + runs its children + with a failure in the top level group + runs its children + descendants + returns self + all descendants + child + is known by parent + is not registered in world + filtering + includes all examples in an explicitly included group + includes explicitly included examples + excludes all examples in an excluded group + filters out excluded examples + with no filters + returns all + with no examples or groups that match filters + returns none + #describes + with a constant as the first parameter + is that constant + with a string as the first parameter + is nil + with a constant in an outer group + and a string in an inner group + is the top level constant + in a nested group + inherits the described class/module from the outer group + #described_class + is the same as describes + #description + grabs the description from the metadata + #metadata + adds the third parameter to the metadata + adds the the file_path to metadata + has a reader for file_path + adds the line_number to metadata + #focus + defines an example that can be filtered with :focused => true + defines an example that can be filtered with :focus => true + #focused + defines an example that can be filtered with :focused => true + defines an example that can be filtered with :focus => true + #before, after, and around hooks + runs the before alls in order + runs the before eachs in order + runs the after eachs in reverse order + runs the after alls in reverse order + only runs before/after(:all) hooks from example groups that have specs that run + runs before_all_defined_in_config, before all, before each, example, after each, after all, after_all_defined_in_config in that order + treats an error in before(:each) as a failure + treats an error in before(:all) as a failure + treats an error in before(:all) as a failure for a spec in a nested group + has no 'running example' within before(:all) + has access to example options within before(:each) + has access to example options within after(:each) + has no 'running example' within after(:all) + after(:all) + has access to state defined before(:all) + cleans up ivars in after(:all) + when an error occurs in an after(:all) hook + allows the example to pass + rescues the error and prints it out + adding examples + allows adding an example using 'it' + allows adding a pending example using 'xit' + exposes all examples at examples + maintains the example order + Object describing nested example_groups + A sample nested group + sets the described class to the described class of the outer most group + sets the description to 'A sample nested describe' + has top level metadata from the example_group and its ancestors + exposes the parent metadata to the contained examples + #run_examples + returns true if all examples pass + returns false if any of the examples fail + runs all examples, regardless of any of them failing + how instance variables are inherited + can access a before each ivar at the same level + can access a before all ivar at the same level + can access the before all ivars in the before_all_ivars hash + but now I am nested + can access a parent example groups before each ivar at a nested level + can access a parent example groups before all ivar at a nested level + changes to before all ivars from within an example do not persist outside the current describe + accessing a before_all ivar that was changed in a parent example_group + does not have access to the modified version + ivars are not shared across examples + (first example) + (second example) + #top_level_description + returns the description from the outermost example group + #run + with fail_fast? => true + does not run examples after the failed example + with RSpec.wants_to_quit=true + returns without starting the group + at top level + purges remaining groups + in a nested group + does not purge remaining groups + with all examples passing + returns true + with top level example failing + returns false + with nested example failing + returns true + #include_context + includes the named context + +RSpec::Core::Example + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + auto-generated example descriptions + when `expect_with :rspec` is configured + generates a description for an example with no description + when `expect_with :rspec, :stdlib` is configured + generates a description for an example with no description + when `expect_with :stdlib` is configured + does not attempt to get the generated description from RSpec::Matchers + fails an example with no description + #described_class + returns the class (if any) of the outermost example group + accessing metadata within a running example + has a reference to itself when running + can access the example group's top level metadata as if it were its own + accessing options within a running example + can look up option values by key + #run + sets its reference to the example group instance to nil + runs after(:each) when the example passes + runs after(:each) when the example fails + runs after(:each) when the example raises an Exception + wraps before/after(:each) inside around + with an after(:each) that raises + runs subsequent after(:each)'s + stores the exception + clearing ivars + sets ivars to nil to prep them for GC + does not impact the before_all_ivars which are copied to each example + #pending + in the example + sets the example to pending + allows post-example processing in around hooks (see https://github.com/rspec/rspec-core/issues/322) + in before(:each) + sets each example to pending + in before(:all) + sets each example to pending + in around(:each) + sets the example to pending + +RSpec::Core::Formatters::BaseFormatter + backtrace_line + trims current working directory + leaves the original line intact + read_failed_line + deals gracefully with a heterogeneous language stack trace + when String alias to_int to_i + doesn't hang when file exists + #format_backtrace + removes lines from rspec and lines that come before the invocation of the at_exit autorun hook + +RSpec::Core::Formatters::BaseTextFormatter + #summary_line + with 0s + outputs pluralized (excluding pending) + with 1s + outputs singular (including pending) + with 2s + outputs pluralized (including pending) + #dump_failures + preserves formatting + with an exception without a message + does not throw NoMethodError + with an exception class other than RSpec + does not show the error class + with a failed expectation (rspec-expectations) + does not show the error class + with a failed message expectation (rspec-mocks) + does not show the error class + for #share_examples_for + outputs the name and location + that contains nested example groups + outputs the name and location + for #share_as + outputs the name and location + that contains nested example groups + outputs the name and location + #dump_profile + names the example + prints the time + prints the path + +RSpec::Core::Formatters::DocumentationFormatter + numbers the failures + represents nested group using hierarchy tree + +RSpec::Core::Formatters::Helpers + format seconds + sub second times + returns 5 digits of precision + strips off trailing zeroes beyond sub-second precision + 0 + strips off trailing zeroes + > 1 + strips off trailing zeroes + second and greater times + returns 2 digits of precision + returns human friendly elasped time + +RSpec::Core::Formatters::HtmlFormatter + produces HTML identical to the one we designed manually + +RSpec::Core::Formatters::ProgressFormatter + produces line break on start dump + produces standard summary without pending when pending has a 0 count + pushes nothing on start + +RSpec::Core::Formatters::SnippetExtractor + falls back on a default message when it doesn't understand a line + falls back on a default message when it doesn't find the file + +RSpec::Core::Formatters::TextMateFormatter + produces HTML identical to the one we designed manually + has a backtrace line from the raw erb evaluation + has a backtrace line from a erb source file we forced to appear + +config block hook filtering + unfiltered hooks + should be ran + hooks with single filters + should be ran if the filter matches the example group's filter + runs before|after :all hooks on matching nested example groups + runs before|after :all hooks only on the highest level group that matches the filter + should not be ran if the filter doesn't match the example group's filter + with no scope specified + should be ran around|before|after :each if the filter matches the example group's filter + when the hook filters apply to individual examples instead of example groups + an example with matching metadata + runs the `:each` hooks + does not run the `:all` hooks + an example without matching metadata + does not run any of the hooks + hooks with multiple filters + should be ran if all hook filters match the group's filters + should not be ran if some hook filters don't match the group's filters + +RSpec::Core::Hooks + #before(each) + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + #before(all) + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + #before(no scope) + defaults to :each scope if no arguments are given + defaults to :each scope if the only argument is a metadata hash + raises an error if only metadata symbols are given as arguments + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + #before(no scope) + defaults to :each scope if no arguments are given + defaults to :each scope if the only argument is a metadata hash + raises an error if only metadata symbols are given as arguments + #after(each) + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + #after(all) + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + #after(no scope) + defaults to :each scope if no arguments are given + defaults to :each scope if the only argument is a metadata hash + raises an error if only metadata symbols are given as arguments + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + #after(no scope) + defaults to :each scope if no arguments are given + defaults to :each scope if the only argument is a metadata hash + raises an error if only metadata symbols are given as arguments + #around(each) + behaves like metadata hash builder + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + treats symbols as metadata keys with a true value + still processes hash values normally + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + prints a deprecation warning about any symbols given as arguments + does not treat symbols as metadata keys + does not print a warning if there are no symbol arguments + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + #around(no scope) + defaults to :each scope if no arguments are given + defaults to :each scope if the only argument is a metadata hash + raises an error if only metadata symbols are given as arguments + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + #around(no scope) + defaults to :each scope if no arguments are given + defaults to :each scope if the only argument is a metadata hash + raises an error if only metadata symbols are given as arguments + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + #before(:each) + does not make :each a metadata key + is scoped to :each + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + #before(:each) + does not make :each a metadata key + is scoped to :each + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + #before(:all) + does not make :all a metadata key + is scoped to :all + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + #before(:all) + does not make :all a metadata key + is scoped to :all + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + #before(:suite) + does not make :suite a metadata key + is scoped to :suite + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + #before(:suite) + does not make :suite a metadata key + is scoped to :suite + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + #after(:each) + does not make :each a metadata key + is scoped to :each + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + #after(:each) + does not make :each a metadata key + is scoped to :each + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + #after(:all) + does not make :all a metadata key + is scoped to :all + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + #after(:all) + does not make :all a metadata key + is scoped to :all + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true + #after(:suite) + does not make :suite a metadata key + is scoped to :suite + when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false + #after(:suite) + does not make :suite a metadata key + is scoped to :suite + #around + when not running the example within the around block + does not run the example + when running the example within the around block + runs the example + when running the example within a block passed to a method + runs the example + RSpec::Core::Hooks::Hook + requires a block + +extensions + debugger + is defined on Kernel + +#let + generates an instance method + caches the value + +#let! + evaluates the value non-lazily + does not interfere between tests + +RSpec::Core::Metadata + #process + prohibits :description as a hash key + prohibits :example_group as a hash key + prohibits :execution_result as a hash key + prohibits :file_path as a hash key + prohibits :full_description as a hash key + prohibits :line_number as a hash key + prohibits :location as a hash key + uses :caller if passed as part of the user metadata + #apply_condition + matches the group when the line_number is the example group line number + matches the example when the line_number is the grandparent example group line number + matches the example when the line_number is the parent example group line number + matches the example when the line_number is the example line number + matches when the line number is between this example and the next + does not match when the line number matches the next example + matches a proc that evaluates to true + does not match a proc that evaluates to false + passes the metadata hash as the second argument if a given proc expects 2 args + #for_example + stores the description + stores the full_description (group description + example description) + creates an empty execution result + extracts file path from caller + extracts line number from caller + extracts location from caller + uses :caller if passed as an option + merges arbitrary options + points :example_group to the same hash object + :describes + with a String + returns nil + with a Symbol + returns nil + with a class + returns the class + with describes from a superclass metadata + returns the superclass' described class + :description + just has the example description + with a string + provides the submitted description + with a non-string + provides the submitted description + with a non-string and a string + concats the args + :full_description + concats example group name and description + concats nested example group descriptions + with a 2nd arg starting with # + removes the space + with a 2nd arg starting with . + removes the space + with a 2nd arg starting with :: + removes the space + with a nested description starting with # + removes the space + with a nested description starting with . + removes the space + with a nested description starting with :: + removes the space + :file_path + finds the first non-rspec lib file in the caller array + :line_number + finds the line number with the first non-rspec lib file in the backtrace + finds the line number with the first spec file with drive letter + uses the number after the first : for ruby 1.9 + child example group + nests the parent's example group metadata + +OptionParser + does not parse empty args + --formatter + is deprecated + gets converted to --format + --format + defines the formatter + -f + defines the formatter + --out + sets the output stream for the formatter + with multiple formatters + after last formatter + sets the output stream for the last formatter + after first formatter + sets the output stream for the first formatter + -o + sets the output stream for the formatter + with multiple formatters + after last formatter + sets the output stream for the last formatter + after first formatter + sets the output stream for the first formatter + --example + escapes the arg + +an example + with no block + is listed as pending with 'Not Yet Implemented' + with no args + is listed as pending with the default message + with no docstring + declared with the pending method + does not have an auto-generated description + after another example with some assertion + does not show any message + with a message + is listed as pending with the supplied message + with a block + that fails + when given no options + is listed as pending with the supplied message + is listed as pending with the default message when no message is given + when given a truthy :if option + is listed as pending with the supplied message + is listed as pending with the default message when no message is given + when given a falsey :if option + runs the example and fails + when given a truthy :unless option + runs the example and fails + when given a falsey :unless option + is listed as pending with the supplied message + is listed as pending with the default message when no message is given + that passes + when given no options + fails with a PendingExampleFixedError + when given a truthy :if option + fails with a PendingExampleFixedError + when given a falsey :if option + runs the example and it passes + when given a truthy :unless option + runs the example and it passes + when given a falsey :unless option + fails with a PendingExampleFixedError + +RSpec::Core::RakeTask + default + renders rspec + with bundler + with Gemfile + renders bundle exec rspec + with non-standard Gemfile + renders bundle exec rspec + without Gemfile + renders bundle exec rspec + with rcov + renders rcov + with bundler and rcov + renders bundle exec rcov + with ruby options + renders them before -S + with rcov_opts + with rcov=false (default) + does not add the rcov options to the command + with rcov=true + renders them after rcov + ensures that -Ispec:lib is in the resulting command + with rspec_opts + with rcov=true + adds the rspec_opts after the rcov_opts and files + with rcov=false (default) + adds the rspec_opts + with SPEC=path/to/file + sets files to run + with paths with quotes + escapes the quotes + +RSpec::Core::Reporter + abort + sends start_dump to the formatter(s) + sends dump_pending to the formatter(s) + sends dump_failures to the formatter(s) + sends dump_summary to the formatter(s) + sends close to the formatter(s) + given one formatter + passes messages to that formatter + passes example_group_started and example_group_finished messages to that formatter in that order + given an example group with no examples + does not pass example_group_started or example_group_finished to formatter + given multiple formatters + passes messages to all formatters + +RSpec::Matchers + behaves like a normal module with a method that supers + raises the expected error (and not SystemStackError) + when RSpec::Matchers has been included in an example group + behaves like a normal module with a method that supers + raises the expected error (and not SystemStackError) + when a module that includes RSpec::Matchers has been included in an example group + behaves like a normal module with a method that supers + raises the expected error (and not SystemStackError) + when RSpec::Matchers is included via configuration + behaves like a normal module with a method that supers + raises the expected error (and not SystemStackError) + when RSpec::Matchers is included in a module that is included via configuration + behaves like a normal module with a method that supers + raises the expected error (and not SystemStackError) + +RSpec::Core::RubyProject + #determine_root + with ancestor containing spec directory + returns ancestor containing the spec directory + without ancestor containing spec directory + returns current working directory + +RSpec::Core::Runner + at_exit + sets an at_exit hook if none is already set + does not set the at_exit hook if it is already set + #run + with --drb or -X + and a DRb server is running + builds a DRbCommandLine and runs the specs + and a DRb server is not running + outputs a message + builds a CommandLine and runs the specs + +RSpec::Core::SharedContext + hooks + creates a before hook + +RSpec::Core::SharedExampleGroup + share_examples_for + is exposed to the global namespace + raises an ArgumentError when adding a second shared example group with the same name + given a string + captures the given string and block in the World's collection of shared example groups + given a symbol + captures the given symbol and block in the World's collection of shared example groups + given a hash + delegates extend on configuration + given a string and a hash + captures the given string and block in the World's collection of shared example groups + delegates extend on configuration + shared_examples_for + is exposed to the global namespace + raises an ArgumentError when adding a second shared example group with the same name + given a string + captures the given string and block in the World's collection of shared example groups + given a symbol + captures the given symbol and block in the World's collection of shared example groups + given a hash + delegates extend on configuration + given a string and a hash + captures the given string and block in the World's collection of shared example groups + delegates extend on configuration + #it_should_behave_like + creates a nested group + adds shared examples to nested group + adds shared instance methods to nested group + adds shared class methods to nested group + raises when named shared example_group can not be found + given some parameters + passes the parameters to the shared example group + adds shared instance methods to nested group + evals the shared example group only once + given a block + evaluates the block in nested group + #share_as + is exposed to the global namespace + adds examples to current example_group using include + +RSpec::Core::Subject + implicit subject + with a class + returns an instance of the class + with a Module + returns the Module + with a string + return the string + with a number + returns the number + explicit subject + with a value of false + is evaluated once per example + with a value of nil + is evaluated once per example + defined in a top level group + replaces the implicit subject in that group + defined in a top level group + is available in a nested group (subclass) + is available in a doubly nested group (subclass) + using 'self' as an explicit subject + delegates matcher to the ExampleGroup + #its + with a call counter + call_count + should == 1 + with nil value + nil_value + should be nil + with nested attributes + name + should == John + name.size + should == 4 + name.size.class + should == Fixnum + when it responds to #[] + [:a] + should == "Symbol: a" + ["a"] + should == "String: a" + [:b, "c", 4] + should == "Symbol: b; String: c; Fixnum: 4" + name + + when referring to an attribute without the proper array syntax + it raises an error + age + should raise NoMethodError + when it does not respond to #[] + it raises an error + [:a] + should raise NoMethodError + calling and overriding super + calls to the subject defined in the parent group + +RSpec::Core::World + #example_groups + contains all registered example groups + #apply_inclusion_filters + finds no groups when given no search parameters + finds matching groups when filtering on :describes (described class or module) + finds matching groups when filtering on :description with text + finds matching groups when filtering on :description with a lambda + finds matching groups when filtering on :description with a regular expression + finds one group when searching for :pending => true + finds matching groups when filtering on arbitrary metadata with a number + finds matching groups when filtering on arbitrary metadata with an array + finds no groups when filtering on arbitrary metadata with an array but the arrays do not match + finds matching examples when filtering on arbitrary metadata + finds matching examples for example that match any of the filters + #apply_exclusion_filters + finds nothing if all describes match the exclusion filter + finds nothing if a regexp matches the exclusion filter + #preceding_declaration_line (again) + with one example + returns nil if no example or group precedes the line + returns the argument line number if a group starts on that line + returns the argument line number if an example starts on that line + returns line number of a group that immediately precedes the argument line + returns line number of an example that immediately precedes the argument line + with two exaples and the second example is registre first + return line number of group if a group start on that line + +RSpec::Core + #configuration + returns the same object every time + #configure + yields the current configuration + when an example group has already been defined + prints a deprecation warning + when no examples have been defined yet + does not print a deprecation warning + #world + returns the RSpec::Core::World instance the current run is using From a4ad3ff243472ffc8f07ca4a2d38aad9a6d68b05 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sat, 9 Apr 2011 17:45:14 -0500 Subject: [PATCH 094/151] run ci against more rubies --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 50d8cc2eb3..8356ae94fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,7 @@ script: "rake" rvm: + - 1.8.6 - 1.8.7 + - 1.9.1 + - 1.9.2 - ree From 4656bd974fbe83e869a2b5b6a19b5bc606ee595a Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 10 Apr 2011 15:27:05 -0500 Subject: [PATCH 095/151] update Gemfile to address build issues with 1.9.1 --- Gemfile | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index a3c0f34027..c65513c061 100644 --- a/Gemfile +++ b/Gemfile @@ -21,17 +21,14 @@ gem "growl", "1.0.3" gem "ZenTest", "~> 4.4.2" gem "nokogiri", "1.4.4" -if RUBY_PLATFORM =~ /darwin/ - gem "autotest-fsevent", "~> 0.2.4" - gem "autotest-growl", "~> 0.2.9" +platforms :mri_18 do + gem 'ruby-debug' end -gem "ruby-debug", :platforms => [:mri_18, :jruby] -gem "ruby-debug19", "~> 0.11.6", :platforms => :mri_19 - -case RUBY_VERSION - when '1.9.1'; gem 'ruby-debug-base19', '0.11.23' - when '1.9.2'; gem 'ruby-debug-base19', '0.11.24' +platforms :mri_19 do + gem 'linecache19', '0.5.11' # 0.5.12 cannot install on 1.9.1, and 0.5.11 appears to work with both 1.9.1 & 1.9.2 + gem 'ruby-debug19' + gem 'ruby-debug-base19', RUBY_VERSION == '1.9.1' ? '0.11.23' : '~> 0.11.24' end platforms :mri_18, :mri_19 do From 851d19993e117c10a35dc07624bab35145eda3b6 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 10 Apr 2011 17:50:20 -0500 Subject: [PATCH 096/151] add travis build status --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f33709f193..6ba3f148e5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # RSpec Core -Behaviour Driven Development for Ruby +RSpec Core provides the structure for writing executable examples of how your +code should behave. + +[![build status](http://travis-ci.org/rspec/rspec-core.png)](http://travis-ci.org/rspec/rspec-core) ## Documentation From 644e372968cd2f6aa641eb3584e87fb091a4e3c9 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 13 Apr 2011 06:56:04 -0500 Subject: [PATCH 097/151] Correctly pass/fail pending block with message expectations - Closes #257 --- .../use_flexmock.feature | 94 +++++++++++++++--- .../use_mocha.feature | 95 +++++++++++++++--- .../mock_framework_integration/use_rr.feature | 97 ++++++++++++++++--- .../use_rspec.feature | 95 +++++++++++++++--- lib/rspec/core/pending.rb | 7 +- .../core/formatters/html_formatted-1.8.6.html | 10 +- .../core/formatters/html_formatted-1.8.7.html | 10 +- .../core/formatters/html_formatted-1.9.1.html | 10 +- .../core/formatters/html_formatted-1.9.2.html | 10 +- .../formatters/text_mate_formatted-1.8.6.html | 10 +- .../formatters/text_mate_formatted-1.8.7.html | 10 +- .../formatters/text_mate_formatted-1.9.1.html | 52 +++++----- .../formatters/text_mate_formatted-1.9.2.html | 10 +- spec/rspec/core/pending_example_spec.rb | 14 ++- 14 files changed, 407 insertions(+), 117 deletions(-) diff --git a/features/mock_framework_integration/use_flexmock.feature b/features/mock_framework_integration/use_flexmock.feature index f6da8274c6..ab25a52184 100644 --- a/features/mock_framework_integration/use_flexmock.feature +++ b/features/mock_framework_integration/use_flexmock.feature @@ -1,28 +1,96 @@ Feature: mock with flexmock - As an RSpec user who likes to mock - I want to be able to use flexmock + Configure RSpec to use flexmock as shown in the scenarios below. - Scenario: Mock with flexmock - Given a file named "flexmock_example_spec.rb" with: + Scenario: passing message expectation + Given a file named "example_spec.rb" with: """ RSpec.configure do |config| config.mock_framework = :flexmock end - describe "plugging in flexmock" do - it "allows flexmock to be used" do - target = Object.new - flexmock(target).should_receive(:foo).once - target.foo + describe "mocking with RSpec" do + it "passes when it should" do + receiver = flexmock('receiver') + receiver.should_receive(:message).once + receiver.message end + end + """ + When I run `rspec example_spec.rb` + Then the examples should all pass + + Scenario: failing message expecation + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :flexmock + end + + describe "mocking with RSpec" do + it "fails when it should" do + receiver = flexmock('receiver') + receiver.should_receive(:message).once + end + end + """ + When I run `rspec example_spec.rb` + Then the output should contain "1 example, 1 failure" + + Scenario: failing message expectation in pending block (remains pending) + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :flexmock + end + + describe "failed message expectation in a pending block" do + it "is listed as pending" do + pending do + receiver = flexmock('receiver') + receiver.should_receive(:message).once + end + end + end + """ + When I run `rspec example_spec.rb` + Then the output should contain "1 example, 0 failures, 1 pending" + And the exit status should be 0 + + Scenario: passing message expectation in pending block (fails) + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :flexmock + end - describe "RSpec.configuration.mock_framework.framework_name" do - it "returns :flexmock" do - RSpec.configuration.mock_framework.framework_name.should eq(:flexmock) + describe "passing message expectation in a pending block" do + it "fails with FIXED" do + pending do + receiver = flexmock('receiver') + receiver.should_receive(:message).once + receiver.message end end end """ - When I run `rspec ./flexmock_example_spec.rb` + When I run `rspec example_spec.rb` + Then the output should contain "FIXED" + Then the output should contain "1 example, 1 failure" + And the exit status should be 1 + + Scenario: accessing RSpec.configuration.mock_framework.framework_name + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :flexmock + end + + describe "RSpec.configuration.mock_framework.framework_name" do + it "returns :flexmock" do + RSpec.configuration.mock_framework.framework_name.should eq(:flexmock) + end + end + """ + When I run `rspec example_spec.rb` Then the examples should all pass diff --git a/features/mock_framework_integration/use_mocha.feature b/features/mock_framework_integration/use_mocha.feature index 75972e8cac..c1595166c2 100644 --- a/features/mock_framework_integration/use_mocha.feature +++ b/features/mock_framework_integration/use_mocha.feature @@ -1,28 +1,97 @@ Feature: mock with mocha - As an RSpec user who likes to mock - I want to be able to use mocha + Configure RSpec to use mocha as shown in the scenarios below. - Scenario: Mock with mocha - Given a file named "mocha_example_spec.rb" with: + Scenario: passing message expectation + Given a file named "example_spec.rb" with: """ RSpec.configure do |config| config.mock_framework = :mocha end - describe "plugging in mocha" do - it "allows mocha to be used" do - target = Object.new - target.expects(:foo).once - target.foo + describe "mocking with RSpec" do + it "passes when it should" do + receiver = mock('receiver') + receiver.expects(:message).once + receiver.message end + end + """ + When I run `rspec example_spec.rb` + Then the examples should all pass + + Scenario: failing message expecation + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :mocha + end - describe "RSpec.configuration.mock_framework.framework_name" do - it "returns :mocha" do - RSpec.configuration.mock_framework.framework_name.should eq(:mocha) + describe "mocking with RSpec" do + it "fails when it should" do + receiver = mock('receiver') + receiver.expects(:message).once + end + end + """ + When I run `rspec example_spec.rb` + Then the output should contain "1 example, 1 failure" + + Scenario: failing message expectation in pending block (remains pending) + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :mocha + end + + describe "failed message expectation in a pending block" do + it "is listed as pending" do + pending do + receiver = mock('receiver') + receiver.expects(:message).once end end end """ - When I run `rspec ./mocha_example_spec.rb` + When I run `rspec example_spec.rb` + Then the output should contain "1 example, 0 failures, 1 pending" + And the exit status should be 0 + + Scenario: passing message expectation in pending block (fails) + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :mocha + end + + describe "passing message expectation in a pending block" do + it "fails with FIXED" do + pending do + receiver = mock('receiver') + receiver.expects(:message).once + receiver.message + end + end + end + """ + When I run `rspec example_spec.rb` + Then the output should contain "FIXED" + Then the output should contain "1 example, 1 failure" + And the exit status should be 1 + + Scenario: accessing RSpec.configuration.mock_framework.framework_name + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :mocha + end + + describe "RSpec.configuration.mock_framework.framework_name" do + it "returns :mocha" do + RSpec.configuration.mock_framework.framework_name.should eq(:mocha) + end + end + """ + When I run `rspec example_spec.rb` Then the examples should all pass + diff --git a/features/mock_framework_integration/use_rr.feature b/features/mock_framework_integration/use_rr.feature index e279f9d6b3..c3cf175e05 100644 --- a/features/mock_framework_integration/use_rr.feature +++ b/features/mock_framework_integration/use_rr.feature @@ -1,29 +1,98 @@ -@no-jruby Feature: mock with rr - As an RSpec user who likes to mock - I want to be able to use rr + Configure RSpec to use rr as shown in the scenarios below. - Scenario: Mock with rr - Given a file named "rr_example_spec.rb" with: + Scenario: passing message expectation + Given a file named "example_spec.rb" with: """ RSpec.configure do |config| config.mock_framework = :rr end - describe "plugging in rr" do - it "allows rr to be used" do - target = Object.new - mock(target).foo - target.foo + describe "mocking with RSpec" do + it "passes when it should" do + receiver = Object.new + mock(receiver).message + receiver.message end + end + """ + When I run `rspec example_spec.rb` + Then the examples should all pass + + Scenario: failing message expecation + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :rr + end + + describe "mocking with RSpec" do + it "fails when it should" do + receiver = Object.new + mock(receiver).message + end + end + """ + When I run `rspec example_spec.rb` + Then the output should contain "1 example, 1 failure" + + Scenario: failing message expectation in pending block (remains pending) + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :rr + end + + describe "failed message expectation in a pending block" do + it "is listed as pending" do + pending do + receiver = Object.new + mock(receiver).message + end + end + end + """ + When I run `rspec example_spec.rb` + Then the output should contain "1 example, 0 failures, 1 pending" + And the exit status should be 0 + + Scenario: passing message expectation in pending block (fails) + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :rr + end - describe "RSpec.configuration.mock_framework.framework_name" do - it "returns :rr" do - RSpec.configuration.mock_framework.framework_name.should eq(:rr) + describe "passing message expectation in a pending block" do + it "fails with FIXED" do + pending do + receiver = Object.new + mock(receiver).message + receiver.message end end end """ - When I run `rspec rr_example_spec.rb` + When I run `rspec example_spec.rb` + Then the output should contain "FIXED" + Then the output should contain "1 example, 1 failure" + And the exit status should be 1 + + Scenario: accessing RSpec.configuration.mock_framework.framework_name + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :rr + end + + describe "RSpec.configuration.mock_framework.framework_name" do + it "returns :rr" do + RSpec.configuration.mock_framework.framework_name.should eq(:rr) + end + end + """ + When I run `rspec example_spec.rb` Then the examples should all pass + + diff --git a/features/mock_framework_integration/use_rspec.feature b/features/mock_framework_integration/use_rspec.feature index c3da137e03..79d44214db 100644 --- a/features/mock_framework_integration/use_rspec.feature +++ b/features/mock_framework_integration/use_rspec.feature @@ -1,28 +1,97 @@ Feature: mock with rspec - As an RSpec user who likes to mock - I want to be able to use rspec + RSpec uses its own mocking framework by default, or you can configure it + explicitly. - Scenario: Mock with rspec - Given a file named "rspec_example_spec.rb" with: + Scenario: passing message expectation + Given a file named "example_spec.rb" with: """ RSpec.configure do |config| config.mock_framework = :rspec end - describe "plugging in rspec" do - it "allows rspec to be used" do - target = mock('target') - target.should_receive(:foo) - target.foo + describe "mocking with RSpec" do + it "passes when it should" do + receiver = double('receiver') + receiver.should_receive(:message) + receiver.message end + end + """ + When I run `rspec example_spec.rb` + Then the examples should all pass + + Scenario: failing message expecation + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :rspec + end + + describe "mocking with RSpec" do + it "fails when it should" do + receiver = double('receiver') + receiver.should_receive(:message) + end + end + """ + When I run `rspec example_spec.rb` + Then the output should contain "1 example, 1 failure" + + Scenario: failing message expectation in pending block (remains pending) + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :rspec + end + + describe "failed message expectation in a pending block" do + it "is listed as pending" do + pending do + receiver = double('receiver') + receiver.should_receive(:message) + end + end + end + """ + When I run `rspec example_spec.rb` + Then the output should contain "1 example, 0 failures, 1 pending" + And the exit status should be 0 + + Scenario: passing message expectation in pending block (fails) + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :rspec + end - describe "RSpec.configuration.mock_framework.framework_name" do - it "returns :rspec" do - RSpec.configuration.mock_framework.framework_name.should eq(:rspec) + describe "passing message expectation in a pending block" do + it "fails with FIXED" do + pending do + receiver = double('receiver') + receiver.should_receive(:message) + receiver.message end end end """ - When I run `rspec ./rspec_example_spec.rb` + When I run `rspec example_spec.rb` + Then the output should contain "FIXED" + Then the output should contain "1 example, 1 failure" + And the exit status should be 1 + + Scenario: accessing RSpec.configuration.mock_framework.framework_name + Given a file named "example_spec.rb" with: + """ + RSpec.configure do |config| + config.mock_framework = :rspec + end + + describe "RSpec.configuration.mock_framework.framework_name" do + it "returns :rspec" do + RSpec.configuration.mock_framework.framework_name.should eq(:rspec) + end + end + """ + When I run `rspec example_spec.rb` Then the examples should all pass diff --git a/lib/rspec/core/pending.rb b/lib/rspec/core/pending.rb index f99efaf547..fd7099e649 100644 --- a/lib/rspec/core/pending.rb +++ b/lib/rspec/core/pending.rb @@ -19,9 +19,14 @@ def pending(*args) example.metadata[:execution_result][:pending_message] = message if block_given? begin - result = yield + result = begin + yield + example.example_group_instance.instance_eval { verify_mocks_for_rspec } + end example.metadata[:pending] = false rescue Exception + ensure + teardown_mocks_for_rspec end raise RSpec::Core::PendingExampleFixedError.new if result end diff --git a/spec/rspec/core/formatters/html_formatted-1.8.6.html b/spec/rspec/core/formatters/html_formatted-1.8.6.html index cae22540f0..8285cbc9d4 100644 --- a/spec/rspec/core/formatters/html_formatted-1.8.6.html +++ b/spec/rspec/core/formatters/html_formatted-1.8.6.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46 ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' ./spec/rspec/core/formatters/html_formatter_spec.rb:45
-
24          rescue Exception
-25          end
-26          raise RSpec::Core::PendingExampleFixedError.new if result
-27        end
-28        raise PendingDeclaredInExample.new(message)
+
29            teardown_mocks_for_rspec
+30          end
+31          raise RSpec::Core::PendingExampleFixedError.new if result
+32        end
+33        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/html_formatted-1.8.7.html b/spec/rspec/core/formatters/html_formatted-1.8.7.html index cae22540f0..8285cbc9d4 100644 --- a/spec/rspec/core/formatters/html_formatted-1.8.7.html +++ b/spec/rspec/core/formatters/html_formatted-1.8.7.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46 ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' ./spec/rspec/core/formatters/html_formatter_spec.rb:45 -
24          rescue Exception
-25          end
-26          raise RSpec::Core::PendingExampleFixedError.new if result
-27        end
-28        raise PendingDeclaredInExample.new(message)
+
29            teardown_mocks_for_rspec
+30          end
+31          raise RSpec::Core::PendingExampleFixedError.new if result
+32        end
+33        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/html_formatted-1.9.1.html b/spec/rspec/core/formatters/html_formatted-1.9.1.html index bb02f09a07..1c7d802533 100644 --- a/spec/rspec/core/formatters/html_formatted-1.9.1.html +++ b/spec/rspec/core/formatters/html_formatted-1.9.1.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46:in `block (4 levels) in ' ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `block (3 levels) in ' -
24          rescue Exception
-25          end
-26          raise RSpec::Core::PendingExampleFixedError.new if result
-27        end
-28        raise PendingDeclaredInExample.new(message)
+
29            teardown_mocks_for_rspec
+30          end
+31          raise RSpec::Core::PendingExampleFixedError.new if result
+32        end
+33        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/html_formatted-1.9.2.html b/spec/rspec/core/formatters/html_formatted-1.9.2.html index bb02f09a07..1c7d802533 100644 --- a/spec/rspec/core/formatters/html_formatted-1.9.2.html +++ b/spec/rspec/core/formatters/html_formatted-1.9.2.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/html_formatter_spec.rb:46:in `block (4 levels) in ' ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `chdir' ./spec/rspec/core/formatters/html_formatter_spec.rb:45:in `block (3 levels) in ' -
24          rescue Exception
-25          end
-26          raise RSpec::Core::PendingExampleFixedError.new if result
-27        end
-28        raise PendingDeclaredInExample.new(message)
+
29            teardown_mocks_for_rspec
+30          end
+31          raise RSpec::Core::PendingExampleFixedError.new if result
+32        end
+33        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html b/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html index a3cb2a4752..0c89666ac2 100644 --- a/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html +++ b/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `chdir' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 -
24          rescue Exception
-25          end
-26          raise RSpec::Core::PendingExampleFixedError.new if result
-27        end
-28        raise PendingDeclaredInExample.new(message)
+
29            teardown_mocks_for_rspec
+30          end
+31          raise RSpec::Core::PendingExampleFixedError.new if result
+32        end
+33        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html b/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html index a3cb2a4752..0c89666ac2 100644 --- a/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +++ b/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `chdir' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 -
24          rescue Exception
-25          end
-26          raise RSpec::Core::PendingExampleFixedError.new if result
-27        end
-28        raise PendingDeclaredInExample.new(message)
+
29            teardown_mocks_for_rspec
+30          end
+31          raise RSpec::Core::PendingExampleFixedError.new if result
+32        end
+33        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html b/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html index a43768e66a..2b555237a3 100644 --- a/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html +++ b/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html @@ -312,18 +312,18 @@

RSpec Code Examples

fails
RSpec::Core::PendingExampleFixedError
- -
24          rescue Exception
-25          end
-26          raise RSpec::Core::PendingExampleFixedError.new if result
-27        end
-28        raise PendingDeclaredInExample.new(message)
+ +
29            teardown_mocks_for_rspec
+30          end
+31          raise RSpec::Core::PendingExampleFixedError.new if result
+32        end
+33        raise PendingDeclaredInExample.new(message)
@@ -350,13 +350,13 @@

RSpec Code Examples

(compared using ==) - +
27        end
 28
 29        raise(RSpec::Expectations::ExpectationNotMetError.new(message))
@@ -376,13 +376,13 @@ 

RSpec Code Examples

-1# Couldn't get snippet for (erb)
diff --git a/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html b/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html index 4c408b42d3..2b555237a3 100644 --- a/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +++ b/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html @@ -319,11 +319,11 @@

RSpec Code Examples

./spec/rspec/core/formatters/text_mate_formatter_spec.rb:47 :in `block (4 levels) in ' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `chdir' ./spec/rspec/core/formatters/text_mate_formatter_spec.rb:46 :in `block (3 levels) in ' -
24          rescue Exception
-25          end
-26          raise RSpec::Core::PendingExampleFixedError.new if result
-27        end
-28        raise PendingDeclaredInExample.new(message)
+
29            teardown_mocks_for_rspec
+30          end
+31          raise RSpec::Core::PendingExampleFixedError.new if result
+32        end
+33        raise PendingDeclaredInExample.new(message)
diff --git a/spec/rspec/core/pending_example_spec.rb b/spec/rspec/core/pending_example_spec.rb index f68fe1f6ab..52900a25a6 100644 --- a/spec/rspec/core/pending_example_spec.rb +++ b/spec/rspec/core/pending_example_spec.rb @@ -72,10 +72,10 @@ end context "with a block" do - def run_example(*pending_args) + def run_example(*pending_args, &block) group = RSpec::Core::ExampleGroup.describe('group') do it "does something" do - pending(*pending_args) { yield } + pending(*pending_args) { block.call if block } end end example = group.examples.first @@ -133,6 +133,16 @@ def run_example(*pending_args) end end + context "that fails due to a failed message expectation" do + def run_example(*pending_args) + super(*pending_args) { "foo".should_receive(:bar) } + end + + it "passes" do + run_example("just because").should be_pending + end + end + context "that passes" do def run_example(*pending_args) super(*pending_args) { 3.should == 3 } From 7169b5686f82dc74638a7fa5783b340385d5cafc Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 13 Apr 2011 06:58:08 -0500 Subject: [PATCH 098/151] changelog --- features/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/features/Changelog.md b/features/Changelog.md index 311f8afb7e..dbfd0adae3 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -31,6 +31,7 @@ * Fix bug where mixing nested groups and outer-level examples gave unpredictable :line_number behavior (Artur Małecki) * Regexp.escape the argument to --example (tip from Elliot Winkler) + * Correctly pass/fail pending block with message expectations ### 2.5.1 / 2011-02-06 From 44d305c9dac197982bdb8fd7adfc9297c592e3a2 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Fri, 15 Apr 2011 06:35:35 -0500 Subject: [PATCH 099/151] add parens to silence warning --- spec/rspec/core/hooks_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/rspec/core/hooks_spec.rb b/spec/rspec/core/hooks_spec.rb index ff59502f81..5d9486d24c 100644 --- a/spec/rspec/core/hooks_spec.rb +++ b/spec/rspec/core/hooks_spec.rb @@ -135,7 +135,7 @@ def yielder it "requires a block" do lambda { Hooks::BeforeHook.new :foo => :bar - }.should raise_error "no block given for before hook" + }.should raise_error("no block given for before hook") end end end From 9e9129117003c4de91d32ff285b749898318d05f Mon Sep 17 00:00:00 2001 From: Rodrigo Rosenfeld Rosas Date: Fri, 15 Apr 2011 18:52:11 -0500 Subject: [PATCH 100/151] Refactoring of ConfigurationOptions#parse_options - Closes #346. --- features/Changelog.md | 1 + lib/rspec/core/configuration_options.rb | 26 ++++++------------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index dbfd0adae3..da627595a8 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -16,6 +16,7 @@ defined. (Myron Marston) * Pass the exit status of a DRb run to the invoking process. This causes specs run via DRb to not just return true or false. (Ilkka Laukkanen) + * Refactoring of ConfigurationOptions#parse_options (Rodrigo Rosenfeld Rosas) * Bug fixes * Don't stumble over an exception without a message (Hans Hasselberg) diff --git a/lib/rspec/core/configuration_options.rb b/lib/rspec/core/configuration_options.rb index 468e6b5367..81f7d77100 100644 --- a/lib/rspec/core/configuration_options.rb +++ b/lib/rspec/core/configuration_options.rb @@ -57,35 +57,21 @@ def drb_argv end def parse_options - @options = begin - options_to_merge = [] - if custom_options_file - options_to_merge << custom_options - else - options_to_merge << global_options - options_to_merge << local_options - end - options_to_merge << command_line_options - options_to_merge << env_options - - options_to_merge.inject do |merged, options| - merged.merge(options) - end - end + @options ||= [file_options, command_line_options, env_options].inject {|merged, o| merged.merge o} end private + def file_options + custom_options_file ? custom_options : global_options.merge(local_options) + end + def env_options ENV["SPEC_OPTS"] ? Parser.parse!(ENV["SPEC_OPTS"].split) : {} end def command_line_options - @command_line_options ||= begin - options = Parser.parse!(@args) - options[:files_or_directories_to_run] = @args - options - end + @command_line_options ||= Parser.parse!(@args).merge :files_or_directories_to_run => @args end def custom_options From 029e6972fcf719542deff1b2619d2945146e84da Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sat, 16 Apr 2011 06:20:41 -0500 Subject: [PATCH 101/151] use the names shared_examples and shared_context in the features --- features/example_groups/shared_context.feature | 2 +- features/example_groups/shared_example_group.feature | 8 ++++---- lib/rspec/core/shared_example_group.rb | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/features/example_groups/shared_context.feature b/features/example_groups/shared_context.feature index b99f385528..bb1d532e57 100644 --- a/features/example_groups/shared_context.feature +++ b/features/example_groups/shared_context.feature @@ -18,7 +18,7 @@ Feature: shared context end end - shared_examples_for "group including shared context" do + shared_examples "group including shared context" do it "has access to methods defined in shared context" do shared_method.should eq("it works") end diff --git a/features/example_groups/shared_example_group.feature b/features/example_groups/shared_example_group.feature index 303bfbacc6..62c7d71b56 100644 --- a/features/example_groups/shared_example_group.feature +++ b/features/example_groups/shared_example_group.feature @@ -13,7 +13,7 @@ Feature: shared example group """ require "set" - shared_examples_for "a collection" do + shared_examples "a collection" do let(:collection) { described_class.new([7, 2, 4]) } context "initialized with 3 items" do @@ -75,7 +75,7 @@ Feature: shared example group """ require "set" - shared_examples_for "a collection object" do + shared_examples "a collection object" do describe "<<" do it "adds objects to the end of the collection" do collection << 1 @@ -115,7 +115,7 @@ Feature: shared example group Scenario: Passing parameters to a shared example group Given a file named "shared_example_group_params_spec.rb" with: """ - shared_examples_for "a measurable object" do |measurement, measurement_methods| + shared_examples "a measurable object" do |measurement, measurement_methods| measurement_methods.each do |measurement_method| it "should return #{measurement} from ##{measurement_method}" do subject.send(measurement_method).should == measurement @@ -155,7 +155,7 @@ Feature: shared example group c.alias_it_should_behave_like_to :it_has_behavior, 'has behavior:' end - shared_examples_for 'sortability' do + shared_examples 'sortability' do it 'responds to <=>' do sortable.should respond_to(:<=>) end diff --git a/lib/rspec/core/shared_example_group.rb b/lib/rspec/core/shared_example_group.rb index a96f48f87c..3bc5f48bff 100644 --- a/lib/rspec/core/shared_example_group.rb +++ b/lib/rspec/core/shared_example_group.rb @@ -2,7 +2,7 @@ module RSpec module Core module SharedExampleGroup - def share_examples_for(*args, &block) + def shared_context(*args, &block) if String === args.first || Symbol === args.first name = args.shift ensure_shared_example_group_name_not_taken(name) @@ -19,9 +19,9 @@ def share_examples_for(*args, &block) end end - alias :shared_examples_for :share_examples_for - alias :shared_examples :share_examples_for - alias :shared_context :share_examples_for + alias :shared_examples :shared_context + alias :share_examples_for :shared_context + alias :shared_examples_for :shared_context def share_as(name, &block) if Object.const_defined?(name) From eae6b4384e71ba391750c0b8bd0ca6d724718202 Mon Sep 17 00:00:00 2001 From: Pat Maddox Date: Sat, 16 Apr 2011 11:38:35 -0700 Subject: [PATCH 102/151] Report the exclusion filter --- features/command_line/tag.feature | 10 ++++++++++ lib/rspec/core/world.rb | 2 ++ 2 files changed, 12 insertions(+) diff --git a/features/command_line/tag.feature b/features/command_line/tag.feature index aaa05467e0..c06008fd4e 100644 --- a/features/command_line/tag.feature +++ b/features/command_line/tag.feature @@ -58,17 +58,27 @@ Feature: --tag option Scenario: exclude examples with a simple tag When I run `rspec . --tag ~skip` + Then the output should contain "Run filtered excluding {:skip=>true}" Then the examples should all pass Scenario: exclude examples with a simple tag and @ When I run `rspec . --tag ~@skip` + Then the output should contain "Run filtered excluding {:skip=>true}" Then the examples should all pass Scenario: exclude examples with a name:value tag When I run `rspec . --tag ~speed:slow` + Then the output should contain: + """ + Run filtered excluding {:speed=>"slow"} + """ Then the examples should all pass Scenario: exclude examples with a name:value tag and @ When I run `rspec . --tag ~@speed:slow` + Then the output should contain: + """ + Run filtered excluding {:speed=>"slow"} + """ Then the examples should all pass diff --git a/lib/rspec/core/world.rb b/lib/rspec/core/world.rb index 78910aab83..c304c954e1 100644 --- a/lib/rspec/core/world.rb +++ b/lib/rspec/core/world.rb @@ -76,6 +76,8 @@ def announce_exclusion_filter @configuration.reporter.message( "No examples were matched. Perhaps #{exclusion_filter.inspect} is excluding everything?") example_groups.clear + else + @configuration.reporter.message "Run filtered excluding #{exclusion_filter.inspect}" end end From 36237841db72eeb7797f199ad0fa057e36e26b40 Mon Sep 17 00:00:00 2001 From: Pat Maddox Date: Sat, 16 Apr 2011 11:51:27 -0700 Subject: [PATCH 103/151] Report exclusion filters (closes #347) --- features/command_line/tag.feature | 4 ++++ lib/rspec/core/command_line.rb | 3 +-- lib/rspec/core/world.rb | 18 ++++++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/features/command_line/tag.feature b/features/command_line/tag.feature index c06008fd4e..09547841ab 100644 --- a/features/command_line/tag.feature +++ b/features/command_line/tag.feature @@ -82,3 +82,7 @@ Feature: --tag option """ Then the examples should all pass + Scenario: filter examples with a simple tag, exclude examples with another tag + When I run `rspec . --tag focus --tag ~skip` + Then the output should contain "Run filtered using {:focus=>true}, excluding {:skip=>true}" + And the examples should all pass diff --git a/lib/rspec/core/command_line.rb b/lib/rspec/core/command_line.rb index 297358b8f5..0b957eb1e9 100644 --- a/lib/rspec/core/command_line.rb +++ b/lib/rspec/core/command_line.rb @@ -16,8 +16,7 @@ def run(err, out) @configuration.output_stream ||= out @options.configure(@configuration) @configuration.load_spec_files - @world.announce_inclusion_filter - @world.announce_exclusion_filter + @world.announce_filters @configuration.reporter.report(@world.example_count) do |reporter| begin diff --git a/lib/rspec/core/world.rb b/lib/rspec/core/world.rb index c304c954e1..7a18490c1b 100644 --- a/lib/rspec/core/world.rb +++ b/lib/rspec/core/world.rb @@ -59,25 +59,35 @@ def preceding_declaration_line(filter_line) end end - def announce_inclusion_filter + def announce_filters + filter_announcements = [] + announce_inclusion_filter filter_announcements + announce_exclusion_filter filter_announcements + + unless filter_announcements.empty? + @configuration.reporter.message("Run filtered #{filter_announcements.join(', ')}") + end + end + + def announce_inclusion_filter(announcements) if inclusion_filter if @configuration.run_all_when_everything_filtered? && RSpec.world.example_count.zero? @configuration.reporter.message "No examples were matched by #{inclusion_filter.inspect}, running all" @configuration.clear_inclusion_filter filtered_examples.clear else - @configuration.reporter.message "Run filtered using #{inclusion_filter.inspect}" + announcements << "using #{inclusion_filter.inspect}" end end end - def announce_exclusion_filter + def announce_exclusion_filter(announcements) if exclusion_filter && RSpec.world.example_count.zero? @configuration.reporter.message( "No examples were matched. Perhaps #{exclusion_filter.inspect} is excluding everything?") example_groups.clear else - @configuration.reporter.message "Run filtered excluding #{exclusion_filter.inspect}" + announcements << "excluding #{exclusion_filter.inspect}" end end From 03a13bcdf21eeae059b2c535338465c7b212f126 Mon Sep 17 00:00:00 2001 From: Pat Maddox Date: Sat, 16 Apr 2011 12:28:15 -0700 Subject: [PATCH 104/151] whoops forgot to commit updated feature --- features/filtering/if_and_unless.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/filtering/if_and_unless.feature b/features/filtering/if_and_unless.feature index 4ee772da84..fd55667aa6 100644 --- a/features/filtering/if_and_unless.feature +++ b/features/filtering/if_and_unless.feature @@ -162,5 +162,7 @@ Feature: :if and :unless | :if => false example | | :unless => true example | | :unless => false example | - And the output should not contain "exclude_me" + And the output should not contain any of these: + | :if => :exclude_me example | + | :unless => :exclude_me_for_unless example | From 87a0f3890473357918b0b88753094d7a84893d71 Mon Sep 17 00:00:00 2001 From: Pat Maddox Date: Sat, 16 Apr 2011 12:42:41 -0700 Subject: [PATCH 105/151] words --- features/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/features/Changelog.md b/features/Changelog.md index da627595a8..aab1e72641 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -17,6 +17,7 @@ * Pass the exit status of a DRb run to the invoking process. This causes specs run via DRb to not just return true or false. (Ilkka Laukkanen) * Refactoring of ConfigurationOptions#parse_options (Rodrigo Rosenfeld Rosas) + * Report excluded filters in runner output * Bug fixes * Don't stumble over an exception without a message (Hans Hasselberg) From f7ff6c0d059231ea7f196bffda5a76044a2c8f95 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Sun, 17 Apr 2011 13:00:25 -0500 Subject: [PATCH 106/151] Give credit. --- features/Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/Changelog.md b/features/Changelog.md index aab1e72641..6e2e718185 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -17,7 +17,7 @@ * Pass the exit status of a DRb run to the invoking process. This causes specs run via DRb to not just return true or false. (Ilkka Laukkanen) * Refactoring of ConfigurationOptions#parse_options (Rodrigo Rosenfeld Rosas) - * Report excluded filters in runner output + * Report excluded filters in runner output (tip from andyl) * Bug fixes * Don't stumble over an exception without a message (Hans Hasselberg) From 5e035eadad47819017143c568dd3cf58c0f87ce6 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 17 Apr 2011 12:45:18 -0500 Subject: [PATCH 107/151] Add shared_examples/include_examples pair. Now we have: shared_examples / include_examples shared_context / include_context These actually do the same thing, but the names make different use cases more intention revealing. --- lib/rspec/core/example_group.rb | 4 ++++ spec/rspec/core/example_group_spec.rb | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 8b0089e6fb..8b28c080a9 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -93,6 +93,10 @@ def self.include_context(name) module_eval(&world.shared_example_groups[name]) end + class << self + alias_method :include_examples, :include_context + end + def self.examples @examples ||= [] end diff --git a/spec/rspec/core/example_group_spec.rb b/spec/rspec/core/example_group_spec.rb index 42bdee1df1..b84988ed67 100644 --- a/spec/rspec/core/example_group_spec.rb +++ b/spec/rspec/core/example_group_spec.rb @@ -820,5 +820,21 @@ def foo; 'foo'; end end end + describe "#include_examples" do + before do + shared_examples "named this" do + example("does something") do + end + end + end + + it "includes the named examples" do + group = ExampleGroup.describe do + include_examples "named this" + end + group.examples.first.description.should eq("does something") + end + end + end end From 98f811deb28dc1ecf15fb9cec08673c2f480cff4 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 17 Apr 2011 14:14:45 -0500 Subject: [PATCH 108/151] doc tweaks --- .../example_groups/shared_context.feature | 105 +++++------------- .../shared_example_group.feature | 22 ++-- 2 files changed, 39 insertions(+), 88 deletions(-) diff --git a/features/example_groups/shared_context.feature b/features/example_groups/shared_context.feature index bb1d532e57..6259bfa1fd 100644 --- a/features/example_groups/shared_context.feature +++ b/features/example_groups/shared_context.feature @@ -3,9 +3,9 @@ Feature: shared context Use `shared_context` to define a block that will be evaluated in the context of example groups either explicitly, using `include_context`, or implicitly by matching metdata. - - Scenario: declare and use shared context with a string name - Given a file named "shared_context_spec.rb" with: + + Background: + Given a file named "shared_stuff.rb" with: """ shared_context "shared stuff", :a => :b do before { @some_var = :some_value } @@ -17,8 +17,16 @@ Feature: shared context 'this is the subject' end end + """ + + Scenario: declare shared context and include it with include_context + Given a file named "shared_context_example.rb" with: + """ + require "./shared_stuff.rb" + + describe "group that includes a shared context using 'include_context'" do + include_context "shared stuff" - shared_examples "group including shared context" do it "has access to methods defined in shared context" do shared_method.should eq("it works") end @@ -35,93 +43,32 @@ Feature: shared context subject.should eq('this is the subject') end end - - describe "group that includes a shared context using 'include_context'" do - include_context "shared stuff" - it_behaves_like "group including shared context" - end - - describe "group that includes a shared context using metadata", :a => :b do - it_behaves_like "group including shared context" - end - """ - When I run `rspec shared_context_spec.rb` - Then the output should contain "8 examples" - And the examples should all pass - - Scenario: share a method - Given a file named "shared_context_spec.rb" with: - """ - shared_context :type => :special do - def shared_method - "it works" - end - end - - describe "something", :type => :special do - it "access methods defined in configuration" do - shared_method.should eq("it works") - end - end """ - When I run `rspec shared_context_spec.rb` + When I run `rspec shared_context_example.rb` Then the examples should all pass - Scenario: share a `let` declaration - Given a file named "shared_context_spec.rb" with: + Scenario: declare shared context and include it with metadata + Given a file named "shared_context_example.rb" with: """ - shared_context :type => :special do - let(:method_defined_by_let_in_config) { "it works" } - end + require "./shared_stuff.rb" - describe "something", :type => :special do - it "access methods defined using let in configuration" do - method_defined_by_let_in_config.should eq("it works") + describe "group that includes a shared context using metadata", :a => :b do + it "has access to methods defined in shared context" do + shared_method.should eq("it works") end - end - """ - When I run `rspec shared_context_spec.rb` - Then the examples should all pass - Scenario: share a subject - Given a file named "shared_context_spec.rb" with: - """ - shared_context :type => :special do - subject { :subject_defined_in_configuration } - end - - describe "something", :type => :special do - it "uses the subject defined in configuration" do - subject.should be(:subject_defined_in_configuration) + it "has access to methods defined with let in shared context" do + shared_let['arbitrary'].should eq('object') end - end - """ - When I run `rspec shared_context_spec.rb` - Then the examples should all pass - - @wip - Scenario: Use symbols as metadata - Given a file named "use_symbols_as_metadata_spec.rb" with: - """ - RSpec.configure do |c| - c.treat_symbols_as_metadata_keys_with_true_values = true - end - - shared_context :special do - let(:help) { :available } - end - describe "something", :special do - it "accesses helper methods defined using `let` in the configuration" do - help.should be(:available) + it "runs the before hooks defined in the shared context" do + @some_var.should be(:some_value) end - end - describe "something else" do - it "cannot access helper methods defined using `let` in the configuration" do - expect { help }.to raise_error(NameError) + it "accesses the subject defined in the shared context" do + subject.should eq('this is the subject') end end """ - When I run `rspec use_symbols_as_metadata_spec.rb` + When I run `rspec shared_context_example.rb` Then the examples should all pass diff --git a/features/example_groups/shared_example_group.feature b/features/example_groups/shared_example_group.feature index 62c7d71b56..70c65ef74f 100644 --- a/features/example_groups/shared_example_group.feature +++ b/features/example_groups/shared_example_group.feature @@ -1,14 +1,18 @@ -Feature: shared example group +Feature: shared examples - Shared example groups let you describe behaviour of types or modules. When + Shared examples let you describe behaviour of types or modules. When declared, a shared group's content is stored. It is only realized in the context of another example group, which provides any context the shared group needs to run. - A shared group is included in another group using the it_behaves_like() or - it_should_behave_like() methods. + A shared group is included in another group using any of: + + include_examples "name" # include the examples in the current context - Scenario: shared example group applied to two groups + it_behaves_like "name" # include the examples in a nested context + it_should_behave_like "name" # include the examples in a nested context + + Scenario: shared examples group included in two groups Given a file named "collection_spec.rb" with: """ require "set" @@ -86,13 +90,13 @@ Feature: shared example group end describe Array do - it_should_behave_like "a collection object" do + it_behaves_like "a collection object" do let(:collection) { Array.new } end end describe Set do - it_should_behave_like "a collection object" do + it_behaves_like "a collection object" do let(:collection) { Set.new } end end @@ -102,12 +106,12 @@ Feature: shared example group And the output should contain: """ Array - it should behave like a collection object + behaves like a collection object << adds objects to the end of the collection Set - it should behave like a collection object + behaves like a collection object << adds objects to the end of the collection """ From 57fe719e68e36631427192109daa138d0fe483f1 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 17 Apr 2011 15:56:43 -0500 Subject: [PATCH 109/151] --tag key:value supports symbols and strings --- features/command_line/tag.feature | 4 +- lib/rspec/core/metadata.rb | 2 +- spec/rspec/core/example_group_spec.rb | 140 +++++++++++++++++++------- 3 files changed, 109 insertions(+), 37 deletions(-) diff --git a/features/command_line/tag.feature b/features/command_line/tag.feature index 09547841ab..8a71ae6c4f 100644 --- a/features/command_line/tag.feature +++ b/features/command_line/tag.feature @@ -19,7 +19,8 @@ Feature: --tag option """ describe "group with tagged specs" do it "example I'm working now", :focus => true do; end - it "special example", :type => 'special' do; end + it "special example with string", :type => 'special' do; end + it "special example with symbol", :type => :special do; end it "slow example", :skip => true do; end it "ordinary example", :speed => 'slow' do; end it "untagged example" do; end @@ -46,6 +47,7 @@ Feature: --tag option """ Run filtered using {:type=>"special"} """ + And the output should contain "2 examples" And the examples should all pass Scenario: filter examples with a name:value tag and @ diff --git a/lib/rspec/core/metadata.rb b/lib/rspec/core/metadata.rb index 65d2c7e292..795c2d4f18 100644 --- a/lib/rspec/core/metadata.rb +++ b/lib/rspec/core/metadata.rb @@ -142,7 +142,7 @@ def apply_condition(key, value, metadata=self) metadata[key] == value end else - metadata[key] == value + metadata[key].to_s == value.to_s end end diff --git a/spec/rspec/core/example_group_spec.rb b/spec/rspec/core/example_group_spec.rb index b84988ed67..7dce90a1d1 100644 --- a/spec/rspec/core/example_group_spec.rb +++ b/spec/rspec/core/example_group_spec.rb @@ -119,49 +119,119 @@ def metadata_hash(*args) describe "filtering" do let(:world) { World.new } - it "includes all examples in an explicitly included group" do - world.stub(:inclusion_filter).and_return({ :awesome => true }) - group = ExampleGroup.describe("does something", :awesome => true) - group.stub(:world) { world } - - examples = [ - group.example("first"), - group.example("second") - ] - group.filtered_examples.should == examples + shared_examples "matching filters" do + context "inclusion" do + before { world.stub(:inclusion_filter).and_return(filter_metadata) } + + it "includes examples in groups matching filter" do + group = ExampleGroup.describe("does something", spec_metadata) + group.stub(:world) { world } + all_examples = [ group.example("first"), group.example("second") ] + + group.filtered_examples.should == all_examples + end + + it "includes examples directly matching filter" do + group = ExampleGroup.describe("does something") + group.stub(:world) { world } + filtered_examples = [ + group.example("first", spec_metadata), + group.example("second", spec_metadata) + ] + group.example("third (not-filtered)") + + group.filtered_examples.should == filtered_examples + end + end + + context "exclusion" do + before { world.stub(:exclusion_filter).and_return(filter_metadata) } + it "excludes examples in groups matching filter" do + group = ExampleGroup.describe("does something", spec_metadata) + group.stub(:world) { world } + all_examples = [ group.example("first"), group.example("second") ] + + group.filtered_examples.should be_empty + end + + it "excludes examples directly matching filter" do + group = ExampleGroup.describe("does something") + group.stub(:world) { world } + filtered_examples = [ + group.example("first", spec_metadata), + group.example("second", spec_metadata) + ] + unfiltered_example = group.example("third (not-filtered)") + + group.filtered_examples.should == [unfiltered_example] + end + end end - it "includes explicitly included examples" do - world.stub(:inclusion_filter).and_return({ :include_me => true }) - group = ExampleGroup.describe - group.stub(:world) { world } - example = group.example("does something", :include_me => true) - group.example("don't run me") - group.filtered_examples.should == [example] + context "matching false" do + let(:spec_metadata) { { :awesome => false }} + + context "against false" do + let(:filter_metadata) { { :awesome => false }} + include_examples "matching filters" + end + + context "against 'false'" do + let(:filter_metadata) { { :awesome => 'false' }} + include_examples "matching filters" + end + + context "against :false" do + let(:filter_metadata) { { :awesome => :false }} + include_examples "matching filters" + end end - it "excludes all examples in an excluded group" do - world.stub(:exclusion_filter).and_return({ :include_me => false }) - group = ExampleGroup.describe("does something", :include_me => false) - group.stub(:world) { world } + context "matching true" do + let(:spec_metadata) { { :awesome => true }} - examples = [ - group.example("first"), - group.example("second") - ] - group.filtered_examples.should == [] + context "against true" do + let(:filter_metadata) { { :awesome => true }} + include_examples "matching filters" + end + + context "against 'true'" do + let(:filter_metadata) { { :awesome => 'true' }} + include_examples "matching filters" + end + + context "against :true" do + let(:filter_metadata) { { :awesome => :true }} + include_examples "matching filters" + end end - it "filters out excluded examples" do - world.stub(:exclusion_filter).and_return({ :exclude_me => true }) - group = ExampleGroup.describe("does something") - group.stub(:world) { world } + context "matching a string" do + let(:spec_metadata) { { :type => 'special' }} - examples = [ - group.example("first", :exclude_me => true), - group.example("second") - ] - group.filtered_examples.should == [examples[1]] + context "against a string" do + let(:filter_metadata) { { :type => 'special' }} + include_examples "matching filters" + end + + context "against a symbol" do + let(:filter_metadata) { { :type => :special }} + include_examples "matching filters" + end + end + + context "matching a symbol" do + let(:spec_metadata) { { :type => :special }} + + context "against a string" do + let(:filter_metadata) { { :type => 'special' }} + include_examples "matching filters" + end + + context "against a symbol" do + let(:filter_metadata) { { :type => :special }} + include_examples "matching filters" + end end context "with no filters" do From f10e8bbc3c9b97c190c7f5a8dab355d44c1ebac0 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 17 Apr 2011 19:00:02 -0500 Subject: [PATCH 110/151] prep for 2.6.0.rc1 --- Rakefile | 41 +++++++++++++++++++++++++++------------ lib/rspec/core/version.rb | 2 +- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Rakefile b/Rakefile index 4413a8c93a..96bdb961b7 100644 --- a/Rakefile +++ b/Rakefile @@ -8,13 +8,25 @@ require "yaml" require "rake/rdoctask" require "rspec/core/rake_task" require "rspec/core/version" -require "cucumber/rake/task" -class Cucumber::Rake::Task::ForkedCucumberRunner - # When cucumber shells out, we still need it to run in the context of our - # bundle. - def run - sh "bundle exec #{RUBY} " + args.join(" ") +cucumber_loaded = false +begin + require "cucumber/rake/task" + + Cucumber::Rake::Task.new(:cucumber) + + class Cucumber::Rake::Task::ForkedCucumberRunner + # When cucumber shells out, we still need it to run in the context of our + # bundle. + def run + sh "bundle exec #{RUBY} " + args.join(" ") + end + end + cucumber_loaded = true +rescue LoadError => e + puts "unable to load cucumber, some tasks unavailable" + task :cucumber do + # no-op end end @@ -25,7 +37,6 @@ RSpec::Core::RakeTask.new(:spec) do |t| t.verbose = false end -Cucumber::Rake::Task.new(:cucumber) namespace :rcov do task :cleanup do @@ -38,11 +49,17 @@ namespace :rcov do t.rcov_opts << %[--no-html --aggregate coverage.data] end - Cucumber::Rake::Task.new :cucumber do |t| - t.cucumber_opts = %w{--format progress} - t.rcov = true - t.rcov_opts = %[-Ilib -Ispec --exclude "gems/*,features"] - t.rcov_opts << %[--text-report --sort coverage --aggregate coverage.data] + if cucumber_loaded + Cucumber::Rake::Task.new :cucumber do |t| + t.cucumber_opts = %w{--format progress} + t.rcov = true + t.rcov_opts = %[-Ilib -Ispec --exclude "gems/*,features"] + t.rcov_opts << %[--text-report --sort coverage --aggregate coverage.data] + end + else + task :cucumber do + # no-op + end end end diff --git a/lib/rspec/core/version.rb b/lib/rspec/core/version.rb index 1f47efc8b2..8ddd43b003 100644 --- a/lib/rspec/core/version.rb +++ b/lib/rspec/core/version.rb @@ -1,7 +1,7 @@ module RSpec # :nodoc: module Core # :nodoc: module Version # :nodoc: - STRING = '2.5.1' + STRING = '2.6.0.rc1' end end end From 059aa960fc7d588bfbe720ccc35ebb25f43ed0df Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 17 Apr 2011 19:45:04 -0500 Subject: [PATCH 111/151] comment aruba/cukes in Gemfile --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index c65513c061..758479a0c7 100644 --- a/Gemfile +++ b/Gemfile @@ -12,8 +12,8 @@ end ### dev dependencies gem "rake", "0.8.7" -gem "cucumber", "~> 0.10.2" -gem "aruba", "~> 0.3.5" +# gem "cucumber", "~> 0.10.2" +# gem "aruba", :git => "git://github.com/aslakhellesoy/aruba" gem "rcov", "0.9.9", :platforms => :mri gem "relish", "0.2.0" gem "guard-rspec", "0.1.9" From bf3ca8c2a4b048ac66a7c5f93b5d42d5c743d9a0 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 17 Apr 2011 19:56:56 -0500 Subject: [PATCH 112/151] update changelog --- features/Changelog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index 6e2e718185..865ada72f6 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,6 +1,6 @@ -### dev +### 2.6.0.rc1 / 2011-04-17 -[full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...master) +[full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.1.rc1) * Enhancements * `shared_context` (Damian Nurzynski) From 422e3345d1879e93e6f754df1c91445bbdd7a577 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 18 Apr 2011 00:22:16 -0500 Subject: [PATCH 113/151] bump to 2.6.0.rc2 --- lib/rspec/core/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rspec/core/version.rb b/lib/rspec/core/version.rb index 8ddd43b003..1c856d2882 100644 --- a/lib/rspec/core/version.rb +++ b/lib/rspec/core/version.rb @@ -1,7 +1,7 @@ module RSpec # :nodoc: module Core # :nodoc: module Version # :nodoc: - STRING = '2.6.0.rc1' + STRING = '2.6.0.rc2' end end end From 0b63cc67719710678d308177b294815d4ae2a8d9 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 18 Apr 2011 00:29:47 -0500 Subject: [PATCH 114/151] update the changelog --- features/Changelog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index 865ada72f6..ee58b6ec6f 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,6 +1,6 @@ -### 2.6.0.rc1 / 2011-04-17 +### 2.6.0.rc2 / 2011-04-18 -[full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.1.rc1) +[full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.1.rc2) * Enhancements * `shared_context` (Damian Nurzynski) From 94908931d7e9bf6776bc8c2122f2eea870caaace Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 18 Apr 2011 23:03:31 -0500 Subject: [PATCH 115/151] reinstate cucumber and aruba --- Gemfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 758479a0c7..cc74df5fc0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source "http://rubygems.org" ### rspec libs -%w[rspec-core rspec-expectations rspec-mocks].each do |lib| +%w[rspec rspec-core rspec-expectations rspec-mocks].each do |lib| library_path = File.expand_path("../../#{lib}", __FILE__) if File.exist?(library_path) gem lib, :path => library_path @@ -10,10 +10,11 @@ source "http://rubygems.org" end end + ### dev dependencies gem "rake", "0.8.7" -# gem "cucumber", "~> 0.10.2" -# gem "aruba", :git => "git://github.com/aslakhellesoy/aruba" +gem "cucumber", "~> 0.10.2" +gem "aruba", "~> 0.3.6" gem "rcov", "0.9.9", :platforms => :mri gem "relish", "0.2.0" gem "guard-rspec", "0.1.9" From edb06bb65c7e42c886553c29ab78bb2e6df5bae6 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 18 Apr 2011 23:23:19 -0500 Subject: [PATCH 116/151] update docs --- features/Upgrade.md | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/features/Upgrade.md b/features/Upgrade.md index 36def50be6..ad897a2e39 100644 --- a/features/Upgrade.md +++ b/features/Upgrade.md @@ -1,3 +1,36 @@ +# rspec-core-2.6 + +## new APIs for sharing content + +Use `shared_context` together with `include_context` to share before/after +hooks, let declarations, and method definitions across example groups. + +Use `shared_examples` together with `include_examples` to share examples +across different contexts. + +All of the old APIs are still supported, but these 4 are easy to remember, and +serve most use cases. + +See `shared_context` and `shared_examples` under "Example Groups" for more +information. + +## `treat_symbols_as_metadata_keys_with_true_values` + +Yes it's a long name, but it's a great feature, and it's going to be the +default behavior in rspec-3. This lets you add metadata to a group or example +like this: + + describe "something", :awesome do + ... + +And then you can run that group (or example) using the tags feature: + + rspec spec --tag awesome + +We're making this an opt-in for rspec-2.6 because `describe "string", :symbol` +is a perfectly legal construct in pre-2.6 releases and we want to maintain +compatibility in minor releases as much as is possible. + # rspec-core-2.3 ## `config.expect_with` @@ -106,7 +139,7 @@ The most obvious use is for filtering the run. For example: end When you run the `rspec` command, rspec will run only the examples that have -`:focus => true` in the hash. +`:focus => true` in the hash. You can also add `run_all_when_everything_filtered` to the config: @@ -207,7 +240,7 @@ A few things changed in the Rake task used to run specs: the `rspec` command no longer supports the `--options` command line option so the options must be embedded directly in the Rakefile, or stored in the `.rspec` files mentioned above. - + 3. In RSpec-1, the rake task would read in rcov options from an `rcov.opts` file. This is ignored by RSpec-2. RCov options are now set directly on the Rake task: From fd5ef93bc9c13fd9f4f54a4f5af29b086c450f82 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 20 Apr 2011 07:54:23 -0500 Subject: [PATCH 117/151] doc updates --- features/Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/Changelog.md b/features/Changelog.md index ee58b6ec6f..6530601af6 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,6 +1,6 @@ ### 2.6.0.rc2 / 2011-04-18 -[full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.1.rc2) +[full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.0.rc2) * Enhancements * `shared_context` (Damian Nurzynski) From aecda56ccb7a859e7168eaf98305b9bcb82f8ede Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Wed, 20 Apr 2011 23:10:58 -0700 Subject: [PATCH 118/151] Improve the filter announcement messaging. - Don't include the default filters. - Remove the noisy hex number from procs. Closes #350. --- lib/rspec/core/configuration.rb | 28 +++++++++++++++--- lib/rspec/core/world.rb | 8 ++--- spec/rspec/core/configuration_spec.rb | 42 +++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index cc19d1ce36..404abeab7a 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -36,6 +36,11 @@ def self.add_setting(name, opts={}) add_setting :treat_symbols_as_metadata_keys_with_true_values, :default => false add_setting :expecting_with_rspec + DEFAULT_EXCLUSION_FILTERS = { + :if => lambda { |value, metadata| metadata.has_key?(:if) && !value }, + :unless => lambda { |value| value } + } + def initialize @color_enabled = false self.include_or_extend_modules = [] @@ -48,10 +53,7 @@ def initialize /lib\/rspec\/(core|expectations|matchers|mocks)/ ] - self.exclusion_filter = { - :if => lambda { |value, metadata| metadata.has_key?(:if) && !value }, - :unless => lambda { |value| value } - } + self.exclusion_filter = DEFAULT_EXCLUSION_FILTERS.dup end # :call-seq: @@ -335,6 +337,24 @@ def alias_it_should_behave_like_to(new_name, report_label = '') RSpec::Core::ExampleGroup.alias_it_should_behave_like_to(new_name, report_label) end + PROC_HEX_NUMBER = /0x[0-9a-f]+@/ + + def exclusion_filter=(filter) + def filter.description + reject { |k, v| DEFAULT_EXCLUSION_FILTERS[k] == v }.inspect.gsub(PROC_HEX_NUMBER, '') + end + + settings[:exclusion_filter] = filter + end + + def filter=(filter) + def filter.description + inspect.gsub(PROC_HEX_NUMBER, '') + end + + settings[:filter] = filter + end + def filter_run_including(*args) force_overwrite = if args.last.is_a?(Hash) || args.last.is_a?(Symbol) false diff --git a/lib/rspec/core/world.rb b/lib/rspec/core/world.rb index 7a18490c1b..fb885d01f4 100644 --- a/lib/rspec/core/world.rb +++ b/lib/rspec/core/world.rb @@ -72,11 +72,11 @@ def announce_filters def announce_inclusion_filter(announcements) if inclusion_filter if @configuration.run_all_when_everything_filtered? && RSpec.world.example_count.zero? - @configuration.reporter.message "No examples were matched by #{inclusion_filter.inspect}, running all" + @configuration.reporter.message "No examples were matched by #{inclusion_filter.description}, running all" @configuration.clear_inclusion_filter filtered_examples.clear else - announcements << "using #{inclusion_filter.inspect}" + announcements << "using #{inclusion_filter.description}" end end end @@ -84,10 +84,10 @@ def announce_inclusion_filter(announcements) def announce_exclusion_filter(announcements) if exclusion_filter && RSpec.world.example_count.zero? @configuration.reporter.message( - "No examples were matched. Perhaps #{exclusion_filter.inspect} is excluding everything?") + "No examples were matched. Perhaps #{exclusion_filter.description} is excluding everything?") example_groups.clear else - announcements << "excluding #{exclusion_filter.inspect}" + announcements << "excluding #{exclusion_filter.description}" end end diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 37bb71814d..1022f42a45 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -517,6 +517,18 @@ def metadata_hash(*args) end end + describe "#filter" do + describe "#description" do + it 'does not include the unnecessary hex number for lambdas' do + # check the assumption of this example + lambda { }.inspect.should include('0x') + + config.filter_run :bar => lambda { } + config.filter.description.should_not include('0x') + end + end + end + describe "#filter_run_excluding" do it_behaves_like "metadata hash builder" do def metadata_hash(*args) @@ -540,6 +552,36 @@ def metadata_hash(*args) end describe "#exclusion_filter" do + describe "#description" do + it 'returns `{}` when it only contains the default filters' do + config.exclusion_filter.description.should == {}.inspect + end + + it 'includes other filters' do + config.exclusion_filter[:foo] = :bar + config.exclusion_filter.description.should == { :foo => :bar }.inspect + end + + it 'includes an overriden :if filter' do + config.exclusion_filter[:if] = :custom_filter + config.exclusion_filter.description.should == { :if => :custom_filter }.inspect + end + + it 'includes an overriden :unless filter' do + config.exclusion_filter[:unless] = :custom_filter + config.exclusion_filter.description.should == { :unless => :custom_filter }.inspect + end + + it 'does not include the unnecessary hex number for lambdas' do + # check the assumption of this example + lambda { }.inspect.should include('0x') + + config.exclusion_filter[:foo] = lambda { } + config.filter_run_excluding :bar => lambda { } + config.exclusion_filter.description.should_not include('0x') + end + end + describe "the default :if filter" do it "does not exclude a spec with no :if metadata" do config.exclusion_filter[:if].call(nil, {}).should be_false From 52eca405614468155f1413644f4089dd5cf84334 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sat, 23 Apr 2011 05:27:40 -0500 Subject: [PATCH 119/151] even shorter description of Proc location --- lib/rspec/core/configuration.rb | 3 ++- spec/rspec/core/configuration_spec.rb | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 404abeab7a..5e12308b03 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -338,10 +338,11 @@ def alias_it_should_behave_like_to(new_name, report_label = '') end PROC_HEX_NUMBER = /0x[0-9a-f]+@/ + PROJECT_DIR = File.expand_path('.') def exclusion_filter=(filter) def filter.description - reject { |k, v| DEFAULT_EXCLUSION_FILTERS[k] == v }.inspect.gsub(PROC_HEX_NUMBER, '') + reject { |k, v| DEFAULT_EXCLUSION_FILTERS[k] == v }.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)','') end settings[:exclusion_filter] = filter diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 1022f42a45..14e94e58af 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -572,13 +572,18 @@ def metadata_hash(*args) config.exclusion_filter.description.should == { :unless => :custom_filter }.inspect end - it 'does not include the unnecessary hex number for lambdas' do - # check the assumption of this example + it 'cleans up the description' do + # check the assumptions of this example + project_dir = File.expand_path('.') + lambda { }.inspect.should include(project_dir) lambda { }.inspect.should include('0x') + lambda { }.inspect.should include(' (lambda)') if RUBY_VERSION > '1.9' config.exclusion_filter[:foo] = lambda { } config.filter_run_excluding :bar => lambda { } config.exclusion_filter.description.should_not include('0x') + config.exclusion_filter.description.should_not include(project_dir) + config.exclusion_filter.description.should_not include(' (lambda)') end end From c66049af16c55bbce502c83b34c2a5f12bee4879 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sat, 23 Apr 2011 14:37:29 -0500 Subject: [PATCH 120/151] friendly description for both inclusion and exclusion filters --- lib/rspec/core/configuration.rb | 18 ++++++++---------- spec/rspec/core/configuration_spec.rb | 16 ++++++++++++++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 5e12308b03..3c0af48970 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -337,23 +337,21 @@ def alias_it_should_behave_like_to(new_name, report_label = '') RSpec::Core::ExampleGroup.alias_it_should_behave_like_to(new_name, report_label) end - PROC_HEX_NUMBER = /0x[0-9a-f]+@/ - PROJECT_DIR = File.expand_path('.') + module Describable + PROC_HEX_NUMBER = /0x[0-9a-f]+@/ + PROJECT_DIR = File.expand_path('.') - def exclusion_filter=(filter) - def filter.description + def description reject { |k, v| DEFAULT_EXCLUSION_FILTERS[k] == v }.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)','') end + end - settings[:exclusion_filter] = filter + def exclusion_filter=(filter) + settings[:exclusion_filter] = filter.extend(Describable) end def filter=(filter) - def filter.description - inspect.gsub(PROC_HEX_NUMBER, '') - end - - settings[:filter] = filter + settings[:filter] = filter.extend(Describable) end def filter_run_including(*args) diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 14e94e58af..d2d7af50a2 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -519,12 +519,24 @@ def metadata_hash(*args) describe "#filter" do describe "#description" do - it 'does not include the unnecessary hex number for lambdas' do + # it 'does not include the unnecessary hex number for lambdas' do # check the assumption of this example + # lambda { }.inspect.should include('0x') + + # config.filter_run :bar => lambda { } + # config.filter.description.should_not include('0x') + # end + it 'cleans up the description' do + # check the assumptions of this example + project_dir = File.expand_path('.') + lambda { }.inspect.should include(project_dir) lambda { }.inspect.should include('0x') + lambda { }.inspect.should include(' (lambda)') if RUBY_VERSION > '1.9' - config.filter_run :bar => lambda { } + config.filter_run :foo => lambda { } config.filter.description.should_not include('0x') + config.filter.description.should_not include(project_dir) + config.filter.description.should_not include(' (lambda)') end end end From 0ac4e6e24940755414a4cf09eaea6439796adf02 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sat, 23 Apr 2011 14:50:34 -0500 Subject: [PATCH 121/151] remove commented example --- spec/rspec/core/configuration_spec.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index d2d7af50a2..4bcd9b3ba1 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -519,13 +519,6 @@ def metadata_hash(*args) describe "#filter" do describe "#description" do - # it 'does not include the unnecessary hex number for lambdas' do - # check the assumption of this example - # lambda { }.inspect.should include('0x') - - # config.filter_run :bar => lambda { } - # config.filter.description.should_not include('0x') - # end it 'cleans up the description' do # check the assumptions of this example project_dir = File.expand_path('.') From 86a0813f00334dbc3f10dbc8f6bc036e54cae0c0 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 28 Apr 2011 07:19:55 -0400 Subject: [PATCH 122/151] remove redundant statement --- lib/rspec/core/extensions/object.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/rspec/core/extensions/object.rb b/lib/rspec/core/extensions/object.rb index 1e025619e6..a5e6667dc2 100644 --- a/lib/rspec/core/extensions/object.rb +++ b/lib/rspec/core/extensions/object.rb @@ -2,7 +2,6 @@ module RSpec module Core module ObjectExtensions def describe(*args, &example_group_block) - args << {} unless args.last.is_a?(Hash) RSpec::Core::ExampleGroup.describe(*args, &example_group_block).register end end From ee66acbc6d7951a55b57fb48d565635a1072209c Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 28 Apr 2011 13:04:07 -0400 Subject: [PATCH 123/151] inclusion/exclusion filter refactoring --- features/Changelog.md | 7 ++ lib/rspec/core/configuration.rb | 32 +++----- lib/rspec/core/world.rb | 74 +++++++++++++----- spec/rspec/core/configuration_spec.rb | 52 ------------- spec/rspec/core/world_spec.rb | 104 +++++++++++++++++++++++++- 5 files changed, 175 insertions(+), 94 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index 6530601af6..ce634da8d8 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,3 +1,10 @@ +### dev + +[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc2...master) + +* Enhancements + * Clean up messages for filters. + ### 2.6.0.rc2 / 2011-04-18 [full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.0.rc2) diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 3c0af48970..cf4a71b5b8 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -26,8 +26,9 @@ def self.add_setting(name, opts={}) add_setting :profile_examples add_setting :fail_fast add_setting :run_all_when_everything_filtered - add_setting :filter add_setting :exclusion_filter + add_setting :inclusion_filter + add_setting :filter, :alias => :inclusion_filter add_setting :filename_pattern, :default => '**/*_spec.rb' add_setting :files_to_run add_setting :include_or_extend_modules @@ -36,7 +37,7 @@ def self.add_setting(name, opts={}) add_setting :treat_symbols_as_metadata_keys_with_true_values, :default => false add_setting :expecting_with_rspec - DEFAULT_EXCLUSION_FILTERS = { + CONDITIONAL_FILTERS = { :if => lambda { |value, metadata| metadata.has_key?(:if) && !value }, :unless => lambda { |value| value } } @@ -53,7 +54,7 @@ def initialize /lib\/rspec\/(core|expectations|matchers|mocks)/ ] - self.exclusion_filter = DEFAULT_EXCLUSION_FILTERS.dup + self.exclusion_filter = CONDITIONAL_FILTERS.dup end # :call-seq: @@ -107,7 +108,7 @@ def settings end def clear_inclusion_filter # :nodoc: - self.filter = nil + self.inclusion_filter = nil end def cleaned_from_backtrace?(line) @@ -337,21 +338,12 @@ def alias_it_should_behave_like_to(new_name, report_label = '') RSpec::Core::ExampleGroup.alias_it_should_behave_like_to(new_name, report_label) end - module Describable - PROC_HEX_NUMBER = /0x[0-9a-f]+@/ - PROJECT_DIR = File.expand_path('.') - - def description - reject { |k, v| DEFAULT_EXCLUSION_FILTERS[k] == v }.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)','') - end - end - def exclusion_filter=(filter) - settings[:exclusion_filter] = filter.extend(Describable) + settings[:exclusion_filter] = filter end - def filter=(filter) - settings[:filter] = filter.extend(Describable) + def inclusion_filter=(filter) + settings[:inclusion_filter] = filter end def filter_run_including(*args) @@ -363,14 +355,14 @@ def filter_run_including(*args) options = build_metadata_hash_from(args) - if filter and filter[:line_number] || filter[:full_description] + if inclusion_filter and inclusion_filter[:line_number] || inclusion_filter[:full_description] warn "Filtering by #{options.inspect} is not possible since " \ - "you are already filtering by #{filter.inspect}" + "you are already filtering by #{inclusion_filter.inspect}" else if force_overwrite - self.filter = options + self.inclusion_filter = options else - self.filter = (filter || {}).merge(options) + self.inclusion_filter = (inclusion_filter || {}).merge(options) end end end diff --git a/lib/rspec/core/world.rb b/lib/rspec/core/world.rb index fb885d01f4..7e8bba0fac 100644 --- a/lib/rspec/core/world.rb +++ b/lib/rspec/core/world.rb @@ -2,6 +2,29 @@ module RSpec module Core class World + module Describable + PROC_HEX_NUMBER = /0x[0-9a-f]+@/ + PROJECT_DIR = File.expand_path('.') + + def description + reject { |k, v| RSpec::Core::Configuration::CONDITIONAL_FILTERS[k] == v }.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)','') + end + + def empty_without_conditional_filters? + reject { |k, v| RSpec::Core::Configuration::CONDITIONAL_FILTERS[k] == v }.empty? + end + + def reject + super rescue {} + end + + def empty? + super rescue false + end + end + + include RSpec::Core::Hooks + attr_reader :example_groups, :filtered_examples, :wants_to_quit attr_writer :wants_to_quit @@ -24,11 +47,11 @@ def register(example_group) end def inclusion_filter - @configuration.filter + @configuration.inclusion_filter.extend(Describable) end def exclusion_filter - @configuration.exclusion_filter + @configuration.exclusion_filter.extend(Describable) end def configure_group(group) @@ -59,40 +82,53 @@ def preceding_declaration_line(filter_line) end end + def reporter + @configuration.reporter + end + def announce_filters filter_announcements = [] + + if @configuration.run_all_when_everything_filtered? && example_count.zero? + reporter.message( "No examples matched #{inclusion_filter.description}. Running all.") + filtered_examples.clear + @configuration.clear_inclusion_filter + end + announce_inclusion_filter filter_announcements announce_exclusion_filter filter_announcements - unless filter_announcements.empty? - @configuration.reporter.message("Run filtered #{filter_announcements.join(', ')}") + if example_count.zero? + example_groups.clear + if filter_announcements.empty? + reporter.message("No examples found.") + elsif inclusion_filter + message = "No examples matched #{inclusion_filter.description}." + if @configuration.run_all_when_everything_filtered? + message << " Running all." + end + reporter.message(message) + elsif exclusion_filter + reporter.message( + "No examples were matched. Perhaps #{exclusion_filter.description} is excluding everything?") + end + else + reporter.message("Run filtered #{filter_announcements.join(', ')}") end end def announce_inclusion_filter(announcements) if inclusion_filter - if @configuration.run_all_when_everything_filtered? && RSpec.world.example_count.zero? - @configuration.reporter.message "No examples were matched by #{inclusion_filter.description}, running all" - @configuration.clear_inclusion_filter - filtered_examples.clear - else - announcements << "using #{inclusion_filter.description}" - end + announcements << "including #{inclusion_filter.description}" end end - + def announce_exclusion_filter(announcements) - if exclusion_filter && RSpec.world.example_count.zero? - @configuration.reporter.message( - "No examples were matched. Perhaps #{exclusion_filter.description} is excluding everything?") - example_groups.clear - else + unless exclusion_filter.empty_without_conditional_filters? announcements << "excluding #{exclusion_filter.description}" end end - include RSpec::Core::Hooks - def find_hook(hook, scope, group, example = nil) @configuration.find_hook(hook, scope, group, example) end diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 4bcd9b3ba1..37bb71814d 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -517,23 +517,6 @@ def metadata_hash(*args) end end - describe "#filter" do - describe "#description" do - it 'cleans up the description' do - # check the assumptions of this example - project_dir = File.expand_path('.') - lambda { }.inspect.should include(project_dir) - lambda { }.inspect.should include('0x') - lambda { }.inspect.should include(' (lambda)') if RUBY_VERSION > '1.9' - - config.filter_run :foo => lambda { } - config.filter.description.should_not include('0x') - config.filter.description.should_not include(project_dir) - config.filter.description.should_not include(' (lambda)') - end - end - end - describe "#filter_run_excluding" do it_behaves_like "metadata hash builder" do def metadata_hash(*args) @@ -557,41 +540,6 @@ def metadata_hash(*args) end describe "#exclusion_filter" do - describe "#description" do - it 'returns `{}` when it only contains the default filters' do - config.exclusion_filter.description.should == {}.inspect - end - - it 'includes other filters' do - config.exclusion_filter[:foo] = :bar - config.exclusion_filter.description.should == { :foo => :bar }.inspect - end - - it 'includes an overriden :if filter' do - config.exclusion_filter[:if] = :custom_filter - config.exclusion_filter.description.should == { :if => :custom_filter }.inspect - end - - it 'includes an overriden :unless filter' do - config.exclusion_filter[:unless] = :custom_filter - config.exclusion_filter.description.should == { :unless => :custom_filter }.inspect - end - - it 'cleans up the description' do - # check the assumptions of this example - project_dir = File.expand_path('.') - lambda { }.inspect.should include(project_dir) - lambda { }.inspect.should include('0x') - lambda { }.inspect.should include(' (lambda)') if RUBY_VERSION > '1.9' - - config.exclusion_filter[:foo] = lambda { } - config.filter_run_excluding :bar => lambda { } - config.exclusion_filter.description.should_not include('0x') - config.exclusion_filter.description.should_not include(project_dir) - config.exclusion_filter.description.should_not include(' (lambda)') - end - end - describe "the default :if filter" do it "does not exclude a spec with no :if metadata" do config.exclusion_filter[:if].call(nil, {}).should be_false diff --git a/spec/rspec/core/world_spec.rb b/spec/rspec/core/world_spec.rb index 9ccad9823b..9ab042ddfe 100644 --- a/spec/rspec/core/world_spec.rb +++ b/spec/rspec/core/world_spec.rb @@ -5,8 +5,9 @@ class Foo; end module RSpec::Core - describe World do - let(:world) { RSpec::Core::World.new } + describe RSpec::Core::World do + let(:configuration) { RSpec::Core::Configuration.new } + let(:world) { RSpec::Core::World.new(configuration) } describe "#example_groups" do it "contains all registered example groups" do @@ -192,6 +193,103 @@ module RSpec::Core end end - end + describe "#announce_filters" do + let(:reporter) { double('reporter').as_null_object } + before { world.stub(:reporter) { reporter } } + + context "with no examples" do + before { world.stub(:example_count) { 0 } } + + context "with no filters" do + it "announces" do + reporter.should_receive(:message). + with("No examples found.") + world.announce_filters + end + end + + context "with an inclusion filter" do + it "announces" do + configuration.inclusion_filter = { :foo => 'bar' } + reporter.should_receive(:message). + with("No examples matched #{{ :foo => 'bar' }.inspect}.") + world.announce_filters + end + end + + context "with an inclusion filter and run_all_when_everything_filtered" do + it "announces" do + configuration.stub(:run_all_when_everything_filtered?) { true } + configuration.inclusion_filter = { :foo => 'bar' } + reporter.should_receive(:message). + with("No examples matched #{{ :foo => 'bar' }.inspect}. Running all.") + world.announce_filters + end + end + + context "with an exclusion filter" do + it "announces" do + configuration.exclusion_filter = { :foo => 'bar' } + reporter.should_receive(:message). + with("No examples were matched. Perhaps #{{ :foo => 'bar' }.inspect} is excluding everything?") + world.announce_filters + end + end + end + end + + describe "#inclusion_filter" do + describe "#description" do + it 'cleans up the description' do + # check the assumptions of this example + project_dir = File.expand_path('.') + lambda { }.inspect.should include(project_dir) + lambda { }.inspect.should include('0x') + lambda { }.inspect.should include(' (lambda)') if RUBY_VERSION > '1.9' + + configuration.filter_run :foo => lambda { } + world.inclusion_filter.description.should_not include('0x') + world.inclusion_filter.description.should_not include(project_dir) + world.inclusion_filter.description.should_not include(' (lambda)') + end + end + end + + describe "#exclusion_filter" do + describe "#description" do + it 'returns `{}` when it only contains the default filters' do + world.exclusion_filter.description.should == {}.inspect + end + + it 'includes other filters' do + configuration.exclusion_filter[:foo] = :bar + world.exclusion_filter.description.should == { :foo => :bar }.inspect + end + + it 'includes an overriden :if filter' do + configuration.exclusion_filter[:if] = :custom_filter + world.exclusion_filter.description.should == { :if => :custom_filter }.inspect + end + + it 'includes an overriden :unless filter' do + configuration.exclusion_filter[:unless] = :custom_filter + world.exclusion_filter.description.should == { :unless => :custom_filter }.inspect + end + it 'cleans up the description' do + # check the assumptions of this example + project_dir = File.expand_path('.') + lambda { }.inspect.should include(project_dir) + lambda { }.inspect.should include('0x') + lambda { }.inspect.should include(' (lambda)') if RUBY_VERSION > '1.9' + + configuration.exclusion_filter[:foo] = lambda { } + configuration.filter_run_excluding :bar => lambda { } + world.exclusion_filter.description.should_not include('0x') + world.exclusion_filter.description.should_not include(project_dir) + world.exclusion_filter.description.should_not include(' (lambda)') + end + end + end + end end From 4909f5ff33db7ec3ddefd58d9e413a7ae902b77a Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 28 Apr 2011 17:37:08 -0400 Subject: [PATCH 124/151] fix some failing (brittle) cukes --- features/command_line/tag.feature | 10 +++++----- .../filtering/run_all_when_everything_filtered.feature | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/command_line/tag.feature b/features/command_line/tag.feature index 8a71ae6c4f..5417cab1f0 100644 --- a/features/command_line/tag.feature +++ b/features/command_line/tag.feature @@ -33,19 +33,19 @@ Feature: --tag option Scenario: filter examples with a simple tag When I run `rspec . --tag focus` - Then the output should contain "Run filtered using {:focus=>true}" + Then the output should contain "Run filtered including {:focus=>true}" And the examples should all pass Scenario: filter examples with a simple tag and @ When I run `rspec . --tag @focus` - Then the output should contain "Run filtered using {:focus=>true}" + Then the output should contain "Run filtered including {:focus=>true}" Then the examples should all pass Scenario: filter examples with a name:value tag When I run `rspec . --tag type:special` Then the output should contain: """ - Run filtered using {:type=>"special"} + Run filtered including {:type=>"special"} """ And the output should contain "2 examples" And the examples should all pass @@ -54,7 +54,7 @@ Feature: --tag option When I run `rspec . --tag @type:special` Then the output should contain: """ - Run filtered using {:type=>"special"} + Run filtered including {:type=>"special"} """ And the examples should all pass @@ -86,5 +86,5 @@ Feature: --tag option Scenario: filter examples with a simple tag, exclude examples with another tag When I run `rspec . --tag focus --tag ~skip` - Then the output should contain "Run filtered using {:focus=>true}, excluding {:skip=>true}" + Then the output should contain "Run filtered including {:focus=>true}, excluding {:skip=>true}" And the examples should all pass diff --git a/features/filtering/run_all_when_everything_filtered.feature b/features/filtering/run_all_when_everything_filtered.feature index a4fee4d77a..6833a359d5 100644 --- a/features/filtering/run_all_when_everything_filtered.feature +++ b/features/filtering/run_all_when_everything_filtered.feature @@ -32,7 +32,7 @@ Feature: run all when everything filtered end """ When I run `rspec spec/sample_spec.rb --format doc` - Then the output should contain "No examples were matched by {:focus=>true}, running all" + Then the output should contain "No examples matched {:focus=>true}" And the examples should all pass And the output should contain: """ From c9851ebb01bb107cbaf6a139810c7436ce0a411f Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sat, 30 Apr 2011 07:41:00 -0400 Subject: [PATCH 125/151] prep for 2.6.0.rc3 --- features/Changelog.md | 6 +++--- lib/rspec/core/version.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index ce634da8d8..3a46a5ee36 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,9 +1,9 @@ -### dev +### 2.6.0.rc3 / 2011-04-30 -[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc2...master) +[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc2...v2.6.0.rc3) * Enhancements - * Clean up messages for filters. + * Clean up messages for filters/tags. ### 2.6.0.rc2 / 2011-04-18 diff --git a/lib/rspec/core/version.rb b/lib/rspec/core/version.rb index 1c856d2882..8d1b9678cb 100644 --- a/lib/rspec/core/version.rb +++ b/lib/rspec/core/version.rb @@ -1,7 +1,7 @@ module RSpec # :nodoc: module Core # :nodoc: module Version # :nodoc: - STRING = '2.6.0.rc2' + STRING = '2.6.0.rc3' end end end From 83db5d530694109600104b9d750ce64bb198a359 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 1 May 2011 08:28:38 -0400 Subject: [PATCH 126/151] bump to 2.6.0.rc4 --- features/Changelog.md | 4 ++-- lib/rspec/core/version.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index 3a46a5ee36..f297fde048 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,6 +1,6 @@ -### 2.6.0.rc3 / 2011-04-30 +### 2.6.0.rc4 / 2011-05-01 -[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc2...v2.6.0.rc3) +[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc2...v2.6.0.rc4) * Enhancements * Clean up messages for filters/tags. diff --git a/lib/rspec/core/version.rb b/lib/rspec/core/version.rb index 8d1b9678cb..a42e70206e 100644 --- a/lib/rspec/core/version.rb +++ b/lib/rspec/core/version.rb @@ -1,7 +1,7 @@ module RSpec # :nodoc: module Core # :nodoc: module Version # :nodoc: - STRING = '2.6.0.rc3' + STRING = '2.6.0.rc4' end end end From 0c7a676e0274683795ebefdda2d5ee50ebdf1ccb Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 5 May 2011 07:24:06 -0500 Subject: [PATCH 127/151] restore --pattern/-P command line option (from rspec-1) --- features/Changelog.md | 7 ++ lib/rspec/core/configuration.rb | 5 +- lib/rspec/core/option_parser.rb | 4 + spec/rspec/core/configuration_spec.rb | 122 ++++++++++++-------------- spec/rspec/core/option_parser_spec.rb | 41 +++++---- 5 files changed, 91 insertions(+), 88 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index f297fde048..d4875e1817 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,3 +1,10 @@ +### dev + +[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc4...master) + +* Enhancements + * Restore --pattern/-P command line option from rspec-1 + ### 2.6.0.rc4 / 2011-05-01 [full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc2...v2.6.0.rc4) diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index cf4a71b5b8..72aae046a9 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -29,7 +29,8 @@ def self.add_setting(name, opts={}) add_setting :exclusion_filter add_setting :inclusion_filter add_setting :filter, :alias => :inclusion_filter - add_setting :filename_pattern, :default => '**/*_spec.rb' + add_setting :pattern, :default => '**/*_spec.rb' + add_setting :filename_pattern, :alias => :pattern add_setting :files_to_run add_setting :include_or_extend_modules add_setting :backtrace_clean_patterns @@ -292,7 +293,7 @@ def reporter def files_or_directories_to_run=(*files) self.files_to_run = files.flatten.collect do |file| if File.directory?(file) - filename_pattern.split(",").collect do |pattern| + pattern.split(",").collect do |pattern| Dir["#{file}/#{pattern.strip}"] end else diff --git a/lib/rspec/core/option_parser.rb b/lib/rspec/core/option_parser.rb index c09d58a797..a169dd1ee3 100644 --- a/lib/rspec/core/option_parser.rb +++ b/lib/rspec/core/option_parser.rb @@ -86,6 +86,10 @@ def parser(options) options[:profile_examples] = o end + parser.on('-P', '--pattern PATTERN', 'Load files those matching this pattern. Default is "spec/**/*_spec.rb"') do |o| + options[:pattern] = o + end + parser.on('-r', '--require PATH', 'Require a file') do |path| options[:requires] ||= [] options[:requires] << path diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 37bb71814d..2b89baffdc 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -143,16 +143,14 @@ module RSpec::Core end end - context "setting the files to run" do - + describe "#files_to_run" do it "loads files not following pattern if named explicitly" do file = "./spec/rspec/core/resources/a_bar.rb" config.files_or_directories_to_run = file config.files_to_run.should == [file] end - describe "with default --pattern" do - + context "with default pattern" do it "loads files named _spec.rb" do dir = "./spec/rspec/core/resources" config.files_or_directories_to_run = dir @@ -164,80 +162,70 @@ module RSpec::Core config.files_or_directories_to_run = file config.files_to_run.should == [file] end - end + end - describe "with explicit pattern (single)" do + %w[pattern= filename_pattern=].each do |setter| + describe "##{setter}" do + context "with single pattern" do + before { config.send(setter, "**/*_foo.rb") } + it "loads files following pattern" do + file = File.expand_path(File.dirname(__FILE__) + "/resources/a_foo.rb") + config.files_or_directories_to_run = file + config.files_to_run.should include(file) + end - before do - config.filename_pattern = "**/*_foo.rb" - end + it "loads files in directories following pattern" do + dir = File.expand_path(File.dirname(__FILE__) + "/resources") + config.files_or_directories_to_run = dir + config.files_to_run.should include("#{dir}/a_foo.rb") + end - it "loads files following pattern" do - file = File.expand_path(File.dirname(__FILE__) + "/resources/a_foo.rb") - config.files_or_directories_to_run = file - config.files_to_run.should include(file) + it "does not load files in directories not following pattern" do + dir = File.expand_path(File.dirname(__FILE__) + "/resources") + config.files_or_directories_to_run = dir + config.files_to_run.should_not include("#{dir}/a_bar.rb") + end end - it "loads files in directories following pattern" do - dir = File.expand_path(File.dirname(__FILE__) + "/resources") - config.files_or_directories_to_run = dir - config.files_to_run.should include("#{dir}/a_foo.rb") - end + context "with multiple patterns" do + it "supports comma separated values" do + config.send(setter, "**/*_foo.rb,**/*_bar.rb") + dir = File.expand_path(File.dirname(__FILE__) + "/resources") + config.files_or_directories_to_run = dir + config.files_to_run.should include("#{dir}/a_foo.rb") + config.files_to_run.should include("#{dir}/a_bar.rb") + end - it "does not load files in directories not following pattern" do - dir = File.expand_path(File.dirname(__FILE__) + "/resources") - config.files_or_directories_to_run = dir - config.files_to_run.should_not include("#{dir}/a_bar.rb") + it "supports comma separated values with spaces" do + config.send(setter, "**/*_foo.rb, **/*_bar.rb") + dir = File.expand_path(File.dirname(__FILE__) + "/resources") + config.files_or_directories_to_run = dir + config.files_to_run.should include("#{dir}/a_foo.rb") + config.files_to_run.should include("#{dir}/a_bar.rb") + end end - end + end - context "with explicit pattern (comma,separated,values)" do - - before do - config.filename_pattern = "**/*_foo.rb,**/*_bar.rb" - end - - it "supports comma separated values" do - dir = File.expand_path(File.dirname(__FILE__) + "/resources") - config.files_or_directories_to_run = dir - config.files_to_run.should include("#{dir}/a_foo.rb") - config.files_to_run.should include("#{dir}/a_bar.rb") - end - - it "supports comma separated values with spaces" do - dir = File.expand_path(File.dirname(__FILE__) + "/resources") - config.files_or_directories_to_run = dir - config.files_to_run.should include("#{dir}/a_foo.rb") - config.files_to_run.should include("#{dir}/a_bar.rb") - end - + describe "path with line number" do + it "assigns the line number as the filter" do + config.files_or_directories_to_run = "path/to/a_spec.rb:37" + config.filter.should == {:line_number => 37} end + end - context "with line number" do - - it "assigns the line number as the filter" do - config.files_or_directories_to_run = "path/to/a_spec.rb:37" - config.filter.should == {:line_number => 37} - end - + context "with full_description" do + it "overrides :focused" do + config.filter_run :focused => true + config.full_description = "foo" + config.filter.should_not have_key(:focused) end - context "with full_description" do - it "overrides :focused" do - config.filter_run :focused => true - config.full_description = "foo" - config.filter.should_not have_key(:focused) - end - - it "assigns the example name as the filter on description" do - config.full_description = "foo" - config.filter.should == {:full_description => /foo/} - end - + it "assigns the example name as the filter on description" do + config.full_description = "foo" + config.filter.should == {:full_description => /foo/} end - end describe "#include" do @@ -306,7 +294,7 @@ def metadata_hash(*args) end - describe "run_all_when_everything_filtered?" do + describe "#run_all_when_everything_filtered?" do it "defaults to false" do config.run_all_when_everything_filtered?.should be_false @@ -407,14 +395,14 @@ def metadata_hash(*args) end end - describe 'formatter=' do + describe '#formatter=' do it "delegates to add_formatter (better API for user-facing configuration)" do config.should_receive(:add_formatter).with('these','options') config.add_formatter('these','options') end end - describe "add_formatter" do + describe "#add_formatter" do it "adds to the list of formatters" do config.add_formatter :documentation @@ -573,7 +561,7 @@ def metadata_hash(*args) end end - describe "line_number=" do + describe "#line_number=" do before { config.stub(:warn) } it "sets the line number" do diff --git a/spec/rspec/core/option_parser_spec.rb b/spec/rspec/core/option_parser_spec.rb index ce49c092fd..54a9faff04 100644 --- a/spec/rspec/core/option_parser_spec.rb +++ b/spec/rspec/core/option_parser_spec.rb @@ -2,13 +2,10 @@ module RSpec::Core describe OptionParser do - before do - RSpec.stub(:deprecate) - end - let(:output_file){ mock File } before do + RSpec.stub(:deprecate) File.stub(:open).with("foo.txt",'w') { (output_file) } end @@ -30,17 +27,12 @@ module RSpec::Core end end - describe "--format" do - it "defines the formatter" do - options = Parser.parse!(%w[--format doc]) - options[:formatters].first.should eq(["doc"]) - end - end - - describe "-f" do - it "defines the formatter" do - options = Parser.parse!(%w[-f doc]) - options[:formatters].first.should eq(["doc"]) + %w[--format -f].each do |option| + describe option do + it "defines the formatter" do + options = Parser.parse!([option, 'doc']) + options[:formatters].first.should eq(["doc"]) + end end end @@ -72,10 +64,21 @@ module RSpec::Core end end - describe "--example" do - it "escapes the arg" do - options = Parser.parse!(["--example", "this (and that)"]) - "this (and that)".should match(options[:full_description]) + %w[--example -e].each do |option| + describe option do + it "escapes the arg" do + options = Parser.parse!([option, "this (and that)"]) + "this (and that)".should match(options[:full_description]) + end + end + end + + %w[--pattern -P].each do |option| + describe option do + it "sets the filename pattern" do + options = Parser.parse!([option, 'spec/**/*.spec']) + options[:pattern].should eq('spec/**/*.spec') + end end end From 2c71a88ba2ba4e7ba34c47185864d5417086be6c Mon Sep 17 00:00:00 2001 From: Andreas Tolf Tolfsen Date: Thu, 5 May 2011 07:28:22 -0500 Subject: [PATCH 128/151] Suppport both true and false on config.full_backtrace= - Closes #355. --- features/Changelog.md | 1 + lib/rspec/core/configuration.rb | 21 +++++++++++---------- spec/rspec/core/configuration_spec.rb | 15 ++++++++++++--- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index d4875e1817..8000725cd2 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -4,6 +4,7 @@ * Enhancements * Restore --pattern/-P command line option from rspec-1 + * Support false as well as true in config.full_backtrace= (Andreas Tolf Tolfsen) ### 2.6.0.rc4 / 2011-05-01 diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 72aae046a9..4cd7ba8858 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -43,18 +43,19 @@ def self.add_setting(name, opts={}) :unless => lambda { |value| value } } + DEFAULT_BACKTRACE_PATTERNS = [ + /\/lib\d*\/ruby\//, + /bin\//, + /gems/, + /spec\/spec_helper\.rb/, + /lib\/rspec\/(core|expectations|matchers|mocks)/ + ] + def initialize @color_enabled = false self.include_or_extend_modules = [] self.files_to_run = [] - self.backtrace_clean_patterns = [ - /\/lib\d*\/ruby\//, - /bin\//, - /gems/, - /spec\/spec_helper\.rb/, - /lib\/rspec\/(core|expectations|matchers|mocks)/ - ] - + self.backtrace_clean_patterns = DEFAULT_BACKTRACE_PATTERNS.dup self.exclusion_filter = CONDITIONAL_FILTERS.dup end @@ -210,8 +211,8 @@ def expect_with(*frameworks) end end - def full_backtrace=(bool) - settings[:backtrace_clean_patterns] = [] + def full_backtrace=(true_or_false) + settings[:backtrace_clean_patterns] = true_or_false ? [] : DEFAULT_BACKTRACE_PATTERNS end def color_enabled diff --git a/spec/rspec/core/configuration_spec.rb b/spec/rspec/core/configuration_spec.rb index 2b89baffdc..c55fd2ae99 100644 --- a/spec/rspec/core/configuration_spec.rb +++ b/spec/rspec/core/configuration_spec.rb @@ -583,9 +583,18 @@ def metadata_hash(*args) end describe "#full_backtrace=" do - it "clears the backtrace clean patterns" do - config.full_backtrace = true - config.backtrace_clean_patterns.should == [] + context "given true" do + it "clears the backtrace clean patterns" do + config.full_backtrace = true + config.backtrace_clean_patterns.should == [] + end + end + + context "given false" do + it "restores backtrace clean patterns" do + config.full_backtrace = false + config.backtrace_clean_patterns.should == RSpec::Core::Configuration::DEFAULT_BACKTRACE_PATTERNS + end end it "doesn't impact other instances of config" do From 4c0f32e75c713e9aaed0debc8ad808d5b3ec0a34 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 5 May 2011 21:35:01 -0500 Subject: [PATCH 129/151] no need for the rubygems version in the gemspec --- rspec-core.gemspec | 1 - 1 file changed, 1 deletion(-) diff --git a/rspec-core.gemspec b/rspec-core.gemspec index bcee7f7a01..f3d28064f2 100644 --- a/rspec-core.gemspec +++ b/rspec-core.gemspec @@ -12,7 +12,6 @@ Gem::Specification.new do |s| s.summary = "rspec-core-#{RSpec::Core::Version::STRING}" s.description = "BDD for Ruby. RSpec runner and example groups." - s.rubygems_version = "1.3.7" s.rubyforge_project = "rspec" s.files = `git ls-files`.split("\n") From 3bbeb31b14e62cb5ae46ead4bfb17b0f160a6b5c Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Fri, 6 May 2011 06:31:44 -0500 Subject: [PATCH 130/151] prep for 2.6.0.rc5 --- features/Changelog.md | 4 ++-- lib/rspec/core/version.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index 8000725cd2..cc416df4c9 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,6 +1,6 @@ -### dev +### 2.6.0.rc5 / 2011-05-06 -[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc4...master) +[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc4...v2.6.0.rc5) * Enhancements * Restore --pattern/-P command line option from rspec-1 diff --git a/lib/rspec/core/version.rb b/lib/rspec/core/version.rb index a42e70206e..cb20797766 100644 --- a/lib/rspec/core/version.rb +++ b/lib/rspec/core/version.rb @@ -1,7 +1,7 @@ module RSpec # :nodoc: module Core # :nodoc: module Version # :nodoc: - STRING = '2.6.0.rc4' + STRING = '2.6.0.rc5' end end end From a37ff24ff9565585216d11f90af3f5904b14fc4c Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Fri, 6 May 2011 06:57:04 -0500 Subject: [PATCH 131/151] prep for rc6 --- features/Changelog.md | 4 ++-- lib/rspec/core/version.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index cc416df4c9..657c95fa40 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,6 +1,6 @@ -### 2.6.0.rc5 / 2011-05-06 +### 2.6.0.rc6 / 2011-05-06 -[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc4...v2.6.0.rc5) +[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc4...v2.6.0.rc6) * Enhancements * Restore --pattern/-P command line option from rspec-1 diff --git a/lib/rspec/core/version.rb b/lib/rspec/core/version.rb index cb20797766..8d4c8048c0 100644 --- a/lib/rspec/core/version.rb +++ b/lib/rspec/core/version.rb @@ -1,7 +1,7 @@ module RSpec # :nodoc: module Core # :nodoc: module Version # :nodoc: - STRING = '2.6.0.rc5' + STRING = '2.6.0.rc6' end end end From 7410e6f42bcc941e67ae62ff8a6f4c2281a120ca Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sat, 7 May 2011 10:39:10 -0500 Subject: [PATCH 132/151] CommandLine.run returns 0/1 instead of true/false - Closes #366 --- features/Changelog.md | 7 +++ lib/rspec/core/command_line.rb | 2 +- lib/rspec/core/runner.rb | 2 +- spec/rspec/core/command_line_spec.rb | 36 +++++++++++++ spec/rspec/core/drb_command_line_spec.rb | 65 +++++++----------------- spec/support/spec_files.rb | 44 ++++++++++++++++ 6 files changed, 108 insertions(+), 48 deletions(-) create mode 100644 spec/support/spec_files.rb diff --git a/features/Changelog.md b/features/Changelog.md index 657c95fa40..c727a40fc3 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,3 +1,10 @@ +### dev + +[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc6...master) + +* Bug fixes + * CommandLine returns exit status (0/1) instead of true/false + ### 2.6.0.rc6 / 2011-05-06 [full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc4...v2.6.0.rc6) diff --git a/lib/rspec/core/command_line.rb b/lib/rspec/core/command_line.rb index 0b957eb1e9..db2f560069 100644 --- a/lib/rspec/core/command_line.rb +++ b/lib/rspec/core/command_line.rb @@ -21,7 +21,7 @@ def run(err, out) @configuration.reporter.report(@world.example_count) do |reporter| begin @configuration.run_hook(:before, :suite) - @world.example_groups.map {|g| g.run(reporter)}.all? + @world.example_groups.map {|g| g.run(reporter)}.all? ? 0 : 1 ensure @configuration.run_hook(:after, :suite) end diff --git a/lib/rspec/core/runner.rb b/lib/rspec/core/runner.rb index 5168283168..d2e8b0682e 100644 --- a/lib/rspec/core/runner.rb +++ b/lib/rspec/core/runner.rb @@ -7,7 +7,7 @@ class Runner def self.autorun return if autorun_disabled? || installed_at_exit? || running_in_drb? @installed_at_exit = true - at_exit { run(ARGV, $stderr, $stdout) ? exit(0) : exit(1) } + at_exit { exit(run(ARGV, $stderr, $stdout)) } end AT_EXIT_HOOK_BACKTRACE_LINE = "#{__FILE__}:#{__LINE__ - 2}:in `autorun'" diff --git a/spec/rspec/core/command_line_spec.rb b/spec/rspec/core/command_line_spec.rb index 5889ecae1f..6e41ab42ef 100644 --- a/spec/rspec/core/command_line_spec.rb +++ b/spec/rspec/core/command_line_spec.rb @@ -4,6 +4,42 @@ module RSpec::Core describe CommandLine do + + describe "#run" do + include_context "spec files" + + let(:out) { StringIO.new } + let(:err) { StringIO.new } + + def config_options(argv=[]) + options = RSpec::Core::ConfigurationOptions.new(argv) + options.parse_options + options + end + + def command_line(args) + RSpec::Core::CommandLine.new(config_options(args)) + end + + def config_options(argv=[]) + options = RSpec::Core::ConfigurationOptions.new(argv) + options.parse_options + options + end + + it "returns 0 if spec passes" do + err, out = StringIO.new, StringIO.new + result = command_line([passing_spec_filename]).run(err, out) + result.should be(0) + end + + it "returns 1 if spec passes" do + err, out = StringIO.new, StringIO.new + result = command_line([failing_spec_filename]).run(err, out) + result.should be(1) + end + end + context "given an Array of options" do it "assigns ConfigurationOptions built from Array to @options" do config_options = ConfigurationOptions.new(%w[--color]) diff --git a/spec/rspec/core/drb_command_line_spec.rb b/spec/rspec/core/drb_command_line_spec.rb index 921a767984..b4bec5481f 100644 --- a/spec/rspec/core/drb_command_line_spec.rb +++ b/spec/rspec/core/drb_command_line_spec.rb @@ -5,18 +5,20 @@ let(:out) { StringIO.new } let(:err) { StringIO.new } + include_context "spec files" + + def command_line(args) + RSpec::Core::DRbCommandLine.new(config_options(args)) + end + def config_options(argv=[]) options = RSpec::Core::ConfigurationOptions.new(argv) options.parse_options options end - def drb_command_line(args) - RSpec::Core::DRbCommandLine.new(config_options(args)) - end - def run_with(args) - drb_command_line(args).run(err, out) + command_line(args).run(err, out) end context "without server running" do @@ -39,14 +41,14 @@ def with_RSPEC_DRB_set_to(val) context "without RSPEC_DRB environment variable set" do it "defaults to 8989" do with_RSPEC_DRB_set_to(nil) do - drb_command_line([]).drb_port.should == 8989 + command_line([]).drb_port.should == 8989 end end it "sets the DRb port" do with_RSPEC_DRB_set_to(nil) do - drb_command_line(["--drb-port", "1234"]).drb_port.should == 1234 - drb_command_line(["--drb-port", "5678"]).drb_port.should == 5678 + command_line(["--drb-port", "1234"]).drb_port.should == 1234 + command_line(["--drb-port", "5678"]).drb_port.should == 5678 end end end @@ -56,7 +58,7 @@ def with_RSPEC_DRB_set_to(val) context "without config variable set" do it "uses RSPEC_DRB value" do with_RSPEC_DRB_set_to('9000') do - drb_command_line([]).drb_port.should == "9000" + command_line([]).drb_port.should == "9000" end end end @@ -64,7 +66,7 @@ def with_RSPEC_DRB_set_to(val) context "and config variable set" do it "uses configured value" do with_RSPEC_DRB_set_to('9000') do - drb_command_line(%w[--drb-port 5678]).drb_port.should == 5678 + command_line(%w[--drb-port 5678]).drb_port.should == 5678 end end end @@ -80,59 +82,30 @@ def self.run(argv, err, out) end end - def dummy_spec_filename - @dummy_spec_filename ||= File.expand_path(File.dirname(__FILE__)) + "/_dummy_spec#{@drb_example_file_counter}.rb" - end - before(:all) do @drb_port = 8990 @drb_example_file_counter = 0 DRb::start_service("druby://127.0.0.1:#{@drb_port}", ::FakeDrbSpecServer) end - before(:each) do - @drb_example_file_counter += 1 - create_dummy_spec_file - end - - after(:each) do - File.delete(dummy_spec_filename) - end - after(:all) do DRb::stop_service end - def create_dummy_spec_file - File.open(dummy_spec_filename, 'w') do |f| - f.write %q{ - describe "DUMMY CONTEXT for 'DrbCommandLine with -c option'" do - it "should be output with green bar" do - true.should be_true - end - - it "should be output with red bar" do - raise("I want to see a red bar!") - end - end - } - end - end - - it "returns true" do + it "returns 0 if spec passes" do err, out = StringIO.new, StringIO.new - result = drb_command_line(["--drb-port", @drb_port.to_s]).run(err, out) - result.should be_true + result = command_line(["--drb-port", @drb_port.to_s, passing_spec_filename]).run(err, out) + result.should be(0) end - it "integrates via Runner.new.run" do + it "returns 1 if spec passes" do err, out = StringIO.new, StringIO.new - result = RSpec::Core::Runner.run(%W[ --drb --drb-port #{@drb_port} #{dummy_spec_filename}], err, out) - result.should be_false + result = command_line(["--drb-port", @drb_port.to_s, failing_spec_filename]).run(err, out) + result.should be(1) end def run_spec_via_druby - run_with([dummy_spec_filename, "--colour", "--drb-port", @drb_port.to_s]) + run_with([failing_spec_filename, "--colour", "--drb-port", @drb_port.to_s]) out.rewind out.read end diff --git a/spec/support/spec_files.rb b/spec/support/spec_files.rb new file mode 100644 index 0000000000..9bce466d77 --- /dev/null +++ b/spec/support/spec_files.rb @@ -0,0 +1,44 @@ +shared_context "spec files" do + def failing_spec_filename + @failing_spec_filename ||= File.expand_path(File.dirname(__FILE__)) + "/_failing_spec.rb" + end + + def passing_spec_filename + @passing_spec_filename ||= File.expand_path(File.dirname(__FILE__)) + "/_passing_spec.rb" + end + + def create_passing_spec_file + File.open(passing_spec_filename, 'w') do |f| + f.write %q{ + describe "passing spec" do + it "passes" do + 1.should eq(1) + end + end + } + end + end + + def create_failing_spec_file + File.open(failing_spec_filename, 'w') do |f| + f.write %q{ + describe "failing spec" do + it "fails" do + 1.should eq(2) + end + end + } + end + end + + before(:all) do + create_passing_spec_file + create_failing_spec_file + end + + after(:all) do + File.delete(passing_spec_filename) + File.delete(failing_spec_filename) + end + +end From e979ab519019377db23ef9e69d38287d8471035a Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 06:50:56 -0500 Subject: [PATCH 133/151] Document that around hooks don't share state with examples - Closes #364. --- features/hooks/around_hooks.feature | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/features/hooks/around_hooks.feature b/features/hooks/around_hooks.feature index 8d293e150a..4da008bce0 100644 --- a/features/hooks/around_hooks.feature +++ b/features/hooks/around_hooks.feature @@ -9,6 +9,13 @@ Feature: around hooks example, if your database library offers a transaction method that receives a block, you can use an around hook as described in the first scenario: + WARNING: around hooks do not share state with the example the way before and + after hooks do. This means that you can not share instance variables between + around hooks and examples. + + Also, mock frameworks are set up and torn down within the context of running + the example, so you can not interact with them directly in around hooks. + Scenario: use the example as a proc within the block passed to around() Given a file named "example_spec.rb" with: """ From 890d6c6f19227cc83a3d28bba69382f2b7f71904 Mon Sep 17 00:00:00 2001 From: marekj Date: Thu, 5 May 2011 17:33:40 -0500 Subject: [PATCH 134/151] Create path to formatter output file if it doesn't exist. - Closes #361. --- features/Changelog.md | 1 + lib/rspec/core/configuration.rb | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/features/Changelog.md b/features/Changelog.md index c727a40fc3..0abe3547ce 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -4,6 +4,7 @@ * Bug fixes * CommandLine returns exit status (0/1) instead of true/false + * Create path to formatter output file if it doesn't exist (marekj). ### 2.6.0.rc6 / 2011-05-06 diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 4cd7ba8858..5a7b37c5f6 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -275,7 +275,13 @@ def add_formatter(formatter_to_use, output=nil) custom_formatter(formatter_to_use) || (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.") - formatters << formatter_class.new(output ? File.new(output, 'w') : self.output) + formatters << formatter_class.new(output ? output_file(output) : self.output) + end + + def output_file(output) + require 'fileutils' + FileUtils.mkdir_p(File.dirname(output)) + File.new(output, 'w') end alias_method :formatter=, :add_formatter From 169c72563856b5eba4b73d6348f4404387c5fdcd Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 07:14:47 -0500 Subject: [PATCH 135/151] make utility method private --- lib/rspec/core/configuration.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 5a7b37c5f6..c4971db14e 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -1,4 +1,5 @@ require "rbconfig" +require 'fileutils' module RSpec module Core @@ -269,19 +270,13 @@ def full_description=(description) filter_run({ :full_description => /#{description}/ }, true) end - def add_formatter(formatter_to_use, output=nil) + def add_formatter(formatter_to_use, path=nil) formatter_class = built_in_formatter(formatter_to_use) || custom_formatter(formatter_to_use) || (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.") - formatters << formatter_class.new(output ? output_file(output) : self.output) - end - - def output_file(output) - require 'fileutils' - FileUtils.mkdir_p(File.dirname(output)) - File.new(output, 'w') + formatters << formatter_class.new(path ? file_at(path) : output) end alias_method :formatter=, :add_formatter @@ -492,6 +487,12 @@ def underscore(camel_cased_word) word.downcase! word end + + def file_at(path) + FileUtils.mkdir_p(File.dirname(path)) + File.new(path, 'w') + end + end end end From 9f620637ac1a12759dae4acbea889755fd1119a0 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 07:21:43 -0500 Subject: [PATCH 136/151] don't announce 'Running filtered' when there are no filters --- lib/rspec/core/world.rb | 2 +- spec/rspec/core/world_spec.rb | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/rspec/core/world.rb b/lib/rspec/core/world.rb index 7e8bba0fac..ce6d4beb8a 100644 --- a/lib/rspec/core/world.rb +++ b/lib/rspec/core/world.rb @@ -112,7 +112,7 @@ def announce_filters reporter.message( "No examples were matched. Perhaps #{exclusion_filter.description} is excluding everything?") end - else + elsif !filter_announcements.empty? reporter.message("Run filtered #{filter_announcements.join(', ')}") end end diff --git a/spec/rspec/core/world_spec.rb b/spec/rspec/core/world_spec.rb index 9ab042ddfe..9b51730fe9 100644 --- a/spec/rspec/core/world_spec.rb +++ b/spec/rspec/core/world_spec.rb @@ -236,6 +236,17 @@ module RSpec::Core end end end + + context "with examples" do + before { world.stub(:example_count) { 1 } } + + context "with no filters" do + it "does not announce" do + reporter.should_not_receive(:message) + world.announce_filters + end + end + end end describe "#inclusion_filter" do From bfd07650f54c1b432d03cffaadcf9d3cab2bf273 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 08:01:48 -0500 Subject: [PATCH 137/151] don't call autorun when registering an example group - the rspec command already does this - if you want to use the ruby command, require 'rspec/autorun' --- lib/rspec/core/example_group.rb | 1 - spec/spec_helper.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 8b28c080a9..4e04314209 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -22,7 +22,6 @@ def self.world end def self.register - RSpec::Core::Runner.autorun world.register(self) end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a1485b6629..295e0876d3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,4 @@ -require 'rspec/core' +require 'rspec/autorun' require 'autotest/rspec2' Dir['./spec/support/**/*.rb'].map {|f| require f} From 67ab2ac36b3121238c40244c20e4dd6c99d50e4c Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 08:08:32 -0500 Subject: [PATCH 138/151] Dev: just require 'rspec/core' --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 295e0876d3..a1485b6629 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,4 @@ -require 'rspec/autorun' +require 'rspec/core' require 'autotest/rspec2' Dir['./spec/support/**/*.rb'].map {|f| require f} From 73b871429e1a383e6929e6b4764ff7c19f626a71 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 10:27:52 -0500 Subject: [PATCH 139/151] Set $stderr and $stdout as defaults for RSpec::Core::Runner.run - See #367. --- lib/rspec/core/runner.rb | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/lib/rspec/core/runner.rb b/lib/rspec/core/runner.rb index d2e8b0682e..d76169282c 100644 --- a/lib/rspec/core/runner.rb +++ b/lib/rspec/core/runner.rb @@ -4,6 +4,7 @@ module RSpec module Core class Runner + # Register an at_exit hook that runs the suite. def self.autorun return if autorun_disabled? || installed_at_exit? || running_in_drb? @installed_at_exit = true @@ -11,24 +12,24 @@ def self.autorun end AT_EXIT_HOOK_BACKTRACE_LINE = "#{__FILE__}:#{__LINE__ - 2}:in `autorun'" - def self.autorun_disabled? - @autorun_disabled ||= false - end - def self.disable_autorun! @autorun_disabled = true end - def self.installed_at_exit? + def self.autorun_disabled? # :nodoc: + @autorun_disabled ||= false + end + + def self.installed_at_exit? # :nodoc: @installed_at_exit ||= false end - def self.running_in_drb? - (DRb.current_server rescue false) && + def self.running_in_drb? # :nodoc: + (DRb.current_server rescue false) && DRb.current_server.uri =~ /druby\:\/\/127.0.0.1\:/ end - def self.trap_interrupt + def self.trap_interrupt # :nodoc: trap('INT') do exit!(1) if RSpec.wants_to_quit RSpec.wants_to_quit = true @@ -36,7 +37,23 @@ def self.trap_interrupt end end - def self.run(args, err, out) + # Run a suite of RSpec examples. + # + # This is used internally by RSpec to run a suite, but is available + # for use by any other automation tool. + # + # If you want to run this multiple times in the same process, and you + # want files like spec_helper.rb to be reloaded, be sure to load `load` + # instead of `require`. + # + # ==== Parameters + # * +args+ - an array of command-line-supported arguments + # * +err+ - error stream (Default: $stderr) + # * +out+ - output stream (Default: $stdout) + # + # ==== Returns + # * +Fixnum+ - exit status code (0/1) + def self.run(args, err=$stderr, out=$stdout) trap_interrupt options = ConfigurationOptions.new(args) options.parse_options @@ -53,11 +70,11 @@ def self.run(args, err, out) end end - def self.run_over_drb(options, err, out) + def self.run_over_drb(options, err, out) # :nodoc: DRbCommandLine.new(options).run(err, out) end - def self.run_in_process(options, err, out) + def self.run_in_process(options, err, out) # :nodoc: CommandLine.new(options, RSpec::configuration, RSpec::world).run(err, out) end From 7658d8b3a30c5ada4c21793dab5ffe9ce277914b Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 10:38:22 -0500 Subject: [PATCH 140/151] Dev: remove obsolete file --- spec/ruby_forker.rb | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 spec/ruby_forker.rb diff --git a/spec/ruby_forker.rb b/spec/ruby_forker.rb deleted file mode 100644 index e2f9591e90..0000000000 --- a/spec/ruby_forker.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'rbconfig' - -module RubyForker - # Forks a ruby interpreter with same type as ourself. - # jruby will fork jruby, ruby will fork ruby etc. - def ruby(args, stderr=nil) - config = ::RbConfig::CONFIG - interpreter = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] - cmd = "#{interpreter} #{args}" - cmd << " 2> #{stderr}" unless stderr.nil? - `#{cmd}` - end -end From 1466f60418c51440c21c919b930fdd6cff95b0c5 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 10:52:04 -0500 Subject: [PATCH 141/151] add comment to remove spork monkey patch --- lib/rspec/monkey/spork/test_framework/rspec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/rspec/monkey/spork/test_framework/rspec.rb b/lib/rspec/monkey/spork/test_framework/rspec.rb index 0a8f27bb2a..2fb2429e89 100644 --- a/lib/rspec/monkey/spork/test_framework/rspec.rb +++ b/lib/rspec/monkey/spork/test_framework/rspec.rb @@ -1,3 +1,4 @@ +# TODO (2011-05-08) - remove this as soon as spork 0.9.0 is released if defined?(Spork::TestFramework::RSpec) class Spork::TestFramework::RSpec < Spork::TestFramework def run_tests(argv, err, out) From f994d217ccad85db0068525a6b4bc6427b2cc79d Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 10:52:21 -0500 Subject: [PATCH 142/151] fix cuke broken by bfd07650f54c1b432d03cffaadcf9d3cab2bf273 --- features/formatters/text_formatter.feature | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/features/formatters/text_formatter.feature b/features/formatters/text_formatter.feature index d751b349ac..04590ee215 100644 --- a/features/formatters/text_formatter.feature +++ b/features/formatters/text_formatter.feature @@ -7,8 +7,6 @@ Feature: text formatter Scenario: Backtrace formatting for failing specs in multiple files Given a file named "string_spec.rb" with: """ - require 'rspec/core' - describe String do it "has a failing example" do "foo".reverse.should == "ofo" @@ -17,7 +15,7 @@ Feature: text formatter """ And a file named "integer_spec.rb" with: """ - require 'rspec/core' + require 'rspec/autorun' describe Integer do it "has a failing example" do @@ -40,6 +38,6 @@ Feature: text formatter Failure/Error: "foo".reverse.should == "ofo" expected: "ofo" got: "oof" (using ==) - # ./string_spec.rb:5 + # ./string_spec.rb:3 """ From 71cb7aff9c70e766b2a3e92f3eef014e356cdf2d Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 11:02:44 -0500 Subject: [PATCH 143/151] clear the world after each run - Closes #367. --- lib/rspec/core.rb | 6 ++++++ lib/rspec/core/runner.rb | 1 + spec/rspec/core/runner_spec.rb | 10 ++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/rspec/core.rb b/lib/rspec/core.rb index da570123c0..1bb301e5af 100644 --- a/lib/rspec/core.rb +++ b/lib/rspec/core.rb @@ -49,6 +49,12 @@ def self.world @world ||= RSpec::Core::World.new end + # Sets the world to nil. Used internally to ensure examples get reloaded + # between multiple runs in the same process. + def self.clear_world + @world = nil + end + def self.configuration @configuration ||= RSpec::Core::Configuration.new end diff --git a/lib/rspec/core/runner.rb b/lib/rspec/core/runner.rb index d76169282c..9af4427267 100644 --- a/lib/rspec/core/runner.rb +++ b/lib/rspec/core/runner.rb @@ -67,6 +67,7 @@ def self.run(args, err=$stderr, out=$stdout) end else run_in_process(options, err, out) + RSpec.clear_world end end diff --git a/spec/rspec/core/runner_spec.rb b/spec/rspec/core/runner_spec.rb index 21e3f599f5..34800ca837 100644 --- a/spec/rspec/core/runner_spec.rb +++ b/spec/rspec/core/runner_spec.rb @@ -21,9 +21,15 @@ module RSpec::Core end describe "#run" do + let(:err) { StringIO.new } + let(:out) { StringIO.new } + + it "clears the world" do + RSpec.should_receive(:clear_world) + RSpec::Core::Runner.run([], err, out) + end + context "with --drb or -X" do - let(:err) { StringIO.new } - let(:out) { StringIO.new } before(:each) do @options = RSpec::Core::ConfigurationOptions.new(%w[--drb --drb-port 8181 --color]) From e58c0a3e0ff700481d9850a64061b7991bb11a96 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 11:22:21 -0500 Subject: [PATCH 144/151] update docs --- features/.nav | 18 +++++++++--------- features/command_line/README.md | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/features/.nav b/features/.nav index dec7aac88d..25b607b405 100644 --- a/features/.nav +++ b/features/.nav @@ -5,6 +5,15 @@ - basic_structure.feature - shared_example_group.feature - shared_context.feature +- command_line: + - configure.feature + - example_name_option.feature + - format_option.feature + - line_number_option.feature + - tag.feature + - line_number_appended_to_path.feature + - exit_status.feature + - rake_task.feature - pending: - pending_examples.feature - hooks: @@ -29,15 +38,6 @@ - exclusion_filters.feature - if_and_unless.feature - run_all_when_everything_filtered.feature -- command_line: - - configure.feature - - example_name_option.feature - - format_option.feature - - line_number_option.feature - - tag.feature - - line_number_appended_to_path.feature - - exit_status.feature - - rake_task.feature - configuration: - read_options_from_file.feature - fail_fast.feature diff --git a/features/command_line/README.md b/features/command_line/README.md index d7955c3f64..e86c43128e 100644 --- a/features/command_line/README.md +++ b/features/command_line/README.md @@ -4,3 +4,25 @@ behavior, including output formats, filtering examples, etc. For a full list of options, run the `rspec` command with the `--help` flag: $ rspec --help + +### Run with `ruby` + +Generally, life is simpler if you just use the `rspec` command. If you must use the `ruby` +command, however, you'll want to do the following: + +* `require 'rspec/autorun'` + +This tells RSpec to run your examples. Do this in any file that you are +passing to the `ruby` command. + +* Update the `LOAD_PATH` + +It is conventional to put configuration in and require assorted support files +from `spec/spec_helper.rb`. It is also conventional to require that file from +the spec files using `require 'spec_helper'`. This works because RSpec +implicitly adds the `spec` directory to the `LOAD_PATH`. It also adds `lib`, so +your implementation files will be on the `LOAD_PATH` as well. + +If you're using the `ruby` command, you'll need to do this yourself: + + ruby -Ilib -Ispec path/to/spec.rb From 9124a62ccf11e07603264b3c318d268520a07452 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sun, 8 May 2011 11:49:08 -0500 Subject: [PATCH 145/151] reset only which needs resetting - #367 --- lib/rspec/core.rb | 9 +++++---- lib/rspec/core/configuration.rb | 4 ++++ lib/rspec/core/runner.rb | 3 ++- lib/rspec/core/world.rb | 4 ++++ spec/rspec/core/runner_spec.rb | 5 +++-- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/rspec/core.rb b/lib/rspec/core.rb index 1bb301e5af..b1c7c46769 100644 --- a/lib/rspec/core.rb +++ b/lib/rspec/core.rb @@ -49,10 +49,11 @@ def self.world @world ||= RSpec::Core::World.new end - # Sets the world to nil. Used internally to ensure examples get reloaded - # between multiple runs in the same process. - def self.clear_world - @world = nil + # Used internally to ensure examples get reloaded between multiple runs in + # the same process. + def self.reset + world.reset + configuration.reset end def self.configuration diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index c4971db14e..72f1afd56e 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -60,6 +60,10 @@ def initialize self.exclusion_filter = CONDITIONAL_FILTERS.dup end + def reset + @reporter = nil + end + # :call-seq: # add_setting(:name) # add_setting(:name, :default => "default_value") diff --git a/lib/rspec/core/runner.rb b/lib/rspec/core/runner.rb index 9af4427267..bfcb382c9a 100644 --- a/lib/rspec/core/runner.rb +++ b/lib/rspec/core/runner.rb @@ -67,8 +67,9 @@ def self.run(args, err=$stderr, out=$stdout) end else run_in_process(options, err, out) - RSpec.clear_world end + ensure + RSpec.reset end def self.run_over_drb(options, err, out) # :nodoc: diff --git a/lib/rspec/core/world.rb b/lib/rspec/core/world.rb index ce6d4beb8a..2d1ecd3f7b 100644 --- a/lib/rspec/core/world.rb +++ b/lib/rspec/core/world.rb @@ -41,6 +41,10 @@ def initialize(configuration=RSpec.configuration) } end + def reset + example_groups.clear + end + def register(example_group) example_groups << example_group example_group diff --git a/spec/rspec/core/runner_spec.rb b/spec/rspec/core/runner_spec.rb index 34800ca837..de2e2d4e36 100644 --- a/spec/rspec/core/runner_spec.rb +++ b/spec/rspec/core/runner_spec.rb @@ -24,8 +24,9 @@ module RSpec::Core let(:err) { StringIO.new } let(:out) { StringIO.new } - it "clears the world" do - RSpec.should_receive(:clear_world) + it "resets world and configuration" do + RSpec.configuration.should_receive(:reset) + RSpec.world.should_receive(:reset) RSpec::Core::Runner.run([], err, out) end From 9d61d59eb7432404961cd2bf435eb7dd4439a4c6 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Mon, 9 May 2011 23:02:46 -0500 Subject: [PATCH 146/151] refactoring: clarify intent of applying filters --- lib/rspec/core.rb | 14 ++++---------- lib/rspec/core/applicable.rb | 9 +++++++++ lib/rspec/core/configuration.rb | 3 ++- lib/rspec/core/example.rb | 5 ++--- lib/rspec/core/example_group.rb | 4 ++-- lib/rspec/core/expecting/with_rspec.rb | 2 -- lib/rspec/core/hooks.rb | 18 ++++++++++-------- lib/rspec/core/metadata.rb | 10 ++++------ .../core/mocking/with_absolutely_nothing.rb | 2 -- lib/rspec/core/mocking/with_flexmock.rb | 3 +++ lib/rspec/core/world.rb | 9 +++------ 11 files changed, 39 insertions(+), 40 deletions(-) create mode 100644 lib/rspec/core/applicable.rb diff --git a/lib/rspec/core.rb b/lib/rspec/core.rb index b1c7c46769..09c6cd356d 100644 --- a/lib/rspec/core.rb +++ b/lib/rspec/core.rb @@ -1,6 +1,7 @@ -require 'rspec/core/extensions' +require 'rspec/core/applicable' require 'rspec/core/load_path' require 'rspec/core/deprecation' +require 'rspec/core/extensions' require 'rspec/core/backward_compatibility' require 'rspec/core/reporter' @@ -25,18 +26,14 @@ require 'rspec/core/example_group' require 'rspec/core/version' require 'rspec/core/errors' +require 'rspec/core/backward_compatibility' +require 'rspec/monkey' module RSpec autoload :Matchers, 'rspec/matchers' SharedContext = Core::SharedContext - module Core - def self.install_directory - @install_directory ||= File.expand_path(File.dirname(__FILE__)) - end - end - def self.wants_to_quit world.wants_to_quit end @@ -89,6 +86,3 @@ def self.warn_about_deprecated_configure NOTICE end end - -require 'rspec/core/backward_compatibility' -require 'rspec/monkey' diff --git a/lib/rspec/core/applicable.rb b/lib/rspec/core/applicable.rb new file mode 100644 index 0000000000..06a41a40ae --- /dev/null +++ b/lib/rspec/core/applicable.rb @@ -0,0 +1,9 @@ +module RSpec + module Core + module Applicable + def apply_to?(target) + target.apply? + end + end + end +end diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 72f1afd56e..6689a0e662 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -5,6 +5,7 @@ module RSpec module Core class Configuration include RSpec::Core::Hooks + include RSpec::Core::Applicable def self.add_setting(name, opts={}) if opts[:alias] @@ -393,7 +394,7 @@ def extend(mod, *args) def configure_group(group) include_or_extend_modules.each do |include_or_extend, mod, filters| - next unless filters.empty? || group.apply?(:any?, filters) + next unless filters.empty? || filters.any?(&apply_to?(group)) group.send(include_or_extend, mod) end end diff --git a/lib/rspec/core/example.rb b/lib/rspec/core/example.rb index e5eddd62ff..c9ead32ae4 100644 --- a/lib/rspec/core/example.rb +++ b/lib/rspec/core/example.rb @@ -27,9 +27,8 @@ def around_hooks @around_hooks ||= example_group.around_hooks_for(self) end - def apply?(predicate, filters) - @metadata.apply?(predicate, filters) || - @example_group_class.apply?(predicate, filters) + def apply? + @metadata.apply? end alias_method :pending?, :pending diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 4e04314209..02dabedc20 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -296,8 +296,8 @@ def self.run_examples(reporter) end.all? end - def self.apply?(predicate, filters) - metadata.apply?(predicate, filters) + def self.apply? + @metadata.apply? end def self.declaration_line_numbers diff --git a/lib/rspec/core/expecting/with_rspec.rb b/lib/rspec/core/expecting/with_rspec.rb index 29888a54b1..a88839fdfe 100644 --- a/lib/rspec/core/expecting/with_rspec.rb +++ b/lib/rspec/core/expecting/with_rspec.rb @@ -3,9 +3,7 @@ module RSpec module Core module ExpectationFrameworkAdapter - include RSpec::Matchers - end end end diff --git a/lib/rspec/core/hooks.rb b/lib/rspec/core/hooks.rb index 5348dcdcb1..a54dac51d6 100644 --- a/lib/rspec/core/hooks.rb +++ b/lib/rspec/core/hooks.rb @@ -4,6 +4,8 @@ module Hooks include MetadataHashBuilder::WithConfigWarning class Hook + include RSpec::Core::Applicable + attr_reader :options def initialize(options, &block) @@ -12,8 +14,8 @@ def initialize(options, &block) @block = block end - def options_apply?(example_or_group) - !example_or_group || example_or_group.apply?(:all?, options) + def with_conditions_applicable_to?(example_or_group) + !example_or_group || options.all?(&apply_to?(example_or_group)) end def to_proc @@ -55,12 +57,12 @@ def call(wrapped_example) end class HookCollection < Array - def find_hooks_for(example_or_group) - self.class.new(select {|hook| hook.options_apply?(example_or_group)}) + def with_conditions_applicable_to(example_or_group) + self.class.new(select {|hook| hook.with_conditions_applicable_to?(example_or_group)}) end - def without_hooks_for(example_or_group) - self.class.new(reject {|hook| hook.options_apply?(example_or_group)}) + def without_conditions_applicable_to(example_or_group) + self.class.new(reject {|hook| hook.with_conditions_applicable_to?(example_or_group)}) end end @@ -126,13 +128,13 @@ def run_hook_filtered(hook, scope, group, example_group_instance, example = nil) end def find_hook(hook, scope, example_group_class, example = nil) - found_hooks = hooks[hook][scope].find_hooks_for(example || example_group_class) + found_hooks = hooks[hook][scope].with_conditions_applicable_to(example || example_group_class) # ensure we don't re-run :all hooks that were applied to any of the parent groups if scope == :all super_klass = example_group_class.superclass while super_klass != RSpec::Core::ExampleGroup - found_hooks = found_hooks.without_hooks_for(super_klass) + found_hooks = found_hooks.without_conditions_applicable_to(super_klass) super_klass = super_klass.superclass end end diff --git a/lib/rspec/core/metadata.rb b/lib/rspec/core/metadata.rb index 795c2d4f18..b0a7209ef7 100644 --- a/lib/rspec/core/metadata.rb +++ b/lib/rspec/core/metadata.rb @@ -102,12 +102,6 @@ def configure_for_example(description, user_metadata) update(user_metadata) end - def apply?(predicate, filters) - filters.send(predicate) do |key, value| - apply_condition(key, value) - end - end - def relevant_line_numbers(metadata) line_numbers = [metadata[:line_number]] if metadata[:example_group] @@ -117,6 +111,10 @@ def relevant_line_numbers(metadata) end end + def apply? + @apply ||= proc {|key, value| apply_condition(key, value)} + end + def apply_condition(key, value, metadata=self) case value when Hash diff --git a/lib/rspec/core/mocking/with_absolutely_nothing.rb b/lib/rspec/core/mocking/with_absolutely_nothing.rb index b7ee933a3a..117eaf9fc5 100644 --- a/lib/rspec/core/mocking/with_absolutely_nothing.rb +++ b/lib/rspec/core/mocking/with_absolutely_nothing.rb @@ -1,11 +1,9 @@ module RSpec module Core module MockFrameworkAdapter - def setup_mocks_for_rspec; end def verify_mocks_for_rspec; end def teardown_mocks_for_rspec; end - end end end diff --git a/lib/rspec/core/mocking/with_flexmock.rb b/lib/rspec/core/mocking/with_flexmock.rb index 9e3e6d1625..bf7c5a7868 100644 --- a/lib/rspec/core/mocking/with_flexmock.rb +++ b/lib/rspec/core/mocking/with_flexmock.rb @@ -12,12 +12,15 @@ module MockFrameworkAdapter def self.framework_name; :flexmock end include FlexMock::MockContainer + def setup_mocks_for_rspec # No setup required end + def verify_mocks_for_rspec flexmock_verify end + def teardown_mocks_for_rspec flexmock_close end diff --git a/lib/rspec/core/world.rb b/lib/rspec/core/world.rb index 2d1ecd3f7b..4a535482bd 100644 --- a/lib/rspec/core/world.rb +++ b/lib/rspec/core/world.rb @@ -24,6 +24,7 @@ def empty? end include RSpec::Core::Hooks + include RSpec::Core::Applicable attr_reader :example_groups, :filtered_examples, :wants_to_quit attr_writer :wants_to_quit @@ -71,13 +72,13 @@ def example_count end def apply_inclusion_filters(examples, conditions={}) - examples.select(&apply?(:any?, conditions)) + examples.select {|example| conditions.any?(&apply_to?(example))} end alias_method :find, :apply_inclusion_filters def apply_exclusion_filters(examples, conditions={}) - examples.reject(&apply?(:any?, conditions)) + examples.reject {|example| conditions.any?(&apply_to?(example))} end def preceding_declaration_line(filter_line) @@ -139,10 +140,6 @@ def find_hook(hook, scope, group, example = nil) private - def apply?(predicate, conditions) - lambda {|example| example.metadata.apply?(predicate, conditions)} - end - def declaration_line_numbers @line_numbers ||= example_groups.inject([]) do |lines, g| lines + g.declaration_line_numbers From 17782b0d341de861f4f6c9a41ac2a68a64929601 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 11 May 2011 08:03:20 -0500 Subject: [PATCH 147/151] easier on the eyes --- lib/rspec/core/example_group.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 02dabedc20..593fdd4b59 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -1,14 +1,15 @@ module RSpec module Core class ExampleGroup + extend MetadataHashBuilder::WithDeprecationWarning extend Extensions::ModuleEvalWithArgs - include Extensions::InstanceEvalWithArgs - extend Hooks extend Subject::ClassMethods + extend Hooks + + include Extensions::InstanceEvalWithArgs include Subject::InstanceMethods - include Let include Pending - extend MetadataHashBuilder::WithDeprecationWarning + include Let attr_accessor :example From 58926bb767a7b4ee77d7e9c8772d3464d841479d Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Wed, 11 May 2011 22:02:35 -0500 Subject: [PATCH 148/151] Revert "refactoring: clarify intent of applying filters" - it was more expressive, but caused errors in rspec-rails - will revisit later This reverts commit 9d61d59eb7432404961cd2bf435eb7dd4439a4c6. --- lib/rspec/core.rb | 14 ++++++++++---- lib/rspec/core/applicable.rb | 9 --------- lib/rspec/core/configuration.rb | 3 +-- lib/rspec/core/example.rb | 5 +++-- lib/rspec/core/example_group.rb | 4 ++-- lib/rspec/core/expecting/with_rspec.rb | 2 ++ lib/rspec/core/hooks.rb | 18 ++++++++---------- lib/rspec/core/metadata.rb | 10 ++++++---- .../core/mocking/with_absolutely_nothing.rb | 2 ++ lib/rspec/core/mocking/with_flexmock.rb | 3 --- lib/rspec/core/world.rb | 9 ++++++--- 11 files changed, 40 insertions(+), 39 deletions(-) delete mode 100644 lib/rspec/core/applicable.rb diff --git a/lib/rspec/core.rb b/lib/rspec/core.rb index 09c6cd356d..b1c7c46769 100644 --- a/lib/rspec/core.rb +++ b/lib/rspec/core.rb @@ -1,7 +1,6 @@ -require 'rspec/core/applicable' +require 'rspec/core/extensions' require 'rspec/core/load_path' require 'rspec/core/deprecation' -require 'rspec/core/extensions' require 'rspec/core/backward_compatibility' require 'rspec/core/reporter' @@ -26,14 +25,18 @@ require 'rspec/core/example_group' require 'rspec/core/version' require 'rspec/core/errors' -require 'rspec/core/backward_compatibility' -require 'rspec/monkey' module RSpec autoload :Matchers, 'rspec/matchers' SharedContext = Core::SharedContext + module Core + def self.install_directory + @install_directory ||= File.expand_path(File.dirname(__FILE__)) + end + end + def self.wants_to_quit world.wants_to_quit end @@ -86,3 +89,6 @@ def self.warn_about_deprecated_configure NOTICE end end + +require 'rspec/core/backward_compatibility' +require 'rspec/monkey' diff --git a/lib/rspec/core/applicable.rb b/lib/rspec/core/applicable.rb deleted file mode 100644 index 06a41a40ae..0000000000 --- a/lib/rspec/core/applicable.rb +++ /dev/null @@ -1,9 +0,0 @@ -module RSpec - module Core - module Applicable - def apply_to?(target) - target.apply? - end - end - end -end diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 6689a0e662..72f1afd56e 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -5,7 +5,6 @@ module RSpec module Core class Configuration include RSpec::Core::Hooks - include RSpec::Core::Applicable def self.add_setting(name, opts={}) if opts[:alias] @@ -394,7 +393,7 @@ def extend(mod, *args) def configure_group(group) include_or_extend_modules.each do |include_or_extend, mod, filters| - next unless filters.empty? || filters.any?(&apply_to?(group)) + next unless filters.empty? || group.apply?(:any?, filters) group.send(include_or_extend, mod) end end diff --git a/lib/rspec/core/example.rb b/lib/rspec/core/example.rb index c9ead32ae4..e5eddd62ff 100644 --- a/lib/rspec/core/example.rb +++ b/lib/rspec/core/example.rb @@ -27,8 +27,9 @@ def around_hooks @around_hooks ||= example_group.around_hooks_for(self) end - def apply? - @metadata.apply? + def apply?(predicate, filters) + @metadata.apply?(predicate, filters) || + @example_group_class.apply?(predicate, filters) end alias_method :pending?, :pending diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index 593fdd4b59..97fb99eb35 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -297,8 +297,8 @@ def self.run_examples(reporter) end.all? end - def self.apply? - @metadata.apply? + def self.apply?(predicate, filters) + metadata.apply?(predicate, filters) end def self.declaration_line_numbers diff --git a/lib/rspec/core/expecting/with_rspec.rb b/lib/rspec/core/expecting/with_rspec.rb index a88839fdfe..29888a54b1 100644 --- a/lib/rspec/core/expecting/with_rspec.rb +++ b/lib/rspec/core/expecting/with_rspec.rb @@ -3,7 +3,9 @@ module RSpec module Core module ExpectationFrameworkAdapter + include RSpec::Matchers + end end end diff --git a/lib/rspec/core/hooks.rb b/lib/rspec/core/hooks.rb index a54dac51d6..5348dcdcb1 100644 --- a/lib/rspec/core/hooks.rb +++ b/lib/rspec/core/hooks.rb @@ -4,8 +4,6 @@ module Hooks include MetadataHashBuilder::WithConfigWarning class Hook - include RSpec::Core::Applicable - attr_reader :options def initialize(options, &block) @@ -14,8 +12,8 @@ def initialize(options, &block) @block = block end - def with_conditions_applicable_to?(example_or_group) - !example_or_group || options.all?(&apply_to?(example_or_group)) + def options_apply?(example_or_group) + !example_or_group || example_or_group.apply?(:all?, options) end def to_proc @@ -57,12 +55,12 @@ def call(wrapped_example) end class HookCollection < Array - def with_conditions_applicable_to(example_or_group) - self.class.new(select {|hook| hook.with_conditions_applicable_to?(example_or_group)}) + def find_hooks_for(example_or_group) + self.class.new(select {|hook| hook.options_apply?(example_or_group)}) end - def without_conditions_applicable_to(example_or_group) - self.class.new(reject {|hook| hook.with_conditions_applicable_to?(example_or_group)}) + def without_hooks_for(example_or_group) + self.class.new(reject {|hook| hook.options_apply?(example_or_group)}) end end @@ -128,13 +126,13 @@ def run_hook_filtered(hook, scope, group, example_group_instance, example = nil) end def find_hook(hook, scope, example_group_class, example = nil) - found_hooks = hooks[hook][scope].with_conditions_applicable_to(example || example_group_class) + found_hooks = hooks[hook][scope].find_hooks_for(example || example_group_class) # ensure we don't re-run :all hooks that were applied to any of the parent groups if scope == :all super_klass = example_group_class.superclass while super_klass != RSpec::Core::ExampleGroup - found_hooks = found_hooks.without_conditions_applicable_to(super_klass) + found_hooks = found_hooks.without_hooks_for(super_klass) super_klass = super_klass.superclass end end diff --git a/lib/rspec/core/metadata.rb b/lib/rspec/core/metadata.rb index b0a7209ef7..795c2d4f18 100644 --- a/lib/rspec/core/metadata.rb +++ b/lib/rspec/core/metadata.rb @@ -102,6 +102,12 @@ def configure_for_example(description, user_metadata) update(user_metadata) end + def apply?(predicate, filters) + filters.send(predicate) do |key, value| + apply_condition(key, value) + end + end + def relevant_line_numbers(metadata) line_numbers = [metadata[:line_number]] if metadata[:example_group] @@ -111,10 +117,6 @@ def relevant_line_numbers(metadata) end end - def apply? - @apply ||= proc {|key, value| apply_condition(key, value)} - end - def apply_condition(key, value, metadata=self) case value when Hash diff --git a/lib/rspec/core/mocking/with_absolutely_nothing.rb b/lib/rspec/core/mocking/with_absolutely_nothing.rb index 117eaf9fc5..b7ee933a3a 100644 --- a/lib/rspec/core/mocking/with_absolutely_nothing.rb +++ b/lib/rspec/core/mocking/with_absolutely_nothing.rb @@ -1,9 +1,11 @@ module RSpec module Core module MockFrameworkAdapter + def setup_mocks_for_rspec; end def verify_mocks_for_rspec; end def teardown_mocks_for_rspec; end + end end end diff --git a/lib/rspec/core/mocking/with_flexmock.rb b/lib/rspec/core/mocking/with_flexmock.rb index bf7c5a7868..9e3e6d1625 100644 --- a/lib/rspec/core/mocking/with_flexmock.rb +++ b/lib/rspec/core/mocking/with_flexmock.rb @@ -12,15 +12,12 @@ module MockFrameworkAdapter def self.framework_name; :flexmock end include FlexMock::MockContainer - def setup_mocks_for_rspec # No setup required end - def verify_mocks_for_rspec flexmock_verify end - def teardown_mocks_for_rspec flexmock_close end diff --git a/lib/rspec/core/world.rb b/lib/rspec/core/world.rb index 4a535482bd..2d1ecd3f7b 100644 --- a/lib/rspec/core/world.rb +++ b/lib/rspec/core/world.rb @@ -24,7 +24,6 @@ def empty? end include RSpec::Core::Hooks - include RSpec::Core::Applicable attr_reader :example_groups, :filtered_examples, :wants_to_quit attr_writer :wants_to_quit @@ -72,13 +71,13 @@ def example_count end def apply_inclusion_filters(examples, conditions={}) - examples.select {|example| conditions.any?(&apply_to?(example))} + examples.select(&apply?(:any?, conditions)) end alias_method :find, :apply_inclusion_filters def apply_exclusion_filters(examples, conditions={}) - examples.reject {|example| conditions.any?(&apply_to?(example))} + examples.reject(&apply?(:any?, conditions)) end def preceding_declaration_line(filter_line) @@ -140,6 +139,10 @@ def find_hook(hook, scope, group, example = nil) private + def apply?(predicate, conditions) + lambda {|example| example.metadata.apply?(predicate, conditions)} + end + def declaration_line_numbers @line_numbers ||= example_groups.inject([]) do |lines, g| lines + g.declaration_line_numbers From b0161c795b7a56c724be33feea8dd3895ef2ca93 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Wed, 11 May 2011 23:02:43 -0500 Subject: [PATCH 149/151] typo --- features/metadata/user_defined.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/metadata/user_defined.feature b/features/metadata/user_defined.feature index 25a1be5faf..ebb2aff705 100644 --- a/features/metadata/user_defined.feature +++ b/features/metadata/user_defined.feature @@ -5,7 +5,7 @@ Feature: User-defined metadata `context` or `it`. RSpec supports many configuration options that apply only to certain examples or groups based on the metadata. - Metadata defined on an example group is available (and can be overriden) + Metadata defined on an example group is available (and can be overridden) by any sub-group or from any example in that group or a sub-group. In addition, there is a configuration option (which will be the default From a530faf47d55ce2f2d316f6f47b87e26334ec004 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Wed, 11 May 2011 23:21:31 -0500 Subject: [PATCH 150/151] typo --- features/metadata/user_defined.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/metadata/user_defined.feature b/features/metadata/user_defined.feature index ebb2aff705..32356edd9b 100644 --- a/features/metadata/user_defined.feature +++ b/features/metadata/user_defined.feature @@ -68,12 +68,12 @@ Feature: User-defined metadata Given a file named "override_metadata_spec.rb" with: """ describe "a group with user-defined metadata", :foo => 'bar' do - it 'can be overriden by an example', :foo => 'bazz' do + it 'can be overridden by an example', :foo => 'bazz' do example.metadata[:foo].should == 'bazz' end describe "a sub-group with an override", :foo => 'goo' do - it 'can be overriden by a sub-group' do + it 'can be overridden by a sub-group' do example.metadata[:foo].should == 'goo' end end From 6766e18be50833fad840908cf9886e3805f9d64b Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Thu, 12 May 2011 07:55:11 -0500 Subject: [PATCH 151/151] prep for 2.6.0 --- features/Changelog.md | 37 ++++++++++--------------------------- lib/rspec/core/version.rb | 2 +- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/features/Changelog.md b/features/Changelog.md index 0abe3547ce..36912a5dd0 100644 --- a/features/Changelog.md +++ b/features/Changelog.md @@ -1,29 +1,6 @@ -### dev +### 2.6.0 / 2011-05-12 -[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc6...master) - -* Bug fixes - * CommandLine returns exit status (0/1) instead of true/false - * Create path to formatter output file if it doesn't exist (marekj). - -### 2.6.0.rc6 / 2011-05-06 - -[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc4...v2.6.0.rc6) - -* Enhancements - * Restore --pattern/-P command line option from rspec-1 - * Support false as well as true in config.full_backtrace= (Andreas Tolf Tolfsen) - -### 2.6.0.rc4 / 2011-05-01 - -[full changelog](http://github.com/rspec/rspec-core/compare/v2.6.0.rc2...v2.6.0.rc4) - -* Enhancements - * Clean up messages for filters/tags. - -### 2.6.0.rc2 / 2011-04-18 - -[full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.0.rc2) +[full changelog](http://github.com/rspec/rspec-core/compare/v2.5.1...v2.6.0) * Enhancements * `shared_context` (Damian Nurzynski) @@ -39,8 +16,11 @@ defined. (Myron Marston) * Pass the exit status of a DRb run to the invoking process. This causes specs run via DRb to not just return true or false. (Ilkka Laukkanen) - * Refactoring of ConfigurationOptions#parse_options (Rodrigo Rosenfeld Rosas) + * Refactoring of `ConfigurationOptions#parse_options` (Rodrigo Rosenfeld Rosas) * Report excluded filters in runner output (tip from andyl) + * Clean up messages for filters/tags. + * Restore --pattern/-P command line option from rspec-1 + * Support false as well as true in config.full_backtrace= (Andreas Tolf Tolfsen) * Bug fixes * Don't stumble over an exception without a message (Hans Hasselberg) @@ -51,12 +31,15 @@ * Include RSpec::Matchers when first example group is defined, rather than just before running the examples. This works around an obscure bug in ruby 1.9 that can cause infinite recursion. (Myron Marston) - * Don't send example_group_[started|finished] to formatters for empty groups. + * Don't send `example_group_[started|finished]` to formatters for empty groups. * Get specs passing on jruby (Sidu Ponnappa) * Fix bug where mixing nested groups and outer-level examples gave unpredictable :line_number behavior (Artur Małecki) * Regexp.escape the argument to --example (tip from Elliot Winkler) * Correctly pass/fail pending block with message expectations + * CommandLine returns exit status (0/1) instead of true/false + * Create path to formatter output file if it doesn't exist (marekj). + ### 2.5.1 / 2011-02-06 diff --git a/lib/rspec/core/version.rb b/lib/rspec/core/version.rb index 8d4c8048c0..65cbb8205f 100644 --- a/lib/rspec/core/version.rb +++ b/lib/rspec/core/version.rb @@ -1,7 +1,7 @@ module RSpec # :nodoc: module Core # :nodoc: module Version # :nodoc: - STRING = '2.6.0.rc6' + STRING = '2.6.0' end end end