Browse files

Created shoulda metagem

  • Loading branch information...
1 parent c482786 commit 46076d5c7517cfc5f11934502eddba99e2dd7da3 @jferris jferris committed with jferris Dec 15, 2010
Showing with 26 additions and 14,398 deletions.
  1. +1 −2 Gemfile
  2. +1 −9 Gemfile.lock
  3. +4 −28 Rakefile
  4. +2 −2 features/rails_integration.feature
  5. +5 −0 features/step_definitions/rails_steps.rb
  6. +0 −8 lib/shoulda-matchers.rb
  7. +0 −38 lib/shoulda/matchers/action_controller.rb
  8. +0 −114 lib/shoulda/matchers/action_controller/assign_to_matcher.rb
  9. +0 −50 lib/shoulda/matchers/action_controller/filter_param_matcher.rb
  10. +0 −62 lib/shoulda/matchers/action_controller/redirect_to_matcher.rb
  11. +0 −54 lib/shoulda/matchers/action_controller/render_template_matcher.rb
  12. +0 −99 lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb
  13. +0 −74 lib/shoulda/matchers/action_controller/respond_with_content_type_matcher.rb
  14. +0 −85 lib/shoulda/matchers/action_controller/respond_with_matcher.rb
  15. +0 −93 lib/shoulda/matchers/action_controller/route_matcher.rb
  16. +0 −98 lib/shoulda/matchers/action_controller/set_session_matcher.rb
  17. +0 −94 lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb
  18. +0 −22 lib/shoulda/matchers/action_mailer.rb
  19. +0 −110 lib/shoulda/matchers/action_mailer/have_sent_email.rb
  20. +0 −42 lib/shoulda/matchers/active_record.rb
  21. +0 −83 lib/shoulda/matchers/active_record/allow_mass_assignment_of_matcher.rb
  22. +0 −110 lib/shoulda/matchers/active_record/allow_value_matcher.rb
  23. +0 −226 lib/shoulda/matchers/active_record/association_matcher.rb
  24. +0 −87 lib/shoulda/matchers/active_record/ensure_inclusion_of_matcher.rb
  25. +0 −141 lib/shoulda/matchers/active_record/ensure_length_of_matcher.rb
  26. +0 −169 lib/shoulda/matchers/active_record/have_db_column_matcher.rb
  27. +0 −112 lib/shoulda/matchers/active_record/have_db_index_matcher.rb
  28. +0 −59 lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb
  29. +0 −34 lib/shoulda/matchers/active_record/helpers.rb
  30. +0 −41 lib/shoulda/matchers/active_record/validate_acceptance_of_matcher.rb
  31. +0 −65 lib/shoulda/matchers/active_record/validate_format_of_matcher.rb
  32. +0 −39 lib/shoulda/matchers/active_record/validate_numericality_of_matcher.rb
  33. +0 −60 lib/shoulda/matchers/active_record/validate_presence_of_matcher.rb
  34. +0 −148 lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb
  35. +0 −56 lib/shoulda/matchers/active_record/validation_matcher.rb
  36. +0 −23 lib/shoulda/matchers/integrations/rspec.rb
  37. +0 −41 lib/shoulda/matchers/integrations/test_unit.rb
  38. +0 −6 lib/shoulda/matchers/version.rb
  39. +4 −0 lib/shoulda/version.rb
  40. +9 −3 shoulda-matchers.gemspec → shoulda.gemspec
  41. +0 −3 spec/fixtures/addresses.yml
  42. 0 spec/fixtures/friendships.yml
  43. +0 −5 spec/fixtures/posts.yml
  44. 0 spec/fixtures/products.yml
  45. 0 spec/fixtures/taggings.yml
  46. +0 −9 spec/fixtures/tags.yml
  47. +0 −6 spec/fixtures/users.yml
  48. +0 −4 spec/rails3_root/.gitignore
  49. +0 −7 spec/rails3_root/Gemfile
  50. +0 −95 spec/rails3_root/Gemfile.lock
  51. +0 −244 spec/rails3_root/README
  52. +0 −10 spec/rails3_root/Rakefile
  53. +0 −22 spec/rails3_root/app/controllers/application_controller.rb
  54. +0 −87 spec/rails3_root/app/controllers/posts_controller.rb
  55. +0 −82 spec/rails3_root/app/controllers/users_controller.rb
  56. +0 −2 spec/rails3_root/app/helpers/application_helper.rb
  57. +0 −7 spec/rails3_root/app/models/address.rb
  58. +0 −11 spec/rails3_root/app/models/flea.rb
  59. +0 −4 spec/rails3_root/app/models/friendship.rb
  60. +0 −8 spec/rails3_root/app/models/notifier.rb
  61. +0 −7 spec/rails3_root/app/models/pets/cat.rb
  62. +0 −10 spec/rails3_root/app/models/pets/dog.rb
  63. +0 −12 spec/rails3_root/app/models/post.rb
  64. +0 −12 spec/rails3_root/app/models/product.rb
  65. +0 −2 spec/rails3_root/app/models/profile.rb
  66. +0 −2 spec/rails3_root/app/models/registration.rb
  67. +0 −8 spec/rails3_root/app/models/tag.rb
  68. +0 −4 spec/rails3_root/app/models/tagging.rb
  69. +0 −3 spec/rails3_root/app/models/treat.rb
  70. +0 −32 spec/rails3_root/app/models/user.rb
  71. +0 −14 spec/rails3_root/app/views/layouts/application.html.erb
  72. +0 −19 spec/rails3_root/app/views/layouts/posts.rhtml
  73. +0 −17 spec/rails3_root/app/views/layouts/users.rhtml
  74. +0 −1 spec/rails3_root/app/views/layouts/wide.html.erb
  75. +0 −1 spec/rails3_root/app/views/notifier/the_email.html.erb
  76. +0 −27 spec/rails3_root/app/views/posts/edit.rhtml
  77. +0 −25 spec/rails3_root/app/views/posts/index.rhtml
  78. +0 −24 spec/rails3_root/app/views/posts/new.rhtml
  79. +0 −18 spec/rails3_root/app/views/posts/show.rhtml
  80. +0 −22 spec/rails3_root/app/views/users/edit.rhtml
  81. +0 −22 spec/rails3_root/app/views/users/index.rhtml
  82. +0 −21 spec/rails3_root/app/views/users/new.rhtml
  83. +0 −13 spec/rails3_root/app/views/users/show.rhtml
  84. +0 −4 spec/rails3_root/config.ru
  85. +0 −46 spec/rails3_root/config/application.rb
  86. +0 −6 spec/rails3_root/config/boot.rb
  87. +0 −22 spec/rails3_root/config/database.yml
  88. +0 −5 spec/rails3_root/config/environment.rb
  89. +0 −19 spec/rails3_root/config/environments/development.rb
  90. +0 −42 spec/rails3_root/config/environments/production.rb
  91. +0 −33 spec/rails3_root/config/environments/test.rb
  92. +0 −7 spec/rails3_root/config/initializers/backtrace_silencers.rb
  93. +0 −10 spec/rails3_root/config/initializers/inflections.rb
  94. +0 −5 spec/rails3_root/config/initializers/mime_types.rb
  95. +0 −7 spec/rails3_root/config/initializers/secret_token.rb
  96. +0 −8 spec/rails3_root/config/initializers/session_store.rb
  97. +0 −5 spec/rails3_root/config/locales/en.yml
  98. +0 −2 spec/rails3_root/config/routes.rb
  99. +0 −19 spec/rails3_root/db/migrate/001_create_users.rb
  100. +0 −13 spec/rails3_root/db/migrate/002_create_posts.rb
  101. +0 −12 spec/rails3_root/db/migrate/003_create_taggings.rb
  102. +0 −11 spec/rails3_root/db/migrate/004_create_tags.rb
  103. +0 −12 spec/rails3_root/db/migrate/005_create_dogs.rb
  104. +0 −14 spec/rails3_root/db/migrate/006_create_addresses.rb
  105. +0 −11 spec/rails3_root/db/migrate/007_create_fleas.rb
  106. +0 −12 spec/rails3_root/db/migrate/008_create_dogs_fleas.rb
  107. +0 −17 spec/rails3_root/db/migrate/009_create_products.rb
  108. +0 −14 spec/rails3_root/db/migrate/010_create_friendships.rb
  109. +0 −12 spec/rails3_root/db/migrate/011_create_treats.rb
  110. +0 −12 spec/rails3_root/db/migrate/20090506203502_create_profiles.rb
  111. +0 −14 spec/rails3_root/db/migrate/20090506203536_create_registrations.rb
  112. +0 −12 spec/rails3_root/db/migrate/20090513104502_create_cats.rb
  113. +0 −7 spec/rails3_root/db/seeds.rb
  114. 0 spec/rails3_root/lib/tasks/.gitkeep
  115. +0 −26 spec/rails3_root/public/404.html
  116. +0 −26 spec/rails3_root/public/422.html
  117. +0 −26 spec/rails3_root/public/500.html
  118. 0 spec/rails3_root/public/favicon.ico
  119. BIN spec/rails3_root/public/images/rails.png
  120. +0 −279 spec/rails3_root/public/index.html
  121. +0 −2 spec/rails3_root/public/javascripts/application.js
  122. +0 −965 spec/rails3_root/public/javascripts/controls.js
  123. +0 −974 spec/rails3_root/public/javascripts/dragdrop.js
  124. +0 −1,123 spec/rails3_root/public/javascripts/effects.js
  125. +0 −4,874 spec/rails3_root/public/javascripts/prototype.js
  126. +0 −118 spec/rails3_root/public/javascripts/rails.js
  127. +0 −5 spec/rails3_root/public/robots.txt
  128. 0 spec/rails3_root/public/stylesheets/.gitkeep
  129. +0 −9 spec/rails3_root/script/rails
  130. +0 −9 spec/rails3_root/test/performance/browsing_test.rb
  131. +0 −6 spec/rails3_root/test/shoulda_macros/custom_macro.rb
  132. +0 −13 spec/rails3_root/test/test_helper.rb
  133. +0 −6 spec/rails3_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb
  134. 0 spec/rails3_root/vendor/plugins/.gitkeep
  135. 0 spec/rails3_root/vendor/plugins/.keep
  136. +0 −6 spec/rails3_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb
  137. +0 −55 spec/shoulda/action_controller/assign_to_matcher_spec.rb
  138. +0 −23 spec/shoulda/action_controller/filter_param_matcher_spec.rb
  139. +0 −37 spec/shoulda/action_controller/redirect_to_matcher_spec.rb
  140. +0 −38 spec/shoulda/action_controller/render_template_matcher_spec.rb
  141. +0 −48 spec/shoulda/action_controller/render_with_layout_matcher_spec.rb
  142. +0 −32 spec/shoulda/action_controller/respond_with_content_type_matcher_spec.rb
  143. +0 −96 spec/shoulda/action_controller/respond_with_matcher_spec.rb
  144. +0 −66 spec/shoulda/action_controller/route_matcher_spec.rb
  145. +0 −48 spec/shoulda/action_controller/set_session_matcher_spec.rb
  146. +0 −95 spec/shoulda/action_controller/set_the_flash_matcher_spec.rb
  147. +0 −71 spec/shoulda/action_mailer/have_sent_email_spec.rb
  148. +0 −74 spec/shoulda/active_record/allow_mass_assignment_of_matcher_spec.rb
  149. +0 −62 spec/shoulda/active_record/allow_value_matcher_spec.rb
  150. +0 −261 spec/shoulda/active_record/association_matcher_spec.rb
  151. +0 −71 spec/shoulda/active_record/ensure_inclusion_of_matcher_spec.rb
  152. +0 −125 spec/shoulda/active_record/ensure_length_of_matcher_spec.rb
  153. +0 −169 spec/shoulda/active_record/have_db_column_matcher_spec.rb
  154. +0 −90 spec/shoulda/active_record/have_db_index_matcher_spec.rb
  155. +0 −29 spec/shoulda/active_record/have_readonly_attributes_matcher_spec.rb
  156. +0 −43 spec/shoulda/active_record/validate_acceptance_of_matcher_spec.rb
  157. +0 −35 spec/shoulda/active_record/validate_format_of_matcher_spec.rb
  158. +0 −49 spec/shoulda/active_record/validate_numericality_of_matcher_spec.rb
  159. +0 −86 spec/shoulda/active_record/validate_presence_of_matcher_spec.rb
  160. +0 −145 spec/shoulda/active_record/validate_uniqueness_of_matcher_spec.rb
  161. +0 −32 spec/spec_helper.rb
  162. +0 −129 spec/support/model_builder.rb
View
3 Gemfile
@@ -2,8 +2,7 @@ source 'http://rubygems.org'
gem 'rails', '3.0.3'
gem 'sqlite3-ruby', :require => 'sqlite3'
-gem 'mocha'
-gem 'rspec-rails'
+gem 'rspec'
gem 'ruby-debug'
gem 'cucumber'
gem "aruba"
View
10 Gemfile.lock
@@ -56,8 +56,6 @@ GEM
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
- mocha (0.9.10)
- rake
polyglot (0.3.1)
rack (1.2.1)
rack-mount (0.6.13)
@@ -86,11 +84,6 @@ GEM
rspec-expectations (2.3.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.3.0)
- rspec-rails (2.3.0)
- actionpack (~> 3.0)
- activesupport (~> 3.0)
- railties (~> 3.0)
- rspec (~> 2.3.0)
ruby-debug (0.10.4)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.4.0)
@@ -109,8 +102,7 @@ PLATFORMS
DEPENDENCIES
aruba
cucumber
- mocha
rails (= 3.0.3)
- rspec-rails
+ rspec
ruby-debug
sqlite3-ruby
View
32 Rakefile
@@ -1,37 +1,13 @@
require 'rubygems'
require 'bundler/setup'
require 'rake'
-require 'rake/rdoctask'
require 'rake/gempackagetask'
-require 'rspec/core/rake_task'
require 'cucumber/rake/task'
$LOAD_PATH.unshift("lib")
-require 'shoulda/matchers/version'
+require 'shoulda/version'
-Rake::RDocTask.new { |rdoc|
- rdoc.rdoc_dir = 'doc'
- rdoc.title = "Shoulda -- Making tests easy on the fingers and eyes"
- rdoc.options << '--line-numbers'
- rdoc.template = "#{ENV['template']}.rb" if ENV['template']
- rdoc.rdoc_files.include('README.rdoc', 'CONTRIBUTION_GUIDELINES.rdoc', 'lib/**/*.rb')
-}
-
-RSpec::Core::RakeTask.new do |t|
- t.pattern = "spec/**/*_spec.rb"
- t.rspec_opts = '--color --format progress'
- t.verbose = false
-end
-
-desc "Run code-coverage analysis using rcov"
-RSpec::Core::RakeTask.new(:coverage) do |t|
- t.rspec_opts = '--color --format progress'
- t.rcov = true
- t.rcov_opts = %{--exclude osx\/objc,spec,gems\/ --failure-threshold 100}
- t.pattern = "spec/**/*_spec.rb"
-end
-
-eval("$specification = begin; #{IO.read('shoulda-matchers.gemspec')}; end")
+eval("$specification = begin; #{IO.read('shoulda.gemspec')}; end")
Rake::GemPackageTask.new $specification do |pkg|
pkg.need_tar = true
pkg.need_zip = true
@@ -45,6 +21,6 @@ Cucumber::Rake::Task.new do |t|
t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'progress')]
end
-desc 'Default: run specs and cucumber features'
-task :default => [:spec, :cucumber]
+desc 'Default: run cucumber features'
+task :default => [:cucumber]
View
4 features/rails_integration.feature
@@ -33,7 +33,7 @@ Feature: integrate with Rails
Scenario: generate a rails application and use matchers in Test::Unit
When I configure the application to use shoulda-context
- And I configure the application to use "shoulda-matchers" from this project
+ When I configure the application to use shoulda-matchers
And I write to "test/unit/user_test.rb" with:
"""
require 'test_helper'
@@ -63,7 +63,7 @@ Feature: integrate with Rails
Scenario: generate a rails application and use matchers in Rspec
When I configure the application to use rspec-rails
- And I configure the application to use "shoulda-matchers" from this project
+ And I configure the application to use shoulda-matchers
And I run the rspec generator
And I write to "spec/models/user_spec.rb" with:
"""
View
5 features/step_definitions/rails_steps.rb
@@ -36,6 +36,11 @@
steps %{And I run "bundle install --local"}
end
+When /^I configure the application to use shoulda-matchers$/ do
+ append_to_gemfile "gem 'shoulda-matchers', :git => 'git@github.com:thoughtbot/shoulda-matchers.git'"
+ steps %{And I run "bundle install --local"}
+end
+
When /^I configure a wildcard route$/ do
steps %{
When I write to "config/routes.rb" with:
View
8 lib/shoulda-matchers.rb
@@ -1,8 +0,0 @@
-require 'shoulda/matchers/version'
-
-if defined?(RSpec)
- require 'shoulda/matchers/integrations/rspec'
-else
- require 'shoulda/matchers/integrations/test_unit'
-end
-
View
38 lib/shoulda/matchers/action_controller.rb
@@ -1,38 +0,0 @@
-require 'shoulda/matchers/action_controller/assign_to_matcher'
-require 'shoulda/matchers/action_controller/filter_param_matcher'
-require 'shoulda/matchers/action_controller/set_the_flash_matcher'
-require 'shoulda/matchers/action_controller/render_with_layout_matcher'
-require 'shoulda/matchers/action_controller/respond_with_matcher'
-require 'shoulda/matchers/action_controller/respond_with_content_type_matcher'
-require 'shoulda/matchers/action_controller/set_session_matcher'
-require 'shoulda/matchers/action_controller/route_matcher'
-require 'shoulda/matchers/action_controller/redirect_to_matcher'
-require 'shoulda/matchers/action_controller/render_template_matcher'
-
-module Shoulda
- module Matchers
- # By using the matchers you can quickly and easily create concise and
- # easy to read test suites.
- #
- # This code segment:
- #
- # describe UsersController, "on GET to show with a valid id" do
- # before(:each) do
- # get :show, :id => User.first.to_param
- # end
- #
- # it { should assign_to(:user) }
- # it { should respond_with(:success) }
- # it { should render_template(:show) }
- # it { should not_set_the_flash) }
- #
- # it "should do something else really cool" do
- # assigns[:user].id.should == 1
- # end
- # end
- #
- # Would produce 5 tests for the show action
- module ActionController
- end
- end
-end
View
114 lib/shoulda/matchers/action_controller/assign_to_matcher.rb
@@ -1,114 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures that the controller assigned to the named instance variable.
- #
- # Options:
- # * <tt>with_kind_of</tt> - The expected class of the instance variable
- # being checked.
- # * <tt>with</tt> - The value that should be assigned.
- #
- # Example:
- #
- # it { should assign_to(:user) }
- # it { should_not assign_to(:user) }
- # it { should assign_to(:user).with_kind_of(User) }
- # it { should assign_to(:user).with(@user) }
- def assign_to(variable)
- AssignToMatcher.new(variable)
- end
-
- class AssignToMatcher # :nodoc:
-
- def initialize(variable)
- @variable = variable.to_s
- @check_value = false
- end
-
- def with_kind_of(expected_class)
- @expected_class = expected_class
- self
- end
-
- def with(expected_value = nil, &block)
- @check_value = true
- @expected_value = expected_value
- @expectation_block = block
- self
- end
-
- def matches?(controller)
- @controller = controller
- @expected_value = @context.instance_eval(&@expectation_block) if @expectation_block
- assigned_value? && kind_of_expected_class? && equal_to_expected_value?
- end
-
- attr_reader :failure_message, :negative_failure_message
-
- def description
- description = "assign @#{@variable}"
- description << " with a kind of #{@expected_class}" if @expected_class
- description
- end
-
- def in_context(context)
- @context = context
- self
- end
-
- private
-
- def assigned_value?
- if !@controller.instance_variables.include?("@#{@variable}")
- @failure_message =
- "Expected action to assign a value for @#{@variable}"
- false
- else
- @negative_failure_message =
- "Didn't expect action to assign a value for @#{@variable}, " <<
- "but it was assigned to #{assigned_value.inspect}"
- true
- end
- end
-
- def kind_of_expected_class?
- return true unless @expected_class
- if assigned_value.kind_of?(@expected_class)
- @negative_failure_message =
- "Didn't expect action to assign a kind of #{@expected_class} " <<
- "for #{@variable}, but got one anyway"
- true
- else
- @failure_message =
- "Expected action to assign a kind of #{@expected_class} " <<
- "for #{@variable}, but got #{@variable.inspect} " <<
- "(#{@variable.class.name})"
- false
- end
- end
-
- def equal_to_expected_value?
- return true unless @check_value
- if @expected_value == assigned_value
- @negative_failure_message =
- "Didn't expect action to assign #{@expected_value.inspect} " <<
- "for #{@variable}, but got it anyway"
- true
- else
- @failure_message =
- "Expected action to assign #{@expected_value.inspect} " <<
- "for #{@variable}, but got #{assigned_value.inspect}"
- false
- end
- end
-
- def assigned_value
- @controller.instance_variable_get("@#{@variable}")
- end
-
- end
-
- end
- end
-end
View
50 lib/shoulda/matchers/action_controller/filter_param_matcher.rb
@@ -1,50 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures that filter_parameter_logging is set for the specified key.
- #
- # Example:
- #
- # it { should filter_param(:password) }
- def filter_param(key)
- FilterParamMatcher.new(key)
- end
-
- class FilterParamMatcher # :nodoc:
-
- def initialize(key)
- @key = key.to_s
- end
-
- def matches?(controller)
- @controller = controller
- filters_key?
- end
-
- def failure_message
- "Expected #{@key} to be filtered; filtered keys: #{filtered_keys.join(', ')}"
- end
-
- def negative_failure_message
- "Did not expect #{@key} to be filtered"
- end
-
- def description
- "filter #{@key}"
- end
-
- private
-
- def filters_key?
- filtered_keys.include?(@key)
- end
-
- def filtered_keys
- Rails.application.config.filter_parameters.map { |filter| filter.to_s }
- end
- end
-
- end
- end
-end
View
62 lib/shoulda/matchers/action_controller/redirect_to_matcher.rb
@@ -1,62 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures a controller redirected to the given url.
- #
- # Example:
- #
- # it { should redirect_to('http://somewhere.com') }
- # it { should redirect_to(users_path) }
- def redirect_to(url_or_description, &block)
- RedirectToMatcher.new(url_or_description, self, &block)
- end
-
- class RedirectToMatcher # :nodoc:
-
- def initialize(url_or_description, context, &block)
- if block
- @url_block = block
- @location = @url_or_description
- else
- @url = url_or_description
- @location = @url
- end
- @context = context
- end
-
- def in_context(context)
- @context = context
- self
- end
-
- def matches?(controller)
- @controller = controller
- redirects_to_url?
- end
-
- attr_reader :failure_message, :negative_failure_message
-
- def description
- "redirect to #{@location}"
- end
-
- private
-
- def redirects_to_url?
- @url = @context.instance_eval(&@url_block) if @url_block
- begin
- @context.send(:assert_redirected_to, @url)
- @negative_failure_message = "Didn't expect to redirect to #{@url}"
- true
- rescue Test::Unit::AssertionFailedError => error
- @failure_message = error.message
- false
- end
- end
-
- end
-
- end
- end
-end
View
54 lib/shoulda/matchers/action_controller/render_template_matcher.rb
@@ -1,54 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures a controller rendered the given template.
- #
- # Example:
- #
- # it { should render_template(:show) }
- def render_template(template)
- RenderTemplateMatcher.new(template, self)
- end
-
- class RenderTemplateMatcher # :nodoc:
-
- def initialize(template, context)
- @template = template.to_s
- @context = context
- end
-
- def matches?(controller)
- @controller = controller
- renders_template?
- end
-
- attr_reader :failure_message, :negative_failure_message
-
- def description
- "render template #{@template}"
- end
-
- def in_context(context)
- @context = context
- self
- end
-
- private
-
- def renders_template?
- begin
- @context.send(:assert_template, @template)
- @negative_failure_message = "Didn't expect to render #{@template}"
- true
- rescue Test::Unit::AssertionFailedError => error
- @failure_message = error.message
- false
- end
- end
-
- end
-
- end
- end
-end
View
99 lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb
@@ -1,99 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures that the controller rendered with the given layout.
- #
- # Example:
- #
- # it { should render_with_layout }
- # it { should render_with_layout(:special) }
- # it { should_not render_with_layout }
- def render_with_layout(expected_layout = nil)
- RenderWithLayoutMatcher.new(expected_layout).in_context(self)
- end
-
- class RenderWithLayoutMatcher # :nodoc:
-
- def initialize(expected_layout)
- @expected_layout = expected_layout.to_s unless expected_layout.nil?
- end
-
- # Used to provide access to layouts recorded by
- # ActionController::TemplateAssertions in Rails 3
- def in_context(context)
- @context = context
- self
- end
-
- def matches?(controller)
- @controller = controller
- rendered_with_layout? && rendered_with_expected_layout?
- end
-
- def failure_message
- "Expected #{expectation}, but #{result}"
- end
-
- def negative_failure_message
- "Did not expect #{expectation}, but #{result}"
- end
-
- def description
- description = "render with "
- if @expected_layout.nil?
- description << "a layout"
- else
- description << "the #{@expected_layout.inspect} layout"
- end
- description
- end
-
- private
-
- def rendered_with_layout?
- !rendered_layouts.empty?
- end
-
- def rendered_with_expected_layout?
- return true if @expected_layout.nil?
- rendered_layouts.include?(@expected_layout)
- end
-
- def rendered_layouts
- if recorded_layouts
- recorded_layouts.keys.compact.map { |layout| layout.sub(%r{^layouts/}, '') }
- else
- layout = @controller.response.layout
- if layout.nil?
- []
- else
- [layout.split('/').last]
- end
- end
- end
-
- def recorded_layouts
- if @context
- @context.instance_variable_get('@layouts')
- end
- end
-
- def expectation
- "to #{description}"
- end
-
- def result
- if rendered_with_layout?
- "rendered with " <<
- rendered_layouts.map { |layout| layout.inspect }.join(", ")
- else
- "rendered without a layout"
- end
- end
-
- end
-
- end
- end
-end
View
74 lib/shoulda/matchers/action_controller/respond_with_content_type_matcher.rb
@@ -1,74 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures a controller responded with expected 'response' content type.
- #
- # You can pass an explicit content type such as 'application/rss+xml'
- # or its symbolic equivalent :rss
- # or a regular expression such as /rss/
- #
- # Example:
- #
- # it { should respond_with_content_type(:xml) }
- # it { should respond_with_content_type(:csv) }
- # it { should respond_with_content_type(:atom) }
- # it { should respond_with_content_type(:yaml) }
- # it { should respond_with_content_type(:text) }
- # it { should respond_with_content_type('application/rss+xml') }
- # it { should respond_with_content_type(/json/) }
- def respond_with_content_type(content_type)
- RespondWithContentTypeMatcher.new(content_type)
- end
-
- class RespondWithContentTypeMatcher # :nodoc:
-
- def initialize(content_type)
- @content_type = if content_type.is_a?(Symbol)
- lookup_by_extension(content_type)
- else
- content_type
- end
- end
-
- def description
- "respond with content type of #{@content_type}"
- end
-
- def matches?(controller)
- @controller = controller
- if @content_type.is_a?(Regexp)
- response_content_type =~ @content_type
- else
- response_content_type == @content_type
- end
- end
-
- def failure_message
- "Expected #{expectation}"
- end
-
- def negative_failure_message
- "Did not expect #{expectation}"
- end
-
- protected
-
- def response_content_type
- @controller.response.content_type.to_s
- end
-
- def lookup_by_extension(extension)
- Mime::Type.lookup_by_extension(extension.to_s).to_s
- end
-
- def expectation
- "content type to be #{@content_type}, " <<
- "but was #{response_content_type}"
- end
-
- end
-
- end
- end
-end
View
85 lib/shoulda/matchers/action_controller/respond_with_matcher.rb
@@ -1,85 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures a controller responded with expected 'response' status code.
- #
- # You can pass an explicit status number like 200, 301, 404, 500
- # or its symbolic equivalent :success, :redirect, :missing, :error.
- # See ActionController::StatusCodes for a full list.
- #
- # Example:
- #
- # it { should respond_with(:success) }
- # it { should respond_with(:redirect) }
- # it { should respond_with(:missing) }
- # it { should respond_with(:error) }
- # it { should respond_with(501) }
- def respond_with(status)
- RespondWithMatcher.new(status)
- end
-
- class RespondWithMatcher # :nodoc:
-
- def initialize(status)
- @status = symbol_to_status_code(status)
- end
-
- def matches?(controller)
- @controller = controller
- correct_status_code? || correct_status_code_range?
- end
-
- def failure_message
- "Expected #{expectation}"
- end
-
- def negative_failure_message
- "Did not expect #{expectation}"
- end
-
- def description
- "respond with #{@status}"
- end
-
- protected
-
- def correct_status_code?
- response_code == @status
- end
-
- def correct_status_code_range?
- @status.is_a?(Range) &&
- @status.include?(response_code)
- end
-
- def response_code
- @controller.response.response_code
- end
-
- def symbol_to_status_code(potential_symbol)
- case potential_symbol
- when :success then 200
- when :redirect then 300..399
- when :missing then 404
- when :error then 500..599
- when Symbol
- if defined?(::Rack::Utils::SYMBOL_TO_STATUS_CODE)
- ::Rack::Utils::SYMBOL_TO_STATUS_CODE[potential_symbol]
- else
- ::ActionController::Base::SYMBOL_TO_STATUS_CODE[potential_symbol]
- end
- else
- potential_symbol
- end
- end
-
- def expectation
- "response to be a #{@status}, but was #{response_code}"
- end
-
- end
-
- end
- end
-end
View
93 lib/shoulda/matchers/action_controller/route_matcher.rb
@@ -1,93 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures that requesting +path+ using +method+ routes to +options+.
- #
- # If you don't specify a controller, it will use the controller from the
- # example group.
- #
- # +to_param+ is called on the +options+ given.
- #
- # Examples:
- #
- # it { should route(:get, "/posts").
- # to(:controller => :posts, :action => :index) }
- # it { should route(:get, "/posts/new").to(:action => :new) }
- # it { should route(:post, "/posts").to(:action => :create) }
- # it { should route(:get, "/posts/1").to(:action => :show, :id => 1) }
- # it { should route(:edit, "/posts/1").to(:action => :show, :id => 1) }
- # it { should route(:put, "/posts/1").to(:action => :update, :id => 1) }
- # it { should route(:delete, "/posts/1").
- # to(:action => :destroy, :id => 1) }
- # it { should route(:get, "/users/1/posts/1").
- # to(:action => :show, :id => 1, :user_id => 1) }
- def route(method, path)
- RouteMatcher.new(method, path, self)
- end
-
- class RouteMatcher # :nodoc:
-
- def initialize(method, path, context)
- @method = method
- @path = path
- @context = context
- end
-
- def to(params)
- @params = params
- stringify_params!
- self
- end
-
- def in_context(context)
- @context = context
- self
- end
-
- def matches?(controller)
- @controller = controller
- guess_controller!
- route_recognized?
- end
-
- attr_reader :failure_message, :negative_failure_message
-
- def description
- "route #{@method.to_s.upcase} #{@path} to/from #{@params.inspect}"
- end
-
- private
-
- def guess_controller!
- @params[:controller] ||= @controller.controller_path
- end
-
- def stringify_params!
- @params.each do |key, value|
- @params[key] = value.is_a?(Array) ? value.collect {|v| v.to_param } : value.to_param
- end
- end
-
- def route_recognized?
- begin
- @context.send(:assert_routing,
- { :method => @method, :path => @path },
- @params)
-
- @negative_failure_message = "Didn't expect to #{description}"
- true
- rescue ::ActionController::RoutingError => error
- @failure_message = error.message
- false
- rescue Test::Unit::AssertionFailedError => error
- @failure_message = error.message
- false
- end
- end
-
- end
-
- end
- end
-end
View
98 lib/shoulda/matchers/action_controller/set_session_matcher.rb
@@ -1,98 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures that a session key was set to the expected value.
- #
- # Example:
- #
- # it { should set_session(:message) }
- # it { should set_session(:user_id).to(@user.id) }
- # it { should_not set_session(:user_id) }
- def set_session(key)
- SetSessionMatcher.new(key)
- end
-
- class SetSessionMatcher # :nodoc:
-
- def initialize(key)
- @key = key.to_s
- end
-
- def to(value = nil, &block)
- @value = value
- @value_block = block
- self
- end
-
- def matches?(controller)
- @controller = controller
- @value = @context.instance_eval(&@value_block) if @value_block
- (assigned_value? && assigned_correct_value?) || cleared_value?
- end
-
- def failure_message
- "Expected #{expectation}, but #{result}"
- end
-
- def negative_failure_message
- "Didn't expect #{expectation}, but #{result}"
- end
-
- def description
- description = "set session variable #{@key.inspect}"
- description << " to #{@value.inspect}" if defined?(@value)
- description
- end
-
- def in_context(context)
- @context = context
- self
- end
-
- private
-
- def assigned_value?
- !assigned_value.nil?
- end
-
- def cleared_value?
- defined?(@value) && @value.nil? && assigned_value.nil?
- end
-
- def assigned_correct_value?
- return true if @value.nil?
- assigned_value == @value
- end
-
- def assigned_value
- session[@key]
- end
-
- def session
- if @controller.request.respond_to?(:session)
- @controller.request.session.to_hash
- else
- @controller.response.session.data
- end
- end
-
- def expectation
- expectation = "session variable #{@key} to be set"
- expectation << " to #{@value.inspect}" if @value
- expectation
- end
-
- def result
- if session.empty?
- "no session variables were set"
- else
- "the session was #{session.inspect}"
- end
- end
-
- end
-
- end
- end
-end
View
94 lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb
@@ -1,94 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionController # :nodoc:
-
- # Ensures that the flash contains the given value. Can be a String, a
- # Regexp, or nil (indicating that the flash should not be set).
- #
- # Example:
- #
- # it { should set_the_flash }
- # it { should set_the_flash.to("Thank you for placing this order.") }
- # it { should set_the_flash.to(/created/i) }
- # it { should set_the_flash.to(/logged in/i).now }
- # it { should_not set_the_flash }
- def set_the_flash
- SetTheFlashMatcher.new
- end
-
- class SetTheFlashMatcher # :nodoc:
-
- def to(value)
- @value = value
- self
- end
-
- def now
- @now = true
- self
- end
-
- def matches?(controller)
- @controller = controller
- sets_the_flash? && string_value_matches? && regexp_value_matches?
- end
-
- attr_reader :failure_message, :negative_failure_message
-
- def description
- description = "set the flash"
- description << " to #{@value.inspect}" unless @value.nil?
- description
- end
-
- def failure_message
- "Expected #{expectation}"
- end
-
- def negative_failure_message
- "Did not expect #{expectation}"
- end
-
- private
-
- def sets_the_flash?
- !flash.blank?
- end
-
- def string_value_matches?
- return true unless String === @value
- flash.values.any? {|value| value == @value }
- end
-
- def regexp_value_matches?
- return true unless Regexp === @value
- flash.values.any? {|value| value =~ @value }
- end
-
- def flash
- return @flash if @flash
- @flash = @controller.flash.dup
- @flash.sweep unless @now
- @flash
- end
-
- def expectation
- expectation = "the flash#{".now" if @now} to be set"
- expectation << " to #{@value.inspect}" unless @value.nil?
- expectation << ", but #{flash_description}"
- expectation
- end
-
- def flash_description
- if flash.blank?
- "no flash was set"
- else
- "was #{flash.inspect}"
- end
- end
-
- end
-
- end
- end
-end
View
22 lib/shoulda/matchers/action_mailer.rb
@@ -1,22 +0,0 @@
-require 'shoulda/matchers/action_mailer/have_sent_email'
-
-module Shoulda
- module Matchers
- # = Matchers for your mailers
- #
- # This matcher will test that email is sent properly
- #
- # describe User do
- # it { should have_sent_email.with_subject(/is spam$/) }
- # it { should have_sent_email.from('do-not-reply@example.com') }
- # it { should have_sent_email.with_body(/is spam\./) }
- # it { should have_sent_email.to('myself@me.com') }
- # it { should have_sent_email.with_subject(/spam/).
- # from('do-not-reply@example.com').
- # with_body(/spam/).
- # to('myself@me.com') }
- # end
- module ActionMailer
- end
- end
-end
View
110 lib/shoulda/matchers/action_mailer/have_sent_email.rb
@@ -1,110 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActionMailer # :nodoc:
-
- # The right email is sent.
- #
- # it { should have_sent_email.with_subject(/is spam$/) }
- # it { should have_sent_email.from('do-not-reply@example.com') }
- # it { should have_sent_email.with_body(/is spam\./) }
- # it { should have_sent_email.to('myself@me.com') }
- # it { should have_sent_email.with_subject(/spam/).
- # from('do-not-reply@example.com').
- # with_body(/spam/).
- # to('myself@me.com') }
- def have_sent_email
- HaveSentEmailMatcher.new
- end
-
- class HaveSentEmailMatcher # :nodoc:
-
- def initialize
- end
-
- def with_subject(email_subject)
- @email_subject = email_subject
- self
- end
-
- def from(sender)
- @sender = sender
- self
- end
-
- def with_body(body)
- @body = body
- self
- end
-
- def to(recipient)
- @recipient = recipient
- self
- end
-
- def matches?(subject)
- ::ActionMailer::Base.deliveries.each do |mail|
- @subject_failed = !regexp_or_string_match(mail.subject, @email_subject) if @email_subject
- @body_failed = !regexp_or_string_match(mail.body, @body) if @body
- @sender_failed = !regexp_or_string_match_in_array(mail.from, @sender) if @sender
- @recipient_failed = !regexp_or_string_match_in_array(mail.to, @recipient) if @recipient
- return true unless anything_failed?
- end
-
- false
- end
-
- def failure_message
- "Expected #{expectation}"
- end
-
- def negative_failure_message
- "Did not expect #{expectation}"
- end
-
- def description
- "send an email"
- end
-
- private
-
- def expectation
- expectation = "sent email"
- expectation << " with subject #{@email_subject.inspect}" if @subject_failed
- expectation << " with body #{@body.inspect}" if @body_failed
- expectation << " from #{@sender.inspect}" if @sender_failed
- expectation << " to #{@recipient.inspect}" if @recipient_failed
- expectation << "\nDeliveries:\n#{inspect_deliveries}"
- end
-
- def inspect_deliveries
- ::ActionMailer::Base.deliveries.map do |delivery|
- "#{delivery.subject.inspect} to #{delivery.to.inspect}"
- end.join("\n")
- end
-
- def anything_failed?
- @subject_failed || @body_failed || @sender_failed || @recipient_failed
- end
-
- def regexp_or_string_match(a_string, a_regexp_or_string)
- case a_regexp_or_string
- when Regexp
- a_string =~ a_regexp_or_string
- when String
- a_string == a_regexp_or_string
- end
- end
-
- def regexp_or_string_match_in_array(an_array, a_regexp_or_string)
- case a_regexp_or_string
- when Regexp
- an_array.any? { |string| string =~ a_regexp_or_string }
- when String
- an_array.include?(a_regexp_or_string)
- end
- end
- end
- end
- end
-
-end
View
42 lib/shoulda/matchers/active_record.rb
@@ -1,42 +0,0 @@
-require 'shoulda/matchers/active_record/helpers'
-require 'shoulda/matchers/active_record/validation_matcher'
-require 'shoulda/matchers/active_record/allow_value_matcher'
-require 'shoulda/matchers/active_record/ensure_length_of_matcher'
-require 'shoulda/matchers/active_record/ensure_inclusion_of_matcher'
-require 'shoulda/matchers/active_record/validate_presence_of_matcher'
-require 'shoulda/matchers/active_record/validate_format_of_matcher'
-require 'shoulda/matchers/active_record/validate_uniqueness_of_matcher'
-require 'shoulda/matchers/active_record/validate_acceptance_of_matcher'
-require 'shoulda/matchers/active_record/validate_numericality_of_matcher'
-require 'shoulda/matchers/active_record/association_matcher'
-require 'shoulda/matchers/active_record/have_db_column_matcher'
-require 'shoulda/matchers/active_record/have_db_index_matcher'
-require 'shoulda/matchers/active_record/have_readonly_attribute_matcher'
-require 'shoulda/matchers/active_record/allow_mass_assignment_of_matcher'
-
-
-module Shoulda
- module Matchers
- # = Matchers for your active record models
- #
- # These matchers will test most of the validations and associations for your
- # ActiveRecord models.
- #
- # describe User do
- # it { should validate_presence_of(:name) }
- # it { should validate_presence_of(:phone_number) }
- # %w(abcd 1234).each do |value|
- # it { should_not allow_value(value).for(:phone_number) }
- # end
- # it { should allow_value("(123) 456-7890").for(:phone_number) }
- # it { should_not allow_mass_assignment_of(:password) }
- # it { should have_one(:profile) }
- # it { should have_many(:dogs) }
- # it { should have_many(:messes).through(:dogs) }
- # it { should belong_to(:lover) }
- # end
- #
- module ActiveRecord
- end
- end
-end
View
83 lib/shoulda/matchers/active_record/allow_mass_assignment_of_matcher.rb
@@ -1,83 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActiveRecord # :nodoc:
-
- # Ensures that the attribute can be set on mass update.
- #
- # it { should_not allow_mass_assignment_of(:password) }
- # it { should allow_mass_assignment_of(:first_name) }
- #
- def allow_mass_assignment_of(value)
- AllowMassAssignmentOfMatcher.new(value)
- end
-
- class AllowMassAssignmentOfMatcher # :nodoc:
-
- def initialize(attribute)
- @attribute = attribute.to_s
- end
-
- def matches?(subject)
- @subject = subject
- if attr_mass_assignable?
- if whitelisting?
- @negative_failure_message = "#{@attribute} was made accessible"
- else
- if protected_attributes.empty?
- @negative_failure_message = "no attributes were protected"
- else
- @negative_failure_message = "#{class_name} is protecting " <<
- "#{protected_attributes.to_a.to_sentence}, " <<
- "but not #{@attribute}."
- end
- end
- true
- else
- if whitelisting?
- @failure_message =
- "Expected #{@attribute} to be accessible"
- else
- @failure_message =
- "Did not expect #{@attribute} to be protected"
- end
- false
- end
- end
-
- attr_reader :failure_message, :negative_failure_message
-
- def description
- "allow mass assignment of #{@attribute}"
- end
-
- private
-
- def protected_attributes
- @protected_attributes ||= (@subject.class.protected_attributes || [])
- end
-
- def accessible_attributes
- @accessible_attributes ||= (@subject.class.accessible_attributes || [])
- end
-
- def whitelisting?
- !accessible_attributes.empty?
- end
-
- def attr_mass_assignable?
- if whitelisting?
- accessible_attributes.include?(@attribute)
- else
- !protected_attributes.include?(@attribute)
- end
- end
-
- def class_name
- @subject.class.name
- end
-
- end
-
- end
- end
-end
View
110 lib/shoulda/matchers/active_record/allow_value_matcher.rb
@@ -1,110 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActiveRecord # :nodoc:
-
- # Ensures that the attribute can be set to the given value.
- #
- # Options:
- # * <tt>with_message</tt> - value the test expects to find in
- # <tt>errors.on(:attribute)</tt>. Regexp or string. If omitted,
- # the test looks for any errors in <tt>errors.on(:attribute)</tt>.
- #
- # Example:
- # it { should_not allow_value('bad').for(:isbn) }
- # it { should allow_value("isbn 1 2345 6789 0").for(:isbn) }
- #
- def allow_value(value)
- AllowValueMatcher.new(value)
- end
-
- class AllowValueMatcher # :nodoc:
- include Helpers
-
- def initialize(value)
- @value = value
- end
-
- def for(attribute)
- @attribute = attribute
- self
- end
-
- def with_message(message)
- @expected_message = message if message
- self
- end
-
- def matches?(instance)
- @instance = instance
- if Symbol === @expected_message
- @expected_message = default_error_message(@expected_message)
- end
- @instance.send("#{@attribute}=", @value)
- !errors_match?
- end
-
- def failure_message
- "Did not expect #{expectation}, got error: #{@matched_error}"
- end
-
- def negative_failure_message
- "Expected #{expectation}, got #{error_description}"
- end
-
- def description
- "allow #{@attribute} to be set to #{@value.inspect}"
- end
-
- private
-
- def errors_match?
- @instance.valid?
- @errors = errors_for_attribute(@instance, @attribute)
- @errors = [@errors] unless @errors.is_a?(Array)
- @expected_message ? (errors_match_regexp? || errors_match_string?) : (@errors.compact.any?)
- end
-
- def errors_for_attribute(instance, attribute)
- if instance.errors.respond_to?(:[])
- instance.errors[attribute]
- else
- instance.errors.on(attribute)
- end
- end
-
- def errors_match_regexp?
- if Regexp === @expected_message
- @matched_error = @errors.detect { |e| e =~ @expected_message }
- !@matched_error.nil?
- else
- false
- end
- end
-
- def errors_match_string?
- if @errors.include?(@expected_message)
- @matched_error = @expected_message
- true
- else
- false
- end
- end
-
- def expectation
- "errors " <<
- (@expected_message ? "to include #{@expected_message.inspect} " : "") <<
- "when #{@attribute} is set to #{@value.inspect}"
- end
-
- def error_description
- if @instance.errors.empty?
- "no errors"
- else
- "errors: #{pretty_error_messages(@instance)}"
- end
- end
- end
-
- end
- end
-end
View
226 lib/shoulda/matchers/active_record/association_matcher.rb
@@ -1,226 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActiveRecord # :nodoc:
-
- # Ensure that the belongs_to relationship exists.
- #
- # it { should belong_to(:parent) }
- #
- def belong_to(name)
- AssociationMatcher.new(:belongs_to, name)
- end
-
- # Ensures that the has_many relationship exists. Will also test that the
- # associated table has the required columns. Works with polymorphic
- # associations.
- #
- # Options:
- # * <tt>through</tt> - association name for <tt>has_many :through</tt>
- # * <tt>dependent</tt> - tests that the association makes use of the
- # dependent option.
- #
- # Example:
- # it { should have_many(:friends) }
- # it { should have_many(:enemies).through(:friends) }
- # it { should have_many(:enemies).dependent(:destroy) }
- #
- def have_many(name)
- AssociationMatcher.new(:has_many, name)
- end
-
- # Ensure that the has_one relationship exists. Will also test that the
- # associated table has the required columns. Works with polymorphic
- # associations.
- #
- # Options:
- # * <tt>:dependent</tt> - tests that the association makes use of the
- # dependent option.
- #
- # Example:
- # it { should have_one(:god) } # unless hindu
- #
- def have_one(name)
- AssociationMatcher.new(:has_one, name)
- end
-
- # Ensures that the has_and_belongs_to_many relationship exists, and that
- # the join table is in place.
- #
- # it { should have_and_belong_to_many(:posts) }
- #
- def have_and_belong_to_many(name)
- AssociationMatcher.new(:has_and_belongs_to_many, name)
- end
-
- class AssociationMatcher # :nodoc:
- def initialize(macro, name)
- @macro = macro
- @name = name
- end
-
- def through(through)
- @through = through
- self
- end
-
- def dependent(dependent)
- @dependent = dependent
- self
- end
-
- def matches?(subject)
- @subject = subject
- association_exists? &&
- macro_correct? &&
- foreign_key_exists? &&
- through_association_valid? &&
- dependent_correct? &&
- join_table_exists?
- end
-
- def failure_message
- "Expected #{expectation} (#{@missing})"
- end
-
- def negative_failure_message
- "Did not expect #{expectation}"
- end
-
- def description
- description = "#{macro_description} #{@name}"
- description += " through #{@through}" if @through
- description += " dependent => #{@dependent}" if @dependent
- description
- end
-
- protected
-
- def association_exists?
- if reflection.nil?
- @missing = "no association called #{@name}"
- false
- else
- true
- end
- end
-
- def macro_correct?
- if reflection.macro == @macro
- true
- else
- @missing = "actual association type was #{reflection.macro}"
- false
- end
- end
-
- def foreign_key_exists?
- !(belongs_foreign_key_missing? || has_foreign_key_missing?)
- end
-
- def belongs_foreign_key_missing?
- @macro == :belongs_to && !class_has_foreign_key?(model_class)
- end
-
- def has_foreign_key_missing?
- [:has_many, :has_one].include?(@macro) &&
- !through? &&
- !class_has_foreign_key?(associated_class)
- end
-
- def through_association_valid?
- @through.nil? || (through_association_exists? && through_association_correct?)
- end
-
- def through_association_exists?
- if through_reflection.nil?
- @missing = "#{model_class.name} does not have any relationship to #{@through}"
- false
- else
- true
- end
- end
-
- def through_association_correct?
- if @through == reflection.options[:through]
- true
- else
- @missing = "Expected #{model_class.name} to have #{@name} through #{@through}, " <<
- "but got it through #{reflection.options[:through]}"
- false
- end
- end
-
- def dependent_correct?
- if @dependent.nil? || @dependent.to_s == reflection.options[:dependent].to_s
- true
- else
- @missing = "#{@name} should have #{@dependent} dependency"
- false
- end
- end
-
- def join_table_exists?
- if @macro != :has_and_belongs_to_many ||
- ::ActiveRecord::Base.connection.tables.include?(join_table.to_s)
- true
- else
- @missing = "join table #{join_table} doesn't exist"
- false
- end
- end
-
- def class_has_foreign_key?(klass)
- if klass.column_names.include?(foreign_key.to_s)
- true
- else
- @missing = "#{klass} does not have a #{foreign_key} foreign key."
- false
- end
- end
-
- def model_class
- @subject.class
- end
-
- def join_table
- reflection.options[:join_table]
- end
-
- def associated_class
- reflection.klass
- end
-
- def foreign_key
- reflection.primary_key_name
- end
-
- def through?
- reflection.options[:through]
- end
-
- def reflection
- @reflection ||= model_class.reflect_on_association(@name)
- end
-
- def through_reflection
- @through_reflection ||= model_class.reflect_on_association(@through)
- end
-
- def expectation
- "#{model_class.name} to have a #{@macro} association called #{@name}"
- end
-
- def macro_description
- case @macro.to_s
- when 'belongs_to' then 'belong to'
- when 'has_many' then 'have many'
- when 'has_one' then 'have one'
- when 'has_and_belongs_to_many' then
- 'have and belong to many'
- end
- end
- end
-
- end
- end
-end
View
87 lib/shoulda/matchers/active_record/ensure_inclusion_of_matcher.rb
@@ -1,87 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActiveRecord # :nodoc:
-
- # Ensure that the attribute's value is in the range specified
- #
- # Options:
- # * <tt>in_range</tt> - the range of allowed values for this attribute
- # * <tt>with_low_message</tt> - value the test expects to find in
- # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
- # translation for :inclusion.
- # * <tt>with_high_message</tt> - value the test expects to find in
- # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
- # translation for :inclusion.
- #
- # Example:
- # it { should ensure_inclusion_of(:age).in_range(0..100) }
- #
- def ensure_inclusion_of(attr)
- EnsureInclusionOfMatcher.new(attr)
- end
-
- class EnsureInclusionOfMatcher < ValidationMatcher # :nodoc:
-
- def in_range(range)
- @range = range
- @minimum = range.first
- @maximum = range.last
- self
- end
-
- def with_message(message)
- if message
- @low_message = message
- @high_message = message
- end
- self
- end
-
- def with_low_message(message)
- @low_message = message if message
- self
- end
-
- def with_high_message(message)
- @high_message = message if message
- self
- end
-
- def description
- "ensure inclusion of #{@attribute} in #{@range.inspect}"
- end
-
- def matches?(subject)
- super(subject)
-
- @low_message ||= :inclusion
- @high_message ||= :inclusion
-
- disallows_lower_value &&
- allows_minimum_value &&
- disallows_higher_value &&
- allows_maximum_value
- end
-
- private
-
- def disallows_lower_value
- @minimum == 0 || disallows_value_of(@minimum - 1, @low_message)
- end
-
- def disallows_higher_value
- disallows_value_of(@maximum + 1, @high_message)
- end
-
- def allows_minimum_value
- allows_value_of(@minimum, @low_message)
- end
-
- def allows_maximum_value
- allows_value_of(@maximum, @high_message)
- end
- end
-
- end
- end
-end
View
141 lib/shoulda/matchers/active_record/ensure_length_of_matcher.rb
@@ -1,141 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActiveRecord # :nodoc:
-
- # Ensures that the length of the attribute is validated.
- #
- # Options:
- # * <tt>is_at_least</tt> - minimum length of this attribute
- # * <tt>is_at_most</tt> - maximum length of this attribute
- # * <tt>is_equal_to</tt> - exact requred length of this attribute
- # * <tt>with_short_message</tt> - value the test expects to find in
- # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
- # translation for :too_short.
- # * <tt>with_long_message</tt> - value the test expects to find in
- # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
- # translation for :too_long.
- # * <tt>with_message</tt> - value the test expects to find in
- # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
- # translation for :wrong_length. Used in conjunction with
- # <tt>is_equal_to</tt>.
- #
- # Examples:
- # it { should ensure_length_of(:password).
- # is_at_least(6).
- # is_at_most(20) }
- # it { should ensure_length_of(:name).
- # is_at_least(3).
- # with_short_message(/not long enough/) }
- # it { should ensure_length_of(:ssn).
- # is_equal_to(9).
- # with_message(/is invalid/) }
- def ensure_length_of(attr)
- EnsureLengthOfMatcher.new(attr)
- end
-
- class EnsureLengthOfMatcher < ValidationMatcher # :nodoc:
- include Helpers
-
- def is_at_least(length)
- @minimum = length
- @short_message ||= :too_short
- self
- end
-
- def is_at_most(length)
- @maximum = length
- @long_message ||= :too_long
- self
- end
-
- def is_equal_to(length)
- @minimum = length
- @maximum = length
- @short_message ||= :wrong_length
- self
- end
-
- def with_short_message(message)
- @short_message = message if message
- self
- end
- alias_method :with_message, :with_short_message
-
- def with_long_message(message)
- @long_message = message if message
- self
- end
-
- def description
- description = "ensure #{@attribute} has a length "
- if @minimum && @maximum
- if @minimum == @maximum
- description << "of exactly #{@minimum}"
- else
- description << "between #{@minimum} and #{@maximum}"
- end
- else
- description << "of at least #{@minimum}" if @minimum
- description << "of at most #{@maximum}" if @maximum
- end
- description
- end
-
- def matches?(subject)
- super(subject)
- translate_messages!
- disallows_lower_length &&
- allows_minimum_length &&
- ((@minimum == @maximum) ||
- (disallows_higher_length &&
- allows_maximum_length))
- end
-
- private
-
- def translate_messages!
- if Symbol === @short_message
- @short_message = default_error_message(@short_message,
- :count => @minimum)
- end
-
- if Symbol === @long_message
- @long_message = default_error_message(@long_message,
- :count => @maximum)
- end
- end
-
- def disallows_lower_length
- @minimum == 0 ||
- @minimum.nil? ||
- disallows_length_of(@minimum - 1, @short_message)
- end
-
- def disallows_higher_length
- @maximum.nil? || disallows_length_of(@maximum + 1, @long_message)
- end
-
- def allows_minimum_length
- allows_length_of(@minimum, @short_message)
- end
-
- def allows_maximum_length
- allows_length_of(@maximum, @long_message)
- end
-
- def allows_length_of(length, message)
- length.nil? || allows_value_of(string_of_length(length), message)
- end
-
- def disallows_length_of(length, message)
- length.nil? || disallows_value_of(string_of_length(length), message)
- end
-
- def string_of_length(length)
- 'x' * length
- end
- end
-
- end
- end
-end
View
169 lib/shoulda/matchers/active_record/have_db_column_matcher.rb
@@ -1,169 +0,0 @@
-module Shoulda # :nodoc:
- module Matchers
- module ActiveRecord # :nodoc:
-
- # Ensures the database column exists.
- #
- # Options:
- # * <tt>of_type</tt> - db column type (:integer, :string, etc.)
- # * <tt>with_options</tt> - same options available in migrations
- # (:default, :null, :limit, :precision, :scale)
- #
- # Examples:
- # it { should_not have_db_column(:admin).of_type(:boolean) }
- # it { should have_db_column(:salary).
- # of_type(:decimal).
- # with_options(:precision => 10, :scale => 2) }
- #
- def have_db_column(column)
- HaveDbColumnMatcher.new(:have_db_column, column)
- end
-
- class HaveDbColumnMatcher # :nodoc:
- def initialize(macro, column)
- @macro = macro
- @column = column
- end
-
- def of_type(column_type)
- @column_type = column_type
- self
- end
-
- def with_options(opts = {})
- @precision = opts[:precision]
- @limit = opts[:limit]
- @default = opts[:default]
- @null = opts[:null]
- @scale = opts[:scale]
- self
- end
-
- def matches?(subject)
- @subject = subject
- column_exists? &&
- correct_column_type? &&
- correct_precision? &&
- correct_limit? &&
- correct_default? &&
- correct_null? &&
- correct_scale?
- end
-
- def failure_message
- "Expected #{expectation} (#{@missing})"
- end
-
- def negative_failure_message
- "Did not expect #{expectation}"
- end
-
- def description
- desc = "have db column named #{@column}"
- desc << " of type #{@column_type}" unless @column_type.nil?
- desc << " of precision #{@precision}" unless @precision.nil?
- desc << " of limit #{@limit}" unless @limit.nil?
- desc << " of default #{@default}" unless @default.nil?
- desc << " of null #{@null}" unless @null.nil?
- desc << " of primary #{@primary}" unless @primary.nil?
- desc << " of scale #{@scale}" unless @scale.nil?
- desc
- end
-
- protected
-
- def column_exists?
- if model_class.column_names.include?(@column.to_s)
- true
- else
- @missing = "#{model_class} does not have a db column named #{@column}."
- false
- end
- end
-
- def correct_column_type?
- return true if @column_type.nil?
- if matched_column.type.to_s == @column_type.to_s
- true
- else
- @missing = "#{model_class} has a db column named #{@column} " <<
- "of type #{matched_column.type}, not #{@column_type}."
- false
- end
- end
-
- def correct_precision?
- return true if @precision.nil?
- if matched_column.precision.to_s == @precision.to_s
- true
- else
- @missing = "#{model_class} has a db column named #{@column} " <<
- "of precision #{matched_column.precision}, " <<
- "not #{@precision}."
- false
- end
- end
-
- def correct_limit?
- return true if @limit.nil?
- if matched_column.limit.to_s == @limit.to_s
- true
- else
- @missing = "#{model_class} has a db column named #{@column} " <<
- "of limit #{matched_column.limit}, " <<
- "not #{@limit}."
- false
- end
- end
-
- def correct_default?
- return true if @default.nil?
- if matched_column.default.to_s == @default.to_s
- true
- else
- @missing = "#{model_class} has a db column named #{@column} " <<
- "of default #{matched_column.default}, " <<
- "not #{@default}."
- false
- end
- end
-
- def correct_null?
- return true if @null.nil?
- if matched_column.null.to_s == @null.to_s
- true
- else
- @missing = "#{model_class} has a db column named #{@column} " <<
- "of null #{matched_column.null}, " <<
- "not #{@null}."
- false
- end
- end
-
- def correct_scale?
- return true if @scale.nil?
- if matched_column.scale.to_s == @scale.to_s
- true
- else
- @missing = "#{model_class} has a db column named #{@column} " <<
- "of scale #{matched_column.scale}, not #{@scale}."
- false
- end
- end
-
- def matched_column
- model_class.columns.detect { |each| each.name == @column.to_s }
- end