Allow the use of matchers from multiple libs, for non rails projects.

* It changes shoulda-matchers to allow the integration with multiple
  libraries like active_model and active_record.

  For example, in a non Rails project isn't possible to use both
  validate_presence_of and validate_uniqueness_of matchers, because they
  are from different libraries (one from active_model and the other from
  active_record respectively).

  This change allow the integration with multiple libraries. fixes #710
This commit is contained in:
Lucas D'Avila 2015-05-07 01:43:35 -03:00 committed by Elliot Winkler
parent c3cc7c9f63
commit 721900b8fd
7 changed files with 83 additions and 33 deletions

View File

@ -19,7 +19,7 @@
include the gem as normal.
* You'll need to add the following somewhere in your `rails_helper` (for
RSpec) or `test_helper` (for Minitest / Test::Unit):
``` ruby
Shoulda::Matchers.configure do |config|
config.integrate do |with|
@ -29,11 +29,11 @@
with.test_framework :minitest_4
with.test_framework :test_unit
# Choose a library:
# Choose one or more libraries:
with.library :active_record
with.library :active_model
with.library :action_controller
# Or, choose all of the above:
# Or, choose the following (which implies all of the above):
with.library :rails
end
end

View File

@ -165,11 +165,11 @@ Shoulda::Matchers.configure do |config|
with.test_framework :minitest_4
with.test_framework :test_unit
# Choose a library:
# Choose one or more libraries:
with.library :active_record
with.library :active_model
with.library :action_controller
# Or, choose all of the above:
# Or, choose the following (which implies all of the above):
with.library :rails
end
end

View File

@ -11,6 +11,7 @@ module Shoulda
def initialize(configuration, &block)
@test_frameworks = Set.new
@libraries = Set.new
test_framework :missing_test_framework
library :missing_library
@ -24,14 +25,14 @@ module Shoulda
end
def library(name)
@library = Integrations.find_library!(name)
@libraries << Integrations.find_library!(name)
end
def apply
if no_test_frameworks_added? && library_not_set?
if no_test_frameworks_added? && no_libraries_added?
raise ConfigurationError, <<EOT
shoulda-matchers is not configured correctly. You need to specify a test
framework and/or library. For example:
shoulda-matchers is not configured correctly. You need to specify at least one
test framework and/or library. For example:
Shoulda::Matchers.configure do |config|
config.integrate do |with|
@ -44,7 +45,7 @@ EOT
@test_frameworks.each do |test_framework|
test_framework.include(Shoulda::Matchers::Independent)
@library.integrate_with(test_framework)
@libraries.each { |library| library.integrate_with(test_framework) }
end
end
@ -58,8 +59,8 @@ EOT
@test_frameworks.empty? || !@test_frameworks.any?(&:present?)
end
def library_not_set?
@library.nil?
def no_libraries_added?
@libraries.empty?
end
end
end

View File

@ -6,7 +6,7 @@ describe 'shoulda-matchers integrates with an ActiveModel project' do
add_shoulda_matchers_to_project(
test_frameworks: [:rspec],
library: :active_model
libraries: [:active_model]
)
write_file 'load_dependencies.rb', <<-FILE

View File

@ -0,0 +1,52 @@
require 'acceptance_spec_helper'
describe 'shoulda-matchers integrates with multiple libraries' do
before do
create_rails_application
write_file 'db/migrate/1_create_users.rb', <<-FILE
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
end
end
end
FILE
run_rake_tasks!(*%w(db:drop db:create db:migrate))
write_file 'app/models/user.rb', <<-FILE
class User < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
end
FILE
add_rspec_file 'spec/models/user_spec.rb', <<-FILE
describe User do
it { should validate_presence_of(:name) }
it { should validate_uniqueness_of(:name) }
end
FILE
updating_bundle do
add_rspec_rails_to_project!
add_shoulda_matchers_to_project(
test_frameworks: [:rspec],
libraries: [:active_record, :active_model]
)
end
end
context 'when using both active_record and active_model libraries' do
it 'allows the use of matchers from both libraries' do
result = run_rspec_suite
expect(result).to have_output('2 examples, 0 failures')
expect(result).to have_output('should require name to be set')
expect(result).to have_output(
'should require case sensitive unique value for name'
)
end
end
end

View File

@ -14,7 +14,7 @@ describe 'shoulda-matchers integrates with Rails' do
end
FILE
run_rake_tasks! *%w(db:drop db:create db:migrate)
run_rake_tasks!(*%w(db:drop db:create db:migrate))
write_file 'app/models/user.rb', <<-FILE
class User < ActiveRecord::Base
@ -39,7 +39,7 @@ describe 'shoulda-matchers integrates with Rails' do
add_gems_for_n_unit
add_shoulda_matchers_to_project(
test_frameworks: [default_test_framework],
library: :rails
libraries: [:rails]
)
end
@ -51,7 +51,7 @@ describe 'shoulda-matchers integrates with Rails' do
add_gems_for_rspec
add_shoulda_matchers_to_project(
test_frameworks: [:rspec],
library: :rails
libraries: [:rails]
)
end
@ -68,7 +68,7 @@ describe 'shoulda-matchers integrates with Rails' do
add_gems_for_rspec
add_shoulda_matchers_to_project(
test_frameworks: [:rspec],
library: :rails,
libraries: [:rails],
manually: true
)
end
@ -84,7 +84,7 @@ describe 'shoulda-matchers integrates with Rails' do
add_gems_for_rspec
add_shoulda_matchers_to_project(
test_frameworks: [:rspec, nil],
library: :rails
libraries: [:rails]
)
end

View File

@ -47,15 +47,15 @@ module AcceptanceTests
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
libraries = options.fetch(:libraries, [])
test_helper_file = test_helper_file_for(test_framework, libraries)
yield test_helper_file, test_framework, libraries
end
end
def add_configuration_block_to(test_helper_file, test_framework, library)
def add_configuration_block_to(test_helper_file, test_framework, libraries)
test_framework_config = test_framework_config_for(test_framework)
library_config = library_config_for(library)
library_config = library_config_for(libraries)
content = <<-EOT
Shoulda::Matchers.configure do |config|
@ -81,16 +81,13 @@ module AcceptanceTests
end
end
def library_config_for(library)
if library
"with.library :#{library}\n"
else
''
end
def library_config_for(libraries)
libraries.map { |library| "with.library :#{library}" }.join("\n")
end
def test_helper_file_for(test_framework, library)
if integrates_with_rails?(test_framework, library) || integrates_with_nunit?(test_framework)
def test_helper_file_for(test_framework, libraries)
if integrates_with_rails?(test_framework, libraries) ||
integrates_with_nunit?(test_framework)
'test/test_helper.rb'
elsif integrates_with_rspec?(test_framework)
spec_helper_file_path
@ -106,8 +103,8 @@ module AcceptanceTests
test_framework == :rspec
end
def integrates_with_rails?(test_framework, library)
test_framework.nil? && library == :rails
def integrates_with_rails?(test_framework, libraries)
test_framework.nil? && libraries.include?(:rails)
end
end
end