Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Enhancements:
* Backport support for `skip` in metadata to skip execution of an example.
(Xavier Shay, #1472)
* Add `Pathname` support for setting all output streams. (Aaron Kromer)
* Add `test_unit` and `minitest` expectation frameworks. (Aaron Kromer)

Deprecations:

Expand Down Expand Up @@ -59,6 +60,8 @@ Deprecations:
* Deprecate `#filename_pattern` in favour of `#pattern`. (Jon Rowe)
* Deprecate `#backtrace_cleaner` in favour of `#backtrace_formatter`. (Jon Rowe)
* Deprecate mutating `RSpec::Configuration#formatters`. (Jon Rowe)
* Deprecate `stdlib` as an available expectation framework in favour of
`test_unit` and `minitest`. (Aaron Kromer)

Bug Fixes:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ Feature: configure expectation framework
desired outcomes. You can also configure RSpec to use:

* rspec/expectations (explicitly)
* stdlib assertions
* test/unit assertions in ruby 1.8
* minitest assertions in ruby 1.9
* rspec/expectations _and_ stlib assertions
* stdlib assertions **DEPRECATED: Use test/unit or minitest explicitly**
* test/unit assertions
* minitest assertions
* any combination of the above libraries

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.
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: rspec-expectations can be used by default if nothing is configured
Scenario: Default configuration uses rspec-expectations
Given a file named "example_spec.rb" with:
"""ruby
RSpec::Matchers.define :be_a_multiple_of do |factor|
Expand All @@ -29,7 +29,7 @@ Feature: configure expectation framework
When I run `rspec example_spec.rb`
Then the examples should all pass

Scenario: configure rspec-expectations (explicitly)
Scenario: Configure rspec-expectations (explicitly)
Given a file named "example_spec.rb" with:
"""ruby
RSpec.configure do |config|
Expand All @@ -45,7 +45,8 @@ Feature: configure expectation framework
When I run `rspec example_spec.rb`
Then the examples should all pass

Scenario: configure test/unit assertions (passing examples)
@deprecated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What purpose does this tag serve?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing other than to help call it out in the docs.

Scenario: Configure 'stdlib' assertions
Given a file named "example_spec.rb" with:
"""ruby
RSpec.configure do |config|
Expand All @@ -58,45 +59,139 @@ Feature: configure expectation framework
end

specify { assert 5 < 6 }

it "is greater than 6 (no it isn't!)" do
assert 5 > 6, "errantly expected 5 to be greater than 5"
end
end
"""
When I run `rspec example_spec.rb`
Then the output should contain "2 examples, 0 failures"
Then the output should match:
"""
(Test::Unit::AssertionFailedError|Mini(T|t)est::Assertion):
errantly expected 5 to be greater than 5
"""
And the output should contain "3 examples, 1 failure"
And the output should contain ":stdlib is deprecated. Use :test_unit or :minitest instead"

Scenario: configure test/unit assertions (failing examples)
Scenario: Configure test/unit assertions
Given a file named "example_spec.rb" with:
"""ruby
RSpec.configure do |config|
config.expect_with :stdlib
config.expect_with :test_unit
end

describe 5 do
it "is greater than 6 (no it isn't!)" do
assert 5 > 6, "errantly expected 5 to be greater than 5"
RSpec.describe [1] do
it "is equal to [1]" do
assert_equal [1], [1], "expected [1] to equal [1]"
end

specify { assert 5 > 6 }
specify { assert_not_equal [1], [] }

it "is equal to [2] (intentional failure)" do
assert [1] == [2], "errantly expected [2] to equal [1]"
end
end
"""
When I run `rspec example_spec.rb`
Then the output should contain "2 examples, 2 failures"
Then the output should match:
"""
(Test::Unit::AssertionFailedError|Mini(T|t)est::Assertion):
errantly expected \[2\] to equal \[1\]
"""
And the output should contain "3 examples, 1 failure"

Scenario: configure rspec/expecations AND test/unit assertions
Scenario: Configure minitest assertions
Given a file named "example_spec.rb" with:
"""ruby
RSpec.configure do |config|
config.expect_with :rspec, :stdlib
config.expect_with :minitest
end

describe 5 do
it "is greater than 4" do
assert 5 > 4, "expected 5 to be greater than 4"
RSpec.describe "Object identity" do
it "the an object is the same as itself" do
x = [1]
assert_same x, x, "expected x to be the same x"
end

it "is less than 6" do
5.should be < 6
specify { refute_same [1], [1] }

it "is empty (intentional failure)" do
assert_empty [1], "errantly expected [1] to be empty"
end
end
"""
When I run `rspec -b example_spec.rb`
Then the output should match:
"""
MiniT|test::Assertion:
errantly expected \[1\] to be empty
"""
And the output should contain "3 examples, 1 failure"
And the output should not contain "Warning: you should require 'minitest/autorun' instead."

Scenario: Configure rspec/expectations AND test/unit assertions
Given a file named "example_spec.rb" with:
"""ruby
RSpec.configure do |config|
config.expect_with :rspec, :test_unit
end

RSpec.describe [1] do
it "is equal to [1]" do
assert_equal [1], [1], "expected [1] to equal [1]"
end

it "matches array [1]" do
is_expected.to match_array([1])
end
end
"""
When I run `rspec example_spec.rb`
Then the examples should all pass

Scenario: Configure rspec/expecations AND minitest assertions
Given a file named "example_spec.rb" with:
"""ruby
RSpec.configure do |config|
config.expect_with :rspec, :minitest
end

RSpec.describe "Object identity" do
it "two arrays are not the same object" do
refute_same [1], [1]
end

it "an array is itself" do
array = [1]
expect(array).to be array
end
end
"""
When I run `rspec example_spec.rb`
Then the examples should all pass

Scenario: Configure test/unit and minitest assertions
Given a file named "example_spec.rb" with:
"""ruby
RSpec.configure do |config|
config.expect_with :test_unit, :minitest
end

RSpec.describe [1] do
it "is equal to [1]" do
assert_equal [1], [1], "expected [1] to equal [1]"
end

specify { assert_not_equal [1], [] }

it "the an object is the same as itself" do
x = [1]
assert_same x, x, "expected x to be the same x"
end

specify { refute_same [1], [1] }
end
"""
When I run `rspec example_spec.rb`
Then the examples should all pass
20 changes: 14 additions & 6 deletions lib/rspec/core/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -526,16 +526,17 @@ def expectation_framework=(framework)
# Sets the expectation framework module(s) to be included in each example
# group.
#
# `frameworks` can be `:rspec`, `:stdlib`, a custom module, or any
# combination thereof:
# `frameworks` can be `:rspec`, `:test_unit`, `:minitest`, a custom
# module, or any combination thereof:
#
# config.expect_with :rspec
# config.expect_with :stdlib
# config.expect_with :rspec, :stdlib
# config.expect_with :test_unit
# config.expect_with :minitest
# config.expect_with :rspec, :minitest
# config.expect_with OtherExpectationFramework
#
# RSpec will translate `:rspec` and `:stdlib` into the appropriate
# modules.
# RSpec will translate `:rspec`, `:minitest`, and `:test_unit` into the
# appropriate modules.
#
# ## Configuration
#
Expand All @@ -555,8 +556,15 @@ def expect_with(*frameworks)
self.expecting_with_rspec = true
::RSpec::Matchers
when :stdlib
RSpec.deprecate ':stdlib', :replacement => ":test_unit or :minitest"
require 'test/unit/assertions'
::Test::Unit::Assertions
when :test_unit
require 'rspec/core/test_unit_assertions_adapter'
::RSpec::Core::TestUnitAssertionsAdapter
when :minitest
require 'rspec/core/minitest_assertions_adapter'
::RSpec::Core::MinitestAssertionsAdapter
else
raise ArgumentError, "#{framework.inspect} is not supported"
end
Expand Down
28 changes: 28 additions & 0 deletions lib/rspec/core/minitest_assertions_adapter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
begin
# Only the minitest 5.x gem includes the minitest.rb and assertions.rb files
require 'minitest'
require 'minitest/assertions'
rescue LoadError => _ignored
# We must be using Ruby Core's MiniTest or the Minitest gem 4.x
require 'minitest/unit'
Minitest = MiniTest
end

module RSpec
module Core
# @private
module MinitestAssertionsAdapter
include ::Minitest::Assertions

# Minitest 5.x requires this accessor to be available. See
# https://github.com/seattlerb/minitest/blob/38f0a5fcbd9c37c3f80a3eaad4ba84d3fc9947a0/lib/minitest/assertions.rb#L8
#
# It is not required for other extension libraries, and RSpec does not
# report or make this information available to formatters.
attr_writer :assertions
def assertions
@assertions ||= 0
end
end
end
end
30 changes: 30 additions & 0 deletions lib/rspec/core/test_unit_assertions_adapter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'test/unit/assertions'

module RSpec
module Core
# @private
module TestUnitAssertionsAdapter
include ::Test::Unit::Assertions

# If using test/unit from Ruby core with Ruby 1.9+, it includes
# MiniTest::Assertions by default. Note the upcasing of 'Test'.
#
# If the test/unit gem is being loaded, it will not include any minitest
# assertions.
#
# Only if Minitest 5.x is included / loaded do we need to worry about
# adding a shim for the new updates. Thus instead of checking on the
# RUBY_VERSION we need to check ancestors.
begin
# MiniTest is 4.x
# Minitest is 5.x
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same nonsensical comment as the other PR

if ancestors.include?(::Minitest::Assertions)
require 'rspec/core/minitest_assertions_adapter'
include ::RSpec::Core::MinitestAssertionsAdapter
end
rescue NameError => _ignored
# No-op. Minitest 5.x was not loaded
end
end
end
end
1 change: 1 addition & 0 deletions rspec-core.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Gem::Specification.new do |s|

s.add_development_dependency "rake", "~> 10.0.0"
s.add_development_dependency "cucumber", "~> 1.1.9"
s.add_development_dependency "minitest", "~> 4.7"
s.add_development_dependency "aruba", "~> 0.5"

s.add_development_dependency "ZenTest", "~> 4.6"
Expand Down
Loading