diff --git a/CHANGELOG.md b/CHANGELOG.md index 629d7a9..c12b0c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,4 +2,10 @@ ## main +## 0.1.1 + +- Added RSpec patch. + +## 0.1.0 + - Initial extraction. diff --git a/README.md b/README.md index 8671d5f..cccd4e5 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,14 @@ gem "rails", "~> 7.0" ``` Then, you can use Action Cable as before. Under the hood, the new implementation would be used. + +### RSpec support + +This gem also includes the corresponding patch for RSpec Rails (see [PR](https://github.com/palkan/rspec-rails/pull/1)). You MUST activate it explicitly +by adding the following line to your `spec/rails_helper.rb`: + +```ruby +# after rspec-rails is loaded +require "rspec/rails" +require "action_cable/next/rspec" +``` diff --git a/lib/action_cable.rb b/lib/action_cable.rb index b351040..0183ecc 100644 --- a/lib/action_cable.rb +++ b/lib/action_cable.rb @@ -39,6 +39,7 @@ "#{lib}/action_cable/version.rb", "#{lib}/action_cable/deprecator.rb", "#{lib}/actioncable-next.rb", + "#{lib}/action_cable/next", ) loader.do_not_eager_load( diff --git a/lib/action_cable/next/rspec.rb b/lib/action_cable/next/rspec.rb new file mode 100644 index 0000000..3e2b9f2 --- /dev/null +++ b/lib/action_cable/next/rspec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# RSpec patches from https://github.com/palkan/rspec-rails/pull/1 + +require "rspec/rails/example/channel_example_group" + +if defined?(RSpec::Rails::ChannelExampleGroup) + RSpec::Rails::ChannelExampleGroup.prepend(Module.new do + def connection_class + (_connection_class || described_class).then do |klass| + # Connection class either specified explicitly or is a described class + next klass if klass && klass <= ::ActionCable::Connection::Base + + # Otherwise, fallback to the default connection class + tests_connection ::ActionCable.server.config.connection_class.call + + _connection_class + end + end + end) +end + +RSpec::Rails::Matchers::ActionCable::HaveStream.prepend(Module.new do + def match(subscription) + case subscription + when ::ActionCable::Channel::Base + @actual = streams_for(subscription) + no_expected? ? actual.any? : actual.any? { |i| expected === i } + else + raise ArgumentError, "have_stream, have_stream_from and have_stream_from support expectations on subscription only" + end + end + + private + def streams_for(subscription) + # In Rails 8, subscription.streams returns a real subscriptions hash, + # not a fake array of stream names like in Rails 6-7. + # So, we must use #stream_names instead. + subscription.respond_to?(:stream_names) ? subscription.stream_names : subscription.streams + end +end) diff --git a/lib/actioncable-next.rb b/lib/actioncable-next.rb index 961ec00..fd81bca 100644 --- a/lib/actioncable-next.rb +++ b/lib/actioncable-next.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module ActionCableNext - VERSION = "0.1.0" + VERSION = "0.1.1" end