Organizando plugins e gems.
This commit is contained in:
258
vendor/gems/thoughtbot-shoulda-2.10.1/.specification
vendored
Normal file
258
vendor/gems/thoughtbot-shoulda-2.10.1/.specification
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
--- !ruby/object:Gem::Specification
|
||||
name: thoughtbot-shoulda
|
||||
version: !ruby/object:Gem::Version
|
||||
version: 2.10.1
|
||||
platform: ruby
|
||||
authors:
|
||||
- Tammer Saleh
|
||||
autorequire:
|
||||
bindir: bin
|
||||
cert_chain: []
|
||||
|
||||
date: 2009-03-05 00:00:00 -03:00
|
||||
default_executable: convert_to_should_syntax
|
||||
dependencies: []
|
||||
|
||||
description:
|
||||
email: tsaleh@thoughtbot.com
|
||||
executables:
|
||||
- convert_to_should_syntax
|
||||
extensions: []
|
||||
|
||||
extra_rdoc_files:
|
||||
- README.rdoc
|
||||
- CONTRIBUTION_GUIDELINES.rdoc
|
||||
files:
|
||||
- CONTRIBUTION_GUIDELINES.rdoc
|
||||
- MIT-LICENSE
|
||||
- Rakefile
|
||||
- README.rdoc
|
||||
- bin/convert_to_should_syntax
|
||||
- lib/shoulda
|
||||
- lib/shoulda/action_controller
|
||||
- lib/shoulda/action_controller/helpers.rb
|
||||
- lib/shoulda/action_controller/macros.rb
|
||||
- lib/shoulda/action_controller/matchers
|
||||
- lib/shoulda/action_controller/matchers/assign_to_matcher.rb
|
||||
- lib/shoulda/action_controller/matchers/filter_param_matcher.rb
|
||||
- lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb
|
||||
- lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb
|
||||
- lib/shoulda/action_controller/matchers/respond_with_matcher.rb
|
||||
- lib/shoulda/action_controller/matchers/route_matcher.rb
|
||||
- lib/shoulda/action_controller/matchers/set_session_matcher.rb
|
||||
- lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb
|
||||
- lib/shoulda/action_controller/matchers.rb
|
||||
- lib/shoulda/action_controller.rb
|
||||
- lib/shoulda/action_mailer
|
||||
- lib/shoulda/action_mailer/assertions.rb
|
||||
- lib/shoulda/action_mailer.rb
|
||||
- lib/shoulda/action_view
|
||||
- lib/shoulda/action_view/macros.rb
|
||||
- lib/shoulda/action_view.rb
|
||||
- lib/shoulda/active_record
|
||||
- lib/shoulda/active_record/assertions.rb
|
||||
- lib/shoulda/active_record/helpers.rb
|
||||
- lib/shoulda/active_record/macros.rb
|
||||
- lib/shoulda/active_record/matchers
|
||||
- lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/allow_value_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/association_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/have_db_column_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/have_index_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/have_named_scope_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb
|
||||
- lib/shoulda/active_record/matchers/validation_matcher.rb
|
||||
- lib/shoulda/active_record/matchers.rb
|
||||
- lib/shoulda/active_record.rb
|
||||
- lib/shoulda/assertions.rb
|
||||
- lib/shoulda/autoload_macros.rb
|
||||
- lib/shoulda/context.rb
|
||||
- lib/shoulda/helpers.rb
|
||||
- lib/shoulda/macros.rb
|
||||
- lib/shoulda/private_helpers.rb
|
||||
- lib/shoulda/proc_extensions.rb
|
||||
- lib/shoulda/rails.rb
|
||||
- lib/shoulda/rspec.rb
|
||||
- lib/shoulda/tasks
|
||||
- lib/shoulda/tasks/list_tests.rake
|
||||
- lib/shoulda/tasks/yaml_to_shoulda.rake
|
||||
- lib/shoulda/tasks.rb
|
||||
- lib/shoulda/test_unit.rb
|
||||
- lib/shoulda.rb
|
||||
- rails/init.rb
|
||||
- test/fail_macros.rb
|
||||
- test/fixtures
|
||||
- test/fixtures/addresses.yml
|
||||
- test/fixtures/friendships.yml
|
||||
- test/fixtures/posts.yml
|
||||
- test/fixtures/products.yml
|
||||
- test/fixtures/taggings.yml
|
||||
- test/fixtures/tags.yml
|
||||
- test/fixtures/users.yml
|
||||
- test/functional
|
||||
- test/functional/posts_controller_test.rb
|
||||
- test/functional/users_controller_test.rb
|
||||
- test/matchers
|
||||
- test/matchers/active_record
|
||||
- test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb
|
||||
- test/matchers/active_record/allow_value_matcher_test.rb
|
||||
- test/matchers/active_record/association_matcher_test.rb
|
||||
- test/matchers/active_record/ensure_inclusion_of_matcher_test.rb
|
||||
- test/matchers/active_record/ensure_length_of_matcher_test.rb
|
||||
- test/matchers/active_record/have_db_column_matcher_test.rb
|
||||
- test/matchers/active_record/have_index_matcher_test.rb
|
||||
- test/matchers/active_record/have_named_scope_matcher_test.rb
|
||||
- test/matchers/active_record/have_readonly_attributes_matcher_test.rb
|
||||
- test/matchers/active_record/validate_acceptance_of_matcher_test.rb
|
||||
- test/matchers/active_record/validate_numericality_of_matcher_test.rb
|
||||
- test/matchers/active_record/validate_presence_of_matcher_test.rb
|
||||
- test/matchers/active_record/validate_uniqueness_of_matcher_test.rb
|
||||
- test/matchers/controller
|
||||
- test/matchers/controller/assign_to_matcher_test.rb
|
||||
- test/matchers/controller/filter_param_matcher_test.rb
|
||||
- test/matchers/controller/render_with_layout_matcher_test.rb
|
||||
- test/matchers/controller/respond_with_content_type_matcher_test.rb
|
||||
- test/matchers/controller/respond_with_matcher_test.rb
|
||||
- test/matchers/controller/route_matcher_test.rb
|
||||
- test/matchers/controller/set_session_matcher_test.rb
|
||||
- test/matchers/controller/set_the_flash_matcher.rb
|
||||
- test/model_builder.rb
|
||||
- test/other
|
||||
- test/other/autoload_macro_test.rb
|
||||
- test/other/context_test.rb
|
||||
- test/other/convert_to_should_syntax_test.rb
|
||||
- test/other/helpers_test.rb
|
||||
- test/other/private_helpers_test.rb
|
||||
- test/other/should_test.rb
|
||||
- test/rails_root
|
||||
- test/rails_root/app
|
||||
- test/rails_root/app/controllers
|
||||
- test/rails_root/app/controllers/application.rb
|
||||
- test/rails_root/app/controllers/posts_controller.rb
|
||||
- test/rails_root/app/controllers/users_controller.rb
|
||||
- test/rails_root/app/helpers
|
||||
- test/rails_root/app/helpers/application_helper.rb
|
||||
- test/rails_root/app/helpers/posts_helper.rb
|
||||
- test/rails_root/app/helpers/users_helper.rb
|
||||
- test/rails_root/app/models
|
||||
- test/rails_root/app/models/address.rb
|
||||
- test/rails_root/app/models/flea.rb
|
||||
- test/rails_root/app/models/friendship.rb
|
||||
- test/rails_root/app/models/pets
|
||||
- test/rails_root/app/models/pets/dog.rb
|
||||
- test/rails_root/app/models/post.rb
|
||||
- test/rails_root/app/models/product.rb
|
||||
- test/rails_root/app/models/tag.rb
|
||||
- test/rails_root/app/models/tagging.rb
|
||||
- test/rails_root/app/models/treat.rb
|
||||
- test/rails_root/app/models/user.rb
|
||||
- test/rails_root/app/views
|
||||
- test/rails_root/app/views/layouts
|
||||
- test/rails_root/app/views/layouts/posts.rhtml
|
||||
- test/rails_root/app/views/layouts/users.rhtml
|
||||
- test/rails_root/app/views/layouts/wide.html.erb
|
||||
- test/rails_root/app/views/posts
|
||||
- test/rails_root/app/views/posts/edit.rhtml
|
||||
- test/rails_root/app/views/posts/index.rhtml
|
||||
- test/rails_root/app/views/posts/new.rhtml
|
||||
- test/rails_root/app/views/posts/show.rhtml
|
||||
- test/rails_root/app/views/users
|
||||
- test/rails_root/app/views/users/edit.rhtml
|
||||
- test/rails_root/app/views/users/index.rhtml
|
||||
- test/rails_root/app/views/users/new.rhtml
|
||||
- test/rails_root/app/views/users/show.rhtml
|
||||
- test/rails_root/config
|
||||
- test/rails_root/config/boot.rb
|
||||
- test/rails_root/config/database.yml
|
||||
- test/rails_root/config/environment.rb
|
||||
- test/rails_root/config/environments
|
||||
- test/rails_root/config/environments/test.rb
|
||||
- test/rails_root/config/initializers
|
||||
- test/rails_root/config/initializers/new_rails_defaults.rb
|
||||
- test/rails_root/config/initializers/shoulda.rb
|
||||
- test/rails_root/config/routes.rb
|
||||
- test/rails_root/db
|
||||
- test/rails_root/db/migrate
|
||||
- test/rails_root/db/migrate/001_create_users.rb
|
||||
- test/rails_root/db/migrate/002_create_posts.rb
|
||||
- test/rails_root/db/migrate/003_create_taggings.rb
|
||||
- test/rails_root/db/migrate/004_create_tags.rb
|
||||
- test/rails_root/db/migrate/005_create_dogs.rb
|
||||
- test/rails_root/db/migrate/006_create_addresses.rb
|
||||
- test/rails_root/db/migrate/007_create_fleas.rb
|
||||
- test/rails_root/db/migrate/008_create_dogs_fleas.rb
|
||||
- test/rails_root/db/migrate/009_create_products.rb
|
||||
- test/rails_root/db/migrate/010_create_friendships.rb
|
||||
- test/rails_root/db/migrate/011_create_treats.rb
|
||||
- test/rails_root/db/schema.rb
|
||||
- test/rails_root/log
|
||||
- test/rails_root/log/sqlite3.log
|
||||
- test/rails_root/log/test.log
|
||||
- test/rails_root/public
|
||||
- test/rails_root/public/404.html
|
||||
- test/rails_root/public/422.html
|
||||
- test/rails_root/public/500.html
|
||||
- test/rails_root/script
|
||||
- test/rails_root/script/console
|
||||
- test/rails_root/script/generate
|
||||
- test/rails_root/test
|
||||
- test/rails_root/test/shoulda_macros
|
||||
- test/rails_root/test/shoulda_macros/custom_macro.rb
|
||||
- test/rails_root/vendor
|
||||
- test/rails_root/vendor/gems
|
||||
- test/rails_root/vendor/gems/gem_with_macro-0.0.1
|
||||
- test/rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros
|
||||
- test/rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb
|
||||
- test/rails_root/vendor/plugins
|
||||
- test/rails_root/vendor/plugins/plugin_with_macro
|
||||
- test/rails_root/vendor/plugins/plugin_with_macro/shoulda_macros
|
||||
- test/rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb
|
||||
- test/README
|
||||
- test/rspec_test.rb
|
||||
- test/test_helper.rb
|
||||
- test/unit
|
||||
- test/unit/address_test.rb
|
||||
- test/unit/dog_test.rb
|
||||
- test/unit/flea_test.rb
|
||||
- test/unit/friendship_test.rb
|
||||
- test/unit/post_test.rb
|
||||
- test/unit/product_test.rb
|
||||
- test/unit/tag_test.rb
|
||||
- test/unit/tagging_test.rb
|
||||
- test/unit/user_test.rb
|
||||
has_rdoc: true
|
||||
homepage: http://thoughtbot.com/projects/shoulda
|
||||
post_install_message:
|
||||
rdoc_options:
|
||||
- --line-numbers
|
||||
- --main
|
||||
- README.rdoc
|
||||
require_paths:
|
||||
- lib
|
||||
required_ruby_version: !ruby/object:Gem::Requirement
|
||||
requirements:
|
||||
- - ">="
|
||||
- !ruby/object:Gem::Version
|
||||
version: "0"
|
||||
version:
|
||||
required_rubygems_version: !ruby/object:Gem::Requirement
|
||||
requirements:
|
||||
- - ">="
|
||||
- !ruby/object:Gem::Version
|
||||
version: "0"
|
||||
version:
|
||||
requirements: []
|
||||
|
||||
rubyforge_project: shoulda
|
||||
rubygems_version: 1.3.1
|
||||
signing_key:
|
||||
specification_version: 2
|
||||
summary: Making tests easy on the fingers and eyes
|
||||
test_files: []
|
||||
|
||||
12
vendor/gems/thoughtbot-shoulda-2.10.1/CONTRIBUTION_GUIDELINES.rdoc
vendored
Normal file
12
vendor/gems/thoughtbot-shoulda-2.10.1/CONTRIBUTION_GUIDELINES.rdoc
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
We're using GitHub[http://github.com/thoughtbot/shoulda/tree/master] and Lighthouse[http://thoughtbot.lighthouseapp.com/projects/5807], and we've been getting any combination of github pull requests, Lighthouse tickets, patches, emails, etc. We need to normalize this workflow to make sure we don't miss any fixes.
|
||||
|
||||
* Make sure you're accessing the source from the {official repository}[http://github.com/thoughtbot/shoulda/tree/master].
|
||||
* We prefer git branches over patches, but we can take either.
|
||||
* If you're using git, please make a branch for each separate contribution. We can cherry pick your commits, but pulling from a branch is easier.
|
||||
* If you're submitting patches, please cut each fix or feature into a separate patch.
|
||||
* There should be a Lighthouse[http://thoughtbot.lighthouseapp.com/projects/5807] ticket for any submission. If you've found a bug and want to fix it, open a new ticket at the same time.
|
||||
* We've got github/lighthouse integration going, so you can update tickets when you commit. {This blog post}[http://hoth.entp.com/2008/4/11/github-and-lighthouse-sitting-in-a-tree] explains the commit options pretty well.
|
||||
* Please <b>don't send pull requests</b> Just update the lighthouse ticket with the url for your fix (or attach the patch) when it's ready. The github pull requests pretty much get dropped on the floor until someone with commit rights notices them in the mailbox.
|
||||
* Contributions without tests won't be accepted. The file <tt>/test/README</tt> explains the testing system pretty thoroughly.
|
||||
|
||||
|
||||
22
vendor/gems/thoughtbot-shoulda-2.10.1/MIT-LICENSE
vendored
Normal file
22
vendor/gems/thoughtbot-shoulda-2.10.1/MIT-LICENSE
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2007, Tammer Saleh, Thoughtbot, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
169
vendor/gems/thoughtbot-shoulda-2.10.1/README.rdoc
vendored
Normal file
169
vendor/gems/thoughtbot-shoulda-2.10.1/README.rdoc
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
= Shoulda - Making tests easy on the fingers and eyes
|
||||
|
||||
Shoulda makes it easy to write elegant, understandable, and maintainable tests. Shoulda consists of test macros, assertions, and helpers added on to the Test::Unit framework. It's fully compatible with your existing tests, and requires no retooling to use.
|
||||
|
||||
Helpers:: #context and #should give you RSpec like test blocks.
|
||||
In addition, you get nested contexts and a much more readable syntax.
|
||||
Macros:: Generate hundreds of lines of Controller and ActiveRecord tests with these powerful macros.
|
||||
They get you started quickly, and can help you ensure that your application is conforming to best practices.
|
||||
Assertions:: Many common rails testing idioms have been distilled into a set of useful assertions.
|
||||
Matchers:: Rspec-compatible matchers providing the same tests as Shoulda macros.
|
||||
|
||||
= Usage
|
||||
|
||||
=== Context Helpers (Shoulda::Context)
|
||||
|
||||
Stop killing your fingers with all of those underscores... Name your tests with plain sentences!
|
||||
|
||||
class UserTest < Test::Unit::TestCase
|
||||
context "A User instance" do
|
||||
setup do
|
||||
@user = User.find(:first)
|
||||
end
|
||||
|
||||
should "return its full name" do
|
||||
assert_equal 'John Doe', @user.full_name
|
||||
end
|
||||
|
||||
context "with a profile" do
|
||||
setup do
|
||||
@user.profile = Profile.find(:first)
|
||||
end
|
||||
|
||||
should "return true when sent #has_profile?" do
|
||||
assert @user.has_profile?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Produces the following test methods:
|
||||
|
||||
"test: A User instance should return its full name."
|
||||
"test: A User instance with a profile should return true when sent #has_profile?."
|
||||
|
||||
So readable!
|
||||
|
||||
=== ActiveRecord Tests (Shoulda::ActiveRecord::Macros)
|
||||
|
||||
Quick macro tests for your ActiveRecord associations and validations:
|
||||
|
||||
class PostTest < Test::Unit::TestCase
|
||||
fixtures :all
|
||||
|
||||
should_belong_to :user
|
||||
should_have_many :tags, :through => :taggings
|
||||
|
||||
should_validate_uniqueness_of :title
|
||||
should_validate_presence_of :body, :message => /wtf/
|
||||
should_validate_presence_of :title
|
||||
should_validate_numericality_of :user_id
|
||||
end
|
||||
|
||||
class UserTest < Test::Unit::TestCase
|
||||
should_have_many :posts
|
||||
|
||||
should_not_allow_values_for :email, "blah", "b lah"
|
||||
should_allow_values_for :email, "a@b.com", "asdf@asdf.com"
|
||||
should_ensure_length_in_range :email, 1..100
|
||||
should_ensure_value_in_range :age, 1..100
|
||||
should_not_allow_mass_assignment_of :password
|
||||
end
|
||||
|
||||
Makes TDD so much easier.
|
||||
|
||||
=== Controller Tests (Shoulda::Controller::Macros)
|
||||
|
||||
Macros to test the most common controller patterns...
|
||||
|
||||
context "on GET to :show for first record" do
|
||||
setup do
|
||||
get :show, :id => 1
|
||||
end
|
||||
|
||||
should_assign_to :user
|
||||
should_respond_with :success
|
||||
should_render_template :show
|
||||
should_not_set_the_flash
|
||||
|
||||
should "do something else really cool" do
|
||||
assert_equal 1, assigns(:user).id
|
||||
end
|
||||
end
|
||||
|
||||
=== Helpful Assertions (Shoulda::Assertions)
|
||||
|
||||
More to come here, but have fun with what's there.
|
||||
|
||||
assert_same_elements([:a, :b, :c], [:c, :a, :b])
|
||||
assert_contains(['a', '1'], /\d/)
|
||||
assert_contains(['a', '1'], 'a')
|
||||
|
||||
=== 3rd Party and Application Specific Macros
|
||||
|
||||
Any *.rb file under RAILS_ROOT/test/shoulda_macros/ or vendor/(plugins|gems)/gem_name/shoulda_macros/ will be automatically required when you run your tests. This allows you to distribute macros with your plugins, or to organize the macros inside your application. Remember to add your macro to Test::Unit::TestCase in the macro file:
|
||||
|
||||
# test/shoulda_macros/security.rb
|
||||
class Test::Unit::TestCase
|
||||
def self.should_be_denied(opts = {})
|
||||
should_set_the_flash_to(opts[:flash] || /Please log in/i)
|
||||
should_redirect_to(opts[:redirect] || 'login_url')
|
||||
end
|
||||
end
|
||||
|
||||
= Rails Installation (Test::Unit)
|
||||
|
||||
=== As a Gem
|
||||
|
||||
Use this if you prefer to use versioned releases of shoulda. Specify the gem dependency in your config/environment.rb file:
|
||||
|
||||
Rails::Initializer.run do |config|
|
||||
config.gem "thoughtbot-shoulda", :lib => "shoulda", :source => "http://gems.github.com"
|
||||
end
|
||||
|
||||
Then:
|
||||
|
||||
$ rake gems:install
|
||||
$ rake gems:unpack
|
||||
|
||||
=== As a Plugin
|
||||
|
||||
Use this if you prefer to use the edge version of shoulda:
|
||||
|
||||
$ script/plugin install git://github.com/thoughtbot/shoulda.git
|
||||
|
||||
=== As a Plugin (using git submodules)
|
||||
|
||||
Use this if you prefer the idea of being able to easily switch between using edge or a tagged version of shoulda:
|
||||
|
||||
$ git submodule add git://github.com/thoughtbot/shoulda.git vendor/plugins/shoulda
|
||||
|
||||
= Rails Installation (RSpec)
|
||||
|
||||
If you're using Shoulda with RSpec, we recommend that you add config.gem lines
|
||||
for RSpec and Shoulda in your config/environment/test.rb file, but do not ask
|
||||
Rails to load the RSpec and Shoulda libraries:
|
||||
|
||||
config.gem 'rspec', :lib => false
|
||||
config.gem 'rspec-rails', :lib => false
|
||||
config.gem 'thoughtbot-shoulda',
|
||||
:lib => false,
|
||||
:source => 'http://gems.github.com'
|
||||
|
||||
Then require shoulda from your spec/spec_helper.rb file, before Spec::Runner is
|
||||
configured:
|
||||
|
||||
# requires for RSpec
|
||||
require 'shoulda'
|
||||
Spec::Runner.configure do |config|
|
||||
# ...
|
||||
|
||||
You should not need to require anything besides the top-level shoulda library.
|
||||
|
||||
= Credits
|
||||
|
||||
Shoulda is maintained by {Tammer Saleh}[mailto:tsaleh@thoughtbot.com], and is funded by Thoughtbot[http://www.thoughtbot.com], inc.
|
||||
|
||||
= License
|
||||
|
||||
Shoulda is Copyright © 2006-2008 Tammer Saleh, Thoughtbot. It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
|
||||
72
vendor/gems/thoughtbot-shoulda-2.10.1/Rakefile
vendored
Normal file
72
vendor/gems/thoughtbot-shoulda-2.10.1/Rakefile
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
require 'rake/gempackagetask'
|
||||
|
||||
$LOAD_PATH.unshift("lib")
|
||||
require 'shoulda'
|
||||
load 'tasks/shoulda.rake'
|
||||
|
||||
# Test::Unit::UI::VERBOSE
|
||||
test_files_pattern = 'test/{unit,functional,other,matchers}/**/*_test.rb'
|
||||
Rake::TestTask.new do |t|
|
||||
t.libs << 'lib'
|
||||
t.pattern = test_files_pattern
|
||||
t.verbose = false
|
||||
end
|
||||
|
||||
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')
|
||||
}
|
||||
|
||||
desc "Run code-coverage analysis using rcov"
|
||||
task :coverage do
|
||||
rm_rf "coverage"
|
||||
files = Dir[test_files_pattern]
|
||||
system "rcov --rails --sort coverage -Ilib #{files.join(' ')}"
|
||||
end
|
||||
|
||||
desc 'Update documentation on website'
|
||||
task :sync_docs => 'rdoc' do
|
||||
`rsync -ave ssh doc/ dev@dev.thoughtbot.com:/home/dev/www/dev.thoughtbot.com/shoulda`
|
||||
end
|
||||
|
||||
desc 'Default: run tests.'
|
||||
task :default => ['test']
|
||||
|
||||
spec = Gem::Specification.new do |s|
|
||||
s.name = "shoulda"
|
||||
s.version = Shoulda::VERSION
|
||||
s.summary = "Making tests easy on the fingers and eyes"
|
||||
s.homepage = "http://thoughtbot.com/projects/shoulda"
|
||||
s.rubyforge_project = "shoulda"
|
||||
|
||||
s.files = FileList["[A-Z]*", "{bin,lib,rails,test}/**/*"]
|
||||
s.executables = s.files.grep(/^bin/) { |f| File.basename(f) }
|
||||
|
||||
s.has_rdoc = true
|
||||
s.extra_rdoc_files = ["README.rdoc", "CONTRIBUTION_GUIDELINES.rdoc"]
|
||||
s.rdoc_options = ["--line-numbers", "--main", "README.rdoc"]
|
||||
|
||||
s.authors = ["Tammer Saleh"]
|
||||
s.email = "tsaleh@thoughtbot.com"
|
||||
end
|
||||
|
||||
Rake::GemPackageTask.new spec do |pkg|
|
||||
pkg.need_tar = true
|
||||
pkg.need_zip = true
|
||||
end
|
||||
|
||||
desc "Clean files generated by rake tasks"
|
||||
task :clobber => [:clobber_rdoc, :clobber_package]
|
||||
|
||||
desc "Generate a gemspec file for GitHub"
|
||||
task :gemspec do
|
||||
File.open("#{spec.name}.gemspec", 'w') do |f|
|
||||
f.write spec.to_ruby
|
||||
end
|
||||
end
|
||||
42
vendor/gems/thoughtbot-shoulda-2.10.1/bin/convert_to_should_syntax
vendored
Executable file
42
vendor/gems/thoughtbot-shoulda-2.10.1/bin/convert_to_should_syntax
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env ruby
|
||||
require 'fileutils'
|
||||
require 'tmpdir'
|
||||
|
||||
TMP = Dir::tmpdir
|
||||
|
||||
def usage(msg = nil)
|
||||
puts "Error: #{msg}" if msg
|
||||
puts if msg
|
||||
puts "Usage: #{File.basename(__FILE__)} normal_test_file.rb"
|
||||
puts
|
||||
puts "Will convert an existing test file with names like "
|
||||
puts
|
||||
puts " def test_should_do_stuff"
|
||||
puts " ..."
|
||||
puts " end"
|
||||
puts
|
||||
puts "to one using the new syntax: "
|
||||
puts
|
||||
puts " should \"be super cool\" do"
|
||||
puts " ..."
|
||||
puts " end"
|
||||
puts
|
||||
puts "A copy of the old file will be left under #{TMP} in case\nthis script just seriously screws up"
|
||||
puts
|
||||
exit (msg ? 2 : 0)
|
||||
end
|
||||
|
||||
usage("Wrong number of arguments.") unless ARGV.size == 1
|
||||
usage("Temp directory '#{TMP}' is not valid. Set TMPDIR environment variable to a writeable directory.") unless File.directory?(TMP) && File.writable?(TMP)
|
||||
|
||||
file = ARGV.shift
|
||||
tmpfile = File.join(TMP, File.basename(file))
|
||||
usage("File '#{file}' doesn't exist") unless File.exists?(file)
|
||||
|
||||
FileUtils.cp(file, tmpfile)
|
||||
contents = File.read(tmpfile)
|
||||
contents.gsub!(/def test_should_(\S+)/) {|line| "should \"#{$1.tr('_', ' ')}\" do"}
|
||||
contents.gsub!(/def test_(\S+)/) {|line| "should \"RENAME ME: test #{$1.tr('_', ' ')}\" do"}
|
||||
File.open(file, 'w') { |f| f.write(contents) }
|
||||
|
||||
puts "File '#{file}' has been converted to 'should' syntax. Old version has been stored in '#{tmpfile}'"
|
||||
9
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda.rb
vendored
Normal file
9
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda.rb
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
module Shoulda
|
||||
VERSION = "2.10.1"
|
||||
end
|
||||
|
||||
if defined? Spec
|
||||
require 'shoulda/rspec'
|
||||
else
|
||||
require 'shoulda/test_unit'
|
||||
end
|
||||
32
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller.rb
vendored
Normal file
32
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller.rb
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
require 'shoulda'
|
||||
require 'shoulda/action_controller/helpers'
|
||||
require 'shoulda/action_controller/matchers'
|
||||
require 'shoulda/action_controller/macros'
|
||||
require 'shoulda/action_controller/resource_options'
|
||||
|
||||
module Test # :nodoc: all
|
||||
module Unit
|
||||
class TestCase
|
||||
include Shoulda::ActionController::Matchers
|
||||
include Shoulda::ActionController::Helpers
|
||||
extend Shoulda::ActionController::Macros
|
||||
Shoulda::ActionController::VALID_FORMATS.each do |format|
|
||||
include "Shoulda::ActionController::#{format.to_s.upcase}".constantize
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'shoulda/active_record/assertions'
|
||||
require 'shoulda/action_mailer/assertions'
|
||||
|
||||
module ActionController #:nodoc: all
|
||||
module Integration
|
||||
class Session
|
||||
include Shoulda::Assertions
|
||||
include Shoulda::Helpers
|
||||
include Shoulda::ActiveRecord::Assertions
|
||||
include Shoulda::ActionMailer::Assertions
|
||||
end
|
||||
end
|
||||
end
|
||||
199
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/formats/html.rb
vendored
Normal file
199
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/formats/html.rb
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module HTML # :nodoc: all
|
||||
def self.included(other)
|
||||
other.class_eval do
|
||||
extend Shoulda::ActionController::HTML::ClassMethods
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def controller_name_from_class
|
||||
self.name.gsub(/Test/, '')
|
||||
end
|
||||
|
||||
def make_show_html_tests(res)
|
||||
context "on GET to #{controller_name_from_class}#show" do
|
||||
setup do
|
||||
record = get_existing_record(res)
|
||||
parent_params = make_parent_params(res, record)
|
||||
get :show, parent_params.merge({ res.identifier => record.to_param })
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:show)
|
||||
should_not_assign_to res.object
|
||||
should_redirect_to res.denied.redirect
|
||||
should_set_the_flash_to res.denied.flash
|
||||
else
|
||||
should_assign_to res.object
|
||||
should_respond_with :success
|
||||
should_render_template :show
|
||||
should_not_set_the_flash
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_edit_html_tests(res)
|
||||
context "on GET to #{controller_name_from_class}#edit" do
|
||||
setup do
|
||||
@record = get_existing_record(res)
|
||||
parent_params = make_parent_params(res, @record)
|
||||
get :edit, parent_params.merge({ res.identifier => @record.to_param })
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:edit)
|
||||
should_not_assign_to res.object
|
||||
should_redirect_to res.denied.redirect
|
||||
should_set_the_flash_to res.denied.flash
|
||||
else
|
||||
should_assign_to res.object
|
||||
should_respond_with :success
|
||||
should_render_template :edit
|
||||
should_not_set_the_flash
|
||||
should_render_a_form
|
||||
should "set @#{res.object} to requested instance" do
|
||||
assert_equal @record, assigns(res.object)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_index_html_tests(res)
|
||||
context "on GET to #{controller_name_from_class}#index" do
|
||||
setup do
|
||||
record = get_existing_record(res) rescue nil
|
||||
parent_params = make_parent_params(res, record)
|
||||
get(:index, parent_params)
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:index)
|
||||
should_not_assign_to res.object.to_s.pluralize
|
||||
should_redirect_to res.denied.redirect
|
||||
should_set_the_flash_to res.denied.flash
|
||||
else
|
||||
should_respond_with :success
|
||||
should_assign_to res.object.to_s.pluralize
|
||||
should_render_template :index
|
||||
should_not_set_the_flash
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_new_html_tests(res)
|
||||
context "on GET to #{controller_name_from_class}#new" do
|
||||
setup do
|
||||
record = get_existing_record(res) rescue nil
|
||||
parent_params = make_parent_params(res, record)
|
||||
get(:new, parent_params)
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:new)
|
||||
should_not_assign_to res.object
|
||||
should_redirect_to res.denied.redirect
|
||||
should_set_the_flash_to res.denied.flash
|
||||
else
|
||||
should_respond_with :success
|
||||
should_assign_to res.object
|
||||
should_not_set_the_flash
|
||||
should_render_template :new
|
||||
should_render_a_form
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_destroy_html_tests(res)
|
||||
context "on DELETE to #{controller_name_from_class}#destroy" do
|
||||
setup do
|
||||
@record = get_existing_record(res)
|
||||
parent_params = make_parent_params(res, @record)
|
||||
delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:destroy)
|
||||
should_redirect_to res.denied.redirect
|
||||
should_set_the_flash_to res.denied.flash
|
||||
|
||||
should "not destroy record" do
|
||||
assert_nothing_raised { assert @record.reload }
|
||||
end
|
||||
else
|
||||
should_set_the_flash_to res.destroy.flash
|
||||
if res.destroy.redirect.is_a? Symbol
|
||||
should_respond_with res.destroy.redirect
|
||||
else
|
||||
should_redirect_to res.destroy.redirect
|
||||
end
|
||||
|
||||
should "destroy record" do
|
||||
assert_raises(::ActiveRecord::RecordNotFound, "@#{res.object} was not destroyed.") do
|
||||
@record.reload
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_create_html_tests(res)
|
||||
context "on POST to #{controller_name_from_class}#create with #{res.create.params.inspect}" do
|
||||
setup do
|
||||
record = get_existing_record(res) rescue nil
|
||||
parent_params = make_parent_params(res, record)
|
||||
@count = res.klass.count
|
||||
post :create, parent_params.merge(res.object => res.create.params)
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:create)
|
||||
should_redirect_to res.denied.redirect
|
||||
should_set_the_flash_to res.denied.flash
|
||||
should_not_assign_to res.object
|
||||
|
||||
should "not create new record" do
|
||||
assert_equal @count, res.klass.count
|
||||
end
|
||||
else
|
||||
should_assign_to res.object
|
||||
should_set_the_flash_to res.create.flash
|
||||
if res.create.redirect.is_a? Symbol
|
||||
should_respond_with res.create.redirect
|
||||
else
|
||||
should_redirect_to res.create.redirect
|
||||
end
|
||||
|
||||
should "not have errors on @#{res.object}" do
|
||||
assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_update_html_tests(res)
|
||||
context "on PUT to #{controller_name_from_class}#update with #{res.create.params.inspect}" do
|
||||
setup do
|
||||
@record = get_existing_record(res)
|
||||
parent_params = make_parent_params(res, @record)
|
||||
put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:update)
|
||||
should_not_assign_to res.object
|
||||
should_redirect_to res.denied.redirect
|
||||
should_set_the_flash_to res.denied.flash
|
||||
else
|
||||
should_assign_to res.object
|
||||
should_set_the_flash_to(res.update.flash)
|
||||
if res.update.redirect.is_a? Symbol
|
||||
should_respond_with res.update.redirect
|
||||
else
|
||||
should_redirect_to res.update.redirect
|
||||
end
|
||||
|
||||
should "not have errors on @#{res.object}" do
|
||||
assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
168
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/formats/xml.rb
vendored
Normal file
168
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/formats/xml.rb
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module XML
|
||||
def self.included(other) #:nodoc:
|
||||
other.class_eval do
|
||||
extend Shoulda::ActionController::XML::ClassMethods
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Macro that creates a test asserting that the controller responded with an XML content-type
|
||||
# and that the XML contains +<name/>+ as the root element.
|
||||
def should_respond_with_xml_for(name = nil)
|
||||
should "have ContentType set to 'application/xml'" do
|
||||
assert_xml_response
|
||||
end
|
||||
|
||||
if name
|
||||
should "return <#{name}/> as the root element" do
|
||||
body = @response.body.first(100).map {|l| " #{l}"}
|
||||
assert_select name.to_s.dasherize, 1, "Body:\n#{body}...\nDoes not have <#{name}/> as the root element."
|
||||
end
|
||||
end
|
||||
end
|
||||
alias should_respond_with_xml should_respond_with_xml_for
|
||||
|
||||
protected
|
||||
|
||||
def make_show_xml_tests(res) # :nodoc:
|
||||
context "on GET to #{controller_name_from_class}#show as xml" do
|
||||
setup do
|
||||
request_xml
|
||||
record = get_existing_record(res)
|
||||
parent_params = make_parent_params(res, record)
|
||||
get :show, parent_params.merge({ res.identifier => record.to_param })
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:show)
|
||||
should_not_assign_to res.object
|
||||
should_respond_with 401
|
||||
else
|
||||
should_assign_to res.object
|
||||
should_respond_with :success
|
||||
should_respond_with_xml_for res.object
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_edit_xml_tests(res) # :nodoc:
|
||||
# XML doesn't need an :edit action
|
||||
end
|
||||
|
||||
def make_new_xml_tests(res) # :nodoc:
|
||||
# XML doesn't need a :new action
|
||||
end
|
||||
|
||||
def make_index_xml_tests(res) # :nodoc:
|
||||
context "on GET to #{controller_name_from_class}#index as xml" do
|
||||
setup do
|
||||
request_xml
|
||||
parent_params = make_parent_params(res)
|
||||
get(:index, parent_params)
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:index)
|
||||
should_not_assign_to res.object.to_s.pluralize
|
||||
should_respond_with 401
|
||||
else
|
||||
should_respond_with :success
|
||||
should_respond_with_xml_for res.object.to_s.pluralize
|
||||
should_assign_to res.object.to_s.pluralize
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_destroy_xml_tests(res) # :nodoc:
|
||||
context "on DELETE to #{controller_name_from_class}#destroy as xml" do
|
||||
setup do
|
||||
request_xml
|
||||
@record = get_existing_record(res)
|
||||
parent_params = make_parent_params(res, @record)
|
||||
delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:destroy)
|
||||
should_respond_with 401
|
||||
|
||||
should "not destroy record" do
|
||||
assert @record.reload
|
||||
end
|
||||
else
|
||||
should "destroy record" do
|
||||
assert_raises(::ActiveRecord::RecordNotFound, "@#{res.object} was not destroyed.") do
|
||||
@record.reload
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_create_xml_tests(res) # :nodoc:
|
||||
context "on POST to #{controller_name_from_class}#create as xml" do
|
||||
setup do
|
||||
request_xml
|
||||
parent_params = make_parent_params(res)
|
||||
@count = res.klass.count
|
||||
post :create, parent_params.merge(res.object => res.create.params)
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:create)
|
||||
should_respond_with 401
|
||||
should_not_assign_to res.object
|
||||
|
||||
should "not create new record" do
|
||||
assert_equal @count, res.klass.count
|
||||
end
|
||||
else
|
||||
should_assign_to res.object
|
||||
|
||||
should "not have errors on @#{res.object}" do
|
||||
assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_update_xml_tests(res) # :nodoc:
|
||||
context "on PUT to #{controller_name_from_class}#update as xml" do
|
||||
setup do
|
||||
request_xml
|
||||
@record = get_existing_record(res)
|
||||
parent_params = make_parent_params(res, @record)
|
||||
put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
|
||||
end
|
||||
|
||||
if res.denied.actions.include?(:update)
|
||||
should_not_assign_to res.object
|
||||
should_respond_with 401
|
||||
else
|
||||
should_assign_to res.object
|
||||
|
||||
should "not have errors on @#{res.object}" do
|
||||
assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the next request's format to 'application/xml'
|
||||
def request_xml
|
||||
@request.accept = "application/xml"
|
||||
end
|
||||
|
||||
# Asserts that the controller's response was 'application/xml'
|
||||
def assert_xml_response
|
||||
content_type = (@response.headers["Content-Type"] || @response.headers["type"]).to_s
|
||||
regex = %r{\bapplication/xml\b}
|
||||
|
||||
msg = "Content Type '#{content_type.inspect}' doesn't match '#{regex.inspect}'\n"
|
||||
msg += "Body: #{@response.body.first(100).chomp} ..."
|
||||
|
||||
assert_match regex, content_type, msg
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
64
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/helpers.rb
vendored
Normal file
64
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/helpers.rb
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module Helpers # :nodoc:
|
||||
private # :enddoc:
|
||||
|
||||
SPECIAL_INSTANCE_VARIABLES = %w{
|
||||
_cookies
|
||||
_flash
|
||||
_headers
|
||||
_params
|
||||
_request
|
||||
_response
|
||||
_session
|
||||
action_name
|
||||
before_filter_chain_aborted
|
||||
cookies
|
||||
flash
|
||||
headers
|
||||
ignore_missing_templates
|
||||
logger
|
||||
params
|
||||
request
|
||||
request_origin
|
||||
response
|
||||
session
|
||||
template
|
||||
template_class
|
||||
template_root
|
||||
url
|
||||
variables_added
|
||||
}.map(&:to_s)
|
||||
|
||||
def instantiate_variables_from_assigns(*names, &blk)
|
||||
old = {}
|
||||
names = (@response.template.assigns.keys - SPECIAL_INSTANCE_VARIABLES) if names.empty?
|
||||
names.each do |name|
|
||||
old[name] = instance_variable_get("@#{name}")
|
||||
instance_variable_set("@#{name}", assigns(name.to_sym))
|
||||
end
|
||||
blk.call
|
||||
names.each do |name|
|
||||
instance_variable_set("@#{name}", old[name])
|
||||
end
|
||||
end
|
||||
|
||||
def get_existing_record(res) # :nodoc:
|
||||
returning(instance_variable_get("@#{res.object}")) do |record|
|
||||
assert(record, "This test requires you to set @#{res.object} in your setup block")
|
||||
end
|
||||
end
|
||||
|
||||
def make_parent_params(resource, record = nil, parent_names = nil) # :nodoc:
|
||||
parent_names ||= resource.parents.reverse
|
||||
return {} if parent_names == [] # Base case
|
||||
parent_name = parent_names.shift
|
||||
parent = record ? record.send(parent_name) : parent_name.to_s.classify.constantize.find(:first)
|
||||
|
||||
{ :"#{parent_name}_id" => parent.to_param }.merge(make_parent_params(resource, parent, parent_names))
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
296
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/macros.rb
vendored
Normal file
296
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/macros.rb
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
# = Macro test helpers for your controllers
|
||||
#
|
||||
# By using the macro helpers you can quickly and easily create concise and easy to read test suites.
|
||||
#
|
||||
# This code segment:
|
||||
# context "on GET to :show for first record" do
|
||||
# setup do
|
||||
# get :show, :id => 1
|
||||
# end
|
||||
#
|
||||
# should_assign_to :user
|
||||
# should_respond_with :success
|
||||
# should_render_template :show
|
||||
# should_not_set_the_flash
|
||||
#
|
||||
# should "do something else really cool" do
|
||||
# assert_equal 1, assigns(:user).id
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Would produce 5 tests for the +show+ action
|
||||
module Macros
|
||||
include Matchers
|
||||
|
||||
def should_be_restful(&blk) # :yields: resource
|
||||
resource = ResourceOptions.new
|
||||
blk.call(resource)
|
||||
resource.normalize!(self)
|
||||
|
||||
resource.formats.each do |format|
|
||||
resource.actions.each do |action|
|
||||
if self.respond_to? :"make_#{action}_#{format}_tests"
|
||||
self.send(:"make_#{action}_#{format}_tests", resource)
|
||||
else
|
||||
should "test #{action} #{format}" do
|
||||
flunk "Test for #{action} as #{format} not implemented"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the flash contains the given value.
|
||||
# val can be a String, a Regex, or nil (indicating that the flash should not be set)
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# should_set_the_flash_to "Thank you for placing this order."
|
||||
# should_set_the_flash_to /created/i
|
||||
# should_set_the_flash_to nil
|
||||
def should_set_the_flash_to(val)
|
||||
matcher = set_the_flash.to(val)
|
||||
if val
|
||||
should matcher.description do
|
||||
assert_accepts matcher, @controller
|
||||
end
|
||||
else
|
||||
should "not #{matcher.description}" do
|
||||
assert_rejects matcher, @controller
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the flash is empty. Same as
|
||||
# @should_set_the_flash_to nil@
|
||||
def should_not_set_the_flash
|
||||
should_set_the_flash_to nil
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that filter_parameter_logging
|
||||
#
|
||||
# is set for the specified keys
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# should_filter_params :password, :ssn
|
||||
def should_filter_params(*keys)
|
||||
keys.each do |key|
|
||||
matcher = filter_param(key)
|
||||
should matcher.description do
|
||||
assert_accepts matcher, @controller
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the controller assigned to
|
||||
# each of the named instance variable(s).
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:class</tt> - The expected class of the instance variable being checked.
|
||||
# * <tt>:equals</tt> - A string which is evaluated and compared for equality with
|
||||
# the instance variable being checked.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# should_assign_to :user, :posts
|
||||
# should_assign_to :user, :class => User
|
||||
# should_assign_to(:user) { @user }
|
||||
def should_assign_to(*names, &block)
|
||||
opts = names.extract_options!
|
||||
if opts[:equals]
|
||||
warn "[DEPRECATION] should_assign_to :var, :equals => 'val' " <<
|
||||
"is deprecated. Use should_assign_to(:var) { 'val' } instead."
|
||||
end
|
||||
names.each do |name|
|
||||
matcher = assign_to(name).with_kind_of(opts[:class])
|
||||
test_name = matcher.description
|
||||
test_name << " which is equal to #{opts[:equals]}" if opts[:equals]
|
||||
should test_name do
|
||||
if opts[:equals]
|
||||
instantiate_variables_from_assigns do
|
||||
expected_value = eval(opts[:equals],
|
||||
self.send(:binding),
|
||||
__FILE__,
|
||||
__LINE__)
|
||||
matcher = matcher.with(expected_value)
|
||||
end
|
||||
elsif block
|
||||
expected_value = instance_eval(&block)
|
||||
matcher = matcher.with(expected_value)
|
||||
end
|
||||
|
||||
assert_accepts matcher, @controller
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the controller did not assign to
|
||||
# any of the named instance variable(s).
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# should_not_assign_to :user, :posts
|
||||
def should_not_assign_to(*names)
|
||||
names.each do |name|
|
||||
matcher = assign_to(name)
|
||||
should "not #{matcher.description}" do
|
||||
assert_rejects matcher, @controller
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the controller responded with a 'response' status code.
|
||||
# Example:
|
||||
#
|
||||
# should_respond_with :success
|
||||
def should_respond_with(response)
|
||||
should "respond with #{response}" do
|
||||
matcher = respond_with(response)
|
||||
assert_accepts matcher, @controller
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the response content type was 'content_type'.
|
||||
# Example:
|
||||
#
|
||||
# should_respond_with_content_type 'application/rss+xml'
|
||||
# should_respond_with_content_type :rss
|
||||
# should_respond_with_content_type /rss/
|
||||
def should_respond_with_content_type(content_type)
|
||||
should "respond with content type of #{content_type}" do
|
||||
matcher = respond_with_content_type(content_type)
|
||||
assert_accepts matcher, @controller
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that a value returned from the session is correct.
|
||||
# The given string is evaled to produce the resulting redirect path. All of the instance variables
|
||||
# set by the controller are available to the evaled string.
|
||||
# Example:
|
||||
#
|
||||
# should_set_session(:user_id) { '@user.id' }
|
||||
# should_set_session(:message) { "Free stuff" }
|
||||
def should_set_session(key, expected = nil, &block)
|
||||
matcher = set_session(key)
|
||||
if expected
|
||||
warn "[DEPRECATION] should_set_session :key, 'val' is deprecated. " <<
|
||||
"Use should_set_session(:key) { 'val' } instead."
|
||||
end
|
||||
should matcher.description do
|
||||
if expected
|
||||
instantiate_variables_from_assigns do
|
||||
expected_value = eval(expected,
|
||||
self.send(:binding),
|
||||
__FILE__,
|
||||
__LINE__)
|
||||
matcher = matcher.to(expected_value)
|
||||
end
|
||||
else
|
||||
expected_value = instance_eval(&block)
|
||||
matcher = matcher.to(expected_value)
|
||||
end
|
||||
assert_accepts matcher, @controller
|
||||
end
|
||||
end
|
||||
|
||||
# Deprecated. See should_set_session
|
||||
def should_return_from_session(key, expected)
|
||||
warn "[DEPRECATION] should_require_attributes is deprecated. " <<
|
||||
"Use should_set_session instead."
|
||||
should_set_session(key, expected)
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the controller rendered the given template.
|
||||
# Example:
|
||||
#
|
||||
# should_render_template :new
|
||||
def should_render_template(template)
|
||||
should "render template #{template.inspect}" do
|
||||
assert_template template.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the controller rendered with the given layout.
|
||||
# Example:
|
||||
#
|
||||
# should_render_with_layout 'special'
|
||||
def should_render_with_layout(expected_layout = 'application')
|
||||
matcher = render_with_layout(expected_layout)
|
||||
if expected_layout
|
||||
should matcher.description do
|
||||
assert_accepts matcher, @controller
|
||||
end
|
||||
else
|
||||
should "render without layout" do
|
||||
assert_rejects matcher, @controller
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the controller rendered without a layout.
|
||||
# Same as @should_render_with_layout false@
|
||||
def should_render_without_layout
|
||||
should_render_with_layout nil
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the controller returned a redirect to the given path.
|
||||
# The given string is evaled to produce the resulting redirect path. All of the instance variables
|
||||
# set by the controller are available to the evaled string.
|
||||
# Example:
|
||||
#
|
||||
# should_redirect_to("the user's profile") { user_url(@user) }
|
||||
def should_redirect_to(description, &block)
|
||||
unless block
|
||||
warn "[DEPRECATION] should_redirect_to without a block is " <<
|
||||
"deprecated. Use should_redirect_to('somewhere') { } instead."
|
||||
end
|
||||
should "redirect to #{description}" do
|
||||
if block
|
||||
url = instance_eval(&block)
|
||||
else
|
||||
instantiate_variables_from_assigns do
|
||||
url = eval(description, self.send(:binding), __FILE__, __LINE__)
|
||||
end
|
||||
end
|
||||
assert_redirected_to url
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a routing test. It tries to use the given HTTP
|
||||
# +method+ on the given +path+, and asserts that it routes to the
|
||||
# given +options+.
|
||||
#
|
||||
# If you don't specify a :controller, it will try to guess the controller
|
||||
# based on the current test.
|
||||
#
|
||||
# +to_param+ is called on the +options+ given.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# should_route :get, "/posts", :controller => :posts, :action => :index
|
||||
# should_route :get, "/posts/new", :action => :new
|
||||
# should_route :post, "/posts", :action => :create
|
||||
# should_route :get, "/posts/1", :action => :show, :id => 1
|
||||
# should_route :edit, "/posts/1", :action => :show, :id => 1
|
||||
# should_route :put, "/posts/1", :action => :update, :id => 1
|
||||
# should_route :delete, "/posts/1", :action => :destroy, :id => 1
|
||||
# should_route :get, "/users/1/posts/1",
|
||||
# :action => :show, :id => 1, :user_id => 1
|
||||
#
|
||||
def should_route(method, path, options)
|
||||
unless options[:controller]
|
||||
options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
|
||||
end
|
||||
|
||||
matcher = route(method, path).to(options)
|
||||
|
||||
should matcher.description do
|
||||
assert_accepts matcher.in_context(self), self
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
37
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/matchers.rb
vendored
Normal file
37
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/matchers.rb
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
require 'shoulda/action_controller/matchers/assign_to_matcher'
|
||||
require 'shoulda/action_controller/matchers/filter_param_matcher'
|
||||
require 'shoulda/action_controller/matchers/set_the_flash_matcher'
|
||||
require 'shoulda/action_controller/matchers/render_with_layout_matcher'
|
||||
require 'shoulda/action_controller/matchers/respond_with_matcher'
|
||||
require 'shoulda/action_controller/matchers/respond_with_content_type_matcher'
|
||||
require 'shoulda/action_controller/matchers/set_session_matcher'
|
||||
require 'shoulda/action_controller/matchers/route_matcher'
|
||||
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
|
||||
# By using the macro helpers 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 Matchers
|
||||
end
|
||||
end
|
||||
end
|
||||
109
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/matchers/assign_to_matcher.rb
vendored
Normal file
109
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/matchers/assign_to_matcher.rb
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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
|
||||
end
|
||||
|
||||
def with_kind_of(expected_class)
|
||||
@expected_class = expected_class
|
||||
self
|
||||
end
|
||||
|
||||
def with(expected_value)
|
||||
@expected_value = expected_value
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(controller)
|
||||
@controller = controller
|
||||
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
|
||||
|
||||
private
|
||||
|
||||
def assigned_value?
|
||||
if assigned_value.nil?
|
||||
@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 @expected_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
|
||||
assigns[@variable]
|
||||
end
|
||||
|
||||
def assigns
|
||||
@controller.response.template.assigns
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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_params? && filters_key?
|
||||
end
|
||||
|
||||
def failure_message
|
||||
"Expected #{@key} to be filtered"
|
||||
end
|
||||
|
||||
def negative_failure_message
|
||||
"Did not expect #{@key} to be filtered"
|
||||
end
|
||||
|
||||
def description
|
||||
"filter #{@key}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filters_params?
|
||||
@controller.respond_to?(:filter_parameters)
|
||||
end
|
||||
|
||||
def filters_key?
|
||||
filtered_value == '[FILTERED]'
|
||||
end
|
||||
|
||||
def filtered_value
|
||||
filtered = @controller.send(:filter_parameters,
|
||||
@key.to_s => @key.to_s)
|
||||
filtered[@key.to_s]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,81 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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(layout = nil)
|
||||
RenderWithLayout.new(layout)
|
||||
end
|
||||
|
||||
class RenderWithLayout # :nodoc:
|
||||
|
||||
def initialize(layout)
|
||||
@layout = layout.to_s unless layout.nil?
|
||||
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 @layout.nil?
|
||||
description << "a layout"
|
||||
else
|
||||
description << "the #{@layout.inspect} layout"
|
||||
end
|
||||
description
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rendered_with_layout?
|
||||
!layout.blank?
|
||||
end
|
||||
|
||||
def rendered_with_expected_layout?
|
||||
return true if @layout.nil?
|
||||
layout == @layout
|
||||
end
|
||||
|
||||
def layout
|
||||
layout = @controller.response.layout
|
||||
if layout.nil?
|
||||
nil
|
||||
else
|
||||
layout.split('/').last
|
||||
end
|
||||
end
|
||||
|
||||
def expectation
|
||||
"to #{description}"
|
||||
end
|
||||
|
||||
def result
|
||||
if rendered_with_layout?
|
||||
"rendered with the #{layout.inspect} layout"
|
||||
else
|
||||
"rendered without a layout"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,70 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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 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
|
||||
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
|
||||
@@ -0,0 +1,81 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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
|
||||
::ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE[potential_symbol]
|
||||
else
|
||||
potential_symbol
|
||||
end
|
||||
end
|
||||
|
||||
def expectation
|
||||
"response to be a #{@status}, but was #{response_code}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
93
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/matchers/route_matcher.rb
vendored
Normal file
93
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/matchers/route_matcher.rb
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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
|
||||
self
|
||||
end
|
||||
|
||||
def in_context(context)
|
||||
@context = context
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(controller)
|
||||
@controller = controller
|
||||
guess_controller!
|
||||
stringify_params!
|
||||
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.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
|
||||
@@ -0,0 +1,87 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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)
|
||||
@value = value
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(controller)
|
||||
@controller = controller
|
||||
(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
|
||||
|
||||
private
|
||||
|
||||
def assigned_value?
|
||||
!assigned_value.blank?
|
||||
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
|
||||
@controller.response.session.data
|
||||
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
|
||||
@@ -0,0 +1,85 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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_not set_the_flash }
|
||||
def set_the_flash
|
||||
SetTheFlashMatcher.new
|
||||
end
|
||||
|
||||
class SetTheFlashMatcher # :nodoc:
|
||||
|
||||
def to(value)
|
||||
@value = value
|
||||
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
|
||||
@controller.response.session['flash']
|
||||
end
|
||||
|
||||
def expectation
|
||||
expectation = "the flash 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
|
||||
233
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/resource_options.rb
vendored
Normal file
233
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_controller/resource_options.rb
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionController
|
||||
# Formats tested by #should_be_restful. Defaults to [:html, :xml]
|
||||
VALID_FORMATS = Dir.glob(File.join(File.dirname(__FILE__), 'formats', '*.rb')).map { |f| File.basename(f, '.rb') }.map(&:to_sym) # :doc:
|
||||
VALID_FORMATS.each {|f| require "shoulda/action_controller/formats/#{f}"}
|
||||
|
||||
# Actions tested by #should_be_restful
|
||||
VALID_ACTIONS = [:index, :show, :new, :edit, :create, :update, :destroy] # :doc:
|
||||
|
||||
# A ResourceOptions object is passed into should_be_restful in order to configure the tests for your controller.
|
||||
#
|
||||
# Example:
|
||||
# class UsersControllerTest < Test::Unit::TestCase
|
||||
# fixtures :all
|
||||
#
|
||||
# def setup
|
||||
# ...normal setup code...
|
||||
# @user = User.find(:first)
|
||||
# end
|
||||
#
|
||||
# should_be_restful do |resource|
|
||||
# resource.identifier = :id
|
||||
# resource.klass = User
|
||||
# resource.object = :user
|
||||
# resource.parent = []
|
||||
# resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
|
||||
# resource.formats = [:html, :xml]
|
||||
#
|
||||
# resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13}
|
||||
# resource.update.params = { :name => "sue" }
|
||||
#
|
||||
# resource.create.redirect = "user_url(@user)"
|
||||
# resource.update.redirect = "user_url(@user)"
|
||||
# resource.destroy.redirect = "users_url"
|
||||
#
|
||||
# resource.create.flash = /created/i
|
||||
# resource.update.flash = /updated/i
|
||||
# resource.destroy.flash = /removed/i
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Whenever possible, the resource attributes will be set to sensible defaults.
|
||||
#
|
||||
class ResourceOptions
|
||||
# Configuration options for the create, update, destroy actions under should_be_restful
|
||||
class ActionOptions
|
||||
# String evaled to get the target of the redirection.
|
||||
# All of the instance variables set by the controller will be available to the
|
||||
# evaled code.
|
||||
#
|
||||
# Example:
|
||||
# resource.create.redirect = "user_url(@user.company, @user)"
|
||||
#
|
||||
# Defaults to a generated url based on the name of the controller, the action, and the resource.parents list.
|
||||
attr_accessor :redirect
|
||||
|
||||
# String or Regexp describing a value expected in the flash. Will match against any flash key.
|
||||
#
|
||||
# Defaults:
|
||||
# destroy:: /removed/
|
||||
# create:: /created/
|
||||
# update:: /updated/
|
||||
attr_accessor :flash
|
||||
|
||||
# Hash describing the params that should be sent in with this action.
|
||||
attr_accessor :params
|
||||
end
|
||||
|
||||
# Configuration options for the denied actions under should_be_restful
|
||||
#
|
||||
# Example:
|
||||
# context "The public" do
|
||||
# setup do
|
||||
# @request.session[:logged_in] = false
|
||||
# end
|
||||
#
|
||||
# should_be_restful do |resource|
|
||||
# resource.parent = :user
|
||||
#
|
||||
# resource.denied.actions = [:index, :show, :edit, :new, :create, :update, :destroy]
|
||||
# resource.denied.flash = /get outta here/i
|
||||
# resource.denied.redirect = 'new_session_url'
|
||||
# end
|
||||
# end
|
||||
#
|
||||
class DeniedOptions
|
||||
# String evaled to get the target of the redirection.
|
||||
# All of the instance variables set by the controller will be available to the
|
||||
# evaled code.
|
||||
#
|
||||
# Example:
|
||||
# resource.create.redirect = "user_url(@user.company, @user)"
|
||||
attr_accessor :redirect
|
||||
|
||||
# String or Regexp describing a value expected in the flash. Will match against any flash key.
|
||||
#
|
||||
# Example:
|
||||
# resource.create.flash = /created/
|
||||
attr_accessor :flash
|
||||
|
||||
# Actions that should be denied (only used by resource.denied). <i>Note that these actions will
|
||||
# only be tested if they are also listed in +resource.actions+</i>
|
||||
# The special value of :all will deny all of the REST actions.
|
||||
attr_accessor :actions
|
||||
end
|
||||
|
||||
# Name of key in params that references the primary key.
|
||||
# Will almost always be :id (default), unless you are using a plugin or have patched rails.
|
||||
attr_accessor :identifier
|
||||
|
||||
# Name of the ActiveRecord class this resource is responsible for. Automatically determined from
|
||||
# test class if not explicitly set. UserTest => "User"
|
||||
attr_accessor :klass
|
||||
|
||||
# Name of the instantiated ActiveRecord object that should be used by some of the tests.
|
||||
# Defaults to the underscored name of the AR class. CompanyManager => :company_manager
|
||||
attr_accessor :object
|
||||
|
||||
# Name of the parent AR objects. Can be set as parent= or parents=, and can take either
|
||||
# the name of the parent resource (if there's only one), or an array of names (if there's
|
||||
# more than one).
|
||||
#
|
||||
# Example:
|
||||
# # in the routes...
|
||||
# map.resources :companies do
|
||||
# map.resources :people do
|
||||
# map.resources :limbs
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# # in the tests...
|
||||
# class PeopleControllerTest < Test::Unit::TestCase
|
||||
# should_be_restful do |resource|
|
||||
# resource.parent = :companies
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# class LimbsControllerTest < Test::Unit::TestCase
|
||||
# should_be_restful do |resource|
|
||||
# resource.parents = [:companies, :people]
|
||||
# end
|
||||
# end
|
||||
attr_accessor :parent
|
||||
alias parents parent
|
||||
alias parents= parent=
|
||||
|
||||
# Actions that should be tested. Must be a subset of VALID_ACTIONS (default).
|
||||
# Tests for each actionw will only be generated if the action is listed here.
|
||||
# The special value of :all will test all of the REST actions.
|
||||
#
|
||||
# Example (for a read-only controller):
|
||||
# resource.actions = [:show, :index]
|
||||
attr_accessor :actions
|
||||
|
||||
# Formats that should be tested. Must be a subset of VALID_FORMATS (default).
|
||||
# Each action will be tested against the formats listed here. The special value
|
||||
# of :all will test all of the supported formats.
|
||||
#
|
||||
# Example:
|
||||
# resource.actions = [:html, :xml]
|
||||
attr_accessor :formats
|
||||
|
||||
# ActionOptions object specifying options for the create action.
|
||||
attr_accessor :create
|
||||
|
||||
# ActionOptions object specifying options for the update action.
|
||||
attr_accessor :update
|
||||
|
||||
# ActionOptions object specifying options for the desrtoy action.
|
||||
attr_accessor :destroy
|
||||
|
||||
# DeniedOptions object specifying which actions should return deny a request, and what should happen in that case.
|
||||
attr_accessor :denied
|
||||
|
||||
def initialize # :nodoc:
|
||||
@create = ActionOptions.new
|
||||
@update = ActionOptions.new
|
||||
@destroy = ActionOptions.new
|
||||
@denied = DeniedOptions.new
|
||||
|
||||
@create.flash ||= /created/i
|
||||
@update.flash ||= /updated/i
|
||||
@destroy.flash ||= /removed/i
|
||||
@denied.flash ||= /denied/i
|
||||
|
||||
@create.params ||= {}
|
||||
@update.params ||= {}
|
||||
|
||||
@actions = VALID_ACTIONS
|
||||
@formats = VALID_FORMATS
|
||||
@denied.actions = []
|
||||
end
|
||||
|
||||
def normalize!(target) # :nodoc:
|
||||
@denied.actions = VALID_ACTIONS if @denied.actions == :all
|
||||
@actions = VALID_ACTIONS if @actions == :all
|
||||
@formats = VALID_FORMATS if @formats == :all
|
||||
|
||||
@denied.actions = @denied.actions.map(&:to_sym)
|
||||
@actions = @actions.map(&:to_sym)
|
||||
@formats = @formats.map(&:to_sym)
|
||||
|
||||
ensure_valid_members(@actions, VALID_ACTIONS, 'actions')
|
||||
ensure_valid_members(@denied.actions, VALID_ACTIONS, 'denied.actions')
|
||||
ensure_valid_members(@formats, VALID_FORMATS, 'formats')
|
||||
|
||||
@identifier ||= :id
|
||||
@klass ||= target.name.gsub(/ControllerTest$/, '').singularize.constantize
|
||||
@object ||= @klass.name.tableize.singularize
|
||||
@parent ||= []
|
||||
@parent = [@parent] unless @parent.is_a? Array
|
||||
|
||||
collection_helper = [@parent, @object.to_s.pluralize, 'url'].flatten.join('_')
|
||||
collection_args = @parent.map {|n| "@#{object}.#{n}"}.join(', ')
|
||||
@destroy.redirect ||= "#{collection_helper}(#{collection_args})"
|
||||
|
||||
member_helper = [@parent, @object, 'url'].flatten.join('_')
|
||||
member_args = [@parent.map {|n| "@#{object}.#{n}"}, "@#{object}"].flatten.join(', ')
|
||||
@create.redirect ||= "#{member_helper}(#{member_args})"
|
||||
@update.redirect ||= "#{member_helper}(#{member_args})"
|
||||
@denied.redirect ||= "new_session_url"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ensure_valid_members(ary, valid_members, name) # :nodoc:
|
||||
invalid = ary - valid_members
|
||||
raise ArgumentError, "Unsupported #{name}: #{invalid.inspect}" unless invalid.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
10
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_mailer.rb
vendored
Normal file
10
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_mailer.rb
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
require 'shoulda'
|
||||
require 'shoulda/action_mailer/assertions'
|
||||
|
||||
module Test # :nodoc: all
|
||||
module Unit
|
||||
class TestCase
|
||||
include Shoulda::ActionMailer::Assertions
|
||||
end
|
||||
end
|
||||
end
|
||||
38
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_mailer/assertions.rb
vendored
Normal file
38
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_mailer/assertions.rb
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionMailer # :nodoc:
|
||||
module Assertions
|
||||
# Asserts that an email was delivered. Can take a block that can further
|
||||
# narrow down the types of emails you're expecting.
|
||||
#
|
||||
# assert_sent_email
|
||||
#
|
||||
# Passes if ActionMailer::Base.deliveries has an email
|
||||
#
|
||||
# assert_sent_email do |email|
|
||||
# email.subject =~ /hi there/ && email.to.include?('none@none.com')
|
||||
# end
|
||||
#
|
||||
# Passes if there is an email with subject containing 'hi there' and
|
||||
# 'none@none.com' as one of the recipients.
|
||||
#
|
||||
def assert_sent_email
|
||||
emails = ::ActionMailer::Base.deliveries
|
||||
assert !emails.empty?, "No emails were sent"
|
||||
if block_given?
|
||||
matching_emails = emails.select {|email| yield email }
|
||||
assert !matching_emails.empty?, "None of the emails matched."
|
||||
end
|
||||
end
|
||||
|
||||
# Asserts that no ActionMailer mails were delivered
|
||||
#
|
||||
# assert_did_not_send_email
|
||||
def assert_did_not_send_email
|
||||
msg = "Sent #{::ActionMailer::Base.deliveries.size} emails.\n"
|
||||
::ActionMailer::Base.deliveries.each { |m| msg << " '#{m.subject}' sent to #{m.to.to_sentence}\n" }
|
||||
assert ::ActionMailer::Base.deliveries.empty?, msg
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
10
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_view.rb
vendored
Normal file
10
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_view.rb
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
require 'shoulda'
|
||||
require 'shoulda/action_view/macros'
|
||||
|
||||
module Test # :nodoc: all
|
||||
module Unit
|
||||
class TestCase
|
||||
extend Shoulda::ActionView::Macros
|
||||
end
|
||||
end
|
||||
end
|
||||
56
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_view/macros.rb
vendored
Normal file
56
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/action_view/macros.rb
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActionView # :nodoc:
|
||||
# = Macro test helpers for your view
|
||||
#
|
||||
# By using the macro helpers you can quickly and easily create concise and
|
||||
# easy to read test suites.
|
||||
#
|
||||
# This code segment:
|
||||
# context "on GET to :new" do
|
||||
# setup do
|
||||
# get :new
|
||||
# end
|
||||
#
|
||||
# should_render_a_form
|
||||
# should_render_page_with_metadata :title => /index/
|
||||
#
|
||||
# should "do something else really cool" do
|
||||
# assert_select '#really_cool'
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Would produce 3 tests for the +show+ action
|
||||
module Macros
|
||||
|
||||
# Macro that creates a test asserting that the rendered view contains a <form> element.
|
||||
def should_render_a_form
|
||||
should "display a form" do
|
||||
assert_select "form", true, "The template doesn't contain a <form> element"
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting that the rendered view contains the selected metatags.
|
||||
# Values can be string or Regexps.
|
||||
# Example:
|
||||
#
|
||||
# should_render_page_with_metadata :description => "Description of this page", :keywords => /post/
|
||||
#
|
||||
# You can also use this method to test the rendered views title.
|
||||
#
|
||||
# Example:
|
||||
# should_render_page_with_metadata :title => /index/
|
||||
def should_render_page_with_metadata(options)
|
||||
options.each do |key, value|
|
||||
should "have metatag #{key}" do
|
||||
if key.to_sym == :title
|
||||
assert_select "title", value
|
||||
else
|
||||
assert_select "meta[name=?][content#{"*" if value.is_a?(Regexp)}=?]", key, value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
16
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record.rb
vendored
Normal file
16
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record.rb
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
require 'shoulda'
|
||||
require 'shoulda/active_record/helpers'
|
||||
require 'shoulda/active_record/matchers'
|
||||
require 'shoulda/active_record/assertions'
|
||||
require 'shoulda/active_record/macros'
|
||||
|
||||
module Test # :nodoc: all
|
||||
module Unit
|
||||
class TestCase
|
||||
include Shoulda::ActiveRecord::Helpers
|
||||
include Shoulda::ActiveRecord::Matchers
|
||||
include Shoulda::ActiveRecord::Assertions
|
||||
extend Shoulda::ActiveRecord::Macros
|
||||
end
|
||||
end
|
||||
end
|
||||
69
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/assertions.rb
vendored
Normal file
69
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/assertions.rb
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Assertions
|
||||
# Asserts that the given object can be saved
|
||||
#
|
||||
# assert_save User.new(params)
|
||||
def assert_save(obj)
|
||||
assert obj.save, "Errors: #{pretty_error_messages obj}"
|
||||
obj.reload
|
||||
end
|
||||
|
||||
# Asserts that the given object is valid
|
||||
#
|
||||
# assert_valid User.new(params)
|
||||
def assert_valid(obj)
|
||||
assert obj.valid?, "Errors: #{pretty_error_messages obj}"
|
||||
end
|
||||
|
||||
# Asserts that an Active Record model validates with the passed
|
||||
# <tt>value</tt> by making sure the <tt>error_message_to_avoid</tt> is not
|
||||
# contained within the list of errors for that attribute.
|
||||
#
|
||||
# assert_good_value(User.new, :email, "user@example.com")
|
||||
# assert_good_value(User.new, :ssn, "123456789", /length/)
|
||||
#
|
||||
# If a class is passed as the first argument, a new object will be
|
||||
# instantiated before the assertion. If an instance variable exists with
|
||||
# the same name as the class (underscored), that object will be used
|
||||
# instead.
|
||||
#
|
||||
# assert_good_value(User, :email, "user@example.com")
|
||||
#
|
||||
# @product = Product.new(:tangible => false)
|
||||
# assert_good_value(Product, :price, "0")
|
||||
def assert_good_value(object_or_klass, attribute, value, error_message_to_avoid = nil)
|
||||
object = get_instance_of(object_or_klass)
|
||||
matcher = allow_value(value).
|
||||
for(attribute).
|
||||
with_message(error_message_to_avoid)
|
||||
assert_accepts(matcher, object)
|
||||
end
|
||||
|
||||
# Asserts that an Active Record model invalidates the passed
|
||||
# <tt>value</tt> by making sure the <tt>error_message_to_expect</tt> is
|
||||
# contained within the list of errors for that attribute.
|
||||
#
|
||||
# assert_bad_value(User.new, :email, "invalid")
|
||||
# assert_bad_value(User.new, :ssn, "123", /length/)
|
||||
#
|
||||
# If a class is passed as the first argument, a new object will be
|
||||
# instantiated before the assertion. If an instance variable exists with
|
||||
# the same name as the class (underscored), that object will be used
|
||||
# instead.
|
||||
#
|
||||
# assert_bad_value(User, :email, "invalid")
|
||||
#
|
||||
# @product = Product.new(:tangible => true)
|
||||
# assert_bad_value(Product, :price, "0")
|
||||
def assert_bad_value(object_or_klass, attribute, value,
|
||||
error_message_to_expect = nil)
|
||||
object = get_instance_of(object_or_klass)
|
||||
matcher = allow_value(value).
|
||||
for(attribute).
|
||||
with_message(error_message_to_expect)
|
||||
assert_rejects(matcher, object)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
40
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/helpers.rb
vendored
Normal file
40
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/helpers.rb
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Helpers
|
||||
def pretty_error_messages(obj) # :nodoc:
|
||||
obj.errors.map do |a, m|
|
||||
msg = "#{a} #{m}"
|
||||
msg << " (#{obj.send(a).inspect})" unless a.to_sym == :base
|
||||
end
|
||||
end
|
||||
|
||||
def get_instance_of(object_or_klass)
|
||||
if object_or_klass.is_a?(Class)
|
||||
klass = object_or_klass
|
||||
instance_variable_get("@#{instance_variable_name_for(klass)}") || klass.new
|
||||
else
|
||||
object_or_klass
|
||||
end
|
||||
end
|
||||
|
||||
def instance_variable_name_for(klass)
|
||||
klass.to_s.split('::').last.underscore
|
||||
end
|
||||
|
||||
# Helper method that determines the default error message used by Active
|
||||
# Record. Works for both existing Rails 2.1 and Rails 2.2 with the newly
|
||||
# introduced I18n module used for localization.
|
||||
#
|
||||
# default_error_message(:blank)
|
||||
# default_error_message(:too_short, :count => 5)
|
||||
# default_error_message(:too_long, :count => 60)
|
||||
def default_error_message(key, values = {})
|
||||
if Object.const_defined?(:I18n) # Rails >= 2.2
|
||||
I18n.translate("activerecord.errors.messages.#{key}", values)
|
||||
else # Rails <= 2.1.x
|
||||
::ActiveRecord::Errors.default_error_messages[key] % values[:count]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
589
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/macros.rb
vendored
Normal file
589
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/macros.rb
vendored
Normal file
@@ -0,0 +1,589 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
# = Macro test helpers for your active record models
|
||||
#
|
||||
# These helpers will test most of the validations and associations for your ActiveRecord models.
|
||||
#
|
||||
# class UserTest < Test::Unit::TestCase
|
||||
# should_validate_presence_of :name, :phone_number
|
||||
# should_not_allow_values_for :phone_number, "abcd", "1234"
|
||||
# should_allow_values_for :phone_number, "(123) 456-7890"
|
||||
#
|
||||
# should_not_allow_mass_assignment_of :password
|
||||
#
|
||||
# should_have_one :profile
|
||||
# should_have_many :dogs
|
||||
# should_have_many :messes, :through => :dogs
|
||||
# should_belong_to :lover
|
||||
# end
|
||||
#
|
||||
# For all of these helpers, the last parameter may be a hash of options.
|
||||
#
|
||||
module Macros
|
||||
include Helpers
|
||||
include Matchers
|
||||
|
||||
# Ensures that the model cannot be saved if one of the attributes listed is not present.
|
||||
#
|
||||
# If an instance variable has been created in the setup named after the
|
||||
# model being tested, then this method will use that. Otherwise, it will
|
||||
# create a new instance to test against.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.blank')</tt>
|
||||
#
|
||||
# Example:
|
||||
# should_validate_presence_of :name, :phone_number
|
||||
#
|
||||
def should_validate_presence_of(*attributes)
|
||||
message = get_options!(attributes, :message)
|
||||
klass = model_class
|
||||
|
||||
attributes.each do |attribute|
|
||||
matcher = validate_presence_of(attribute).with_message(message)
|
||||
should matcher.description do
|
||||
assert_accepts(matcher, get_instance_of(klass))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Deprecated. See should_validate_presence_of
|
||||
def should_require_attributes(*attributes)
|
||||
warn "[DEPRECATION] should_require_attributes is deprecated. " <<
|
||||
"Use should_validate_presence_of instead."
|
||||
should_validate_presence_of(*attributes)
|
||||
end
|
||||
|
||||
# Ensures that the model cannot be saved if one of the attributes listed is not unique.
|
||||
# Requires an existing record
|
||||
#
|
||||
# Options:
|
||||
|
||||
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.taken')</tt>
|
||||
# * <tt>:scoped_to</tt> - field(s) to scope the uniqueness to.
|
||||
# * <tt>:case_sensitive</tt> - whether or not uniqueness is defined by an
|
||||
# exact match. Ignored by non-text attributes. Default = <tt>true</tt>
|
||||
#
|
||||
# Examples:
|
||||
# should_validate_uniqueness_of :keyword, :username
|
||||
# should_validate_uniqueness_of :name, :message => "O NOES! SOMEONE STOELED YER NAME!"
|
||||
# should_validate_uniqueness_of :email, :scoped_to => :name
|
||||
# should_validate_uniqueness_of :address, :scoped_to => [:first_name, :last_name]
|
||||
# should_validate_uniqueness_of :email, :case_sensitive => false
|
||||
#
|
||||
def should_validate_uniqueness_of(*attributes)
|
||||
message, scope, case_sensitive = get_options!(attributes, :message, :scoped_to, :case_sensitive)
|
||||
scope = [*scope].compact
|
||||
case_sensitive = true if case_sensitive.nil?
|
||||
|
||||
klass = model_class
|
||||
|
||||
attributes.each do |attribute|
|
||||
matcher = validate_uniqueness_of(attribute).
|
||||
with_message(message).scoped_to(scope)
|
||||
matcher = matcher.case_insensitive unless case_sensitive
|
||||
should matcher.description do
|
||||
assert_accepts(matcher, get_instance_of(klass))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Deprecated. See should_validate_uniqueness_of
|
||||
def should_require_unique_attributes(*attributes)
|
||||
warn "[DEPRECATION] should_require_unique_attributes is deprecated. " <<
|
||||
"Use should_validate_uniqueness_of instead."
|
||||
should_validate_uniqueness_of(*attributes)
|
||||
end
|
||||
|
||||
# Ensures that the attribute can be set on mass update.
|
||||
#
|
||||
# should_allow_mass_assignment_of :first_name, :last_name
|
||||
#
|
||||
def should_allow_mass_assignment_of(*attributes)
|
||||
get_options!(attributes)
|
||||
klass = model_class
|
||||
|
||||
attributes.each do |attribute|
|
||||
matcher = allow_mass_assignment_of(attribute)
|
||||
should matcher.description do
|
||||
assert_accepts matcher, klass.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensures that the attribute cannot be set on mass update.
|
||||
#
|
||||
# should_not_allow_mass_assignment_of :password, :admin_flag
|
||||
#
|
||||
def should_not_allow_mass_assignment_of(*attributes)
|
||||
get_options!(attributes)
|
||||
klass = model_class
|
||||
|
||||
attributes.each do |attribute|
|
||||
matcher = allow_mass_assignment_of(attribute)
|
||||
should "not #{matcher.description}" do
|
||||
assert_rejects matcher, klass.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Deprecated. See should_not_allow_mass_assignment_of
|
||||
def should_protect_attributes(*attributes)
|
||||
warn "[DEPRECATION] should_protect_attributes is deprecated. " <<
|
||||
"Use should_not_allow_mass_assignment_of instead."
|
||||
should_not_allow_mass_assignment_of(*attributes)
|
||||
end
|
||||
|
||||
# Ensures that the attribute cannot be changed once the record has been created.
|
||||
#
|
||||
# should_have_readonly_attributes :password, :admin_flag
|
||||
#
|
||||
def should_have_readonly_attributes(*attributes)
|
||||
get_options!(attributes)
|
||||
klass = model_class
|
||||
|
||||
attributes.each do |attribute|
|
||||
matcher = have_readonly_attribute(attribute)
|
||||
should matcher.description do
|
||||
assert_accepts matcher, klass.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensures that the attribute cannot be set to the given values
|
||||
#
|
||||
# If an instance variable has been created in the setup named after the
|
||||
# model being tested, then this method will use that. Otherwise, it will
|
||||
# create a new instance to test against.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.invalid')</tt>
|
||||
#
|
||||
# Example:
|
||||
# should_not_allow_values_for :isbn, "bad 1", "bad 2"
|
||||
#
|
||||
def should_not_allow_values_for(attribute, *bad_values)
|
||||
message = get_options!(bad_values, :message)
|
||||
klass = model_class
|
||||
bad_values.each do |value|
|
||||
matcher = allow_value(value).for(attribute).with_message(message)
|
||||
should "not #{matcher.description}" do
|
||||
assert_rejects matcher, get_instance_of(klass)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensures that the attribute can be set to the given values.
|
||||
#
|
||||
# If an instance variable has been created in the setup named after the
|
||||
# model being tested, then this method will use that. Otherwise, it will
|
||||
# create a new instance to test against.
|
||||
#
|
||||
# Example:
|
||||
# should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0"
|
||||
#
|
||||
def should_allow_values_for(attribute, *good_values)
|
||||
get_options!(good_values)
|
||||
klass = model_class
|
||||
klass = model_class
|
||||
good_values.each do |value|
|
||||
matcher = allow_value(value).for(attribute)
|
||||
should matcher.description do
|
||||
assert_accepts matcher, get_instance_of(klass)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensures that the length of the attribute is in the given range
|
||||
#
|
||||
# If an instance variable has been created in the setup named after the
|
||||
# model being tested, then this method will use that. Otherwise, it will
|
||||
# create a new instance to test against.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.too_short') % range.first</tt>
|
||||
# * <tt>:long_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.too_long') % range.last</tt>
|
||||
#
|
||||
# Example:
|
||||
# should_ensure_length_in_range :password, (6..20)
|
||||
#
|
||||
def should_ensure_length_in_range(attribute, range, opts = {})
|
||||
short_message, long_message = get_options!([opts],
|
||||
:short_message,
|
||||
:long_message)
|
||||
klass = model_class
|
||||
|
||||
matcher = ensure_length_of(attribute).
|
||||
is_at_least(range.first).
|
||||
with_short_message(short_message).
|
||||
is_at_most(range.last).
|
||||
with_long_message(long_message)
|
||||
|
||||
should matcher.description do
|
||||
assert_accepts matcher, get_instance_of(klass)
|
||||
end
|
||||
end
|
||||
|
||||
# Ensures that the length of the attribute is at least a certain length
|
||||
#
|
||||
# If an instance variable has been created in the setup named after the
|
||||
# model being tested, then this method will use that. Otherwise, it will
|
||||
# create a new instance to test against.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.too_short') % min_length</tt>
|
||||
#
|
||||
# Example:
|
||||
# should_ensure_length_at_least :name, 3
|
||||
#
|
||||
def should_ensure_length_at_least(attribute, min_length, opts = {})
|
||||
short_message = get_options!([opts], :short_message)
|
||||
klass = model_class
|
||||
|
||||
matcher = ensure_length_of(attribute).
|
||||
is_at_least(min_length).
|
||||
with_short_message(short_message)
|
||||
|
||||
should matcher.description do
|
||||
assert_accepts matcher, get_instance_of(klass)
|
||||
end
|
||||
end
|
||||
|
||||
# Ensures that the length of the attribute is exactly a certain length
|
||||
#
|
||||
# If an instance variable has been created in the setup named after the
|
||||
# model being tested, then this method will use that. Otherwise, it will
|
||||
# create a new instance to test against.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.wrong_length') % length</tt>
|
||||
#
|
||||
# Example:
|
||||
# should_ensure_length_is :ssn, 9
|
||||
#
|
||||
def should_ensure_length_is(attribute, length, opts = {})
|
||||
message = get_options!([opts], :message)
|
||||
klass = model_class
|
||||
matcher = ensure_length_of(attribute).
|
||||
is_equal_to(length).
|
||||
with_message(message)
|
||||
|
||||
should matcher.description do
|
||||
assert_accepts matcher, get_instance_of(klass)
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure that the attribute is in the range specified
|
||||
#
|
||||
# If an instance variable has been created in the setup named after the
|
||||
# model being tested, then this method will use that. Otherwise, it will
|
||||
# create a new instance to test against.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:low_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.inclusion')</tt>
|
||||
# * <tt>:high_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.inclusion')</tt>
|
||||
#
|
||||
# Example:
|
||||
# should_ensure_value_in_range :age, (0..100)
|
||||
#
|
||||
def should_ensure_value_in_range(attribute, range, opts = {})
|
||||
message, low_message, high_message = get_options!([opts],
|
||||
:message,
|
||||
:low_message,
|
||||
:high_message)
|
||||
klass = model_class
|
||||
matcher = ensure_inclusion_of(attribute).
|
||||
in_range(range).
|
||||
with_message(message).
|
||||
with_low_message(low_message).
|
||||
with_high_message(high_message)
|
||||
should matcher.description do
|
||||
assert_accepts matcher, get_instance_of(klass)
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure that the attribute is numeric
|
||||
#
|
||||
# If an instance variable has been created in the setup named after the
|
||||
# model being tested, then this method will use that. Otherwise, it will
|
||||
# create a new instance to test against.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.not_a_number')</tt>
|
||||
#
|
||||
# Example:
|
||||
# should_validate_numericality_of :age
|
||||
#
|
||||
def should_validate_numericality_of(*attributes)
|
||||
message = get_options!(attributes, :message)
|
||||
klass = model_class
|
||||
attributes.each do |attribute|
|
||||
matcher = validate_numericality_of(attribute).
|
||||
with_message(message)
|
||||
should matcher.description do
|
||||
assert_accepts matcher, get_instance_of(klass)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Deprecated. See should_validate_numericality_of
|
||||
def should_only_allow_numeric_values_for(*attributes)
|
||||
warn "[DEPRECATION] should_only_allow_numeric_values_for is " <<
|
||||
"deprecated. Use should_validate_numericality_of instead."
|
||||
should_validate_numericality_of(*attributes)
|
||||
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:
|
||||
# should_have_many :friends
|
||||
# should_have_many :enemies, :through => :friends
|
||||
# should_have_many :enemies, :dependent => :destroy
|
||||
#
|
||||
def should_have_many(*associations)
|
||||
through, dependent = get_options!(associations, :through, :dependent)
|
||||
klass = model_class
|
||||
associations.each do |association|
|
||||
matcher = have_many(association).through(through).dependent(dependent)
|
||||
should matcher.description do
|
||||
assert_accepts(matcher, klass.new)
|
||||
end
|
||||
end
|
||||
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:
|
||||
# should_have_one :god # unless hindu
|
||||
#
|
||||
def should_have_one(*associations)
|
||||
dependent = get_options!(associations, :dependent)
|
||||
klass = model_class
|
||||
associations.each do |association|
|
||||
matcher = have_one(association).dependent(dependent)
|
||||
should matcher.description do
|
||||
assert_accepts(matcher, klass.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensures that the has_and_belongs_to_many relationship exists, and that the join
|
||||
# table is in place.
|
||||
#
|
||||
# should_have_and_belong_to_many :posts, :cars
|
||||
#
|
||||
def should_have_and_belong_to_many(*associations)
|
||||
get_options!(associations)
|
||||
klass = model_class
|
||||
|
||||
associations.each do |association|
|
||||
matcher = have_and_belong_to_many(association)
|
||||
should matcher.description do
|
||||
assert_accepts(matcher, klass.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure that the belongs_to relationship exists.
|
||||
#
|
||||
# should_belong_to :parent
|
||||
#
|
||||
def should_belong_to(*associations)
|
||||
dependent = get_options!(associations, :dependent)
|
||||
klass = model_class
|
||||
associations.each do |association|
|
||||
matcher = belong_to(association).dependent(dependent)
|
||||
should matcher.description do
|
||||
assert_accepts(matcher, klass.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure that the given class methods are defined on the model.
|
||||
#
|
||||
# should_have_class_methods :find, :destroy
|
||||
#
|
||||
def should_have_class_methods(*methods)
|
||||
get_options!(methods)
|
||||
klass = model_class
|
||||
methods.each do |method|
|
||||
should "respond to class method ##{method}" do
|
||||
assert_respond_to klass, method, "#{klass.name} does not have class method #{method}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure that the given instance methods are defined on the model.
|
||||
#
|
||||
# should_have_instance_methods :email, :name, :name=
|
||||
#
|
||||
def should_have_instance_methods(*methods)
|
||||
get_options!(methods)
|
||||
klass = model_class
|
||||
methods.each do |method|
|
||||
should "respond to instance method ##{method}" do
|
||||
assert_respond_to klass.new, method, "#{klass.name} does not have instance method #{method}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure that the given columns are defined on the models backing SQL table.
|
||||
# Also aliased to should_have_index for readability.
|
||||
# Takes the same options available in migrations:
|
||||
# :type, :precision, :limit, :default, :null, and :scale
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# should_have_db_columns :id, :email, :name, :created_at
|
||||
#
|
||||
# should_have_db_column :email, :type => "string", :limit => 255
|
||||
# should_have_db_column :salary, :decimal, :precision => 15, :scale => 2
|
||||
# should_have_db_column :admin, :default => false, :null => false
|
||||
#
|
||||
def should_have_db_columns(*columns)
|
||||
column_type, precision, limit, default, null, scale, sql_type =
|
||||
get_options!(columns, :type, :precision, :limit,
|
||||
:default, :null, :scale, :sql_type)
|
||||
klass = model_class
|
||||
columns.each do |name|
|
||||
matcher = have_db_column(name).
|
||||
of_type(column_type).
|
||||
with_options(:precision => precision, :limit => limit,
|
||||
:default => default, :null => null,
|
||||
:scale => scale, :sql_type => sql_type)
|
||||
should matcher.description do
|
||||
assert_accepts(matcher, klass.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :should_have_db_column, :should_have_db_columns
|
||||
|
||||
# Ensures that there are DB indices on the given columns or tuples of columns.
|
||||
# Also aliased to should_have_index for readability
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:unique</tt> - whether or not the index has a unique
|
||||
# constraint. Use <tt>true</tt> to explicitly test for a unique
|
||||
# constraint. Use <tt>false</tt> to explicitly test for a non-unique
|
||||
# constraint. Use <tt>nil</tt> if you don't care whether the index is
|
||||
# unique or not. Default = <tt>nil</tt>
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# should_have_indices :email, :name, [:commentable_type, :commentable_id]
|
||||
# should_have_index :age
|
||||
# should_have_index :ssn, :unique => true
|
||||
#
|
||||
def should_have_indices(*columns)
|
||||
unique = get_options!(columns, :unique)
|
||||
klass = model_class
|
||||
|
||||
columns.each do |column|
|
||||
matcher = have_index(column).unique(unique)
|
||||
should matcher.description do
|
||||
assert_accepts(matcher, klass.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
alias_method :should_have_index, :should_have_indices
|
||||
|
||||
# Ensures that the model cannot be saved if one of the attributes listed is not accepted.
|
||||
#
|
||||
# If an instance variable has been created in the setup named after the
|
||||
# model being tested, then this method will use that. Otherwise, it will
|
||||
# create a new instance to test against.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
||||
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.accepted')</tt>
|
||||
#
|
||||
# Example:
|
||||
# should_validate_acceptance_of :eula
|
||||
#
|
||||
def should_validate_acceptance_of(*attributes)
|
||||
message = get_options!(attributes, :message)
|
||||
klass = model_class
|
||||
|
||||
attributes.each do |attribute|
|
||||
matcher = validate_acceptance_of(attribute).with_message(message)
|
||||
should matcher.description do
|
||||
assert_accepts matcher, get_instance_of(klass)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Deprecated. See should_validate_uniqueness_of
|
||||
def should_require_acceptance_of(*attributes)
|
||||
warn "[DEPRECATION] should_require_acceptance_of is deprecated. " <<
|
||||
"Use should_validate_acceptance_of instead."
|
||||
should_validate_acceptance_of(*attributes)
|
||||
end
|
||||
|
||||
# Ensures that the model has a method named scope_name that returns a NamedScope object with the
|
||||
# proxy options set to the options you supply. scope_name can be either a symbol, or a method
|
||||
# call which will be evaled against the model. The eval'd method call has access to all the same
|
||||
# instance variables that a should statement would.
|
||||
#
|
||||
# Options: Any of the options that the named scope would pass on to find.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# should_have_named_scope :visible, :conditions => {:visible => true}
|
||||
#
|
||||
# Passes for
|
||||
#
|
||||
# named_scope :visible, :conditions => {:visible => true}
|
||||
#
|
||||
# Or for
|
||||
#
|
||||
# def self.visible
|
||||
# scoped(:conditions => {:visible => true})
|
||||
# end
|
||||
#
|
||||
# You can test lambdas or methods that return ActiveRecord#scoped calls:
|
||||
#
|
||||
# should_have_named_scope 'recent(5)', :limit => 5
|
||||
# should_have_named_scope 'recent(1)', :limit => 1
|
||||
#
|
||||
# Passes for
|
||||
# named_scope :recent, lambda {|c| {:limit => c}}
|
||||
#
|
||||
# Or for
|
||||
#
|
||||
# def self.recent(c)
|
||||
# scoped(:limit => c)
|
||||
# end
|
||||
#
|
||||
def should_have_named_scope(scope_call, find_options = nil)
|
||||
klass = model_class
|
||||
matcher = have_named_scope(scope_call).finding(find_options)
|
||||
should matcher.description do
|
||||
assert_accepts matcher.in_context(self), klass.new
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
42
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers.rb
vendored
Normal file
42
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers.rb
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
require 'shoulda/active_record/helpers'
|
||||
require 'shoulda/active_record/matchers/validation_matcher'
|
||||
require 'shoulda/active_record/matchers/allow_value_matcher'
|
||||
require 'shoulda/active_record/matchers/ensure_length_of_matcher'
|
||||
require 'shoulda/active_record/matchers/ensure_inclusion_of_matcher'
|
||||
require 'shoulda/active_record/matchers/validate_presence_of_matcher'
|
||||
require 'shoulda/active_record/matchers/validate_uniqueness_of_matcher'
|
||||
require 'shoulda/active_record/matchers/validate_acceptance_of_matcher'
|
||||
require 'shoulda/active_record/matchers/validate_numericality_of_matcher'
|
||||
require 'shoulda/active_record/matchers/association_matcher'
|
||||
require 'shoulda/active_record/matchers/have_db_column_matcher'
|
||||
require 'shoulda/active_record/matchers/have_index_matcher'
|
||||
require 'shoulda/active_record/matchers/have_readonly_attribute_matcher'
|
||||
require 'shoulda/active_record/matchers/allow_mass_assignment_of_matcher'
|
||||
require 'shoulda/active_record/matchers/have_named_scope_matcher'
|
||||
|
||||
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
# = 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 Matchers
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,83 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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?
|
||||
@failure_message = "#{@attribute} was made accessible"
|
||||
else
|
||||
if protected_attributes.empty?
|
||||
@failure_message = "no attributes were protected"
|
||||
else
|
||||
@failure_message = "#{class_name} is protecting " <<
|
||||
"#{protected_attributes.to_a.to_sentence}, " <<
|
||||
"but not #{@attribute}."
|
||||
end
|
||||
end
|
||||
true
|
||||
else
|
||||
if whitelisting?
|
||||
@negative_failure_message =
|
||||
"Expected #{@attribute} to be accessible"
|
||||
else
|
||||
@negative_failure_message =
|
||||
"Did not expect #{@attribute} to be protected"
|
||||
end
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :failure_message, :negative_failure_message
|
||||
|
||||
def description
|
||||
"protect #{@attribute} from mass updates"
|
||||
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
|
||||
102
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/allow_value_matcher.rb
vendored
Normal file
102
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/allow_value_matcher.rb
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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. Defaults to the
|
||||
# translation for :invalid.
|
||||
#
|
||||
# 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
|
||||
@expected_message ||= :invalid
|
||||
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 = @instance.errors.on(@attribute)
|
||||
@errors = [@errors] unless @errors.is_a?(Array)
|
||||
errors_match_regexp? || errors_match_string?
|
||||
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 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
|
||||
226
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/association_matcher.rb
vendored
Normal file
226
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/association_matcher.rb
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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?
|
||||
"#{model_class.name} does not have any relationship to #{@through}"
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def through_association_correct?
|
||||
if @through == reflection.options[:through]
|
||||
"Expected #{model_class.name} to have #{@name} through #{@through}, " <<
|
||||
" but got it through #{reflection.options[:through]}"
|
||||
true
|
||||
else
|
||||
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
|
||||
@@ -0,0 +1,87 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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
|
||||
141
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb
vendored
Normal file
141
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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
|
||||
169
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/have_db_column_matcher.rb
vendored
Normal file
169
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/have_db_column_matcher.rb
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# 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
|
||||
|
||||
def model_class
|
||||
@subject.class
|
||||
end
|
||||
|
||||
def expectation
|
||||
expected = "#{model_class.name} to #{description}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
105
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/have_index_matcher.rb
vendored
Normal file
105
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/have_index_matcher.rb
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# Ensures that there are DB indices on the given columns or tuples of
|
||||
# columns.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>unique</tt> - whether or not the index has a unique
|
||||
# constraint. Use <tt>true</tt> to explicitly test for a unique
|
||||
# constraint. Use <tt>false</tt> to explicitly test for a non-unique
|
||||
# constraint. Use <tt>nil</tt> if you don't care whether the index is
|
||||
# unique or not. Default = <tt>nil</tt>
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# it { should have_index(:age) }
|
||||
# it { should have_index([:commentable_type, :commentable_id]) }
|
||||
# it { should have_index(:ssn).unique(true) }
|
||||
#
|
||||
def have_index(columns)
|
||||
HaveIndexMatcher.new(:have_index, columns)
|
||||
end
|
||||
|
||||
class HaveIndexMatcher # :nodoc:
|
||||
def initialize(macro, columns)
|
||||
@macro = macro
|
||||
@columns = normalize_columns_to_array(columns)
|
||||
end
|
||||
|
||||
def unique(unique)
|
||||
@unique = unique
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@subject = subject
|
||||
index_exists? && correct_unique?
|
||||
end
|
||||
|
||||
def failure_message
|
||||
"Expected #{expectation} (#{@missing})"
|
||||
end
|
||||
|
||||
def negative_failure_message
|
||||
"Did not expect #{expectation}"
|
||||
end
|
||||
|
||||
def description
|
||||
"have a #{index_type} index on columns #{@columns}"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def index_exists?
|
||||
! matched_index.nil?
|
||||
end
|
||||
|
||||
def correct_unique?
|
||||
return true if @unique.nil?
|
||||
if matched_index.unique == @unique
|
||||
true
|
||||
else
|
||||
@missing = "#{table_name} has an index named #{matched_index.name} " <<
|
||||
"of unique #{matched_index.unique}, not #{@unique}."
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def matched_index
|
||||
indexes.detect { |each| each.columns == @columns }
|
||||
end
|
||||
|
||||
def model_class
|
||||
@subject.class
|
||||
end
|
||||
|
||||
def table_name
|
||||
model_class.table_name
|
||||
end
|
||||
|
||||
def indexes
|
||||
::ActiveRecord::Base.connection.indexes(table_name)
|
||||
end
|
||||
|
||||
def expectation
|
||||
expected = "#{model_class.name} to #{description}"
|
||||
end
|
||||
|
||||
def index_type
|
||||
@unique ? "unique" : "non-unique"
|
||||
end
|
||||
|
||||
def normalize_columns_to_array(columns)
|
||||
if columns.class == Array
|
||||
columns.collect { |each| each.to_s }
|
||||
else
|
||||
[columns.to_s]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
125
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb
vendored
Normal file
125
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# Ensures that the model has a method named scope_call that returns a
|
||||
# NamedScope object with the proxy options set to the options you supply.
|
||||
# scope_call can be either a symbol, or a Ruby expression in a String
|
||||
# which will be evaled. The eval'd method call has access to all the same
|
||||
# instance variables that an example would.
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
# * <tt>in_context</tt> - Any of the options that the named scope would
|
||||
# pass on to find.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# it { should have_named_scope(:visible).
|
||||
# finding(:conditions => {:visible => true}) }
|
||||
#
|
||||
# Passes for
|
||||
#
|
||||
# named_scope :visible, :conditions => {:visible => true}
|
||||
#
|
||||
# Or for
|
||||
#
|
||||
# def self.visible
|
||||
# scoped(:conditions => {:visible => true})
|
||||
# end
|
||||
#
|
||||
# You can test lambdas or methods that return ActiveRecord#scoped calls:
|
||||
#
|
||||
# it { should have_named_scope('recent(5)').finding(:limit => 5) }
|
||||
# it { should have_named_scope('recent(1)').finding(:limit => 1) }
|
||||
#
|
||||
# Passes for
|
||||
# named_scope :recent, lambda {|c| {:limit => c}}
|
||||
#
|
||||
# Or for
|
||||
#
|
||||
# def self.recent(c)
|
||||
# scoped(:limit => c)
|
||||
# end
|
||||
#
|
||||
def have_named_scope(scope_call)
|
||||
HaveNamedScopeMatcher.new(scope_call).in_context(self)
|
||||
end
|
||||
|
||||
class HaveNamedScopeMatcher # :nodoc:
|
||||
|
||||
def initialize(scope_call)
|
||||
@scope_call = scope_call.to_s
|
||||
end
|
||||
|
||||
def finding(finding)
|
||||
@finding = finding
|
||||
self
|
||||
end
|
||||
|
||||
def in_context(context)
|
||||
@context = context
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@subject = subject
|
||||
call_succeeds? && returns_scope? && finds_correct_scope?
|
||||
end
|
||||
|
||||
def failure_message
|
||||
"Expected #{@missing_expectation}"
|
||||
end
|
||||
|
||||
def negative_failure_message
|
||||
"Didn't expect a named scope for #{@scope_call}"
|
||||
end
|
||||
|
||||
def description
|
||||
result = "have a named scope for #{@scope_call}"
|
||||
result << " finding #{@finding.inspect}" unless @finding.nil?
|
||||
result
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def call_succeeds?
|
||||
scope
|
||||
true
|
||||
rescue Exception => exception
|
||||
@missing_expectation = "#{@subject.class.name} " <<
|
||||
"to respond to #{@scope_call} " <<
|
||||
"but raised error: #{exception.inspect}"
|
||||
false
|
||||
end
|
||||
|
||||
def scope
|
||||
@scope ||= @context.instance_eval("#{@subject.class.name}.#{@scope_call}")
|
||||
end
|
||||
|
||||
def returns_scope?
|
||||
if ::ActiveRecord::NamedScope::Scope === scope
|
||||
true
|
||||
else
|
||||
@missing_expectation = "#{@scope_call} to return a scope"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def finds_correct_scope?
|
||||
return true if @finding.nil?
|
||||
if @finding == scope.proxy_options
|
||||
true
|
||||
else
|
||||
@missing_expectation = "#{@scope_call} to return results scoped to "
|
||||
@missing_expectation << "#{@finding.inspect} but was scoped to "
|
||||
@missing_expectation << scope.proxy_options.inspect
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# Ensures that the attribute cannot be changed once the record has been
|
||||
# created.
|
||||
#
|
||||
# it { should have_readonly_attributes(:password) }
|
||||
#
|
||||
def have_readonly_attribute(value)
|
||||
HaveReadonlyAttributeMatcher.new(value)
|
||||
end
|
||||
|
||||
class HaveReadonlyAttributeMatcher # :nodoc:
|
||||
|
||||
def initialize(attribute)
|
||||
@attribute = attribute.to_s
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@subject = subject
|
||||
if readonly_attributes.include?(@attribute)
|
||||
@negative_failure_message =
|
||||
"Did not expect #{@attribute} to be read-only"
|
||||
true
|
||||
else
|
||||
if readonly_attributes.empty?
|
||||
@failure_message = "#{class_name} attribute #{@attribute} " <<
|
||||
"is not read-only"
|
||||
else
|
||||
@failure_message = "#{class_name} is making " <<
|
||||
"#{readonly_attributes.to_sentence} " <<
|
||||
"read-only, but not #{@attribute}."
|
||||
end
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :failure_message, :negative_failure_message
|
||||
|
||||
def description
|
||||
"make #{@attribute} read-only"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def readonly_attributes
|
||||
@readonly_attributes ||= (@subject.class.readonly_attributes || [])
|
||||
end
|
||||
|
||||
def class_name
|
||||
@subject.class.name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# Ensures that the model cannot be saved the given attribute is not
|
||||
# accepted.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>with_message</tt> - value the test expects to find in
|
||||
# <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
|
||||
# translation for <tt>:accepted</tt>.
|
||||
#
|
||||
# Example:
|
||||
# it { should validate_acceptance_of(:eula) }
|
||||
#
|
||||
def validate_acceptance_of(attr)
|
||||
ValidateAcceptanceOfMatcher.new(attr)
|
||||
end
|
||||
|
||||
class ValidateAcceptanceOfMatcher < ValidationMatcher # :nodoc:
|
||||
|
||||
def with_message(message)
|
||||
@expected_message = message if message
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
super(subject)
|
||||
@expected_message ||= :accepted
|
||||
disallows_value_of(false, @expected_message)
|
||||
end
|
||||
|
||||
def description
|
||||
"require #{@attribute} to be accepted"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# Ensure that the attribute is numeric
|
||||
#
|
||||
# Options:
|
||||
# * <tt>with_message</tt> - value the test expects to find in
|
||||
# <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
|
||||
# translation for <tt>:not_a_number</tt>.
|
||||
#
|
||||
# Example:
|
||||
# it { should validate_numericality_of(:age) }
|
||||
#
|
||||
def validate_numericality_of(attr)
|
||||
ValidateNumericalityOfMatcher.new(attr)
|
||||
end
|
||||
|
||||
class ValidateNumericalityOfMatcher < ValidationMatcher # :nodoc:
|
||||
|
||||
def with_message(message)
|
||||
@expected_message = message if message
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
super(subject)
|
||||
@expected_message ||= :not_a_number
|
||||
disallows_value_of('abcd', @expected_message)
|
||||
end
|
||||
|
||||
def description
|
||||
"only allow numeric values for #{@attribute}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# Ensures that the model is not valid if the given attribute is not
|
||||
# present.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>with_message</tt> - value the test expects to find in
|
||||
# <tt>errors.on(:attribute)</tt>. <tt>Regexp</tt> or <tt>String</tt>.
|
||||
# Defaults to the translation for <tt>:blank</tt>.
|
||||
#
|
||||
# Examples:
|
||||
# it { should validate_presence_of(:name) }
|
||||
# it { should validate_presence_of(:name).
|
||||
# with_message(/is not optional/) }
|
||||
#
|
||||
def validate_presence_of(attr)
|
||||
ValidatePresenceOfMatcher.new(attr)
|
||||
end
|
||||
|
||||
class ValidatePresenceOfMatcher < ValidationMatcher # :nodoc:
|
||||
|
||||
def with_message(message)
|
||||
@expected_message = message if message
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
super(subject)
|
||||
@expected_message ||= :blank
|
||||
disallows_value_of(blank_value, @expected_message)
|
||||
end
|
||||
|
||||
def description
|
||||
"require #{@attribute} to be set"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def blank_value
|
||||
if collection?
|
||||
[]
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def collection?
|
||||
if reflection = @subject.class.reflect_on_association(@attribute)
|
||||
[:has_many, :has_and_belongs_to_many].include?(reflection.macro)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,148 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
# Ensures that the model is invalid if the given attribute is not unique.
|
||||
#
|
||||
# Internally, this uses values from existing records to test validations,
|
||||
# so this will always fail if you have not saved at least one record for
|
||||
# the model being tested, like so:
|
||||
#
|
||||
# describe User do
|
||||
# before(:each) { User.create!(:email => 'address@example.com') }
|
||||
# it { should validate_uniqueness_of(:email) }
|
||||
# end
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
# * <tt>with_message</tt> - value the test expects to find in
|
||||
# <tt>errors.on(:attribute)</tt>. <tt>Regexp</tt> or <tt>String</tt>.
|
||||
# Defaults to the translation for <tt>:taken</tt>.
|
||||
# * <tt>scoped_to</tt> - field(s) to scope the uniqueness to.
|
||||
# * <tt>case_insensitive</tt> - ensures that the validation does not
|
||||
# check case. Off by default. Ignored by non-text attributes.
|
||||
#
|
||||
# Examples:
|
||||
# it { should validate_uniqueness_of(:keyword) }
|
||||
# it { should validate_uniqueness_of(:keyword).with_message(/dup/) }
|
||||
# it { should validate_uniqueness_of(:email).scoped_to(:name) }
|
||||
# it { should validate_uniqueness_of(:email).
|
||||
# scoped_to(:first_name, :last_name) }
|
||||
# it { should validate_uniqueness_of(:keyword).case_insensitive }
|
||||
#
|
||||
def validate_uniqueness_of(attr)
|
||||
ValidateUniquenessOfMatcher.new(attr)
|
||||
end
|
||||
|
||||
class ValidateUniquenessOfMatcher < ValidationMatcher # :nodoc:
|
||||
include Helpers
|
||||
|
||||
def initialize(attribute)
|
||||
@attribute = attribute
|
||||
end
|
||||
|
||||
def scoped_to(*scopes)
|
||||
@scopes = [*scopes].flatten
|
||||
self
|
||||
end
|
||||
|
||||
def with_message(message)
|
||||
@expected_message = message
|
||||
self
|
||||
end
|
||||
|
||||
def case_insensitive
|
||||
@case_insensitive = true
|
||||
self
|
||||
end
|
||||
|
||||
def description
|
||||
result = "require "
|
||||
result << "case sensitive " unless @case_insensitive
|
||||
result << "unique value for #{@attribute}"
|
||||
result << " scoped to #{@scopes.join(', ')}" unless @scopes.blank?
|
||||
result
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@subject = subject.class.new
|
||||
@expected_message ||= :taken
|
||||
find_existing &&
|
||||
set_scoped_attributes &&
|
||||
validate_attribute &&
|
||||
validate_after_scope_change
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_existing
|
||||
if @existing = @subject.class.find(:first)
|
||||
true
|
||||
else
|
||||
@failure_message = "Can't find first #{class_name}"
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def set_scoped_attributes
|
||||
unless @scopes.blank?
|
||||
@scopes.each do |scope|
|
||||
setter = :"#{scope}="
|
||||
unless @subject.respond_to?(setter)
|
||||
@failure_message =
|
||||
"#{class_name} doesn't seem to have a #{scope} attribute."
|
||||
return false
|
||||
end
|
||||
@subject.send("#{scope}=", @existing.send(scope))
|
||||
end
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def validate_attribute
|
||||
disallows_value_of(existing_value, @expected_message)
|
||||
end
|
||||
|
||||
# TODO: There is a chance that we could change the scoped field
|
||||
# to a value that's already taken. An alternative implementation
|
||||
# could actually find all values for scope and create a unique
|
||||
def validate_after_scope_change
|
||||
if @scopes.blank?
|
||||
true
|
||||
else
|
||||
@scopes.all? do |scope|
|
||||
previous_value = @existing.send(scope)
|
||||
|
||||
# Assume the scope is a foreign key if the field is nil
|
||||
previous_value ||= 0
|
||||
|
||||
next_value = previous_value.next
|
||||
|
||||
@subject.send("#{scope}=", next_value)
|
||||
|
||||
if allows_value_of(existing_value, @expected_message)
|
||||
@negative_failure_message <<
|
||||
" (with different value of #{scope})"
|
||||
true
|
||||
else
|
||||
@failure_message << " (with different value of #{scope})"
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def class_name
|
||||
@subject.class.name
|
||||
end
|
||||
|
||||
def existing_value
|
||||
value = @existing.send(@attribute)
|
||||
value.swapcase! if @case_insensitive && value.respond_to?(:swapcase!)
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
56
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/validation_matcher.rb
vendored
Normal file
56
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/active_record/matchers/validation_matcher.rb
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
module Shoulda # :nodoc:
|
||||
module ActiveRecord # :nodoc:
|
||||
module Matchers
|
||||
|
||||
class ValidationMatcher # :nodoc:
|
||||
|
||||
attr_reader :failure_message
|
||||
|
||||
def initialize(attribute)
|
||||
@attribute = attribute
|
||||
end
|
||||
|
||||
def negative_failure_message
|
||||
@negative_failure_message || @failure_message
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@subject = subject
|
||||
false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def allows_value_of(value, message = nil)
|
||||
allow = AllowValueMatcher.
|
||||
new(value).
|
||||
for(@attribute).
|
||||
with_message(message)
|
||||
if allow.matches?(@subject)
|
||||
@negative_failure_message = allow.failure_message
|
||||
true
|
||||
else
|
||||
@failure_message = allow.negative_failure_message
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def disallows_value_of(value, message = nil)
|
||||
disallow = AllowValueMatcher.
|
||||
new(value).
|
||||
for(@attribute).
|
||||
with_message(message)
|
||||
if disallow.matches?(@subject)
|
||||
@failure_message = disallow.negative_failure_message
|
||||
false
|
||||
else
|
||||
@negative_failure_message = disallow.failure_message
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
59
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/assertions.rb
vendored
Normal file
59
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/assertions.rb
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
module Shoulda # :nodoc:
|
||||
module Assertions
|
||||
# Asserts that two arrays contain the same elements, the same number of times. Essentially ==, but unordered.
|
||||
#
|
||||
# assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes
|
||||
def assert_same_elements(a1, a2, msg = nil)
|
||||
[:select, :inject, :size].each do |m|
|
||||
[a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
|
||||
end
|
||||
|
||||
assert a1h = a1.inject({}) { |h,e| h[e] = a1.select { |i| i == e }.size; h }
|
||||
assert a2h = a2.inject({}) { |h,e| h[e] = a2.select { |i| i == e }.size; h }
|
||||
|
||||
assert_equal(a1h, a2h, msg)
|
||||
end
|
||||
|
||||
# Asserts that the given collection contains item x. If x is a regular expression, ensure that
|
||||
# at least one element from the collection matches x. +extra_msg+ is appended to the error message if the assertion fails.
|
||||
#
|
||||
# assert_contains(['a', '1'], /\d/) => passes
|
||||
# assert_contains(['a', '1'], 'a') => passes
|
||||
# assert_contains(['a', '1'], /not there/) => fails
|
||||
def assert_contains(collection, x, extra_msg = "")
|
||||
collection = [collection] unless collection.is_a?(Array)
|
||||
msg = "#{x.inspect} not found in #{collection.to_a.inspect} #{extra_msg}"
|
||||
case x
|
||||
when Regexp
|
||||
assert(collection.detect { |e| e =~ x }, msg)
|
||||
else
|
||||
assert(collection.include?(x), msg)
|
||||
end
|
||||
end
|
||||
|
||||
# Asserts that the given collection does not contain item x. If x is a regular expression, ensure that
|
||||
# none of the elements from the collection match x.
|
||||
def assert_does_not_contain(collection, x, extra_msg = "")
|
||||
collection = [collection] unless collection.is_a?(Array)
|
||||
msg = "#{x.inspect} found in #{collection.to_a.inspect} " + extra_msg
|
||||
case x
|
||||
when Regexp
|
||||
assert(!collection.detect { |e| e =~ x }, msg)
|
||||
else
|
||||
assert(!collection.include?(x), msg)
|
||||
end
|
||||
end
|
||||
|
||||
# Asserts that the given matcher returns true when +target+ is passed to #matches?
|
||||
def assert_accepts(matcher, target)
|
||||
success = matcher.matches?(target)
|
||||
assert_block(matcher.failure_message) { success }
|
||||
end
|
||||
|
||||
# Asserts that the given matcher returns false when +target+ is passed to #matches?
|
||||
def assert_rejects(matcher, target)
|
||||
success = !matcher.matches?(target)
|
||||
assert_block(matcher.negative_failure_message) { success }
|
||||
end
|
||||
end
|
||||
end
|
||||
46
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/autoload_macros.rb
vendored
Normal file
46
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/autoload_macros.rb
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
module Shoulda # :nodoc:
|
||||
# Call autoload_macros when you want to load test macros automatically in a non-Rails
|
||||
# project (it's done automatically for Rails projects).
|
||||
# You don't need to specify ROOT/test/shoulda_macros explicitly. Your custom macros
|
||||
# are loaded automatically when you call autoload_macros.
|
||||
#
|
||||
# The first argument is the path to you application's root directory.
|
||||
# All following arguments are directories relative to your root, which contain
|
||||
# shoulda_macros subdirectories. These directories support the same kinds of globs as the
|
||||
# Dir class.
|
||||
#
|
||||
# Basic usage (from a test_helper):
|
||||
# Shoulda.autoload_macros(File.dirname(__FILE__) + '/..')
|
||||
# will load everything in
|
||||
# - your_app/test/shoulda_macros
|
||||
#
|
||||
# To load vendored macros as well:
|
||||
# Shoulda.autoload_macros(APP_ROOT, 'vendor/*')
|
||||
# will load everything in
|
||||
# - APP_ROOT/vendor/*/shoulda_macros
|
||||
# - APP_ROOT/test/shoulda_macros
|
||||
#
|
||||
# To load macros in an app with a vendor directory laid out like Rails':
|
||||
# Shoulda.autoload_macros(APP_ROOT, 'vendor/{plugins,gems}/*')
|
||||
# or
|
||||
# Shoulda.autoload_macros(APP_ROOT, 'vendor/plugins/*', 'vendor/gems/*')
|
||||
# will load everything in
|
||||
# - APP_ROOT/vendor/plugins/*/shoulda_macros
|
||||
# - APP_ROOT/vendor/gems/*/shoulda_macros
|
||||
# - APP_ROOT/test/shoulda_macros
|
||||
#
|
||||
# If you prefer to stick testing dependencies away from your production dependencies:
|
||||
# Shoulda.autoload_macros(APP_ROOT, 'vendor/*', 'test/vendor/*')
|
||||
# will load everything in
|
||||
# - APP_ROOT/vendor/*/shoulda_macros
|
||||
# - APP_ROOT/test/vendor/*/shoulda_macros
|
||||
# - APP_ROOT/test/shoulda_macros
|
||||
def self.autoload_macros(root, *dirs)
|
||||
dirs << File.join('test')
|
||||
complete_dirs = dirs.map{|d| File.join(root, d, 'shoulda_macros')}
|
||||
all_files = complete_dirs.inject([]){ |files, dir| files + Dir[File.join(dir, '*.rb')] }
|
||||
all_files.each do |file|
|
||||
require file
|
||||
end
|
||||
end
|
||||
end
|
||||
304
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb
vendored
Normal file
304
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/context.rb
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
module Shoulda
|
||||
class << self
|
||||
attr_accessor :contexts
|
||||
def contexts # :nodoc:
|
||||
@contexts ||= []
|
||||
end
|
||||
|
||||
def current_context # :nodoc:
|
||||
self.contexts.last
|
||||
end
|
||||
|
||||
def add_context(context) # :nodoc:
|
||||
self.contexts.push(context)
|
||||
end
|
||||
|
||||
def remove_context # :nodoc:
|
||||
self.contexts.pop
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# == Should statements
|
||||
#
|
||||
# Should statements are just syntactic sugar over normal Test::Unit test methods. A should block
|
||||
# contains all the normal code and assertions you're used to seeing, with the added benefit that
|
||||
# they can be wrapped inside context blocks (see below).
|
||||
#
|
||||
# === Example:
|
||||
#
|
||||
# class UserTest < Test::Unit::TestCase
|
||||
#
|
||||
# def setup
|
||||
# @user = User.new("John", "Doe")
|
||||
# end
|
||||
#
|
||||
# should "return its full name"
|
||||
# assert_equal 'John Doe', @user.full_name
|
||||
# end
|
||||
#
|
||||
# end
|
||||
#
|
||||
# ...will produce the following test:
|
||||
# * <tt>"test: User should return its full name. "</tt>
|
||||
#
|
||||
# Note: The part before <tt>should</tt> in the test name is gleamed from the name of the Test::Unit class.
|
||||
#
|
||||
# Should statements can also take a Proc as a <tt>:before </tt>option. This proc runs after any
|
||||
# parent context's setups but before the current context's setup.
|
||||
#
|
||||
# === Example:
|
||||
#
|
||||
# context "Some context" do
|
||||
# setup { puts("I run after the :before proc") }
|
||||
#
|
||||
# should "run a :before proc", :before => lambda { puts("I run before the setup") } do
|
||||
# assert true
|
||||
# end
|
||||
# end
|
||||
|
||||
def should(name, options = {}, &blk)
|
||||
if Shoulda.current_context
|
||||
block_given? ? Shoulda.current_context.should(name, options, &blk) : Should.current_context.should_eventually(name)
|
||||
else
|
||||
context_name = self.name.gsub(/Test/, "")
|
||||
context = Shoulda::Context.new(context_name, self) do
|
||||
block_given? ? should(name, options, &blk) : should_eventually(name)
|
||||
end
|
||||
context.build
|
||||
end
|
||||
end
|
||||
|
||||
# == Before statements
|
||||
#
|
||||
# Before statements are should statements that run before the current
|
||||
# context's setup. These are especially useful when setting expectations.
|
||||
#
|
||||
# === Example:
|
||||
#
|
||||
# class UserControllerTest < Test::Unit::TestCase
|
||||
# context "the index action" do
|
||||
# setup do
|
||||
# @users = [Factory(:user)]
|
||||
# User.stubs(:find).returns(@users)
|
||||
# end
|
||||
#
|
||||
# context "on GET" do
|
||||
# setup { get :index }
|
||||
#
|
||||
# should_respond_with :success
|
||||
#
|
||||
# # runs before "get :index"
|
||||
# before_should "find all users" do
|
||||
# User.expects(:find).with(:all).returns(@users)
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
def before_should(name, &blk)
|
||||
should(name, :before => blk) { assert true }
|
||||
end
|
||||
|
||||
# Just like should, but never runs, and instead prints an 'X' in the Test::Unit output.
|
||||
def should_eventually(name, options = {}, &blk)
|
||||
context_name = self.name.gsub(/Test/, "")
|
||||
context = Shoulda::Context.new(context_name, self) do
|
||||
should_eventually(name, &blk)
|
||||
end
|
||||
context.build
|
||||
end
|
||||
|
||||
# == Contexts
|
||||
#
|
||||
# A context block groups should statements under a common set of setup/teardown methods.
|
||||
# Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability
|
||||
# and readability of your test code.
|
||||
#
|
||||
# A context block can contain setup, should, should_eventually, and teardown blocks.
|
||||
#
|
||||
# class UserTest < Test::Unit::TestCase
|
||||
# context "A User instance" do
|
||||
# setup do
|
||||
# @user = User.find(:first)
|
||||
# end
|
||||
#
|
||||
# should "return its full name"
|
||||
# assert_equal 'John Doe', @user.full_name
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# This code will produce the method <tt>"test: A User instance should return its full name. "</tt>.
|
||||
#
|
||||
# Contexts may be nested. Nested contexts run their setup blocks from out to in before each
|
||||
# should statement. They then run their teardown blocks from in to out after each should statement.
|
||||
#
|
||||
# class UserTest < Test::Unit::TestCase
|
||||
# context "A User instance" do
|
||||
# setup do
|
||||
# @user = User.find(:first)
|
||||
# end
|
||||
#
|
||||
# should "return its full name"
|
||||
# assert_equal 'John Doe', @user.full_name
|
||||
# end
|
||||
#
|
||||
# context "with a profile" do
|
||||
# setup do
|
||||
# @user.profile = Profile.find(:first)
|
||||
# end
|
||||
#
|
||||
# should "return true when sent :has_profile?"
|
||||
# assert @user.has_profile?
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# This code will produce the following methods
|
||||
# * <tt>"test: A User instance should return its full name. "</tt>
|
||||
# * <tt>"test: A User instance with a profile should return true when sent :has_profile?. "</tt>
|
||||
#
|
||||
# <b>Just like should statements, a context block can exist next to normal <tt>def test_the_old_way; end</tt>
|
||||
# tests</b>. This means you do not have to fully commit to the context/should syntax in a test file.
|
||||
|
||||
def context(name, &blk)
|
||||
if Shoulda.current_context
|
||||
Shoulda.current_context.context(name, &blk)
|
||||
else
|
||||
context = Shoulda::Context.new(name, self, &blk)
|
||||
context.build
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Context # :nodoc:
|
||||
|
||||
attr_accessor :name # my name
|
||||
attr_accessor :parent # may be another context, or the original test::unit class.
|
||||
attr_accessor :subcontexts # array of contexts nested under myself
|
||||
attr_accessor :setup_blocks # blocks given via setup methods
|
||||
attr_accessor :teardown_blocks # blocks given via teardown methods
|
||||
attr_accessor :shoulds # array of hashes representing the should statements
|
||||
attr_accessor :should_eventuallys # array of hashes representing the should eventually statements
|
||||
|
||||
def initialize(name, parent, &blk)
|
||||
Shoulda.add_context(self)
|
||||
self.name = name
|
||||
self.parent = parent
|
||||
self.setup_blocks = []
|
||||
self.teardown_blocks = []
|
||||
self.shoulds = []
|
||||
self.should_eventuallys = []
|
||||
self.subcontexts = []
|
||||
|
||||
merge_block(&blk)
|
||||
Shoulda.remove_context
|
||||
end
|
||||
|
||||
def merge_block(&blk)
|
||||
blk.bind(self).call
|
||||
end
|
||||
|
||||
def context(name, &blk)
|
||||
self.subcontexts << Context.new(name, self, &blk)
|
||||
end
|
||||
|
||||
def setup(&blk)
|
||||
self.setup_blocks << blk
|
||||
end
|
||||
|
||||
def teardown(&blk)
|
||||
self.teardown_blocks << blk
|
||||
end
|
||||
|
||||
def should(name, options = {}, &blk)
|
||||
if block_given?
|
||||
self.shoulds << { :name => name, :before => options[:before], :block => blk }
|
||||
else
|
||||
self.should_eventuallys << { :name => name }
|
||||
end
|
||||
end
|
||||
|
||||
def should_eventually(name, &blk)
|
||||
self.should_eventuallys << { :name => name, :block => blk }
|
||||
end
|
||||
|
||||
def full_name
|
||||
parent_name = parent.full_name if am_subcontext?
|
||||
return [parent_name, name].join(" ").strip
|
||||
end
|
||||
|
||||
def am_subcontext?
|
||||
parent.is_a?(self.class) # my parent is the same class as myself.
|
||||
end
|
||||
|
||||
def test_unit_class
|
||||
am_subcontext? ? parent.test_unit_class : parent
|
||||
end
|
||||
|
||||
def create_test_from_should_hash(should)
|
||||
test_name = ["test:", full_name, "should", "#{should[:name]}. "].flatten.join(' ').to_sym
|
||||
|
||||
if test_unit_class.instance_methods.include?(test_name.to_s)
|
||||
warn " * WARNING: '#{test_name}' is already defined"
|
||||
end
|
||||
|
||||
context = self
|
||||
test_unit_class.send(:define_method, test_name) do
|
||||
begin
|
||||
context.run_parent_setup_blocks(self)
|
||||
should[:before].bind(self).call if should[:before]
|
||||
context.run_current_setup_blocks(self)
|
||||
should[:block].bind(self).call
|
||||
ensure
|
||||
context.run_all_teardown_blocks(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_all_setup_blocks(binding)
|
||||
run_parent_setup_blocks(binding)
|
||||
run_current_setup_blocks(binding)
|
||||
end
|
||||
|
||||
def run_parent_setup_blocks(binding)
|
||||
self.parent.run_all_setup_blocks(binding) if am_subcontext?
|
||||
end
|
||||
|
||||
def run_current_setup_blocks(binding)
|
||||
setup_blocks.each do |setup_block|
|
||||
setup_block.bind(binding).call
|
||||
end
|
||||
end
|
||||
|
||||
def run_all_teardown_blocks(binding)
|
||||
teardown_blocks.reverse.each do |teardown_block|
|
||||
teardown_block.bind(binding).call
|
||||
end
|
||||
self.parent.run_all_teardown_blocks(binding) if am_subcontext?
|
||||
end
|
||||
|
||||
def print_should_eventuallys
|
||||
should_eventuallys.each do |should|
|
||||
test_name = [full_name, "should", "#{should[:name]}. "].flatten.join(' ')
|
||||
puts " * DEFERRED: " + test_name
|
||||
end
|
||||
end
|
||||
|
||||
def build
|
||||
shoulds.each do |should|
|
||||
create_test_from_should_hash(should)
|
||||
end
|
||||
|
||||
subcontexts.each { |context| context.build }
|
||||
|
||||
print_should_eventuallys
|
||||
end
|
||||
|
||||
def method_missing(method, *args, &blk)
|
||||
test_unit_class.send(method, *args, &blk)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
8
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/helpers.rb
vendored
Normal file
8
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/helpers.rb
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
module Shoulda # :nodoc:
|
||||
module Helpers
|
||||
# Prints a message to stdout, tagged with the name of the calling method.
|
||||
def report!(msg = "")
|
||||
puts("#{caller.first}: #{msg}")
|
||||
end
|
||||
end
|
||||
end
|
||||
73
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/macros.rb
vendored
Normal file
73
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/macros.rb
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
require 'shoulda/private_helpers'
|
||||
|
||||
module Shoulda # :nodoc:
|
||||
module Macros
|
||||
# Macro that creates a test asserting a change between the return value
|
||||
# of an expression that is run before and after the current setup block
|
||||
# is run. This is similar to Active Support's <tt>assert_difference</tt>
|
||||
# assertion, but supports more than just numeric values. See also
|
||||
# should_not_change.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# context "Creating a post" do
|
||||
# setup { Post.create }
|
||||
# should_change "Post.count", :by => 1
|
||||
# end
|
||||
#
|
||||
# As shown in this example, the <tt>:by</tt> option expects a numeric
|
||||
# difference between the before and after values of the expression. You
|
||||
# may also specify <tt>:from</tt> and <tt>:to</tt> options:
|
||||
#
|
||||
# should_change "Post.count", :from => 0, :to => 1
|
||||
# should_change "@post.title", :from => "old", :to => "new"
|
||||
#
|
||||
# Combinations of <tt>:by</tt>, <tt>:from</tt>, and <tt>:to</tt> are allowed:
|
||||
#
|
||||
# should_change "@post.title" # => assert the value changed in some way
|
||||
# should_change "@post.title", :from => "old" # => assert the value changed to anything other than "old"
|
||||
# should_change "@post.title", :to => "new" # => assert the value changed from anything other than "new"
|
||||
def should_change(expression, options = {})
|
||||
by, from, to = get_options!([options], :by, :from, :to)
|
||||
stmt = "change #{expression.inspect}"
|
||||
stmt << " from #{from.inspect}" if from
|
||||
stmt << " to #{to.inspect}" if to
|
||||
stmt << " by #{by.inspect}" if by
|
||||
|
||||
expression_eval = lambda { eval(expression) }
|
||||
before = lambda { @_before_should_change = expression_eval.bind(self).call }
|
||||
should stmt, :before => before do
|
||||
old_value = @_before_should_change
|
||||
new_value = expression_eval.bind(self).call
|
||||
assert_operator from, :===, old_value, "#{expression.inspect} did not originally match #{from.inspect}" if from
|
||||
assert_not_equal old_value, new_value, "#{expression.inspect} did not change" unless by == 0
|
||||
assert_operator to, :===, new_value, "#{expression.inspect} was not changed to match #{to.inspect}" if to
|
||||
assert_equal old_value + by, new_value if by
|
||||
end
|
||||
end
|
||||
|
||||
# Macro that creates a test asserting no change between the return value
|
||||
# of an expression that is run before and after the current setup block
|
||||
# is run. This is the logical opposite of should_change.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# context "Updating a post" do
|
||||
# setup { @post.update_attributes(:title => "new") }
|
||||
# should_not_change "Post.count"
|
||||
# end
|
||||
def should_not_change(expression)
|
||||
expression_eval = lambda { eval(expression) }
|
||||
before = lambda { @_before_should_not_change = expression_eval.bind(self).call }
|
||||
should "not change #{expression.inspect}", :before => before do
|
||||
new_value = expression_eval.bind(self).call
|
||||
assert_equal @_before_should_not_change, new_value, "#{expression.inspect} changed"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
include Shoulda::Private
|
||||
end
|
||||
end
|
||||
|
||||
20
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/private_helpers.rb
vendored
Normal file
20
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/private_helpers.rb
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
module Shoulda # :nodoc:
|
||||
module Private # :nodoc:
|
||||
# Returns the values for the entries in the args hash who's keys are listed in the wanted array.
|
||||
# Will raise if there are keys in the args hash that aren't listed.
|
||||
def get_options!(args, *wanted)
|
||||
ret = []
|
||||
opts = (args.last.is_a?(Hash) ? args.pop : {})
|
||||
wanted.each {|w| ret << opts.delete(w)}
|
||||
raise ArgumentError, "Unsupported options given: #{opts.keys.join(', ')}" unless opts.keys.empty?
|
||||
return *ret
|
||||
end
|
||||
|
||||
# Returns the model class constant, as determined by the test class name.
|
||||
#
|
||||
# class TestUser; model_class; end => User
|
||||
def model_class
|
||||
self.name.gsub(/Test$/, '').constantize
|
||||
end
|
||||
end
|
||||
end
|
||||
14
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/proc_extensions.rb
vendored
Normal file
14
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/proc_extensions.rb
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Stolen straight from ActiveSupport
|
||||
|
||||
class Proc #:nodoc:
|
||||
def bind(object)
|
||||
block, time = self, Time.now
|
||||
(class << object; self end).class_eval do
|
||||
method_name = "__bind_#{time.to_i}_#{time.usec}"
|
||||
define_method(method_name, &block)
|
||||
method = instance_method(method_name)
|
||||
remove_method(method_name)
|
||||
method
|
||||
end.bind(object)
|
||||
end
|
||||
end
|
||||
13
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/rails.rb
vendored
Normal file
13
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/rails.rb
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'rubygems'
|
||||
require 'active_support'
|
||||
require 'shoulda'
|
||||
|
||||
require 'shoulda/active_record' if defined? ActiveRecord::Base
|
||||
require 'shoulda/action_controller' if defined? ActionController::Base
|
||||
require 'shoulda/action_view' if defined? ActionView::Base
|
||||
require 'shoulda/action_mailer' if defined? ActionMailer::Base
|
||||
|
||||
if defined?(RAILS_ROOT)
|
||||
# load in the 3rd party macros from vendorized plugins and gems
|
||||
Shoulda.autoload_macros RAILS_ROOT, File.join("vendor", "{plugins,gems}", "*")
|
||||
end
|
||||
11
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/rspec.rb
vendored
Normal file
11
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/rspec.rb
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
require 'shoulda/active_record/matchers'
|
||||
require 'shoulda/action_controller/matchers'
|
||||
require 'active_support/test_case'
|
||||
|
||||
# :enddoc:
|
||||
module ActiveSupport
|
||||
class TestCase
|
||||
include Shoulda::ActiveRecord::Matchers
|
||||
include Shoulda::ActionController::Matchers
|
||||
end
|
||||
end
|
||||
3
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/tasks.rb
vendored
Normal file
3
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/tasks.rb
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
Dir[File.join(File.dirname(__FILE__), 'tasks', '*.rake')].each do |f|
|
||||
load f
|
||||
end
|
||||
29
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/tasks/list_tests.rake
vendored
Normal file
29
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/tasks/list_tests.rake
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace :shoulda do
|
||||
desc "List the names of the test methods in a specification like format"
|
||||
task :list do
|
||||
$LOAD_PATH.unshift("test")
|
||||
|
||||
require 'test/unit'
|
||||
require 'rubygems'
|
||||
require 'active_support'
|
||||
|
||||
# bug in test unit. Set to true to stop from running.
|
||||
Test::Unit.run = true
|
||||
|
||||
test_files = Dir.glob(File.join('test', '**', '*_test.rb'))
|
||||
test_files.each do |file|
|
||||
load file
|
||||
klass = File.basename(file, '.rb').classify
|
||||
unless Object.const_defined?(klass.to_s)
|
||||
puts "Skipping #{klass} because it doesn't map to a Class"
|
||||
next
|
||||
end
|
||||
klass = klass.constantize
|
||||
|
||||
puts klass.name.gsub('Test', '')
|
||||
|
||||
test_methods = klass.instance_methods.grep(/^test/).map {|s| s.gsub(/^test: /, '')}.sort
|
||||
test_methods.each {|m| puts " " + m }
|
||||
end
|
||||
end
|
||||
end
|
||||
28
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/tasks/yaml_to_shoulda.rake
vendored
Normal file
28
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/tasks/yaml_to_shoulda.rake
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
namespace :shoulda do
|
||||
# From http://blog.internautdesign.com/2007/11/2/a-yaml_to_shoulda-rake-task
|
||||
# David.Lowenfels@gmail.com
|
||||
desc "Converts a YAML file (FILE=./path/to/yaml) into a Shoulda skeleton"
|
||||
task :from_yaml do
|
||||
require 'yaml'
|
||||
|
||||
def yaml_to_context(hash, indent = 0)
|
||||
indent1 = ' ' * indent
|
||||
indent2 = ' ' * (indent + 1)
|
||||
hash.each_pair do |context, shoulds|
|
||||
puts indent1 + "context \"#{context}\" do"
|
||||
puts
|
||||
shoulds.each do |should|
|
||||
yaml_to_context( should, indent + 1 ) and next if should.is_a?( Hash )
|
||||
puts indent2 + "should_eventually \"" + should.gsub(/^should +/,'') + "\" do"
|
||||
puts indent2 + "end"
|
||||
puts
|
||||
end
|
||||
puts indent1 + "end"
|
||||
end
|
||||
end
|
||||
|
||||
puts("Please pass in a FILE argument.") and exit unless ENV['FILE']
|
||||
|
||||
yaml_to_context( YAML.load_file( ENV['FILE'] ) )
|
||||
end
|
||||
end
|
||||
19
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/test_unit.rb
vendored
Normal file
19
vendor/gems/thoughtbot-shoulda-2.10.1/lib/shoulda/test_unit.rb
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
require 'shoulda/context'
|
||||
require 'shoulda/proc_extensions'
|
||||
require 'shoulda/assertions'
|
||||
require 'shoulda/macros'
|
||||
require 'shoulda/helpers'
|
||||
require 'shoulda/autoload_macros'
|
||||
require 'shoulda/rails' if defined? RAILS_ROOT
|
||||
|
||||
module Test # :nodoc: all
|
||||
module Unit
|
||||
class TestCase
|
||||
extend Shoulda::ClassMethods
|
||||
include Shoulda::Assertions
|
||||
extend Shoulda::Macros
|
||||
include Shoulda::Helpers
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
7
vendor/gems/thoughtbot-shoulda-2.10.1/rails/init.rb
vendored
Normal file
7
vendor/gems/thoughtbot-shoulda-2.10.1/rails/init.rb
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
if RAILS_ENV == 'test'
|
||||
if defined? Spec
|
||||
require 'shoulda/rspec'
|
||||
else
|
||||
require 'shoulda/rails'
|
||||
end
|
||||
end
|
||||
36
vendor/gems/thoughtbot-shoulda-2.10.1/test/README
vendored
Normal file
36
vendor/gems/thoughtbot-shoulda-2.10.1/test/README
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
The Shoulda test suite (in particular - the tests that test shoulda)
|
||||
|
||||
Quick overview:
|
||||
|
||||
The test directory contains the following files and subdirectories:
|
||||
|
||||
* rails_root - contains the stripped down rails application that the tests run against. The rails root contains:
|
||||
** the models, controllers, and views defined under app/
|
||||
** the test.rb environment file
|
||||
** a migration file for each model
|
||||
** a shoulda initializer that simulates loading the plugin but without relying on vendor/plugins
|
||||
* fixtures - contain the sample DB data for each model
|
||||
* functional - controller tests for each of the controllers under rails_root/app
|
||||
* unit - model tests for each of the models under rails_root/app
|
||||
* other - tests for the shoulda contexts, should statements, and assertions
|
||||
* test_helper.rb - responsible for initializing the test environment
|
||||
** sets the rails_env to test
|
||||
** sets the rails_root
|
||||
** runs all the migrations against the in-memory sqlite3 db
|
||||
** adds some magic to load the right fixture files
|
||||
|
||||
In order to add a new model (or controller) to the test suite:
|
||||
|
||||
* add that model to rails_root/app/models
|
||||
* add a migration for that model
|
||||
* add a fixture file
|
||||
* add a test for that file under test/units
|
||||
|
||||
Dependencies:
|
||||
|
||||
* Rails gem installed in the host system
|
||||
* A working sqlite3 installation.
|
||||
|
||||
If you have problems running these tests, please notify the mailing list: shoulda@googlegroups.com
|
||||
|
||||
- Tammer Saleh <tsaleh@thoughtbot.com>
|
||||
34
vendor/gems/thoughtbot-shoulda-2.10.1/test/fail_macros.rb
vendored
Normal file
34
vendor/gems/thoughtbot-shoulda-2.10.1/test/fail_macros.rb
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
module Shoulda
|
||||
class << self
|
||||
attr_accessor :expected_exceptions
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Enables the core shoulda test suite to test for failure scenarios. For
|
||||
# example, to ensure that a set of test macros should fail, do this:
|
||||
#
|
||||
# should_fail do
|
||||
# should_validate_presence_of :comments
|
||||
# should_not_allow_mass_assignment_of :name
|
||||
# end
|
||||
def should_fail(&block)
|
||||
context "should fail when trying to run:" do
|
||||
Shoulda.expected_exceptions = [Test::Unit::AssertionFailedError]
|
||||
yield block
|
||||
Shoulda.expected_exceptions = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Context
|
||||
# alias_method_chain hack to allow the should_fail macro to work
|
||||
def should_with_failure_scenario(name, options = {}, &block)
|
||||
if Shoulda.expected_exceptions
|
||||
expected_exceptions = Shoulda.expected_exceptions
|
||||
failure_block = lambda { assert_raise(*expected_exceptions, &block.bind(self)) }
|
||||
end
|
||||
should_without_failure_scenario(name, options, &(failure_block || block))
|
||||
end
|
||||
alias_method_chain :should, :failure_scenario
|
||||
end
|
||||
end
|
||||
3
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/addresses.yml
vendored
Normal file
3
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/addresses.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
first:
|
||||
title: Home
|
||||
addressable: first (User)
|
||||
0
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/friendships.yml
vendored
Normal file
0
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/friendships.yml
vendored
Normal file
5
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/posts.yml
vendored
Normal file
5
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/posts.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
first:
|
||||
id: 1
|
||||
title: My Cute Kitten!
|
||||
body: This is totally a cute kitten
|
||||
user_id: 1
|
||||
0
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/products.yml
vendored
Normal file
0
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/products.yml
vendored
Normal file
0
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/taggings.yml
vendored
Normal file
0
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/taggings.yml
vendored
Normal file
9
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/tags.yml
vendored
Normal file
9
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/tags.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
first:
|
||||
id: 1
|
||||
name: Stuff
|
||||
second:
|
||||
id: 2
|
||||
name: Rails
|
||||
third:
|
||||
id: 3
|
||||
name: Nothing
|
||||
6
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/users.yml
vendored
Normal file
6
vendor/gems/thoughtbot-shoulda-2.10.1/test/fixtures/users.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
first:
|
||||
id: 1
|
||||
name: Some dude
|
||||
age: 2
|
||||
email: none@none.com
|
||||
ssn: 123456789
|
||||
125
vendor/gems/thoughtbot-shoulda-2.10.1/test/functional/posts_controller_test.rb
vendored
Normal file
125
vendor/gems/thoughtbot-shoulda-2.10.1/test/functional/posts_controller_test.rb
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'posts_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class PostsController; def rescue_action(e) raise e end; end
|
||||
|
||||
class PostsControllerTest < Test::Unit::TestCase
|
||||
fixtures :all
|
||||
|
||||
def setup
|
||||
@controller = PostsController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
@post = Post.find(:first)
|
||||
end
|
||||
|
||||
# autodetects the :controller
|
||||
should_route :get, '/posts', :action => :index
|
||||
# explicitly specify :controller
|
||||
should_route :post, '/posts', :controller => :posts, :action => :create
|
||||
# non-string parameter
|
||||
should_route :get, '/posts/1', :action => :show, :id => 1
|
||||
# string-parameter
|
||||
should_route :put, '/posts/1', :action => :update, :id => "1"
|
||||
should_route :delete, '/posts/1', :action => :destroy, :id => 1
|
||||
should_route :get, '/posts/new', :action => :new
|
||||
|
||||
# Test the nested routes
|
||||
should_route :get, '/users/5/posts', :action => :index, :user_id => 5
|
||||
should_route :post, '/users/5/posts', :action => :create, :user_id => 5
|
||||
should_route :get, '/users/5/posts/1', :action => :show, :id => 1, :user_id => 5
|
||||
should_route :delete, '/users/5/posts/1', :action => :destroy, :id => 1, :user_id => 5
|
||||
should_route :get, '/users/5/posts/new', :action => :new, :user_id => 5
|
||||
should_route :put, '/users/5/posts/1', :action => :update, :id => 1, :user_id => 5
|
||||
|
||||
context "Logged in" do
|
||||
setup do
|
||||
@request.session[:logged_in] = true
|
||||
end
|
||||
|
||||
context "viewing posts for a user" do
|
||||
setup do
|
||||
get :index, :user_id => users(:first)
|
||||
end
|
||||
should_respond_with :success
|
||||
should_assign_to :user, :class => User, :equals => 'users(:first)'
|
||||
should_assign_to(:user) { users(:first) }
|
||||
should_fail do
|
||||
should_assign_to :user, :class => Post
|
||||
end
|
||||
should_fail do
|
||||
should_assign_to :user, :equals => 'posts(:first)'
|
||||
end
|
||||
should_fail do
|
||||
should_assign_to(:user) { posts(:first) }
|
||||
end
|
||||
should_assign_to :posts
|
||||
should_not_assign_to :foo, :bar
|
||||
should_render_page_with_metadata :description => /Posts/, :title => /index/
|
||||
should_render_page_with_metadata :keywords => "posts"
|
||||
end
|
||||
|
||||
context "viewing posts for a user with rss format" do
|
||||
setup do
|
||||
get :index, :user_id => users(:first), :format => 'rss'
|
||||
@user = users(:first)
|
||||
end
|
||||
should_respond_with :success
|
||||
should_respond_with_content_type 'application/rss+xml'
|
||||
should_respond_with_content_type :rss
|
||||
should_respond_with_content_type /rss/
|
||||
context "deprecated" do # to avoid redefining a test
|
||||
should_return_from_session :special, "'$2 off your next purchase'"
|
||||
end
|
||||
should_fail do
|
||||
should_return_from_session :special, "'not special'"
|
||||
end
|
||||
should_set_session(:mischief) { nil }
|
||||
should_return_from_session :malarky, "nil"
|
||||
should_set_session :special, "'$2 off your next purchase'"
|
||||
should_set_session :special_user_id, '@user.id'
|
||||
context "with a block" do
|
||||
should_set_session(:special_user_id) { @user.id }
|
||||
end
|
||||
should_fail do # to avoid redefining a test
|
||||
should_set_session(:special_user_id) { 'value' }
|
||||
end
|
||||
should_assign_to :user, :posts
|
||||
should_not_assign_to :foo, :bar
|
||||
end
|
||||
|
||||
context "viewing a post on GET to #show" do
|
||||
setup { get :show, :user_id => users(:first), :id => posts(:first) }
|
||||
should_render_with_layout 'wide'
|
||||
context "with a symbol" do # to avoid redefining a test
|
||||
should_render_with_layout :wide
|
||||
end
|
||||
should_assign_to :false_flag
|
||||
end
|
||||
|
||||
context "on GET to #new" do
|
||||
setup { get :new, :user_id => users(:first) }
|
||||
should_render_without_layout
|
||||
end
|
||||
|
||||
context "on POST to #create" do
|
||||
setup do
|
||||
post :create, :user_id => users(:first),
|
||||
:post => { :title => "first post",
|
||||
:body => 'blah blah blah' }
|
||||
end
|
||||
|
||||
should_redirect_to 'user_post_url(@post.user, @post)'
|
||||
should_redirect_to('the created post') { user_post_url(users(:first),
|
||||
assigns(:post)) }
|
||||
should_fail do
|
||||
should_redirect_to 'user_posts_url(@post.user)'
|
||||
end
|
||||
should_fail do
|
||||
should_redirect_to('elsewhere') { user_posts_url(users(:first)) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
19
vendor/gems/thoughtbot-shoulda-2.10.1/test/functional/users_controller_test.rb
vendored
Normal file
19
vendor/gems/thoughtbot-shoulda-2.10.1/test/functional/users_controller_test.rb
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'users_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class UsersController; def rescue_action(e) raise e end; end
|
||||
|
||||
class UsersControllerTest < Test::Unit::TestCase
|
||||
fixtures :all
|
||||
|
||||
def setup
|
||||
@controller = UsersController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
@user = User.find(:first)
|
||||
end
|
||||
|
||||
should_filter_params :ssn
|
||||
|
||||
end
|
||||
@@ -0,0 +1,68 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class AllowMassAssignmentOfMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "an attribute that is blacklisted from mass-assignment" do
|
||||
setup do
|
||||
define_model :example, :attr => :string do
|
||||
attr_protected :attr
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "reject being mass-assignable" do
|
||||
assert_rejects allow_mass_assignment_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that is not whitelisted for mass-assignment" do
|
||||
setup do
|
||||
define_model :example, :attr => :string, :other => :string do
|
||||
attr_accessible :other
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "reject being mass-assignable" do
|
||||
assert_rejects allow_mass_assignment_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that is whitelisted for mass-assignment" do
|
||||
setup do
|
||||
define_model :example, :attr => :string do
|
||||
attr_accessible :attr
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "accept being mass-assignable" do
|
||||
assert_accepts allow_mass_assignment_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute not included in the mass-assignment blacklist" do
|
||||
setup do
|
||||
define_model :example, :attr => :string, :other => :string do
|
||||
attr_protected :other
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "accept being mass-assignable" do
|
||||
assert_accepts allow_mass_assignment_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute on a class with no protected attributes" do
|
||||
setup do
|
||||
define_model :example, :attr => :string
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "accept being mass-assignable" do
|
||||
assert_accepts allow_mass_assignment_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
41
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/allow_value_matcher_test.rb
vendored
Normal file
41
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/allow_value_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class AllowValueMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "an attribute with a format validation" do
|
||||
setup do
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, :with => /abc/
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "allow a good value" do
|
||||
assert_accepts allow_value("abcde").for(:attr), @model
|
||||
end
|
||||
|
||||
should "not allow a bad value" do
|
||||
assert_rejects allow_value("xyz").for(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a format validation and a custom message" do
|
||||
setup do
|
||||
define_model :example, :attr => :string do
|
||||
validates_format_of :attr, :with => /abc/, :message => 'bad value'
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "allow a good value" do
|
||||
assert_accepts allow_value('abcde').for(:attr).with_message(/bad/),
|
||||
@model
|
||||
end
|
||||
|
||||
should "not allow a bad value" do
|
||||
assert_rejects allow_value('xyz').for(:attr).with_message(/bad/),
|
||||
@model
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
258
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/association_matcher_test.rb
vendored
Normal file
258
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/association_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class AssociationMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "belong_to" do
|
||||
setup do
|
||||
@matcher = belong_to(:parent)
|
||||
end
|
||||
|
||||
should "accept a good association with the default foreign key" do
|
||||
define_model :parent
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent
|
||||
end
|
||||
assert_accepts @matcher, Child.new
|
||||
end
|
||||
|
||||
should "reject a nonexistent association" do
|
||||
define_model :child
|
||||
assert_rejects @matcher, Child.new
|
||||
end
|
||||
|
||||
should "reject an association of the wrong type" do
|
||||
define_model :parent, :child_id => :integer
|
||||
child_class = define_model :child do
|
||||
has_one :parent
|
||||
end
|
||||
assert_rejects @matcher, Child.new
|
||||
end
|
||||
|
||||
should "reject an association that has a nonexistent foreign key" do
|
||||
define_model :parent
|
||||
define_model :child do
|
||||
belongs_to :parent
|
||||
end
|
||||
assert_rejects @matcher, Child.new
|
||||
end
|
||||
|
||||
should "accept an association with an existing custom foreign key" do
|
||||
define_model :parent
|
||||
define_model :child, :guardian_id => :integer do
|
||||
belongs_to :parent, :foreign_key => 'guardian_id'
|
||||
end
|
||||
assert_accepts @matcher, Child.new
|
||||
end
|
||||
|
||||
should "accept a polymorphic association" do
|
||||
define_model :child, :parent_type => :string,
|
||||
:parent_id => :integer do
|
||||
belongs_to :parent, :polymorphic => true
|
||||
end
|
||||
assert_accepts @matcher, Child.new
|
||||
end
|
||||
|
||||
should "accept an association with a valid :dependent option" do
|
||||
define_model :parent
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent, :dependent => :destroy
|
||||
end
|
||||
assert_accepts @matcher.dependent(:destroy), Child.new
|
||||
end
|
||||
|
||||
should "reject an association with a bad :dependent option" do
|
||||
define_model :parent
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent
|
||||
end
|
||||
assert_rejects @matcher.dependent(:destroy), Child.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_many" do
|
||||
setup do
|
||||
@matcher = have_many(:children)
|
||||
end
|
||||
|
||||
should "accept a valid association without any options" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
assert_accepts @matcher, Parent.new
|
||||
end
|
||||
|
||||
should "accept a valid association with a :through option" do
|
||||
define_model :child
|
||||
define_model :conception, :child_id => :integer,
|
||||
:parent_id => :integer do
|
||||
belongs_to :child
|
||||
end
|
||||
define_model :parent do
|
||||
has_many :conceptions
|
||||
has_many :children, :through => :conceptions
|
||||
end
|
||||
assert_accepts @matcher, Parent.new
|
||||
end
|
||||
|
||||
should "accept a valid association with an :as option" do
|
||||
define_model :child, :guardian_type => :string,
|
||||
:guardian_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, :as => :guardian
|
||||
end
|
||||
assert_accepts @matcher, Parent.new
|
||||
end
|
||||
|
||||
should "reject an association that has a nonexistent foreign key" do
|
||||
define_model :child
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
assert_rejects @matcher, Parent.new
|
||||
end
|
||||
|
||||
should "reject an association with a bad :as option" do
|
||||
define_model :child, :caretaker_type => :string,
|
||||
:caretaker_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, :as => :guardian
|
||||
end
|
||||
assert_rejects @matcher, Parent.new
|
||||
end
|
||||
|
||||
should "reject an association that has a bad :through option" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
assert_rejects @matcher.through(:conceptions), Parent.new
|
||||
end
|
||||
|
||||
should "reject an association that has the wrong :through option" do
|
||||
define_model :child
|
||||
define_model :conception, :child_id => :integer,
|
||||
:parent_id => :integer do
|
||||
belongs_to :child
|
||||
end
|
||||
define_model :parent do
|
||||
has_many :conceptions
|
||||
has_many :children, :through => :conceptions
|
||||
end
|
||||
assert_rejects @matcher.through(:relationships), Parent.new
|
||||
end
|
||||
|
||||
should "accept an association with a valid :dependent option" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, :dependent => :destroy
|
||||
end
|
||||
assert_accepts @matcher.dependent(:destroy), Parent.new
|
||||
end
|
||||
|
||||
should "reject an association with a bad :dependent option" do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children
|
||||
end
|
||||
assert_rejects @matcher.dependent(:destroy), Parent.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_one" do
|
||||
setup do
|
||||
@matcher = have_one(:profile)
|
||||
end
|
||||
|
||||
should "accept a valid association without any options" do
|
||||
define_model :profile, :person_id => :integer
|
||||
define_model :person do
|
||||
has_one :profile
|
||||
end
|
||||
assert_accepts @matcher, Person.new
|
||||
end
|
||||
|
||||
should "accept a valid association with an :as option" do
|
||||
define_model :profile, :profilable_id => :integer,
|
||||
:profilable_type => :string
|
||||
define_model :person do
|
||||
has_one :profile, :as => :profilable
|
||||
end
|
||||
assert_accepts @matcher, Person.new
|
||||
end
|
||||
|
||||
should "reject an association that has a nonexistent foreign key" do
|
||||
define_model :profile
|
||||
define_model :person do
|
||||
has_one :profile
|
||||
end
|
||||
assert_rejects @matcher, Person.new
|
||||
end
|
||||
|
||||
should "reject an association with a bad :as option" do
|
||||
define_model :profile, :profilable_id => :integer,
|
||||
:profilable_type => :string
|
||||
define_model :person do
|
||||
has_one :profile, :as => :describable
|
||||
end
|
||||
assert_rejects @matcher, Person.new
|
||||
end
|
||||
|
||||
should "accept an association with a valid :dependent option" do
|
||||
define_model :profile, :person_id => :integer
|
||||
define_model :person do
|
||||
has_one :profile, :dependent => :destroy
|
||||
end
|
||||
assert_accepts @matcher.dependent(:destroy), Person.new
|
||||
end
|
||||
|
||||
should "reject an association with a bad :dependent option" do
|
||||
define_model :profile, :person_id => :integer
|
||||
define_model :person do
|
||||
has_one :profile
|
||||
end
|
||||
assert_rejects @matcher.dependent(:destroy), Person.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_and_belong_to_many" do
|
||||
setup do
|
||||
@matcher = have_and_belong_to_many(:relatives)
|
||||
end
|
||||
|
||||
should "accept a valid association" do
|
||||
define_model :relatives
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives
|
||||
end
|
||||
define_model :people_relative, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
assert_accepts @matcher, Person.new
|
||||
end
|
||||
|
||||
should "reject a nonexistent association" do
|
||||
define_model :relatives
|
||||
define_model :person
|
||||
define_model :people_relative, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
assert_rejects @matcher, Person.new
|
||||
end
|
||||
|
||||
should "reject an association with a nonexistent join table" do
|
||||
define_model :relatives
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives
|
||||
end
|
||||
assert_rejects @matcher, Person.new
|
||||
end
|
||||
|
||||
should "reject an association of the wrong type" do
|
||||
define_model :relatives, :person_id => :integer
|
||||
define_model :person do
|
||||
has_many :relatives
|
||||
end
|
||||
assert_rejects @matcher, Person.new
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,80 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class EnsureInclusionOfMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "an attribute which must be included in a range" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :integer) do
|
||||
validates_inclusion_of :attr, :in => 2..5
|
||||
end.new
|
||||
end
|
||||
|
||||
should "accept ensuring the correct range" do
|
||||
assert_accepts ensure_inclusion_of(:attr).in_range(2..5), @model
|
||||
end
|
||||
|
||||
should "reject ensuring a lower minimum value" do
|
||||
assert_rejects ensure_inclusion_of(:attr).in_range(1..5), @model
|
||||
end
|
||||
|
||||
should "reject ensuring a higher minimum value" do
|
||||
assert_rejects ensure_inclusion_of(:attr).in_range(3..5), @model
|
||||
end
|
||||
|
||||
should "reject ensuring a lower maximum value" do
|
||||
assert_rejects ensure_inclusion_of(:attr).in_range(2..4), @model
|
||||
end
|
||||
|
||||
should "reject ensuring a higher maximum value" do
|
||||
assert_rejects ensure_inclusion_of(:attr).in_range(2..6), @model
|
||||
end
|
||||
|
||||
should "not override the default message with a blank" do
|
||||
assert_accepts ensure_inclusion_of(:attr).
|
||||
in_range(2..5).
|
||||
with_message(nil),
|
||||
@model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a custom ranged value validation" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_inclusion_of :attr, :in => 2..4, :message => 'not good'
|
||||
|
||||
end.new
|
||||
end
|
||||
|
||||
should "accept ensuring the correct range" do
|
||||
assert_accepts ensure_inclusion_of(:attr).
|
||||
in_range(2..4).
|
||||
with_message(/not good/),
|
||||
@model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with custom range validations" do
|
||||
setup do
|
||||
define_model :example, :attr => :integer do
|
||||
def validate
|
||||
if attr < 2
|
||||
errors.add(:attr, 'too low')
|
||||
elsif attr > 5
|
||||
errors.add(:attr, 'too high')
|
||||
end
|
||||
end
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "accept ensuring the correct range and messages" do
|
||||
assert_accepts ensure_inclusion_of(:attr).
|
||||
in_range(2..5).
|
||||
with_low_message(/low/).
|
||||
with_high_message(/high/),
|
||||
@model
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
158
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/ensure_length_of_matcher_test.rb
vendored
Normal file
158
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/ensure_length_of_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class EnsureLengthOfMatcher < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "an attribute with a non-zero minimum length validation" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :minimum => 4
|
||||
end.new
|
||||
end
|
||||
|
||||
should "accept ensuring the correct minimum length" do
|
||||
assert_accepts ensure_length_of(:attr).is_at_least(4), @model
|
||||
end
|
||||
|
||||
should "reject ensuring a lower minimum length with any message" do
|
||||
assert_rejects ensure_length_of(:attr).
|
||||
is_at_least(3).
|
||||
with_short_message(/.*/),
|
||||
@model
|
||||
end
|
||||
|
||||
should "reject ensuring a higher minimum length with any message" do
|
||||
assert_rejects ensure_length_of(:attr).
|
||||
is_at_least(5).
|
||||
with_short_message(/.*/),
|
||||
@model
|
||||
end
|
||||
|
||||
should "not override the default message with a blank" do
|
||||
assert_accepts ensure_length_of(:attr).
|
||||
is_at_least(4).
|
||||
with_short_message(nil),
|
||||
@model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a minimum length validation of 0" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :minimum => 0
|
||||
end.new
|
||||
end
|
||||
|
||||
should "accept ensuring the correct minimum length" do
|
||||
assert_accepts ensure_length_of(:attr).is_at_least(0), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a maximum length" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :maximum => 4
|
||||
end.new
|
||||
end
|
||||
|
||||
should "accept ensuring the correct maximum length" do
|
||||
assert_accepts ensure_length_of(:attr).is_at_most(4), @model
|
||||
end
|
||||
|
||||
should "reject ensuring a lower maximum length with any message" do
|
||||
assert_rejects ensure_length_of(:attr).
|
||||
is_at_most(3).
|
||||
with_long_message(/.*/),
|
||||
@model
|
||||
end
|
||||
|
||||
should "reject ensuring a higher maximum length with any message" do
|
||||
assert_rejects ensure_length_of(:attr).
|
||||
is_at_most(5).
|
||||
with_long_message(/.*/),
|
||||
@model
|
||||
end
|
||||
|
||||
should "not override the default message with a blank" do
|
||||
assert_accepts ensure_length_of(:attr).
|
||||
is_at_most(4).
|
||||
with_long_message(nil),
|
||||
@model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a required exact length" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :is => 4
|
||||
end.new
|
||||
end
|
||||
|
||||
should "accept ensuring the correct length" do
|
||||
assert_accepts ensure_length_of(:attr).is_equal_to(4), @model
|
||||
end
|
||||
|
||||
should "reject ensuring a lower maximum length with any message" do
|
||||
assert_rejects ensure_length_of(:attr).
|
||||
is_equal_to(3).
|
||||
with_message(/.*/),
|
||||
@model
|
||||
end
|
||||
|
||||
should "reject ensuring a higher maximum length with any message" do
|
||||
assert_rejects ensure_length_of(:attr).
|
||||
is_equal_to(5).
|
||||
with_message(/.*/),
|
||||
@model
|
||||
end
|
||||
|
||||
should "not override the default message with a blank" do
|
||||
assert_accepts ensure_length_of(:attr).
|
||||
is_equal_to(4).
|
||||
with_message(nil),
|
||||
@model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a custom minimum length validation" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :minimum => 4, :too_short => 'short'
|
||||
end.new
|
||||
end
|
||||
|
||||
should "accept ensuring the correct minimum length" do
|
||||
assert_accepts ensure_length_of(:attr).
|
||||
is_at_least(4).
|
||||
with_short_message(/short/),
|
||||
@model
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "an attribute with a custom maximum length validation" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_length_of :attr, :maximum => 4, :too_long => 'long'
|
||||
end.new
|
||||
end
|
||||
|
||||
should "accept ensuring the correct minimum length" do
|
||||
assert_accepts ensure_length_of(:attr).
|
||||
is_at_most(4).
|
||||
with_long_message(/long/),
|
||||
@model
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "an attribute without a length validation" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
end
|
||||
|
||||
should "reject ensuring a minimum length" do
|
||||
assert_rejects ensure_length_of(:attr).is_at_least(1), @model
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
169
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/have_db_column_matcher_test.rb
vendored
Normal file
169
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/have_db_column_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class HaveDbColumnMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "have_db_column" do
|
||||
setup do
|
||||
@matcher = have_db_column(:nickname)
|
||||
end
|
||||
|
||||
should "accept an existing database column" do
|
||||
create_table 'superheros' do |table|
|
||||
table.string :nickname
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_accepts @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject a nonexistent database column" do
|
||||
define_model :superhero
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column of type string" do
|
||||
setup do
|
||||
@matcher = have_db_column(:nickname).of_type(:string)
|
||||
end
|
||||
|
||||
should "accept a column of correct type" do
|
||||
create_table 'superheros' do |table|
|
||||
table.string :nickname
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_accepts @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject a nonexistent database column" do
|
||||
define_model :superhero
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject a column of wrong type" do
|
||||
create_table 'superheros' do |table|
|
||||
table.integer :nickname
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with precision option" do
|
||||
setup do
|
||||
@matcher = have_db_column(:salary).with_options(:precision => 5)
|
||||
end
|
||||
|
||||
should "accept a column of correct precision" do
|
||||
create_table 'superheros' do |table|
|
||||
table.decimal :salary, :precision => 5
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_accepts @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject a column of wrong precision" do
|
||||
create_table 'superheros' do |table|
|
||||
table.decimal :salary, :precision => 15
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with limit option" do
|
||||
setup do
|
||||
@matcher = have_db_column(:email).
|
||||
of_type(:string).
|
||||
with_options(:limit => 255)
|
||||
end
|
||||
|
||||
should "accept a column of correct limit" do
|
||||
create_table 'superheros' do |table|
|
||||
table.string :email, :limit => 255
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_accepts @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject a column of wrong limit" do
|
||||
create_table 'superheros' do |table|
|
||||
table.string :email, :limit => 500
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with default option" do
|
||||
setup do
|
||||
@matcher = have_db_column(:admin).
|
||||
of_type(:boolean).
|
||||
with_options(:default => false)
|
||||
end
|
||||
|
||||
should "accept a column of correct default" do
|
||||
create_table 'superheros' do |table|
|
||||
table.boolean :admin, :default => false
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_accepts @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject a column of wrong default" do
|
||||
create_table 'superheros' do |table|
|
||||
table.boolean :admin, :default => true
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with null option" do
|
||||
setup do
|
||||
@matcher = have_db_column(:admin).
|
||||
of_type(:boolean).
|
||||
with_options(:null => false)
|
||||
end
|
||||
|
||||
should "accept a column of correct null" do
|
||||
create_table 'superheros' do |table|
|
||||
table.boolean :admin, :null => false
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_accepts @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject a column of wrong null" do
|
||||
create_table 'superheros' do |table|
|
||||
table.boolean :admin, :null => true
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_db_column with scale option" do
|
||||
setup do
|
||||
@matcher = have_db_column(:salary).
|
||||
of_type(:decimal).
|
||||
with_options(:scale => 2)
|
||||
end
|
||||
|
||||
should "accept a column of correct scale" do
|
||||
create_table 'superheros' do |table|
|
||||
table.decimal :salary, :precision => 10, :scale => 2
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_accepts @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject a column of wrong scale" do
|
||||
create_table 'superheros' do |table|
|
||||
table.decimal :salary, :precision => 10, :scale => 4
|
||||
end
|
||||
define_model_class 'Superhero'
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
74
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/have_index_matcher_test.rb
vendored
Normal file
74
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/active_record/have_index_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class HaveIndexMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "have_index" do
|
||||
setup do
|
||||
@matcher = have_index(:age)
|
||||
end
|
||||
|
||||
should "accept an existing index" do
|
||||
db_connection = create_table 'superheros' do |table|
|
||||
table.integer :age
|
||||
end
|
||||
db_connection.add_index :superheros, :age
|
||||
define_model_class 'Superhero'
|
||||
assert_accepts @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject a nonexistent index" do
|
||||
define_model :superhero
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_index with unique option" do
|
||||
setup do
|
||||
@matcher = have_index(:ssn).unique(true)
|
||||
end
|
||||
|
||||
should "accept an index of correct unique" do
|
||||
db_connection = create_table 'superheros' do |table|
|
||||
table.integer :ssn
|
||||
end
|
||||
db_connection.add_index :superheros, :ssn, :unique => true
|
||||
define_model_class 'Superhero'
|
||||
assert_accepts @matcher, Superhero.new
|
||||
end
|
||||
|
||||
should "reject an index of wrong unique" do
|
||||
db_connection = create_table 'superheros' do |table|
|
||||
table.integer :ssn
|
||||
end
|
||||
db_connection.add_index :superheros, :ssn, :unique => false
|
||||
define_model_class 'Superhero'
|
||||
assert_rejects @matcher, Superhero.new
|
||||
end
|
||||
end
|
||||
|
||||
context "have_index on multiple columns" do
|
||||
setup do
|
||||
@matcher = have_index([:geocodable_type, :geocodable_id])
|
||||
end
|
||||
|
||||
should "accept an existing index" do
|
||||
db_connection = create_table 'geocodings' do |table|
|
||||
table.integer :geocodable_id
|
||||
table.string :geocodable_type
|
||||
end
|
||||
db_connection.add_index :geocodings, [:geocodable_type, :geocodable_id]
|
||||
define_model_class 'Geocoding'
|
||||
assert_accepts @matcher, Geocoding.new
|
||||
end
|
||||
|
||||
should "reject a nonexistant index" do
|
||||
db_connection = create_table 'geocodings' do |table|
|
||||
table.integer :geocodable_id
|
||||
table.string :geocodable_type
|
||||
end
|
||||
define_model_class 'Geocoding'
|
||||
assert_rejects @matcher, Geocoding.new
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,65 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class HaveNamedScopeMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "an attribute with a named scope" do
|
||||
setup do
|
||||
define_model :example, :attr => :string do
|
||||
named_scope :xyz, lambda {|n|
|
||||
{ :order => :attr }
|
||||
}
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "accept having a scope with the correct signature" do
|
||||
assert_accepts have_named_scope("xyz(1)"), @model
|
||||
end
|
||||
|
||||
should "accept having a scope with the correct signature and find options" do
|
||||
assert_accepts have_named_scope("xyz(1)").finding(:order => :attr), @model
|
||||
end
|
||||
|
||||
should "reject having a scope with incorrect find options" do
|
||||
assert_rejects have_named_scope("xyz(1)").
|
||||
finding(:order => 'attr DESC'),
|
||||
@model
|
||||
end
|
||||
|
||||
should "reject having a scope with another name" do
|
||||
assert_rejects have_named_scope("abc(1)"), @model
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
should "evaluate the scope in the correct context" do
|
||||
define_model :example, :attr => :string do
|
||||
named_scope :xyz, lambda {|n|
|
||||
{ :order => n }
|
||||
}
|
||||
end
|
||||
model = Example.new
|
||||
@order = :attr
|
||||
assert_accepts have_named_scope("xyz(@order)").
|
||||
finding(:order => @order).
|
||||
in_context(self),
|
||||
model
|
||||
end
|
||||
|
||||
context "a method that does not return a scope" do
|
||||
setup do
|
||||
klass = Class.new
|
||||
klass.class_eval do
|
||||
def self.xyz
|
||||
'xyz'
|
||||
end
|
||||
end
|
||||
@model = klass.new
|
||||
end
|
||||
|
||||
should "reject having a named scope with that name" do
|
||||
assert_rejects have_named_scope(:xyz), @model
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class HaveReadonlyAttributesMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "an attribute that cannot be set after being saved" do
|
||||
setup do
|
||||
define_model :example, :attr => :string do
|
||||
attr_readonly :attr
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "accept being read-only" do
|
||||
assert_accepts have_readonly_attribute(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that can be set after being saved" do
|
||||
setup do
|
||||
define_model :example, :attr => :string
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "accept being read-only" do
|
||||
assert_rejects have_readonly_attribute(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class ValidateAcceptanceOfMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "an attribute which must be accepted" do
|
||||
setup do
|
||||
@model = define_model(:example) do
|
||||
validates_acceptance_of :attr
|
||||
end.new
|
||||
end
|
||||
|
||||
should "require that attribute to be accepted" do
|
||||
assert_accepts validate_acceptance_of(:attr), @model
|
||||
end
|
||||
|
||||
should "not overwrite the default message with nil" do
|
||||
assert_accepts validate_acceptance_of(:attr).with_message(nil), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute that does not need to be accepted" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
end
|
||||
|
||||
should "not require that attribute to be accepted" do
|
||||
assert_rejects validate_acceptance_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute which must be accepted with a custom message" do
|
||||
setup do
|
||||
@model = define_model(:example) do
|
||||
validates_acceptance_of :attr, :message => 'custom'
|
||||
end.new
|
||||
end
|
||||
|
||||
should "require that attribute to be accepted with that message" do
|
||||
assert_accepts validate_acceptance_of(:attr).with_message(/custom/),
|
||||
@model
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class ValidateNumericalityOfMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a numeric attribute" do
|
||||
setup do
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "only allow numeric values for that attribute" do
|
||||
assert_accepts validate_numericality_of(:attr), @model
|
||||
end
|
||||
|
||||
should "not override the default message with a blank" do
|
||||
assert_accepts validate_numericality_of(:attr).with_message(nil),
|
||||
@model
|
||||
end
|
||||
end
|
||||
|
||||
context "a numeric attribute with a custom validation message" do
|
||||
setup do
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, :message => 'custom'
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "only allow numeric values for that attribute with that message" do
|
||||
assert_accepts validate_numericality_of(:attr).
|
||||
with_message(/custom/),
|
||||
@model
|
||||
end
|
||||
|
||||
should "not allow numeric values for that attribute with another message" do
|
||||
assert_rejects validate_numericality_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "a non-numeric attribute" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
end
|
||||
|
||||
should "not only allow numeric values for that attribute" do
|
||||
assert_rejects validate_numericality_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,86 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class ValidatePresenceOfMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a required attribute" do
|
||||
setup do
|
||||
define_model :example, :attr => :string do
|
||||
validates_presence_of :attr
|
||||
end
|
||||
@model = Example.new
|
||||
end
|
||||
|
||||
should "require a value" do
|
||||
assert_accepts validate_presence_of(:attr), @model
|
||||
end
|
||||
|
||||
should "not override the default message with a blank" do
|
||||
assert_accepts validate_presence_of(:attr).with_message(nil), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an optional attribute" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
end
|
||||
|
||||
should "not require a value" do
|
||||
assert_rejects validate_presence_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "a required has_many association" do
|
||||
setup do
|
||||
define_model :child
|
||||
@model = define_model :parent do
|
||||
has_many :children
|
||||
validates_presence_of :children
|
||||
end.new
|
||||
end
|
||||
|
||||
should "require the attribute to be set" do
|
||||
assert_accepts validate_presence_of(:children), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an optional has_many association" do
|
||||
setup do
|
||||
define_model :child
|
||||
@model = define_model :parent do
|
||||
has_many :children
|
||||
end.new
|
||||
end
|
||||
|
||||
should "not require the attribute to be set" do
|
||||
assert_rejects validate_presence_of(:children), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "a required has_and_belongs_to_many association" do
|
||||
setup do
|
||||
define_model :child
|
||||
@model = define_model :parent do
|
||||
has_and_belongs_to_many :children
|
||||
validates_presence_of :children
|
||||
end.new
|
||||
end
|
||||
|
||||
should "require the attribute to be set" do
|
||||
assert_accepts validate_presence_of(:children), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "an optional has_and_belongs_to_many association" do
|
||||
setup do
|
||||
define_model :child
|
||||
@model = define_model :parent do
|
||||
has_and_belongs_to_many :children
|
||||
end.new
|
||||
end
|
||||
|
||||
should "not require the attribute to be set" do
|
||||
assert_rejects validate_presence_of(:children), @model
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,147 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class ValidateUniquenessOfMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a unique attribute" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string,
|
||||
:other => :integer) do
|
||||
validates_uniqueness_of :attr
|
||||
end.new
|
||||
end
|
||||
|
||||
context "with an existing value" do
|
||||
setup do
|
||||
@existing = Example.create!(:attr => 'value', :other => 1)
|
||||
end
|
||||
|
||||
should "require a unique value for that attribute" do
|
||||
assert_accepts validate_uniqueness_of(:attr), @model
|
||||
end
|
||||
|
||||
should "pass when the subject is an existing record" do
|
||||
assert_accepts validate_uniqueness_of(:attr), @existing
|
||||
end
|
||||
|
||||
should "fail when a scope is specified" do
|
||||
assert_rejects validate_uniqueness_of(:attr).scoped_to(:other), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "without an existing value" do
|
||||
setup do
|
||||
assert_nil Example.find(:first)
|
||||
@matcher = validate_uniqueness_of(:attr)
|
||||
end
|
||||
|
||||
should "fail to require a unique value" do
|
||||
assert_rejects @matcher, @model
|
||||
end
|
||||
|
||||
should "alert the tester that an existing value is not present" do
|
||||
@matcher.matches?(@model)
|
||||
assert @matcher.negative_failure_message =~ /^Can't find first .*/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "a unique attribute with a custom error and an existing value" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_uniqueness_of :attr, :message => 'Bad value'
|
||||
end.new
|
||||
Example.create!
|
||||
end
|
||||
|
||||
should "fail when checking the default message" do
|
||||
assert_rejects validate_uniqueness_of(:attr), @model
|
||||
end
|
||||
|
||||
should "fail when checking a message that doesn't match" do
|
||||
assert_rejects validate_uniqueness_of(:attr).with_message(/abc/i), @model
|
||||
end
|
||||
|
||||
should "pass when checking a message that matches" do
|
||||
assert_accepts validate_uniqueness_of(:attr).with_message(/bad/i), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "a scoped unique attribute with an existing value" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string,
|
||||
:scope1 => :integer,
|
||||
:scope2 => :integer) do
|
||||
validates_uniqueness_of :attr, :scope => [:scope1, :scope2]
|
||||
end.new
|
||||
@existing = Example.create!(:attr => 'value', :scope1 => 1, :scope2 => 2)
|
||||
end
|
||||
|
||||
should "pass when the correct scope is specified" do
|
||||
assert_accepts validate_uniqueness_of(:attr).scoped_to(:scope1, :scope2),
|
||||
@model
|
||||
end
|
||||
|
||||
should "pass when the subject is an existing record" do
|
||||
assert_accepts validate_uniqueness_of(:attr).scoped_to(:scope1, :scope2),
|
||||
@existing
|
||||
end
|
||||
|
||||
should "fail when a different scope is specified" do
|
||||
assert_rejects validate_uniqueness_of(:attr).scoped_to(:scope1), @model
|
||||
end
|
||||
|
||||
should "fail when no scope is specified" do
|
||||
assert_rejects validate_uniqueness_of(:attr), @model
|
||||
end
|
||||
|
||||
should "fail when a non-existent attribute is specified as a scope" do
|
||||
assert_rejects validate_uniqueness_of(:attr).scoped_to(:fake), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "a non-unique attribute with an existing value" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string).new
|
||||
Example.create!(:attr => 'value')
|
||||
end
|
||||
|
||||
should "not require a unique value for that attribute" do
|
||||
assert_rejects validate_uniqueness_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "a case sensitive unique attribute with an existing value" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :string) do
|
||||
validates_uniqueness_of :attr, :case_sensitive => true
|
||||
end.new
|
||||
Example.create!(:attr => 'value')
|
||||
end
|
||||
|
||||
should "not require a unique, case-insensitive value for that attribute" do
|
||||
assert_rejects validate_uniqueness_of(:attr).case_insensitive, @model
|
||||
end
|
||||
|
||||
should "require a unique, case-sensitive value for that attribute" do
|
||||
assert_accepts validate_uniqueness_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
context "a case sensitive unique integer attribute with an existing value" do
|
||||
setup do
|
||||
@model = define_model(:example, :attr => :integer) do
|
||||
validates_uniqueness_of :attr, :case_sensitive => true
|
||||
end.new
|
||||
Example.create!(:attr => 'value')
|
||||
end
|
||||
|
||||
should "require a unique, case-insensitive value for that attribute" do
|
||||
assert_accepts validate_uniqueness_of(:attr).case_insensitive, @model
|
||||
end
|
||||
|
||||
should "require a unique, case-sensitive value for that attribute" do
|
||||
assert_accepts validate_uniqueness_of(:attr), @model
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
35
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/assign_to_matcher_test.rb
vendored
Normal file
35
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/assign_to_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class AssignToMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a controller that assigns to an instance variable" do
|
||||
setup do
|
||||
@controller = build_response { @var = 'value' }
|
||||
end
|
||||
|
||||
should "accept assigning to that variable" do
|
||||
assert_accepts assign_to(:var), @controller
|
||||
end
|
||||
|
||||
should "accept assigning to that variable with the correct class" do
|
||||
assert_accepts assign_to(:var).with_kind_of(String), @controller
|
||||
end
|
||||
|
||||
should "reject assigning to that variable with another class" do
|
||||
assert_rejects assign_to(:var).with_kind_of(Fixnum), @controller
|
||||
end
|
||||
|
||||
should "accept assigning the correct value to that variable" do
|
||||
assert_accepts assign_to(:var).with('value'), @controller
|
||||
end
|
||||
|
||||
should "reject assigning another value to that variable" do
|
||||
assert_rejects assign_to(:var).with('other'), @controller
|
||||
end
|
||||
|
||||
should "reject assigning to another variable" do
|
||||
assert_rejects assign_to(:other), @controller
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
32
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/filter_param_matcher_test.rb
vendored
Normal file
32
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/filter_param_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class FilterParamMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a controller that filters no parameters" do
|
||||
setup do
|
||||
@controller = define_controller(:examples).new
|
||||
end
|
||||
|
||||
should "reject filtering any parameter" do
|
||||
assert_rejects filter_param(:any), @controller
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that filters a parameter" do
|
||||
setup do
|
||||
@controller = define_controller :examples do
|
||||
filter_parameter_logging :password
|
||||
end.new
|
||||
end
|
||||
|
||||
should "accept filtering that parameter" do
|
||||
assert_accepts filter_param(:password), @controller
|
||||
end
|
||||
|
||||
should "reject filtering another parameter" do
|
||||
assert_rejects filter_param(:other), @controller
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class RenderWithLayoutMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a controller that renders with a layout" do
|
||||
setup do
|
||||
@controller = build_response { render :layout => 'wide' }
|
||||
end
|
||||
|
||||
should "accept rendering with any layout" do
|
||||
assert_accepts render_with_layout, @controller
|
||||
end
|
||||
|
||||
should "accept rendering with that layout" do
|
||||
assert_accepts render_with_layout(:wide), @controller
|
||||
end
|
||||
|
||||
should "reject rendering with another layout" do
|
||||
assert_rejects render_with_layout(:other), @controller
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that renders without a layout" do
|
||||
setup do
|
||||
@controller = build_response { render :layout => false }
|
||||
end
|
||||
|
||||
should "reject rendering with a layout" do
|
||||
assert_rejects render_with_layout, @controller
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class RespondWithContentTypeMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a controller responding with content type :xml" do
|
||||
setup do
|
||||
@controller = build_response { render :xml => { :user => "thoughtbot" }.to_xml }
|
||||
end
|
||||
|
||||
should "accept responding with content type :xml" do
|
||||
assert_accepts respond_with_content_type(:xml), @controller
|
||||
end
|
||||
|
||||
should "accept responding with content type 'application/xml'" do
|
||||
assert_accepts respond_with_content_type('application/xml'), @controller
|
||||
end
|
||||
|
||||
should "accept responding with content type /xml/" do
|
||||
assert_accepts respond_with_content_type(/xml/), @controller
|
||||
end
|
||||
|
||||
should "reject responding with another content type" do
|
||||
assert_rejects respond_with_content_type(:json), @controller
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
106
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/respond_with_matcher_test.rb
vendored
Normal file
106
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/respond_with_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class RespondWithMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a controller responding with success" do
|
||||
setup do
|
||||
@controller = build_response { render :text => "text", :status => 200 }
|
||||
end
|
||||
|
||||
should "accept responding with 200" do
|
||||
assert_accepts respond_with(200), @controller
|
||||
end
|
||||
|
||||
should "accept responding with :success" do
|
||||
assert_accepts respond_with(:success), @controller
|
||||
end
|
||||
|
||||
should "reject responding with another status" do
|
||||
assert_rejects respond_with(:error), @controller
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller responding with redirect" do
|
||||
setup do
|
||||
@controller = build_response { render :text => "text", :status => 301 }
|
||||
end
|
||||
|
||||
should "accept responding with 301" do
|
||||
assert_accepts respond_with(301), @controller
|
||||
end
|
||||
|
||||
should "accept responding with :redirect" do
|
||||
assert_accepts respond_with(:redirect), @controller
|
||||
end
|
||||
|
||||
should "reject responding with another status" do
|
||||
assert_rejects respond_with(:error), @controller
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller responding with missing" do
|
||||
setup do
|
||||
@controller = build_response { render :text => "text", :status => 404 }
|
||||
end
|
||||
|
||||
should "accept responding with 404" do
|
||||
assert_accepts respond_with(404), @controller
|
||||
end
|
||||
|
||||
should "accept responding with :missing" do
|
||||
assert_accepts respond_with(:missing), @controller
|
||||
end
|
||||
|
||||
should "reject responding with another status" do
|
||||
assert_rejects respond_with(:success), @controller
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller responding with error" do
|
||||
setup do
|
||||
@controller = build_response { render :text => "text", :status => 500 }
|
||||
end
|
||||
|
||||
should "accept responding with 500" do
|
||||
assert_accepts respond_with(500), @controller
|
||||
end
|
||||
|
||||
should "accept responding with :error" do
|
||||
assert_accepts respond_with(:error), @controller
|
||||
end
|
||||
|
||||
should "reject responding with another status" do
|
||||
assert_rejects respond_with(:success), @controller
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller responding with not implemented" do
|
||||
setup do
|
||||
@controller = build_response { render :text => "text", :status => 501 }
|
||||
end
|
||||
|
||||
should "accept responding with 501" do
|
||||
assert_accepts respond_with(501), @controller
|
||||
end
|
||||
|
||||
should "accept responding with :not_implemented" do
|
||||
assert_accepts respond_with(:not_implemented), @controller
|
||||
end
|
||||
|
||||
should "reject responding with another status" do
|
||||
assert_rejects respond_with(:success), @controller
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller raising an error" do
|
||||
setup do
|
||||
@controller = build_response { raise RailsError }
|
||||
end
|
||||
|
||||
should "reject responding with any status" do
|
||||
assert_rejects respond_with(:success), @controller
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
58
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/route_matcher_test.rb
vendored
Normal file
58
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/route_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class RouteToMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "given a controller with a defined route" do
|
||||
setup do
|
||||
@controller = define_controller('Examples').new
|
||||
define_routes do |map|
|
||||
map.connect 'examples/:id', :controller => 'examples',
|
||||
:action => 'example'
|
||||
end
|
||||
end
|
||||
|
||||
should "accept routing the correct path to the correct parameters" do
|
||||
assert_accepts route(:get, '/examples/1').
|
||||
to(:action => 'example', :id => '1'),
|
||||
@controller
|
||||
end
|
||||
|
||||
should "accept a symbol controller" do
|
||||
assert_accepts route(:get, '/examples/1').
|
||||
to(:controller => :examples,
|
||||
:action => 'example',
|
||||
:id => '1'),
|
||||
self
|
||||
end
|
||||
|
||||
should "accept a symbol action" do
|
||||
assert_accepts route(:get, '/examples/1').
|
||||
to(:action => :example, :id => '1'),
|
||||
@controller
|
||||
end
|
||||
|
||||
should "accept a non-string parameter" do
|
||||
assert_accepts route(:get, '/examples/1').
|
||||
to(:action => 'example', :id => 1),
|
||||
@controller
|
||||
end
|
||||
|
||||
should "reject an undefined route" do
|
||||
assert_rejects route(:get, '/bad_route').to(:var => 'value'), @controller
|
||||
end
|
||||
|
||||
should "reject a route for another controller" do
|
||||
@other = define_controller('Other').new
|
||||
assert_rejects route(:get, '/examples/1').
|
||||
to(:action => 'example', :id => '1'),
|
||||
@other
|
||||
end
|
||||
|
||||
should "reject a route for different parameters" do
|
||||
assert_rejects route(:get, '/examples/1').
|
||||
to(:action => 'other', :id => '1'),
|
||||
@controller
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
31
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/set_session_matcher_test.rb
vendored
Normal file
31
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/set_session_matcher_test.rb
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class SetSessionMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a controller that sets a session variable" do
|
||||
setup do
|
||||
@controller = build_response { session[:var] = 'value' }
|
||||
end
|
||||
|
||||
should "accept assigning to that variable" do
|
||||
assert_accepts set_session(:var), @controller
|
||||
end
|
||||
|
||||
should "accept assigning the correct value to that variable" do
|
||||
assert_accepts set_session(:var).to('value'), @controller
|
||||
end
|
||||
|
||||
should "reject assigning another value to that variable" do
|
||||
assert_rejects set_session(:var).to('other'), @controller
|
||||
end
|
||||
|
||||
should "reject assigning to another variable" do
|
||||
assert_rejects set_session(:other), @controller
|
||||
end
|
||||
|
||||
should "accept assigning nil to another variable" do
|
||||
assert_accepts set_session(:other).to(nil), @controller
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
41
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/set_the_flash_matcher.rb
vendored
Normal file
41
vendor/gems/thoughtbot-shoulda-2.10.1/test/matchers/controller/set_the_flash_matcher.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class SetTheFlashMatcherTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "a controller that sets a flash message" do
|
||||
setup do
|
||||
@controller = build_response { flash[:notice] = 'value' }
|
||||
end
|
||||
|
||||
should "accept setting any flash message" do
|
||||
assert_accepts set_the_flash, @controller
|
||||
end
|
||||
|
||||
should "accept setting the exact flash message" do
|
||||
assert_accepts set_the_flash.to('value'), @controller
|
||||
end
|
||||
|
||||
should "accept setting a matched flash message" do
|
||||
assert_accepts set_the_flash.to(/value/), @controller
|
||||
end
|
||||
|
||||
should "reject setting a different flash message" do
|
||||
assert_rejects set_the_flash.to('other'), @controller
|
||||
end
|
||||
|
||||
should "reject setting a different pattern" do
|
||||
assert_rejects set_the_flash.to(/other/), @controller
|
||||
end
|
||||
end
|
||||
|
||||
context "a controller that doesn't set a flash message" do
|
||||
setup do
|
||||
@controller = build_response
|
||||
end
|
||||
|
||||
should "reject setting any flash message" do
|
||||
assert_rejects set_the_flash, @controller
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
106
vendor/gems/thoughtbot-shoulda-2.10.1/test/model_builder.rb
vendored
Normal file
106
vendor/gems/thoughtbot-shoulda-2.10.1/test/model_builder.rb
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
class Test::Unit::TestCase
|
||||
def create_table(table_name, &block)
|
||||
connection = ActiveRecord::Base.connection
|
||||
|
||||
begin
|
||||
connection.execute("DROP TABLE IF EXISTS #{table_name}")
|
||||
connection.create_table(table_name, &block)
|
||||
@created_tables ||= []
|
||||
@created_tables << table_name
|
||||
connection
|
||||
rescue Exception => e
|
||||
connection.execute("DROP TABLE IF EXISTS #{table_name}")
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
def define_constant(class_name, base, &block)
|
||||
class_name = class_name.to_s.camelize
|
||||
|
||||
klass = Class.new(base)
|
||||
Object.const_set(class_name, klass)
|
||||
|
||||
klass.class_eval(&block) if block_given?
|
||||
|
||||
@defined_constants ||= []
|
||||
@defined_constants << class_name
|
||||
|
||||
klass
|
||||
end
|
||||
|
||||
def define_model_class(class_name, &block)
|
||||
define_constant(class_name, ActiveRecord::Base, &block)
|
||||
end
|
||||
|
||||
def define_model(name, columns = {}, &block)
|
||||
class_name = name.to_s.pluralize.classify
|
||||
table_name = class_name.tableize
|
||||
|
||||
create_table(table_name) do |table|
|
||||
columns.each do |name, type|
|
||||
table.column name, type
|
||||
end
|
||||
end
|
||||
|
||||
define_model_class(class_name, &block)
|
||||
end
|
||||
|
||||
def define_controller(class_name, &block)
|
||||
class_name = class_name.to_s
|
||||
class_name << 'Controller' unless class_name =~ /Controller$/
|
||||
define_constant(class_name, ActionController::Base, &block)
|
||||
end
|
||||
|
||||
def define_routes(&block)
|
||||
@replaced_routes = ActionController::Routing::Routes
|
||||
new_routes = ActionController::Routing::RouteSet.new
|
||||
silence_warnings do
|
||||
ActionController::Routing.const_set('Routes', new_routes)
|
||||
end
|
||||
new_routes.draw(&block)
|
||||
end
|
||||
|
||||
def build_response(&block)
|
||||
klass = define_controller('Examples')
|
||||
block ||= lambda { render :nothing => true }
|
||||
klass.class_eval { define_method(:example, &block) }
|
||||
define_routes do |map|
|
||||
map.connect 'examples', :controller => 'examples', :action => 'example'
|
||||
end
|
||||
|
||||
@controller = klass.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
get :example
|
||||
|
||||
@controller
|
||||
end
|
||||
|
||||
def teardown_with_models
|
||||
if @defined_constants
|
||||
@defined_constants.each do |class_name|
|
||||
Object.send(:remove_const, class_name)
|
||||
end
|
||||
end
|
||||
|
||||
if @created_tables
|
||||
@created_tables.each do |table_name|
|
||||
ActiveRecord::Base.
|
||||
connection.
|
||||
execute("DROP TABLE IF EXISTS #{table_name}")
|
||||
end
|
||||
end
|
||||
|
||||
if @replaced_routes
|
||||
ActionController::Routing::Routes.clear!
|
||||
silence_warnings do
|
||||
ActionController::Routing.const_set('Routes', @replaced_routes)
|
||||
end
|
||||
@replaced_routes.reload!
|
||||
end
|
||||
|
||||
teardown_without_models
|
||||
end
|
||||
alias_method :teardown_without_models, :teardown
|
||||
alias_method :teardown, :teardown_with_models
|
||||
end
|
||||
18
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/autoload_macro_test.rb
vendored
Normal file
18
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/autoload_macro_test.rb
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
||||
|
||||
class AutoloadMacroTest < Test::Unit::TestCase # :nodoc:
|
||||
context "The macro auto-loader" do
|
||||
should "load macros from the plugins" do
|
||||
assert self.class.respond_to?('plugin_macro')
|
||||
end
|
||||
|
||||
should "load macros from the gems" do
|
||||
assert self.class.respond_to?('gem_macro')
|
||||
end
|
||||
|
||||
should "load custom macros from ROOT/test/shoulda_macros" do
|
||||
assert self.class.respond_to?('custom_macro')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
145
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/context_test.rb
vendored
Normal file
145
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/context_test.rb
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
||||
|
||||
class ContextTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
def self.context_macro(&blk)
|
||||
context "with a subcontext made by a macro" do
|
||||
setup { @context_macro = :foo }
|
||||
|
||||
merge_block &blk
|
||||
end
|
||||
end
|
||||
|
||||
# def self.context_macro(&blk)
|
||||
# context "with a subcontext made by a macro" do
|
||||
# setup { @context_macro = :foo }
|
||||
# yield # <- this doesn't work.
|
||||
# end
|
||||
# end
|
||||
|
||||
context "context with setup block" do
|
||||
setup do
|
||||
@blah = "blah"
|
||||
end
|
||||
|
||||
should "run the setup block" do
|
||||
assert_equal "blah", @blah
|
||||
end
|
||||
|
||||
should "have name set right" do
|
||||
assert_match(/^test: context with setup block/, self.to_s)
|
||||
end
|
||||
|
||||
context "and a subcontext" do
|
||||
setup do
|
||||
@blah = "#{@blah} twice"
|
||||
end
|
||||
|
||||
should "be named correctly" do
|
||||
assert_match(/^test: context with setup block and a subcontext should be named correctly/, self.to_s)
|
||||
end
|
||||
|
||||
should "run the setup blocks in order" do
|
||||
assert_equal @blah, "blah twice"
|
||||
end
|
||||
end
|
||||
|
||||
context_macro do
|
||||
should "have name set right" do
|
||||
assert_match(/^test: context with setup block with a subcontext made by a macro should have name set right/, self.to_s)
|
||||
end
|
||||
|
||||
should "run the setup block of that context macro" do
|
||||
assert_equal :foo, @context_macro
|
||||
end
|
||||
|
||||
should "run the setup block of the main context" do
|
||||
assert_equal "blah", @blah
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "another context with setup block" do
|
||||
setup do
|
||||
@blah = "foo"
|
||||
end
|
||||
|
||||
should "have @blah == 'foo'" do
|
||||
assert_equal "foo", @blah
|
||||
end
|
||||
|
||||
should "have name set right" do
|
||||
assert_match(/^test: another context with setup block/, self.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
context "context with method definition" do
|
||||
setup do
|
||||
def hello; "hi"; end
|
||||
end
|
||||
|
||||
should "be able to read that method" do
|
||||
assert_equal "hi", hello
|
||||
end
|
||||
|
||||
should "have name set right" do
|
||||
assert_match(/^test: context with method definition/, self.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
context "another context" do
|
||||
should "not define @blah" do
|
||||
assert_nil @blah
|
||||
end
|
||||
end
|
||||
|
||||
context "context with multiple setups and/or teardowns" do
|
||||
|
||||
cleanup_count = 0
|
||||
|
||||
2.times do |i|
|
||||
setup { cleanup_count += 1 }
|
||||
teardown { cleanup_count -= 1 }
|
||||
end
|
||||
|
||||
2.times do |i|
|
||||
should "call all setups and all teardowns (check ##{i + 1})" do
|
||||
assert_equal 2, cleanup_count
|
||||
end
|
||||
end
|
||||
|
||||
context "subcontexts" do
|
||||
|
||||
2.times do |i|
|
||||
setup { cleanup_count += 1 }
|
||||
teardown { cleanup_count -= 1 }
|
||||
end
|
||||
|
||||
2.times do |i|
|
||||
should "also call all setups and all teardowns in parent and subcontext (check ##{i + 1})" do
|
||||
assert_equal 4, cleanup_count
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
should_eventually "pass, since it's unimplemented" do
|
||||
flunk "what?"
|
||||
end
|
||||
|
||||
should_eventually "not require a block when using should_eventually"
|
||||
should "pass without a block, as that causes it to piggyback to should_eventually"
|
||||
|
||||
context "context for testing should piggybacking" do
|
||||
should "call should_eventually as we are not passing a block"
|
||||
end
|
||||
|
||||
context "context" do
|
||||
context "with nested subcontexts" do
|
||||
should_eventually "only print this statement once for a should_eventually"
|
||||
end
|
||||
end
|
||||
end
|
||||
63
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/convert_to_should_syntax_test.rb
vendored
Normal file
63
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/convert_to_should_syntax_test.rb
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
require 'test/unit'
|
||||
|
||||
class ConvertToShouldSyntaxTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
BEFORE_FIXTURE = <<-EOS
|
||||
class DummyTest < Test::Unit::TestCase
|
||||
|
||||
should "Not change this_word_with_underscores" do
|
||||
end
|
||||
|
||||
def test_should_be_working
|
||||
assert true
|
||||
end
|
||||
|
||||
def test_some_cool_stuff
|
||||
assert true
|
||||
end
|
||||
|
||||
def non_test_method
|
||||
end
|
||||
|
||||
end
|
||||
EOS
|
||||
|
||||
AFTER_FIXTURE = <<-EOS
|
||||
class DummyTest < Test::Unit::TestCase
|
||||
|
||||
should "Not change this_word_with_underscores" do
|
||||
end
|
||||
|
||||
should "be working" do
|
||||
assert true
|
||||
end
|
||||
|
||||
should "RENAME ME: test some cool stuff" do
|
||||
assert true
|
||||
end
|
||||
|
||||
def non_test_method
|
||||
end
|
||||
|
||||
end
|
||||
EOS
|
||||
|
||||
FIXTURE_PATH = "./convert_to_should_syntax_fixture.dat"
|
||||
|
||||
RUBY = ENV['RUBY'] || 'ruby'
|
||||
|
||||
def test_convert_to_should_syntax
|
||||
File.open(FIXTURE_PATH, "w") {|f| f.write(BEFORE_FIXTURE)}
|
||||
cmd = "#{RUBY} #{File.join(File.dirname(__FILE__), '../../bin/convert_to_should_syntax')} #{FIXTURE_PATH}"
|
||||
output = `#{cmd}`
|
||||
File.unlink($1) if output.match(/has been stored in '([^']+)/)
|
||||
assert_match(/has been converted/, output)
|
||||
result = IO.read(FIXTURE_PATH)
|
||||
assert_equal result, AFTER_FIXTURE
|
||||
end
|
||||
|
||||
def teardown
|
||||
File.unlink(FIXTURE_PATH)
|
||||
end
|
||||
|
||||
end
|
||||
241
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/helpers_test.rb
vendored
Normal file
241
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/helpers_test.rb
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
||||
require 'action_mailer'
|
||||
require 'mocha'
|
||||
|
||||
class HelpersTest < Test::Unit::TestCase # :nodoc:
|
||||
|
||||
context "given delivered emails" do
|
||||
setup do
|
||||
email1 = stub(:subject => "one", :to => ["none1@email.com"])
|
||||
email2 = stub(:subject => "two", :to => ["none2@email.com"])
|
||||
ActionMailer::Base.stubs(:deliveries).returns([email1, email2])
|
||||
end
|
||||
|
||||
should "have sent an email" do
|
||||
assert_sent_email
|
||||
|
||||
assert_raises(Test::Unit::AssertionFailedError) do
|
||||
assert_did_not_send_email
|
||||
end
|
||||
end
|
||||
|
||||
should "find email one" do
|
||||
assert_sent_email do |e|
|
||||
e.subject =~ /one/
|
||||
end
|
||||
end
|
||||
|
||||
should "not find an email that doesn't exist" do
|
||||
assert_raises(Test::Unit::AssertionFailedError) do
|
||||
assert_sent_email do |e|
|
||||
e.subject =~ /whatever/
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are no emails" do
|
||||
setup do
|
||||
ActionMailer::Base.stubs(:deliveries).returns([])
|
||||
end
|
||||
|
||||
should "not have sent an email" do
|
||||
assert_did_not_send_email
|
||||
|
||||
assert_raises(Test::Unit::AssertionFailedError) do
|
||||
assert_sent_email
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "an array of values" do
|
||||
setup do
|
||||
@a = ['abc', 'def', 3]
|
||||
end
|
||||
|
||||
[/b/, 'abc', 3].each do |x|
|
||||
should "contain #{x.inspect}" do
|
||||
assert_raises(Test::Unit::AssertionFailedError) do
|
||||
assert_does_not_contain @a, x
|
||||
end
|
||||
assert_contains @a, x
|
||||
end
|
||||
end
|
||||
|
||||
should "not contain 'wtf'" do
|
||||
assert_raises(Test::Unit::AssertionFailedError) {assert_contains @a, 'wtf'}
|
||||
assert_does_not_contain @a, 'wtf'
|
||||
end
|
||||
|
||||
should "be the same as another array, ordered differently" do
|
||||
assert_same_elements(@a, [3, "def", "abc"])
|
||||
assert_raises(Test::Unit::AssertionFailedError) do
|
||||
assert_same_elements(@a, [3, 3, "def", "abc"])
|
||||
end
|
||||
assert_raises(Test::Unit::AssertionFailedError) do
|
||||
assert_same_elements([@a, "abc"].flatten, [3, 3, "def", "abc"])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "an array of values" do
|
||||
setup do
|
||||
@a = [1, 2, "(3)"]
|
||||
end
|
||||
|
||||
context "after adding another value" do
|
||||
setup do
|
||||
@a.push(4)
|
||||
end
|
||||
|
||||
should_change "@a.length", :by => 1
|
||||
should_change "@a.length", :from => 3
|
||||
should_change "@a.length", :to => 4
|
||||
should_change "@a[0]", :by => 0
|
||||
should_not_change "@a[0]"
|
||||
end
|
||||
|
||||
context "after replacing it with an array of strings" do
|
||||
setup do
|
||||
@a = %w(a b c d e f)
|
||||
end
|
||||
|
||||
should_change "@a.length", :by => 3
|
||||
should_change "@a.length", :from => 3, :to => 6, :by => 3
|
||||
should_change "@a[0]"
|
||||
should_change "@a[1]", :from => 2, :to => "b"
|
||||
should_change "@a[2]", :from => /\d/, :to => /\w/
|
||||
should_change "@a[3]", :to => String
|
||||
end
|
||||
end
|
||||
|
||||
context "assert_good_value" do
|
||||
should "validate a good email address" do
|
||||
assert_good_value User.new, :email, "good@example.com"
|
||||
end
|
||||
|
||||
should "validate a good SSN with a custom message" do
|
||||
assert_good_value User.new, :ssn, "xxxxxxxxx", /length/
|
||||
end
|
||||
|
||||
should "fail to validate a bad email address" do
|
||||
assert_raises Test::Unit::AssertionFailedError do
|
||||
assert_good_value User.new, :email, "bad"
|
||||
end
|
||||
end
|
||||
|
||||
should "fail to validate a bad SSN that is too short" do
|
||||
assert_raises Test::Unit::AssertionFailedError do
|
||||
assert_good_value User.new, :ssn, "x", /length/
|
||||
end
|
||||
end
|
||||
|
||||
should "accept a class as the first argument" do
|
||||
assert_good_value User, :email, "good@example.com"
|
||||
end
|
||||
|
||||
context "with an instance variable" do
|
||||
setup do
|
||||
@product = Product.new(:tangible => true)
|
||||
end
|
||||
|
||||
should "use that instance variable" do
|
||||
assert_good_value Product, :price, "9999", /included/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "assert_bad_value" do
|
||||
should "invalidate a bad email address" do
|
||||
assert_bad_value User.new, :email, "bad"
|
||||
end
|
||||
|
||||
should "invalidate a bad SSN with a custom message" do
|
||||
assert_bad_value User.new, :ssn, "x", /length/
|
||||
end
|
||||
|
||||
should "fail to invalidate a good email address" do
|
||||
assert_raises Test::Unit::AssertionFailedError do
|
||||
assert_bad_value User.new, :email, "good@example.com"
|
||||
end
|
||||
end
|
||||
|
||||
should "fail to invalidate a good SSN" do
|
||||
assert_raises Test::Unit::AssertionFailedError do
|
||||
assert_bad_value User.new, :ssn, "xxxxxxxxx", /length/
|
||||
end
|
||||
end
|
||||
|
||||
should "accept a class as the first argument" do
|
||||
assert_bad_value User, :email, "bad"
|
||||
end
|
||||
|
||||
context "with an instance variable" do
|
||||
setup do
|
||||
@product = Product.new(:tangible => true)
|
||||
end
|
||||
|
||||
should "use that instance variable" do
|
||||
assert_bad_value Product, :price, "0", /included/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "a matching matcher" do
|
||||
setup do
|
||||
@matcher = stub('matcher', :matches? => true,
|
||||
:failure_message => 'bad failure message',
|
||||
:negative_failure_message => 'big time failure')
|
||||
end
|
||||
|
||||
should "pass when given to assert_accepts" do
|
||||
assert_accepts @matcher, 'target'
|
||||
end
|
||||
|
||||
context "when given to assert_rejects" do
|
||||
setup do
|
||||
begin
|
||||
assert_rejects @matcher, 'target'
|
||||
rescue Test::Unit::AssertionFailedError => @error
|
||||
end
|
||||
end
|
||||
|
||||
should "fail" do
|
||||
assert_not_nil @error
|
||||
end
|
||||
|
||||
should "use the error message from the matcher" do
|
||||
assert_equal 'big time failure', @error.message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "a non-matching matcher" do
|
||||
setup do
|
||||
@matcher = stub('matcher', :matches? => false,
|
||||
:failure_message => 'big time failure',
|
||||
:negative_failure_message => 'bad failure message')
|
||||
end
|
||||
|
||||
should "pass when given to assert_rejects" do
|
||||
assert_rejects @matcher, 'target'
|
||||
end
|
||||
|
||||
context "when given to assert_accepts" do
|
||||
setup do
|
||||
begin
|
||||
assert_accepts @matcher, 'target'
|
||||
rescue Test::Unit::AssertionFailedError => @error
|
||||
end
|
||||
end
|
||||
|
||||
should "fail" do
|
||||
assert_not_nil @error
|
||||
end
|
||||
|
||||
should "use the error message from the matcher" do
|
||||
assert_equal 'big time failure', @error.message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
34
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/private_helpers_test.rb
vendored
Normal file
34
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/private_helpers_test.rb
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
||||
|
||||
class PrivateHelpersTest < Test::Unit::TestCase # :nodoc:
|
||||
include Shoulda::Private
|
||||
context "get_options!" do
|
||||
should "remove opts from args" do
|
||||
args = [:a, :b, {}]
|
||||
get_options!(args)
|
||||
assert_equal [:a, :b], args
|
||||
end
|
||||
|
||||
should "return wanted opts in order" do
|
||||
args = [{:one => 1, :two => 2}]
|
||||
one, two = get_options!(args, :one, :two)
|
||||
assert_equal 1, one
|
||||
assert_equal 2, two
|
||||
end
|
||||
|
||||
should "raise ArgumentError if given unwanted option" do
|
||||
args = [{:one => 1, :two => 2}]
|
||||
assert_raises ArgumentError do
|
||||
get_options!(args, :one)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ::SomeModel; end
|
||||
context "model_class" do
|
||||
should "sniff the class constant from the test class" do
|
||||
self.expects(:name).returns("SomeModelTest")
|
||||
assert_equal SomeModel, model_class
|
||||
end
|
||||
end
|
||||
end
|
||||
266
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/should_test.rb
vendored
Normal file
266
vendor/gems/thoughtbot-shoulda-2.10.1/test/other/should_test.rb
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
||||
|
||||
class ShouldTest < Test::Unit::TestCase # :nodoc:
|
||||
should "be able to define a should statement outside of a context" do
|
||||
assert true
|
||||
end
|
||||
|
||||
should "see the name of my class as ShouldTest" do
|
||||
assert_equal "ShouldTest", self.class.name
|
||||
end
|
||||
|
||||
def self.should_see_class_methods
|
||||
should "be able to see class methods" do
|
||||
assert true
|
||||
end
|
||||
end
|
||||
|
||||
def self.should_see_a_context_block_like_a_Test_Unit_class
|
||||
should "see a context block as a Test::Unit class" do
|
||||
assert_equal "ShouldTest", self.class.name
|
||||
end
|
||||
end
|
||||
|
||||
def self.should_see_blah
|
||||
should "see @blah through a macro" do
|
||||
assert @blah
|
||||
end
|
||||
end
|
||||
|
||||
def self.should_not_see_blah
|
||||
should "not see @blah through a macro" do
|
||||
assert_nil @blah
|
||||
end
|
||||
end
|
||||
|
||||
def self.should_be_able_to_make_context_macros(prefix = nil)
|
||||
context "a macro" do
|
||||
should "have the tests named correctly" do
|
||||
assert_match(/^test: #{prefix}a macro should have the tests named correctly/, self.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "Context" do
|
||||
|
||||
should_see_class_methods
|
||||
should_see_a_context_block_like_a_Test_Unit_class
|
||||
should_be_able_to_make_context_macros("Context ")
|
||||
|
||||
should "not define @blah" do
|
||||
assert ! self.instance_variables.include?("@blah")
|
||||
end
|
||||
|
||||
should_not_see_blah
|
||||
|
||||
should "be able to define a should statement" do
|
||||
assert true
|
||||
end
|
||||
|
||||
should "see the name of my class as ShouldTest" do
|
||||
assert_equal "ShouldTest", self.class.name
|
||||
end
|
||||
|
||||
context "with a subcontext" do
|
||||
should_be_able_to_make_context_macros("Context with a subcontext ")
|
||||
end
|
||||
end
|
||||
|
||||
context "Context with setup block" do
|
||||
setup do
|
||||
@blah = "blah"
|
||||
end
|
||||
|
||||
should "have @blah == 'blah'" do
|
||||
assert_equal "blah", @blah
|
||||
end
|
||||
should_see_blah
|
||||
|
||||
should "have name set right" do
|
||||
assert_match(/^test: Context with setup block/, self.to_s)
|
||||
end
|
||||
|
||||
context "and a subcontext" do
|
||||
setup do
|
||||
@blah = "#{@blah} twice"
|
||||
end
|
||||
|
||||
should "be named correctly" do
|
||||
assert_match(/^test: Context with setup block and a subcontext should be named correctly/, self.to_s)
|
||||
end
|
||||
|
||||
should "run the setup methods in order" do
|
||||
assert_equal @blah, "blah twice"
|
||||
end
|
||||
should_see_blah
|
||||
end
|
||||
end
|
||||
|
||||
context "Another context with setup block" do
|
||||
setup do
|
||||
@blah = "foo"
|
||||
end
|
||||
|
||||
should "have @blah == 'foo'" do
|
||||
assert_equal "foo", @blah
|
||||
end
|
||||
|
||||
should "have name set right" do
|
||||
assert_match(/^test: Another context with setup block/, self.to_s)
|
||||
end
|
||||
should_see_blah
|
||||
end
|
||||
|
||||
should_eventually "pass, since it's a should_eventually" do
|
||||
flunk "what?"
|
||||
end
|
||||
|
||||
# Context creation and naming
|
||||
|
||||
def test_should_create_a_new_context
|
||||
assert_nothing_raised do
|
||||
Shoulda::Context.new("context name", self) do; end
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_create_a_nested_context
|
||||
assert_nothing_raised do
|
||||
parent = Shoulda::Context.new("Parent", self) do; end
|
||||
child = Shoulda::Context.new("Child", parent) do; end
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_name_a_contexts_correctly
|
||||
parent = Shoulda::Context.new("Parent", self) do; end
|
||||
child = Shoulda::Context.new("Child", parent) do; end
|
||||
grandchild = Shoulda::Context.new("GrandChild", child) do; end
|
||||
|
||||
assert_equal "Parent", parent.full_name
|
||||
assert_equal "Parent Child", child.full_name
|
||||
assert_equal "Parent Child GrandChild", grandchild.full_name
|
||||
end
|
||||
|
||||
# Should statements
|
||||
|
||||
def test_should_have_should_hashes_when_given_should_statements
|
||||
context = Shoulda::Context.new("name", self) do
|
||||
should "be good" do; end
|
||||
should "another" do; end
|
||||
end
|
||||
|
||||
names = context.shoulds.map {|s| s[:name]}
|
||||
assert_equal ["another", "be good"], names.sort
|
||||
end
|
||||
|
||||
# setup and teardown
|
||||
|
||||
def test_should_capture_setup_and_teardown_blocks
|
||||
context = Shoulda::Context.new("name", self) do
|
||||
setup do; "setup"; end
|
||||
teardown do; "teardown"; end
|
||||
end
|
||||
|
||||
assert_equal "setup", context.setup_blocks.first.call
|
||||
assert_equal "teardown", context.teardown_blocks.first.call
|
||||
end
|
||||
|
||||
# building
|
||||
|
||||
def test_should_create_shoulda_test_for_each_should_on_build
|
||||
context = Shoulda::Context.new("name", self) do
|
||||
should "one" do; end
|
||||
should "two" do; end
|
||||
end
|
||||
context.expects(:create_test_from_should_hash).with(has_entry(:name => "one"))
|
||||
context.expects(:create_test_from_should_hash).with(has_entry(:name => "two"))
|
||||
context.build
|
||||
end
|
||||
|
||||
def test_should_create_test_methods_on_build
|
||||
tu_class = Test::Unit::TestCase
|
||||
context = Shoulda::Context.new("A Context", tu_class) do
|
||||
should "define the test" do; end
|
||||
end
|
||||
|
||||
tu_class.expects(:define_method).with(:"test: A Context should define the test. ")
|
||||
context.build
|
||||
end
|
||||
|
||||
def test_should_create_test_methods_on_build_when_subcontext
|
||||
tu_class = Test::Unit::TestCase
|
||||
context = Shoulda::Context.new("A Context", tu_class) do
|
||||
context "with a child" do
|
||||
should "define the test" do; end
|
||||
end
|
||||
end
|
||||
|
||||
tu_class.expects(:define_method).with(:"test: A Context with a child should define the test. ")
|
||||
context.build
|
||||
end
|
||||
|
||||
# Test::Unit integration
|
||||
|
||||
def test_should_create_a_new_context_and_build_it_on_Test_Unit_context
|
||||
c = mock("context")
|
||||
c.expects(:build)
|
||||
Shoulda::Context.expects(:new).with("foo", kind_of(Class)).returns(c)
|
||||
self.class.context "foo" do; end
|
||||
end
|
||||
|
||||
def test_should_create_a_one_off_context_and_build_it_on_Test_Unit_should
|
||||
s = mock("test")
|
||||
Shoulda::Context.any_instance.expects(:should).with("rock", {}).returns(s)
|
||||
Shoulda::Context.any_instance.expects(:build)
|
||||
self.class.should "rock" do; end
|
||||
end
|
||||
|
||||
def test_should_create_a_one_off_context_and_build_it_on_Test_Unit_should_eventually
|
||||
s = mock("test")
|
||||
Shoulda::Context.any_instance.expects(:should_eventually).with("rock").returns(s)
|
||||
Shoulda::Context.any_instance.expects(:build)
|
||||
self.class.should_eventually "rock" do; end
|
||||
end
|
||||
|
||||
should "run a :before proc", :before => lambda { @value = "before" } do
|
||||
assert_equal "before", @value
|
||||
end
|
||||
|
||||
context "A :before proc" do
|
||||
setup do
|
||||
assert_equal "before", @value
|
||||
@value = "setup"
|
||||
end
|
||||
|
||||
should "run before the current setup", :before => lambda { @value = "before" } do
|
||||
assert_equal "setup", @value
|
||||
end
|
||||
end
|
||||
|
||||
context "a before statement" do
|
||||
setup do
|
||||
assert_equal "before", @value
|
||||
@value = "setup"
|
||||
end
|
||||
|
||||
before_should "run before the current setup" do
|
||||
@value = "before"
|
||||
end
|
||||
end
|
||||
|
||||
context "A context" do
|
||||
setup do
|
||||
@value = "outer"
|
||||
end
|
||||
|
||||
context "with a subcontext and a :before proc" do
|
||||
before = lambda do
|
||||
assert "outer", @value
|
||||
@value = "before"
|
||||
end
|
||||
should "run after the parent setup", :before => before do
|
||||
assert_equal "before", @value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
25
vendor/gems/thoughtbot-shoulda-2.10.1/test/rails_root/app/controllers/application.rb
vendored
Normal file
25
vendor/gems/thoughtbot-shoulda-2.10.1/test/rails_root/app/controllers/application.rb
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Filters added to this controller apply to all controllers in the application.
|
||||
# Likewise, all the methods added will be available for all controllers.
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
# Pick a unique cookie name to distinguish our session data from others'
|
||||
session :session_key => '_rails_root_session_id'
|
||||
|
||||
def ensure_logged_in
|
||||
unless session[:logged_in]
|
||||
respond_to do |accepts|
|
||||
accepts.html do
|
||||
flash[:error] = 'What do you think you\'re doing?'
|
||||
redirect_to '/'
|
||||
end
|
||||
accepts.xml do
|
||||
headers["Status"] = "Unauthorized"
|
||||
headers["WWW-Authenticate"] = %(Basic realm="Web Password")
|
||||
render :text => "Couldn't authenticate you", :status => '401 Unauthorized'
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
86
vendor/gems/thoughtbot-shoulda-2.10.1/test/rails_root/app/controllers/posts_controller.rb
vendored
Normal file
86
vendor/gems/thoughtbot-shoulda-2.10.1/test/rails_root/app/controllers/posts_controller.rb
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
class PostsController < ApplicationController
|
||||
before_filter :ensure_logged_in
|
||||
before_filter :load_user
|
||||
|
||||
def index
|
||||
@posts = @user.posts
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.rhtml
|
||||
format.xml { render :xml => @posts.to_xml }
|
||||
format.rss do
|
||||
headers['Content-Type'] = 'application/rss+xml'
|
||||
session[:special] = '$2 off your next purchase'
|
||||
session[:special_user_id] = @user.id
|
||||
head :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@post = @user.posts.find(params[:id])
|
||||
@false_flag = false
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :layout => 'wide' }
|
||||
format.xml { render :xml => @post.to_xml }
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@post = @user.posts.build
|
||||
render :layout => false
|
||||
end
|
||||
|
||||
def edit
|
||||
@post = @user.posts.find(params[:id])
|
||||
end
|
||||
|
||||
def create
|
||||
@post = @user.posts.build(params[:post])
|
||||
|
||||
respond_to do |format|
|
||||
if @post.save
|
||||
flash[:notice] = 'Post was successfully created.'
|
||||
format.html { redirect_to user_post_url(@post.user, @post) }
|
||||
format.xml { head :created, :location => user_post_url(@post.user, @post) }
|
||||
else
|
||||
format.html { render :action => "new" }
|
||||
format.xml { render :xml => @post.errors.to_xml }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@post = @user.posts.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @post.update_attributes(params[:post])
|
||||
flash[:notice] = 'Post was successfully updated.'
|
||||
format.html { redirect_to user_post_url(@post.user, @post) }
|
||||
format.xml { head :ok }
|
||||
else
|
||||
format.html { render :action => "edit" }
|
||||
format.xml { render :xml => @post.errors.to_xml }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@post = @user.posts.find(params[:id])
|
||||
@post.destroy
|
||||
|
||||
flash[:notice] = "Post was removed"
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to user_posts_url(@post.user) }
|
||||
format.xml { head :ok }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_user
|
||||
@user = User.find(params[:user_id])
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user