glib-web 4.39.0 → 4.39.2

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/glib/auth/policy.rb +13 -0
  3. data/app/controllers/glib/api_docs_controller.rb +145 -0
  4. data/app/helpers/glib/json_ui/abstract_builder.rb +16 -0
  5. data/app/helpers/glib/json_ui/action_builder/dialogs.rb +4 -0
  6. data/app/helpers/glib/json_ui/list_builders.rb +2 -0
  7. data/app/helpers/glib/json_ui/view_builder/fields.rb +15 -0
  8. data/app/helpers/glib/json_ui/view_builder/panels.rb +450 -11
  9. data/app/helpers/glib/json_ui/view_builder.rb +1 -1
  10. data/app/views/glib/api_docs/component.json.jbuilder +215 -0
  11. data/app/views/glib/api_docs/index.json.jbuilder +103 -0
  12. data/app/views/glib/api_docs/show.json.jbuilder +111 -0
  13. data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +2 -2
  14. data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +2 -2
  15. data/app/views/json_ui/garage/forms/file_upload_new.json.jbuilder +1 -1
  16. data/app/views/json_ui/garage/forms/partial_update.json.jbuilder +12 -12
  17. data/app/views/json_ui/garage/forms/selects.json.jbuilder +1 -1
  18. data/app/views/json_ui/garage/forms/show_hide.json.jbuilder +62 -7
  19. data/app/views/json_ui/garage/lists/edit_mode.json.jbuilder +4 -4
  20. data/app/views/json_ui/garage/lists/templating.json.jbuilder +68 -44
  21. data/app/views/json_ui/garage/pages/custom_style_class.json.jbuilder +1 -1
  22. data/app/views/json_ui/garage/pages/nav_buttons.json.jbuilder +31 -13
  23. data/app/views/json_ui/garage/panels/_styled.json.jbuilder +8 -8
  24. data/app/views/json_ui/garage/panels/hover.json.jbuilder +2 -2
  25. data/app/views/json_ui/garage/panels/timeline.json.jbuilder +5 -5
  26. data/app/views/json_ui/garage/panels/ul.json.jbuilder +1 -1
  27. data/app/views/json_ui/garage/tables/bulk_edit.json.jbuilder +1 -1
  28. data/app/views/json_ui/garage/test_page/file_upload_new.json.jbuilder +1 -1
  29. data/app/views/json_ui/garage/test_page/form.json.jbuilder +6 -6
  30. data/app/views/json_ui/garage/test_page/form_dynamic.json.jbuilder +2 -2
  31. data/app/views/json_ui/garage/test_page/logics_set.json.jbuilder +94 -0
  32. data/app/views/json_ui/garage/views/components_replace.json.jbuilder +13 -13
  33. data/app/views/json_ui/garage/views/components_set.json.jbuilder +6 -6
  34. data/app/views/json_ui/garage/views/fields_focus.json.jbuilder +22 -22
  35. data/app/views/json_ui/garage/views/markdowns.json.jbuilder +2 -0
  36. data/config/routes.rb +4 -0
  37. data/lib/glib/doc_generator.rb +386 -0
  38. data/lib/glib/json_crawler/router.rb +45 -24
  39. data/lib/glib/rubocop/cops/json_ui/base_nested_parameter.rb +145 -0
  40. data/lib/glib/rubocop/cops/json_ui/nested_action_parameter.rb +55 -0
  41. data/lib/glib/rubocop/cops/json_ui/nested_block_parameter.rb +51 -0
  42. data/lib/glib/rubocop/cops/multiline_method_call_style.rb +74 -5
  43. data/lib/glib/rubocop/cops/test_name_parentheses.rb +33 -0
  44. data/lib/glib/rubocop.rb +4 -0
  45. data/lib/glib/test/parallel_coverage.rb +38 -0
  46. data/lib/glib/test_helpers.rb +12 -0
  47. data/lib/glib-web.rb +1 -0
  48. data/lib/tasks/db.rake +1 -1
  49. data/lib/tasks/docs.rake +59 -0
  50. metadata +13 -1
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_nested_parameter'
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Glib
8
+ module JsonUi
9
+ # Enforces using the immediate block parameter instead of outer block variables
10
+ # in nested view blocks (childViews, content) in JsonUi templates.
11
+ #
12
+ # @example
13
+ # # bad - using outer variable
14
+ # scroll.panels_form childViews: ->(form) do
15
+ # scroll.label text: 'TEST' # using 'scroll' instead of 'form'
16
+ # end
17
+ #
18
+ # # good
19
+ # scroll.panels_form childViews: ->(form) do
20
+ # form.label text: 'TEST'
21
+ # end
22
+ #
23
+ # # bad - parameter shadowing
24
+ # scroll.panels_form childViews: ->(form) do
25
+ # form.panels_responsive childViews: ->(form) do # shadows outer 'form'
26
+ # form.fields_text name: 'user[field]'
27
+ # end
28
+ # end
29
+ #
30
+ # # good
31
+ # scroll.panels_form childViews: ->(form) do
32
+ # form.panels_responsive childViews: ->(res) do
33
+ # res.fields_text name: 'user[field]'
34
+ # end
35
+ # end
36
+ class NestedBlockParameter < BaseNestedParameter
37
+ private
38
+
39
+ def relevant_block?(block_node)
40
+ return false unless lambda_block?(block_node)
41
+
42
+ pair = hash_pair_parent(block_node)
43
+ return false unless pair
44
+
45
+ pair.key.sym_type? && [:childViews, :content].include?(pair.key.value)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -37,6 +37,7 @@ module RuboCop
37
37
  return unless multi_line_call_with_args?(node)
38
38
  return if proper_parentheses_style?(node)
39
39
  return if proper_backslash_style?(node) && allow_backslash?
40
+ return if inside_correctable_parent?(node)
40
41
 
41
42
  add_offense(node) do |corrector|
42
43
  autocorrect(corrector, node)
@@ -122,12 +123,28 @@ module RuboCop
122
123
  args
123
124
  end
124
125
 
126
+ def inside_correctable_parent?(node)
127
+ # Check if this node is inside a block that belongs to a multi-line call
128
+ # that will also be corrected. If so, skip this node to avoid conflicts.
129
+ current = node.parent
130
+
131
+ while current
132
+ if current.send_type? || current.csend_type?
133
+ if multi_line_call_with_args?(current) && !proper_parentheses_style?(current)
134
+ return true
135
+ end
136
+ end
137
+ current = current.parent
138
+ end
139
+
140
+ false
141
+ end
142
+
125
143
  def autocorrect(corrector, node)
126
144
  method_end_pos = node.loc.selector.end_pos
127
145
 
128
- # Find the indentation of the method call
129
- line_begin_pos = processed_source.buffer.line_range(node.loc.line).begin_pos
130
- base_indent = node.source_range.begin_pos - line_begin_pos
146
+ # Calculate indentation based on the node's actual column position
147
+ base_indent = node.loc.column
131
148
  arg_indent = ' ' * (base_indent + 2)
132
149
 
133
150
  # Build the new argument list
@@ -137,7 +154,9 @@ module RuboCop
137
154
 
138
155
  if arg.hash_type?
139
156
  arg.pairs.each do |pair|
140
- arg_parts << pair.source
157
+ # Re-indent pair if it contains a block
158
+ pair_source = reindent_pair_with_block(pair, arg_indent)
159
+ arg_parts << pair_source
141
160
  end
142
161
  else
143
162
  arg_parts << arg.source
@@ -151,7 +170,7 @@ module RuboCop
151
170
 
152
171
  # If there's a block, add it on the last argument line
153
172
  if node.block_literal?
154
- block_source = node.block_literal.source
173
+ block_source = reindent_block(node.block_literal, arg_indent)
155
174
  replacement += " #{block_source}"
156
175
  end
157
176
 
@@ -175,6 +194,56 @@ module RuboCop
175
194
 
176
195
  corrector.replace(range, replacement)
177
196
  end
197
+
198
+ def reindent_pair_with_block(pair, base_indent)
199
+ # Check if the pair's value is a block
200
+ return pair.source unless pair.value.block_type?
201
+
202
+ # Format: "key: ->(param) do ... end"
203
+ key_source = pair.key.source
204
+ block_source = reindent_block(pair.value, base_indent)
205
+
206
+ "#{key_source}: #{block_source}"
207
+ end
208
+
209
+ def reindent_block(block_node, base_indent)
210
+ # Get block source lines
211
+ source = block_node.source
212
+ lines = source.lines
213
+
214
+ return source if lines.length == 1 # Single line block, no reindent needed
215
+
216
+ # Find the current indentation of the block's first line
217
+ # (this is usually where "do" appears)
218
+ first_line = lines[0]
219
+
220
+ # Process the block:
221
+ # Line 0: "->(param) do" - keep as is
222
+ # Lines 1..-2: block body - re-indent to base_indent + 2
223
+ # Last line: "end" - indent to base_indent
224
+
225
+ result_lines = []
226
+ block_body_indent = base_indent + ' ' * 2
227
+
228
+ lines.each_with_index do |line, index|
229
+ if index == 0
230
+ # First line: "->(param) do"
231
+ result_lines << line.rstrip
232
+ elsif index == lines.length - 1
233
+ # Last line: "end"
234
+ result_lines << "#{base_indent}#{line.strip}"
235
+ else
236
+ # Body lines: re-indent
237
+ # Remove existing indentation and add new indentation
238
+ stripped = line.lstrip
239
+ next if stripped.empty? # Skip blank lines
240
+
241
+ result_lines << "#{block_body_indent}#{stripped.rstrip}"
242
+ end
243
+ end
244
+
245
+ result_lines.join("\n")
246
+ end
178
247
  end
179
248
  end
180
249
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Glib
6
+ # Prevents test method names from containing parentheses which can cause issues with test runners
7
+ #
8
+ # @example
9
+ # # bad
10
+ # test 'user creation (with email)' do
11
+ # end
12
+ #
13
+ # # good
14
+ # test 'user creation with email' do
15
+ # end
16
+ class TestNameParentheses < Base
17
+ MSG = "Test name should not contain parentheses because for some reason, this will produce: 'Syntax error: \"(\" unexpected'."
18
+
19
+ def_node_matcher :test_method?, <<~PATTERN
20
+ (send nil? :test (str $_) ...)
21
+ PATTERN
22
+
23
+ def on_send(node)
24
+ test_method?(node) do |test_name|
25
+ if test_name.include?('(') || test_name.include?(')')
26
+ add_offense(node)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/glib/rubocop.rb CHANGED
@@ -1,2 +1,6 @@
1
1
  require_relative 'rubocop/cops/localize'
2
2
  require_relative 'rubocop/cops/multiline_method_call_style'
3
+ require_relative 'rubocop/cops/json_ui/base_nested_parameter'
4
+ require_relative 'rubocop/cops/json_ui/nested_block_parameter'
5
+ require_relative 'rubocop/cops/json_ui/nested_action_parameter'
6
+ require_relative 'rubocop/cops/test_name_parentheses'
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glib
4
+ module Test
5
+ # ParallelCoverage configures Rails parallel testing to work properly with SimpleCov.
6
+ #
7
+ # Without this configuration, SimpleCov reports inaccurate coverage (often very low, like 1-2%)
8
+ # when running tests with parallelization enabled, because it only captures data from one worker
9
+ # instead of merging results from all parallel workers.
10
+ #
11
+ # Usage:
12
+ # class ActiveSupport::TestCase
13
+ # include Glib::Test::ParallelCoverage
14
+ # end
15
+ #
16
+ # This will:
17
+ # - Enable parallel test execution using all available processors
18
+ # - Configure SimpleCov to track each worker separately
19
+ # - Automatically merge coverage results from all workers
20
+ module ParallelCoverage
21
+ extend ActiveSupport::Concern
22
+
23
+ included do
24
+ # Set threshold for force parallelization.
25
+ parallelize(workers: :number_of_processors, threshold: 1)
26
+
27
+ # Configure SimpleCov to properly merge coverage from parallel workers
28
+ parallelize_setup do |worker|
29
+ SimpleCov.command_name "#{SimpleCov.command_name}-#{worker}"
30
+ end
31
+
32
+ parallelize_teardown do |_worker|
33
+ SimpleCov.result
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -83,6 +83,18 @@ module Glib
83
83
  "http://#{HOST}/users/sign_out.json"
84
84
  end
85
85
 
86
+ def glib_travel(*args, &block)
87
+ Timecop.travel(*args, &block)
88
+ end
89
+
90
+ def glib_travel_freeze(*args, &block)
91
+ Timecop.freeze(*args, &block)
92
+ end
93
+
94
+ def glib_travel_back
95
+ Timecop.return
96
+ end
97
+
86
98
  private
87
99
  def __execute_crawler(user, inspect_http:, log_file: nil, &block)
88
100
  auth_token = login user
data/lib/glib-web.rb CHANGED
@@ -8,6 +8,7 @@ require 'glib/json_crawler'
8
8
 
9
9
  require 'glib/dynamic_text'
10
10
  require 'glib/test_helpers'
11
+ require 'glib/test/parallel_coverage'
11
12
  require 'glib/integration_test'
12
13
 
13
14
  require 'glib/time_freezable_mailer'
data/lib/tasks/db.rake CHANGED
@@ -63,7 +63,7 @@ namespace :db do
63
63
 
64
64
  entries.each do |a|
65
65
  attrs = Hash[a.attributes.sort]
66
- attrs.delete_if { |k, v| v.nil? }
66
+ # attrs.delete_if { |k, v| v.nil? }
67
67
 
68
68
  id = if attrs.include?('id')
69
69
  [a.id]
@@ -0,0 +1,59 @@
1
+ namespace :glib do
2
+ namespace :docs do
3
+ desc 'Generate component documentation in YAML format'
4
+ task :generate do
5
+ require_relative '../glib/doc_generator'
6
+
7
+ generator = Glib::DocGenerator.new
8
+
9
+ # Generate documentation for different component categories
10
+ categories = [
11
+ {
12
+ name: 'panels',
13
+ file: 'app/helpers/glib/json_ui/view_builder/panels.rb',
14
+ output: 'doc/components/panels.yml'
15
+ },
16
+ {
17
+ name: 'fields',
18
+ file: 'app/helpers/glib/json_ui/view_builder/fields.rb',
19
+ output: 'doc/components/fields.yml'
20
+ },
21
+ {
22
+ name: 'views',
23
+ file: 'app/helpers/glib/json_ui/view_builder.rb',
24
+ output: 'doc/components/views.yml'
25
+ },
26
+ {
27
+ name: 'actions',
28
+ file: 'app/helpers/glib/json_ui/action_builder.rb',
29
+ output: 'doc/components/actions.yml'
30
+ }
31
+ ]
32
+
33
+ categories.each do |category|
34
+ puts "Generating documentation for #{category[:name]}..."
35
+ generator.generate_for_file(category[:file], category[:output])
36
+ puts " -> #{category[:output]}"
37
+ end
38
+
39
+ # Also scan action subdirectories
40
+ Dir.glob('app/helpers/glib/json_ui/action_builder/*.rb').each do |file|
41
+ basename = File.basename(file, '.rb')
42
+ output = "doc/components/actions_#{basename}.yml"
43
+ puts "Generating documentation for actions/#{basename}..."
44
+ generator.generate_for_file(file, output)
45
+ puts " -> #{output}"
46
+ end
47
+
48
+ puts "\nDocumentation generation complete!"
49
+ end
50
+
51
+ desc 'Validate YARD documentation'
52
+ task :validate do
53
+ puts "Validating YARD documentation..."
54
+ system('yard stats --list-undoc')
55
+ system('yard doc --fail-on-warning --no-output')
56
+ puts "\nValidation complete!"
57
+ end
58
+ end
59
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glib-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.39.0
4
+ version: 4.39.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
@@ -156,6 +156,7 @@ files:
156
156
  - app/controllers/concerns/glib/json/traversal.rb
157
157
  - app/controllers/concerns/glib/json/ui.rb
158
158
  - app/controllers/concerns/glib/json/validation.rb
159
+ - app/controllers/glib/api_docs_controller.rb
159
160
  - app/controllers/glib/blob_url_generators_controller.rb
160
161
  - app/controllers/glib/errors_controller.rb
161
162
  - app/controllers/glib/glib_direct_uploads_controller.rb
@@ -220,6 +221,9 @@ files:
220
221
  - app/validators/mutually_exclusive_with_validator.rb
221
222
  - app/validators/presence_only_if_validator.rb
222
223
  - app/validators/url_validator.rb
224
+ - app/views/glib/api_docs/component.json.jbuilder
225
+ - app/views/glib/api_docs/index.json.jbuilder
226
+ - app/views/glib/api_docs/show.json.jbuilder
223
227
  - app/views/json_ui/garage/_nav_menu.json.jbuilder
224
228
  - app/views/json_ui/garage/actions/_commands.json.jbuilder
225
229
  - app/views/json_ui/garage/actions/_components.json.jbuilder
@@ -376,6 +380,7 @@ files:
376
380
  - app/views/json_ui/garage/test_page/form.json.jbuilder
377
381
  - app/views/json_ui/garage/test_page/form_dynamic.json.jbuilder
378
382
  - app/views/json_ui/garage/test_page/lifecycle.json.jbuilder
383
+ - app/views/json_ui/garage/test_page/logics_set.json.jbuilder
379
384
  - app/views/json_ui/garage/test_page/multiupload.json.jbuilder
380
385
  - app/views/json_ui/garage/test_page/selectable.json.jbuilder
381
386
  - app/views/json_ui/garage/test_page/window.json.jbuilder
@@ -422,6 +427,7 @@ files:
422
427
  - lib/glib-web.rb
423
428
  - lib/glib/all_helpers.rb
424
429
  - lib/glib/crypt/utils.rb
430
+ - lib/glib/doc_generator.rb
425
431
  - lib/glib/dynamic_text.rb
426
432
  - lib/glib/dynamic_text/config.rb
427
433
  - lib/glib/engine.rb
@@ -442,15 +448,21 @@ files:
442
448
  - lib/glib/json_crawler/router.rb
443
449
  - lib/glib/mailer_tester.rb
444
450
  - lib/glib/rubocop.rb
451
+ - lib/glib/rubocop/cops/json_ui/base_nested_parameter.rb
452
+ - lib/glib/rubocop/cops/json_ui/nested_action_parameter.rb
453
+ - lib/glib/rubocop/cops/json_ui/nested_block_parameter.rb
445
454
  - lib/glib/rubocop/cops/localize.rb
446
455
  - lib/glib/rubocop/cops/multiline_method_call_style.rb
456
+ - lib/glib/rubocop/cops/test_name_parentheses.rb
447
457
  - lib/glib/snapshot.rb
458
+ - lib/glib/test/parallel_coverage.rb
448
459
  - lib/glib/test_helpers.rb
449
460
  - lib/glib/time_freezable_mailer.rb
450
461
  - lib/glib/time_returning_mailer.rb
451
462
  - lib/glib/value.rb
452
463
  - lib/glib/version.rb
453
464
  - lib/tasks/db.rake
465
+ - lib/tasks/docs.rake
454
466
  homepage:
455
467
  licenses: []
456
468
  metadata: {}