rspec-rails 2.14.2 → 3.9.1

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.
Files changed (99) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +4 -2
  5. data/Capybara.md +2 -4
  6. data/Changelog.md +592 -34
  7. data/{License.txt → LICENSE.md} +5 -2
  8. data/README.md +290 -369
  9. data/lib/generators/rspec/controller/controller_generator.rb +1 -0
  10. data/lib/generators/rspec/controller/templates/controller_spec.rb +5 -5
  11. data/lib/generators/rspec/controller/templates/view_spec.rb +2 -2
  12. data/lib/generators/rspec/feature/feature_generator.rb +29 -0
  13. data/lib/generators/rspec/feature/templates/feature_singular_spec.rb +5 -0
  14. data/lib/generators/rspec/feature/templates/feature_spec.rb +5 -0
  15. data/lib/generators/rspec/generators/generator_generator.rb +24 -0
  16. data/lib/generators/rspec/generators/templates/generator_spec.rb +6 -0
  17. data/lib/generators/rspec/helper/helper_generator.rb +1 -0
  18. data/lib/generators/rspec/helper/templates/helper_spec.rb +2 -2
  19. data/lib/generators/rspec/install/install_generator.rb +44 -5
  20. data/lib/generators/rspec/install/templates/spec/rails_helper.rb +78 -0
  21. data/lib/generators/rspec/integration/integration_generator.rb +8 -13
  22. data/lib/generators/rspec/integration/templates/request_spec.rb +4 -9
  23. data/lib/generators/rspec/job/job_generator.rb +12 -0
  24. data/lib/generators/rspec/job/templates/job_spec.rb.erb +7 -0
  25. data/lib/generators/rspec/mailer/mailer_generator.rb +7 -0
  26. data/lib/generators/rspec/mailer/templates/mailer_spec.rb +7 -7
  27. data/lib/generators/rspec/mailer/templates/preview.rb +13 -0
  28. data/lib/generators/rspec/model/model_generator.rb +19 -5
  29. data/lib/generators/rspec/model/templates/fixtures.yml +1 -1
  30. data/lib/generators/rspec/model/templates/model_spec.rb +2 -2
  31. data/lib/generators/rspec/observer/observer_generator.rb +1 -0
  32. data/lib/generators/rspec/observer/templates/observer_spec.rb +2 -2
  33. data/lib/generators/rspec/request/request_generator.rb +10 -0
  34. data/lib/generators/rspec/scaffold/scaffold_generator.rb +68 -138
  35. data/lib/generators/rspec/scaffold/templates/api_controller_spec.rb +165 -0
  36. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +98 -73
  37. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +9 -13
  38. data/lib/generators/rspec/scaffold/templates/index_spec.rb +3 -10
  39. data/lib/generators/rspec/scaffold/templates/new_spec.rb +10 -14
  40. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +21 -12
  41. data/lib/generators/rspec/scaffold/templates/show_spec.rb +4 -11
  42. data/lib/generators/rspec/system/system_generator.rb +26 -0
  43. data/lib/generators/rspec/system/templates/system_spec.rb +9 -0
  44. data/lib/generators/rspec/view/templates/view_spec.rb +2 -2
  45. data/lib/generators/rspec/view/view_generator.rb +1 -0
  46. data/lib/generators/rspec.rb +20 -6
  47. data/lib/rspec/rails/active_record.rb +25 -0
  48. data/lib/rspec/rails/adapters.rb +104 -37
  49. data/lib/rspec/rails/configuration.rb +148 -0
  50. data/lib/rspec/rails/example/controller_example_group.rb +188 -138
  51. data/lib/rspec/rails/example/feature_example_group.rb +63 -20
  52. data/lib/rspec/rails/example/helper_example_group.rb +35 -26
  53. data/lib/rspec/rails/example/job_example_group.rb +23 -0
  54. data/lib/rspec/rails/example/mailer_example_group.rb +30 -14
  55. data/lib/rspec/rails/example/model_example_group.rb +8 -7
  56. data/lib/rspec/rails/example/rails_example_group.rb +3 -1
  57. data/lib/rspec/rails/example/request_example_group.rb +23 -16
  58. data/lib/rspec/rails/example/routing_example_group.rb +49 -40
  59. data/lib/rspec/rails/example/system_example_group.rb +108 -0
  60. data/lib/rspec/rails/example/view_example_group.rb +168 -135
  61. data/lib/rspec/rails/example.rb +2 -33
  62. data/lib/rspec/rails/extensions/active_record/proxy.rb +0 -1
  63. data/lib/rspec/rails/extensions.rb +0 -1
  64. data/lib/rspec/rails/feature_check.rb +64 -0
  65. data/lib/rspec/rails/file_fixture_support.rb +17 -0
  66. data/lib/rspec/rails/fixture_file_upload_support.rb +40 -0
  67. data/lib/rspec/rails/fixture_support.rb +32 -13
  68. data/lib/rspec/rails/matchers/active_job.rb +317 -0
  69. data/lib/rspec/rails/matchers/base_matcher.rb +184 -0
  70. data/lib/rspec/rails/matchers/be_a_new.rb +69 -62
  71. data/lib/rspec/rails/matchers/be_new_record.rb +24 -21
  72. data/lib/rspec/rails/matchers/be_valid.rb +42 -33
  73. data/lib/rspec/rails/matchers/have_enqueued_mail.rb +174 -0
  74. data/lib/rspec/rails/matchers/have_http_status.rb +381 -0
  75. data/lib/rspec/rails/matchers/have_rendered.rb +54 -31
  76. data/lib/rspec/rails/matchers/redirect_to.rb +30 -29
  77. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  78. data/lib/rspec/rails/matchers/routing_matchers.rb +107 -93
  79. data/lib/rspec/rails/matchers.rb +13 -14
  80. data/lib/rspec/rails/tasks/rspec.rake +1 -1
  81. data/lib/rspec/rails/vendor/capybara.rb +10 -4
  82. data/lib/rspec/rails/version.rb +3 -1
  83. data/lib/rspec/rails/view_assigns.rb +18 -18
  84. data/lib/rspec/rails/view_path_builder.rb +29 -0
  85. data/lib/rspec/rails/view_rendering.rb +89 -63
  86. data/lib/rspec/rails/view_spec_methods.rb +56 -0
  87. data/lib/rspec/rails.rb +10 -10
  88. data/lib/rspec-rails.rb +66 -1
  89. data.tar.gz.sig +0 -0
  90. metadata +92 -77
  91. metadata.gz.sig +0 -0
  92. data/lib/autotest/rails_rspec2.rb +0 -85
  93. data/lib/generators/rspec/install/templates/.rspec +0 -1
  94. data/lib/generators/rspec/install/templates/spec/spec_helper.rb.tt +0 -49
  95. data/lib/rspec/rails/extensions/active_record/base.rb +0 -58
  96. data/lib/rspec/rails/matchers/have_extension.rb +0 -36
  97. data/lib/rspec/rails/mocks.rb +0 -274
  98. data/lib/rspec/rails/module_inclusion.rb +0 -19
  99. data/lib/rspec/rails/vendor/webrat.rb +0 -33
@@ -1,53 +1,34 @@
1
1
  require 'action_view/testing/resolvers'
2
2
 
3
- RSpec.configure do |config|
4
- # This allows us to expose `render_views` as a config option even though it
5
- # breaks the convention of other options by using `render_views` as a
6
- # command (i.e. render_views = true), where it would normally be used as a
7
- # getter. This makes it easier for rspec-rails users because we use
8
- # `render_views` directly in example groups, so this aligns the two APIs,
9
- # but requires this workaround:
10
- config.add_setting :rendering_views, :default => false
11
-
12
- def config.render_views=(val)
13
- self.rendering_views = val
14
- end
15
-
16
- def config.render_views
17
- self.rendering_views = true
18
- end
19
-
20
- def config.render_views?
21
- rendering_views
22
- end
23
- end
24
-
25
3
  module RSpec
26
4
  module Rails
5
+ # @api public
6
+ # Helpers for optionally rendering views in controller specs.
27
7
  module ViewRendering
28
8
  extend ActiveSupport::Concern
29
9
 
30
- attr_accessor :controller
10
+ # @!attribute [r]
11
+ # Returns the controller object instance under test.
12
+ attr_reader :controller
31
13
 
32
- module ClassMethods
33
- def metadata_for_rspec_rails
34
- metadata[:rspec_rails] = metadata[:rspec_rails] ? metadata[:rspec_rails].dup : {}
35
- end
14
+ # @private
15
+ attr_writer :controller
16
+ private :controller=
36
17
 
18
+ # DSL methods
19
+ module ClassMethods
37
20
  # @see RSpec::Rails::ControllerExampleGroup
38
- def render_views(true_or_false=true)
39
- metadata_for_rspec_rails[:render_views] = true_or_false
40
- end
41
-
42
- # @deprecated Use `render_views` instead.
43
- def integrate_views
44
- RSpec.deprecate("integrate_views", :replacement => "render_views")
45
- render_views
21
+ def render_views(true_or_false = true)
22
+ @render_views = true_or_false
46
23
  end
47
24
 
48
25
  # @api private
49
26
  def render_views?
50
- metadata_for_rspec_rails.fetch(:render_views) do
27
+ return @render_views if defined?(@render_views)
28
+
29
+ if superclass.respond_to?(:render_views?)
30
+ superclass.render_views?
31
+ else
51
32
  RSpec.configuration.render_views?
52
33
  end
53
34
  end
@@ -58,68 +39,113 @@ module RSpec
58
39
  self.class.render_views? || !controller.class.respond_to?(:view_paths)
59
40
  end
60
41
 
61
- # Delegates find_all to the submitted path set and then returns templates
62
- # with modified source
63
- class EmptyTemplatePathSetDecorator < ::ActionView::Resolver
64
- attr_reader :original_path_set
65
-
66
- def initialize(original_path_set)
67
- @original_path_set = original_path_set
42
+ # @private
43
+ class EmptyTemplateResolver
44
+ def self.build(path)
45
+ if path.is_a?(::ActionView::Resolver)
46
+ ResolverDecorator.new(path)
47
+ else
48
+ FileSystemResolver.new(path)
49
+ end
68
50
  end
69
51
 
70
- # @api private
71
- def find_all(*args)
72
- original_path_set.find_all(*args).collect do |template|
52
+ def self.nullify_template_rendering(templates)
53
+ templates.map do |template|
73
54
  ::ActionView::Template.new(
74
55
  "",
75
56
  template.identifier,
76
57
  EmptyTemplateHandler,
77
- {
78
- :virtual_path => template.virtual_path,
79
- :format => template.formats
80
- }
58
+ :virtual_path => template.virtual_path,
59
+ :format => template.formats
81
60
  )
82
61
  end
83
62
  end
63
+
64
+ # Delegates all methods to the submitted resolver and for all methods
65
+ # that return a collection of `ActionView::Template` instances, return
66
+ # templates with modified source
67
+ #
68
+ # @private
69
+ class ResolverDecorator
70
+ def initialize(resolver)
71
+ @resolver = resolver
72
+ end
73
+
74
+ def method_missing(name, *args, &block)
75
+ result = @resolver.send(name, *args, &block)
76
+ nullify_templates(result)
77
+ end
78
+
79
+ private
80
+
81
+ def nullify_templates(collection)
82
+ return collection unless collection.is_a?(Enumerable)
83
+ return collection unless collection.all? { |element| element.is_a?(::ActionView::Template) }
84
+
85
+ EmptyTemplateResolver.nullify_template_rendering(collection)
86
+ end
87
+ end
88
+
89
+ # Delegates find_templates to the submitted path set and then returns
90
+ # templates with modified source
91
+ #
92
+ # @private
93
+ class FileSystemResolver < ::ActionView::FileSystemResolver
94
+ private
95
+
96
+ def find_templates(*args)
97
+ templates = super
98
+ EmptyTemplateResolver.nullify_template_rendering(templates)
99
+ end
100
+ end
84
101
  end
85
102
 
103
+ # @private
86
104
  class EmptyTemplateHandler
87
- def self.call(template)
105
+ def self.call(_template)
106
+ ::Rails.logger.info(" Template rendering was prevented by rspec-rails. Use `render_views` to verify rendered view contents if necessary.")
107
+
88
108
  %("")
89
109
  end
90
110
  end
91
111
 
112
+ # Used to null out view rendering in controller specs.
113
+ #
114
+ # @private
92
115
  module EmptyTemplates
93
- # @api private
94
116
  def prepend_view_path(new_path)
95
- lookup_context.view_paths.unshift(*_path_decorator(new_path))
117
+ lookup_context.view_paths.unshift(*_path_decorator(*new_path))
96
118
  end
97
119
 
98
- # @api private
99
120
  def append_view_path(new_path)
100
- lookup_context.view_paths.push(*_path_decorator(new_path))
121
+ lookup_context.view_paths.push(*_path_decorator(*new_path))
101
122
  end
102
123
 
103
- private
124
+ private
104
125
 
105
- def _path_decorator(path)
106
- EmptyTemplatePathSetDecorator.new(ActionView::PathSet.new(Array.wrap(path)))
126
+ def _path_decorator(*paths)
127
+ paths.map { |path| EmptyTemplateResolver.build(path) }
107
128
  end
108
129
  end
109
130
 
131
+ # @private
132
+ RESOLVER_CACHE = Hash.new do |hash, path|
133
+ hash[path] = EmptyTemplateResolver.build(path)
134
+ end
135
+
110
136
  included do
111
137
  before do
112
138
  unless render_views?
113
- @_empty_view_path_set_delegator = EmptyTemplatePathSetDecorator.new(controller.class.view_paths)
114
- controller.class.view_paths = ::ActionView::PathSet.new.push(@_empty_view_path_set_delegator)
139
+ @_original_path_set = controller.class.view_paths
140
+ path_set = @_original_path_set.map { |resolver| RESOLVER_CACHE[resolver] }
141
+
142
+ controller.class.view_paths = path_set
115
143
  controller.extend(EmptyTemplates)
116
144
  end
117
145
  end
118
146
 
119
147
  after do
120
- unless render_views?
121
- controller.class.view_paths = @_empty_view_path_set_delegator.original_path_set
122
- end
148
+ controller.class.view_paths = @_original_path_set unless render_views?
123
149
  end
124
150
  end
125
151
  end
@@ -0,0 +1,56 @@
1
+ module RSpec
2
+ module Rails
3
+ # Adds methods (generally to ActionView::TestCase::TestController).
4
+ # Intended for use in view specs.
5
+ module ViewSpecMethods
6
+ module_function
7
+
8
+ # Adds methods `extra_params=` and `extra_params` to the indicated class.
9
+ # When class is `::ActionView::TestCase::TestController`, these methods
10
+ # are exposed in view specs on the `controller` object.
11
+ def add_to(klass)
12
+ return if klass.method_defined?(:extra_params) && klass.method_defined?(:extra_params=)
13
+
14
+ klass.module_exec do
15
+ # Set any extra parameters that rendering a URL for this view
16
+ # would require.
17
+ #
18
+ # @example
19
+ #
20
+ # # In "spec/views/widgets/show.html.erb_spec.rb":
21
+ # before do
22
+ # widget = Widget.create!(:name => "slicer")
23
+ # controller.extra_params = { :id => widget.id }
24
+ # end
25
+ def extra_params=(hash)
26
+ @extra_params = hash
27
+ request.path =
28
+ ViewPathBuilder.new(::Rails.application.routes).path_for(
29
+ extra_params.merge(request.path_parameters)
30
+ )
31
+ end
32
+
33
+ # Use to read extra parameters that are set in the view spec.
34
+ #
35
+ # @example
36
+ #
37
+ # # After the before in the above example:
38
+ # controller.extra_params
39
+ # # => { :id => 4 }
40
+ def extra_params
41
+ @extra_params ||= {}
42
+ @extra_params.dup.freeze
43
+ end
44
+ end
45
+ end
46
+
47
+ # Removes methods `extra_params=` and `extra_params` from the indicated class.
48
+ def remove_from(klass)
49
+ klass.module_exec do
50
+ undef extra_params= if klass.method_defined?(:extra_params=)
51
+ undef extra_params if klass.method_defined?(:extra_params)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
data/lib/rspec/rails.rb CHANGED
@@ -1,18 +1,18 @@
1
1
  require 'rspec/core'
2
-
3
- RSpec::configure do |c|
4
- c.backtrace_exclusion_patterns << /vendor\//
5
- c.backtrace_exclusion_patterns << /lib\/rspec\/rails/
6
- end
7
-
8
2
  require 'rails/version'
3
+
4
+ # Load any of our adapters and extensions early in the process
5
+ require 'rspec/rails/adapters'
9
6
  require 'rspec/rails/extensions'
7
+
8
+ # Load the rspec-rails parts
10
9
  require 'rspec/rails/view_rendering'
11
- require 'rspec/rails/adapters'
12
10
  require 'rspec/rails/matchers'
13
11
  require 'rspec/rails/fixture_support'
14
- require 'rspec/rails/mocks'
15
- require 'rspec/rails/module_inclusion'
12
+ require 'rspec/rails/file_fixture_support'
13
+ require 'rspec/rails/fixture_file_upload_support'
16
14
  require 'rspec/rails/example'
17
15
  require 'rspec/rails/vendor/capybara'
18
- require 'rspec/rails/vendor/webrat'
16
+ require 'rspec/rails/configuration'
17
+ require 'rspec/rails/active_record'
18
+ require 'rspec/rails/feature_check'
data/lib/rspec-rails.rb CHANGED
@@ -1,14 +1,79 @@
1
+ require 'rspec/rails/feature_check'
2
+
3
+ # Namespace for all core RSpec projects.
1
4
  module RSpec
5
+ # Namespace for rspec-rails code.
2
6
  module Rails
7
+ # Railtie to hook into Rails.
3
8
  class Railtie < ::Rails::Railtie
9
+ # As of Rails 5.1.0 you can register directories to work with `rake notes`
10
+ if ::Rails::VERSION::STRING >= '5.1'
11
+ require 'rails/source_annotation_extractor'
12
+ if ::Rails::VERSION::STRING >= '6.0'
13
+ ::Rails::SourceAnnotationExtractor::Annotation.register_directories("spec")
14
+ else
15
+ SourceAnnotationExtractor::Annotation.register_directories("spec")
16
+ end
17
+ end
4
18
  # Rails-3.0.1 requires config.app_generators instead of 3.0.0's config.generators
5
19
  generators = config.respond_to?(:app_generators) ? config.app_generators : config.generators
6
20
  generators.integration_tool :rspec
7
- generators.test_framework :rspec
21
+ generators.test_framework :rspec
22
+
23
+ generators do
24
+ ::Rails::Generators.hidden_namespaces.reject! { |namespace| namespace.to_s.start_with?("rspec") }
25
+ end
8
26
 
9
27
  rake_tasks do
10
28
  load "rspec/rails/tasks/rspec.rake"
11
29
  end
30
+
31
+ # This is called after the environment has been loaded but before Rails
32
+ # sets the default for the `preview_path`
33
+ initializer "rspec_rails.action_mailer",
34
+ :before => "action_mailer.set_configs" do |app|
35
+ setup_preview_path(app)
36
+ end
37
+
38
+ private
39
+
40
+ def setup_preview_path(app)
41
+ return unless supports_action_mailer_previews?(app.config)
42
+ options = app.config.action_mailer
43
+ config_default_preview_path(options) if config_preview_path?(options)
44
+ end
45
+
46
+ def config_preview_path?(options)
47
+ # We cannot use `respond_to?(:show_previews)` here as it will always
48
+ # return `true`.
49
+ if ::Rails::VERSION::STRING < '4.2'
50
+ ::Rails.env.development?
51
+ elsif options.show_previews.nil?
52
+ options.show_previews = ::Rails.env.development?
53
+ else
54
+ options.show_previews
55
+ end
56
+ end
57
+
58
+ def config_default_preview_path(options)
59
+ return unless options.preview_path.blank?
60
+ options.preview_path = "#{::Rails.root}/spec/mailers/previews"
61
+ end
62
+
63
+ def supports_action_mailer_previews?(config)
64
+ # These checks avoid loading `ActionMailer`. Using `defined?` has the
65
+ # side-effect of the class getting loaded if it is available. This is
66
+ # problematic because loading `ActionMailer::Base` will cause it to
67
+ # read the config settings; this is the only time the config is read.
68
+ # If the config is loaded now, any settings declared in a config block
69
+ # in an initializer will be ignored.
70
+ #
71
+ # If the action mailer railtie has not been loaded then `config` will
72
+ # not respond to the method. However, we cannot use
73
+ # `config.action_mailer.respond_to?(:preview_path)` here as it will
74
+ # always return `true`.
75
+ config.respond_to?(:action_mailer) && ::Rails::VERSION::STRING > '4.1'
76
+ end
12
77
  end
13
78
  end
14
79
  end
data.tar.gz.sig ADDED
Binary file