rspec-rails 2.14.2 → 4.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) 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 +6 -57
  6. data/Changelog.md +715 -37
  7. data/{License.txt → LICENSE.md} +5 -2
  8. data/README.md +287 -362
  9. data/lib/generators/rspec/channel/channel_generator.rb +12 -0
  10. data/lib/generators/rspec/channel/templates/channel_spec.rb.erb +7 -0
  11. data/lib/generators/rspec/controller/controller_generator.rb +23 -5
  12. data/lib/generators/rspec/controller/templates/controller_spec.rb +5 -5
  13. data/lib/generators/rspec/controller/templates/request_spec.rb +19 -0
  14. data/lib/generators/rspec/controller/templates/routing_spec.rb +13 -0
  15. data/lib/generators/rspec/controller/templates/view_spec.rb +2 -2
  16. data/lib/generators/rspec/feature/feature_generator.rb +29 -0
  17. data/lib/generators/rspec/feature/templates/feature_singular_spec.rb +5 -0
  18. data/lib/generators/rspec/feature/templates/feature_spec.rb +5 -0
  19. data/lib/generators/rspec/generator/generator_generator.rb +24 -0
  20. data/lib/generators/rspec/generator/templates/generator_spec.rb +6 -0
  21. data/lib/generators/rspec/helper/helper_generator.rb +2 -1
  22. data/lib/generators/rspec/helper/templates/helper_spec.rb +2 -2
  23. data/lib/generators/rspec/install/install_generator.rb +44 -5
  24. data/lib/generators/rspec/install/templates/spec/rails_helper.rb +79 -0
  25. data/lib/generators/rspec/integration/integration_generator.rb +8 -13
  26. data/lib/generators/rspec/integration/templates/request_spec.rb +4 -9
  27. data/lib/generators/rspec/job/job_generator.rb +12 -0
  28. data/lib/generators/rspec/{observer/templates/observer_spec.rb → job/templates/job_spec.rb.erb} +2 -2
  29. data/lib/generators/rspec/mailbox/mailbox_generator.rb +14 -0
  30. data/lib/generators/rspec/mailbox/templates/mailbox_spec.rb.erb +7 -0
  31. data/lib/generators/rspec/mailer/mailer_generator.rb +9 -1
  32. data/lib/generators/rspec/mailer/templates/mailer_spec.rb +7 -7
  33. data/lib/generators/rspec/mailer/templates/preview.rb +13 -0
  34. data/lib/generators/rspec/model/model_generator.rb +21 -6
  35. data/lib/generators/rspec/model/templates/fixtures.yml +1 -1
  36. data/lib/generators/rspec/model/templates/model_spec.rb +2 -2
  37. data/lib/generators/rspec/request/request_generator.rb +10 -0
  38. data/lib/generators/rspec/scaffold/scaffold_generator.rb +88 -148
  39. data/lib/generators/rspec/scaffold/templates/api_controller_spec.rb +129 -0
  40. data/lib/generators/rspec/scaffold/templates/api_request_spec.rb +131 -0
  41. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +105 -80
  42. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +10 -14
  43. data/lib/generators/rspec/scaffold/templates/index_spec.rb +5 -12
  44. data/lib/generators/rspec/scaffold/templates/new_spec.rb +11 -15
  45. data/lib/generators/rspec/scaffold/templates/request_spec.rb +137 -0
  46. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +19 -12
  47. data/lib/generators/rspec/scaffold/templates/show_spec.rb +5 -12
  48. data/lib/generators/rspec/system/system_generator.rb +26 -0
  49. data/lib/generators/rspec/system/templates/system_spec.rb +9 -0
  50. data/lib/generators/rspec/view/templates/view_spec.rb +2 -2
  51. data/lib/generators/rspec/view/view_generator.rb +3 -2
  52. data/lib/generators/rspec.rb +18 -10
  53. data/lib/rspec/rails/active_record.rb +25 -0
  54. data/lib/rspec/rails/adapters.rb +49 -47
  55. data/lib/rspec/rails/configuration.rb +194 -0
  56. data/lib/rspec/rails/example/channel_example_group.rb +93 -0
  57. data/lib/rspec/rails/example/controller_example_group.rb +188 -138
  58. data/lib/rspec/rails/example/feature_example_group.rb +43 -20
  59. data/lib/rspec/rails/example/helper_example_group.rb +28 -26
  60. data/lib/rspec/rails/example/job_example_group.rb +23 -0
  61. data/lib/rspec/rails/example/mailbox_example_group.rb +80 -0
  62. data/lib/rspec/rails/example/mailer_example_group.rb +30 -14
  63. data/lib/rspec/rails/example/model_example_group.rb +8 -7
  64. data/lib/rspec/rails/example/rails_example_group.rb +4 -2
  65. data/lib/rspec/rails/example/request_example_group.rb +23 -16
  66. data/lib/rspec/rails/example/routing_example_group.rb +49 -40
  67. data/lib/rspec/rails/example/system_example_group.rb +125 -0
  68. data/lib/rspec/rails/example/view_example_group.rb +178 -134
  69. data/lib/rspec/rails/example.rb +4 -33
  70. data/lib/rspec/rails/extensions/active_record/proxy.rb +5 -11
  71. data/lib/rspec/rails/extensions.rb +0 -1
  72. data/lib/rspec/rails/feature_check.rb +47 -0
  73. data/lib/rspec/rails/file_fixture_support.rb +17 -0
  74. data/lib/rspec/rails/fixture_file_upload_support.rb +35 -0
  75. data/lib/rspec/rails/fixture_support.rb +54 -23
  76. data/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb +170 -0
  77. data/lib/rspec/rails/matchers/action_cable/have_streams.rb +58 -0
  78. data/lib/rspec/rails/matchers/action_cable.rb +65 -0
  79. data/lib/rspec/rails/matchers/action_mailbox.rb +64 -0
  80. data/lib/rspec/rails/matchers/active_job.rb +465 -0
  81. data/lib/rspec/rails/matchers/base_matcher.rb +179 -0
  82. data/lib/rspec/rails/matchers/be_a_new.rb +69 -62
  83. data/lib/rspec/rails/matchers/be_new_record.rb +24 -21
  84. data/lib/rspec/rails/matchers/be_valid.rb +42 -33
  85. data/lib/rspec/rails/matchers/have_enqueued_mail.rb +198 -0
  86. data/lib/rspec/rails/matchers/have_http_status.rb +385 -0
  87. data/lib/rspec/rails/matchers/have_rendered.rb +55 -31
  88. data/lib/rspec/rails/matchers/redirect_to.rb +30 -29
  89. data/lib/rspec/rails/matchers/relation_match_array.rb +2 -2
  90. data/lib/rspec/rails/matchers/routing_matchers.rb +107 -93
  91. data/lib/rspec/rails/matchers.rb +22 -14
  92. data/lib/rspec/rails/tasks/rspec.rake +8 -18
  93. data/lib/rspec/rails/vendor/capybara.rb +12 -11
  94. data/lib/rspec/rails/version.rb +3 -1
  95. data/lib/rspec/rails/view_assigns.rb +18 -18
  96. data/lib/rspec/rails/view_path_builder.rb +29 -0
  97. data/lib/rspec/rails/view_rendering.rb +100 -63
  98. data/lib/rspec/rails/view_spec_methods.rb +56 -0
  99. data/lib/rspec/rails.rb +10 -10
  100. data/lib/rspec-rails.rb +67 -3
  101. data.tar.gz.sig +0 -0
  102. metadata +121 -94
  103. metadata.gz.sig +0 -0
  104. data/lib/autotest/rails_rspec2.rb +0 -85
  105. data/lib/generators/rspec/install/templates/.rspec +0 -1
  106. data/lib/generators/rspec/install/templates/spec/spec_helper.rb.tt +0 -49
  107. data/lib/generators/rspec/observer/observer_generator.rb +0 -12
  108. data/lib/rspec/rails/extensions/active_record/base.rb +0 -58
  109. data/lib/rspec/rails/matchers/have_extension.rb +0 -36
  110. data/lib/rspec/rails/mocks.rb +0 -274
  111. data/lib/rspec/rails/module_inclusion.rb +0 -19
  112. 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,124 @@ 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_format(template),
60
+ locals: []
81
61
  )
82
62
  end
83
63
  end
64
+
65
+ if ::Rails::VERSION::STRING >= '6'
66
+ def self.template_format(template)
67
+ template.format
68
+ end
69
+ else
70
+ def self.template_format(template)
71
+ template.formats
72
+ end
73
+ end
74
+
75
+ # Delegates all methods to the submitted resolver and for all methods
76
+ # that return a collection of `ActionView::Template` instances, return
77
+ # templates with modified source
78
+ #
79
+ # @private
80
+ class ResolverDecorator
81
+ def initialize(resolver)
82
+ @resolver = resolver
83
+ end
84
+
85
+ def method_missing(name, *args, &block)
86
+ result = @resolver.send(name, *args, &block)
87
+ nullify_templates(result)
88
+ end
89
+
90
+ private
91
+
92
+ def nullify_templates(collection)
93
+ return collection unless collection.is_a?(Enumerable)
94
+ return collection unless collection.all? { |element| element.is_a?(::ActionView::Template) }
95
+
96
+ EmptyTemplateResolver.nullify_template_rendering(collection)
97
+ end
98
+ end
99
+
100
+ # Delegates find_templates to the submitted path set and then returns
101
+ # templates with modified source
102
+ #
103
+ # @private
104
+ class FileSystemResolver < ::ActionView::FileSystemResolver
105
+ private
106
+
107
+ def find_templates(*args)
108
+ templates = super
109
+ EmptyTemplateResolver.nullify_template_rendering(templates)
110
+ end
111
+ end
84
112
  end
85
113
 
114
+ # @private
86
115
  class EmptyTemplateHandler
87
- def self.call(template)
116
+ def self.call(_template, _source = nil)
117
+ ::Rails.logger.info(" Template rendering was prevented by rspec-rails. Use `render_views` to verify rendered view contents if necessary.")
118
+
88
119
  %("")
89
120
  end
90
121
  end
91
122
 
123
+ # Used to null out view rendering in controller specs.
124
+ #
125
+ # @private
92
126
  module EmptyTemplates
93
- # @api private
94
127
  def prepend_view_path(new_path)
95
- lookup_context.view_paths.unshift(*_path_decorator(new_path))
128
+ lookup_context.view_paths.unshift(*_path_decorator(*new_path))
96
129
  end
97
130
 
98
- # @api private
99
131
  def append_view_path(new_path)
100
- lookup_context.view_paths.push(*_path_decorator(new_path))
132
+ lookup_context.view_paths.push(*_path_decorator(*new_path))
101
133
  end
102
134
 
103
- private
135
+ private
104
136
 
105
- def _path_decorator(path)
106
- EmptyTemplatePathSetDecorator.new(ActionView::PathSet.new(Array.wrap(path)))
137
+ def _path_decorator(*paths)
138
+ paths.map { |path| EmptyTemplateResolver.build(path) }
107
139
  end
108
140
  end
109
141
 
142
+ # @private
143
+ RESOLVER_CACHE = Hash.new do |hash, path|
144
+ hash[path] = EmptyTemplateResolver.build(path)
145
+ end
146
+
110
147
  included do
111
148
  before do
112
149
  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)
150
+ @_original_path_set = controller.class.view_paths
151
+ path_set = @_original_path_set.map { |resolver| RESOLVER_CACHE[resolver] }
152
+
153
+ controller.class.view_paths = path_set
115
154
  controller.extend(EmptyTemplates)
116
155
  end
117
156
  end
118
157
 
119
158
  after do
120
- unless render_views?
121
- controller.class.view_paths = @_empty_view_path_set_delegator.original_path_set
122
- end
159
+ controller.class.view_paths = @_original_path_set unless render_views?
123
160
  end
124
161
  end
125
162
  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,78 @@
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
4
- # Rails-3.0.1 requires config.app_generators instead of 3.0.0's config.generators
5
- generators = config.respond_to?(:app_generators) ? config.app_generators : config.generators
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
18
+ generators = config.app_generators
6
19
  generators.integration_tool :rspec
7
- generators.test_framework :rspec
20
+ generators.test_framework :rspec
21
+
22
+ generators do
23
+ ::Rails::Generators.hidden_namespaces.reject! { |namespace| namespace.to_s.start_with?("rspec") }
24
+ end
8
25
 
9
26
  rake_tasks do
10
27
  load "rspec/rails/tasks/rspec.rake"
11
28
  end
29
+
30
+ # This is called after the environment has been loaded but before Rails
31
+ # sets the default for the `preview_path`
32
+ initializer "rspec_rails.action_mailer",
33
+ before: "action_mailer.set_configs" do |app|
34
+ setup_preview_path(app)
35
+ end
36
+
37
+ private
38
+
39
+ def setup_preview_path(app)
40
+ return unless supports_action_mailer_previews?(app.config)
41
+
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 options.show_previews.nil?
50
+ options.show_previews = ::Rails.env.development?
51
+ else
52
+ options.show_previews
53
+ end
54
+ end
55
+
56
+ def config_default_preview_path(options)
57
+ return unless options.preview_path.blank?
58
+
59
+ options.preview_path = "#{::Rails.root}/spec/mailers/previews"
60
+ end
61
+
62
+ def supports_action_mailer_previews?(config)
63
+ # These checks avoid loading `ActionMailer`. Using `defined?` has the
64
+ # side-effect of the class getting loaded if it is available. This is
65
+ # problematic because loading `ActionMailer::Base` will cause it to
66
+ # read the config settings; this is the only time the config is read.
67
+ # If the config is loaded now, any settings declared in a config block
68
+ # in an initializer will be ignored.
69
+ #
70
+ # If the action mailer railtie has not been loaded then `config` will
71
+ # not respond to the method. However, we cannot use
72
+ # `config.action_mailer.respond_to?(:preview_path)` here as it will
73
+ # always return `true`.
74
+ config.respond_to?(:action_mailer)
75
+ end
12
76
  end
13
77
  end
14
78
  end
data.tar.gz.sig ADDED
Binary file