event_stream 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +99 -0
- data/Rakefile +10 -0
- data/event_stream.gemspec +26 -0
- data/lib/event_stream.rb +79 -0
- data/lib/event_stream/subscriber_dsl.rb +49 -0
- data/lib/event_stream/test_helper.rb +34 -0
- data/lib/event_stream/version.rb +3 -0
- data/test/event_stream/event_stream_test.rb +54 -0
- data/test/event_stream/subscriber_dsl_test.rb +54 -0
- data/test/event_stream/test_helper_test.rb +42 -0
- data/test/test_helper.rb +13 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4eb7f64821b9716f61474ae0fbeb45933544a449
|
4
|
+
data.tar.gz: 7b2dff88c4593999dffab1121a20cda3bafaaedf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 63b1d01de337fcedd119ec1b89435bb0153c886297ef1958420cc6c395571333466781876a71360233113eee119a0ee8d63c9d7417904b492d3c98dfff822970
|
7
|
+
data.tar.gz: 81f0a46e4dcf4e4dca4637d8c5b0f78cfcae07ac0e0bb5b90e26de4d91a9590f606c00b25005ad1b18a364822abdf5907c7a1f52a646806c0108dbd10e911e03
|
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in event_stream.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem "pry"
|
8
|
+
gem "awesome_print"
|
9
|
+
gem 'm', :git => 'git@github.com:ANorwell/m.git', :branch => 'minitest_5'
|
10
|
+
end
|
11
|
+
|
12
|
+
group :test do
|
13
|
+
gem 'minitest_should', :git => 'git@github.com:citrus/minitest_should.git'
|
14
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Datto
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# EventStream
|
2
|
+
|
3
|
+
A minimal library for synchronously publishing and subscribing to events.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
Create an event subscription:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
EventStream.subscribe(:my_event) do |event|
|
11
|
+
log("#{event.name}, #{event.description}")
|
12
|
+
end
|
13
|
+
```
|
14
|
+
Then fire an event:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
EventStream.publish(:my_event, :description => "An example event.")
|
18
|
+
```
|
19
|
+
|
20
|
+
An event is just an OpenStruct with a name and a bundle of other attributes, so the use of `:description` here is arbitrary.
|
21
|
+
|
22
|
+
Events can be subscribed to by name, as above, but many other ways are supported:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
# Subscribe to all events
|
26
|
+
EventStream.subscribe { |e| ... }
|
27
|
+
|
28
|
+
# Subscribe to events with a given name
|
29
|
+
EventStream.subscribe(:my_event) { |e| ... }
|
30
|
+
|
31
|
+
# Subscribe to events based on a name regex
|
32
|
+
EventStream.subscribe(/my/) { |e| ... }
|
33
|
+
|
34
|
+
# Subscribe to events based on their attributes
|
35
|
+
EventStream.subscribe(:user_id => 1) { |e| ... }
|
36
|
+
|
37
|
+
# Subscribe to events based on an arbitrary filter
|
38
|
+
filter = lambda { |e| e.size > 3 }
|
39
|
+
EventStream.subscribe(filter) { |e| ... }
|
40
|
+
```
|
41
|
+
|
42
|
+
### Event Streams
|
43
|
+
|
44
|
+
If you wish, you may create more than one event stream:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
stream = EventStream::Stream.new
|
48
|
+
stream.subscribe(...) { |e| ... }
|
49
|
+
stream.publish(...)
|
50
|
+
```
|
51
|
+
|
52
|
+
### Subscriber DSL
|
53
|
+
|
54
|
+
It's sometimes useful to separate the definition of a subscriber action
|
55
|
+
from the registration of the subscriber. The `SubscriberDSL` module
|
56
|
+
provides a way to do this.
|
57
|
+
|
58
|
+
Define a subscriber by mixing in the module:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
class MySubscriber
|
62
|
+
include EventStream::SubscriberDSL
|
63
|
+
|
64
|
+
# Which event_stream to use. If not specified, the default will be used.
|
65
|
+
event_stream EventStream.default_stream
|
66
|
+
|
67
|
+
# Sets up a subscriber using a block
|
68
|
+
on(:my_event) { |event| puts event.name }
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
The definition of this class does NOT subscribe to any events. To subscribe
|
73
|
+
to the :my_event event, it is necessary to call `MySubscriber.subscribe`.
|
74
|
+
|
75
|
+
It is possible to use multiple `on` statements in a single class.
|
76
|
+
`MySubscriber.subscribe` will register all subscriptions.
|
77
|
+
|
78
|
+
## Application Testing
|
79
|
+
|
80
|
+
event_stream includes a test_helper module that provides some assertions, like `assert_event_published`. To use:
|
81
|
+
1. `require 'event_stream/test_helper'`
|
82
|
+
2. Call `EventStream::Assertions.setup_test_subscription` in the setup block of your tests
|
83
|
+
3. Include the `EventStream::Assertions` module where needed
|
84
|
+
|
85
|
+
## Installation
|
86
|
+
|
87
|
+
Add this line to your application's Gemfile:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
gem 'event_stream', :git => 'git@github.com:backupify/event_stream.git'
|
91
|
+
```
|
92
|
+
|
93
|
+
And then execute:
|
94
|
+
|
95
|
+
$ bundle
|
96
|
+
|
97
|
+
Or install it yourself as:
|
98
|
+
|
99
|
+
$ gem install event_stream
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'event_stream/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "event_stream"
|
8
|
+
spec.version = EventStream::VERSION
|
9
|
+
spec.authors = ["Arron Norwell"]
|
10
|
+
spec.email = ["anorwell@datto.com"]
|
11
|
+
spec.summary = %q{A minimal library for synchronously publishing and subscribing to events.}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
21
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
+
spec.add_development_dependency "minitest"
|
23
|
+
spec.add_development_dependency "minitest-reporters"
|
24
|
+
|
25
|
+
spec.add_dependency 'activesupport'
|
26
|
+
end
|
data/lib/event_stream.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require_relative 'event_stream/subscriber_dsl'
|
3
|
+
|
4
|
+
module EventStream
|
5
|
+
class << self
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
# The default event stream
|
9
|
+
# @return [Stream]
|
10
|
+
def default_stream
|
11
|
+
@default_stream ||= Stream.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def_delegators :default_stream, :publish, :subscribe, :clear_subscribers
|
15
|
+
end
|
16
|
+
|
17
|
+
# An Event. Each event is an OpenStruct with a name as well as any number of other optional fields.
|
18
|
+
# @!attribute name
|
19
|
+
# @return [Symbol]
|
20
|
+
class Event < OpenStruct; end
|
21
|
+
|
22
|
+
class Stream
|
23
|
+
def initialize
|
24
|
+
@subscribers = []
|
25
|
+
end
|
26
|
+
|
27
|
+
# Publishes an event to this event stream
|
28
|
+
# @param name [Symbol] name of this event
|
29
|
+
# @param attrs [Hash] optional attributes representing this event
|
30
|
+
def publish(name, attrs = {})
|
31
|
+
e = Event.new(attrs.merge(:name => name))
|
32
|
+
@subscribers.each { |l| l.consume(e) }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Registers a subscriber to this event stream.
|
36
|
+
# @param filter [Object] Filters which events this subscriber will consume.
|
37
|
+
# If a string or regexp is provided, these will be matched against the event name.
|
38
|
+
# A hash will be matched against the attributes of the event.
|
39
|
+
# Or, any arbitrary predicate on events may be provided.
|
40
|
+
# @yield [Event] action to perform when the event occurs.
|
41
|
+
def subscribe(filter = nil, &action)
|
42
|
+
add_subscriber(Subscriber.create(filter, &action))
|
43
|
+
end
|
44
|
+
|
45
|
+
# Clears all subscribers from this event stream.
|
46
|
+
def clear_subscribers
|
47
|
+
@subscribers = []
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns all subscribers for this stream
|
51
|
+
# @return [Array<EventStream::Subscriber]
|
52
|
+
def subscribers
|
53
|
+
@subscribers
|
54
|
+
end
|
55
|
+
|
56
|
+
# Adds a subscriber to this stream
|
57
|
+
# @param [EventStream::Subscriber]
|
58
|
+
def add_subscriber(subscriber)
|
59
|
+
@subscribers << subscriber
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Subscriber < Struct.new(:filter, :action)
|
64
|
+
def self.create(filter = nil, &action)
|
65
|
+
filter ||= lambda { |e| true }
|
66
|
+
filter_predicate = case filter
|
67
|
+
when Symbol, String then lambda { |e| e.name.to_s == filter.to_s }
|
68
|
+
when Regexp then lambda { |e| e.name =~ filter }
|
69
|
+
when Hash then lambda { |e| filter.all? { |k,v| e[k] === v } }
|
70
|
+
else filter
|
71
|
+
end
|
72
|
+
new(filter_predicate, action)
|
73
|
+
end
|
74
|
+
|
75
|
+
def consume(event)
|
76
|
+
action.call(event) if filter.call(event)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/core_ext/class/attribute'
|
3
|
+
|
4
|
+
module EventStream
|
5
|
+
# Provides a DSL with which to create Subscribers.
|
6
|
+
# For example:
|
7
|
+
#
|
8
|
+
# class MySubscriber
|
9
|
+
# include EventStream::SubscriberDSL
|
10
|
+
#
|
11
|
+
# # Which event_stream to use. If not specified, the default will be used.
|
12
|
+
# event_stream EventStream.default_stream
|
13
|
+
#
|
14
|
+
# # Sets up a subscriber using a block
|
15
|
+
# on(:my_other_event) { |event| puts event.name }
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# Note that this does NOT register subscribers. To register subscribers, call:
|
19
|
+
#
|
20
|
+
# MySubscriber.subscribe
|
21
|
+
#
|
22
|
+
# This registers all subscribers to the provided event_stream (or to the default).
|
23
|
+
#
|
24
|
+
module SubscriberDSL
|
25
|
+
extend ActiveSupport::Concern
|
26
|
+
|
27
|
+
included do
|
28
|
+
class_attribute :_event_subscribers
|
29
|
+
class_attribute :_event_stream
|
30
|
+
attr_reader :event
|
31
|
+
self._event_subscribers = []
|
32
|
+
self._event_stream = EventStream.default_stream
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
def event_stream(event_stream)
|
37
|
+
self._event_stream = event_stream
|
38
|
+
end
|
39
|
+
|
40
|
+
def on(filter, &action)
|
41
|
+
self._event_subscribers << Subscriber.create(filter, &action)
|
42
|
+
end
|
43
|
+
|
44
|
+
def subscribe
|
45
|
+
_event_subscribers.each { |subscriber| _event_stream.add_subscriber(subscriber) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module EventStream
|
2
|
+
|
3
|
+
module TestEventStream
|
4
|
+
class << self
|
5
|
+
attr_accessor :events
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module Assertions
|
10
|
+
def self.setup_test_subscription
|
11
|
+
TestEventStream.events = []
|
12
|
+
|
13
|
+
EventStream.subscribe(//) do |event|
|
14
|
+
TestEventStream.events << event
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def assert_event_matching(message = nil, &predicate)
|
19
|
+
if TestEventStream.events.nil?
|
20
|
+
raise "Call EventStream::TestHelper.setup prior to using event_stream test assertions!"
|
21
|
+
end
|
22
|
+
|
23
|
+
assert TestEventStream.events.any?(&predicate), "Event stream did not include a matching event: #{message}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def assert_event_published(event_name)
|
27
|
+
assert_event_matching("No event with name #{event_name}") { |event| event.name == event_name }
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_published_event(&predicate)
|
31
|
+
TestEventStream.events.find(&predicate)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class EventStreamTest < Minitest::Should::TestCase
|
4
|
+
|
5
|
+
def pub_sub(name, attrs = {}, filter = nil)
|
6
|
+
event = nil
|
7
|
+
EventStream.subscribe(filter) do |e|
|
8
|
+
event = e
|
9
|
+
end
|
10
|
+
EventStream.publish(name, attrs)
|
11
|
+
event
|
12
|
+
end
|
13
|
+
|
14
|
+
teardown do
|
15
|
+
EventStream.default_stream.clear_subscribers
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'an event stream' do
|
19
|
+
should 'publish an event and allow a subscriber to consume it' do
|
20
|
+
event = pub_sub(:test)
|
21
|
+
assert event
|
22
|
+
assert_equal :test, event.name
|
23
|
+
end
|
24
|
+
|
25
|
+
should 'expose all event attributes to the subscriber' do
|
26
|
+
event = pub_sub(:test, :x => 1)
|
27
|
+
assert_equal 1, event.x
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'filtering events' do
|
31
|
+
should 'allow subscription to event names' do
|
32
|
+
assert pub_sub(:test, {}, :test)
|
33
|
+
refute pub_sub(:test, {}, :other_name)
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'allow subscription to event names by regex' do
|
37
|
+
assert pub_sub(:test_event, {}, /test/)
|
38
|
+
refute pub_sub(:test_event, {}, /no_match/)
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'allow subscription by event attributes' do
|
42
|
+
assert pub_sub(:test, { :x => 1, :y => :attr}, :y => :attr)
|
43
|
+
refute pub_sub(:test, { :x => 1, :y => :other}, :y => :attr)
|
44
|
+
end
|
45
|
+
|
46
|
+
should 'allow subscription via arbitrary predicate' do
|
47
|
+
predicate = lambda { |e| e.x > 1 }
|
48
|
+
assert pub_sub(:test, { :x => 2, :y => :attr}, predicate)
|
49
|
+
refute pub_sub(:test, { :x => 1, :y => :attr}, predicate)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
module EventStream
|
4
|
+
class SubscriberDSLTest < Minitest::Should::TestCase
|
5
|
+
|
6
|
+
class MySubscriber
|
7
|
+
include SubscriberDSL
|
8
|
+
|
9
|
+
class << self
|
10
|
+
attr_accessor :events
|
11
|
+
end
|
12
|
+
|
13
|
+
on(:event) { |event| self.events << event }
|
14
|
+
|
15
|
+
def a_method(event)
|
16
|
+
self.class.events << event
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'The Subscriber DSL' do
|
21
|
+
setup do
|
22
|
+
MySubscriber.events = []
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'the default stream' do
|
26
|
+
setup do
|
27
|
+
EventStream.clear_subscribers
|
28
|
+
MySubscriber.event_stream(EventStream.default_stream)
|
29
|
+
MySubscriber.subscribe
|
30
|
+
end
|
31
|
+
|
32
|
+
should 'handle a published event' do
|
33
|
+
EventStream.publish(:event, test: true)
|
34
|
+
assert_equal 1, MySubscriber.events.count
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'other event streams' do
|
39
|
+
setup do
|
40
|
+
@stream = EventStream::Stream.new
|
41
|
+
MySubscriber.event_stream(@stream)
|
42
|
+
|
43
|
+
@stream.clear_subscribers
|
44
|
+
MySubscriber.subscribe
|
45
|
+
end
|
46
|
+
|
47
|
+
should 'handle a published event' do
|
48
|
+
@stream.publish(:event, test: true)
|
49
|
+
assert_equal 1, MySubscriber.events.count
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
require 'event_stream/test_helper'
|
3
|
+
|
4
|
+
module EventStream
|
5
|
+
class TestHelperTest < Minitest::Should::TestCase
|
6
|
+
include Assertions
|
7
|
+
|
8
|
+
setup do
|
9
|
+
EventStream.clear_subscribers
|
10
|
+
Assertions.setup_test_subscription
|
11
|
+
end
|
12
|
+
|
13
|
+
context '#assert_event_published' do
|
14
|
+
should 'raise no error when an event has been published' do
|
15
|
+
EventStream.publish(:test_event)
|
16
|
+
assert_event_published(:test_event)
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'raise an error if the event has not been published' do
|
20
|
+
assert_raises(Minitest::Assertion) { assert_event_published(:test_event) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'registering the test subscription' do
|
25
|
+
should 'not register multiple subscriptions' do
|
26
|
+
assert_equal 1, EventStream.default_stream.subscribers.length
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context '#find_published_event' do
|
31
|
+
should 'find an event if one is present' do
|
32
|
+
EventStream.publish(:test_event, key: :val)
|
33
|
+
assert find_published_event { |evt| evt.key == :val }
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'not find an event if it does not match' do
|
37
|
+
EventStream.publish(:test_event, key: :other)
|
38
|
+
refute find_published_event { |evt| evt.key == :val }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: event_stream
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Arron Norwell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activesupport
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- anorwell@datto.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- event_stream.gemspec
|
96
|
+
- lib/event_stream.rb
|
97
|
+
- lib/event_stream/subscriber_dsl.rb
|
98
|
+
- lib/event_stream/test_helper.rb
|
99
|
+
- lib/event_stream/version.rb
|
100
|
+
- test/event_stream/event_stream_test.rb
|
101
|
+
- test/event_stream/subscriber_dsl_test.rb
|
102
|
+
- test/event_stream/test_helper_test.rb
|
103
|
+
- test/test_helper.rb
|
104
|
+
homepage: ''
|
105
|
+
licenses:
|
106
|
+
- MIT
|
107
|
+
metadata: {}
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 2.2.2
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: A minimal library for synchronously publishing and subscribing to events.
|
128
|
+
test_files:
|
129
|
+
- test/event_stream/event_stream_test.rb
|
130
|
+
- test/event_stream/subscriber_dsl_test.rb
|
131
|
+
- test/event_stream/test_helper_test.rb
|
132
|
+
- test/test_helper.rb
|
133
|
+
has_rdoc:
|