view_component 2.57.0 → 2.59.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 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