diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7299c20..62e5431 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: ["2.7", "3.0", "3.1", "3.2", "3.3", "head"] + ruby: ["3.2", "3.3", "head"] steps: - uses: actions/checkout@v4 - name: Set up Ruby diff --git a/CHANGELOG.md b/CHANGELOG.md index d69a43b..45eae33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## [Unreleased] +## [0.5.0] - 2025-09-08 +- Prepare for Phlex 2.0 💪 +- Drop Ruby 2.7, 3.0 and 3.1 support +- Add Phlex::Kit compatibility tests +- Make `Phlex::Slotable::VERSION` available by default + ## [0.4.0] - 2024-02-14 - [BREAKING CHANGE] Rename `many` option to `collection`. diff --git a/Gemfile b/Gemfile index e25493f..d91bfb6 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ source "https://rubygems.org" # Specify your gem's dependencies in phlex-slotable.gemspec gemspec -gem "benchmark-ips", "2.13.0" +gem "benchmark-ips", "2.14.0" gem "minitest", "5.22.3" gem "rake", "13.2.1" gem "standard", "1.35.1" diff --git a/README.md b/README.md index f4d0575..227b53c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Phlex::Slotable enables slots feature to [Phlex](https://www.phlex.fun/) views. - [Component slot](#component-slot) - [Lambda slot](#lambda-slot) - [Polymorphic slot](#polymorphic-slot) +- [Performance](#performance) - [Development](#development) - [Contributing](#contributing) @@ -343,6 +344,29 @@ Note that you need to use `with_{type}_{slot_name}` to set slot content. In the > } > ``` +## Performance +Using Phlex::Slotable you don't suffer a performance penalty compared to using Phlex::DeferredRender, sometimes it can even be a little faster. + +``` +Generated using `ruby benchmark/main.rb` + +Phlex 1.11.0 +Phlex::Slotable 0.5.0 + +ruby 3.3.5 (2024-09-03 revision ef084cc8f4) [arm64-darwin23] +Warming up -------------------------------------- + Deferred 22.176k i/100ms + Slotable 23.516k i/100ms +Calculating ------------------------------------- + Deferred 222.727k (± 0.8%) i/s (4.49 μs/i) - 1.131M in 5.078157s + Slotable 237.405k (± 0.6%) i/s (4.21 μs/i) - 1.199M in 5.051936s + +Comparison: + Slotable: 237405.0 i/s + Deferred: 222726.8 i/s - 1.07x slower +``` + + ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. diff --git a/benchmark/main.rb b/benchmark/main.rb index c01b586..31de258 100644 --- a/benchmark/main.rb +++ b/benchmark/main.rb @@ -2,6 +2,11 @@ require "benchmark/ips" require_relative "../lib/phlex/slotable" +require "phlex/version" + +puts "Phlex #{Phlex::VERSION}" +puts "Phlex::Slotable #{Phlex::Slotable::VERSION}" + class DeferredList < Phlex::HTML include Phlex::DeferredRender diff --git a/bin/console b/bin/console index 81eef70..a558652 100755 --- a/bin/console +++ b/bin/console @@ -2,7 +2,7 @@ # frozen_string_literal: true require "bundler/setup" -require "phlex/slotable" +require_relative "../lib/phlex/slotable" # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. diff --git a/lib/phlex/slotable.rb b/lib/phlex/slotable.rb index d5bf1a5..aff29ee 100644 --- a/lib/phlex/slotable.rb +++ b/lib/phlex/slotable.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "phlex" +require_relative "slotable/version" module Phlex module Slotable @@ -56,16 +57,14 @@ def define_lambda_method(slot_name, callable) def define_getter_method(slot_name, collection:) getter_method = if collection <<-RUBY - def #{slot_name}_slots - @#{slot_name}_slots ||= [] - end + def #{slot_name}_slots = @#{slot_name}_slots ||= [] + private :#{slot_name}_slots RUBY else <<-RUBY - def #{slot_name}_slot - @#{slot_name}_slot - end + def #{slot_name}_slot = @#{slot_name}_slot + private :#{slot_name}_slot RUBY end @@ -76,16 +75,14 @@ def #{slot_name}_slot def define_predicate_method(slot_name, collection:) predicate_method = if collection <<-RUBY - def #{slot_name}_slots? - #{slot_name}_slots.any? - end + def #{slot_name}_slots? = #{slot_name}_slots.any? + private :#{slot_name}_slots? RUBY else <<-RUBY - def #{slot_name}_slot? - !#{slot_name}_slot.nil? - end + def #{slot_name}_slot? = !#{slot_name}_slot.nil? + private :#{slot_name}_slot? RUBY end diff --git a/lib/phlex/slotable/version.rb b/lib/phlex/slotable/version.rb index 8915b42..461e314 100644 --- a/lib/phlex/slotable/version.rb +++ b/lib/phlex/slotable/version.rb @@ -2,6 +2,6 @@ module Phlex module Slotable - VERSION = "0.4.0" + VERSION = "0.5.0" end end diff --git a/phlex-slotable.gemspec b/phlex-slotable.gemspec index cc18378..ffa9a29 100644 --- a/phlex-slotable.gemspec +++ b/phlex-slotable.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |spec| spec.summary = "Enable Slot API for Phlex views" spec.homepage = "https://github.com/stephannv/phlex-slotable" spec.license = "MIT" - spec.required_ruby_version = ">= 2.7.0" + spec.required_ruby_version = ">= 3.2.0" # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'" @@ -32,7 +32,7 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] # Uncomment to register a new dependency of your gem - spec.add_dependency "phlex", "~> 1.9" + spec.add_dependency "phlex", ">= 1.9", "< 3" # For more information and examples about making a new gem, check out our # guide at: https://bundler.io/guides/creating_gem.html diff --git a/test/phlex/test_kit_compatibility.rb b/test/phlex/test_kit_compatibility.rb new file mode 100644 index 0000000..de98926 --- /dev/null +++ b/test/phlex/test_kit_compatibility.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require "test_helper" + +class Phlex::TestKitCompatibility < Minitest::Test + class Headline < Phlex::HTML + include Phlex::Slotable + + slot :icon + slot :title + + def initialize(size:, bg_color:) + @size = size + @bg_color = bg_color + end + + def view_template + div class: "headline text-#{@size} bg-#{@bg_color}" do + render icon_slot + render title_slot + end + end + end + + class Header < Phlex::HTML + def view_template(&) + h1(&) + end + end + + module Components + extend Phlex::Kit + + Headline = Phlex::TestKitCompatibility::Headline + Header = Phlex::TestKitCompatibility::Header + end + + class Page < Phlex::HTML + include Components + + def view_template + Headline(size: :lg, bg_color: :red) do |h| + h.with_icon { h.i(class: "star") } + h.with_title do + Header { "Hello World!" } + end + end + end + end + + def test_with_slots + output = Page.new.call + + expected_html = <<~HTML.join_lines +