README.md in wisper-1.3.0 vs README.md in wisper-1.4.0
- old
+ new
@@ -1,12 +1,14 @@
# Wisper
Wisper is a Ruby library for decoupling and managing the dependencies of your
Ruby objects using Pub/Sub.
+[![Gem Version](https://badge.fury.io/rb/wisper.png)](http://badge.fury.io/rb/wisper)
[![Code Climate](https://codeclimate.com/github/krisleech/wisper.png)](https://codeclimate.com/github/krisleech/wisper)
[![Build Status](https://travis-ci.org/krisleech/wisper.png?branch=master)](https://travis-ci.org/krisleech/wisper)
+[![Coverage Status](https://coveralls.io/repos/krisleech/wisper/badge.png?branch=master)](https://coveralls.io/r/krisleech/wisper?branch=master)
Wisper was extracted from a Rails codebase but is not dependant on Rails.
It is commonly used as an alternative to ActiveRecord callbacks and Observers
to reduce coupling between data and domain layers.
@@ -14,11 +16,11 @@
## Installation
Add this line to your application's Gemfile:
```ruby
-gem 'wisper', '~>1.2.0'
+gem 'wisper'
```
## Usage
Any class with the `Wisper::Publisher` module included can broadcast events
@@ -74,11 +76,11 @@
```ruby
class Bid < ActiveRecord::Base
include Wisper::Publisher
- validates :amount, :presence => true
+ validates :amount, presence: true
def commit(_attrs = nil)
assign_attributes(_attrs) if _attrs.present?
if valid?
save!
@@ -104,11 +106,11 @@
@bid.subscribe(PusherListener.new)
@bid.subscribe(ActivityListener.new)
@bid.subscribe(StatisticsListener.new)
@bid.on(:create_bid_successful) { |bid| redirect_to bid }
- @bid.on(:create_bid_failed) { |bid| render :action => :new }
+ @bid.on(:create_bid_failed) { |bid| render action: :new }
@bid.commit
end
end
```
@@ -203,11 +205,11 @@
Global listeners should be used with caution, the execution path becomes less
obvious on reading the code and of course you are introducing global state and
'always on' behaviour. This may not desirable.
```ruby
-Wisper.add_listener(MyListener.new)
+Wisper.subscribe(MyListener.new)
```
In a Rails app you might want to add your global listeners in an initalizer.
Global listeners are threadsafe.
@@ -216,28 +218,28 @@
You might want to globally subscribe a listener to publishers with a certain
class.
```ruby
-Wisper.add_listener(MyListener.new, :scope => :MyPublisher)
+Wisper.subscribe(MyListener.new, scope: :MyPublisher)
```
This will subscribe the listener to all instances of `MyPublisher` and its
subclasses.
Alternatively you can also do exactly the same with a publisher class:
```ruby
-MyPublisher.add_listener(MyListener.new)
+MyPublisher.subscribe(MyListener.new)
```
## Temporary Global Listeners
You can also globally subscribe listeners for the duration of a block.
```ruby
-Wisper.with_listeners(MyListener.new, OtherListener.new) do
+Wisper.subscribe(MyListener.new, OtherListener.new) do
# do stuff
end
```
Any events broadcast within the block by any publisher will be sent to the
@@ -248,68 +250,98 @@
## Subscribing to selected events
By default a listener will get notified of all events it can respond to. You
can limit which events a listener is notified of by passing an event or array
-of events to `:on`.
+of events to `on:`.
```ruby
-post_creater.subscribe(PusherListener.new, :on => :create_post_successful)
+post_creater.subscribe(PusherListener.new, on: :create_post_successful)
```
## Prefixing broadcast events
If you would prefer listeners to receive events with a prefix, for example
-`on`, you can do so by passing a string or symbol to `:prefix`.
+`on`, you can do so by passing a string or symbol to `prefix:`.
```ruby
-post_creater.subscribe(PusherListener.new, :prefix => :on)
+post_creater.subscribe(PusherListener.new, prefix: :on)
```
If `post_creater` where to broadcast the event `post_created` the subscribed
listeners would receive `on_post_created`. You can also pass `true` which will
use the default prefix, "on".
## Mapping an event to a different method
By default the method called on the subscriber is the same as the event
-broadcast. However it can be mapped to a different method using `:with`.
+broadcast. However it can be mapped to a different method using `with:`.
```ruby
-report_creator.subscribe(MailResponder.new, :with => :successful)
+report_creator.subscribe(MailResponder.new, with: :successful)
```
-This is pretty useless unless used in conjuction with `:on`, since all events
+This is pretty useless unless used in conjuction with `on:`, since all events
will get mapped to `:successful`. Instead you might do something like this:
```ruby
-report_creator.subscribe(MailResponder.new, :on => :create_report_successful,
- :with => :successful)
+report_creator.subscribe(MailResponder.new, on: :create_report_successful,
+ with: :successful)
```
-If you pass an array of events to `:on` each event will be mapped to the same
-method when `:with` is specified. If you need to listen for select events
+If you pass an array of events to `on:` each event will be mapped to the same
+method when `with:` is specified. If you need to listen for select events
_and_ map each one to a different method subscribe the listener once for
each mapping:
```ruby
-report_creator.subscribe(MailResponder.new, :on => :create_report_successful,
- :with => :successful)
+report_creator.subscribe(MailResponder.new, on: :create_report_successful,
+ with: :successful)
-report_creator.subscribe(MailResponder.new, :on => :create_report_failed,
- :with => :failed)
+report_creator.subscribe(MailResponder.new, on: :create_report_failed,
+ with: :failed)
```
## Chaining subscriptions
```ruby
post.on(:success) { |post| redirect_to post }
- .on(:failure) { |post| render :action => :edit, :locals => :post => post }
+ .on(:failure) { |post| render action: :edit, locals: { post: post } }
```
## RSpec
+### Broadcast Matcher
+
+```ruby
+require 'wisper/rspec/matchers'
+
+RSpec::configure do |config|
+ config.include(Wisper::RSpec::BroadcastMatcher)
+end
+
+expect { publisher.execute }.to broadcast(:an_event)
+```
+
+### Using message expections
+
+If you need to assert on the arguments broadcast you can subscribe a double
+with a [message expection](https://github.com/rspec/rspec-mocks#message-expectations)
+and then use any of the [argument matchers](https://github.com/rspec/rspec-mocks#argument-matchers).
+
+```ruby
+listener = double('Listener')
+
+expect(listener).to receive(:an_event).with(some_args)
+
+publisher.subscribe(listener)
+
+publisher.execute
+```
+
+### Stubbing publishers
+
Wisper comes with a method for stubbing event publishers so that you can create
isolation tests that only care about reacting to events.
Given this piece of code:
@@ -336,10 +368,10 @@
stub_wisper_publisher("MyPublisher", :execute, :some_event, "foo")
end
it "renders" do
response = CodeThatReactsToEvents.new.do_something
- response.should == "Hello with foo!"
+ expect(response).to eq "Hello with foo!"
end
end
end
```