diff --git a/lib/rspec/rails/adapters.rb b/lib/rspec/rails/adapters.rb index dbf0e32150..66e82eb8c4 100644 --- a/lib/rspec/rails/adapters.rb +++ b/lib/rspec/rails/adapters.rb @@ -1,156 +1,11 @@ -require 'delegate' -require 'active_support/concern' -require 'test/unit/assertions' - -module RSpec - module Rails - class AssertionDelegator < Module - # @api private - def initialize(*assertion_modules) - assertion_class = Class.new(SimpleDelegator) do - include Test::Unit::Assertions - include ::RSpec::Rails::MinitestCounters - assertion_modules.each { |mod| include mod } - end - - super() do - # @api private - define_method :build_assertion_instance do - assertion_class.new(self) - end - - # @api private - def assertion_instance - @assertion_instance ||= build_assertion_instance - end - - assertion_modules.each do |mod| - mod.public_instance_methods.each do |method| - next if method == :method_missing || method == "method_missing" - class_eval <<-EOM, __FILE__, __LINE__ + 1 - def #{method}(*args, &block) - assertion_instance.send(:#{method}, *args, &block) - end - EOM - end - end - end - end - end - - # MiniTest::Unit::LifecycleHooks - module MiniTestLifecycleAdapter - extend ActiveSupport::Concern - - included do |group| - group.before { after_setup } - group.after { before_teardown } - - group.around do |example| - before_setup - example.run - after_teardown - end - end - - def before_setup - end - - def after_setup - end - - def before_teardown - end - - def after_teardown - end - end - - # @api private - module MinitestCounters - # @api private - def assertions - @assertions ||= 0 - end - - # @api private - def assertions=(assertions) - @assertions = assertions - end - end - - module SetupAndTeardownAdapter - extend ActiveSupport::Concern - - module ClassMethods - # @api private - # - # Wraps `setup` calls from within Rails' testing framework in `before` - # hooks. - def setup(*methods) - methods.each do |method| - if method.to_s =~ /^setup_(fixtures|controller_request_and_response)$/ - prepend_before { send method } - else - before { send method } - end - end - end - - # @api private - # - # Wraps `teardown` calls from within Rails' testing framework in - # `after` hooks. - def teardown(*methods) - methods.each { |method| after { send method } } - end - end - - # @api private - def method_name - @example - end - end - - module TestUnitAssertionAdapter - extend ActiveSupport::Concern - - module ClassMethods - # @api private - # - # Returns the names of assertion methods that we want to expose to - # examples without exposing non-assertion methods in Test::Unit or - # Minitest. - def assertion_method_names - Test::Unit::Assertions.public_instance_methods.select{|m| m.to_s =~ /^(assert|flunk)/} + - [:build_message] - end - - # @api private - def define_assertion_delegators - assertion_method_names.each do |m| - class_eval <<-CODE, __FILE__, __LINE__ + 1 - def #{m}(*args, &block) - assertion_delegator.send :#{m}, *args, &block - end - CODE - end - end - end - - class AssertionDelegator - include Test::Unit::Assertions - include ::RSpec::Rails::MinitestCounters - end - - # @api private - def assertion_delegator - @assertion_delegator ||= AssertionDelegator.new - end - - included do - define_assertion_delegators - end - end +module RSpec::Rails + module Adapters end end + +require 'rspec/rails/adapters/assertion_delegator' +require 'rspec/rails/adapters/assertions' +require 'rspec/rails/adapters/minitest_counters' +require 'rspec/rails/adapters/minitest_lifecycle_adapter' +require 'rspec/rails/adapters/setup_and_teardown_adapter' +require 'rspec/rails/adapters/test_unit_assertion_adapter' diff --git a/lib/rspec/rails/adapters/assertion_delegator.rb b/lib/rspec/rails/adapters/assertion_delegator.rb new file mode 100644 index 0000000000..096159f50e --- /dev/null +++ b/lib/rspec/rails/adapters/assertion_delegator.rb @@ -0,0 +1,37 @@ +require 'delegate' + +module RSpec::Rails::Adapters + class AssertionDelegator < Module + # @api private + def initialize(*assertion_modules) + assertion_class = Class.new(SimpleDelegator) do + include ::RSpec::Rails::Adapters::Assertions + include ::RSpec::Rails::Adapters::MinitestCounters + assertion_modules.each { |mod| include mod } + end + + super() do + # @api private + define_method :build_assertion_instance do + assertion_class.new(self) + end + + # @api private + def assertion_instance + @assertion_instance ||= build_assertion_instance + end + + assertion_modules.each do |mod| + mod.public_instance_methods.each do |method| + next if method == :method_missing || method == "method_missing" + class_eval <<-EOM, __FILE__, __LINE__ + 1 + def #{method}(*args, &block) + assertion_instance.send(:#{method}, *args, &block) + end + EOM + end + end + end + end + end +end diff --git a/lib/rspec/rails/adapters/assertions.rb b/lib/rspec/rails/adapters/assertions.rb new file mode 100644 index 0000000000..c9fd4d9eaf --- /dev/null +++ b/lib/rspec/rails/adapters/assertions.rb @@ -0,0 +1,17 @@ +if ::Rails::VERSION::STRING >= '4.1.0' + gem 'minitest' + require 'minitest/assertions' +else + require 'test/unit/assertions' +end + + +module RSpec::Rails::Adapters + module Assertions + if ::Rails::VERSION::STRING >= '4.1.0' + include Minitest::Assertions + else + include Test::Unit::Assertions + end + end +end diff --git a/lib/rspec/rails/adapters/minitest_counters.rb b/lib/rspec/rails/adapters/minitest_counters.rb new file mode 100644 index 0000000000..2a80c67214 --- /dev/null +++ b/lib/rspec/rails/adapters/minitest_counters.rb @@ -0,0 +1,14 @@ +module RSpec::Rails::Adapters + # @api private + module MinitestCounters + # @api private + def assertions + @assertions ||= 0 + end + + # @api private + def assertions=(assertions) + @assertions = assertions + end + end +end diff --git a/lib/rspec/rails/adapters/minitest_lifecycle_adapter.rb b/lib/rspec/rails/adapters/minitest_lifecycle_adapter.rb new file mode 100644 index 0000000000..7ee146111f --- /dev/null +++ b/lib/rspec/rails/adapters/minitest_lifecycle_adapter.rb @@ -0,0 +1,31 @@ +require 'active_support/concern' + +module RSpec::Rails::Adapters + # Minitest::Test::LifecycleHooks + module MinitestLifecycleAdapter + extend ActiveSupport::Concern + + included do |group| + group.before { after_setup } + group.after { before_teardown } + + group.around do |example| + before_setup + example.run + after_teardown + end + end + + def before_setup + end + + def after_setup + end + + def before_teardown + end + + def after_teardown + end + end +end diff --git a/lib/rspec/rails/adapters/setup_and_teardown_adapter.rb b/lib/rspec/rails/adapters/setup_and_teardown_adapter.rb new file mode 100644 index 0000000000..1fa0427ff0 --- /dev/null +++ b/lib/rspec/rails/adapters/setup_and_teardown_adapter.rb @@ -0,0 +1,36 @@ +require 'active_support/concern' + +module RSpec::Rails::Adapters + module SetupAndTeardownAdapter + extend ActiveSupport::Concern + + module ClassMethods + # @api private + # + # Wraps `setup` calls from within Rails' testing framework in `before` + # hooks. + def setup(*methods) + methods.each do |method| + if method.to_s =~ /^setup_(fixtures|controller_request_and_response)$/ + prepend_before { send method } + else + before { send method } + end + end + end + + # @api private + # + # Wraps `teardown` calls from within Rails' testing framework in + # `after` hooks. + def teardown(*methods) + methods.each { |method| after { send method } } + end + end + + # @api private + def method_name + @example + end + end +end diff --git a/lib/rspec/rails/adapters/test_unit_assertion_adapter.rb b/lib/rspec/rails/adapters/test_unit_assertion_adapter.rb new file mode 100644 index 0000000000..d382b1689e --- /dev/null +++ b/lib/rspec/rails/adapters/test_unit_assertion_adapter.rb @@ -0,0 +1,45 @@ +require 'active_support/concern' +require 'rspec/rails/adapters/assertions' + +module RSpec::Rails::Adapters + module TestUnitAssertionAdapter + extend ActiveSupport::Concern + + module ClassMethods + # @api private + # + # Returns the names of assertion methods that we want to expose to + # examples without exposing non-assertion methods in Test::Unit or + # Minitest. + def assertion_method_names + ::RSpec::Rails::Adapters::Assertions.public_instance_methods.select{|m| m.to_s =~ /^(assert|flunk)/} + + [:build_message] + end + + # @api private + def define_assertion_delegators + assertion_method_names.each do |m| + class_eval <<-CODE, __FILE__, __LINE__ + 1 + def #{m}(*args, &block) + assertion_delegator.send :#{m}, *args, &block + end + CODE + end + end + end + + class AssertionDelegator + include ::RSpec::Rails::Adapters::Assertions + include ::RSpec::Rails::Adapters::MinitestCounters + end + + # @api private + def assertion_delegator + @assertion_delegator ||= AssertionDelegator.new + end + + included do + define_assertion_delegators + end + end +end diff --git a/lib/rspec/rails/example/controller_example_group.rb b/lib/rspec/rails/example/controller_example_group.rb index 916787aa45..e54e38a703 100644 --- a/lib/rspec/rails/example/controller_example_group.rb +++ b/lib/rspec/rails/example/controller_example_group.rb @@ -11,7 +11,7 @@ module ControllerExampleGroup include RSpec::Rails::Matchers::RedirectTo include RSpec::Rails::Matchers::RenderTemplate include RSpec::Rails::Matchers::RoutingMatchers - include RSpec::Rails::AssertionDelegator.new(ActionDispatch::Assertions::RoutingAssertions) + include RSpec::Rails::Adapters::AssertionDelegator.new(ActionDispatch::Assertions::RoutingAssertions) module ClassMethods # @private diff --git a/lib/rspec/rails/example/rails_example_group.rb b/lib/rspec/rails/example/rails_example_group.rb index 3d92803c03..6569e5ce36 100644 --- a/lib/rspec/rails/example/rails_example_group.rb +++ b/lib/rspec/rails/example/rails_example_group.rb @@ -6,9 +6,9 @@ module RSpec module Rails module RailsExampleGroup extend ActiveSupport::Concern - include RSpec::Rails::SetupAndTeardownAdapter - include RSpec::Rails::MiniTestLifecycleAdapter if ::Rails::VERSION::STRING >= '4' - include RSpec::Rails::TestUnitAssertionAdapter + include RSpec::Rails::Adapters::SetupAndTeardownAdapter + include RSpec::Rails::Adapters::MinitestLifecycleAdapter if ::Rails::VERSION::STRING >= '4' + include RSpec::Rails::Adapters::TestUnitAssertionAdapter include RSpec::Rails::Matchers end end diff --git a/lib/rspec/rails/example/routing_example_group.rb b/lib/rspec/rails/example/routing_example_group.rb index b408d4becb..2ff55c3424 100644 --- a/lib/rspec/rails/example/routing_example_group.rb +++ b/lib/rspec/rails/example/routing_example_group.rb @@ -6,7 +6,7 @@ module RoutingExampleGroup include RSpec::Rails::RailsExampleGroup include RSpec::Rails::Matchers::RoutingMatchers include RSpec::Rails::Matchers::RoutingMatchers::RouteHelpers - include RSpec::Rails::AssertionDelegator.new(ActionDispatch::Assertions::RoutingAssertions) + include RSpec::Rails::Adapters::AssertionDelegator.new(ActionDispatch::Assertions::RoutingAssertions) module ClassMethods # Specifies the routeset that will be used for the example group. This diff --git a/lib/rspec/rails/fixture_support.rb b/lib/rspec/rails/fixture_support.rb index 0758faa1d4..f6dda6c459 100644 --- a/lib/rspec/rails/fixture_support.rb +++ b/lib/rspec/rails/fixture_support.rb @@ -3,9 +3,9 @@ module Rails if defined?(ActiveRecord::TestFixtures) module FixtureSupport extend ActiveSupport::Concern - include RSpec::Rails::SetupAndTeardownAdapter - include RSpec::Rails::MiniTestLifecycleAdapter if ::Rails::VERSION::STRING > '4' - include RSpec::Rails::TestUnitAssertionAdapter + include RSpec::Rails::Adapters::SetupAndTeardownAdapter + include RSpec::Rails::Adapters::MinitestLifecycleAdapter if ::Rails::VERSION::STRING > '4' + include RSpec::Rails::Adapters::TestUnitAssertionAdapter include ActiveRecord::TestFixtures included do diff --git a/rspec-rails.gemspec b/rspec-rails.gemspec index 44b8eeb392..6e41f2ce77 100644 --- a/rspec-rails.gemspec +++ b/rspec-rails.gemspec @@ -33,8 +33,9 @@ Gem::Specification.new do |s| end s.add_development_dependency 'rake', '~> 10.0.0' - s.add_development_dependency 'cucumber', '~> 1.1.9' + s.add_development_dependency 'cucumber', '~> 1.3.5' s.add_development_dependency 'aruba', '~> 0.4.11' s.add_development_dependency 'ZenTest', '4.9.0' s.add_development_dependency 'ammeter', '0.2.5' + s.add_development_dependency 'minitest', '>= 4.2' end diff --git a/spec/rspec/rails/assertion_delegator_spec.rb b/spec/rspec/rails/adapters/assertion_delegator_spec.rb similarity index 72% rename from spec/rspec/rails/assertion_delegator_spec.rb rename to spec/rspec/rails/adapters/assertion_delegator_spec.rb index 6ccc2df9b0..1e5461e373 100644 --- a/spec/rspec/rails/assertion_delegator_spec.rb +++ b/spec/rspec/rails/adapters/assertion_delegator_spec.rb @@ -1,9 +1,9 @@ require "spec_helper" -describe RSpec::Rails::AssertionDelegator do +describe RSpec::Rails::Adapters::AssertionDelegator do it "provides a module that delegates assertion methods to an isolated class" do klass = Class.new { - include RSpec::Rails::AssertionDelegator.new(Test::Unit::Assertions) + include RSpec::Rails::Adapters::AssertionDelegator.new(RSpec::Rails::Adapters::Assertions) } expect(klass.new).to respond_to(:assert) @@ -17,7 +17,7 @@ def has_thing?(thing) } klass = Class.new { - include RSpec::Rails::AssertionDelegator.new(assertions) + include RSpec::Rails::Adapters::AssertionDelegator.new(assertions) def things [:a] @@ -35,7 +35,7 @@ def method_missing(method, *args) } klass = Class.new { - include RSpec::Rails::AssertionDelegator.new(assertions) + include RSpec::Rails::Adapters::AssertionDelegator.new(assertions) } expect { klass.new.abc123 }.to raise_error(NoMethodError) diff --git a/spec/rspec/rails/minitest_lifecycle_adapter_spec.rb b/spec/rspec/rails/adapters/minitest_lifecycle_adapter_spec.rb similarity index 77% rename from spec/rspec/rails/minitest_lifecycle_adapter_spec.rb rename to spec/rspec/rails/adapters/minitest_lifecycle_adapter_spec.rb index 66b4caaf2a..13be4c94a1 100644 --- a/spec/rspec/rails/minitest_lifecycle_adapter_spec.rb +++ b/spec/rspec/rails/adapters/minitest_lifecycle_adapter_spec.rb @@ -1,10 +1,10 @@ require "spec_helper" -describe RSpec::Rails::MiniTestLifecycleAdapter do +describe RSpec::Rails::Adapters::MinitestLifecycleAdapter do it "invokes minitest lifecycle hooks at the appropriate times" do invocations = [] - example_group = RSpec::Core::ExampleGroup.describe("MiniTestHooks") do - include RSpec::Rails::MiniTestLifecycleAdapter + example_group = RSpec::Core::ExampleGroup.describe("MinitestHooks") do + include RSpec::Rails::Adapters::MinitestLifecycleAdapter define_method(:before_setup) { invocations << :before_setup } define_method(:after_setup) { invocations << :after_setup } diff --git a/spec/rspec/rails/setup_and_teardown_adapter_spec.rb b/spec/rspec/rails/adapters/setup_and_teardown_adapter_spec.rb similarity index 84% rename from spec/rspec/rails/setup_and_teardown_adapter_spec.rb rename to spec/rspec/rails/adapters/setup_and_teardown_adapter_spec.rb index eab7762968..03d0dd684b 100644 --- a/spec/rspec/rails/setup_and_teardown_adapter_spec.rb +++ b/spec/rspec/rails/adapters/setup_and_teardown_adapter_spec.rb @@ -1,10 +1,10 @@ require 'spec_helper' -describe RSpec::Rails::SetupAndTeardownAdapter do +describe RSpec::Rails::Adapters::SetupAndTeardownAdapter do describe "::setup" do it "registers before hooks in the order setup is received" do klass = Class.new do - include RSpec::Rails::SetupAndTeardownAdapter + include RSpec::Rails::Adapters::SetupAndTeardownAdapter def self.foo; "foo"; end def self.bar; "bar"; end end @@ -17,7 +17,7 @@ def self.bar; "bar"; end it "registers prepend_before hooks for the Rails' setup methods" do klass = Class.new do - include RSpec::Rails::SetupAndTeardownAdapter + include RSpec::Rails::Adapters::SetupAndTeardownAdapter def self.setup_fixtures; "setup fixtures" end def self.setup_controller_request_and_response; "setup controller" end end diff --git a/spec/rspec/rails/assertion_adapter_spec.rb b/spec/rspec/rails/adapters/test_unit_assertion_adapter_spec.rb similarity index 57% rename from spec/rspec/rails/assertion_adapter_spec.rb rename to spec/rspec/rails/adapters/test_unit_assertion_adapter_spec.rb index ae974fdb09..8a5ccdf474 100644 --- a/spec/rspec/rails/assertion_adapter_spec.rb +++ b/spec/rspec/rails/adapters/test_unit_assertion_adapter_spec.rb @@ -1,9 +1,9 @@ require "spec_helper" -describe RSpec::Rails::TestUnitAssertionAdapter do - include RSpec::Rails::TestUnitAssertionAdapter +describe RSpec::Rails::Adapters::TestUnitAssertionAdapter do + include RSpec::Rails::Adapters::TestUnitAssertionAdapter - Test::Unit::Assertions.public_instance_methods.select{|m| m.to_s =~ /^(assert|flunk)/}.each do |m| + RSpec::Rails::Adapters::Assertions.public_instance_methods.select{|m| m.to_s =~ /^(assert|flunk)/}.each do |m| if m.to_s == "assert_equal" it "exposes #{m} to host examples" do assert_equal 3,3 @@ -18,11 +18,11 @@ end end - it "does not expose internal methods of MiniTest" do + it "does not expose internal methods of Minitest" do methods.should_not include("_assertions") end - it "does not expose MiniTest's message method" do + it "does not expose Minitest's message method" do methods.should_not include("message") end end diff --git a/spec/rspec/rails/mocks/mock_model_spec.rb b/spec/rspec/rails/mocks/mock_model_spec.rb index 24e60a679c..7d487ba630 100644 --- a/spec/rspec/rails/mocks/mock_model_spec.rb +++ b/spec/rspec/rails/mocks/mock_model_spec.rb @@ -360,9 +360,8 @@ end describe "ActiveModel Lint tests" do - require 'test/unit/assertions' require 'active_model/lint' - include RSpec::Rails::TestUnitAssertionAdapter + include RSpec::Rails::Adapters::TestUnitAssertionAdapter include ActiveModel::Lint::Tests # to_s is to support ruby-1.9