cross-talk 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +6 -0
- data/Gemfile +11 -1
- data/NOTES.md +58 -0
- data/README.md +59 -4
- data/Rakefile +35 -1
- data/cross-talk.gemspec +2 -0
- data/lib/cross-talk.rb +14 -1
- data/lib/cross-talk/listener.rb +123 -0
- data/lib/cross-talk/manager.rb +38 -0
- data/lib/cross-talk/version.rb +1 -1
- data/spec/helpers/the.rb +17 -0
- data/spec/listener_spec.rb +102 -0
- data/spec/manager_spec.rb +76 -0
- data/spec/spec_helper.rb +32 -0
- metadata +38 -4
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/NOTES.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# Cross::Talk -- Event Pub/Sub for PORC
|
2
|
+
|
3
|
+
## Design Notes
|
4
|
+
|
5
|
+
At require-time, create a `Cross::Talk::Manager` instance (a singleton). This
|
6
|
+
serves as the clearinghouse for all events. It is a celluloid actor.
|
7
|
+
|
8
|
+
NB. Though cross-talk is perfectly happy to run on MRI, you'll probably have
|
9
|
+
performance issues unless you run on RBX/JRuby, because we are likely sending
|
10
|
+
_lots_ of messages at any given point in time, and that means we're probably
|
11
|
+
eating a lot of CPU cycles.
|
12
|
+
|
13
|
+
Every public method call triggers and asynchronous notification to the
|
14
|
+
`Cross::Talk::Manager` (henceforth, `CTM`). Containing the method invoked, the
|
15
|
+
object that invoked it, and `:before` or `:after` (depending on which side of
|
16
|
+
the method you're on).
|
17
|
+
|
18
|
+
Another class can subscribe to any event by simply using the class macro
|
19
|
+
`#listen`, a la:
|
20
|
+
|
21
|
+
|
22
|
+
class Foo
|
23
|
+
include Celluloid::Actor
|
24
|
+
include Celluloid::Logger
|
25
|
+
include Cross::Talk
|
26
|
+
|
27
|
+
def bar
|
28
|
+
info "baz"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Listener
|
33
|
+
include Celluloid::Actor
|
34
|
+
include Celluloid::Logger
|
35
|
+
include Cross::Talk
|
36
|
+
|
37
|
+
listen Foo, :bar, :before do
|
38
|
+
info "before Foo#bar"
|
39
|
+
end
|
40
|
+
|
41
|
+
listen "Foo#bar:after" do |obj|
|
42
|
+
info "Calling terminate! on Foo instance"
|
43
|
+
obj.terminate!
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
Listener.new
|
49
|
+
Foo.new.bar
|
50
|
+
|
51
|
+
#=> before Foo#bar
|
52
|
+
#=> baz
|
53
|
+
#=> Calling terminate! on Foo instance
|
54
|
+
#=> <Celluloid::Actor Foo Terminated>
|
55
|
+
|
56
|
+
(mod output formatting).
|
57
|
+
|
58
|
+
|
data/README.md
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
-
# Cross::Talk
|
1
|
+
# Cross::Talk [![Gem Version](https://badge.fury.io/rb/cross-talk.png)](http://badge.fury.io/rb/cross-talk) [![Build Status](https://travis-ci.org/jfredett/cross-talk.png?branch=master)](http://travis-ci.org/jfredett/cross-talk) [![Code Climate](https://codeclimate.com/github/jfredett/cross-talk.png)](https://codeclimate.com/github/jfredett/cross-talk) [![Coverage Status](https://coveralls.io/repos/jfredett/cross-talk/badge.png?branch=master)](https://coveralls.io/r/jfredett/cross-talk)
|
2
2
|
|
3
3
|
NOTA BENE:
|
4
4
|
|
5
|
-
This is
|
6
|
-
|
5
|
+
This is not production ready, the basic functionality is there, but use in
|
6
|
+
critical code is at your own risk.
|
7
|
+
|
8
|
+
Also, this thing is almost certainly going to give you performance problems of
|
9
|
+
the most severe variety.
|
10
|
+
|
11
|
+
## Support
|
12
|
+
|
13
|
+
Check CI for edge support, but ideally we support MRI > 1.9, (including 2.0),
|
14
|
+
Reasonably recent RBX, and JRuby.
|
15
|
+
|
16
|
+
JRuby is broken right now though for unknown reasons.
|
7
17
|
|
8
18
|
## Installation
|
9
19
|
|
@@ -21,7 +31,52 @@ Or install it yourself as:
|
|
21
31
|
|
22
32
|
## Usage
|
23
33
|
|
24
|
-
|
34
|
+
For any object (not just Celluloid Actors, though they'll work the best) simply
|
35
|
+
include `Cross::Talk` and enjoy the following features for that class:
|
36
|
+
|
37
|
+
1. Any public method will automatically send out two events -- one at the
|
38
|
+
beginning of execution, the other at the end. These are identified by the
|
39
|
+
schema: `<class>#<method>:<time>`. Eg. for a class `Foo`, and a method `bar`,
|
40
|
+
calling `Foo.new.bar` would send an event `Foo#bar:before`, and then a
|
41
|
+
`Foo#bar:after`. Note that the event is the same for any instance of the
|
42
|
+
class, then read the "Plans" section, item 2.
|
43
|
+
|
44
|
+
2. Any Cross::Talk class can bind to an event by using the `listen` macro at
|
45
|
+
define-time
|
46
|
+
|
47
|
+
3. Any instance of a Cross::Talk class can bind to an event later, without
|
48
|
+
forcing every other instance to also bind to that event. Think of the
|
49
|
+
difference between `define_method` and `define_singleton_method` (in fact
|
50
|
+
they are implemented precisely that way)
|
51
|
+
|
52
|
+
4. Celluloid Actors which include `Cross::Talk` will have the events sent to
|
53
|
+
them asynchronously, so the event handler won't block while trying to
|
54
|
+
dispatch those events
|
55
|
+
|
56
|
+
|
57
|
+
## Plans
|
58
|
+
|
59
|
+
1. Improve the `listen` macro so you don't always need to supply an argument --
|
60
|
+
it should just be ignored if it's not there.
|
61
|
+
|
62
|
+
2. Allow `listen` to bind to a specific _instance_ of an event, rather than just
|
63
|
+
the whole class of events.
|
64
|
+
|
65
|
+
3. Refactor the codebase, it's a bit sprawling right now
|
66
|
+
|
67
|
+
4. Optimize for dispatch speed -- basically make it as lightweight as possible
|
68
|
+
|
69
|
+
5. Make the Event Dispatcher maybe use some thread primitives during dispatch
|
70
|
+
around non-actors, so that we can join at the end and still send them
|
71
|
+
asynchronous events?
|
72
|
+
|
73
|
+
### Pipe dreams
|
74
|
+
|
75
|
+
1. Optionally back the event manager with a message queue, because why the hell
|
76
|
+
not? It's worth a try, maybe it'll do something neat.
|
77
|
+
|
78
|
+
2. Experiment with making this usable efficiently over DCell. Including making
|
79
|
+
the Event Manager run as a cluster of actors, notifying remote actors, etc.
|
25
80
|
|
26
81
|
## Contributing
|
27
82
|
|
data/Rakefile
CHANGED
@@ -1 +1,35 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
desc 'run specs'
|
7
|
+
RSpec::Core::RakeTask.new do |task|
|
8
|
+
task.rspec_opts = ["-c", "-f progress"]
|
9
|
+
end
|
10
|
+
|
11
|
+
task :default => :spec
|
12
|
+
|
13
|
+
|
14
|
+
task :flog do
|
15
|
+
puts "#### FLOG ####"
|
16
|
+
system 'flog lib/*'
|
17
|
+
puts "##############"
|
18
|
+
end
|
19
|
+
|
20
|
+
task :flay do
|
21
|
+
puts "#### FLAY ####"
|
22
|
+
system 'flay lib/*'
|
23
|
+
puts "##############"
|
24
|
+
end
|
25
|
+
|
26
|
+
task :mutant, [:klass] do |_, args|
|
27
|
+
puts "#### MUTANT TESTING ####"
|
28
|
+
system "mutant -I lib -r cross-talk --rspec-full #{args[:name] || '::Katuv'}"
|
29
|
+
puts "########################"
|
30
|
+
end
|
31
|
+
|
32
|
+
task :metrics => [:flog, :flay]
|
33
|
+
|
34
|
+
|
35
|
+
task :all => [:spec, :mutant, :metrics]
|
data/cross-talk.gemspec
CHANGED
data/lib/cross-talk.rb
CHANGED
@@ -1,7 +1,20 @@
|
|
1
|
+
require 'celluloid'
|
2
|
+
|
1
3
|
require "cross-talk/version"
|
4
|
+
require 'cross-talk/manager'
|
5
|
+
require 'cross-talk/listener'
|
2
6
|
|
3
7
|
module Cross
|
4
8
|
module Talk
|
5
|
-
#
|
9
|
+
# Access the Event Manager
|
10
|
+
def self.manager
|
11
|
+
Celluloid::Actor[:manager] ||= Cross::Talk::Manager.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.included(base)
|
15
|
+
base.send(:include, Listener)
|
16
|
+
end
|
6
17
|
end
|
7
18
|
end
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Cross
|
2
|
+
module Talk
|
3
|
+
module Listener
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:include, InstanceMethods)
|
6
|
+
base.send(:extend, ClassMethods)
|
7
|
+
base.send(:include, Celluloid::Logger)
|
8
|
+
base.send(:extend, Celluloid::Logger)
|
9
|
+
|
10
|
+
# This makes sure that when we add a new hook at runtime, we rebuild all
|
11
|
+
# of our hooks so that they're up-to-date.
|
12
|
+
base.instance_eval do
|
13
|
+
listen base, :__new_hook, :before do
|
14
|
+
register_hooks!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
def register_hooks!
|
21
|
+
self.class.registration_hooks.each { |hook| hook.call(__get_receiver) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(*_)
|
25
|
+
register_hooks!
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
def silenced?
|
30
|
+
@__silenced
|
31
|
+
end
|
32
|
+
|
33
|
+
def silence!
|
34
|
+
@__silenced = true
|
35
|
+
end
|
36
|
+
|
37
|
+
def unsilence!
|
38
|
+
@__silenced = false
|
39
|
+
end
|
40
|
+
|
41
|
+
def silently(&block)
|
42
|
+
silence!
|
43
|
+
block.call
|
44
|
+
unsilence!
|
45
|
+
end
|
46
|
+
|
47
|
+
def listen(klass, event, timing, &block)
|
48
|
+
event_name = "#{klass}##{event}:#{timing}"
|
49
|
+
Cross::Talk.manager.notify('__new_hook:before', event_name)
|
50
|
+
define_singleton_method event_name, &block
|
51
|
+
Cross::Talk.manager.register(event_name, __get_receiver)
|
52
|
+
Cross::Talk.manager.notify('__new_hook:after', event_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def __notify_event(method, timing)
|
58
|
+
return if Object.methods.include?(method)
|
59
|
+
return unless public_methods(false).include?(method)
|
60
|
+
return if silenced?
|
61
|
+
|
62
|
+
receiver = __get_receiver
|
63
|
+
event_name = "#{receiver.class}##{method}:#{timing}"
|
64
|
+
|
65
|
+
Cross::Talk.manager.notify(event_name, receiver)
|
66
|
+
end
|
67
|
+
|
68
|
+
def __get_receiver
|
69
|
+
return Celluloid::Actor.current if is_a?(Celluloid)
|
70
|
+
return self
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module ClassMethods
|
75
|
+
def registration_hooks
|
76
|
+
@registration_hooks ||= []
|
77
|
+
end
|
78
|
+
|
79
|
+
def listen(klass, event, timing, &block)
|
80
|
+
event_name = "#{klass}##{event}:#{timing}"
|
81
|
+
Cross::Talk.manager.notify('__new_hook:before', event_name)
|
82
|
+
define_hook! event_name, &block
|
83
|
+
registration_hooks << proc { |actor| Cross::Talk.manager.register(event_name, actor) }
|
84
|
+
Cross::Talk.manager.notify('__new_hook:after', event_name)
|
85
|
+
end
|
86
|
+
|
87
|
+
def notify(method_name)
|
88
|
+
class_eval %{
|
89
|
+
alias __old_#{method_name} #{method_name}
|
90
|
+
|
91
|
+
def #{method_name}(*args, &block)
|
92
|
+
__notify_event(#{method_name.inspect}, :before)
|
93
|
+
result = __old_#{method_name}(*args, &block)
|
94
|
+
__notify_event(#{method_name.inspect}, :after)
|
95
|
+
result
|
96
|
+
end
|
97
|
+
}
|
98
|
+
|
99
|
+
send(:private, method_name) if private_instance_methods.include?("__old_#{method_name}".to_sym)
|
100
|
+
send(:protected, method_name) if protected_instance_methods.include?("__old_#{method_name}".to_sym)
|
101
|
+
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
|
105
|
+
def method_added(method)
|
106
|
+
# if we're redefining a method, the lock is set to true, so bug out.
|
107
|
+
return if @lock
|
108
|
+
#don't notify hook methods
|
109
|
+
return if method =~ /^.*#.*:.*$/
|
110
|
+
# don't notify pseudoprivate methods
|
111
|
+
return if method =~ /^__/
|
112
|
+
@lock = true
|
113
|
+
notify(method)
|
114
|
+
@lock = false
|
115
|
+
end
|
116
|
+
|
117
|
+
def define_hook!(method, &block)
|
118
|
+
define_method(method, &block)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Cross
|
2
|
+
module Talk
|
3
|
+
class Manager
|
4
|
+
include Celluloid
|
5
|
+
include Celluloid::Logger
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@event_table = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def notify(event, sender)
|
12
|
+
receivers_for(event).each do |receiver|
|
13
|
+
next unless receiver.respond_to?(event)
|
14
|
+
if receiver.respond_to?(:async)
|
15
|
+
receiver.async
|
16
|
+
else
|
17
|
+
receiver
|
18
|
+
end.send(event, sender)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def register(event, receiver)
|
23
|
+
receivers_for(event) << receiver
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :event_table
|
30
|
+
|
31
|
+
def receivers_for(event)
|
32
|
+
# We need to ||= here to avoid a weird behavior with Hash.new { [] } --
|
33
|
+
# you can't destructively update the first element to it.
|
34
|
+
event_table[event] ||= Set.new
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/cross-talk/version.rb
CHANGED
data/spec/helpers/the.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Cross
|
3
|
+
module Talk
|
4
|
+
module DSL
|
5
|
+
module Macros
|
6
|
+
def the(sym, &block)
|
7
|
+
context sym do
|
8
|
+
subject { if sym.is_a? Class then sym else send sym end }
|
9
|
+
it &block
|
10
|
+
end
|
11
|
+
end
|
12
|
+
alias the_class the
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe Cross::Talk::Listener do
|
5
|
+
before :all do
|
6
|
+
class Sender
|
7
|
+
include Celluloid
|
8
|
+
include Cross::Talk
|
9
|
+
|
10
|
+
def test
|
11
|
+
end
|
12
|
+
|
13
|
+
def late
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def protected_method
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def private_method
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Receiver
|
28
|
+
include Celluloid
|
29
|
+
include Cross::Talk
|
30
|
+
|
31
|
+
listen Sender, :test, :after do |sender|
|
32
|
+
@notified = true
|
33
|
+
end
|
34
|
+
|
35
|
+
listen Sender, :private_method, :after do |sender|
|
36
|
+
debug "Should never occur"
|
37
|
+
@notified = true
|
38
|
+
end
|
39
|
+
|
40
|
+
listen Sender, :protected_method, :after do |sender|
|
41
|
+
debug "Should never occur"
|
42
|
+
@notified = true
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_been_notified?
|
46
|
+
@notified
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
after :all do
|
51
|
+
Object.send(:remove_const, :Receiver)
|
52
|
+
Object.send(:remove_const, :Sender)
|
53
|
+
end
|
54
|
+
|
55
|
+
let!(:receiver) { Receiver.new }
|
56
|
+
let!(:other_receiver) { Receiver.new }
|
57
|
+
let!(:sender) { Sender.new }
|
58
|
+
|
59
|
+
subject { receiver }
|
60
|
+
|
61
|
+
context 'late-bound listen' do
|
62
|
+
|
63
|
+
before do
|
64
|
+
receiver.listen(Sender, :late, :after) do |*_|
|
65
|
+
@notified = true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
the(:receiver) { should_not have_been_notified }
|
70
|
+
the(:other_receiver) { should_not have_been_notified }
|
71
|
+
|
72
|
+
describe 'when the message is sent' do
|
73
|
+
before { sender.late }
|
74
|
+
|
75
|
+
the(:receiver) { should have_been_notified }
|
76
|
+
the(:other_receiver) { should_not have_been_notified }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'define-time bound listen' do
|
81
|
+
it { should respond_to :"Sender#test:after" }
|
82
|
+
it { should_not have_been_notified }
|
83
|
+
|
84
|
+
describe 'calling the method' do
|
85
|
+
before { sender.test }
|
86
|
+
|
87
|
+
it { should have_been_notified }
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'calling a private method on the sender' do
|
91
|
+
before { sender.send(:private_method) }
|
92
|
+
|
93
|
+
it { should_not have_been_notified }
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'calling a protected method on the sender' do
|
97
|
+
before { sender.send(:protected_method) }
|
98
|
+
|
99
|
+
it { should_not have_been_notified }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe Cross::Talk::Manager do
|
5
|
+
subject(:manager) { Cross::Talk.manager }
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
class Receiver
|
9
|
+
include Celluloid
|
10
|
+
include Celluloid::Logger
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
Cross::Talk.manager.register('an_event', Actor.current)
|
14
|
+
end
|
15
|
+
|
16
|
+
def an_event(*_)
|
17
|
+
@notification = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_received_notification?
|
21
|
+
@notification
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class StupidReceiver
|
26
|
+
include Celluloid
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
Cross::Talk.manager.register('an_event', Actor.current)
|
30
|
+
end
|
31
|
+
|
32
|
+
# I'm dumb because I didn't implement the event method!
|
33
|
+
end
|
34
|
+
|
35
|
+
class NonReceiver
|
36
|
+
include Celluloid
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
Cross::Talk.manager.register('another_event', Actor.current)
|
40
|
+
end
|
41
|
+
|
42
|
+
def another_event(*_)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
after :all do
|
48
|
+
Object.send(:remove_const, :Receiver)
|
49
|
+
Object.send(:remove_const, :NonReceiver)
|
50
|
+
Object.send(:remove_const, :StupidReceiver)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
describe 'api' do
|
55
|
+
it { should respond_to :notify }
|
56
|
+
it { should respond_to :register }
|
57
|
+
end
|
58
|
+
|
59
|
+
let!(:receiver) { Receiver.new }
|
60
|
+
let!(:non_receiver) { NonReceiver.new }
|
61
|
+
let!(:stupid_receiver) { StupidReceiver.new }
|
62
|
+
|
63
|
+
before { manager.notify('an_event', nil) }
|
64
|
+
|
65
|
+
it 'notifies registered receivers when an event occurs' do
|
66
|
+
receiver.should have_received_notification
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'only notifies registered receivers which actually define the event method' do
|
70
|
+
stupid_receiver.should_not have_received :an_event
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'does not notify receivers of other messages of that message' do
|
74
|
+
non_receiver.should_not have_received :an_event
|
75
|
+
end
|
76
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
require 'cross-talk'
|
6
|
+
|
7
|
+
require 'rspec-spies'
|
8
|
+
|
9
|
+
require 'coveralls'
|
10
|
+
Coveralls.wear!
|
11
|
+
|
12
|
+
#include helpers
|
13
|
+
Dir["./spec/helpers/*.rb"].each { |file| require file }
|
14
|
+
|
15
|
+
#include shared examples
|
16
|
+
Dir["./spec/shared/*_examples.rb"].each { |file| require file }
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.before do
|
20
|
+
allow_message_expectations_on_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
24
|
+
|
25
|
+
config.extend(RSpec::Cross::Talk::DSL::Macros)
|
26
|
+
end
|
27
|
+
|
28
|
+
class RSpec::Mocks::Mock
|
29
|
+
def inspect
|
30
|
+
"double(#{@name.inspect})"
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cross-talk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
13
|
-
dependencies:
|
12
|
+
date: 2013-04-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: celluloid
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
description: A Pub/Sub Event Management Service for Ruby Classes
|
15
31
|
email:
|
16
32
|
- jfredett@gmail.com
|
@@ -19,13 +35,21 @@ extensions: []
|
|
19
35
|
extra_rdoc_files: []
|
20
36
|
files:
|
21
37
|
- .gitignore
|
38
|
+
- .travis.yml
|
22
39
|
- Gemfile
|
23
40
|
- LICENSE.txt
|
41
|
+
- NOTES.md
|
24
42
|
- README.md
|
25
43
|
- Rakefile
|
26
44
|
- cross-talk.gemspec
|
27
45
|
- lib/cross-talk.rb
|
46
|
+
- lib/cross-talk/listener.rb
|
47
|
+
- lib/cross-talk/manager.rb
|
28
48
|
- lib/cross-talk/version.rb
|
49
|
+
- spec/helpers/the.rb
|
50
|
+
- spec/listener_spec.rb
|
51
|
+
- spec/manager_spec.rb
|
52
|
+
- spec/spec_helper.rb
|
29
53
|
homepage: ''
|
30
54
|
licenses: []
|
31
55
|
post_install_message:
|
@@ -38,16 +62,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
38
62
|
- - ! '>='
|
39
63
|
- !ruby/object:Gem::Version
|
40
64
|
version: '0'
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
hash: 635870557992844421
|
41
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
69
|
none: false
|
43
70
|
requirements:
|
44
71
|
- - ! '>='
|
45
72
|
- !ruby/object:Gem::Version
|
46
73
|
version: '0'
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
hash: 635870557992844421
|
47
77
|
requirements: []
|
48
78
|
rubyforge_project:
|
49
79
|
rubygems_version: 1.8.24
|
50
80
|
signing_key:
|
51
81
|
specification_version: 3
|
52
82
|
summary: A Pub/Sub Event Management Service for Ruby Classes
|
53
|
-
test_files:
|
83
|
+
test_files:
|
84
|
+
- spec/helpers/the.rb
|
85
|
+
- spec/listener_spec.rb
|
86
|
+
- spec/manager_spec.rb
|
87
|
+
- spec/spec_helper.rb
|