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.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/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 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/action_widget_tasks.rake b/lib/action_widget/extensions/rails/action_widget_tasks.rake new file mode 100644 index 0000000..dd0379f --- /dev/null +++ b/lib/action_widget/extensions/rails/action_widget_tasks.rake @@ -0,0 +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 + require_relative './generators' + ActionWidget::InitializerGenerator.start + end +end \ No newline at end of file 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/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/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 diff --git a/support/templates/initializer.rb.erb b/support/templates/initializer.rb.erb new file mode 100644 index 0000000..db16b97 --- /dev/null +++ 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