neighborparrot 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,10 +1,9 @@
1
1
  source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
2
 
6
- # Add dependencies to develop your gem here.
7
- # Include everything needed to run rake, tests, features, etc.
3
+ gem 'eventmachine'
4
+ gem 'em-http-request'
5
+ gem 'em-eventsource'
6
+
8
7
  group :development do
9
8
  gem "rspec", "~> 2.3.0"
10
9
  gem "bundler", "~> 1.0.0"
data/Gemfile.lock CHANGED
@@ -1,10 +1,23 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ addressable (2.2.6)
4
5
  diff-lcs (1.1.3)
6
+ em-eventsource (0.1.5)
7
+ em-http-request (~> 1.0.0)
8
+ eventmachine (~> 1.0.0.beta3)
9
+ em-http-request (1.0.0)
10
+ addressable (>= 2.2.3)
11
+ em-socksify
12
+ eventmachine (>= 1.0.0.beta.3)
13
+ http_parser.rb (>= 0.5.2)
14
+ em-socksify (0.1.0)
15
+ eventmachine
16
+ eventmachine (1.0.0.beta.4)
5
17
  faker (1.0.1)
6
18
  i18n (~> 0.4)
7
19
  git (1.2.5)
20
+ http_parser.rb (0.5.3)
8
21
  i18n (0.6.0)
9
22
  jeweler (1.6.4)
10
23
  bundler (~> 1.0)
@@ -26,6 +39,9 @@ PLATFORMS
26
39
 
27
40
  DEPENDENCIES
28
41
  bundler (~> 1.0.0)
42
+ em-eventsource
43
+ em-http-request
44
+ eventmachine
29
45
  faker
30
46
  jeweler (~> 1.6.4)
31
47
  rcov
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.3.2
@@ -0,0 +1,20 @@
1
+ # Callbacks used by the client
2
+ module Neighborparrot
3
+ @@module_event_block = {}
4
+
5
+ EVENTS = %w(message error close connect success timeout)
6
+
7
+ # Callbacks helpers are auto generated
8
+ #===============================================
9
+
10
+ # Generate class helpers
11
+ EVENTS.each do |event|
12
+ clazz = class << self; self; end
13
+ clazz.send :define_method, "on_#{event}" do |&block|
14
+ @@module_event_block[event] = block
15
+ end
16
+ clazz.send :define_method, "trigger_#{event}" do |*args|
17
+ @@module_event_block[event].call *args
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,57 @@
1
+ # Configuration settings and methods
2
+ module Neighborparrot
3
+
4
+ # Setup the configuration options
5
+ # * :api_id => Your api ID in neighborparrot.com
6
+ # * :api_key => Your api key
7
+ # * :server => Server to connect (Only for development)
8
+ # * :dummy_tests => See neighboparrot/helpers/url_helpers
9
+ def self.configure(params={})
10
+ @@config.merge! params
11
+ end
12
+
13
+ # Return settings
14
+ def self.configuration
15
+ @@config
16
+ end
17
+
18
+ private
19
+
20
+ DEFAULT_SERVER = 'https://neighborparrot.net'
21
+ ASSETS_SERVER = 'https://neighborparrot.com'
22
+ DEFAULT_SEND_TIMEOUT = 5
23
+
24
+ def self.default_values
25
+ {
26
+ :server => DEFAULT_SERVER ,
27
+ :assets_server => ASSETS_SERVER,
28
+ :send_timeout => DEFAULT_SEND_TIMEOUT
29
+ }
30
+ end
31
+
32
+
33
+ @@config = self.default_values
34
+
35
+ # Return true if neighborparrot is in dummy connection mode
36
+ def dummy_connections?
37
+ @@config[:dummy_tests] && in_rails? && Rails.env.test?
38
+ end
39
+
40
+
41
+ # Chen mandatory parameters
42
+ # @param [Hash] parameters
43
+ # @param [Symbol] action [:send/:open]
44
+ def check_params(p, action=:send)
45
+ trigger_on_error "Channel can't be nil" if p[:channel].nil? || p[:channel].length == 0
46
+ trigger_on_error "ERROR# Neighborparrot: api_id can't be nil" if p[:api_id].nil? || p[:api_id].length == 0
47
+ if action == :send
48
+ trigger_on_error "ERROR# Neighborparrot: api_key can't be nil" if p[:api_key].nil? || p[:api_key].length == 0
49
+ end
50
+ true
51
+ end
52
+
53
+ # In rails?
54
+ def in_rails?
55
+ defined?(Rails) == 'constant'
56
+ end
57
+ end
@@ -0,0 +1,20 @@
1
+ module ActionView
2
+ module Helpers
3
+ module AssetTagHelper
4
+
5
+ NEIGHBORPARROT_JS_API = '/js/parrot.js'
6
+ NEIGHBORPARROT_JS_DUMMY_API = '/js/dummy-parrot.js'
7
+
8
+ # URL helper for the parrot js client
9
+ # If :dummy_tests is true, use a dummy parrot
10
+ # avoiding connections with the server but
11
+ # triggering onconnect
12
+ def neighborparrot_include_tag
13
+ config = Neighborparrot.configuration
14
+ parrot_js = config[:dummy_connections] ? NEIGHBORPARROT_JS_DUMMY_API : NEIGHBORPARROT_JS_API
15
+ src = "#{config[:assets_server]}#{parrot_js}"
16
+ content_tag(:script, nil, { :type => 'text/javascript', :src => src })
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,66 @@
1
+ require 'em-eventsource'
2
+ module Neighborparrot
3
+
4
+ # Open a persistent connection to the Neighbor in a new
5
+ # thread and return true if all works unless :foreground
6
+ # options is true.
7
+ # Current options to the connectio are:
8
+ #
9
+ # @param [String] channel to connect
10
+ # @param [Hash] Params for the connection. this params can be:
11
+ # * :foreground [Boolean] run the connection in the foreground
12
+ # stoping the clode flow until the connection is closed by server or
13
+ # another thread call close
14
+ # * :api_id => Your api ID in neighborparrot.com
15
+ # * :api_key => Your api key
16
+ # * :server => Server to connect (Only for development)
17
+ def open_connection(params)
18
+ params = Neighborparrot.configuration.merge params
19
+ return unless check_params params, :post
20
+ return if dummy_connections?
21
+ uri = URI.parse(params[:server])
22
+ channel = params[:channel]
23
+ url = "#{params[:server]}/open"
24
+
25
+ @source = EM::EventSource.new(url, :channel => channel )
26
+ @source.inactivity_timeout = 120
27
+ @source.message do |message|
28
+ EM.next_tick { trigger_message message }
29
+ end
30
+ @source.error do |error|
31
+ EM.next_tick { trigger_error error }
32
+ end
33
+
34
+ @source.open do
35
+ EM.next_tick { trigger_connect }
36
+ end
37
+
38
+ @source.start
39
+ end
40
+
41
+ def connected?
42
+ @source && @source.ready_state == EM::EventSource::OPEN
43
+ end
44
+
45
+ def close
46
+ return unless connected?
47
+ @source.close
48
+ end
49
+
50
+ # Static helper. Create a EM Reactor and open the connexion on it
51
+ def self.open(params={})
52
+ EM.run do
53
+ parrot = Neighborparrot::Reactor.new
54
+ parrot.on_error do |error|
55
+ puts "Error: #{error}"
56
+ EM.stop
57
+ end
58
+ parrot.on_message do |message|
59
+ puts "Received: #{message}"
60
+ end
61
+ parrot.on_connect { puts "Connected" }
62
+
63
+ parrot.open params
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,109 @@
1
+ require 'eventmachine'
2
+ require 'em-http'
3
+
4
+ module Neighborparrot
5
+ @@class_reactor = nil
6
+ # Static a module reactor and keeping running and waiting
7
+ def self.reactor_start
8
+ if @@class_reactor.nil?
9
+ return @@class_reactor = Reactor.new
10
+ end
11
+ @@class_reactor.start
12
+ end
13
+
14
+ # Stop the module reactor
15
+ def self.reactor_stop
16
+ return unless @@class_reactor
17
+ @@class_reactor.stop
18
+ end
19
+
20
+ # @return true if module reactor running
21
+ def self.reactor_running?
22
+ @@class_reactor && @@class_reactor.running?
23
+ end
24
+
25
+
26
+ # Reactor class
27
+ #=====================================
28
+ class Reactor
29
+ include Neighborparrot
30
+
31
+ # Start the reactor in a new thead and prepare
32
+ def initialize
33
+ reactor_start
34
+ define_event_helpers
35
+ end
36
+
37
+ # generate events helpers for instances
38
+ # This define tho methods:
39
+ # on_event(&block): Setup a block for the event
40
+ # trigger_event(*args): Trigger the event
41
+ def define_event_helpers
42
+ @event_block = {}
43
+ EVENTS.each do |event|
44
+ clazz = class << self; self; end
45
+ clazz.send :define_method, "on_#{event}" do |&block|
46
+ @event_block[event] = block
47
+ end
48
+ clazz.send :define_method, "trigger_#{event}" do |*args|
49
+ @event_block[event].call *args if @event_block[event]
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ # Start the reactor if not running
56
+ def start
57
+ reactor_start unless running?
58
+ end
59
+
60
+ # Stop the reactor
61
+ def stop
62
+ EM.schedule { EM.stop }
63
+ end
64
+ # @return true if reactor running
65
+ def running?
66
+ EM.reactor_running?
67
+ end
68
+
69
+ # Send a message to a channel
70
+ # If empty data, refuse to send nothing
71
+ # @param [Hash] params
72
+ # * :api_id => Your api ID in neighborparrot.com
73
+ # * :api_key => Your api key
74
+ # * :server => Server to connect (Only for development)
75
+ # * :channel => The channel name
76
+ # * :data => Your payload
77
+ # @return [Boolean] true if sended
78
+ def send(params)
79
+ EM.schedule { @out_queue.push params }
80
+ end
81
+
82
+
83
+ # Open a Event Source connection with the broker
84
+ def open(params)
85
+ EM.schedule { open_connection params }
86
+ end
87
+
88
+ private
89
+ # Create a thread for the reactor and startit
90
+ def reactor_start
91
+ if EM.reactor_running?
92
+ return init_queue unless @out_queue
93
+ end
94
+ @em_thread = Thread.new {
95
+ EM.run { init_queue }
96
+ }
97
+ end
98
+
99
+ # Prepare the sent queue for send the message to the broker
100
+ # as soon as possible
101
+ def init_queue
102
+ @out_queue = EM::Queue.new
103
+ processor = proc { |msg|
104
+ send_to_broker msg
105
+ @out_queue.pop(&processor)
106
+ }
107
+ @out_queue.pop(&processor)
108
+ end
109
+ end
@@ -1,30 +1,47 @@
1
+ require 'pp'
1
2
  module Neighborparrot
2
3
 
3
- # Post a message to a channel
4
- # Raise exception if channel is not setted
5
- # If empty data, refuse to send nothing
6
- # @param [Hash] params
7
- # * :api_id => Your api ID in neighborparrot.com
8
- # * :api_key => Your api key
9
- # * :server => Server to connect (Only for development)
10
- # * :channel => The channel name
11
- # * :data => Your payload
12
- # @return [Boolean] true if sended
4
+ # Send the message to the broker.
5
+ # Create a new reactor and run the request inside
6
+ # Any output is printed in the standard output.
7
+ # If you start a module reactor in some point in your program
8
+ # the request is scheduled in this reactor and return
9
+ # the control to your program. Module callbacks are used in this case.
13
10
  def self.send(params={})
14
- params = self.configuration.merge params
15
- self.check_params params
16
- return false if params[:data].nil? || params[:data].length == 0
17
-
18
- uri = URI(params[:server])
19
- Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
20
- request = Net::HTTP::Post.new('/send')
21
- request.set_form_data(params)
22
- response = http.request(request)
23
- return true if response.body == "Ok"
11
+ if self.reactor_running?
12
+ return @@class_reactor.send params
13
+ end
14
+ EM.run do
15
+ parrot = Neighborparrot::Reactor.new
16
+ parrot.on_error do |error|
17
+ puts "Error: #{error}"
18
+ parrot.stop
19
+ end
20
+ parrot.on_success do |resp|
21
+ puts "=> #{resp}"
22
+ parrot.stop
23
+ end
24
+ parrot.send params
24
25
  end
25
26
  end
26
27
 
27
- def post(channel, data, params={})
28
- Neighborparrot.post(channel, data, params)
28
+ private
29
+ # Send the message to the broker
30
+ def send_to_broker(params={})
31
+ params = Neighborparrot.configuration.merge params
32
+ return unless check_params params
33
+ return if params[:data].nil? || params[:data].length == 0
34
+ return if params[:dummy_connections]
35
+ url = "#{params[:server]}/send"
36
+ http = EventMachine::HttpRequest.new(url).post :body => params
37
+ http.errback{ |msg| trigger_error msg }
38
+ http.callback do
39
+ if http.response_header.status == 200
40
+ trigger_success http.response, params
41
+ else
42
+ trigger_error http.response
43
+ end
44
+ end
29
45
  end
46
+
30
47
  end
@@ -1,38 +1,8 @@
1
- require 'net/http'
2
- require 'net/https'
3
1
  require 'uri'
4
2
 
5
- module Neighborparrot
6
-
7
- # Setup the configuration options
8
- # * :api_id => Your api ID in neighborparrot.com
9
- # * :api_key => Your api key
10
- # * :server => Server to connect (Only for development)
11
- def self.configure(params={})
12
- @@config.merge! params
13
- end
14
-
15
- # Return settings
16
- def self.configuration
17
- @@config
18
- end
19
-
20
- private
21
-
22
- DEFAULT_SERVER = 'https://neighborparrot.net'
23
- @@config = { :server => DEFAULT_SERVER }
24
-
25
- # Chen mandatory parameters
26
- # @param [Hash] parameters
27
- # @param [Symbol] action [:send/:open]
28
- def self.check_params(p, action=:send)
29
- raise "Channel can't be nil" if p[:channel].nil? || p[:channel].length == 0
30
- raise "ERROR# Neighborparrot: api_id can't be nil" if p[:api_id].nil? || p[:api_id].length == 0
31
- if action == :send
32
- raise "ERROR# Neighborparrot: api_key can't be nil" if p[:api_key].nil? || p[:api_key].length == 0
33
- end
34
- end
35
- end
36
-
3
+ require 'neighborparrot/config'
4
+ require 'neighborparrot/callbacks'
5
+ require 'neighborparrot/reactor'
37
6
  require 'neighborparrot/send'
38
- require 'neighborparrot/esparrot'
7
+ require 'neighborparrot/open'
8
+ require 'neighborparrot/helpers/url_helpers'
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "neighborparrot"
8
- s.version = "0.3.1"
8
+ s.version = "0.3.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Eloy Gomez"]
12
- s.date = "2012-01-07"
12
+ s.date = "2012-01-11"
13
13
  s.description = "Send messages to the neighborparrot event source service"
14
14
  s.email = "eloy@indeos.es"
15
15
  s.extra_rdoc_files = [
@@ -26,13 +26,18 @@ Gem::Specification.new do |s|
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "lib/neighborparrot.rb",
29
- "lib/neighborparrot/esparrot.rb",
29
+ "lib/neighborparrot/callbacks.rb",
30
+ "lib/neighborparrot/config.rb",
31
+ "lib/neighborparrot/helpers/url_helpers.rb",
32
+ "lib/neighborparrot/open.rb",
33
+ "lib/neighborparrot/reactor.rb",
30
34
  "lib/neighborparrot/send.rb",
31
35
  "neighborparrot.gemspec",
32
- "spec/esparrot_spec.rb",
33
- "spec/neighborparrot_spec.rb",
36
+ "spec/integration/neighborparrot_spec.rb",
37
+ "spec/reactor_spec.rb",
34
38
  "spec/spec_helper.rb",
35
- "spec/support/helpers.rb"
39
+ "spec/support/helpers.rb",
40
+ "spec/unit/callbacks_spec.rb"
36
41
  ]
37
42
  s.homepage = "http://neighborparrot.com"
38
43
  s.licenses = ["MIT"]
@@ -44,17 +49,26 @@ Gem::Specification.new do |s|
44
49
  s.specification_version = 3
45
50
 
46
51
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<eventmachine>, [">= 0"])
53
+ s.add_runtime_dependency(%q<em-http-request>, [">= 0"])
54
+ s.add_runtime_dependency(%q<em-eventsource>, [">= 0"])
47
55
  s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
48
56
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
49
57
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
50
58
  s.add_development_dependency(%q<rcov>, [">= 0"])
51
59
  else
60
+ s.add_dependency(%q<eventmachine>, [">= 0"])
61
+ s.add_dependency(%q<em-http-request>, [">= 0"])
62
+ s.add_dependency(%q<em-eventsource>, [">= 0"])
52
63
  s.add_dependency(%q<rspec>, ["~> 2.3.0"])
53
64
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
54
65
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
55
66
  s.add_dependency(%q<rcov>, [">= 0"])
56
67
  end
57
68
  else
69
+ s.add_dependency(%q<eventmachine>, [">= 0"])
70
+ s.add_dependency(%q<em-http-request>, [">= 0"])
71
+ s.add_dependency(%q<em-eventsource>, [">= 0"])
58
72
  s.add_dependency(%q<rspec>, ["~> 2.3.0"])
59
73
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
60
74
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe "Neighborparrot::ESParrot" do
4
4
  before :all do
@@ -9,12 +9,13 @@ describe "Neighborparrot::ESParrot" do
9
9
  end
10
10
 
11
11
  before :each do
12
- @parrot = ESParrot.new
12
+ @parrot = Neighborparrot::Reactor.new
13
+ @parrot.on_error { |e| raise e }
13
14
  end
14
15
 
15
16
  describe "Neighborparrot::ESParrot#open" do
16
17
  after :each do
17
- @parrot.close
18
+ @parrot.stop
18
19
  end
19
20
 
20
21
  it "should open a connection with correct values" do
@@ -23,7 +24,7 @@ describe "Neighborparrot::ESParrot" do
23
24
  connected = true
24
25
  end
25
26
  @parrot.open(:channel => @channel)
26
- sleep(2)
27
+ sleep 1
27
28
  connected.should be_true
28
29
  end
29
30
 
@@ -33,16 +34,15 @@ describe "Neighborparrot::ESParrot" do
33
34
  received = msg
34
35
  end
35
36
  @parrot.open(:channel => @channel)
36
- sleep(2)
37
+
37
38
  text = Faker::Lorem.paragraph(30)
38
- Neighborparrot.send(:channel => 'test', :data => text)
39
- sleep(1)
39
+ @parrot.send(:channel => 'test', :data => text)
40
+ sleep 1
40
41
  received.should eq text
41
42
  end
42
43
 
43
44
  it "should return false if already a connection active" do
44
45
  @parrot.open(:channel => @channel)
45
- sleep(2)
46
46
  @parrot.open(:channel => 'other test').should be_false
47
47
  end
48
48
  end
@@ -50,8 +50,7 @@ describe "Neighborparrot::ESParrot" do
50
50
  describe "Neighborparrot::ESParrot#close" do
51
51
  it "should close a connection" do
52
52
  @parrot.open(:channel => @channel)
53
- sleep(2)
54
- @parrot.close()
53
+ @parrot.stop
55
54
  @parrot.connected?.should be_false
56
55
  end
57
56
  end
@@ -64,7 +63,7 @@ describe "Neighborparrot::ESParrot" do
64
63
 
65
64
  it "should be true when connected" do
66
65
  @parrot.open(:channel => @channel)
67
- sleep(2)
66
+ sleep 2
68
67
  @parrot.connected?.should be_true
69
68
  @parrot.close
70
69
  end
@@ -0,0 +1,68 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Neighborparrot::Reactor do
4
+
5
+ describe 'class reactor' do
6
+ after :each do
7
+ Neighborparrot.reactor_stop
8
+ end
9
+ describe 'Neighborparrot#reactor_start' do
10
+ it 'should not have a static reactor by default' do
11
+ Neighborparrot.reactor_running?.should be_false
12
+ end
13
+ it 'should create a static reator' do
14
+ Neighborparrot.reactor_start
15
+ sleep 1
16
+ Neighborparrot.reactor_running?.should be_true
17
+ end
18
+ end
19
+ describe 'Neighborparrot#reactor_stop' do
20
+ it 'should stop the static reator' do
21
+ Neighborparrot.reactor_start
22
+ Neighborparrot.reactor_stop
23
+ sleep 1
24
+ Neighborparrot.reactor_running?.should be_false
25
+ end
26
+ end
27
+ end
28
+ describe 'Reactor#define_event_helpers' do
29
+ before :each do
30
+ @parrot = Neighborparrot::Reactor.new
31
+ end
32
+ Neighborparrot::EVENTS.each do |event|
33
+ it "Shold respond to on_#{event}" do
34
+ @parrot.respond_to?("on_#{event}").should be_true
35
+ end
36
+
37
+ it "Shold respond to trigger_#{event}" do
38
+ @parrot.respond_to?("trigger_#{event}").should be_true
39
+ end
40
+
41
+ it 'should trigger defined blocks to events' do
42
+ received = nil
43
+ message = 'test string'
44
+ @parrot.on_message { |m| received = m }
45
+ @parrot.trigger_message message
46
+ received.should eq message
47
+ end
48
+ end
49
+ end
50
+
51
+ describe 'Reactor#initialize' do
52
+ it 'should create a new reactor unless skeep start'
53
+ it 'should not start the reactor if skeep start'
54
+ end
55
+
56
+ describe 'Reactor#start' do
57
+ it 'should start the reactor'
58
+ end
59
+
60
+ describe 'Reactor#stop' do
61
+ it 'should stop the reactor'
62
+ end
63
+
64
+ describe 'Reactor#send' do
65
+ it 'should send a message to the broker'
66
+ end
67
+
68
+ end
data/spec/spec_helper.rb CHANGED
@@ -10,7 +10,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../lib/neighborparrot')
10
10
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
11
11
 
12
12
  # Setup server on localhost
13
- Neighborparrot.configure :server => 'http://127.0.0.1:9000'
13
+ # Neighborparrot.configure :server => 'http://127.0.0.1:9000'
14
14
 
15
15
  RSpec.configure do |config|
16
16
 
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe 'Callbacks' do
4
+
5
+ describe 'class helpers' do
6
+ Neighborparrot::EVENTS.each do |event|
7
+ it "Shold respond to on_#{event}" do
8
+ Neighborparrot.respond_to?("on_#{event}").should be_true
9
+ end
10
+
11
+ it "Shold respond to trigger_#{event}" do
12
+ Neighborparrot.respond_to?("trigger_#{event}").should be_true
13
+ end
14
+ end
15
+ end
16
+ end
17
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neighborparrot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,44 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-07 00:00:00.000000000Z
12
+ date: 2012-01-11 00:00:00.000000000Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: eventmachine
16
+ requirement: &27578960 !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: *27578960
25
+ - !ruby/object:Gem::Dependency
26
+ name: em-http-request
27
+ requirement: &27577740 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *27577740
36
+ - !ruby/object:Gem::Dependency
37
+ name: em-eventsource
38
+ requirement: &27576580 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *27576580
14
47
  - !ruby/object:Gem::Dependency
15
48
  name: rspec
16
- requirement: &13007020 !ruby/object:Gem::Requirement
49
+ requirement: &27575720 !ruby/object:Gem::Requirement
17
50
  none: false
18
51
  requirements:
19
52
  - - ~>
@@ -21,10 +54,10 @@ dependencies:
21
54
  version: 2.3.0
22
55
  type: :development
23
56
  prerelease: false
24
- version_requirements: *13007020
57
+ version_requirements: *27575720
25
58
  - !ruby/object:Gem::Dependency
26
59
  name: bundler
27
- requirement: &13006480 !ruby/object:Gem::Requirement
60
+ requirement: &27574720 !ruby/object:Gem::Requirement
28
61
  none: false
29
62
  requirements:
30
63
  - - ~>
@@ -32,10 +65,10 @@ dependencies:
32
65
  version: 1.0.0
33
66
  type: :development
34
67
  prerelease: false
35
- version_requirements: *13006480
68
+ version_requirements: *27574720
36
69
  - !ruby/object:Gem::Dependency
37
70
  name: jeweler
38
- requirement: &13005740 !ruby/object:Gem::Requirement
71
+ requirement: &27573720 !ruby/object:Gem::Requirement
39
72
  none: false
40
73
  requirements:
41
74
  - - ~>
@@ -43,10 +76,10 @@ dependencies:
43
76
  version: 1.6.4
44
77
  type: :development
45
78
  prerelease: false
46
- version_requirements: *13005740
79
+ version_requirements: *27573720
47
80
  - !ruby/object:Gem::Dependency
48
81
  name: rcov
49
- requirement: &13004940 !ruby/object:Gem::Requirement
82
+ requirement: &27572860 !ruby/object:Gem::Requirement
50
83
  none: false
51
84
  requirements:
52
85
  - - ! '>='
@@ -54,7 +87,7 @@ dependencies:
54
87
  version: '0'
55
88
  type: :development
56
89
  prerelease: false
57
- version_requirements: *13004940
90
+ version_requirements: *27572860
58
91
  description: Send messages to the neighborparrot event source service
59
92
  email: eloy@indeos.es
60
93
  executables: []
@@ -72,13 +105,18 @@ files:
72
105
  - Rakefile
73
106
  - VERSION
74
107
  - lib/neighborparrot.rb
75
- - lib/neighborparrot/esparrot.rb
108
+ - lib/neighborparrot/callbacks.rb
109
+ - lib/neighborparrot/config.rb
110
+ - lib/neighborparrot/helpers/url_helpers.rb
111
+ - lib/neighborparrot/open.rb
112
+ - lib/neighborparrot/reactor.rb
76
113
  - lib/neighborparrot/send.rb
77
114
  - neighborparrot.gemspec
78
- - spec/esparrot_spec.rb
79
- - spec/neighborparrot_spec.rb
115
+ - spec/integration/neighborparrot_spec.rb
116
+ - spec/reactor_spec.rb
80
117
  - spec/spec_helper.rb
81
118
  - spec/support/helpers.rb
119
+ - spec/unit/callbacks_spec.rb
82
120
  homepage: http://neighborparrot.com
83
121
  licenses:
84
122
  - MIT
@@ -94,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
94
132
  version: '0'
95
133
  segments:
96
134
  - 0
97
- hash: -1488788034171426421
135
+ hash: 4307022084171942048
98
136
  required_rubygems_version: !ruby/object:Gem::Requirement
99
137
  none: false
100
138
  requirements:
@@ -1,92 +0,0 @@
1
- class ESParrot
2
- include Neighborparrot
3
-
4
- # Open a persistent connection to the Neighbor in a new
5
- # thread and return true if all works unless :foreground
6
- # options is true.
7
- # Current options to the connectio are:
8
- #
9
- # @param [String] channel to connect
10
- # @param [Hash] Params for the connection. this params can be:
11
- # * :foreground [Boolean] run the connection in the foreground
12
- # stoping the clode flow until the connection is closed by server or
13
- # another thread call close
14
- # * :api_id => Your api ID in neighborparrot.com
15
- # * :api_key => Your api key
16
- # * :server => Server to connect (Only for development)
17
- def open(params={})
18
- params = Neighborparrot.configuration.merge(params)
19
- Neighborparrot.check_params params, :open
20
- return false if connected?
21
- if ! params[:foreground] == true
22
- close if @current_thread # If previus thread but closed connection, kill it
23
- @current_thread = Thread.new(params) do | params|
24
- open_connection params
25
- end
26
- return true
27
- else
28
- open_connection params
29
- end
30
- end
31
-
32
- # @return true if a connection exists and is started
33
- def connected?
34
- @connection && @connection.started?
35
- end
36
-
37
- # close the active connection
38
- def close
39
- return unless connected?
40
- @connection.finish()
41
- @current_thread.kill
42
- @current_thread = nil
43
- end
44
-
45
- # Define a block called on message received
46
- # The received message is passed to the block as a var
47
- def on_message(&block)
48
- @on_message_blk = block
49
- end
50
-
51
- # Define a block called on error
52
- # An optional param with the error should be pass if present
53
- def on_error(&block)
54
- @on_error_blk = block
55
- end
56
-
57
- # Define a block called on connection closed
58
- def on_close(&block)
59
- @on_close_blk = block
60
- end
61
-
62
- # Define a block called on connect
63
- def on_connect(&block)
64
- @on_connect_blk = block
65
- end
66
-
67
- private
68
-
69
- # Open a persistent connection to the neighbor
70
- # TODO: Refactor, EM??
71
- def open_connection(params)
72
- begin
73
- uri = URI(params[:server])
74
- Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
75
- http.read_timeout = 9999999999999999 # TODO Fix this
76
- request = Net::HTTP::Get.new URI.escape("/open?channel=#{params[:channel]}")
77
- @connection = http
78
- @on_connect_blk.call if @on_connect_blk
79
- http.request request do |response|
80
- response.read_body do |chunk|
81
- if chunk.start_with? "data:"
82
- @on_message_blk.call(chunk[5..-3]) if @on_message_blk # Remove data: and \n\n
83
- end
84
- end
85
- end
86
- end
87
- rescue
88
- @on_error_blk.call($!) if @on_error_blk
89
- end
90
- @on_close_blk.call if @on_close_blk
91
- end
92
- end
@@ -1,41 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe "Neighborparrot" do
4
- before :each do
5
- api_id = 'test-id'
6
- api_key = 'api_key'
7
- Neighborparrot.configure({ :api_id => api_id, :api_key => :api_key })
8
- end
9
-
10
- describe "Neigborparrot#post" do
11
- it 'should return true if no errors' do
12
- send_test.should be_true
13
- end
14
-
15
- it "should rails exception without id" do
16
- Neighborparrot.configure({ :api_key => nil })
17
- expect { send_test }.to raise_error
18
- end
19
-
20
- it "should rails exception without key" do
21
- Neighborparrot.configure({:api_id => nil})
22
- expect { send_test }.to raise_error
23
- end
24
-
25
- it "should raise exception with nill channel" do
26
- expect { Neighborparrot.send(:channel => nil, :data => 'test string') }.to raise_error
27
- end
28
-
29
- it "should raise exception with empty channel" do
30
- expect { Neighborparrot.send(:channel => '', :data => 'test string') }.to raise_error
31
- end
32
-
33
- it "should not send message with nil data" do
34
- Neighborparrot.send(:channel => 'test-channel', :data => nil).should be_false
35
- end
36
-
37
- it "should not send message with empty data" do
38
- Neighborparrot.send(:channel => 'test-channel', :data => '').should be_false
39
- end
40
- end
41
- end