From 2b95b869abb24413bdbbd7b00de6a17093ed7563 Mon Sep 17 00:00:00 2001 From: Baron Bloomer Date: Fri, 20 Nov 2020 16:46:26 +0000 Subject: [PATCH 1/2] Add #fits and #xits methods RSpec core library has a convention of prepending 'f' and 'x' to it's methods to support running certain blocks or tests with :focus or :skip tags. This commit aims to bring rspec-its inline with this convention by making #fits and #xits methods available to the spec writer. --- .gitignore | 2 ++ README.md | 7 ++++++ lib/rspec/its.rb | 30 ++++++++++++++++++++++- spec/rspec/its_spec.rb | 55 ++++++++++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 2 +- 5 files changed, 94 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 4279c1c..22f3714 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ spec/reports test/tmp test/version_tmp tmp +bundle +bin diff --git a/README.md b/README.md index 5833921..a0e34bf 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,13 @@ Metadata arguments are supported. its(:size, focus: true) { should eq(1) } ``` +Alternatively, you can use the `f` and `x` prefix for `focus` and `skip` metadata, respectively. + +```ruby +fits(:size) { should eq(1) } +xits(:not_implemented_method) { will_not raise_error } +``` + ## Contributing 1. Fork it diff --git a/lib/rspec/its.rb b/lib/rspec/its.rb index 4eb83ba..4939a01 100644 --- a/lib/rspec/its.rb +++ b/lib/rspec/its.rb @@ -171,12 +171,40 @@ def should_not(matcher=nil, message=nil) end end + # Calls the #its method adding the :focus tag to metadata to allowing + # to be run in focus. + # + # @example + # + # # This ... + # describe Array do + # fits(:size) { should eq(0) } + # end + def fits(attribute, *options, &block) + opts = (Array(options) << :focus).uniq + its(attribute, *opts, &block) + end + + # Calls the #its method adding the :skip tag to metadata to allowing + # to be be skipped. + # + # @example + # + # # This ... + # describe Array do + # xits(:size) { should eq(0) } + # end + def xits(attribute, *options, &block) + opts = (Array(options) << :skip).uniq + its(attribute, *opts, &block) + end + end end RSpec.configure do |rspec| rspec.extend RSpec::Its - rspec.backtrace_exclusion_patterns << %r(/lib/rspec/its) + rspec.backtrace_exclusion_patterns << %r{/lib/rspec/its/fits/xits} end RSpec::SharedContext.send(:include, RSpec::Its) diff --git a/spec/rspec/its_spec.rb b/spec/rspec/its_spec.rb index ebc59d5..3ac7b18 100644 --- a/spec/rspec/its_spec.rb +++ b/spec/rspec/its_spec.rb @@ -9,6 +9,7 @@ module RSpec its([]) { expect(described_class).to be Its } end end + context "with explicit subject" do subject do Class.new do @@ -243,6 +244,7 @@ def false_if_first_time end end end + context "with metadata" do context "preserves access to metadata that doesn't end in hash" do its([], :foo) do |example| @@ -376,5 +378,58 @@ def terminator end end end + + describe "#fits" do + it 'calls #its with :focus metadata' do + stub = Class.new do + include RSpec::Its + end.new + allow(stub).to receive(:its) + + expect(stub).to receive(:its).with('attribute', :focus).and_yield + stub.fits('attribute') {} + end + + it "fits is focused within the example group" do + ex_its, ex_fits = nil + + RSpec.describe do + extend RSpec::Its + + ex_its = its(:name) { :its_example } + ex_fits = fits(:class) { :fits_example } + end + + expect(ex_its.examples.first.metadata[:focus]).to be_falsey + expect(ex_fits.examples.first.metadata[:focus]).to be_truthy + end + end + + describe "#xits" do + it 'calls #its with :skip metadata' do + stub = Class.new do + include RSpec::Its + end.new + allow(stub).to receive(:its) + + expect(stub).to receive(:its).with('attribute', :skip).and_yield + stub.xits('attribute') {} + end + + it "xits is skipped within the example group" do + ex_its, ex_xits = nil + + RSpec.describe do + extend RSpec::Its + + ex_its = its(:name) { :its_example } + ex_xits = xits(:class) { :xits_example } + end + + expect(ex_its.examples.first.metadata[:skip]).to be_falsey + expect(ex_xits.examples.first.metadata[:skip]).to be_truthy + end + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3433ee9..69fd379 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,6 @@ require 'rspec/its' -Dir['./spec/support/**/*'].each {|f| require f} +Dir['./support/**/*.rb'].each {|f| require f} class NullFormatter private From 78e40495db5cb4adf9d2ad56767399a35e26afbe Mon Sep 17 00:00:00 2001 From: Baron Bloomer Date: Mon, 7 Dec 2020 00:09:38 +0000 Subject: [PATCH 2/2] Fix comments --- lib/rspec/its.rb | 6 ++--- spec/rspec/its_spec.rb | 61 +++++++++++++++--------------------------- spec/spec_helper.rb | 2 +- 3 files changed, 26 insertions(+), 43 deletions(-) diff --git a/lib/rspec/its.rb b/lib/rspec/its.rb index 4939a01..345e01b 100644 --- a/lib/rspec/its.rb +++ b/lib/rspec/its.rb @@ -181,7 +181,7 @@ def should_not(matcher=nil, message=nil) # fits(:size) { should eq(0) } # end def fits(attribute, *options, &block) - opts = (Array(options) << :focus).uniq + opts = (options << :focus).uniq its(attribute, *opts, &block) end @@ -195,7 +195,7 @@ def fits(attribute, *options, &block) # xits(:size) { should eq(0) } # end def xits(attribute, *options, &block) - opts = (Array(options) << :skip).uniq + opts = (options << :skip).uniq its(attribute, *opts, &block) end @@ -204,7 +204,7 @@ def xits(attribute, *options, &block) RSpec.configure do |rspec| rspec.extend RSpec::Its - rspec.backtrace_exclusion_patterns << %r{/lib/rspec/its/fits/xits} + rspec.backtrace_exclusion_patterns << %r{/lib/rspec/its} end RSpec::SharedContext.send(:include, RSpec::Its) diff --git a/spec/rspec/its_spec.rb b/spec/rspec/its_spec.rb index 3ac7b18..b56838d 100644 --- a/spec/rspec/its_spec.rb +++ b/spec/rspec/its_spec.rb @@ -380,56 +380,39 @@ def terminator end describe "#fits" do - it 'calls #its with :focus metadata' do - stub = Class.new do - include RSpec::Its - end.new - allow(stub).to receive(:its) - - expect(stub).to receive(:its).with('attribute', :focus).and_yield - stub.fits('attribute') {} - end - - it "fits is focused within the example group" do - ex_its, ex_fits = nil - - RSpec.describe do - extend RSpec::Its + describe "focus with metadata" do + let(:group) do + RSpec.describe do + extend RSpec::Its - ex_its = its(:name) { :its_example } - ex_fits = fits(:class) { :fits_example } + fits(:class) { true } + end end + let(:reporter) { RSpec::Core::Reporter.new(RSpec::Core::Configuration.new) } - expect(ex_its.examples.first.metadata[:focus]).to be_falsey - expect(ex_fits.examples.first.metadata[:focus]).to be_truthy + it "generates a focused example" do + group.run(reporter) + expect(group.descendants.last.examples.first.metadata[:focus]).to be_truthy + end end end describe "#xits" do - it 'calls #its with :skip metadata' do - stub = Class.new do - include RSpec::Its - end.new - allow(stub).to receive(:its) - - expect(stub).to receive(:its).with('attribute', :skip).and_yield - stub.xits('attribute') {} - end + describe "skip with metadata" do + let(:group) do + RSpec.describe do + extend RSpec::Its - it "xits is skipped within the example group" do - ex_its, ex_xits = nil - - RSpec.describe do - extend RSpec::Its - - ex_its = its(:name) { :its_example } - ex_xits = xits(:class) { :xits_example } + xits(:class) { true } + end end + let(:reporter) { RSpec::Core::Reporter.new(RSpec::Core::Configuration.new) } - expect(ex_its.examples.first.metadata[:skip]).to be_falsey - expect(ex_xits.examples.first.metadata[:skip]).to be_truthy + it "generates a focused example" do + group.run(reporter) + expect(group.descendants.last.examples.first.metadata[:skip]).to be_truthy + end end end - end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 69fd379..81703dd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,6 @@ require 'rspec/its' -Dir['./support/**/*.rb'].each {|f| require f} +Dir['./support/**/*'].each {|f| require f} class NullFormatter private