Skip to content

Commit 65e22b4

Browse files
committed
wip
1 parent e55c22f commit 65e22b4

19 files changed

Lines changed: 145 additions & 12 deletions

.github/workflows/lint.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,6 @@ jobs:
8989
bundle update
9090
bundle exec standardrb -r "rubocop-md"
9191
bundle exec erb_lint --lint-all
92+
bundle exec yard-lint lib/view_component/
9293
env:
9394
RAILS_VERSION: '~> 8'

.yard-lint.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
AllValidators:
2+
Exclude:
3+
- '\.git'
4+
- 'vendor/**/*'
5+
- 'spec/**/*'
6+
- 'test/**/*'
7+
- 'lib/docs/**/*'
8+
- 'lib/generators/**/*'
9+
- 'lib/yard/**/*'
10+
11+
FailOnSeverity: warning
12+
13+
Documentation/UndocumentedObjects:
14+
Enabled: false
15+
16+
Documentation/UndocumentedBooleanMethods:
17+
Enabled: false

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ group :development, :test do
4747
gem "warning"
4848
gem "yard-activesupport-concern", "< 1"
4949
gem "yard", "< 1"
50+
gem "yard-lint", "< 1"
5051
end

Gemfile.lock

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ GEM
184184
matrix (0.4.3)
185185
method_source (1.1.0)
186186
mini_mime (1.1.5)
187-
mini_portile2 (2.8.9)
188187
minitest (6.0.2)
189188
drb (~> 2.0)
190189
prism (~> 1.5)
@@ -199,9 +198,6 @@ GEM
199198
net-smtp (0.5.1)
200199
net-protocol
201200
nio4r (2.7.5)
202-
nokogiri (1.19.1)
203-
mini_portile2 (~> 2.8.2)
204-
racc (~> 1.4)
205201
nokogiri (1.19.1-aarch64-linux-gnu)
206202
racc (~> 1.4)
207203
nokogiri (1.19.1-aarch64-linux-musl)
@@ -413,6 +409,9 @@ GEM
413409
yard (0.9.38)
414410
yard-activesupport-concern (0.0.1)
415411
yard (>= 0.8)
412+
yard-lint (0.2.1)
413+
yard (~> 0.9)
414+
zeitwerk (~> 2.6)
416415
zeitwerk (2.7.4)
417416

418417
PLATFORMS
@@ -464,6 +463,7 @@ DEPENDENCIES
464463
warning
465464
yard (< 1)
466465
yard-activesupport-concern (< 1)
466+
yard-lint (< 1)
467467

468468
CHECKSUMS
469469
action_text-trix (2.1.16) sha256=f645a2c21821b8449fd1d6770708f4031c91a2eedf9ef476e9be93c64e703a8a
@@ -529,15 +529,13 @@ CHECKSUMS
529529
matrix (0.4.3) sha256=a0d5ab7ddcc1973ff690ab361b67f359acbb16958d1dc072b8b956a286564c5b
530530
method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5
531531
mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef
532-
mini_portile2 (2.8.9) sha256=0cd7c7f824e010c072e33f68bc02d85a00aeb6fce05bb4819c03dfd3c140c289
533532
minitest (6.0.2) sha256=db6e57956f6ecc6134683b4c87467d6dd792323c7f0eea7b93f66bd284adbc3d
534533
minitest-mock (5.27.0) sha256=7040ed7185417a966920987eaa6eaf1be4ea1fc5b25bb03ff4703f98564a55b0
535534
net-imap (0.6.2) sha256=08caacad486853c61676cca0c0c47df93db02abc4a8239a8b67eb0981428acc6
536535
net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3
537536
net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8
538537
net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736
539538
nio4r (2.7.5) sha256=6c90168e48fb5f8e768419c93abb94ba2b892a1d0602cb06eef16d8b7df1dca1
540-
nokogiri (1.19.1) sha256=598b327f36df0b172abd57b68b18979a6e14219353bca87180c31a51a00d5ad3
541539
nokogiri (1.19.1-aarch64-linux-gnu) sha256=cfdb0eafd9a554a88f12ebcc688d2b9005f9fce42b00b970e3dc199587b27f32
542540
nokogiri (1.19.1-aarch64-linux-musl) sha256=1e2150ab43c3b373aba76cd1190af7b9e92103564063e48c474f7600923620b5
543541
nokogiri (1.19.1-arm-linux-gnu) sha256=0a39ed59abe3bf279fab9dd4c6db6fe8af01af0608f6e1f08b8ffa4e5d407fa3
@@ -627,6 +625,7 @@ CHECKSUMS
627625
xpath (3.2.0) sha256=6dfda79d91bb3b949b947ecc5919f042ef2f399b904013eb3ef6d20dd3a4082e
628626
yard (0.9.38) sha256=721fb82afb10532aa49860655f6cc2eaa7130889df291b052e1e6b268283010f
629627
yard-activesupport-concern (0.0.1) sha256=be790cb0efc23e2e87677063598ac8b743586154657bbd9655a7f03ce78390ef
628+
yard-lint (0.2.1) sha256=7d2d374ff6ead506ca00a417bf1e49e45a562368f366fa8f6326ffb76b8a0d20
630629
zeitwerk (2.7.4) sha256=2bef90f356bdafe9a6c2bd32bcd804f83a4f9b8bc27f3600fff051eb3edcec8b
631630

632631
RUBY VERSION

lib/view_component/base.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
module ActionView
1919
class OutputBuffer
20+
# @param buf [String, nil] optional buffer to use
2021
def with_buffer(buf = nil)
2122
new_buffer = buf || +""
2223
old_buffer, @raw_buffer = @raw_buffer, new_buffer
@@ -101,6 +102,8 @@ def initialize
101102
#
102103
# Returns HTML that has been escaped by the respective template handler.
103104
#
105+
# @param view_context [ActionView::Base] ActionView context from calling view
106+
# @param block [Proc] optional block to be captured within the view context
104107
# @return [String]
105108
def render_in(view_context, &block)
106109
self.class.__vc_compile(raise_errors: true)
@@ -251,6 +254,9 @@ def render?
251254
# to maintain backwards compatibility.
252255
#
253256
# @private
257+
# @param options [Object] render options or component
258+
# @param args [Hash] additional arguments
259+
# @param block [Proc] optional block
254260
def render(options = {}, args = {}, &block)
255261
if options.respond_to?(:set_original_view_context)
256262
options.set_original_view_context(self.__vc_original_view_context)
@@ -306,6 +312,8 @@ def helpers
306312

307313
if defined?(Rails.env) && (::Rails.env.development? || ::Rails.env.test?)
308314
# @private
315+
# @param method_name [Symbol] the missing method name
316+
# @param args [Array] positional arguments
309317
def method_missing(method_name, *args) # rubocop:disable Style/MissingRespondToMissing
310318
super
311319
rescue => e # rubocop:disable Style/RescueStandardError
@@ -382,6 +390,7 @@ def content?
382390
# @private
383391
# Temporarily sets the virtual path to the captured value, then restores it.
384392
# This ensures translations and other path-dependent code execute with the correct scope.
393+
# @param captured_path [String] the virtual path to set
385394
def with_captured_virtual_path(captured_path)
386395
old_virtual_path = @view_context.instance_variable_get(:@virtual_path)
387396
@view_context.instance_variable_set(:@virtual_path, captured_path)
@@ -564,11 +573,14 @@ def with_collection(collection, spacer_component: nil, **args)
564573
end
565574

566575
# @private
576+
# @param raise_errors [Boolean] whether to raise on compile errors
577+
# @param force [Boolean] whether to force recompilation
567578
def __vc_compile(raise_errors: false, force: false)
568579
__vc_compiler.compile(raise_errors: raise_errors, force: force)
569580
end
570581

571582
# @private
583+
# @param child [Class] the inheriting class
572584
def inherited(child)
573585
# Compile so child will inherit compiled `call_*` template methods that
574586
# `compile` defines
@@ -674,6 +686,7 @@ def strip_trailing_whitespace?
674686
# is accepted, as support for collection
675687
# rendering is optional.
676688
# @private
689+
# @param validate_default [Boolean] whether to validate the default parameter name
677690
def __vc_validate_collection_parameter!(validate_default: false)
678691
parameter = validate_default ? __vc_collection_parameter : __vc_provided_collection_parameter
679692

lib/view_component/collection.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ class Collection
1010

1111
delegate :size, to: :@collection
1212

13+
# @param view_context [ActionView::Base] the view context
14+
# @param block [Proc] optional block
1315
def render_in(view_context, &block)
1416
components.map do |component|
1517
component.render_in(view_context, &block)
1618
end.join(rendered_spacer(view_context)).html_safe
1719
end
1820

21+
# @param block [Proc] the iteration block
1922
def each(&block)
2023
components.each(&block)
2124
end

lib/view_component/compile_cache.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ module CompileCache
1010

1111
module_function
1212

13+
# @param klass [Class] the component class to register
1314
def register(klass)
1415
cache << klass
1516
end
1617

18+
# @param klass [Class] the component class to check
1719
def compiled?(klass)
1820
cache.include? klass
1921
end
2022

23+
# @param klass [Class] the component class to invalidate
2124
def invalidate_class!(klass)
2225
cache.delete(klass)
2326
end

lib/view_component/compiler.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class Compiler
1010
# * false(a non-blocking mode, default in Rails production mode)
1111
class_attribute :__vc_development_mode, default: false
1212

13+
# @param component [Class] the component class to compile
1314
def initialize(component)
1415
@component = component
1516
@lock = Mutex.new
@@ -19,6 +20,8 @@ def compiled?
1920
CompileCache.compiled?(@component)
2021
end
2122

23+
# @param raise_errors [Boolean] whether to raise on template errors
24+
# @param force [Boolean] whether to force recompilation
2225
def compile(raise_errors: false, force: false)
2326
return if compiled? && !force
2427
return if @component == ViewComponent::Base
@@ -57,9 +60,8 @@ def compile(raise_errors: false, force: false)
5760
end
5861
end
5962

63+
# @param requested_details [ActionView::TemplateDetails::Requested] i.e. locales, formats, variants
6064
# @return all matching compiled templates, in priority order based on the requested details from LookupContext
61-
#
62-
# @param [ActionView::TemplateDetails::Requested] requested_details i.e. locales, formats, variants
6365
def find_templates_for(requested_details)
6466
filtered_templates = @templates.select do |template|
6567
template.details.matches?(requested_details)

lib/view_component/errors.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@ class DuplicateSlotContentError < StandardError
1111
"which means that ViewComponent doesn't know which content to use.\n\n" \
1212
"To fix this issue, use either `with_content` or a block."
1313

14+
# @param klass_name [String] the name of the component class
1415
def initialize(klass_name)
1516
super(MESSAGE.gsub("COMPONENT", klass_name.to_s))
1617
end
1718
end
1819

1920
class TemplateError < StandardError
21+
# @param errors [Array<String>] the list of template errors
22+
# @param templates [Array, nil] the associated templates
2023
def initialize(errors, templates = nil)
2124
message = errors.join("\n")
2225

@@ -33,6 +36,7 @@ class MissingPreviewTemplateError < StandardError
3336
"A preview template for example EXAMPLE doesn't exist.\n\n" \
3437
"To fix this issue, create a template for the example."
3538

39+
# @param example [String] the name of the preview example
3640
def initialize(example)
3741
super(MESSAGE.gsub("EXAMPLE", example))
3842
end
@@ -43,6 +47,8 @@ class MissingTemplateError < StandardError
4347
"No templates for COMPONENT match the request DETAIL.\n\n" \
4448
"To fix this issue, provide a suitable template."
4549

50+
# @param component [String] the component identifier
51+
# @param request_detail [Object] the request detail constraints
4652
def initialize(component, request_detail)
4753
detail = {
4854
locale: request_detail.locale,
@@ -60,6 +66,7 @@ class DuplicateContentError < StandardError
6066
"which means that ViewComponent doesn't know which content to use.\n\n" \
6167
"To fix this issue, use either `with_content` or a block."
6268

69+
# @param klass_name [String] the name of the component class
6370
def initialize(klass_name)
6471
super(MESSAGE.gsub("COMPONENT", klass_name.to_s))
6572
end
@@ -72,6 +79,8 @@ class MissingCollectionArgumentError < StandardError
7279
"To fix this issue, update the initializer to accept `PARAMETER`.\n\n" \
7380
"See [the collections docs](https://viewcomponent.org/guide/collections.html) for more information on rendering collections."
7481

82+
# @param klass_name [String] the name of the component class
83+
# @param parameter [Symbol] the missing collection parameter
7584
def initialize(klass_name, parameter)
7685
super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("PARAMETER", parameter.to_s))
7786
end
@@ -82,6 +91,8 @@ class ReservedParameterError < StandardError
8291
"COMPONENT initializer can't accept the parameter `PARAMETER`, as it will override a " \
8392
"public ViewComponent method. To fix this issue, rename the parameter."
8493

94+
# @param klass_name [String] the name of the component class
95+
# @param parameter [Symbol] the reserved parameter name
8596
def initialize(klass_name, parameter)
8697
super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("PARAMETER", parameter.to_s))
8798
end
@@ -99,6 +110,7 @@ class ContentSlotNameError < StandardError
99110
"Content passed to a ViewComponent as a block is captured and assigned to the `content` accessor without having to create an explicit slot.\n\n" \
100111
"To fix this issue, either use the `content` accessor directly or choose a different slot name."
101112

113+
# @param klass_name [String] the name of the component class
102114
def initialize(klass_name)
103115
super(MESSAGE.gsub("COMPONENT", klass_name.to_s))
104116
end
@@ -120,6 +132,8 @@ class SlotPredicateNameError < InvalidSlotNameError
120132
"methods ending in `?`.\n\n" \
121133
"To fix this issue, choose a different name."
122134

135+
# @param klass_name [String] the name of the component class
136+
# @param slot_name [Symbol] the invalid slot name
123137
def initialize(klass_name, slot_name)
124138
super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s))
125139
end
@@ -130,6 +144,8 @@ class RedefinedSlotError < StandardError
130144
"COMPONENT declares the SLOT_NAME slot multiple times.\n\n" \
131145
"To fix this issue, choose a different slot name."
132146

147+
# @param klass_name [String] the name of the component class
148+
# @param slot_name [Symbol] the redefined slot name
133149
def initialize(klass_name, slot_name)
134150
super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s))
135151
end
@@ -140,6 +156,8 @@ class ReservedSingularSlotNameError < InvalidSlotNameError
140156
"COMPONENT declares a slot named SLOT_NAME, which is a reserved word in the ViewComponent framework.\n\n" \
141157
"To fix this issue, choose a different name."
142158

159+
# @param klass_name [String] the name of the component class
160+
# @param slot_name [Symbol] the reserved slot name
143161
def initialize(klass_name, slot_name)
144162
super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s))
145163
end
@@ -150,6 +168,8 @@ class ReservedPluralSlotNameError < InvalidSlotNameError
150168
"COMPONENT declares a slot named SLOT_NAME, which is a reserved word in the ViewComponent framework.\n\n" \
151169
"To fix this issue, choose a different name."
152170

171+
# @param klass_name [String] the name of the component class
172+
# @param slot_name [Symbol] the reserved slot name
153173
def initialize(klass_name, slot_name)
154174
super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s))
155175
end
@@ -160,6 +180,8 @@ class UncountableSlotNameError < InvalidSlotNameError
160180
"COMPONENT declares a slot named SLOT_NAME, which is an uncountable word\n\n" \
161181
"To fix this issue, choose a different name."
162182

183+
# @param klass_name [String] the name of the component class
184+
# @param slot_name [Symbol] the uncountable slot name
163185
def initialize(klass_name, slot_name)
164186
super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s))
165187
end
@@ -168,6 +190,7 @@ def initialize(klass_name, slot_name)
168190
class ContentAlreadySetForPolymorphicSlotError < StandardError
169191
MESSAGE = "Content for slot SLOT_NAME has already been provided."
170192

193+
# @param slot_name [Symbol] the polymorphic slot name
171194
def initialize(slot_name)
172195
super(MESSAGE.gsub("SLOT_NAME", slot_name.to_s))
173196
end
@@ -215,6 +238,8 @@ class AlreadyDefinedPolymorphicSlotSetterError < StandardError
215238
"A method called 'SETTER_METHOD_NAME' already exists and would be overwritten by the 'SETTER_NAME' polymorphic " \
216239
"slot setter.\n\nPlease choose a different setter name."
217240

241+
# @param setter_method_name [Symbol] the existing method name
242+
# @param setter_name [Symbol] the polymorphic slot setter name
218243
def initialize(setter_method_name, setter_name)
219244
super(MESSAGE.gsub("SETTER_METHOD_NAME", setter_method_name.to_s).gsub("SETTER_NAME", setter_name.to_s))
220245
end

lib/view_component/inline_template.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ module InlineTemplate
77
Template = Struct.new(:source, :language, :path, :lineno)
88

99
class_methods do
10+
# @param method [Symbol] the method name
11+
# @param args [Array] the method arguments
1012
def method_missing(method, *args)
1113
return super if !method.end_with?("_template")
1214

@@ -34,6 +36,8 @@ def method_missing(method, *args)
3436
@__vc_inline_template_defined = true
3537
end
3638

39+
# @param method [Symbol] the method name
40+
# @param include_all [Boolean] whether to include private methods
3741
def respond_to_missing?(method, include_all = false)
3842
method.end_with?("_template") || super
3943
end
@@ -46,6 +50,7 @@ def __vc_inline_template_language
4650
@__vc_inline_template_language if defined?(@__vc_inline_template_language)
4751
end
4852

53+
# @param subclass [Class] the inheriting class
4954
def inherited(subclass)
5055
super
5156
subclass.instance_variable_set(:@__vc_inline_template_language, __vc_inline_template_language)

0 commit comments

Comments
 (0)