mcmire-shoulda-matchers 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +32 -0
- data/.yardopts +7 -0
- data/Appraisals +45 -0
- data/CONTRIBUTING.md +41 -0
- data/Gemfile +31 -0
- data/Gemfile.lock +166 -0
- data/MIT-LICENSE +22 -0
- data/NEWS.md +299 -0
- data/README.md +163 -0
- data/Rakefile +116 -0
- data/doc_config/gh-pages/index.html.erb +9 -0
- data/doc_config/yard/setup.rb +22 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +5967 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/full_list.css +12 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/global.css +45 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/solarized.css +69 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/style.css +283 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +32 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list_class.erb +1 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list_method.erb +8 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/app.js +300 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/full_list.js +1 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/jquery.stickyheaders.js +289 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/underscore.min.js +6 -0
- data/doc_config/yard/templates/default/fulldoc/html/setup.rb +8 -0
- data/doc_config/yard/templates/default/layout/html/breadcrumb.erb +14 -0
- data/doc_config/yard/templates/default/layout/html/fonts.erb +1 -0
- data/doc_config/yard/templates/default/layout/html/layout.erb +23 -0
- data/doc_config/yard/templates/default/layout/html/search.erb +13 -0
- data/doc_config/yard/templates/default/layout/html/setup.rb +8 -0
- data/doc_config/yard/templates/default/method_details/html/source.erb +10 -0
- data/doc_config/yard/templates/default/module/html/box_info.erb +31 -0
- data/features/rails_integration.feature +113 -0
- data/features/step_definitions/rails_steps.rb +162 -0
- data/features/support/env.rb +5 -0
- data/gemfiles/3.0.gemfile +24 -0
- data/gemfiles/3.0.gemfile.lock +150 -0
- data/gemfiles/3.1.gemfile +27 -0
- data/gemfiles/3.1.gemfile.lock +173 -0
- data/gemfiles/3.2.gemfile +27 -0
- data/gemfiles/3.2.gemfile.lock +171 -0
- data/gemfiles/4.0.0.gemfile +28 -0
- data/gemfiles/4.0.0.gemfile.lock +172 -0
- data/gemfiles/4.0.1.gemfile +28 -0
- data/gemfiles/4.0.1.gemfile.lock +172 -0
- data/lib/shoulda-matchers.rb +1 -0
- data/lib/shoulda/matchers.rb +11 -0
- data/lib/shoulda/matchers/action_controller.rb +17 -0
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +64 -0
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +97 -0
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +81 -0
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +117 -0
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +114 -0
- data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +154 -0
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +116 -0
- data/lib/shoulda/matchers/action_controller/route_params.rb +48 -0
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +164 -0
- data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +296 -0
- data/lib/shoulda/matchers/active_model.rb +30 -0
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +167 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +314 -0
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +46 -0
- data/lib/shoulda/matchers/active_model/ensure_exclusion_of_matcher.rb +160 -0
- data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +417 -0
- data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +337 -0
- data/lib/shoulda/matchers/active_model/errors.rb +10 -0
- data/lib/shoulda/matchers/active_model/exception_message_finder.rb +58 -0
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +92 -0
- data/lib/shoulda/matchers/active_model/helpers.rb +46 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers.rb +9 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +75 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +27 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +27 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +26 -0
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +112 -0
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +77 -0
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +121 -0
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +380 -0
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +89 -0
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +372 -0
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +97 -0
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +69 -0
- data/lib/shoulda/matchers/active_record.rb +22 -0
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +204 -0
- data/lib/shoulda/matchers/active_record/association_matcher.rb +901 -0
- data/lib/shoulda/matchers/active_record/association_matchers.rb +9 -0
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +81 -0
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +65 -0
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +94 -0
- data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +63 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +261 -0
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +149 -0
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +72 -0
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +181 -0
- data/lib/shoulda/matchers/assertion_error.rb +19 -0
- data/lib/shoulda/matchers/error.rb +6 -0
- data/lib/shoulda/matchers/integrations/rspec.rb +20 -0
- data/lib/shoulda/matchers/integrations/test_unit.rb +30 -0
- data/lib/shoulda/matchers/rails_shim.rb +50 -0
- data/lib/shoulda/matchers/version.rb +6 -0
- data/lib/shoulda/matchers/warn.rb +8 -0
- data/shoulda-matchers.gemspec +23 -0
- data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +22 -0
- data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +42 -0
- data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +78 -0
- data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +63 -0
- data/spec/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +63 -0
- data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +31 -0
- data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +70 -0
- data/spec/shoulda/matchers/action_controller/route_params_spec.rb +30 -0
- data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +51 -0
- data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +153 -0
- data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +111 -0
- data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +170 -0
- data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +81 -0
- data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +95 -0
- data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +320 -0
- data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +166 -0
- data/spec/shoulda/matchers/active_model/exception_message_finder_spec.rb +111 -0
- data/spec/shoulda/matchers/active_model/have_secure_password_matcher_spec.rb +20 -0
- data/spec/shoulda/matchers/active_model/helpers_spec.rb +158 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +169 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +59 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +59 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +57 -0
- data/spec/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +139 -0
- data/spec/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +41 -0
- data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +47 -0
- data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +331 -0
- data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +180 -0
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +398 -0
- data/spec/shoulda/matchers/active_model/validation_message_finder_spec.rb +127 -0
- data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +107 -0
- data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +860 -0
- data/spec/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +247 -0
- data/spec/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +111 -0
- data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +78 -0
- data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +41 -0
- data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +86 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/active_model_versions.rb +13 -0
- data/spec/support/active_resource_builder.rb +29 -0
- data/spec/support/activemodel_helpers.rb +19 -0
- data/spec/support/capture_helpers.rb +19 -0
- data/spec/support/class_builder.rb +42 -0
- data/spec/support/controller_builder.rb +74 -0
- data/spec/support/fail_with_message_including_matcher.rb +33 -0
- data/spec/support/fail_with_message_matcher.rb +32 -0
- data/spec/support/i18n_faker.rb +10 -0
- data/spec/support/mailer_builder.rb +10 -0
- data/spec/support/model_builder.rb +81 -0
- data/spec/support/rails_versions.rb +18 -0
- data/spec/support/shared_examples/numerical_submatcher.rb +19 -0
- data/spec/support/shared_examples/numerical_type_submatcher.rb +17 -0
- data/spec/support/test_application.rb +120 -0
- data/yard.watchr +5 -0
- metadata +281 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shoulda::Matchers::ActiveRecord::SerializeMatcher do
|
4
|
+
it 'accepts when the attribute is serialized' do
|
5
|
+
expect(with_serialized_attr).to serialize(:attr)
|
6
|
+
end
|
7
|
+
|
8
|
+
context 'when attribute is not serialized' do
|
9
|
+
it 'rejects' do
|
10
|
+
expect(unserialized_model).not_to serialize(:attr)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'assigns a helpful failure message' do
|
14
|
+
matcher = serialize(:attr)
|
15
|
+
|
16
|
+
matcher.matches?(unserialized_model)
|
17
|
+
|
18
|
+
expect(matcher.failure_message).to match(/to serialize the attribute called :attr/)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'assigns a helpful failure message when using #as' do
|
22
|
+
matcher = serialize(:attr).as(Hash)
|
23
|
+
|
24
|
+
matcher.matches?(unserialized_model)
|
25
|
+
|
26
|
+
expect(matcher.failure_message).to match(/with a type of Hash/)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'assigns a helpful failure message when using #as_instance_of' do
|
30
|
+
matcher = serialize(:attr).as_instance_of(Hash)
|
31
|
+
|
32
|
+
matcher.matches?(unserialized_model)
|
33
|
+
|
34
|
+
expect(matcher.failure_message).to match(/with an instance of Hash/)
|
35
|
+
end
|
36
|
+
|
37
|
+
def unserialized_model
|
38
|
+
@model ||= define_model(:example, attr: :string).new
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'an attribute that is serialized as a specific type' do
|
43
|
+
it 'accepts when the types match' do
|
44
|
+
expect(with_serialized_attr(Hash)).to serialize(:attr).as(Hash)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'rejects when the types do not match' do
|
48
|
+
expect(with_serialized_attr(Hash)).not_to serialize(:attr).as(String)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'rejects when using as_instance_of' do
|
52
|
+
expect(with_serialized_attr(Hash)).not_to serialize(:attr).as_instance_of(Hash)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'a serializer that is an instance of a class' do
|
57
|
+
it 'accepts when using #as_instance_of' do
|
58
|
+
define_serializer(:ExampleSerializer)
|
59
|
+
expect(with_serialized_attr(ExampleSerializer.new)).
|
60
|
+
to serialize(:attr).as_instance_of(ExampleSerializer)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'rejects when using #as' do
|
64
|
+
define_serializer(:ExampleSerializer)
|
65
|
+
expect(with_serialized_attr(ExampleSerializer.new)).
|
66
|
+
not_to serialize(:attr).as(ExampleSerializer)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def with_serialized_attr(type = nil)
|
71
|
+
define_model(:example, attr: :string) do
|
72
|
+
if type
|
73
|
+
serialize :attr, type
|
74
|
+
else
|
75
|
+
serialize :attr
|
76
|
+
end
|
77
|
+
end.new
|
78
|
+
end
|
79
|
+
|
80
|
+
def define_serializer(name)
|
81
|
+
define_class(name) do
|
82
|
+
def load(*); end
|
83
|
+
def dump(*); end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path('../support/test_application', __FILE__)
|
2
|
+
|
3
|
+
$test_app = TestApplication.new
|
4
|
+
$test_app.create
|
5
|
+
$test_app.load
|
6
|
+
|
7
|
+
ENV['BUNDLE_GEMFILE'] ||= app.gemfile_path
|
8
|
+
ENV['RAILS_ENV'] = 'test'
|
9
|
+
|
10
|
+
require 'bourne'
|
11
|
+
require 'shoulda-matchers'
|
12
|
+
require 'rspec/rails'
|
13
|
+
|
14
|
+
PROJECT_ROOT = File.expand_path('../..', __FILE__)
|
15
|
+
$LOAD_PATH << File.join(PROJECT_ROOT, 'lib')
|
16
|
+
Dir[ File.join(PROJECT_ROOT, 'spec/support/**/*.rb') ].each { |file| require file }
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.expect_with :rspec do |c|
|
20
|
+
c.syntax = :expect
|
21
|
+
end
|
22
|
+
|
23
|
+
config.mock_with :mocha
|
24
|
+
config.include Shoulda::Matchers::ActionController,
|
25
|
+
example_group: { file_path: /action_controller/ }
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
RSpec.configure do |c|
|
2
|
+
def active_model_3_1?
|
3
|
+
(::ActiveModel::VERSION::MAJOR == 3 && ::ActiveModel::VERSION::MINOR >= 1) || active_model_4_0?
|
4
|
+
end
|
5
|
+
|
6
|
+
def active_model_3_2?
|
7
|
+
(::ActiveModel::VERSION::MAJOR == 3 && ::ActiveModel::VERSION::MINOR >= 2) || active_model_4_0?
|
8
|
+
end
|
9
|
+
|
10
|
+
def active_model_4_0?
|
11
|
+
::ActiveModel::VERSION::MAJOR == 4
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'active_resource'
|
2
|
+
|
3
|
+
module ActiveResourceBuilder
|
4
|
+
def self.included(example_group)
|
5
|
+
example_group.class_eval do
|
6
|
+
after do
|
7
|
+
ActiveSupport::Dependencies.clear
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def define_active_resource_class(class_name, attributes = {}, &block)
|
13
|
+
define_class(class_name, ActiveResource::Base) do
|
14
|
+
schema do
|
15
|
+
attributes.each do |attr, type|
|
16
|
+
attribute attr, type
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if block_given?
|
21
|
+
class_eval(&block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
RSpec.configure do |config|
|
28
|
+
config.include ActiveResourceBuilder
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveModelHelpers
|
2
|
+
def custom_validation(&block)
|
3
|
+
define_model(:example, attr: :integer) do
|
4
|
+
validate :custom_validation
|
5
|
+
|
6
|
+
define_method(:custom_validation, &block)
|
7
|
+
end.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def validating_format(options)
|
11
|
+
define_model :example, attr: :string do
|
12
|
+
validates_format_of :attr, options
|
13
|
+
end.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.configure do |c|
|
18
|
+
c.include ActiveModelHelpers
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Kernel
|
2
|
+
unless method_defined?(:capture)
|
3
|
+
def capture(stream)
|
4
|
+
stream = stream.to_s
|
5
|
+
captured_stream = Tempfile.new(stream)
|
6
|
+
stream_io = eval("$#{stream}")
|
7
|
+
origin_stream = stream_io.dup
|
8
|
+
stream_io.reopen(captured_stream)
|
9
|
+
|
10
|
+
yield
|
11
|
+
|
12
|
+
stream_io.rewind
|
13
|
+
return captured_stream.read
|
14
|
+
ensure
|
15
|
+
captured_stream.unlink
|
16
|
+
stream_io.reopen(origin_stream)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module ClassBuilder
|
2
|
+
def self.included(example_group)
|
3
|
+
example_group.class_eval do
|
4
|
+
after do
|
5
|
+
teardown_defined_constants
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def define_class(class_name, base = Object, &block)
|
11
|
+
class_name = class_name.to_s.camelize
|
12
|
+
|
13
|
+
# FIXME: ActionMailer 3.2 calls `name.underscore` immediately upon
|
14
|
+
# subclassing. Class.new.name == nil. So, Class.new(ActionMailer::Base)
|
15
|
+
# errors out since it's trying to do `nil.underscore`. This is very ugly but
|
16
|
+
# allows us to test against ActionMailer 3.2.x.
|
17
|
+
eval <<-A_REAL_CLASS_FOR_ACTION_MAILER_3_2
|
18
|
+
class ::#{class_name} < #{base}
|
19
|
+
end
|
20
|
+
A_REAL_CLASS_FOR_ACTION_MAILER_3_2
|
21
|
+
|
22
|
+
Object.const_get(class_name).tap do |constant_class|
|
23
|
+
constant_class.unloadable
|
24
|
+
|
25
|
+
if block_given?
|
26
|
+
constant_class.class_eval(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
if constant_class.respond_to?(:reset_column_information)
|
30
|
+
constant_class.reset_column_information
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def teardown_defined_constants
|
36
|
+
ActiveSupport::Dependencies.clear
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
RSpec.configure do |config|
|
41
|
+
config.include ClassBuilder
|
42
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ControllerBuilder
|
2
|
+
def self.included(example_group)
|
3
|
+
example_group.class_eval do
|
4
|
+
after do
|
5
|
+
delete_temporary_views
|
6
|
+
restore_original_routes
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def define_controller(class_name, &block)
|
12
|
+
class_name = class_name.to_s
|
13
|
+
class_name << 'Controller' unless class_name =~ /Controller$/
|
14
|
+
define_class(class_name, ActionController::Base, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def define_routes(&block)
|
18
|
+
@routes = $test_app.draw_routes(&block)
|
19
|
+
class << self
|
20
|
+
include ActionDispatch::Assertions
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def build_response(opts = {}, &block)
|
25
|
+
action = opts[:action] || 'example'
|
26
|
+
partial = opts[:partial] || '_partial'
|
27
|
+
block ||= lambda { render nothing: true }
|
28
|
+
controller_class = define_controller('Examples') do
|
29
|
+
layout false
|
30
|
+
define_method(action, &block)
|
31
|
+
end
|
32
|
+
controller_class.view_paths = [ $test_app.temp_views_dir_path ]
|
33
|
+
|
34
|
+
define_routes do
|
35
|
+
get 'examples', to: "examples##{action}"
|
36
|
+
end
|
37
|
+
|
38
|
+
create_view("examples/#{action}.html.erb", 'action')
|
39
|
+
create_view("examples/#{partial}.html.erb", 'partial')
|
40
|
+
|
41
|
+
setup_rails_controller_test(controller_class)
|
42
|
+
get action
|
43
|
+
|
44
|
+
@controller
|
45
|
+
end
|
46
|
+
|
47
|
+
def setup_rails_controller_test(controller_class)
|
48
|
+
@controller = controller_class.new
|
49
|
+
@request = ::ActionController::TestRequest.new
|
50
|
+
@response = ::ActionController::TestResponse.new
|
51
|
+
|
52
|
+
class << self
|
53
|
+
include ActionController::TestCase::Behavior
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_view(path, contents)
|
58
|
+
$test_app.create_temp_view(path, contents)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def delete_temporary_views
|
64
|
+
$test_app.delete_temp_views
|
65
|
+
end
|
66
|
+
|
67
|
+
def restore_original_routes
|
68
|
+
Rails.application.reload_routes!
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
RSpec.configure do |config|
|
73
|
+
config.include ControllerBuilder
|
74
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
RSpec::Matchers.define :fail_with_message_including do |expected|
|
2
|
+
match do |block|
|
3
|
+
@actual = nil
|
4
|
+
|
5
|
+
begin
|
6
|
+
block.call
|
7
|
+
rescue RSpec::Expectations::ExpectationNotMetError => ex
|
8
|
+
@actual = ex.message
|
9
|
+
end
|
10
|
+
|
11
|
+
@actual && @actual.include?(expected)
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_for_should do
|
15
|
+
msg = "Expectation should have failed with message including '#{expected}'"
|
16
|
+
|
17
|
+
if @actual
|
18
|
+
msg << ", actually failed with '#{@actual}'"
|
19
|
+
else
|
20
|
+
msg << ", but did not fail."
|
21
|
+
end
|
22
|
+
|
23
|
+
msg
|
24
|
+
end
|
25
|
+
|
26
|
+
failure_message_for_should_not do
|
27
|
+
msg = "Expectation should not have failed with message including '#{expected}'"
|
28
|
+
msg << ", but did."
|
29
|
+
|
30
|
+
msg
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
RSpec::Matchers.define :fail_with_message do |expected|
|
2
|
+
match do |block|
|
3
|
+
@actual = nil
|
4
|
+
|
5
|
+
begin
|
6
|
+
block.call
|
7
|
+
rescue RSpec::Expectations::ExpectationNotMetError => ex
|
8
|
+
@actual = ex.message
|
9
|
+
end
|
10
|
+
|
11
|
+
@actual && @actual == expected
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_for_should do
|
15
|
+
msg = "Expectation should have failed with message '#{expected}'"
|
16
|
+
|
17
|
+
if @actual
|
18
|
+
msg << ", actually failed with '#{@actual}'"
|
19
|
+
else
|
20
|
+
msg << ", but did not fail."
|
21
|
+
end
|
22
|
+
|
23
|
+
msg
|
24
|
+
end
|
25
|
+
|
26
|
+
failure_message_for_should_not do
|
27
|
+
msg = "Expectation should not have failed with message '#{expected}'"
|
28
|
+
msg << ", but did."
|
29
|
+
|
30
|
+
msg
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module ModelBuilder
|
2
|
+
def self.included(example_group)
|
3
|
+
example_group.class_eval do
|
4
|
+
before do
|
5
|
+
@created_tables ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
after do
|
9
|
+
drop_created_tables
|
10
|
+
ActiveSupport::Dependencies.clear
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_table(table_name, options = {}, &block)
|
16
|
+
connection = ActiveRecord::Base.connection
|
17
|
+
|
18
|
+
begin
|
19
|
+
connection.execute("DROP TABLE IF EXISTS #{table_name}")
|
20
|
+
connection.create_table(table_name, options, &block)
|
21
|
+
@created_tables << table_name
|
22
|
+
connection
|
23
|
+
rescue Exception => e
|
24
|
+
connection.execute("DROP TABLE IF EXISTS #{table_name}")
|
25
|
+
raise e
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def define_model_class(class_name, &block)
|
30
|
+
define_class(class_name, ActiveRecord::Base, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def define_active_model_class(class_name, options = {}, &block)
|
34
|
+
define_class(class_name) do
|
35
|
+
include ActiveModel::Validations
|
36
|
+
|
37
|
+
options[:accessors].each do |column|
|
38
|
+
attr_accessor column.to_sym
|
39
|
+
end
|
40
|
+
|
41
|
+
if block_given?
|
42
|
+
class_eval(&block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def define_model(name, columns = {}, &block)
|
48
|
+
class_name = name.to_s.pluralize.classify
|
49
|
+
table_name = class_name.tableize
|
50
|
+
table_block = lambda do |table|
|
51
|
+
columns.each do |name, specification|
|
52
|
+
if specification.is_a?(Hash)
|
53
|
+
table.column name, specification[:type], specification[:options]
|
54
|
+
else
|
55
|
+
table.column name, specification
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if columns.key?(:id) && columns[:id] == false
|
61
|
+
columns.delete(:id)
|
62
|
+
create_table(table_name, id: false, &table_block)
|
63
|
+
else
|
64
|
+
create_table(table_name, &table_block)
|
65
|
+
end
|
66
|
+
|
67
|
+
define_model_class(class_name, &block)
|
68
|
+
end
|
69
|
+
|
70
|
+
def drop_created_tables
|
71
|
+
connection = ActiveRecord::Base.connection
|
72
|
+
|
73
|
+
@created_tables.each do |table_name|
|
74
|
+
connection.execute("DROP TABLE IF EXISTS #{table_name}")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
RSpec.configure do |config|
|
80
|
+
config.include ModelBuilder
|
81
|
+
end
|