view_component 4.2.0 → 4.4.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: 79d1337f1589a6e9ec7617c7d07917825c4f90b2e6093e6e925ef9fad3e06937
4
- data.tar.gz: aaa0ddcd3a30c628409a4001efdd99c702ff5b97ff7873a3f3e092e05b54c3f6
3
+ metadata.gz: c3a3df2973d8a5830f14e1ec81396eb006e254a6d0092022686279231edc7fa1
4
+ data.tar.gz: 7633b908531c74612dab36a40f5d56efd2cb4e89cd89a7d476446cc758172673
5
5
  SHA512:
6
- metadata.gz: 98381938a50a979a6ee135dff98c4e3b13a4a1b5ac8ee2f19c7e5f9b1bdc04470b355c55696d2724c733fab29a9379fe59c0a8e4273374e9db5210202be2dc06
7
- data.tar.gz: 0b5276ff41b7b7ff493f935c75e8c3e8cc604decc42a950c97f1da3becccfba3446b40178c35b9b54578a47f3718bfa53ba2c6e91ec7b929a6adc7f26f41f782
6
+ metadata.gz: c4e3496a4dd6acd8568d81ea39f69fd960e5dfc1297c008bbb83b3b946ca7f311093dee3cf129c0df77427394ba60e45407c6542e6132d6493b3748b11a483f2
7
+ data.tar.gz: 71edfce3f459946670adf0f7c96eefdb4e811d1a2a9ca613fbfd40697526d5bdf3ed204855171ebd3e2291e17b0a10bcbc0d6ea08d40515a0d2b370a454f9005
data/docs/CHANGELOG.md CHANGED
@@ -10,6 +10,34 @@ nav_order: 6
10
10
 
11
11
  ## main
12
12
 
13
+ ## 4.4.0
14
+
15
+ * Fix segfaults when Ruby coverage is enabled.
16
+
17
+ *George Holborn*, *Joel Hawksley*
18
+
19
+ * Add `protocol` parameter to `with_request_url` test helper to enable testing with HTTPS protocol.
20
+
21
+ *Joel Hawksley*
22
+
23
+ ## 4.3.0
24
+
25
+ * Fix load order issues for 3rd-party template handlers.
26
+
27
+ *Cameron Dutro*
28
+
29
+ * Fix segfault when Ruby coverage is enabled with Rails 8.1 ERB templates.
30
+
31
+ *George Holborn*
32
+
33
+ * Automatically merge dependabot PRs.
34
+
35
+ *Joel Hawksley*
36
+
37
+ * Use Ruby 4.0.0 in CI and dev.
38
+
39
+ *Joel Hawksley*
40
+
13
41
  ## 4.2.0
14
42
 
15
43
  * Fix translation scope resolution in deeply nested component blocks (3+ levels). Translations called inside deeply nested slot blocks using `renders_many`/`renders_one` were incorrectly resolving to an intermediate component's scope instead of the partial's scope where the block was defined. The fix captures the virtual path at block definition time and restores it during block execution, ensuring translations always resolve relative to where the block was created regardless of nesting depth.
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "action_view"
4
+ require "action_view/base"
4
5
  require "view_component/collection"
5
6
  require "view_component/compile_cache"
6
7
  require "view_component/compiler"
@@ -577,7 +578,7 @@ module ViewComponent
577
578
  # eager loading is disabled and the parent component is rendered before the child. In
578
579
  # such a scenario, the parent will override ViewComponent::Base#render_template_for,
579
580
  # meaning it will not be called for any children and thus not compile their templates.
580
- if !child.instance_methods(false).include?(:render_template_for) && !child.__vc_compiled?
581
+ if !child.method_defined?(:render_template_for, false) && !child.__vc_compiled?
581
582
  child.class_eval <<~RUBY, __FILE__, __LINE__ + 1
582
583
  def render_template_for(requested_details)
583
584
  # Force compilation here so the compiler always redefines render_template_for.
@@ -600,7 +601,7 @@ module ViewComponent
600
601
  # Set collection parameter to the extended component
601
602
  child.with_collection_parameter(__vc_provided_collection_parameter)
602
603
 
603
- if instance_methods(false).include?(:render_template_for)
604
+ if method_defined?(:render_template_for, false)
604
605
  vc_ancestor_calls = defined?(@__vc_ancestor_calls) ? @__vc_ancestor_calls.dup : []
605
606
 
606
607
  vc_ancestor_calls.unshift(instance_method(:render_template_for))
@@ -115,11 +115,11 @@ module ViewComponent
115
115
  .tally
116
116
  .select { |_, count| count > 1 }
117
117
  .each do |tally|
118
- variant, this_format = tally.first
118
+ variant, this_format = tally.first
119
119
 
120
- variant_string = " for variant `#{variant}`" if variant.present?
120
+ variant_string = " for variant `#{variant}`" if variant.present?
121
121
 
122
- errors << "More than one #{this_format.upcase} template found#{variant_string} for #{@component}. "
122
+ errors << "More than one #{this_format.upcase} template found#{variant_string} for #{@component}. "
123
123
  end
124
124
 
125
125
  default_template_types = @templates.each_with_object(Set.new) do |template, memo|
@@ -190,11 +190,11 @@ module ViewComponent
190
190
  ).flat_map { |ancestor| ancestor.instance_methods(false).grep(/^call(_|$)/) }
191
191
  .uniq
192
192
  .each do |method_name|
193
- templates << Template::InlineCall.new(
194
- component: @component,
195
- method_name: method_name,
196
- defined_on_self: component_instance_methods_on_self.include?(method_name)
197
- )
193
+ templates << Template::InlineCall.new(
194
+ component: @component,
195
+ method_name: method_name,
196
+ defined_on_self: component_instance_methods_on_self.include?(method_name)
197
+ )
198
198
  end
199
199
 
200
200
  templates
@@ -259,7 +259,7 @@ module ViewComponent
259
259
 
260
260
  setter_method_name = :"with_#{poly_slot_name}"
261
261
 
262
- if instance_methods.include?(setter_method_name)
262
+ if method_defined?(setter_method_name)
263
263
  raise AlreadyDefinedPolymorphicSlotSetterError.new(setter_method_name, poly_slot_name)
264
264
  end
265
265
 
@@ -21,11 +21,23 @@ module ViewComponent
21
21
 
22
22
  class File < Template
23
23
  def initialize(component:, details:, path:)
24
- # Rails 8.1 added a newline to the compiled ERB output in
25
- # https://github.com/rails/rails/pull/53731
24
+ @strip_annotation_line = false
25
+
26
+ # Rails 8.1 added a newline to compiled ERB output (rails/rails#53731).
27
+ # Use -1 to compensate for correct line numbers in stack traces.
28
+ # However, negative line numbers cause segfaults when Ruby's coverage
29
+ # is enabled (bugs.ruby-lang.org/issues/19363). In that case, strip the
30
+ # annotation line from compiled source instead.
26
31
  lineno =
27
32
  if Rails::VERSION::MAJOR >= 8 && Rails::VERSION::MINOR > 0 && details.handler == :erb
28
- - 1
33
+ if coverage_running?
34
+ # Can't use negative lineno with coverage (causes segfault on Linux).
35
+ # Strip annotation line if enabled to preserve correct line numbers.
36
+ @strip_annotation_line = ActionView::Base.annotate_rendered_view_with_filenames
37
+ 0
38
+ else
39
+ -1
40
+ end
29
41
  else
30
42
  0
31
43
  end
@@ -46,6 +58,16 @@ module ViewComponent
46
58
  def source
47
59
  ::File.read(@path)
48
60
  end
61
+
62
+ private
63
+
64
+ def compiled_source
65
+ result = super
66
+ # Strip the annotation line to maintain correct line numbers when coverage
67
+ # is running (avoids segfault from negative lineno)
68
+ result = result.partition(";").last if @strip_annotation_line
69
+ result
70
+ end
49
71
  end
50
72
 
51
73
  class Inline < Template
@@ -54,8 +76,10 @@ module ViewComponent
54
76
  def initialize(component:, inline_template:)
55
77
  details = ActionView::TemplateDetails.new(nil, inline_template.language.to_sym, nil, nil)
56
78
 
57
- # Rails 8.1 added a newline to the compiled ERB output in
58
- # https://github.com/rails/rails/pull/53731
79
+ # Rails 8.1 added a newline to compiled ERB output (rails/rails#53731).
80
+ # Subtract 1 to compensate for correct line numbers in stack traces.
81
+ # Inline templates start at line 2+ (defined inside a class), so this
82
+ # won't result in negative line numbers that cause segfaults with coverage.
59
83
  lineno =
60
84
  if Rails::VERSION::MAJOR >= 8 && Rails::VERSION::MINOR > 0 && details.handler == :erb
61
85
  inline_template.lineno - 1
@@ -126,6 +150,10 @@ module ViewComponent
126
150
  @component.define_method(safe_method_name, @component.instance_method(@call_method_name))
127
151
  end
128
152
 
153
+ def coverage_running?
154
+ defined?(Coverage) && Coverage.running?
155
+ end
156
+
129
157
  def safe_method_name_call
130
158
  m = safe_method_name
131
159
  proc { send(m) }
@@ -196,10 +196,19 @@ module ViewComponent
196
196
  # end
197
197
  # ```
198
198
  #
199
+ # To specify a protocol, pass the protocol param:
200
+ #
201
+ # ```ruby
202
+ # with_request_url("/users/42", protocol: :https) do
203
+ # render_inline(MyComponent.new)
204
+ # end
205
+ # ```
206
+ #
199
207
  # @param full_path [String] The path to set for the current request.
200
208
  # @param host [String] The host to set for the current request.
201
209
  # @param method [String] The request method to set for the current request.
202
- def with_request_url(full_path, host: nil, method: nil)
210
+ # @param protocol [Symbol] The protocol to set for the current request (e.g., `:http` or `:https`).
211
+ def with_request_url(full_path, host: nil, method: nil, protocol: nil)
203
212
  old_request_host = vc_test_request.host
204
213
  old_request_method = vc_test_request.request_method
205
214
  old_request_path_info = vc_test_request.path_info
@@ -207,6 +216,7 @@ module ViewComponent
207
216
  old_request_query_parameters = vc_test_request.query_parameters
208
217
  old_request_query_string = vc_test_request.query_string
209
218
  old_request_format = vc_test_request.format.symbol
219
+ old_request_scheme = vc_test_request.scheme
210
220
  old_controller = defined?(@vc_test_controller) && @vc_test_controller
211
221
 
212
222
  path, query = full_path.split("?", 2)
@@ -214,6 +224,7 @@ module ViewComponent
214
224
  vc_test_request.instance_variable_set(:@original_fullpath, full_path)
215
225
  vc_test_request.host = host if host
216
226
  vc_test_request.request_method = method if method
227
+ vc_test_request.set_header(Rack::RACK_URL_SCHEME, protocol.to_s) if protocol
217
228
  vc_test_request.path_info = path
218
229
  vc_test_request.path_parameters = Rails.application.routes.recognize_path_with_request(vc_test_request, path, {})
219
230
  vc_test_request.set_header("action_dispatch.request.query_parameters",
@@ -223,6 +234,7 @@ module ViewComponent
223
234
  ensure
224
235
  vc_test_request.host = old_request_host
225
236
  vc_test_request.request_method = old_request_method
237
+ vc_test_request.set_header(Rack::RACK_URL_SCHEME, old_request_scheme)
226
238
  vc_test_request.path_info = old_request_path_info
227
239
  vc_test_request.path_parameters = old_request_path_parameters
228
240
  vc_test_request.set_header("action_dispatch.request.query_parameters", old_request_query_parameters)
@@ -3,7 +3,7 @@
3
3
  module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 4
6
- MINOR = 2
6
+ MINOR = 4
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_component
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.0
4
+ version: 4.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ViewComponent Team
@@ -135,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
135
  - !ruby/object:Gem::Version
136
136
  version: '0'
137
137
  requirements: []
138
- rubygems_version: 3.6.9
138
+ rubygems_version: 4.0.3
139
139
  specification_version: 4
140
140
  summary: A framework for building reusable, testable & encapsulated view components
141
141
  in Ruby on Rails.