Remove auto-detection of Rails / test framework

This commit is contained in:
Elliot Winkler 2014-10-22 18:54:36 -06:00
parent 19c38a642a
commit 190007155e
37 changed files with 718 additions and 163 deletions

View File

@ -1,28 +1,22 @@
require 'shoulda/matchers/assertion_error'
require 'shoulda/matchers/configuration'
require 'shoulda/matchers/doublespeak'
require 'shoulda/matchers/error'
require 'shoulda/matchers/independent'
require 'shoulda/matchers/integrations'
require 'shoulda/matchers/matcher_context'
require 'shoulda/matchers/rails_shim'
require 'shoulda/matchers/util'
require 'shoulda/matchers/version'
require 'shoulda/matchers/warn'
require 'shoulda/matchers/independent'
require 'shoulda/matchers/action_controller'
require 'shoulda/matchers/active_model'
require 'shoulda/matchers/active_record'
if defined?(ActiveModel)
require 'shoulda/matchers/active_model'
module Shoulda
module Matchers
class << self
attr_accessor :assertion_exception_class
end
end
end
if defined?(ActiveRecord)
require 'shoulda/matchers/active_record'
end
if defined?(ActionController)
require 'shoulda/matchers/action_controller'
end
if defined?(RSpec)
require 'shoulda/matchers/integrations/rspec'
end
require 'shoulda/matchers/integrations/test_unit'

View File

@ -82,7 +82,7 @@ module Shoulda
@context.__send__(:assert_redirected_to, url)
@failure_message_when_negated = "Didn't expect to redirect to #{url}"
true
rescue Shoulda::Matchers::AssertionError => error
rescue Shoulda::Matchers.assertion_exception_class => error
@failure_message = error.message
false
end

View File

@ -80,7 +80,7 @@ module Shoulda
@context.__send__(:assert_template, @options, @message)
@failure_message_when_negated = "Didn't expect to render #{@template}"
true
rescue Shoulda::Matchers::AssertionError => error
rescue Shoulda::Matchers.assertion_exception_class => error
@failure_message = error.message
false
end

View File

@ -135,7 +135,7 @@ module Shoulda
rescue ::ActionController::RoutingError => error
@failure_message = error.message
false
rescue Shoulda::Matchers::AssertionError => error
rescue Shoulda::Matchers.assertion_exception_class => error
@failure_message = error.message
false
end

View File

@ -1,27 +0,0 @@
module Shoulda
module Matchers
if defined?(ActiveSupport::TestCase)
# @private
AssertionError = ActiveSupport::TestCase::Assertion
elsif Gem.ruby_version >= Gem::Version.new('1.8') && Gem.ruby_version < Gem::Version.new('1.9')
require 'test/unit'
# @private
AssertionError = Test::Unit::AssertionFailedError
elsif defined?(Test::Unit::AssertionFailedError)
# Test::Unit has been loaded already, so we use it
# @private
AssertionError = Test::Unit::AssertionFailedError
elsif Gem.ruby_version >= Gem::Version.new("1.9")
begin
require 'minitest'
rescue LoadError
require 'minitest/unit'
ensure
# @private
AssertionError = MiniTest::Assertion
end
else
raise 'No unit test library available'
end
end
end

View File

@ -0,0 +1,20 @@
module Shoulda
module Matchers
# @private
def self.configure
yield configuration
end
# @private
def self.configuration
@_configuration ||= Configuration.new
end
# @private
class Configuration
def integrate(&block)
Integrations::Configuration.apply(self, &block)
end
end
end
end

View File

@ -0,0 +1,42 @@
module Shoulda
module Matchers
module Integrations
class << self
def register_library(klass, name)
library_registry.register(klass, name)
end
def find_library!(name)
library_registry.find!(name)
end
def register_test_framework(klass, name)
test_framework_registry.register(klass, name)
end
def find_test_framework!(name)
test_framework_registry.find!(name)
end
private
def library_registry
@_library_registry ||= Registry.new
end
def test_framework_registry
@_test_framework_registry ||= Registry.new
end
end
end
end
end
require 'shoulda/matchers/integrations/configuration'
require 'shoulda/matchers/integrations/configuration_error'
require 'shoulda/matchers/integrations/inclusion'
require 'shoulda/matchers/integrations/rails'
require 'shoulda/matchers/integrations/registry'
require 'shoulda/matchers/integrations/libraries'
require 'shoulda/matchers/integrations/test_frameworks'

View File

@ -0,0 +1,67 @@
require 'set'
module Shoulda
module Matchers
module Integrations
# @private
class Configuration
def self.apply(configuration, &block)
new(configuration, &block).apply
end
def initialize(configuration, &block)
@test_frameworks = Set.new
test_framework :missing_test_framework
library :missing_library
block.call(self)
end
def test_framework(name)
clear_default_test_framework
@test_frameworks << Integrations.find_test_framework!(name)
end
def library(name)
@library = Integrations.find_library!(name)
end
def apply
if no_test_frameworks_added? && library_not_set?
raise ConfigurationError, <<EOT
shoulda-matchers is not configured correctly. You need to specify a test
framework and/or library. For example:
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
EOT
end
@test_frameworks.each do |test_framework|
test_framework.include(Shoulda::Matchers::Independent)
@library.integrate_with(test_framework)
end
end
private
def clear_default_test_framework
@test_frameworks.select!(&:present?)
end
def no_test_frameworks_added?
@test_frameworks.empty? || !@test_frameworks.any?(&:present?)
end
def library_not_set?
@library.nil?
end
end
end
end
end

View File

@ -0,0 +1,8 @@
module Shoulda
module Matchers
module Integrations
class ConfigurationError < StandardError
end
end
end
end

View File

@ -0,0 +1,19 @@
module Shoulda
module Matchers
module Integrations
module Inclusion
def include_into(mod, *other_mods, &block)
mods_to_include = other_mods.dup
mods_to_extend = other_mods.dup
if block
mods_to_include << Module.new(&block)
end
mod.__send__(:include, *mods_to_include)
mod.extend(*mods_to_extend)
end
end
end
end
end

View File

@ -0,0 +1,5 @@
require 'shoulda/matchers/integrations/libraries/action_controller'
require 'shoulda/matchers/integrations/libraries/active_model'
require 'shoulda/matchers/integrations/libraries/active_record'
require 'shoulda/matchers/integrations/libraries/missing_library'
require 'shoulda/matchers/integrations/libraries/rails'

View File

@ -0,0 +1,30 @@
module Shoulda
module Matchers
module Integrations
module Libraries
class ActionController
Integrations.register_library(self, :action_controller)
include Integrations::Inclusion
include Integrations::Rails
def integrate_with(test_framework)
test_framework.include(matchers_module)
include_into(::ActionController::TestCase, matchers_module) do
def subject
@controller
end
end
end
private
def matchers_module
Shoulda::Matchers::ActionController
end
end
end
end
end
end

View File

@ -0,0 +1,25 @@
module Shoulda
module Matchers
module Integrations
module Libraries
class ActiveModel
Integrations.register_library(self, :active_model)
include Integrations::Inclusion
include Integrations::Rails
def integrate_with(test_framework)
test_framework.include(matchers_module)
include_into(ActiveSupport::TestCase, matchers_module)
end
private
def matchers_module
Shoulda::Matchers::ActiveModel
end
end
end
end
end
end

View File

@ -0,0 +1,25 @@
module Shoulda
module Matchers
module Integrations
module Libraries
class ActiveRecord
Integrations.register_library(self, :active_record)
include Integrations::Inclusion
include Integrations::Rails
def integrate_with(test_framework)
test_framework.include(matchers_module)
include_into(ActiveSupport::TestCase, matchers_module)
end
private
def matchers_module
Shoulda::Matchers::ActiveRecord
end
end
end
end
end
end

View File

@ -0,0 +1,18 @@
module Shoulda
module Matchers
module Integrations
module Libraries
class MissingLibrary
Integrations.register_library(self, :missing_library)
def integrate_with(test_framework)
end
def rails?
false
end
end
end
end
end
end

View File

@ -0,0 +1,29 @@
module Shoulda
module Matchers
module Integrations
module Libraries
class Rails
Integrations.register_library(self, :rails)
include Integrations::Rails
SUB_LIBRARIES = [
:active_model,
:active_record,
:action_controller
]
def integrate_with(test_framework)
Shoulda::Matchers.assertion_exception_class =
ActiveSupport::TestCase::Assertion
SUB_LIBRARIES.each do |name|
library = Integrations.find_library!(name)
library.integrate_with(test_framework)
end
end
end
end
end
end
end

View File

@ -1,39 +0,0 @@
module Shoulda
module Matchers
# @private
module Integrations
# @private
module NUnitTestCaseDetection
def self.possible_test_case_constants
[
-> { ActiveSupport::TestCase },
-> { Minitest::Test },
-> { MiniTest::Unit::TestCase },
-> { Test::Unit::TestCase }
]
end
def self.resolve_constant(future_constant)
future_constant.call
rescue NameError
nil
end
def self.detected_test_case_constants
possible_test_case_constants.
map { |future_constant| resolve_constant(future_constant) }.
compact
end
def self.test_case_constants
@_test_case_constants ||= detected_test_case_constants
end
end
end
# @private
def self.nunit_test_case_constants
Integrations::NUnitTestCaseDetection.test_case_constants
end
end
end

View File

@ -0,0 +1,11 @@
module Shoulda
module Matchers
module Integrations
module Rails
def rails?
true
end
end
end
end
end

View File

@ -0,0 +1,27 @@
module Shoulda
module Matchers
module Integrations
class Registry
def register(klass, name)
registry[name] = klass
end
def find!(name)
find_class!(name).new
end
private
def registry
@_registry ||= {}
end
def find_class!(name)
registry.fetch(name) do
raise ArgumentError, "'#{name}' is not registered"
end
end
end
end
end
end

View File

@ -1,19 +0,0 @@
# :enddoc:
if RSpec.respond_to?(:configure)
RSpec.configure do |config|
config.include Shoulda::Matchers::Independent
if defined?(ActiveRecord)
config.include Shoulda::Matchers::ActiveRecord
end
if defined?(ActiveModel)
config.include Shoulda::Matchers::ActiveModel
end
if defined?(ActionController)
config.include Shoulda::Matchers::ActionController
end
end
end

View File

@ -0,0 +1,6 @@
require 'shoulda/matchers/integrations/test_frameworks/active_support_test_case'
require 'shoulda/matchers/integrations/test_frameworks/minitest_4'
require 'shoulda/matchers/integrations/test_frameworks/minitest_5'
require 'shoulda/matchers/integrations/test_frameworks/missing_test_framework'
require 'shoulda/matchers/integrations/test_frameworks/rspec'
require 'shoulda/matchers/integrations/test_frameworks/test_unit'

View File

@ -0,0 +1,36 @@
module Shoulda
module Matchers
module Integrations
module TestFrameworks
class ActiveSupportTestCase
Integrations.register_test_framework(self, :active_support_test_case)
def validate!
end
def include(*modules)
test_case_class.include(*modules)
end
def n_unit?
true
end
def present?
true
end
protected
attr_reader :configuration
private
def test_case_class
ActiveSupport::TestCase
end
end
end
end
end
end

View File

@ -0,0 +1,35 @@
module Shoulda
module Matchers
module Integrations
module TestFrameworks
class Minitest4
Integrations.register_test_framework(self, :minitest_4)
def validate!
end
def include(*modules)
test_case_class.class_eval do
include(*modules)
extend(*modules)
end
end
def n_unit?
true
end
def present?
true
end
private
def test_case_class
MiniTest::Unit::TestCase
end
end
end
end
end
end

View File

@ -0,0 +1,36 @@
module Shoulda
module Matchers
module Integrations
module TestFrameworks
class Minitest5
Integrations.register_test_framework(self, :minitest_5)
Integrations.register_test_framework(self, :minitest)
def validate!
end
def include(*modules)
test_case_class.class_eval do
include(*modules)
extend(*modules)
end
end
def n_unit?
true
end
def present?
true
end
private
def test_case_class
Minitest::Test
end
end
end
end
end
end

View File

@ -0,0 +1,39 @@
module Shoulda
module Matchers
module Integrations
module TestFrameworks
class MissingTestFramework
Integrations.register_test_framework(self, :missing_test_framework)
def validate!
raise TestFrameworkNotConfigured, <<-EOT
You need to set a test framework. Please add the following to your
test helper:
Shoulda::Matchers.configure do |config|
config.integrate do |with|
# Choose one:
with.test_framework :rspec
with.test_framework :minitest # or, :minitest_5
with.test_framework :minitest_4
with.test_framework :test_unit
end
end
EOT
end
def include(*modules)
end
def n_unit?
false
end
def present?
false
end
end
end
end
end
end

View File

@ -0,0 +1,28 @@
module Shoulda
module Matchers
module Integrations
module TestFrameworks
class Rspec
Integrations.register_test_framework(self, :rspec)
def validate!
end
def include(*modules)
::RSpec.configure do |config|
config.include(*modules)
end
end
def n_unit?
false
end
def present?
true
end
end
end
end
end
end

View File

@ -0,0 +1,35 @@
module Shoulda
module Matchers
module Integrations
module TestFrameworks
class TestUnit
Integrations.register_test_framework(self, :test_unit)
def validate!
end
def include(*modules)
test_case_class.class_eval do
include(*modules)
extend(*modules)
end
end
def n_unit?
true
end
def present?
true
end
private
def test_case_class
::Test::Unit::TestCase
end
end
end
end
end
end

View File

@ -1,34 +0,0 @@
# :enddoc:
require 'shoulda/matchers/integrations/nunit_test_case_detection'
Shoulda::Matchers.nunit_test_case_constants.each do |constant|
constant.class_eval do
include Shoulda::Matchers::Independent
extend Shoulda::Matchers::Independent
end
end
if defined?(ActionController::TestCase)
ActionController::TestCase.class_eval do
include Shoulda::Matchers::ActionController
extend Shoulda::Matchers::ActionController
def subject
@controller
end
end
end
if defined?(ActiveSupport::TestCase)
ActiveSupport::TestCase.class_eval do
if defined?(Shoulda::Matchers::ActiveRecord)
include Shoulda::Matchers::ActiveRecord
extend Shoulda::Matchers::ActiveRecord
end
if defined?(Shoulda::Matchers::ActiveModel)
include Shoulda::Matchers::ActiveModel
extend Shoulda::Matchers::ActiveModel
end
end
end

View File

@ -4,7 +4,10 @@ describe 'shoulda-matchers integrates with an ActiveModel project' do
specify 'and loads without errors' do
create_active_model_project
add_shoulda_matchers_to_project
add_shoulda_matchers_to_project(
test_frameworks: [:rspec],
library: :active_model
)
write_file 'load_dependencies.rb', <<-FILE
require 'active_model'

View File

@ -9,7 +9,7 @@ describe 'shoulda-matchers has independent matchers' do
add_minitest_to_project
add_shoulda_context_to_project(manually: true)
add_shoulda_matchers_to_project(
test_frameworks: [:n_unit],
test_frameworks: [:minitest],
manually: true
)
end

View File

@ -34,10 +34,13 @@ describe 'shoulda-matchers integrates with Rails' do
configure_routes_with_single_wildcard_route
end
specify 'in a project that uses Test::Unit' do
specify 'in a project that uses the default test framework' do
updating_bundle do
add_gems_for_n_unit
add_shoulda_matchers_to_project
add_shoulda_matchers_to_project(
test_frameworks: [default_test_framework],
library: :rails
)
end
run_tests_for_n_unit
@ -46,7 +49,10 @@ describe 'shoulda-matchers integrates with Rails' do
specify 'in a project that uses RSpec' do
updating_bundle do
add_gems_for_rspec
add_shoulda_matchers_to_project(test_frameworks: [:rspec])
add_shoulda_matchers_to_project(
test_frameworks: [:rspec],
library: :rails
)
end
run_tests_for_rspec
@ -62,6 +68,7 @@ describe 'shoulda-matchers integrates with Rails' do
add_gems_for_rspec
add_shoulda_matchers_to_project(
test_frameworks: [:rspec],
library: :rails,
manually: true
)
end
@ -75,7 +82,10 @@ describe 'shoulda-matchers integrates with Rails' do
updating_bundle do
add_gems_for_n_unit
add_gems_for_rspec
add_shoulda_matchers_to_project
add_shoulda_matchers_to_project(
test_frameworks: [:rspec, nil],
library: :rails
)
end
run_tests_for_n_unit

View File

@ -0,0 +1,113 @@
require_relative 'helpers/base_helpers'
require_relative 'helpers/rspec_helpers'
module AcceptanceTests
class AddsShouldaMatchersToProject
def self.call(options)
new(options).call
end
include BaseHelpers
include RspecHelpers
def initialize(options)
@options = options
end
def call
add_gem 'shoulda-matchers', gem_options
configure_test_helper_files
end
protected
attr_reader :options
private
def gem_options
gem_options = { path: fs.root_directory }
if options[:manually]
gem_options[:require] = false
end
gem_options
end
def configure_test_helper_files
each_test_helper_file do |test_helper_file, test_framework, library|
add_configuration_block_to(
test_helper_file,
test_framework,
library
)
end
end
def each_test_helper_file
options[:test_frameworks].each do |test_framework|
library = options[:library]
test_helper_file = test_helper_file_for(test_framework, library)
yield test_helper_file, test_framework, library
end
end
def add_configuration_block_to(test_helper_file, test_framework, library)
test_framework_config = test_framework_config_for(test_framework)
library_config = library_config_for(library)
content = <<-EOT
Shoulda::Matchers.configure do |config|
config.integrate do |with|
#{test_framework_config}
#{library_config}
end
end
EOT
if options[:manually]
content = "require 'shoulda-matchers'\n#{content}"
end
fs.append_to_file(test_helper_file, content)
end
def test_framework_config_for(test_framework)
if test_framework
"with.test_framework :#{test_framework}\n"
else
''
end
end
def library_config_for(library)
if library
"with.library :#{library}\n"
else
''
end
end
def test_helper_file_for(test_framework, library)
if integrates_with_rails?(test_framework, library) || integrates_with_nunit?(test_framework)
'test/test_helper.rb'
elsif integrates_with_rspec?(test_framework)
spec_helper_file_path
end
end
def integrates_with_nunit?(test_framework)
nunit_frameworks = [:test_unit, :minitest, :minitest_4, :minitest_5]
nunit_frameworks.include?(test_framework)
end
def integrates_with_rspec?(test_framework)
test_framework == :rspec
end
def integrates_with_rails?(test_framework, library)
test_framework.nil? && library == :rails
end
end
end

View File

@ -2,6 +2,7 @@ require_relative 'helpers/active_model_helpers'
require_relative 'helpers/base_helpers'
require_relative 'helpers/command_helpers'
require_relative 'helpers/gem_helpers'
require_relative 'helpers/n_unit_helpers'
require_relative 'helpers/rails_version_helpers'
require_relative 'helpers/rspec_helpers'
require_relative 'helpers/ruby_version_helpers'
@ -21,6 +22,7 @@ module AcceptanceTests
include BaseHelpers
include CommandHelpers
include GemHelpers
include NUnitHelpers
include RailsVersionHelpers
include RspecHelpers
include RubyVersionHelpers

View File

@ -0,0 +1,17 @@
require_relative 'rails_version_helpers'
module AcceptanceTests
module NUnitHelpers
include RailsVersionHelpers
def default_test_framework
if rails_version =~ '< 4'
:test_unit
elsif rails_version =~ '~> 4.0.0'
:minitest_4
else
:minitest
end
end
end
end

View File

@ -1,3 +1,5 @@
require_relative 'gem_helpers'
module AcceptanceTests
module RspecHelpers
include GemHelpers

View File

@ -21,23 +21,7 @@ module AcceptanceTests
end
def add_shoulda_matchers_to_project(options = {})
gem_options = { path: fs.root_directory }
if options[:manually]
gem_options[:require] = false
end
add_gem 'shoulda-matchers', gem_options
if options[:manually]
if options[:test_frameworks].include?(:rspec)
append_to_file spec_helper_file_path, "require 'shoulda/matchers'"
end
if options[:test_frameworks].include?(:n_unit)
append_to_file 'test/test_helper.rb', "require 'shoulda/matchers'"
end
end
AddsShouldaMatchersToProject.call(options)
end
def add_minitest_to_project

View File

@ -56,4 +56,12 @@ RSpec.configure do |config|
end
ActiveSupport::Deprecation.behavior = :stderr
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
$VERBOSE = true