From 98a508fc93b396c96ebd597f470b43a005de7301 Mon Sep 17 00:00:00 2001 From: Myron Marston Date: Thu, 20 Mar 2014 20:42:15 -0700 Subject: [PATCH] Make `:example` and `:context` scopes primary. Fixes #1184. --- features/command_line/dry_run.feature | 8 +- features/command_line/order.feature | 2 +- .../overriding_global_ordering.feature | 6 +- features/filtering/exclusion_filters.feature | 26 +- features/filtering/inclusion_filters.feature | 10 +- features/hooks/around_hooks.feature | 94 +++---- features/hooks/before_and_after_hooks.feature | 239 +++++++++--------- features/hooks/filtering.feature | 112 ++++---- lib/rspec/core.rb | 2 +- lib/rspec/core/configuration.rb | 6 +- lib/rspec/core/example.rb | 32 +-- lib/rspec/core/example_group.rb | 34 +-- lib/rspec/core/hooks.rb | 229 +++++++++-------- lib/rspec/core/memoized_helpers.rb | 26 +- lib/rspec/core/pending.rb | 4 +- lib/rspec/core/shared_context.rb | 2 +- spec/rspec/core/example_group_spec.rb | 12 +- spec/rspec/core/example_spec.rb | 2 +- spec/rspec/core/hooks_spec.rb | 14 +- spec/rspec/core/memoized_helpers_spec.rb | 4 +- 20 files changed, 440 insertions(+), 424 deletions(-) diff --git a/features/command_line/dry_run.feature b/features/command_line/dry_run.feature index 44a6b3d237..6fd1c01875 100644 --- a/features/command_line/dry_run.feature +++ b/features/command_line/dry_run.feature @@ -12,15 +12,15 @@ Feature: --dry-run end describe "dry run" do - before(:all) { fail } - before(:each) { fail } + before(:context) { fail } + before(:example) { fail } it "fails in example" do fail end - after(:each) { fail } - after(:all) { fail } + after(:example) { fail } + after(:context) { fail } end """ When I run `rspec --dry-run` diff --git a/features/command_line/order.feature b/features/command_line/order.feature index b05c4d336c..928fb9c0cd 100644 --- a/features/command_line/order.feature +++ b/features/command_line/order.feature @@ -9,7 +9,7 @@ Feature: --order (new in rspec-core-2.8) Use `rand` to randomize the order of groups and examples within groups.* * Nested groups are always run from top-level to bottom-level in order to avoid - executing `before(:all)` and `after(:all)` hooks more than once, but the order + executing `before(:context)` and `after(:all)` hooks more than once, but the order of groups at each level is randomized. You can also specify a seed: diff --git a/features/configuration/overriding_global_ordering.feature b/features/configuration/overriding_global_ordering.feature index dea03b0a29..2469b2a72f 100644 --- a/features/configuration/overriding_global_ordering.feature +++ b/features/configuration/overriding_global_ordering.feature @@ -17,7 +17,7 @@ Feature: Overriding global ordering Given a file named "order_dependent_spec.rb" with: """ruby describe "examples only pass when they are run in order", :order => :defined do - before(:all) { @list = [] } + before(:context) { @list = [] } it "passes when run first" do @list << 1 @@ -49,7 +49,7 @@ Feature: Overriding global ordering end describe "A group that must run in reverse order", :order => :reverse do - before(:all) { @list = [] } + before(:context) { @list = [] } it "passes when run second" do @list << 2 @@ -75,7 +75,7 @@ Feature: Overriding global ordering end describe "A group without :order metadata" do - before(:all) { @list = [] } + before(:context) { @list = [] } it "passes when run second" do @list << 2 diff --git a/features/filtering/exclusion_filters.feature b/features/filtering/exclusion_filters.feature index 756ce43d0f..e222d175a0 100644 --- a/features/filtering/exclusion_filters.feature +++ b/features/filtering/exclusion_filters.feature @@ -58,7 +58,7 @@ Feature: exclusion filters end describe "group 1", :broken => true do - before(:all) do + before(:context) do raise "you should not see me" end @@ -70,7 +70,7 @@ Feature: exclusion filters end describe "group 2", :broken => true do - before(:each) do + before(:example) do raise "you should not see me" end @@ -83,24 +83,24 @@ Feature: exclusion filters And the output should not contain "group 1" And the output should not contain "group 2" - Scenario: before/after(:all) hooks in excluded example group are not run - Given a file named "spec/before_after_all_exclusion_filter_spec.rb" with: + Scenario: before/after(:context) hooks in excluded example group are not run + Given a file named "spec/before_after_context_exclusion_filter_spec.rb" with: """ruby RSpec.configure do |c| c.filter_run_excluding :broken => true end describe "group 1" do - before(:all) { puts "before all in included group" } - after(:all) { puts "after all in included group" } + before(:context) { puts "before context in included group" } + after(:context) { puts "after context in included group" } it "group 1 example" do end end describe "group 2", :broken => true do - before(:all) { puts "before all in excluded group" } - after(:all) { puts "after all in excluded group" } + before(:context) { puts "before context in excluded group" } + after(:context) { puts "after context in excluded group" } context "context 1" do it "group 2 context 1 example 1" do @@ -108,11 +108,11 @@ Feature: exclusion filters end end """ - 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" - And the output should not contain "after all in excluded group" + When I run `rspec ./spec/before_after_context_exclusion_filter_spec.rb` + Then the output should contain "before context in included group" + And the output should contain "after context in included group" + And the output should not contain "before context in excluded group" + And the output should not contain "after context in excluded group" Scenario: Use symbols as metadata Given a file named "symbols_as_metadata_spec.rb" with: diff --git a/features/filtering/inclusion_filters.feature b/features/filtering/inclusion_filters.feature index 40893cbd16..89dbc74dd6 100644 --- a/features/filtering/inclusion_filters.feature +++ b/features/filtering/inclusion_filters.feature @@ -52,22 +52,22 @@ Feature: inclusion filters And the output should contain "group 1 example 2" And the output should not contain "group 2 example 1" - Scenario: before/after(:all) hooks in unmatched example group are not run + Scenario: before/after(:context) hooks in unmatched example group are not run Given a file named "spec/before_after_all_inclusion_filter_spec.rb" with: """ruby require "spec_helper" describe "group 1", :focus => true do - before(:all) { puts "before all in focused group" } - after(:all) { puts "after all in focused group" } + before(:context) { puts "before all in focused group" } + after(:context) { puts "after all in focused group" } it "group 1 example" do end end describe "group 2" do - before(:all) { puts "before all in unfocused group" } - after(:all) { puts "after all in unfocused group" } + before(:context) { puts "before all in unfocused group" } + after(:context) { puts "after all in unfocused group" } context "context 1" do it "group 2 context 1 example 1" do diff --git a/features/hooks/around_hooks.feature b/features/hooks/around_hooks.feature index b05387f3e7..52004471fc 100644 --- a/features/hooks/around_hooks.feature +++ b/features/hooks/around_hooks.feature @@ -28,7 +28,7 @@ Feature: around hooks end describe "around filter" do - around(:each) do |example| + around(:example) do |example| Database.transaction(&example) end @@ -49,10 +49,10 @@ Feature: around hooks Given a file named "example_spec.rb" with: """ruby describe "around hook" do - around(:each) do |example| - puts "around each before" + around(:example) do |example| + puts "around example before" example.run - puts "around each after" + puts "around example after" end it "gets run in order" do @@ -63,16 +63,16 @@ Feature: around hooks When I run `rspec example_spec.rb` Then the output should contain: """ - around each before + around example before in the example - around each after + around example after """ Scenario: access the example metadata Given a file named "example_spec.rb" with: """ruby describe "something" do - around(:each) do |example| + around(:example) do |example| puts example.metadata[:foo] example.run end @@ -88,10 +88,10 @@ Feature: around hooks Given a file named "example_spec.rb" with: """ruby RSpec.configure do |c| - c.around(:each) do |example| - puts "around each before" + c.around(:example) do |example| + puts "around example before" example.run - puts "around each after" + puts "around example after" end end @@ -104,27 +104,27 @@ Feature: around hooks When I run `rspec example_spec.rb` Then the output should contain: """ - around each before + around example before in the example - around each after + around example after """ - Scenario: before/after(:each) hooks are wrapped by the around hook + Scenario: before/after(:example) hooks are wrapped by the around hook Given a file named "example_spec.rb" with: """ruby describe "around filter" do - around(:each) do |example| - puts "around each before" + around(:example) do |example| + puts "around example before" example.run - puts "around each after" + puts "around example after" end - before(:each) do - puts "before each" + before(:example) do + puts "before example" end - after(:each) do - puts "after each" + after(:example) do + puts "after example" end it "gets run in order" do @@ -135,29 +135,29 @@ Feature: around hooks When I run `rspec example_spec.rb` Then the output should contain: """ - around each before - before each + around example before + before example in the example - after each - around each after + after example + around example after """ - Scenario: before/after(:all) hooks are NOT wrapped by the around hook + Scenario: before/after(:context) hooks are NOT wrapped by the around hook Given a file named "example_spec.rb" with: """ruby describe "around filter" do - around(:each) do |example| - puts "around each before" + around(:example) do |example| + puts "around example before" example.run - puts "around each after" + puts "around example after" end - before(:all) do - puts "before all" + before(:context) do + puts "before context" end - after(:all) do - puts "after all" + after(:context) do + puts "after context" end it "gets run in order" do @@ -168,11 +168,11 @@ Feature: around hooks When I run `rspec --format progress example_spec.rb` Then the output should contain: """ - before all - around each before + before context + around example before in the example - around each after - .after all + around example after + .after context """ Scenario: examples run by an around block are run in the configured context @@ -187,7 +187,7 @@ Feature: around hooks end describe "around filter" do - around(:each) do |example| + around(:example) do |example| example.run end @@ -203,7 +203,7 @@ Feature: around hooks Given a file named "example_spec.rb" with: """ruby describe "implicit pending example" do - around(:each) do |example| + around(:example) do |example| example.run end @@ -224,7 +224,7 @@ Feature: around hooks Given a file named "example_spec.rb" with: """ruby describe "explicit pending example" do - around(:each) do |example| + around(:example) do |example| example.run end @@ -246,13 +246,13 @@ Feature: around hooks Given a file named "example_spec.rb" with: """ruby describe "if there are multiple around hooks in the same scope" do - around(:each) do |example| + around(:example) do |example| puts "first around hook before" example.run puts "first around hook after" end - around(:each) do |example| + around(:example) do |example| puts "second around hook before" example.run puts "second around hook after" @@ -279,39 +279,39 @@ Feature: around hooks Given a file named "example_spec.rb" with: """ruby describe "if there are around hooks in an outer scope" do - around(:each) do |example| + around(:example) do |example| puts "first outermost around hook before" example.run puts "first outermost around hook after" end - around(:each) do |example| + around(:example) do |example| puts "second outermost around hook before" example.run puts "second outermost around hook after" end describe "outer scope" do - around(:each) do |example| + around(:example) do |example| puts "first outer around hook before" example.run puts "first outer around hook after" end - around(:each) do |example| + around(:example) do |example| puts "second outer around hook before" example.run puts "second outer around hook after" end describe "inner scope" do - around(:each) do |example| + around(:example) do |example| puts "first inner around hook before" example.run puts "first inner around hook after" end - around(:each) do |example| + around(:example) do |example| puts "second inner around hook before" example.run puts "second inner around hook after" diff --git a/features/hooks/before_and_after_hooks.feature b/features/hooks/before_and_after_hooks.feature index 54bfd1de5c..c2fe66c262 100644 --- a/features/hooks/before_and_after_hooks.feature +++ b/features/hooks/before_and_after_hooks.feature @@ -3,19 +3,19 @@ Feature: before and after hooks Use `before` and `after` hooks to execute arbitrary code before and/or after the body of an example is run: - before(:each) # run before each example - before(:all) # run one time only, before all of the examples in a group + before(:example) # run before each example + before(:context) # run one time only, before all of the examples in a group - after(:each) # run after each example - after(:all) # run one time only, after all of the examples in a group + after(:example) # run after each example + after(:context) # run one time only, after all of the examples in a group Before and after blocks are called in the following order: before suite - before all - before each - after each - after all + before context + before example + after example + after context after suite `before` and `after` hooks can be defined directly in the example groups they @@ -23,10 +23,13 @@ Feature: before and after hooks Setting instance variables are not supported in `before(:suite)`. - Mocks are only supported in `before(:each)`. + Mocks are only supported in `before(:example)`. - Scenario: define before(:each) block - Given a file named "before_each_spec.rb" with: + Note: the `:example` and `:context` scopes are also available as + `:each` and `:all`, respectively. Use whichever you prefer. + + Scenario: define before(:example) block + Given a file named "before_example_spec.rb" with: """ruby require "rspec/expectations" @@ -37,11 +40,11 @@ Feature: before and after hooks end describe Thing do - before(:each) do + before(:example) do @thing = Thing.new end - describe "initialized in before(:each)" do + describe "initialized in before(:example)" do it "has 0 widgets" do expect(@thing.widgets.count).to eq(0) end @@ -56,11 +59,11 @@ Feature: before and after hooks end end """ - When I run `rspec before_each_spec.rb` + When I run `rspec before_example_spec.rb` Then the examples should all pass - Scenario: define before(:all) block in example group - Given a file named "before_all_spec.rb" with: + Scenario: define before(:context) block in example group + Given a file named "before_context_spec.rb" with: """ruby require "rspec/expectations" @@ -71,11 +74,11 @@ Feature: before and after hooks end describe Thing do - before(:all) do + before(:context) do @thing = Thing.new end - describe "initialized in before(:all)" do + describe "initialized in before(:context)" do it "has 0 widgets" do expect(@thing.widgets.count).to eq(0) end @@ -90,17 +93,17 @@ Feature: before and after hooks end end """ - When I run `rspec before_all_spec.rb` + When I run `rspec before_context_spec.rb` Then the examples should all pass - When I run `rspec before_all_spec.rb:15` + When I run `rspec before_context_spec.rb:15` Then the examples should all pass - Scenario: failure in before(:all) block - Given a file named "before_all_spec.rb" with: + Scenario: failure in before(:context) block + Given a file named "before_context_spec.rb" with: """ruby - describe "an error in before(:all)" do - before(:all) do + describe "an error in before(:context)" do + before(:context) do raise "oops" end @@ -110,8 +113,8 @@ Feature: before and after hooks it "fails this example, too" do end - after(:all) do - puts "after all ran" + after(:context) do + puts "after context ran" end describe "nested group" do @@ -128,11 +131,11 @@ Feature: before and after hooks end end """ - When I run `rspec before_all_spec.rb --format documentation` + When I run `rspec before_context_spec.rb --format documentation` Then the output should contain "5 examples, 5 failures" And the output should contain: """ - an error in before(:all) + an error in before(:context) fails this example (FAILED - 1) fails this example, too (FAILED - 2) nested group @@ -140,22 +143,22 @@ Feature: before and after hooks fails this fourth example (FAILED - 4) yet another level deep fails this last example (FAILED - 5) - after all ran + after context ran """ - When I run `rspec before_all_spec.rb:9 --format documentation` + When I run `rspec before_context_spec.rb:9 --format documentation` Then the output should contain "1 example, 1 failure" And the output should contain: """ - an error in before(:all) + an error in before(:context) fails this example, too (FAILED - 1) """ - Scenario: failure in after(:all) block - Given a file named "after_all_spec.rb" with: + Scenario: failure in after(:context) block + Given a file named "after_context_spec.rb" with: """ruby - describe "an error in after(:all)" do - after(:all) do + describe "an error in after(:context)" do + after(:context) do raise StandardError.new("Boom!") end @@ -166,11 +169,11 @@ Feature: before and after hooks end end """ - When I run `rspec after_all_spec.rb` + When I run `rspec after_context_spec.rb` Then the examples should all pass And the output should contain: """ - An error occurred in an after(:all) hook. + An error occurred in an `after(:context)` hook. StandardError: Boom! """ @@ -180,23 +183,23 @@ Feature: before and after hooks require "rspec/expectations" RSpec.configure do |config| - config.before(:each) do - @before_each = "before each" + config.before(:example) do + @before_example = "before example" end - config.before(:all) do - @before_all = "before all" + config.before(:context) do + @before_context = "before context" end end describe "stuff in before blocks" do - describe "with :all" do + describe "with :context" do it "should be available in the example" do - expect(@before_all).to eq("before all") + expect(@before_context).to eq("before context") end end - describe "with :each" do + describe "with :example" do it "should be available in the example" do - expect(@before_each).to eq("before each") + expect(@before_example).to eq("before example") end end end @@ -210,20 +213,20 @@ Feature: before and after hooks require "rspec/expectations" describe "before and after callbacks" do - before(:all) do - puts "before all" + before(:context) do + puts "before context" end - before(:each) do - puts "before each" + before(:example) do + puts "before example" end - after(:each) do - puts "after each" + after(:example) do + puts "after example" end - after(:all) do - puts "after all" + after(:context) do + puts "after context" end it "gets run in order" do @@ -234,10 +237,10 @@ Feature: before and after hooks When I run `rspec --format progress ensure_block_order_spec.rb` Then the output should contain: """ - before all - before each - after each - .after all + before context + before example + after example + .after context """ Scenario: before/after blocks defined in config are run in order @@ -250,20 +253,20 @@ Feature: before and after hooks puts "before suite" end - config.before(:all) do - puts "before all" + config.before(:context) do + puts "before context" end - config.before(:each) do - puts "before each" + config.before(:example) do + puts "before example" end - config.after(:each) do - puts "after each" + config.after(:example) do + puts "after example" end - config.after(:all) do - puts "after all" + config.after(:context) do + puts "after context" end config.after(:suite) do @@ -280,141 +283,141 @@ Feature: before and after hooks Then the output should contain: """ before suite - before all - before each - after each - .after all + before context + before example + after example + .after context after suite """ - Scenario: before/after all blocks are run once - Given a file named "before_and_after_all_spec.rb" with: + Scenario: before/after context blocks are run once + Given a file named "before_and_after_context_spec.rb" with: """ruby describe "before and after callbacks" do - before(:all) do - puts "outer before all" + before(:context) do + puts "outer before context" end example "in outer group" do end - after(:all) do - puts "outer after all" + after(:context) do + puts "outer after context" end describe "nested group" do - before(:all) do - puts "inner before all" + before(:context) do + puts "inner before context" end example "in nested group" do end - after(:all) do - puts "inner after all" + after(:context) do + puts "inner after context" end end end """ - When I run `rspec --format progress before_and_after_all_spec.rb` + When I run `rspec --format progress before_and_after_context_spec.rb` Then the examples should all pass And the output should contain: """ - outer before all - .inner before all - .inner after all - outer after all + outer before context + .inner before context + .inner after context + outer after context """ - When I run `rspec --format progress before_and_after_all_spec.rb:14` + When I run `rspec --format progress before_and_after_context_spec.rb:14` Then the examples should all pass And the output should contain: """ - outer before all - inner before all - .inner after all - outer after all + outer before context + inner before context + .inner after context + outer after context """ - When I run `rspec --format progress before_and_after_all_spec.rb:6` + When I run `rspec --format progress before_and_after_context_spec.rb:6` Then the examples should all pass And the output should contain: """ - outer before all - .outer after all + outer before context + .outer after context """ - Scenario: nested examples have access to state set in outer before(:all) - Given a file named "before_all_spec.rb" with: + Scenario: nested examples have access to state set in outer before(:context) + Given a file named "before_context_spec.rb" with: """ruby describe "something" do - before :all do + before :context do @value = 123 end describe "nested" do - it "access state set in before(:all)" do + it "access state set in before(:context)" do expect(@value).to eq(123) end describe "nested more deeply" do - it "access state set in before(:all)" do + it "access state set in before(:context)" do expect(@value).to eq(123) end end end describe "nested in parallel" do - it "access state set in before(:all)" do + it "access state set in before(:context)" do expect(@value).to eq(123) end end end """ - When I run `rspec before_all_spec.rb` + When I run `rspec before_context_spec.rb` Then the examples should all pass - Scenario: before/after all blocks have access to state - Given a file named "before_and_after_all_spec.rb" with: + Scenario: before/after context blocks have access to state + Given a file named "before_and_after_context_spec.rb" with: """ruby describe "before and after callbacks" do - before(:all) do - @outer_state = "set in outer before all" + before(:context) do + @outer_state = "set in outer before context" end example "in outer group" do - expect(@outer_state).to eq("set in outer before all") + expect(@outer_state).to eq("set in outer before context") end describe "nested group" do - before(:all) do - @inner_state = "set in inner before all" + before(:context) do + @inner_state = "set in inner before context" end example "in nested group" do - expect(@outer_state).to eq("set in outer before all") - expect(@inner_state).to eq("set in inner before all") + expect(@outer_state).to eq("set in outer before context") + expect(@inner_state).to eq("set in inner before context") end - after(:all) do - expect(@inner_state).to eq("set in inner before all") + after(:context) do + expect(@inner_state).to eq("set in inner before context") end end - after(:all) do - expect(@outer_state).to eq("set in outer before all") + after(:context) do + expect(@outer_state).to eq("set in outer before context") end end """ - When I run `rspec before_and_after_all_spec.rb` + When I run `rspec before_and_after_context_spec.rb` Then the examples should all pass - Scenario: exception in before(:each) is captured and reported as failure - Given a file named "error_in_before_each_spec.rb" with: + Scenario: exception in before(:example) is captured and reported as failure + Given a file named "error_in_before_example_spec.rb" with: """ruby - describe "error in before(:each)" do - before(:each) do + describe "error in before(:example)" do + before(:example) do raise "this error" end @@ -422,6 +425,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_example_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 058b5bf061..dd47ff2781 100644 --- a/features/hooks/filtering.feature +++ b/features/hooks/filtering.feature @@ -5,7 +5,7 @@ Feature: filters metadata as a filter. RSpec.configure do |c| - c.before(:each, :type => :model) do + c.before(:example, :type => :model) do end end @@ -14,16 +14,16 @@ Feature: filters You can also specify metadata using only symbols. - Scenario: filter `before(:each)` hooks using arbitrary metadata - Given a file named "filter_before_each_hooks_spec.rb" with: + Scenario: filter `before(:example)` hooks using arbitrary metadata + Given a file named "filter_before_example_hooks_spec.rb" with: """ruby RSpec.configure do |config| - config.before(:each, :foo => :bar) do - invoked_hooks << :before_each_foo_bar + config.before(:example, :foo => :bar) do + invoked_hooks << :before_example_foo_bar end end - describe "a filtered before :each hook" do + describe "a filtered before :example hook" do let(:invoked_hooks) { [] } describe "group without matching metadata" do @@ -32,30 +32,30 @@ Feature: filters end it "runs the hook for an example with matching metadata", :foo => :bar do - expect(invoked_hooks).to eq([:before_each_foo_bar]) + expect(invoked_hooks).to eq([:before_example_foo_bar]) end end describe "group with matching metadata", :foo => :bar do it "runs the hook" do - expect(invoked_hooks).to eq([:before_each_foo_bar]) + expect(invoked_hooks).to eq([:before_example_foo_bar]) end end end """ - When I run `rspec filter_before_each_hooks_spec.rb` + When I run `rspec filter_before_example_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: + Scenario: filter `after(:example)` hooks using arbitrary metadata + Given a file named "filter_after_example_hooks_spec.rb" with: """ruby RSpec.configure do |config| - config.after(:each, :foo => :bar) do + config.after(:example, :foo => :bar) do raise "boom!" end end - describe "a filtered after :each hook" do + describe "a filtered after :example hook" do describe "group without matching metadata" do it "does not run the hook" do # should pass @@ -73,21 +73,21 @@ Feature: filters end end """ - When I run `rspec filter_after_each_hooks_spec.rb` + When I run `rspec filter_after_example_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: + Scenario: filter around(:example) hooks using arbitrary metadata + Given a file named "filter_around_example_hooks_spec.rb" with: """ruby RSpec.configure do |config| - config.around(:each, :foo => :bar) do |example| - order << :before_around_each_foo_bar + config.around(:example, :foo => :bar) do |example| + order << :before_around_example_foo_bar example.run - expect(order).to eq([:before_around_each_foo_bar, :example]) + expect(order).to eq([:before_around_example_foo_bar, :example]) end end - describe "a filtered around(:each) hook" do + describe "a filtered around(:example) hook" do let(:order) { [] } describe "a group without matching metadata" do @@ -96,30 +96,30 @@ Feature: filters end it "runs the hook for an example with matching metadata", :foo => :bar do - expect(order).to eq([:before_around_each_foo_bar]) + expect(order).to eq([:before_around_example_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 - expect(order).to eq([:before_around_each_foo_bar]) + expect(order).to eq([:before_around_example_foo_bar]) order << :example end end end """ - When I run `rspec filter_around_each_hooks_spec.rb` + When I run `rspec filter_around_example_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: + Scenario: filter before(:context) hooks using arbitrary metadata + Given a file named "filter_before_context_hooks_spec.rb" with: """ruby RSpec.configure do |config| - config.before(:all, :foo => :bar) { @hook = :before_all_foo_bar } + config.before(:context, :foo => :bar) { @hook = :before_context_foo_bar } end - describe "a filtered before(:all) hook" do + describe "a filtered before(:context) hook" do describe "a group without matching metadata" do it "does not run the hook" do expect(@hook).to be_nil @@ -127,39 +127,39 @@ Feature: filters describe "a nested subgroup with matching metadata", :foo => :bar do it "runs the hook" do - expect(@hook).to eq(:before_all_foo_bar) + expect(@hook).to eq(:before_context_foo_bar) end end end describe "a group with matching metadata", :foo => :bar do it "runs the hook" do - expect(@hook).to eq(:before_all_foo_bar) + expect(@hook).to eq(:before_context_foo_bar) end describe "a nested subgroup" do it "runs the hook" do - expect(@hook).to eq(:before_all_foo_bar) + expect(@hook).to eq(:before_context_foo_bar) end end end end """ - When I run `rspec filter_before_all_hooks_spec.rb` + When I run `rspec filter_before_context_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: + Scenario: filter after(:context) hooks using arbitrary metadata + Given a file named "filter_after_context_hooks_spec.rb" with: """ruby example_msgs = [] RSpec.configure do |config| - config.after(:all, :foo => :bar) do - puts "after :all" + config.after(:context, :foo => :bar) do + puts "after :context" end end - describe "a filtered after(:all) hook" do + describe "a filtered after(:context) hook" do describe "a group without matching metadata" do it "does not run the hook" do puts "unfiltered" @@ -181,52 +181,52 @@ Feature: filters end end """ - When I run `rspec --format progress filter_after_all_hooks_spec.rb` + When I run `rspec --format progress filter_after_context_hooks_spec.rb` Then the examples should all pass And the output should contain: """ unfiltered .filtered 1 - .after :all + .after :context filtered 2 - .after :all + .after :context """ Scenario: Use symbols as metadata Given a file named "less_verbose_metadata_filter.rb" with: """ruby RSpec.configure do |c| - 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)" + c.before(:example, :before_example) { puts "before example" } + c.after(:example, :after_example) { puts "after example" } + c.around(:example, :around_example) do |example| + puts "around example (before)" example.run - puts "around each (after)" + puts "around example (after)" end - c.before(:all, :before_all) { puts "before all" } - c.after(:all, :after_all) { puts "after all" } + c.before(:context, :before_context) { puts "before context" } + c.after(:context, :after_context) { puts "after context" } end - describe "group 1", :before_all, :after_all do + describe "group 1", :before_context, :after_context do it("") { puts "example 1" } - it("", :before_each) { puts "example 2" } - it("", :after_each) { puts "example 3" } - it("", :around_each) { puts "example 4" } + it("", :before_example) { puts "example 2" } + it("", :after_example) { puts "example 3" } + it("", :around_example) { puts "example 4" } end """ When I run `rspec --format progress less_verbose_metadata_filter.rb` Then the examples should all pass And the output should contain: """ - before all + before context example 1 - .before each + .before example example 2 .example 3 - after each - .around each (before) + after example + .around example (before) example 4 - around each (after) - .after all + around example (after) + .after context """ diff --git a/lib/rspec/core.rb b/lib/rspec/core.rb index b8a7444f2a..19152d2cb8 100644 --- a/lib/rspec/core.rb +++ b/lib/rspec/core.rb @@ -98,7 +98,7 @@ def self.configure # fetch_current_example = RSpec.respond_to?(:current_example) ? # proc { RSpec.current_example } : proc { |context| context.example } # - # c.before(:each) do + # c.before(:example) do # example = fetch_current_example.call(self) # # # ... diff --git a/lib/rspec/core/configuration.rb b/lib/rspec/core/configuration.rb index 49c4ca4f32..bf6ef6b207 100644 --- a/lib/rspec/core/configuration.rb +++ b/lib/rspec/core/configuration.rb @@ -22,9 +22,9 @@ module Core # # @example Hooks # RSpec.configure do |c| - # c.before(:suite) { establish_connection } - # c.before(:each) { log_in_as :authorized } - # c.around(:each) { |ex| Database.transaction(&ex) } + # c.before(:suite) { establish_connection } + # c.before(:example) { log_in_as :authorized } + # c.around(:example) { |ex| Database.transaction(&ex) } # end # # @see RSpec.configure diff --git a/lib/rspec/core/example.rb b/lib/rspec/core/example.rb index 8f5d4b7af9..d85066292b 100644 --- a/lib/rspec/core/example.rb +++ b/lib/rspec/core/example.rb @@ -125,9 +125,9 @@ def run(example_group_instance, reporter) if skipped? Pending.mark_pending! self, skip elsif !RSpec.configuration.dry_run? - with_around_each_hooks do + with_around_example_hooks do begin - run_before_each + run_before_example @example_group_instance.instance_exec(self, &@example_block) if pending? @@ -143,7 +143,7 @@ def run(example_group_instance, reporter) rescue Exception => e set_exception(e) ensure - run_after_each + run_after_example end end end @@ -209,8 +209,8 @@ def all_apply?(filters) end # @private - def around_each_hooks - @around_each_hooks ||= example_group.hooks.around_each_hooks_for(self) + def around_example_hooks + @around_example_hooks ||= example_group.hooks.around_example_hooks_for(self) end # @private @@ -241,7 +241,7 @@ def set_exception(exception, context=nil) # @private # # Used internally to set an exception and fail without actually executing - # the example when an exception is raised in before(:all). + # the example when an exception is raised in before(:context). def fail_with_exception(reporter, exception) start(reporter) set_exception(exception) @@ -251,7 +251,7 @@ def fail_with_exception(reporter, exception) # @private # # Used internally to skip without actually executing the example when - # skip is used in before(:all) + # skip is used in before(:context) def skip_with_exception(reporter, exception) start(reporter) Pending.mark_skipped! self, exception.argument @@ -272,14 +272,14 @@ def instance_exec(*args, &block) private - def with_around_each_hooks(&block) - if around_each_hooks.empty? + def with_around_example_hooks(&block) + if around_example_hooks.empty? yield else - @example_group_class.hooks.run(:around, :each, self, Procsy.new(metadata, &block)) + @example_group_class.hooks.run(:around, :example, self, Procsy.new(metadata, &block)) end rescue Exception => e - set_exception(e, "in an around(:each) hook") + set_exception(e, "in an `around(:example)` hook") end def start(reporter) @@ -311,17 +311,17 @@ def record_finished(status) execution_result.record_finished(status, clock.now) end - def run_before_each + def run_before_example @example_group_instance.setup_mocks_for_rspec - @example_group_class.hooks.run(:before, :each, self) + @example_group_class.hooks.run(:before, :example, self) end - def run_after_each - @example_group_class.hooks.run(:after, :each, self) + def run_after_example + @example_group_class.hooks.run(:after, :example, self) verify_mocks assign_generated_description if RSpec.configuration.expecting_with_rspec? rescue Exception => e - set_exception(e, "in an after(:each) hook") + set_exception(e, "in an `after(:example)` hook") ensure @example_group_instance.teardown_mocks_for_rspec end diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index adcaa580c7..701c8dfd95 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -382,40 +382,40 @@ def self.ensure_example_groups_are_configured end # @private - def self.before_all_ivars - @before_all_ivars ||= {} + def self.before_context_ivars + @before_context_ivars ||= {} end # @private - def self.store_before_all_ivars(example_group_instance) + def self.store_before_context_ivars(example_group_instance) return if example_group_instance.instance_variables.empty? example_group_instance.instance_variables.each { |ivar| - before_all_ivars[ivar] = example_group_instance.instance_variable_get(ivar) + before_context_ivars[ivar] = example_group_instance.instance_variable_get(ivar) } end # @private - def self.run_before_all_hooks(example_group_instance) + def self.run_before_context_hooks(example_group_instance) return if descendant_filtered_examples.empty? begin - set_ivars(example_group_instance, superclass.before_all_ivars) + set_ivars(example_group_instance, superclass.before_context_ivars) - AllHookMemoizedHash::Before.isolate_for_all_hook(example_group_instance) do - hooks.run(:before, :all, example_group_instance) + ContextHookMemoizedHash::Before.isolate_for_context_hook(example_group_instance) do + hooks.run(:before, :context, example_group_instance) end ensure - store_before_all_ivars(example_group_instance) + store_before_context_ivars(example_group_instance) end end # @private - def self.run_after_all_hooks(example_group_instance) + def self.run_after_context_hooks(example_group_instance) return if descendant_filtered_examples.empty? - set_ivars(example_group_instance, before_all_ivars) + set_ivars(example_group_instance, before_context_ivars) - AllHookMemoizedHash::After.isolate_for_all_hook(example_group_instance) do - hooks.run(:after, :all, example_group_instance) + ContextHookMemoizedHash::After.isolate_for_context_hook(example_group_instance) do + hooks.run(:after, :context, example_group_instance) end end @@ -428,7 +428,7 @@ def self.run(reporter) reporter.example_group_started(self) begin - run_before_all_hooks(new) + run_before_context_hooks(new) result_for_this_group = run_examples(reporter) results_for_descendants = ordering_strategy.order(children).map { |child| child.run(reporter) }.all? result_for_this_group && results_for_descendants @@ -438,8 +438,8 @@ def self.run(reporter) RSpec.world.wants_to_quit = true if fail_fast? for_filtered_examples(reporter) {|example| example.fail_with_exception(reporter, ex) } ensure - run_after_all_hooks(new) - before_all_ivars.clear + run_after_context_hooks(new) + before_context_ivars.clear reporter.example_group_finished(self) end end @@ -465,7 +465,7 @@ def self.run_examples(reporter) ordering_strategy.order(filtered_examples).map do |example| next if RSpec.world.wants_to_quit instance = new - set_ivars(instance, before_all_ivars) + set_ivars(instance, before_context_ivars) succeeded = example.run(instance, reporter) RSpec.world.wants_to_quit = true if fail_fast? && !succeeded succeeded diff --git a/lib/rspec/core/hooks.rb b/lib/rspec/core/hooks.rb index 9b82c59477..03ee8a60b0 100644 --- a/lib/rspec/core/hooks.rb +++ b/lib/rspec/core/hooks.rb @@ -3,16 +3,21 @@ module Core # Hooks module Hooks # @api public + # # @overload before(&block) # @overload before(scope, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to `:example`) # @overload before(scope, conditions, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to `:example`) + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `before(:example, :ui => true) { ... }` will only run with examples or + # groups declared with `:ui => true`. # @overload before(conditions, &block) - # - # @option scope [Symbol] `:each`, `:all`, or `:suite` (defaults to `:each`) - # @option conditions [Hash] - # constrains this hook to examples matching these conditions e.g. - # `before(:each, :ui => true) { ... }` will only run with examples or - # groups declared with `:ui => true`. + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `before(:example, :ui => true) { ... }` will only run with examples or + # groups declared with `:ui => true`. # # @see #after # @see #around @@ -21,43 +26,43 @@ module Hooks # @see SharedExampleGroup # @see Configuration # - # Declare a block of code to be run before each example (using `:each`) - # or once before any example (using `:all`). These are usually declared + # Declare a block of code to be run before each example (using `:example`) + # or once before any example (using `:context`). These are usually declared # directly in the {ExampleGroup} to which they apply, but they can also # be shared across multiple groups. # # You can also use `before(:suite)` to run a block of code before any # example groups are run. This should be declared in {RSpec.configure} # - # Instance variables declared in `before(:each)` or `before(:all)` are + # Instance variables declared in `before(:example)` or `before(:context)` are # accessible within each example. # # ### Order # # `before` hooks are stored in three scopes, which are run in order: - # `:suite`, `:all`, and `:each`. They can also be declared in several + # `:suite`, `:context`, and `:example`. They can also be declared in several # different places: `RSpec.configure`, a parent group, the current group. # They are run in the following order: # - # before(:suite) # declared in RSpec.configure - # before(:all) # declared in RSpec.configure - # before(:all) # declared in a parent group - # before(:all) # declared in the current group - # before(:each) # declared in RSpec.configure - # before(:each) # declared in a parent group - # before(:each) # declared in the current group + # before(:suite) # declared in RSpec.configure + # before(:context) # declared in RSpec.configure + # before(:context) # declared in a parent group + # before(:context) # declared in the current group + # before(:example) # declared in RSpec.configure + # before(:example) # declared in a parent group + # before(:example) # declared in the current group # # If more than one `before` is declared within any one scope, they are run # in the order in which they are declared. # # ### Conditions # - # When you add a conditions hash to `before(:each)` or `before(:all)`, + # When you add a conditions hash to `before(:example)` or `before(:context)`, # RSpec will only apply that hook to groups or examples that match the # conditions. e.g. # # RSpec.configure do |config| - # config.before(:each, :authorized => true) do + # config.before(:example, :authorized => true) do # log_in_as :authorized_user # end # end @@ -86,7 +91,7 @@ module Hooks # # When an exception is raised in a `before` block, RSpec skips any # subsequent `before` blocks and the example, but runs all of the - # `after(:each)` and `after(:all)` hooks. + # `after(:example)` and `after(:context)` hooks. # # ### Warning: implicit before blocks # @@ -97,20 +102,20 @@ module Hooks # before block depends on state that is prepared in another before block # that gets run later. # - # ### Warning: `before(:all)` + # ### Warning: `before(:context)` # - # It is very tempting to use `before(:all)` to speed things up, but we + # It is very tempting to use `before(:context)` to speed things up, but we # recommend that you avoid this as there are a number of gotchas, as well # as things that simply don't work. # # #### context # - # `before(:all)` is run in an example that is generated to provide group + # `before(:context)` is run in an example that is generated to provide group # context for the block. # # #### instance variables # - # Instance variables declared in `before(:all)` are shared across all the + # Instance variables declared in `before(:context)` are shared across all the # examples in the group. This means that each example can change the # state of a shared object, resulting in an ordering dependency that can # make it difficult to reason about failures. @@ -118,7 +123,7 @@ module Hooks # #### unsupported rspec constructs # # RSpec has several constructs that reset state between each example - # automatically. These are not intended for use from within `before(:all)`: + # automatically. These are not intended for use from within `before(:context)`: # # * `let` declarations # * `subject` declarations @@ -130,17 +135,17 @@ module Hooks # ActiveRecord) are typically designed around the idea of setting up # before an example, running that one example, and then tearing down. # This means that mocks and stubs can (sometimes) be declared in - # `before(:all)`, but get torn down before the first real example is ever + # `before(:context)`, but get torn down before the first real example is ever # run. # - # You _can_ create database-backed model objects in a `before(:all)` in + # You _can_ create database-backed model objects in a `before(:context)` in # rspec-rails, but it will not be wrapped in a transaction for you, so - # you are on your own to clean up in an `after(:all)` block. + # you are on your own to clean up in an `after(:context)` block. # - # @example before(:each) declared in an {ExampleGroup} + # @example before(:example) declared in an {ExampleGroup} # # describe Thing do - # before(:each) do + # before(:example) do # @thing = Thing.new # end # @@ -149,10 +154,10 @@ module Hooks # end # end # - # @example before(:all) declared in an {ExampleGroup} + # @example before(:context) declared in an {ExampleGroup} # # describe Parser do - # before(:all) do + # before(:context) do # File.open(file_to_parse, 'w') do |f| # f.write <<-CONTENT # stuff in the file @@ -164,10 +169,13 @@ module Hooks # Parser.parse(file_to_parse) # end # - # after(:all) do + # after(:context) do # File.delete(file_to_parse) # end # end + # + # @note The `:example` and `:context` scopes are also available as + # `:each` and `:all`, respectively. Use whichever you prefer. def before(*args, &block) hooks.register :append, :before, *args, &block end @@ -175,9 +183,9 @@ def before(*args, &block) alias_method :append_before, :before # Adds `block` to the front of the list of `before` blocks in the same - # scope (`:each`, `:all`, or `:suite`). + # scope (`:example`, `:context`, or `:suite`). # - # See #before for scoping semantics. + # See {#before} for scoping semantics. def prepend_before(*args, &block) hooks.register :prepend, :before, *args, &block end @@ -185,14 +193,18 @@ def prepend_before(*args, &block) # @api public # @overload after(&block) # @overload after(scope, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to `:example`) # @overload after(scope, conditions, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to `:example`) + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `after(:example, :ui => true) { ... }` will only run with examples or + # groups declared with `:ui => true`. # @overload after(conditions, &block) - # - # @option scope [Symbol] `:each`, `:all`, or `:suite` (defaults to `:each`) - # @option conditions [Hash] - # constrains this hook to examples matching these conditions e.g. - # `after(:each, :ui => true) { ... }` will only run with examples or - # groups declared with `:ui => true`. + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `after(:example, :ui => true) { ... }` will only run with examples or + # groups declared with `:ui => true`. # # @see #before # @see #around @@ -201,10 +213,9 @@ def prepend_before(*args, &block) # @see SharedExampleGroup # @see Configuration # - # Declare a block of code to be run after each example (using `:each`) or - # once after all examples (using `:all`). See - # [#before](Hooks#before-instance_method) for more information about - # ordering. + # Declare a block of code to be run after each example (using `:example`) or + # once after all examples n the context (using `:context`). See {#before} for + # more information about ordering. # # ### Exceptions # @@ -216,20 +227,24 @@ def prepend_before(*args, &block) # ### Order # # `after` hooks are stored in three scopes, which are run in order: - # `:each`, `:all`, and `:suite`. They can also be declared in several + # `:example`, `:context`, and `:suite`. They can also be declared in several # different places: `RSpec.configure`, a parent group, the current group. # They are run in the following order: # - # after(:each) # declared in the current group - # after(:each) # declared in a parent group - # after(:each) # declared in RSpec.configure - # after(:all) # declared in the current group - # after(:all) # declared in a parent group - # after(:all) # declared in RSpec.configure + # after(:example) # declared in the current group + # after(:example) # declared in a parent group + # after(:example) # declared in RSpec.configure + # after(:context) # declared in the current group + # after(:context) # declared in a parent group + # after(:context) # declared in RSpec.configure + # after(:suite) # declared in RSpec.configure # # This is the reverse of the order in which `before` hooks are run. # Similarly, if more than one `after` is declared within any one scope, # they are run in reverse order of that in which they are declared. + # + # @note The `:example` and `:context` scopes are also available as + # `:each` and `:all`, respectively. Use whichever you prefer. def after(*args, &block) hooks.register :prepend, :after, *args, &block end @@ -237,9 +252,9 @@ def after(*args, &block) alias_method :prepend_after, :after # Adds `block` to the back of the list of `after` blocks in the same - # scope (`:each`, `:all`, or `:suite`). + # scope (`:example`, `:context`, or `:suite`). # - # See #after for scoping semantics. + # See {#after} for scoping semantics. def append_after(*args, &block) hooks.register :append, :after, *args, &block end @@ -247,17 +262,22 @@ def append_after(*args, &block) # @api public # @overload around(&block) # @overload around(scope, &block) + # @param scope [Symbol] `:example` (defaults to `:example`) + # present for syntax parity with `before` and `after`, but + # `:example`/`:each` is the only supported value. # @overload around(scope, conditions, &block) + # @param scope [Symbol] `:example` (defaults to `:example`) + # present for syntax parity with `before` and `after`, but + # `:example`/`:each` is the only supported value. + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `around(:example, :ui => true) { ... }` will only run with examples or + # groups declared with `:ui => true`. # @overload around(conditions, &block) - # - # @option scope [Symbol] `:each` (defaults to `:each`) - # present for syntax parity with `before` and `after`, but `:each` is - # the only supported value. - # - # @option conditions [Hash] - # constrains this hook to examples matching these conditions e.g. - # `around(:each, :ui => true) { ... }` will only run with examples or - # groups declared with `:ui => true`. + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `around(:example, :ui => true) { ... }` will only run with examples or + # groups declared with `:ui => true`. # # @yield [Example] the example to run # @@ -269,12 +289,12 @@ def append_after(*args, &block) # resources that are made available within the examples and their # associated `before` and `after` hooks. # - # @note `:each` is the only supported scope. + # @note `:example`/`:each` is the only supported scope. # # Declare a block of code, parts of which will be run before and parts # after the example. It is your responsibility to run the example: # - # around(:each) do |ex| + # around(:example) do |ex| # # do some stuff before # ex.run # # do some stuff after @@ -285,8 +305,8 @@ def append_after(*args, &block) # that manage their own setup and teardown using a block or proc syntax, # e.g. # - # around(:each) {|ex| Database.transaction(&ex)} - # around(:each) {|ex| FakeFS(&ex)} + # around(:example) {|ex| Database.transaction(&ex)} + # around(:example) {|ex| FakeFS(&ex)} # def around(*args, &block) hooks.register :prepend, :around, *args, &block @@ -296,9 +316,9 @@ def around(*args, &block) # Holds the various registered hooks. def hooks @hooks ||= HookCollections.new(self, - :around => { :each => AroundHookCollection.new }, - :before => { :each => HookCollection.new, :all => HookCollection.new, :suite => HookCollection.new }, - :after => { :each => HookCollection.new, :all => HookCollection.new, :suite => HookCollection.new } + :around => { :example => AroundHookCollection.new }, + :before => { :example => HookCollection.new, :context => HookCollection.new, :suite => HookCollection.new }, + :after => { :example => HookCollection.new, :context => HookCollection.new, :suite => HookCollection.new } ) end @@ -341,14 +361,14 @@ def display_name end # @private - class AfterAllHook < Hook + class AfterContextHook < Hook def run(example) example.instance_exec(example, &block) rescue Exception => e # TODO: come up with a better solution for this. RSpec.configuration.reporter.message <<-EOS -An error occurred in an after(:all) hook. +An error occurred in an `after(:context)` hook. #{e.class}: #{e.message} occurred at #{e.backtrace.first} @@ -356,7 +376,7 @@ def run(example) end def display_name - "after(:all) hook" + "after(:context) hook" end end @@ -448,17 +468,17 @@ def [](key) end def register_globals(host, globals) - process(host, globals, :before, :each) - process(host, globals, :after, :each) - process(host, globals, :around, :each) + process(host, globals, :before, :example) + process(host, globals, :after, :example) + process(host, globals, :around, :example) - process(host, globals, :before, :all) - process(host, globals, :after, :all) + process(host, globals, :before, :context) + process(host, globals, :after, :context) end - def around_each_hooks_for(example, initial_procsy=nil) + def around_example_hooks_for(example, initial_procsy=nil) AroundHookCollection.new(FlatMap.flat_map(@owner.parent_groups) do |a| - a.hooks[:around][:each] + a.hooks[:around][:example] end).for(example, initial_procsy) end @@ -476,12 +496,9 @@ def run(hook, scope, example_or_group, initial_procsy=nil) find_hook(hook, scope, example_or_group, initial_procsy).run end - SCOPES = [:each, :all, :suite] + SCOPES = [:example, :context, :suite] - SCOPE_ALIASES = { - :example => :each, - :context => :all, - } + SCOPE_ALIASES = { :each => :example, :all => :context } HOOK_TYPES = { :before => Hash.new { BeforeHook }, @@ -489,13 +506,13 @@ def run(hook, scope, example_or_group, initial_procsy=nil) :around => Hash.new { AroundHook } } - HOOK_TYPES[:after][:all] = AfterAllHook + HOOK_TYPES[:after][:context] = AfterContextHook private def process(host, globals, position, scope) globals[position][scope].each do |hook| - next unless scope == :each || hook.options_apply?(host) + next unless scope == :example || hook.options_apply?(host) next if host.parent_groups.any? {|a| a.hooks[position][scope].include?(hook)} self[position][scope] << hook end @@ -512,7 +529,7 @@ def extract_scope_from(args) error_message = "You must explicitly give a scope (#{SCOPES.join(", ")}) or scope alias (#{SCOPE_ALIASES.keys.join(", ")}) when using symbols as metadata for a hook." raise ArgumentError.new error_message else - :each + :example end end @@ -528,38 +545,38 @@ def normalized_scope_for(scope) def find_hook(hook, scope, example_or_group, initial_procsy) case [hook, scope] - when [:before, :all] - before_all_hooks_for(example_or_group) - when [:after, :all] - after_all_hooks_for(example_or_group) - when [:around, :each] - around_each_hooks_for(example_or_group, initial_procsy) - when [:before, :each] - before_each_hooks_for(example_or_group) - when [:after, :each] - after_each_hooks_for(example_or_group) + when [:before, :context] + before_context_hooks_for(example_or_group) + when [:after, :context] + after_context_hooks_for(example_or_group) + when [:around, :example] + around_example_hooks_for(example_or_group, initial_procsy) + when [:before, :example] + before_example_hooks_for(example_or_group) + when [:after, :example] + after_example_hooks_for(example_or_group) when [:before, :suite], [:after, :suite] self[hook][:suite].with(example_or_group) end end - def before_all_hooks_for(group) - GroupHookCollection.new(self[:before][:all]).for(group) + def before_context_hooks_for(group) + GroupHookCollection.new(self[:before][:context]).for(group) end - def after_all_hooks_for(group) - GroupHookCollection.new(self[:after][:all]).for(group) + def after_context_hooks_for(group) + GroupHookCollection.new(self[:after][:context]).for(group) end - def before_each_hooks_for(example) + def before_example_hooks_for(example) HookCollection.new(FlatMap.flat_map(@owner.parent_groups.reverse) do |a| - a.hooks[:before][:each] + a.hooks[:before][:example] end).for(example) end - def after_each_hooks_for(example) + def after_example_hooks_for(example) HookCollection.new(FlatMap.flat_map(@owner.parent_groups) do |a| - a.hooks[:after][:each] + a.hooks[:after][:example] end).for(example) end end diff --git a/lib/rspec/core/memoized_helpers.rb b/lib/rspec/core/memoized_helpers.rb index 4349bd863d..7e111d7f58 100644 --- a/lib/rspec/core/memoized_helpers.rb +++ b/lib/rspec/core/memoized_helpers.rb @@ -42,11 +42,9 @@ module MemoizedHelpers # end # # @note Because `subject` is designed to create state that is reset between - # each example, and `before(:all)` is designed to setup state that is + # each example, and `before(:context)` is designed to setup state that is # shared across _all_ examples in an example group, `subject` is _not_ - # intended to be used in a `before(:all)` hook. RSpec 2.13.1 prints - # a warning when you reference a `subject` from `before(:all)` and we plan - # to have it raise an error in RSpec 3. + # intended to be used in a `before(:context)` hook. # # @see #should def subject @@ -124,11 +122,11 @@ def __memoized end # Used internally to customize the behavior of the - # memoized hash when used in a `before(:all)` hook. + # memoized hash when used in a `before(:context)` hook. # # @private - class AllHookMemoizedHash - def self.isolate_for_all_hook(example_group_instance) + class ContextHookMemoizedHash + def self.isolate_for_context_hook(example_group_instance) hash = self example_group_instance.instance_exec do @@ -163,7 +161,7 @@ def self.fetch(key, &block) # @private class Before < self def self.hook_expression - "`before(:all)`" + "`before(:context)`" end def self.article @@ -178,7 +176,7 @@ def self.hook_intention # @private class After < self def self.hook_expression - "`after(:all)`" + "`after(:context)`" end def self.article @@ -210,11 +208,9 @@ module ClassMethods # though we have yet to see this in practice. You've been warned. # # @note Because `let` is designed to create state that is reset between - # each example, and `before(:all)` is designed to setup state that is + # each example, and `before(:context)` is designed to setup state that is # shared across _all_ examples in an example group, `let` is _not_ - # intended to be used in a `before(:all)` hook. RSpec 2.13.1 prints - # a warning when you reference a `let` from `before(:all)` and we plan - # to have it raise an error in RSpec 3. + # intended to be used in a `before(:context)` hook. # # @example # @@ -269,7 +265,7 @@ def let(name, &block) # end # # describe Thing do - # after(:each) { Thing.reset_count } + # after(:example) { Thing.reset_count } # # context "using let" do # let(:thing) { Thing.new } @@ -370,7 +366,7 @@ def subject(name=nil, &block) # end # # describe Thing do - # after(:each) { Thing.reset_count } + # after(:example) { Thing.reset_count } # # context "using subject" do # subject { Thing.new } diff --git a/lib/rspec/core/pending.rb b/lib/rspec/core/pending.rb index 0a2236cfb5..376f850c39 100644 --- a/lib/rspec/core/pending.rb +++ b/lib/rspec/core/pending.rb @@ -51,7 +51,7 @@ class PendingExampleFixedError < StandardError; end # end # end # - # @note `before(:each)` hooks are eval'd when you use the `pending` + # @note `before(:example)` hooks are eval'd when you use the `pending` # method within an example. If you want to declare an example `pending` # and bypass the `before` hooks as well, you can pass `:pending => true` # to the `it` method: @@ -91,7 +91,7 @@ def pending(*args) Pending.mark_pending! current_example, args.first else raise "`pending` may not be used outside of examples, such as in " + - "before(:all). Maybe you want `skip`?" + "before(:context). Maybe you want `skip`?" end end diff --git a/lib/rspec/core/shared_context.rb b/lib/rspec/core/shared_context.rb index b5690eb26c..6de7f649d0 100644 --- a/lib/rspec/core/shared_context.rb +++ b/lib/rspec/core/shared_context.rb @@ -7,7 +7,7 @@ module Core # # module LoggedInAsAdmin # extend RSpec::Core::SharedContext - # before(:each) do + # before(:example) do # log_in_as :admin # end # end diff --git a/spec/rspec/core/example_group_spec.rb b/spec/rspec/core/example_group_spec.rb index 56e782fb35..01e361407f 100644 --- a/spec/rspec/core/example_group_spec.rb +++ b/spec/rspec/core/example_group_spec.rb @@ -786,10 +786,10 @@ def define_and_run_group(define_outer_example = false) outer.run - expect(inner.before_all_ivars[:@inner]).to be_nil - expect(inner.before_all_ivars[:@outer]).to be_nil - expect(outer.before_all_ivars[:@inner]).to be_nil - expect(outer.before_all_ivars[:@outer]).to be_nil + expect(inner.before_context_ivars[:@inner]).to be_nil + expect(inner.before_context_ivars[:@outer]).to be_nil + expect(outer.before_context_ivars[:@inner]).to be_nil + expect(outer.before_context_ivars[:@outer]).to be_nil end end @@ -1194,11 +1194,11 @@ def extract_execution_results(group) end it "can access the before all ivars in the before_all_ivars hash", :ruby => 1.8 do |ex| - expect(ex.example_group.before_all_ivars).to include('@before_all_top_level' => 'before_all_top_level') + expect(ex.example_group.before_context_ivars).to include('@before_all_top_level' => 'before_all_top_level') end it "can access the before all ivars in the before_all_ivars hash", :ruby => 1.9 do |ex| - expect(ex.example_group.before_all_ivars).to include(:@before_all_top_level => 'before_all_top_level') + expect(ex.example_group.before_context_ivars).to include(:@before_all_top_level => 'before_all_top_level') end describe "but now I am nested" do diff --git a/spec/rspec/core/example_spec.rb b/spec/rspec/core/example_spec.rb index 3c61bab2e6..9b37537367 100644 --- a/spec/rspec/core/example_spec.rb +++ b/spec/rspec/core/example_spec.rb @@ -328,7 +328,7 @@ def run_and_capture_reported_message(group) end message = run_and_capture_reported_message(group) - expect(message).to match(/An error occurred in an around.* hook/i) + expect(message).to match(/An error occurred in an `around.* hook/i) end it "prints any after hook errors rather than silencing them" do diff --git a/spec/rspec/core/hooks_spec.rb b/spec/rspec/core/hooks_spec.rb index 5514908b9a..015595098e 100644 --- a/spec/rspec/core/hooks_spec.rb +++ b/spec/rspec/core/hooks_spec.rb @@ -11,8 +11,8 @@ def parent_groups end [:before, :after, :around].each do |type| - [:each, :all].each do |scope| - next if type == :around && scope == :all + [:example, :context].each do |scope| + next if type == :around && scope == :context describe "##{type}(#{scope})" do it_behaves_like "metadata hash builder" do @@ -29,16 +29,16 @@ def parent_groups describe "##{type}(no scope)" do let(:instance) { HooksHost.new } - it "defaults to :each scope if no arguments are given" do + it "defaults to :example scope if no arguments are given" do hooks = instance.send(type) {} hook = hooks.first - expect(instance.hooks[type][:each]).to include(hook) + expect(instance.hooks[type][:example]).to include(hook) end - it "defaults to :each scope if the only argument is a metadata hash" do + it "defaults to :example scope if the only argument is a metadata hash" do hooks = instance.send(type, :foo => :bar) {} hook = hooks.first - expect(instance.hooks[type][:each]).to include(hook) + expect(instance.hooks[type][:example]).to include(hook) end it "raises an error if only metadata symbols are given as arguments" do @@ -48,7 +48,7 @@ def parent_groups end [:before, :after].each do |type| - [:each, :all, :suite].each do |scope| + [:example, :context, :suite].each do |scope| describe "##{type}(#{scope.inspect})" do let(:instance) { HooksHost.new } let!(:hook) do diff --git a/spec/rspec/core/memoized_helpers_spec.rb b/spec/rspec/core/memoized_helpers_spec.rb index 0f07f83826..6f9481d59a 100644 --- a/spec/rspec/core/memoized_helpers_spec.rb +++ b/spec/rspec/core/memoized_helpers_spec.rb @@ -157,7 +157,7 @@ def subject_value_for(describe_arg, &block) end.run expect(result).to be_an(Exception) - expect(result.message).to match(/subject accessed.*#{hook}\(:all\).*#{__FILE__}:#{line}/m) + expect(result.message).to match(/subject accessed.*#{hook}\(:context\).*#{__FILE__}:#{line}/m) end end end @@ -432,7 +432,7 @@ def count end.run expect(result).to be_an(Exception) - expect(result.message).to match(/let declaration `foo` accessed.*#{hook}\(:all\).*#{__FILE__}:#{line}/m) + expect(result.message).to match(/let declaration `foo` accessed.*#{hook}\(:context\).*#{__FILE__}:#{line}/m) end end