view_component 2.57.0 → 2.59.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of view_component might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a22d7248560f80072ed000776afa4f92b164cd80931570feb4a3416bb6ba3627
4
- data.tar.gz: 9bc617ae2ff51bad6f61b41412b4b3827c4bbe3f2366e0a3829ee00216d9518d
3
+ metadata.gz: ca82494216cd6b91d9a073bd1ab025cbe48049560893a500e72caff01141e02f
4
+ data.tar.gz: 9eecd79663f09edb31cae5a104b861c4922a99a92307f583b0703b11053a2d60
5
5
  SHA512:
6
- metadata.gz: 648585993d06389775c8d14edee060fc551394edadaa7337a4b10709183941f9143cad71dc045ec4dca50db5bd568b8b57066518c0222e32e569f89e787043af
7
- data.tar.gz: 4c8fbee2640a2fba303ce93010bdf789cbe094f233e7253dc4491207cadd3101914d86ae22c4b85e7c3db78b18e048b14955b41ce86ceb510fd4495e6ef216dc
6
+ metadata.gz: 4e04336d18bd57be41e3ae4637ae1978a4884a352fced4b852a40901fa1ff02a13e6266ab4c669fbb3669fa718eecbfd8a5b13c54df79cbb9b692e278f02f35e
7
+ data.tar.gz: 2fed6153f148f683afe4cd27c909051aedfc92e9f896e6fe41736083d05217e7df15ac12799291fd2299ca59c1ee12e7ec1145ac9be5ee78cacb81d55fccf548
@@ -37,21 +37,24 @@ module ViewComponent
37
37
  opts = {}
38
38
  opts[:layout] = layout if layout.present? || layout == false
39
39
  opts[:locals] = locals if locals.present?
40
- render "view_components/preview", opts # rubocop:disable GitHub/RailsControllerRenderLiteral
40
+ render "view_components/preview", opts
41
41
  end
42
42
  end
43
43
 
44
44
  private
45
45
 
46
- def default_preview_layout # :doc:
46
+ # :doc:
47
+ def default_preview_layout
47
48
  ViewComponent::Base.default_preview_layout
48
49
  end
49
50
 
50
- def show_previews? # :doc:
51
+ # :doc:
52
+ def show_previews?
51
53
  ViewComponent::Base.show_previews
52
54
  end
53
55
 
54
- def find_preview # :doc:
56
+ # :doc:
57
+ def find_preview
55
58
  candidates = []
56
59
  params[:path].to_s.scan(%r{/|$}) { candidates << $` }
57
60
  preview = candidates.detect { |candidate| ViewComponent::Preview.exists?(candidate) }
@@ -7,14 +7,14 @@ module PreviewHelper
7
7
  def preview_source
8
8
  return if @render_args.nil?
9
9
 
10
- render "preview_source" # rubocop:disable GitHub/RailsViewRenderPathsExist
10
+ render "preview_source"
11
11
  end
12
12
 
13
13
  def find_template_data(lookup_context:, template_identifier:)
14
14
  template = lookup_context.find_template(template_identifier)
15
15
 
16
16
  if Rails.version.to_f >= 6.1 || template.source.present?
17
- return {
17
+ {
18
18
  source: template.source,
19
19
  prism_language_name: prism_language_name_by_template(template: template)
20
20
  }
@@ -40,7 +40,7 @@ module PreviewHelper
40
40
  template_source = File.read(template_file_path)
41
41
  prism_language_name = prism_language_name_by_template_path(template_file_path: template_file_path)
42
42
 
43
- return {
43
+ {
44
44
  source: template_source,
45
45
  prism_language_name: prism_language_name
46
46
  }
data/docs/CHANGELOG.md CHANGED
@@ -9,6 +9,109 @@ title: Changelog
9
9
 
10
10
  ## main
11
11
 
12
+ ## 2.59.0
13
+
14
+ * Expose Capybara DSL methods directly inside tests.
15
+
16
+ The following Capybara methods are now available directly without having to use the `page` method:
17
+
18
+ * [`all`](https://rubydoc.info/github/teamcapybara/capybara/Capybara%2FNode%2FFinders:all)
19
+ * [`first`](https://rubydoc.info/github/teamcapybara/capybara/Capybara%2FNode%2FFinders:first)
20
+ * [`text`](https://rubydoc.info/github/teamcapybara/capybara/Capybara%2FNode%2FSimple:text)
21
+ * [`find`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FFinders:find)
22
+ * [`find_all`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FFinders:find_all)
23
+ * [`find_button`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FFinders:find_button)
24
+ * [`find_by_id`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FFinders:find_by_id)
25
+ * [`find_field`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FFinders:find_field)
26
+ * [`find_link`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FFinders:find_link)
27
+ * [`has_content?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_content%3F)
28
+ * [`has_text?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_text%3F)
29
+ * [`has_css?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_css%3F)
30
+ * [`has_no_content?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_content%3F)
31
+ * [`has_no_text?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_text%3F)
32
+ * [`has_no_css?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_css%3F)
33
+ * [`has_no_xpath?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_xpath%3F)
34
+ * [`has_xpath?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_xpath%3F)
35
+ * [`has_link?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_link%3F)
36
+ * [`has_no_link?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_link%3F)
37
+ * [`has_button?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_button%3F)
38
+ * [`has_no_button?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_button%3F)
39
+ * [`has_field?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_field%3F)
40
+ * [`has_no_field?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_field%3F)
41
+ * [`has_checked_field?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_checked_field%3F)
42
+ * [`has_unchecked_field?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_unchecked_field%3F)
43
+ * [`has_no_table?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_table%3F)
44
+ * [`has_table?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_table%3F)
45
+ * [`has_select?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_select%3F)
46
+ * [`has_no_select?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_select%3F)
47
+ * [`has_selector?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_selector%3F)
48
+ * [`has_no_selector?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_selector%3F)
49
+ * [`has_no_checked_field?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_checked_field%3F)
50
+ * [`has_no_unchecked_field?`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FNode%2FMatchers:has_no_unchecked_field%3F)
51
+
52
+ * Add support for `within*` Capybara DLS methods:
53
+
54
+ * [`within`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FSession:within)
55
+ * [`within_element`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FSession:within)
56
+ * [`within_fieldset`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FSession:within_fieldset)
57
+ * [`within_table`](https://rubydoc.info/github/teamcapybara/capybara/master/Capybara%2FSession:within_table)
58
+
59
+ *Jacob Carlborg*
60
+
61
+ ## 2.58.0
62
+
63
+ * Switch to `standardrb`.
64
+
65
+ *Joel Hawksley*
66
+
67
+ * Add BootrAils article to resources.
68
+
69
+ *Joel Hawksley*
70
+
71
+ * Add @boardfish and @spone as maintainers.
72
+
73
+ *Joel Hawksley*, *Cameron Dutro*, *Blake Williams*
74
+
75
+ * Re-compile updated, inherited templates when class caching is disabled.
76
+
77
+ *Patrick Arnett*
78
+
79
+ * Add the latest version to the docs index.
80
+ * Improve the docs: add the versions various features were introduced in.
81
+
82
+ *Hans Lemuet*
83
+
84
+ * Update docs to reflect lack of block content support in controllers.
85
+
86
+ *Joel Hawksley*
87
+
88
+ * Prevent adding duplicates to `autoload_paths`.
89
+
90
+ *Thomas Hutterer*
91
+
92
+ * Add FreeAgent to list of companies using ViewComponent.
93
+
94
+ *Simon Fish*
95
+
96
+ * Include polymorphic slots in `ViewComponent::Base` by default.
97
+
98
+ *Cameron Dutro*
99
+
100
+ * Add per-component config option for stripping newlines from templates before compilation.
101
+
102
+ *Cameron Dutro*
103
+
104
+ * Add link to article by Matouš Borák.
105
+
106
+ *Joel Hawksley*
107
+
108
+ ## 2.57.1
109
+
110
+ * Fix issue causing `NoMethodError`s when calling helper methods from components rendered as part of a collection.
111
+ * Fix syntax error in the ERB example in the polymorphic slots docs.
112
+
113
+ *Cameron Dutro*
114
+
12
115
  ## 2.57.0
13
116
 
14
117
  * Add missing `require` for `Translatable` module in `Base`.
@@ -36,10 +36,10 @@ module ViewComponent
36
36
 
37
37
  def stimulus_controller
38
38
  if options["stimulus"]
39
- File.join(destination_directory, destination_file_name).
40
- sub("#{component_path}/", "").
41
- gsub("_", "-").
42
- gsub("/", "--")
39
+ File.join(destination_directory, destination_file_name)
40
+ .sub("#{component_path}/", "")
41
+ .tr("_", "-")
42
+ .gsub("/", "--")
43
43
  end
44
44
  end
45
45
 
@@ -16,6 +16,7 @@ module ViewComponent
16
16
  class Base < ActionView::Base
17
17
  include ActiveSupport::Configurable
18
18
  include ViewComponent::ContentAreas
19
+ include ViewComponent::PolymorphicSlots
19
20
  include ViewComponent::Previewable
20
21
  include ViewComponent::SlotableV2
21
22
  include ViewComponent::Translatable
@@ -31,8 +32,25 @@ module ViewComponent
31
32
  class_attribute :content_areas
32
33
  self.content_areas = [] # class_attribute:default doesn't work until Rails 5.2
33
34
 
35
+ # Config option that strips trailing whitespace in templates before compiling them.
36
+ class_attribute :__vc_strip_trailing_whitespace, instance_accessor: false, instance_predicate: false
37
+ self.__vc_strip_trailing_whitespace = false # class_attribute:default doesn't work until Rails 5.2
38
+
34
39
  attr_accessor :__vc_original_view_context
35
40
 
41
+ # Components render in their own view context. Helpers and other functionality
42
+ # require a reference to the original Rails view context, an instance of
43
+ # `ActionView::Base`. Use this method to set a reference to the original
44
+ # view context. Objects that implement this method will render in the component's
45
+ # view context, while objects that don't will render in the original view context
46
+ # so helpers, etc work as expected.
47
+ #
48
+ # @param view_context [ActionView::Base] The original view context.
49
+ # @return [void]
50
+ def set_original_view_context(view_context)
51
+ self.__vc_original_view_context = view_context
52
+ end
53
+
36
54
  # EXPERIMENTAL: This API is experimental and may be removed at any time.
37
55
  # Hook for allowing components to do work as part of the compilation process.
38
56
  #
@@ -114,24 +132,27 @@ module ViewComponent
114
132
  @current_template = old_current_template
115
133
  end
116
134
 
135
+ # @private
117
136
  def perform_render
118
137
  render_template_for(@__vc_variant).to_s + _output_postamble
119
138
  end
120
139
 
121
140
  # Subclass components that call `super` inside their template code will cause a
122
- # double render if they accidentally emit the result:
141
+ # double render if they emit the result:
123
142
  #
143
+ # ```erb
124
144
  # <%= super %> # double-renders
125
- #
126
145
  # <% super %> # does not double-render
146
+ # ```
127
147
  #
128
- # Calls `super`, returning nil to avoid rendering the result twice.
148
+ # Calls `super`, returning `nil` to avoid rendering the result twice.
129
149
  def render_parent
130
150
  mtd = @__vc_variant ? "call_#{@__vc_variant}" : "call"
131
151
  method(mtd).super_method.call
132
152
  nil
133
153
  end
134
154
 
155
+ # @private
135
156
  # :nocov:
136
157
  def render_template_for(variant = nil)
137
158
  # Force compilation here so the compiler always redefines render_template_for.
@@ -173,7 +194,8 @@ module ViewComponent
173
194
  end
174
195
 
175
196
  # @private
176
- def initialize(*); end
197
+ def initialize(*)
198
+ end
177
199
 
178
200
  # Re-use original view_context if we're not rendering a component.
179
201
  #
@@ -183,11 +205,8 @@ module ViewComponent
183
205
  #
184
206
  # @private
185
207
  def render(options = {}, args = {}, &block)
186
- if options.respond_to?(:render_in)
187
- if options.is_a?(ViewComponent::Base)
188
- options.__vc_original_view_context = __vc_original_view_context
189
- end
190
-
208
+ if options.respond_to?(:set_original_view_context)
209
+ options.set_original_view_context(self.__vc_original_view_context)
191
210
  super
192
211
  else
193
212
  __vc_original_view_context.render(options, args, &block)
@@ -304,7 +323,9 @@ module ViewComponent
304
323
 
305
324
  # Set the controller used for testing components:
306
325
  #
307
- # config.view_component.test_controller = "MyTestController"
326
+ # ```ruby
327
+ # config.view_component.test_controller = "MyTestController"
328
+ # ```
308
329
  #
309
330
  # Defaults to ApplicationController. Can also be configured on a per-test
310
331
  # basis using `with_controller_class`.
@@ -314,13 +335,17 @@ module ViewComponent
314
335
 
315
336
  # Set if render monkey patches should be included or not in Rails <6.1:
316
337
  #
317
- # config.view_component.render_monkey_patch_enabled = false
338
+ # ```ruby
339
+ # config.view_component.render_monkey_patch_enabled = false
340
+ # ```
318
341
  #
319
342
  mattr_accessor :render_monkey_patch_enabled, instance_writer: false, default: true
320
343
 
321
344
  # Path for component files
322
345
  #
323
- # config.view_component.view_component_path = "app/my_components"
346
+ # ```ruby
347
+ # config.view_component.view_component_path = "app/my_components"
348
+ # ```
324
349
  #
325
350
  # Defaults to `app/components`.
326
351
  #
@@ -328,7 +353,9 @@ module ViewComponent
328
353
 
329
354
  # Parent class for generated components
330
355
  #
331
- # config.view_component.component_parent_class = "MyBaseComponent"
356
+ # ```ruby
357
+ # config.view_component.component_parent_class = "MyBaseComponent"
358
+ # ```
332
359
  #
333
360
  # Defaults to nil. If this is falsy, generators will use
334
361
  # "ApplicationComponent" if defined, "ViewComponent::Base" otherwise.
@@ -344,25 +371,33 @@ module ViewComponent
344
371
  #
345
372
  # Always generate a component with a sidecar directory:
346
373
  #
347
- # config.view_component.generate.sidecar = true
374
+ # ```ruby
375
+ # config.view_component.generate.sidecar = true
376
+ # ```
348
377
  #
349
378
  # #### #stimulus_controller
350
379
  #
351
380
  # Always generate a Stimulus controller alongside the component:
352
381
  #
353
- # config.view_component.generate.stimulus_controller = true
382
+ # ```ruby
383
+ # config.view_component.generate.stimulus_controller = true
384
+ # ```
354
385
  #
355
386
  # #### #locale
356
387
  #
357
388
  # Always generate translations file alongside the component:
358
389
  #
359
- # config.view_component.generate.locale = true
390
+ # ```ruby
391
+ # config.view_component.generate.locale = true
392
+ # ```
360
393
  #
361
394
  # #### #distinct_locale_files
362
395
  #
363
396
  # Always generate as many translations files as available locales:
364
397
  #
365
- # config.view_component.generate.distinct_locale_files = true
398
+ # ```ruby
399
+ # config.view_component.generate.distinct_locale_files = true
400
+ # ```
366
401
  #
367
402
  # One file will be generated for each configured `I18n.available_locales`,
368
403
  # falling back to `[:en]` when no `available_locales` is defined.
@@ -371,7 +406,9 @@ module ViewComponent
371
406
  #
372
407
  # Always generate preview alongside the component:
373
408
  #
374
- # config.view_component.generate.preview = true
409
+ # ```ruby
410
+ # config.view_component.generate.preview = true
411
+ # ```
375
412
  #
376
413
  # Defaults to `false`.
377
414
  mattr_accessor :generate, instance_writer: false, default: ActiveSupport::OrderedOptions.new(false)
@@ -425,7 +462,9 @@ module ViewComponent
425
462
 
426
463
  # Render a component for each element in a collection ([documentation](/guide/collections)):
427
464
  #
428
- # render(ProductsComponent.with_collection(@products, foo: :bar))
465
+ # ```ruby
466
+ # render(ProductsComponent.with_collection(@products, foo: :bar))
467
+ # ```
429
468
  #
430
469
  # @param collection [Enumerable] A list of items to pass the ViewComponent one at a time.
431
470
  # @param args [Arguments] Arguments to pass to the ViewComponent every time.
@@ -521,13 +560,35 @@ module ViewComponent
521
560
 
522
561
  # Set the parameter name used when rendering elements of a collection ([documentation](/guide/collections)):
523
562
  #
524
- # with_collection_parameter :item
563
+ # ```ruby
564
+ # with_collection_parameter :item
565
+ # ```
525
566
  #
526
567
  # @param parameter [Symbol] The parameter name used when rendering elements of a collection.
527
568
  def with_collection_parameter(parameter)
528
569
  @provided_collection_parameter = parameter
529
570
  end
530
571
 
572
+ # Strips trailing whitespace from templates before compiling them.
573
+ #
574
+ # ```ruby
575
+ # class MyComponent < ViewComponent::Base
576
+ # strip_trailing_whitespace
577
+ # end
578
+ # ```
579
+ #
580
+ # @param value [Boolean] Whether or not to strip newlines.
581
+ def strip_trailing_whitespace(value = true)
582
+ self.__vc_strip_trailing_whitespace = value
583
+ end
584
+
585
+ # Whether trailing whitespace will be stripped before compilation.
586
+ #
587
+ # @return [Boolean]
588
+ def strip_trailing_whitespace?
589
+ __vc_strip_trailing_whitespace
590
+ end
591
+
531
592
  # Ensure the component initializer accepts the
532
593
  # collection parameter. By default, we don't
533
594
  # validate that the default parameter name
@@ -575,11 +636,7 @@ module ViewComponent
575
636
 
576
637
  # @private
577
638
  def collection_parameter
578
- if provided_collection_parameter
579
- provided_collection_parameter
580
- else
581
- name && name.demodulize.underscore.chomp("_component").to_sym
582
- end
639
+ provided_collection_parameter || name && name.demodulize.underscore.chomp("_component").to_sym
583
640
  end
584
641
 
585
642
  # @private
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ViewComponent
4
+ # This is a simpler version of {Capybara::Session}.
5
+ #
6
+ # It only includes {Capybara::Node::Finders}, {Capybara::Node::Matchers},
7
+ # {#within} and {#within_element}. It is useful in that it does not require a
8
+ # session, an application or a driver, but can still use Capybara's finders
9
+ # and matchers on any string that contains HTML.
10
+ class CapybaraSimpleSession
11
+ # Most of the code in this class is shamelessly stolen from the
12
+ # {Capybara::Session} class in the Capybara gem
13
+ # (https://github.com/teamcapybara/capybara/blob/e704d00879fb1d1e1a0cc01e04c101bcd8af4a68/lib/capybara/session.rb#L38).
14
+
15
+ NODE_METHODS = %i[
16
+ all
17
+ first
18
+ text
19
+
20
+ find
21
+ find_all
22
+ find_button
23
+ find_by_id
24
+ find_field
25
+ find_link
26
+
27
+ has_content?
28
+ has_text?
29
+ has_css?
30
+ has_no_content?
31
+ has_no_text?
32
+ has_no_css?
33
+ has_no_xpath?
34
+ has_xpath?
35
+ has_link?
36
+ has_no_link?
37
+ has_button?
38
+ has_no_button?
39
+ has_field?
40
+ has_no_field?
41
+ has_checked_field?
42
+ has_unchecked_field?
43
+ has_no_table?
44
+ has_table?
45
+ has_select?
46
+ has_no_select?
47
+ has_selector?
48
+ has_no_selector?
49
+ has_no_checked_field?
50
+ has_no_unchecked_field?
51
+
52
+ assert_selector
53
+ assert_no_selector
54
+ assert_all_of_selectors
55
+ assert_none_of_selectors
56
+ assert_any_of_selectors
57
+ assert_text
58
+ assert_no_text
59
+ ].freeze
60
+
61
+ private_constant :NODE_METHODS
62
+
63
+ SESSION_METHODS = %i[within within_element within_fieldset within_table].freeze
64
+
65
+ private_constant :SESSION_METHODS
66
+
67
+ DSL_METHODS = (NODE_METHODS + SESSION_METHODS).freeze
68
+
69
+ # Stolen from: https://github.com/teamcapybara/capybara/blob/e704d00879fb1d1e1a0cc01e04c101bcd8af4a68/lib/capybara/session.rb#L767-L774.
70
+ NODE_METHODS.each do |method|
71
+ if RUBY_VERSION >= "2.7"
72
+ class_eval <<~METHOD, __FILE__, __LINE__ + 1
73
+ def #{method}(...)
74
+ current_scope.#{method}(...)
75
+ end
76
+ METHOD
77
+ else
78
+ define_method method do |*args, &block|
79
+ current_scope.send(method, *args, &block)
80
+ end
81
+ end
82
+ end
83
+
84
+ # Initializes the receiver with the given string of HTML.
85
+ #
86
+ # @param html [String] the HTML to create the session out of
87
+ def initialize(html)
88
+ @document = Capybara::Node::Simple.new(html)
89
+ end
90
+
91
+ # (see Capybara::Session#within)
92
+ def within(*args, **kw_args)
93
+ new_scope = args.first.respond_to?(:to_capybara_node) ? args.first.to_capybara_node : find(*args, **kw_args)
94
+ begin
95
+ scopes.push(new_scope)
96
+ yield if block_given?
97
+ ensure
98
+ scopes.pop
99
+ end
100
+ end
101
+
102
+ # (see Capybara::Session#within_element)
103
+ alias_method :within_element, :within
104
+
105
+ # (see Capybara::Session#within_fieldset)
106
+ def within_fieldset(locator, &block)
107
+ within(:fieldset, locator, &block)
108
+ end
109
+
110
+ # (see Capybara::Session#within_table)
111
+ def within_table(locator, &block)
112
+ within(:table, locator, &block)
113
+ end
114
+
115
+ # (see Capybara::Node::Element#native)
116
+ def native
117
+ current_scope.native
118
+ end
119
+
120
+ private
121
+
122
+ attr_reader :document
123
+
124
+ def scopes
125
+ @scopes ||= [nil]
126
+ end
127
+
128
+ def current_scope
129
+ scopes.last.presence || document
130
+ end
131
+ end
132
+ end
@@ -10,10 +10,17 @@ module ViewComponent
10
10
  delegate :format, to: :component
11
11
  delegate :size, to: :@collection
12
12
 
13
+ attr_accessor :__vc_original_view_context
14
+
15
+ def set_original_view_context(view_context)
16
+ self.__vc_original_view_context = view_context
17
+ end
18
+
13
19
  def render_in(view_context, &block)
14
20
  components.map do |component|
21
+ component.set_original_view_context(__vc_original_view_context)
15
22
  component.render_in(view_context, &block)
16
- end.join.html_safe # rubocop:disable Rails/OutputSafety
23
+ end.join.html_safe
17
24
  end
18
25
 
19
26
  def components
@@ -54,7 +61,7 @@ module ViewComponent
54
61
  end
55
62
 
56
63
  def component_options(item, iterator)
57
- item_options = { component.collection_parameter => item }
64
+ item_options = {component.collection_parameter => item}
58
65
  item_options[component.collection_counter_parameter] = iterator.index + 1 if component.counter_argument_present?
59
66
  item_options[component.collection_iteration_parameter] = iterator.dup if component.iteration_argument_present?
60
67
 
@@ -31,6 +31,8 @@ module ViewComponent
31
31
  return if compiled? && !force
32
32
  return if component_class == ViewComponent::Base
33
33
 
34
+ component_class.superclass.compile(raise_errors: raise_errors) if should_compile_superclass?
35
+
34
36
  with_lock do
35
37
  subclass_instance_methods = component_class.instance_methods(false)
36
38
 
@@ -68,11 +70,13 @@ module ViewComponent
68
70
  component_class.send(:remove_method, method_name.to_sym)
69
71
  end
70
72
 
73
+ # rubocop:disable Style/EvalWithLocation
71
74
  component_class.class_eval <<-RUBY, template[:path], 0
72
75
  def #{method_name}
73
76
  #{compiled_template(template[:path])}
74
77
  end
75
78
  RUBY
79
+ # rubocop:enable Style/EvalWithLocation
76
80
  end
77
81
 
78
82
  define_render_template_for
@@ -151,15 +155,15 @@ module ViewComponent
151
155
  end
152
156
 
153
157
  invalid_variants =
154
- templates.
155
- group_by { |template| template[:variant] }.
156
- map { |variant, grouped| variant if grouped.length > 1 }.
157
- compact.
158
- sort
158
+ templates
159
+ .group_by { |template| template[:variant] }
160
+ .map { |variant, grouped| variant if grouped.length > 1 }
161
+ .compact
162
+ .sort
159
163
 
160
164
  unless invalid_variants.empty?
161
165
  errors <<
162
- "More than one template found for #{'variant'.pluralize(invalid_variants.count)} " \
166
+ "More than one template found for #{"variant".pluralize(invalid_variants.count)} " \
163
167
  "#{invalid_variants.map { |v| "'#{v}'" }.to_sentence} in #{component_class}. " \
164
168
  "There can only be one template file per variant."
165
169
  end
@@ -177,8 +181,8 @@ module ViewComponent
177
181
  count = duplicate_template_file_and_inline_variant_calls.count
178
182
 
179
183
  errors <<
180
- "Template #{'file'.pluralize(count)} and inline render #{'method'.pluralize(count)} " \
181
- "found for #{'variant'.pluralize(count)} " \
184
+ "Template #{"file".pluralize(count)} and inline render #{"method".pluralize(count)} " \
185
+ "found for #{"variant".pluralize(count)} " \
182
186
  "#{duplicate_template_file_and_inline_variant_calls.map { |v| "'#{v}'" }.to_sentence} " \
183
187
  "in #{component_class}. " \
184
188
  "There can only be a template file or inline render method per variant."
@@ -236,8 +240,9 @@ module ViewComponent
236
240
  end
237
241
 
238
242
  def compiled_template(file_path)
239
- handler = ActionView::Template.handler_for_extension(File.extname(file_path).gsub(".", ""))
243
+ handler = ActionView::Template.handler_for_extension(File.extname(file_path).delete("."))
240
244
  template = File.read(file_path)
245
+ template.rstrip! if component_class.strip_trailing_whitespace?
241
246
 
242
247
  if handler.method(:call).parameters.length > 1
243
248
  handler.call(component_class, template)
@@ -259,5 +264,14 @@ module ViewComponent
259
264
  "call"
260
265
  end
261
266
  end
267
+
268
+ def should_compile_superclass?
269
+ development? &&
270
+ templates.empty? &&
271
+ !(
272
+ component_class.instance_methods(false).include?(:call) ||
273
+ component_class.private_instance_methods(false).include?(:call)
274
+ )
275
+ end
262
276
  end
263
277
  end
@@ -21,7 +21,7 @@ module ViewComponent
21
21
  )
22
22
  end
23
23
 
24
- if block_given?
24
+ if block
25
25
  content = view_context.capture(&block)
26
26
  end
27
27
 
@@ -28,7 +28,7 @@ module ViewComponent
28
28
  end
29
29
 
30
30
  def types
31
- " → [#{@method.tag(:return).types.join(',')}]" if @method.tag(:return)&.types && show_types?
31
+ " → [#{@method.tag(:return).types.join(",")}]" if @method.tag(:return)&.types && show_types?
32
32
  end
33
33
 
34
34
  def signature_or_name
@@ -77,7 +77,8 @@ module ViewComponent
77
77
  options = app.config.view_component
78
78
 
79
79
  if options.show_previews && !options.preview_paths.empty?
80
- ActiveSupport::Dependencies.autoload_paths.concat(options.preview_paths)
80
+ paths_to_add = options.preview_paths - ActiveSupport::Dependencies.autoload_paths
81
+ ActiveSupport::Dependencies.autoload_paths.concat(paths_to_add) if paths_to_add.any?
81
82
  end
82
83
  end
83
84
 
@@ -133,10 +134,10 @@ module ViewComponent
133
134
 
134
135
  initializer "compiler mode" do |app|
135
136
  ViewComponent::Compiler.mode = if Rails.env.development? || Rails.env.test?
136
- ViewComponent::Compiler::DEVELOPMENT_MODE
137
- else
138
- ViewComponent::Compiler::PRODUCTION_MODE
139
- end
137
+ ViewComponent::Compiler::DEVELOPMENT_MODE
138
+ else
139
+ ViewComponent::Compiler::PRODUCTION_MODE
140
+ end
140
141
  end
141
142
 
142
143
  config.after_initialize do |app|
@@ -34,13 +34,14 @@ module ViewComponent
34
34
  def with_output_buffer(buf = nil)
35
35
  unless buf
36
36
  buf = ActionView::OutputBuffer.new
37
+ # rubocop:disable Style/SafeNavigation
37
38
  if output_buffer && output_buffer.respond_to?(:encoding)
38
39
  buf.force_encoding(output_buffer.encoding)
39
40
  end
41
+ # rubocop:enable Style/SafeNavigation
40
42
  end
41
43
 
42
44
  output_buffer.push(buf)
43
- result = nil
44
45
 
45
46
  begin
46
47
  yield
@@ -65,13 +66,13 @@ module ViewComponent
65
66
  def with_output_buffer(buf = nil)
66
67
  unless buf
67
68
  buf = ActionView::OutputBuffer.new
69
+ # rubocop:disable Style/SafeNavigation
68
70
  if @output_buffer && @output_buffer.respond_to?(:encoding)
69
71
  buf.force_encoding(@output_buffer.encoding)
70
72
  end
73
+ # rubocop:enable Style/SafeNavigation
71
74
  end
72
75
 
73
- result = nil
74
-
75
76
  if @output_buffer.is_a?(OutputBufferStack)
76
77
  @output_buffer.push(buf)
77
78
 
@@ -37,9 +37,7 @@ module ViewComponent
37
37
  end
38
38
 
39
39
  def safe_concat(arg)
40
- # rubocop:disable Rails/OutputSafety
41
40
  @current_buffer.safe_concat(arg)
42
- # rubocop:enable Rails/OutputSafety
43
41
  end
44
42
 
45
43
  def length
@@ -5,6 +5,17 @@ module ViewComponent
5
5
  # In older rails versions, using a concern isn't a good idea here because they appear to not work with
6
6
  # Module#prepend and class methods.
7
7
  def self.included(base)
8
+ if base != ViewComponent::Base
9
+ # :nocov:
10
+ location = Kernel.caller_locations(1, 1)[0]
11
+
12
+ warn(
13
+ "warning: ViewComponent::PolymorphicSlots is now included in ViewComponent::Base by default "\
14
+ "and can be removed from #{location.path}:#{location.lineno}"
15
+ )
16
+ # :nocov:
17
+ end
18
+
8
19
  base.singleton_class.prepend(ClassMethods)
9
20
  base.include(InstanceMethods)
10
21
  end
@@ -45,8 +56,12 @@ module ViewComponent
45
56
  "#{slot_name}_#{poly_type}"
46
57
  end
47
58
 
48
- # Deprecated: Will be removed in 3.0
49
59
  define_method(setter_name) do |*args, &block|
60
+ ViewComponent::Deprecation.warn(
61
+ "polymorphic slot setters like `#{setter_name}` are deprecated and will be removed in"\
62
+ "ViewComponent v3.0.0.\n\nUse `with_#{setter_name}` instead."
63
+ )
64
+
50
65
  set_polymorphic_slot(slot_name, poly_type, *args, &block)
51
66
  end
52
67
  ruby2_keywords(setter_name.to_sym) if respond_to?(:ruby2_keywords, true)
@@ -57,7 +72,7 @@ module ViewComponent
57
72
  ruby2_keywords(:"with_#{setter_name}") if respond_to?(:ruby2_keywords, true)
58
73
  end
59
74
 
60
- self.registered_slots[slot_name] = {
75
+ registered_slots[slot_name] = {
61
76
  collection: collection,
62
77
  renderable_hash: renderable_hash
63
78
  }
@@ -14,7 +14,7 @@ module ViewComponent # :nodoc:
14
14
  block: block,
15
15
  component: component,
16
16
  locals: {},
17
- template: "view_components/preview",
17
+ template: "view_components/preview"
18
18
  }
19
19
  end
20
20
 
@@ -66,10 +66,12 @@ module ViewComponent # :nodoc:
66
66
  name.chomp("Preview").underscore
67
67
  end
68
68
 
69
+ # rubocop:disable Style/TrivialAccessors
69
70
  # Setter for layout name.
70
71
  def layout(layout_name)
71
72
  @layout = layout_name
72
73
  end
74
+ # rubocop:enable Style/TrivialAccessors
73
75
 
74
76
  # Returns the relative path (from preview_path) to the preview example template if the template exists
75
77
  def preview_example_template_path(example)
@@ -87,15 +89,15 @@ module ViewComponent # :nodoc:
87
89
  end
88
90
 
89
91
  path = Dir["#{preview_path}/#{preview_name}_preview/#{example}.html.*"].first
90
- Pathname.new(path).
91
- relative_path_from(Pathname.new(preview_path)).
92
- to_s.
93
- sub(/\..*$/, "")
92
+ Pathname.new(path)
93
+ .relative_path_from(Pathname.new(preview_path))
94
+ .to_s
95
+ .sub(/\..*$/, "")
94
96
  end
95
97
 
96
98
  # Returns the method body for the example from the preview file.
97
99
  def preview_source(example)
98
- source = self.instance_method(example.to_sym).source.split("\n")
100
+ source = instance_method(example.to_sym).source.split("\n")
99
101
  source[1...(source.size - 1)].join("\n")
100
102
  end
101
103
 
@@ -3,7 +3,7 @@
3
3
  module ViewComponent
4
4
  module RenderComponentToStringHelper # :nodoc:
5
5
  def render_component_to_string(component)
6
- component.render_in(self.view_context)
6
+ component.render_in(view_context)
7
7
  end
8
8
  end
9
9
  end
@@ -4,7 +4,7 @@ module ViewComponent
4
4
  module RenderToStringMonkeyPatch # :nodoc:
5
5
  def render_to_string(options = {}, args = {})
6
6
  if options.respond_to?(:render_in)
7
- options.render_in(self.view_context)
7
+ options.render_in(view_context)
8
8
  else
9
9
  super
10
10
  end
@@ -3,7 +3,7 @@
3
3
  module ViewComponent
4
4
  module RenderingComponentHelper # :nodoc:
5
5
  def render_component(component)
6
- self.response_body = component.render_in(self.view_context)
6
+ self.response_body = component.render_in(view_context)
7
7
  end
8
8
  end
9
9
  end
@@ -4,7 +4,7 @@ module ViewComponent
4
4
  module RenderingMonkeyPatch # :nodoc:
5
5
  def render(options = {}, args = {})
6
6
  if options.respond_to?(:render_in)
7
- self.response_body = options.render_in(self.view_context)
7
+ self.response_body = options.render_in(view_context)
8
8
  else
9
9
  super
10
10
  end
@@ -30,7 +30,7 @@ module ViewComponent
30
30
 
31
31
  slot_names.each do |slot_name|
32
32
  # Ensure slot_name isn't already declared
33
- if self.slots.key?(slot_name)
33
+ if slots.key?(slot_name)
34
34
  raise ArgumentError.new("#{slot_name} slot declared multiple times")
35
35
  end
36
36
 
@@ -73,7 +73,7 @@ module ViewComponent
73
73
  class_name = "ViewComponent::Slot" unless class_name.present?
74
74
 
75
75
  # Register the slot on the component
76
- self.slots[slot_name] = {
76
+ slots[slot_name] = {
77
77
  class_name: class_name,
78
78
  instance_variable_name: instance_variable_name,
79
79
  collection: collection
@@ -84,7 +84,7 @@ module ViewComponent
84
84
  def inherited(child)
85
85
  # Clone slot configuration into child class
86
86
  # see #test_slots_pollution
87
- child.slots = self.slots.clone
87
+ child.slots = slots.clone
88
88
 
89
89
  super
90
90
  end
@@ -106,7 +106,7 @@ module ViewComponent
106
106
  #
107
107
  def slot(slot_name, **args, &block)
108
108
  # Raise ArgumentError if `slot` doesn't exist
109
- unless slots.keys.include?(slot_name)
109
+ unless slots.key?(slot_name)
110
110
  raise ArgumentError.new "Unknown slot '#{slot_name}' - expected one of '#{slots.keys}'"
111
111
  end
112
112
 
@@ -123,8 +123,7 @@ module ViewComponent
123
123
  slot_instance = args.present? ? slot_class.new(**args) : slot_class.new
124
124
 
125
125
  # Capture block and assign to slot_instance#content
126
- # rubocop:disable Rails/OutputSafety
127
- slot_instance.content = view_context.capture(&block).to_s.strip.html_safe if block_given?
126
+ slot_instance.content = view_context.capture(&block).to_s.strip.html_safe if block
128
127
 
129
128
  if slot[:collection]
130
129
  # Initialize instance variable as an empty array
@@ -9,7 +9,7 @@ module ViewComponent
9
9
 
10
10
  RESERVED_NAMES = {
11
11
  singular: %i[content render].freeze,
12
- plural: %i[contents renders].freeze,
12
+ plural: %i[contents renders].freeze
13
13
  }.freeze
14
14
 
15
15
  # Setup component slot state
@@ -190,20 +190,20 @@ module ViewComponent
190
190
  # Clone slot configuration into child class
191
191
  # see #test_slots_pollution
192
192
  def inherited(child)
193
- child.registered_slots = self.registered_slots.clone
193
+ child.registered_slots = registered_slots.clone
194
194
  super
195
195
  end
196
196
 
197
197
  private
198
198
 
199
199
  def register_slot(slot_name, **kwargs)
200
- self.registered_slots[slot_name] = define_slot(slot_name, **kwargs)
200
+ registered_slots[slot_name] = define_slot(slot_name, **kwargs)
201
201
  end
202
202
 
203
203
  def define_slot(slot_name, collection:, callable:)
204
204
  # Setup basic slot data
205
205
  slot = {
206
- collection: collection,
206
+ collection: collection
207
207
  }
208
208
  return slot unless callable
209
209
 
@@ -254,7 +254,7 @@ module ViewComponent
254
254
  end
255
255
 
256
256
  def raise_if_slot_registered(slot_name)
257
- if self.registered_slots.key?(slot_name)
257
+ if registered_slots.key?(slot_name)
258
258
  # TODO remove? This breaks overriding slots when slots are inherited
259
259
  raise ArgumentError.new(
260
260
  "#{self} declares the #{slot_name} slot multiple times.\n\n" \
@@ -287,8 +287,6 @@ module ViewComponent
287
287
 
288
288
  if slot[:collection]
289
289
  []
290
- else
291
- nil
292
290
  end
293
291
  end
294
292
 
@@ -305,7 +303,7 @@ module ViewComponent
305
303
  # 2. Since we've to pass block content to components when calling
306
304
  # `render`, evaluating the block here would require us to call
307
305
  # `view_context.capture` twice, which is slower
308
- slot.__vc_content_block = block if block_given?
306
+ slot.__vc_content_block = block if block
309
307
 
310
308
  # If class
311
309
  if slot_definition[:renderable]
@@ -321,7 +319,7 @@ module ViewComponent
321
319
  # methods like `content_tag` as well as parent component state.
322
320
  renderable_function = slot_definition[:renderable_function].bind(self)
323
321
  renderable_value =
324
- if block_given?
322
+ if block
325
323
  renderable_function.call(*args) do |*rargs|
326
324
  view_context.capture(*rargs, &block)
327
325
  end
@@ -1,15 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "view_component/render_preview_helper"
4
+ require "view_component/capybara_simple_session"
4
5
 
5
6
  module ViewComponent
6
7
  module TestHelpers
7
8
  begin
8
9
  require "capybara/minitest"
10
+
9
11
  include Capybara::Minitest::Assertions
10
12
 
13
+ CapybaraSimpleSession::DSL_METHODS.each do |method|
14
+ if RUBY_VERSION >= "2.7"
15
+ class_eval <<~METHOD, __FILE__, __LINE__ + 1
16
+ def #{method}(...)
17
+ page.method("#{method}").call(...)
18
+ end
19
+ METHOD
20
+ else
21
+ define_method method do |*args, &block|
22
+ page.send method, *args, &block
23
+ end
24
+ end
25
+ end
26
+
27
+ def self.included(mod)
28
+ Capybara::Node::Simple.send(:define_method, :to_capybara_node) do
29
+ self
30
+ end
31
+ end
32
+
11
33
  def page
12
- Capybara::Node::Simple.new(@rendered_content)
34
+ @page ||= CapybaraSimpleSession.new(rendered_content)
13
35
  end
14
36
 
15
37
  def refute_component_rendered
@@ -32,6 +54,9 @@ module ViewComponent
32
54
  # @private
33
55
  attr_reader :rendered_content
34
56
 
57
+ # Returns the result of a render_inline call.
58
+ #
59
+ # @return [String]
35
60
  def rendered_component
36
61
  ViewComponent::Deprecation.warn(
37
62
  "`rendered_component` is deprecated and will be removed in v3.0.0. " \
@@ -52,6 +77,7 @@ module ViewComponent
52
77
  # @param component [ViewComponent::Base, ViewComponent::Collection] The instance of the component to be rendered.
53
78
  # @return [Nokogiri::HTML]
54
79
  def render_inline(component, **args, &block)
80
+ @page = nil
55
81
  @rendered_content =
56
82
  if Rails.version.to_f >= 6.1
57
83
  controller.view_context.render(component, args, &block)
@@ -73,6 +99,7 @@ module ViewComponent
73
99
  # assert_text("Hello, World!")
74
100
  # ```
75
101
  def render_in_view_context(&block)
102
+ @page = nil
76
103
  @rendered_content = controller.view_context.instance_exec(&block)
77
104
  Nokogiri::HTML.fragment(@rendered_content)
78
105
  end
@@ -9,7 +9,7 @@ module ViewComponent
9
9
  module Translatable
10
10
  extend ActiveSupport::Concern
11
11
 
12
- HTML_SAFE_TRANSLATION_KEY = /(?:_|\b)html\z/.freeze
12
+ HTML_SAFE_TRANSLATION_KEY = /(?:_|\b)html\z/
13
13
 
14
14
  included do
15
15
  class_attribute :i18n_backend, instance_writer: false, instance_predicate: false
@@ -23,14 +23,13 @@ module ViewComponent
23
23
  def build_i18n_backend
24
24
  return if CompileCache.compiled? self
25
25
 
26
- if (translation_files = _sidecar_files(%w[yml yaml])).any?
27
- self.i18n_backend = I18nBackend.new(
26
+ self.i18n_backend = if (translation_files = _sidecar_files(%w[yml yaml])).any?
27
+ # Returning nil cleans up if translations file has been removed since the last compilation
28
+
29
+ I18nBackend.new(
28
30
  i18n_scope: i18n_scope,
29
- load_paths: translation_files,
31
+ load_paths: translation_files
30
32
  )
31
- else
32
- # Cleanup if translations file has been removed since the last compilation
33
- self.i18n_backend = nil
34
33
  end
35
34
  end
36
35
  end
@@ -50,7 +49,7 @@ module ViewComponent
50
49
 
51
50
  def scope_data(data)
52
51
  @i18n_scope.reverse_each do |part|
53
- data = { part => data }
52
+ data = {part => data}
54
53
  end
55
54
  data
56
55
  end
@@ -95,7 +94,7 @@ module ViewComponent
95
94
  super(key, locale: locale, **options)
96
95
  end
97
96
  end
98
- alias :t :translate
97
+ alias_method :t, :translate
99
98
 
100
99
  # Exposes .i18n_scope as an instance method
101
100
  def i18n_scope
@@ -109,7 +108,7 @@ module ViewComponent
109
108
  # It's assumed here that objects loaded by the i18n backend will respond to `#html_safe?`.
110
109
  # It's reasonable that if we're in Rails, `active_support/core_ext/string/output_safety.rb`
111
110
  # will provide this to `Object`.
112
- translation.html_safe # rubocop:disable Rails/OutputSafety
111
+ translation.html_safe
113
112
  end
114
113
  end
115
114
 
@@ -3,7 +3,7 @@
3
3
  module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 2
6
- MINOR = 57
6
+ MINOR = 59
7
7
  PATCH = 0
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
@@ -7,6 +7,7 @@ module ViewComponent
7
7
  extend ActiveSupport::Autoload
8
8
 
9
9
  autoload :Base
10
+ autoload :CapybaraSimpleSession
10
11
  autoload :Compiler
11
12
  autoload :CompileCache
12
13
  autoload :ComponentError
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_component
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.57.0
4
+ version: 2.59.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-10 00:00:00.000000000 Z
11
+ date: 2022-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -185,19 +185,19 @@ dependencies:
185
185
  - !ruby/object:Gem::Version
186
186
  version: '13.0'
187
187
  - !ruby/object:Gem::Dependency
188
- name: rubocop-github
188
+ name: standard
189
189
  requirement: !ruby/object:Gem::Requirement
190
190
  requirements:
191
191
  - - "~>"
192
192
  - !ruby/object:Gem::Version
193
- version: 0.16.1
193
+ version: '1'
194
194
  type: :development
195
195
  prerelease: false
196
196
  version_requirements: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - "~>"
199
199
  - !ruby/object:Gem::Version
200
- version: 0.16.1
200
+ version: '1'
201
201
  - !ruby/object:Gem::Dependency
202
202
  name: simplecov
203
203
  requirement: !ruby/object:Gem::Requirement
@@ -325,6 +325,7 @@ files:
325
325
  - lib/rails/generators/test_unit/templates/component_test.rb.tt
326
326
  - lib/view_component.rb
327
327
  - lib/view_component/base.rb
328
+ - lib/view_component/capybara_simple_session.rb
328
329
  - lib/view_component/collection.rb
329
330
  - lib/view_component/compile_cache.rb
330
331
  - lib/view_component/compiler.rb