diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52846f1f..f6f69b12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,13 +5,17 @@ jobs: strategy: fail-fast: false matrix: - rails: [ "6.1", "7.0", "7.1" ] - ruby: [ "3.0", "3.1", "3.2", "3.3" ] + rails: [ "6.1", "7.0", "7.1", "7.2" ] + ruby: [ "2.7", "3.0", "3.1", "3.2", "3.3" ] allow-fail: [ false ] include: + - { ruby: "2.6", rails: "6.1" } - { ruby: "3.3", rails: "main", allow-fail: true } - { ruby: "3.2", rails: "main", allow-fail: true } - { ruby: "head", rails: "main", allow-fail: true } + exclude: + - { ruby: "2.7", rails: "7.2" } + - { ruby: "3.0", rails: "7.2" } env: FERRUM_PROCESS_TIMEOUT: 25 @@ -33,6 +37,7 @@ jobs: - name: Run Bug Template Tests run: ruby bug_report_template.rb || ruby bug_report_template.rb + continue-on-error: ${{ startsWith(matrix.ruby, '2') || false }} - name: Run tests id: test diff --git a/Gemfile b/Gemfile index 9cd37faf..8cd3ba34 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' gemspec -rails_version = ENV.fetch("RAILS_VERSION", "7.1") +rails_version = ENV.fetch("RAILS_VERSION", "7.2") if rails_version == "main" rails_constraint = { github: "rails/rails" } @@ -15,16 +15,27 @@ gem "sprockets-rails" gem 'rake' gem 'byebug' -gem 'puma' -gem 'rack' + +if RUBY_VERSION < "3" + gem "rack", "< 3" + gem "puma", "< 6" + gem "ruby2_keywords" +else + gem "rack" + gem "puma" +end group :development, :test do - gem 'importmap-rails' + if rails_version == "6.1" + gem "importmap-rails", "0.6.1" + else + gem "importmap-rails" + end end group :test do gem 'capybara' gem 'rexml' gem 'cuprite', '~> 0.9', require: 'capybara/cuprite' - gem 'sqlite3', '~> 1.4' + gem 'sqlite3', '1.5' end diff --git a/app/helpers/turbo/streams/action_helper.rb b/app/helpers/turbo/streams/action_helper.rb index d4e71d63..bb38487b 100644 --- a/app/helpers/turbo/streams/action_helper.rb +++ b/app/helpers/turbo/streams/action_helper.rb @@ -22,7 +22,10 @@ module Turbo::Streams::ActionHelper # message = Message.find(1) # turbo_stream_action_tag "remove", target: [message, :special] # # => - def turbo_stream_action_tag(action, target: nil, targets: nil, template: nil, **attributes) + def turbo_stream_action_tag(action, attributes = {}) + target = attributes.delete(:target) + targets = attributes.delete(:targets) + template = attributes.delete(:template) template = action.to_sym.in?(%i[ remove refresh ]) ? "" : tag.template(template.to_s.html_safe) if target = convert_to_turbo_stream_dom_id(target) @@ -39,7 +42,7 @@ def turbo_stream_action_tag(action, target: nil, targets: nil, template: nil, ** # turbo_stream_refresh_tag # # => def turbo_stream_refresh_tag(request_id: Turbo.current_request_id, **attributes) - turbo_stream_action_tag(:refresh, **{ "request-id": request_id }.compact, **attributes) + turbo_stream_action_tag(:refresh, attributes.with_defaults({ "request-id": request_id }.compact)) end private diff --git a/app/models/concerns/turbo/broadcastable.rb b/app/models/concerns/turbo/broadcastable.rb index b39c186e..462d647d 100644 --- a/app/models/concerns/turbo/broadcastable.rb +++ b/app/models/concerns/turbo/broadcastable.rb @@ -508,7 +508,7 @@ def broadcast_target_default self.class.broadcast_target_default end - def extract_options_and_add_target(rendering = {}, target: broadcast_target_default) + def extract_options_and_add_target(rendering, target: broadcast_target_default) broadcast_rendering_with_defaults(rendering).tap do |options| options[:target] = target if !options.key?(:target) && !options.key?(:targets) end diff --git a/app/models/turbo/streams/tag_builder.rb b/app/models/turbo/streams/tag_builder.rb index 93cf2e76..8b6eed84 100644 --- a/app/models/turbo/streams/tag_builder.rb +++ b/app/models/turbo/streams/tag_builder.rb @@ -240,8 +240,8 @@ def prepend_all(targets, content = nil, **rendering, &block) # # turbo_stream.refresh request_id: "abc123" # # => - def refresh(...) - turbo_stream_refresh_tag(...) + def refresh(**options) + turbo_stream_refresh_tag(**options) end # Send an action of the type name to target. Options described in the concrete methods. diff --git a/lib/turbo/engine.rb b/lib/turbo/engine.rb index ecfd82e0..8fb9933f 100644 --- a/lib/turbo/engine.rb +++ b/lib/turbo/engine.rb @@ -164,7 +164,7 @@ class TurboStreamEncoder < IdentityEncoder ActiveSupport.on_load(:action_dispatch_system_test_case) do app.config.turbo.test_connect_after_actions.map do |method| class_eval <<~RUBY, __FILE__, __LINE__ + 1 - def #{method}(...) # def visit(...) + def #{method}(*args, &block) # def visit(*args, &block) super.tap { connect_turbo_cable_stream_sources } # super.tap { connect_turbo_cable_stream_sources } end # end RUBY diff --git a/lib/turbo/system_test_helper.rb b/lib/turbo/system_test_helper.rb index 4e81a1e1..4e4a5bc7 100644 --- a/lib/turbo/system_test_helper.rb +++ b/lib/turbo/system_test_helper.rb @@ -51,9 +51,10 @@ def connect_turbo_cable_stream_sources(**options, &block) # # In addition to the filters listed above, accepts any valid Capybara global # filter option. - def assert_turbo_cable_stream_source(...) - assert_selector(:turbo_cable_stream_source, ...) + def assert_turbo_cable_stream_source(*args, &block) + assert_selector(:turbo_cable_stream_source, *args, &block) end + ruby2_keywords :assert_turbo_cable_stream_source # Asserts that a `` element is absent from the # document @@ -75,9 +76,10 @@ def assert_turbo_cable_stream_source(...) # # In addition to the filters listed above, accepts any valid Capybara global # filter option. - def assert_no_turbo_cable_stream_source(...) - assert_no_selector(:turbo_cable_stream_source, ...) + def assert_no_turbo_cable_stream_source(*args, &block) + assert_no_selector(:turbo_cable_stream_source, *args, &block) end + ruby2_keywords :assert_no_turbo_cable_stream_source Capybara.add_selector :turbo_cable_stream_source do xpath do |locator| diff --git a/test/streams/broadcastable_test.rb b/test/streams/broadcastable_test.rb index 989d6585..3a5be551 100644 --- a/test/streams/broadcastable_test.rb +++ b/test/streams/broadcastable_test.rb @@ -15,10 +15,12 @@ def to_partial_path test "broadcasting ignores blank streamables" do ActionCable.server.stub :broadcast, proc { flunk "expected no broadcasts" } do - @message.broadcast_remove_to nil - @message.broadcast_remove_to [nil] - @message.broadcast_remove_to "" - @message.broadcast_remove_to [""] + assert_no_broadcasts @message.to_gid_param do + @message.broadcast_remove_to nil + @message.broadcast_remove_to [nil] + @message.broadcast_remove_to "" + @message.broadcast_remove_to [""] + end end end diff --git a/test/streams/streams_helper_test.rb b/test/streams/streams_helper_test.rb index be9bea9f..45d66429 100644 --- a/test/streams/streams_helper_test.rb +++ b/test/streams/streams_helper_test.rb @@ -4,11 +4,17 @@ class TestChannel < ApplicationCable::Channel; end class Turbo::StreamsHelperTest < ActionView::TestCase class Component - extend ActiveModel::Naming + include ActiveModel::Model - def initialize(id:, content:) = (@id, @content = id, content) - def render_in(...) = @content - def to_key = [@id] + attr_accessor :id, :content + + def render_in(view_context) + content + end + + def to_key + [id] + end end attr_accessor :formats diff --git a/test/test_helper.rb b/test/test_helper.rb index bbe0f583..1c54616f 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -8,8 +8,8 @@ ActionCable.server.config.logger = Logger.new(STDOUT) if ENV["VERBOSE"] module ActionViewTestCaseExtensions - def render(...) - ApplicationController.renderer.render(...) + def render(*args, &block) + ApplicationController.renderer.render(*args, &block) end end