From 12bcd07fb42f1e3d9207eaab134178f17b7e3b64 Mon Sep 17 00:00:00 2001 From: Konstantin Tennhard Date: Sat, 15 Mar 2025 17:41:10 -0400 Subject: [PATCH 1/4] SmartProperties 1.12 Raise the minimum requirement for SmartProperties in order to support `property!` --- action_widget.gemspec | 2 +- lib/action_widget/extensions/rails/action_widget_tasks.rake | 6 ++++++ support/templates/initializer.rb.erb | 0 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 lib/action_widget/extensions/rails/action_widget_tasks.rake create mode 100644 support/templates/initializer.rb.erb diff --git a/action_widget.gemspec b/action_widget.gemspec index d334609..dfa71ac 100644 --- a/action_widget.gemspec +++ b/action_widget.gemspec @@ -17,7 +17,7 @@ Gem::Specification.new do |gem| gem.required_ruby_version = '>= 3.0.0' gem.add_dependency 'activesupport', '> 6.0' - gem.add_dependency 'smart_properties', '~> 1.10' + gem.add_dependency 'smart_properties', '~> 1.12' gem.add_development_dependency 'actionview', '>= 6.0' gem.add_development_dependency 'pry' diff --git a/lib/action_widget/extensions/rails/action_widget_tasks.rake b/lib/action_widget/extensions/rails/action_widget_tasks.rake new file mode 100644 index 0000000..9a36584 --- /dev/null +++ b/lib/action_widget/extensions/rails/action_widget_tasks.rake @@ -0,0 +1,6 @@ +namespace :action_widget do + desc "Install" + task :install do + puts "Install" + end +end \ No newline at end of file diff --git a/support/templates/initializer.rb.erb b/support/templates/initializer.rb.erb new file mode 100644 index 0000000..e69de29 From 0c06fa8a10d36e08865d62753b3694c401080c72 Mon Sep 17 00:00:00 2001 From: Konstantin Tennhard Date: Sat, 15 Mar 2025 19:19:53 -0400 Subject: [PATCH 2/4] Better prefix and suffix control Prefixes and suffixes can now be independently configured for class names and helper names --- lib/action_widget.rb | 15 +++---- lib/action_widget/configuration.rb | 39 +++++++------------ .../extensions/rails/generators.rb | 20 ++++++---- spec/action_widget_spec.rb | 26 +++++++++++++ 4 files changed, 60 insertions(+), 40 deletions(-) diff --git a/lib/action_widget.rb b/lib/action_widget.rb index 1bbc441..843ea7b 100644 --- a/lib/action_widget.rb +++ b/lib/action_widget.rb @@ -12,15 +12,11 @@ def []=(helper_name, klass) end def configuration - @configuration ||= Configuration.new(suffix: "Widget") + @configuration ||= Configuration.new end def configure(&block) - @configuration = Configuration.new(&block) - end - - def helper?(name) - !!configuration.pattern.match(name) + @configuration = Configuration.new.tap(&block) end protected @@ -38,9 +34,10 @@ def registry private def find_action_widget(helper_name) - return nil unless helper?(helper_name) - basename = configuration.pattern.match(helper_name)[1] - classname = [configuration.prefix, basename.camelcase, configuration.suffix].join("") + match = configuration.helper_pattern.match(helper_name) + return nil if match.nil? + basename = match[1] + classname = [configuration.class_prefix, basename.classify, configuration.class_suffix].join("") classname.constantize rescue NameError, LoadError nil diff --git a/lib/action_widget/configuration.rb b/lib/action_widget/configuration.rb index 6d1e2a6..47ee199 100644 --- a/lib/action_widget/configuration.rb +++ b/lib/action_widget/configuration.rb @@ -1,34 +1,25 @@ module ActionWidget class Configuration include SmartProperties - property :prefix - property :suffix - property :superclass, required: true, default: -> { ActionWidget::Base } - property :directory, required: true, converts: :to_s, accepts: ->(string) { !string.empty? }, default: -> { [underscored_prefix, underscored_suffix].compact.join("_").pluralize } - property :minitest_superclass - attr_reader :pattern + property :class_prefix + property :class_suffix, default: "Widget" + property :helper_prefix + property :helper_suffix, default: "widget" + property! :superclass, default: "ActionWidget::Base" + property! :directory, + converts: :to_s, + accepts: ->(string) { !string.empty? }, + default: "widgets" + property! :minitest_superclass, + default: "ActionView::TestCase" - def initialize(*) - super - - @pattern = Regexp.new("^%s$" % [ - underscored_prefix, - "(.*)", - underscored_suffix - ].compact.join("_")) - end - - private - - def underscored_prefix - return if prefix.nil? - prefix.underscore + def class_pattern + Regexp.new("^%s$" % [class_prefix, "(.*?)", class_suffix].compact.join("")) end - def underscored_suffix - return if suffix.nil? - suffix.underscore + def helper_pattern + Regexp.new("^%s$" % [helper_prefix, "(.*?)", helper_suffix].compact.join("_")) end end end diff --git a/lib/action_widget/extensions/rails/generators.rb b/lib/action_widget/extensions/rails/generators.rb index 4d515a7..5d9a95b 100644 --- a/lib/action_widget/extensions/rails/generators.rb +++ b/lib/action_widget/extensions/rails/generators.rb @@ -40,7 +40,7 @@ def test_path end def test_filename - "#{helper_name}_test.rb" + "#{filename}_test.rb" end def spec_path @@ -48,7 +48,7 @@ def spec_path end def spec_filename - "#{helper_name}_spec.rb" + "#{filename}_spec.rb" end def implementation_path @@ -56,11 +56,15 @@ def implementation_path end def implementation_filename - "#{helper_name}.rb" + "#{filename}.rb" + end + + def filename + [configuration.class_prefix&.underscore, basename.underscore, configuration.class_suffix&.underscore].compact.join('_') end def class_name - [configuration.prefix, basename.classify, configuration.suffix].join('') + [configuration.class_prefix, basename.classify, configuration.class_suffix].compact.join('') end def superclass_name @@ -68,15 +72,17 @@ def superclass_name end def minitest_superclass_name - (configuration.minitest_superclass || "ActionView::TestCase").to_s + configuration.minitest_superclass.to_s end def helper_name - class_name.underscore + [configuration.helper_prefix, basename.underscore, configuration.helper_suffix].compact.join('_') end def basename - if match = name.underscore.match(configuration.pattern) + if match = name.match(configuration.class_pattern) + match[1] + elsif match = name.match(configuration.helper_pattern) match[1] else name diff --git a/spec/action_widget_spec.rb b/spec/action_widget_spec.rb index 3b7d3c9..9fbd9a1 100644 --- a/spec/action_widget_spec.rb +++ b/spec/action_widget_spec.rb @@ -27,6 +27,10 @@ class ViewContext < ActionView::Base RSpec.describe DummyWidget do let(:view) { ViewContext.empty } + it "should be registered" do + expect(ActionWidget[:dummy_widget]).to be(DummyWidget) + end + it "should delegate unknown method calls to the view context" do expect(described_class.new(view).render).to eq("

") end @@ -49,4 +53,26 @@ class ViewContext < ActionView::Base expect(instance.options).to eq({class: 'wide'}) end end + + context "with custom configuration" do + let(:expected_html) { '

Hello World

' } + + before do + ActionWidget.configure do |config| + config.helper_suffix = nil + end + end + + it "should have an adjusted helper pattern" do + expect(ActionWidget.configuration.helper_pattern).to eq(/^(.*?)$/) + end + + it "should be possible to override the helper suffix" do + expect(view.dummy("Hello World")).to eq(expected_html) + end + + after do + ActionWidget.configure {} + end + end end From 19834ac5a068454f3f28ec27d6b2909eeb4ba0c5 Mon Sep 17 00:00:00 2001 From: Konstantin Tennhard Date: Sat, 15 Mar 2025 19:20:37 -0400 Subject: [PATCH 3/4] Rake task: action_widget:install Adds a rake task for creating an initializer that allows ActionWidget to be configured. --- .../extensions/rails/action_widget_tasks.rake | 15 ++++++++++++++- lib/action_widget/extensions/rails/railtie.rb | 4 ++++ support/templates/initializer.rb.erb | 9 +++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/action_widget/extensions/rails/action_widget_tasks.rake b/lib/action_widget/extensions/rails/action_widget_tasks.rake index 9a36584..dd0379f 100644 --- a/lib/action_widget/extensions/rails/action_widget_tasks.rake +++ b/lib/action_widget/extensions/rails/action_widget_tasks.rake @@ -1,6 +1,19 @@ +require "rails/generators" + +module ActionWidget + class InitializerGenerator < Rails::Generators::Base + source_root File.expand_path('../../../../../support/templates', __FILE__) + + def create_initializer_file + template "initializer.rb.erb", Rails.root.join("config", "initializers", "action_widget.rb") + end + end +end + namespace :action_widget do desc "Install" task :install do - puts "Install" + require_relative './generators' + ActionWidget::InitializerGenerator.start end end \ No newline at end of file diff --git a/lib/action_widget/extensions/rails/railtie.rb b/lib/action_widget/extensions/rails/railtie.rb index 7e2ed6d..ac12732 100644 --- a/lib/action_widget/extensions/rails/railtie.rb +++ b/lib/action_widget/extensions/rails/railtie.rb @@ -4,6 +4,10 @@ module ActionWidget module Extensions module Rails class Railtie < ::Rails::Railtie + rake_tasks do + load File.expand_path("../action_widget_tasks.rake", __FILE__) + end + initializer "action_widget.helper" do ActiveSupport.on_load(:action_view) do include ActionWidget::ViewHelper diff --git a/support/templates/initializer.rb.erb b/support/templates/initializer.rb.erb index e69de29..db16b97 100644 --- a/support/templates/initializer.rb.erb +++ b/support/templates/initializer.rb.erb @@ -0,0 +1,9 @@ +ActionWidget.configure do |config| + # config.class_prefix = nil + config.class_suffix = "Widget" + + # config.helper_prefix = nil + config.helper_suffix = "widget" + + # config.directory = "widgets" +end \ No newline at end of file From 734599ceb22aed8402c01d7f0ace7de92497ff9f Mon Sep 17 00:00:00 2001 From: Konstantin Tennhard Date: Sat, 15 Mar 2025 19:21:02 -0400 Subject: [PATCH 4/4] render(*) Allow the render stub to take any number of arguments. --- lib/action_widget/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/action_widget/base.rb b/lib/action_widget/base.rb index bea14d1..be18691 100644 --- a/lib/action_widget/base.rb +++ b/lib/action_widget/base.rb @@ -18,7 +18,7 @@ def initialize(view, attributes = {}) super(view, Hash[attributes]) end - def render + def render(*) raise NotImplementedError, "#{self.class} must implement #render" end end