celluloid-eventsource 0.2.2 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9012f0cf1c6f9e95a413556b650d0d1f24a15e81
4
- data.tar.gz: ef92620f9f3f0672b3d8ff62e3b2c8a8a8e4366f
3
+ metadata.gz: 7fbe88d12ab2285c9b866977ade2ab069c5fce76
4
+ data.tar.gz: 72e75170841864fd4746aad568c17f43e4984c55
5
5
  SHA512:
6
- metadata.gz: 952e0b75111a6ba5e979680dc3f8a23f4d7fe64620eb48b1df7a5bfc20f58c6721c34ab4d376ec6b5dce1b493b993d093ed886e6739b6e6819b4bfee4b31297e
7
- data.tar.gz: db714b09edea419560f31733560b1decdc0995b0626f7a39aba41773c18e81da86a87da4d22d280320856cfc587ef5e306bb856288357656f529e3449a7c255b
6
+ metadata.gz: b8ad5063fbcbe45581f9c8b53f8f7b4adf25578b4f26a20c56d942b367ff8bdf226e7d8dfbd8a222a6bd3c5986b9c90a54731ee5b924199168ba5b0f6ea6707e
7
+ data.tar.gz: e5f052c515980ca818b6bbfac1449c22e8f59b423139215b98d31c798cfbc1afeb9b6004766576496f705736afa227a39bbf890b7d78c6dab463cc736dd65318
data/.gitignore CHANGED
@@ -18,3 +18,4 @@ spec/reports
18
18
  test/tmp
19
19
  test/version_tmp
20
20
  tmp
21
+ .idea
@@ -3,6 +3,6 @@ language: ruby
3
3
  before_install: gem update bundler
4
4
 
5
5
  rvm:
6
- - "1.9.3"
7
6
  - "2.0.0"
8
7
  - "2.1.0"
8
+ - "2.2.2"
File without changes
data/README.md CHANGED
@@ -4,8 +4,6 @@
4
4
  [![Code Climate](https://codeclimate.com/github/Tonkpils/celluloid-eventsource.png)](https://codeclimate.com/github/Tonkpils/celluloid-eventsource)
5
5
  [![Build Status](https://travis-ci.org/Tonkpils/celluloid-eventsource.svg?branch=master)](https://travis-ci.org/Tonkpils/celluloid-eventsource)
6
6
 
7
- #### Under Development!! Use at your own risk :)
8
-
9
7
  An EventSource client based off Celluloid::IO.
10
8
 
11
9
  Specification based on [EventSource](http://www.w3.org/TR/2012/CR-eventsource-20121211/)
@@ -21,8 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency 'celluloid-io', '>= 0.15.0', '<= 0.16.2'
22
22
  spec.add_dependency 'http_parser.rb', '~> 0.6.0'
23
23
 
24
- spec.add_development_dependency "timers"
25
- spec.add_development_dependency "reel", '>= 0.5.0'
24
+ spec.add_development_dependency 'atomic', '~> 1.1.99'
26
25
  spec.add_development_dependency "rspec", '~> 3.0.0'
27
26
  spec.add_development_dependency "bundler", ">= 1.7.0"
28
27
  spec.add_development_dependency "rake", '~> 10.1.0'
@@ -33,6 +33,8 @@ module Celluloid
33
33
  @on = { open: ->{}, message: ->(_) {}, error: ->(_) {} }
34
34
  @parser = ResponseParser.new
35
35
 
36
+ @chunked = false
37
+
36
38
  yield self if block_given?
37
39
 
38
40
  async.listen
@@ -53,7 +55,7 @@ module Celluloid
53
55
  def listen
54
56
  establish_connection
55
57
 
56
- process_stream
58
+ chunked? ? process_chunked_stream : process_stream
57
59
  rescue IOError
58
60
  # Closing the socket during read causes this exception and kills the actor
59
61
  # We really don't wan to do anything if the socket is closed.
@@ -82,6 +84,8 @@ module Celluloid
82
84
 
83
85
  private
84
86
 
87
+ MessageEvent = Struct.new(:type, :data, :last_event_id)
88
+
85
89
  def ssl?
86
90
  url.scheme == 'https'
87
91
  end
@@ -120,35 +124,6 @@ module Celluloid
120
124
  }
121
125
  end
122
126
 
123
- def process_field(line)
124
- case line
125
- when /^data:(.+)$/
126
- @data_buffer << $1.lstrip.concat("\n")
127
- when /^id:(.+)$/
128
- @last_event_id_buffer = $1.lstrip
129
- when /^retry:(\d+)$/
130
- @reconnect_timeout = $1.to_i
131
- when /^event:(.+)$/
132
- @event_type_buffer = $1.lstrip
133
- end
134
- end
135
-
136
- MessageEvent = Struct.new(:type, :data, :last_event_id)
137
-
138
- def process_event
139
- @last_event_id = @last_event_id_buffer
140
-
141
- unless @data_buffer.empty?
142
- @data_buffer = @data_buffer.chomp("\n") if @data_buffer.end_with?("\n")
143
- event = MessageEvent.new(:message, @data_buffer, @last_event_id)
144
- event.type = @event_type_buffer.to_sym unless @event_type_buffer.empty?
145
-
146
- dispatch_event(event)
147
- end
148
-
149
- clear_buffers!
150
- end
151
-
152
127
  def clear_buffers!
153
128
  @data_buffer = ""
154
129
  @event_type_buffer = ""
@@ -160,20 +135,84 @@ module Celluloid
160
135
  end
161
136
  end
162
137
 
138
+ def chunked?
139
+ @chunked
140
+ end
141
+
142
+ def process_chunked_stream
143
+ until closed? || @socket.eof?
144
+ handle_chunked_stream
145
+ end
146
+ end
147
+
163
148
  def process_stream
164
149
  until closed? || @socket.eof?
165
150
  line = @socket.readline
151
+ line.strip.empty? ? process_event : parse_line(line)
152
+ end
153
+ end
154
+
155
+ def handle_chunked_stream
156
+ chunk_header = @socket.readline
157
+ bytes_to_read = chunk_header.to_i(16)
158
+ bytes_read = 0
159
+ while bytes_read < bytes_to_read do
160
+ line = @socket.readline
161
+ bytes_read += line.size
162
+
163
+ line.strip.empty? ? process_event : parse_line(line)
164
+ end
165
+
166
+ if !line.nil? && line.strip.empty?
167
+ process_event
168
+ end
169
+ end
170
+
171
+ def parse_line(line)
172
+ case line
173
+ when /^:.*$/
174
+ when /^(\w+): ?(.*)$/
175
+ process_field($1, $2)
176
+ else
177
+ if chunked? && !@data_buffer.empty?
178
+ @data_buffer.rstrip!
179
+ process_field("data", line.rstrip)
180
+ end
181
+ end
182
+ end
183
+
184
+ def process_event
185
+ @last_event_id = @last_event_id_buffer
186
+
187
+ return if @data_buffer.empty?
188
+
189
+ @data_buffer.chomp!("\n") if @data_buffer.end_with?("\n")
190
+ event = MessageEvent.new(:message, @data_buffer, @last_event_id)
191
+ event.type = @event_type_buffer.to_sym unless @event_type_buffer.empty?
192
+
193
+ dispatch_event(event)
194
+ ensure
195
+ clear_buffers!
196
+ end
166
197
 
167
- if line.strip.empty?
168
- process_event
169
- else
170
- process_field(line)
198
+ def process_field(field_name, field_value)
199
+ case field_name
200
+ when "event"
201
+ @event_type_buffer = field_value
202
+ when "data"
203
+ @data_buffer << field_value.concat("\n")
204
+ when "id"
205
+ @last_event_id_buffer = field_value
206
+ when "retry"
207
+ if /^(?<num>\d+)$/ =~ field_value
208
+ @reconnect_timeout = num.to_i
171
209
  end
172
210
  end
173
211
  end
174
212
 
175
213
  def handle_headers(headers)
176
214
  if headers['Content-Type'].include?("text/event-stream")
215
+ @chunked = !headers["Transfer-Encoding"].nil? && headers["Transfer-Encoding"].include?("chunked")
177
216
  @ready_state = OPEN
178
217
  @on[:open].call
179
218
  else
@@ -1,5 +1,5 @@
1
1
  module Celluloid
2
2
  class EventSource
3
- VERSION = "0.2.2"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -1,15 +1,23 @@
1
1
  require 'spec_helper'
2
+ require 'support/dummy_server'
2
3
 
3
- TIMEOUT = 0.0001
4
4
 
5
+ # See: https://html.spec.whatwg.org/multipage/comms.html#event-stream-interpretation
5
6
  RSpec.describe Celluloid::EventSource do
6
- let(:data) { "foo bar " }
7
7
 
8
- def with_sse_server
9
- server = ServerSentEvents.new
10
- yield server
11
- ensure
12
- server.terminate if server && server.alive?
8
+ let!(:chunk_size) { DummyServer::CHUNK_SIZE }
9
+
10
+ def dummy
11
+ @dummy ||= DummyServer.new
12
+ end
13
+
14
+ before(:all) do
15
+ dummy.listen(DummyServer::CONFIG[:BindAddress], DummyServer::CONFIG[:Port])
16
+ Thread.new { dummy.start }
17
+ end
18
+
19
+ after(:all) do
20
+ dummy.shutdown
13
21
  end
14
22
 
15
23
  describe '#initialize' do
@@ -33,93 +41,136 @@ RSpec.describe Celluloid::EventSource do
33
41
  end
34
42
  end
35
43
 
36
- it "keeps track of last event id" do
37
- with_sse_server do |server|
38
- @last_event_id = ""
39
- ces = Celluloid::EventSource.new("http://localhost:63310") do |conn|
40
- conn.on_message { |event| @last_event_id = event.last_event_id }
41
- end
44
+ context 'callbacks' do
42
45
 
43
- sleep TIMEOUT until ces.connected?
46
+ let(:future) { Celluloid::Future.new }
47
+ let(:value_class) { Class.new(Struct.new(:value)) }
44
48
 
45
- expect { server.broadcast(nil, data); sleep TIMEOUT }.to change { @last_event_id }.to("1")
46
- end
47
- end
49
+ describe '#on_open' do
50
+
51
+ it 'the client has an opened connection' do
48
52
 
49
- it "ignores comment ':' lines" do
50
- with_sse_server do |server|
51
- expect { |event|
52
- ces = Celluloid::EventSource.new("http://localhost:63310") do |conn|
53
- conn.on_message(&event)
53
+ Celluloid::EventSource.new(dummy.endpoint) do |conn|
54
+ conn.on_open do
55
+ future.signal(value_class.new({ called: true, state: conn.ready_state }))
56
+ conn.close
57
+ end
54
58
  end
55
59
 
56
- sleep TIMEOUT until ces.connected?
60
+ expect(future.value).to eq({ called: true, state: Celluloid::EventSource::OPEN })
61
+ end
62
+ end
57
63
 
58
- server.send_ping
64
+ describe '#on_error' do
59
65
 
60
- sleep TIMEOUT
61
- }.to_not yield_control
62
- end
63
- end
66
+ it 'receives response body through error event' do
64
67
 
65
- it 'receives data through message event' do
66
- with_sse_server do |server|
67
- expect { |event|
68
- ces = Celluloid::EventSource.new("http://localhost:63310") do |conn|
69
- conn.on_message(&event)
68
+ Celluloid::EventSource.new("#{dummy.endpoint}/error") do |conn|
69
+ conn.on_error do |error|
70
+ future.signal(value_class.new({ msg: error, state: conn.ready_state }))
71
+ end
70
72
  end
71
73
 
72
- sleep TIMEOUT until ces.connected?
74
+ expect(future.value).to eq({ msg: { status_code: 400, body: '{"msg": "blop"}' },
75
+ state: Celluloid::EventSource::CLOSED })
76
+ end
77
+ end
73
78
 
74
- server.broadcast(nil, data)
79
+ describe '#on_message' do
75
80
 
76
- sleep TIMEOUT
77
- }.to yield_with_args(Celluloid::EventSource::MessageEvent)
78
- end
79
- end
81
+ it 'receives data through message event' do
80
82
 
81
- it 'receives response body through error event' do
82
- with_sse_server do |server|
83
- expect { |error|
84
- ces = Celluloid::EventSource.new("http://localhost:63310/error") do |conn|
85
- conn.on_error(&error)
83
+ Celluloid::EventSource.new(dummy.endpoint) do |conn|
84
+ conn.on_message do |message|
85
+ if '3' == message.last_event_id
86
+ future.signal(value_class.new({ msg: message, state: conn.ready_state }))
87
+ conn.close
88
+ end
89
+ end
86
90
  end
87
91
 
88
- sleep TIMEOUT until ces.closed?
92
+ payload = future.value
93
+ expect(payload[:msg]).to be_a(Celluloid::EventSource::MessageEvent)
94
+ expect(payload[:msg].type).to eq(:message)
95
+ expect(payload[:msg].last_event_id).to eq('3')
96
+ expect(payload[:state]).to eq(Celluloid::EventSource::OPEN)
97
+ end
89
98
 
90
- }.to yield_with_args({status_code: 400, body:"blop"})
91
- end
92
- end
99
+ it 'ignores lines starting with ":"' do
100
+ Celluloid::EventSource.new("#{dummy.endpoint}/ping") do |conn|
101
+ conn.on_message do |message|
102
+ future.signal(value_class.new({ msg: message, state: conn.ready_state }))
103
+ conn.close
104
+ end
105
+ end
106
+
107
+ expect(future.value(3)[:msg].data).to eq('pong')
108
+ end
93
109
 
94
- it 'receives response without a body through error event' do
95
- with_sse_server do |server|
96
- expect { |error|
97
- ces = Celluloid::EventSource.new("http://localhost:63310/error/no_body") do |conn|
98
- conn.on_error(&error)
110
+ it "aggregates events properly" do
111
+ Celluloid::EventSource.new("#{dummy.endpoint}/continuous") do |conn|
112
+ conn.on_message do |message|
113
+ future.signal(value_class.new({ msg: message, state: conn.ready_state }))
114
+ conn.close
115
+ end
99
116
  end
117
+ expect(future.value(3)[:msg].data).to eq("YHOO\n+2\n10")
118
+ end
100
119
 
101
- sleep TIMEOUT until ces.closed?
120
+ context "with chunked streams" do
121
+ it "properly parses chunked encoding" do
122
+ Celluloid::EventSource.new("#{dummy.endpoint}/chunk") do |conn|
123
+ conn.on_message do |message|
124
+ future.signal(value_class.new({ msg: message, state: conn.ready_state }))
125
+ conn.close
126
+ end
127
+ end
128
+ expect(future.value(3)[:msg].data).to eq("f" * (chunk_size + 25))
129
+ end
102
130
 
103
- }.to yield_with_args({status_code: 400, body:""})
104
- end
105
- end
131
+ it "parses multiple continuous chunks" do
132
+ Celluloid::EventSource.new("#{dummy.endpoint}/continuous_chunks") do |conn|
133
+ conn.on_message do |message|
134
+ future.signal(value_class.new({ msg: message, state: conn.ready_state }))
135
+ conn.close
136
+ end
137
+ end
106
138
 
107
- it 'receives custom events through event handlers' do
108
- with_sse_server do |server|
109
- event_name = :custom_event
139
+ data = "o" * chunk_size + "\n" + "m" * chunk_size + "\n" + "g" * chunk_size
140
+ expect(future.value(3)[:msg].data).to eq(data)
141
+ end
142
+
143
+ it "parses multiple chunks" do
144
+ Celluloid::EventSource.new("#{dummy.endpoint}/multiple_chunks") do |conn|
145
+ conn.on_message do |message|
146
+ future.signal(value_class.new({ msg: message, state: conn.ready_state }))
147
+ conn.close
148
+ end
149
+ end
110
150
 
111
- expect { |event|
112
- ces = Celluloid::EventSource.new("http://localhost:63310") do |conn|
113
- conn.on(event_name, &event)
151
+ expect(future.value(3)[:msg].data).to eq({test: "long_chunk", another_chunk: "a" * chunk_size, chunks: "f" * chunk_size }.to_json)
114
152
  end
153
+ end
154
+ end
115
155
 
116
- sleep TIMEOUT until ces.connected?
156
+ describe '#on' do
157
+ let(:custom) { :custom_event }
117
158
 
118
- server.broadcast(event_name, data)
159
+ it 'receives custom events and handles them' do
119
160
 
120
- sleep TIMEOUT
121
- }.to yield_with_args(Celluloid::EventSource::MessageEvent)
161
+ Celluloid::EventSource.new("#{dummy.endpoint}/#{custom}") do |conn|
162
+ conn.on(custom) do |message|
163
+ future.signal(value_class.new({ msg: message, state: conn.ready_state }))
164
+ conn.close
165
+ end
166
+ end
167
+
168
+ payload = future.value
169
+ expect(payload[:msg]).to be_a(Celluloid::EventSource::MessageEvent)
170
+ expect(payload[:msg].type).to eq(custom)
171
+ expect(payload[:msg].last_event_id).to eq('1')
172
+ expect(payload[:state]).to eq(Celluloid::EventSource::OPEN)
173
+ end
122
174
  end
123
175
  end
124
-
125
176
  end
@@ -4,8 +4,6 @@ require 'bundler/setup'
4
4
  require 'celluloid/eventsource'
5
5
  require 'celluloid/rspec'
6
6
 
7
- require 'reel'
8
-
9
7
  logfile = File.open(File.expand_path("../../log/test.log", __FILE__), 'a')
10
8
  logfile.sync = true
11
9
 
@@ -13,89 +11,10 @@ Celluloid.logger = Logger.new(logfile)
13
11
 
14
12
  RSpec.configure do |config|
15
13
  config.expose_dsl_globally = false
16
- end
17
-
18
- class ServerSentEvents < Reel::Server::HTTP
19
- include Celluloid::Logger
20
-
21
- attr_reader :last_event_id, :connections
22
-
23
- def initialize(ip = '127.0.0.1', port = 63310)
24
- @connections = []
25
- @history = []
26
- @last_event_id = 0
27
- super(ip, port, &method(:on_connection))
28
- end
29
-
30
- def broadcast(event, data)
31
- if @history.size >= 10
32
- @history.slice!(0, @history.size - 1000)
33
- end
34
-
35
- @last_event_id += 1
36
- @history << { id: @last_event_id, event: event, data: data }
37
-
38
- @connections.each do |socket|
39
- async.send_sse(socket, data, event, @last_event_id)
40
- end
41
- true
42
- end
43
-
44
- def send_ping
45
- @connections.each do |socket|
46
- begin
47
- socket << ":\n"
48
- rescue Reel::SocketError
49
- @connections.delete(socket)
50
- end
51
- end
52
- end
53
-
54
- private
55
- # event and id are optional, Eventsource only needs data
56
- def send_sse(socket, data, event = nil, id = nil)
57
- begin
58
- socket.id id if id
59
- socket.event event if event
60
- socket.data data
61
- rescue Reel::SocketError, NoMethodError
62
- @connections.delete(socket) if @connections.include?(socket)
63
- end
64
- end
65
-
66
- def handle_request(request)
67
- event_stream = Reel::EventStream.new do |socket|
68
- @connections << socket
69
- socket.retry 5000
70
- # after a Connection reset resend newer Messages to the Client, query['last_event_id'] is needed for https://github.com/Yaffle/EventSource
71
- if @history.count > 0 && id = request.headers['Last-Event-ID']
72
- begin
73
- if history = @history.select {|h| h[:id] >= Integer(id)}.map {|a| "id: \nevent: %s%s\ndata: %s" % [a[:id], a[:event], a[:data]]}.join("\n\n")
74
- socket << "%s\n\n" % [history]
75
- end
76
- rescue ArgumentError, Reel::SocketError
77
- @connections.delete(socket)
78
- request.close
79
- end
80
- end
81
- end
82
-
83
- request.respond Reel::StreamResponse.new(:ok, {
84
- 'Content-Type' => 'text/event-stream; charset=utf-8',
85
- 'Cache-Control' => 'no-cache'}, event_stream)
86
- end
87
14
 
88
- def on_connection(connection)
89
- connection.each_request do |request|
90
- if request.path == '/error'
91
- request.respond :bad_request, {'Content-Type' => 'application/json; charset=UTF-8'}, "blop"
92
- request.close
93
- elsif request.path == '/error/no_body'
94
- request.respond :bad_request, {'Content-Type' => 'application/json; charset=UTF-8'}
95
- request.close
96
- else
97
- handle_request(request)
98
- end
99
- end
100
- end
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = :random
101
20
  end
@@ -0,0 +1,5 @@
1
+ module BlackHole
2
+ def self.method_missing(*)
3
+ self
4
+ end
5
+ end
@@ -0,0 +1,100 @@
1
+ require 'webrick'
2
+ require 'atomic'
3
+ require 'json'
4
+
5
+ require 'support/black_hole'
6
+
7
+ class DummyServer < WEBrick::HTTPServer
8
+ CHUNK_SIZE = 100
9
+ CONFIG = {
10
+ :BindAddress => '127.0.0.1',
11
+ :Port => 5000,
12
+ :AccessLog => BlackHole,
13
+ :Logger => BlackHole,
14
+ :DoNotListen => true,
15
+ :OutputBufferSize => CHUNK_SIZE
16
+ }.freeze
17
+
18
+ def initialize(options = {})
19
+ super(CONFIG)
20
+ mount('/', SSETestServlet)
21
+ mount('/error', ErrorServlet)
22
+ end
23
+
24
+ def endpoint
25
+ "#{scheme}://#{addr}:#{port}"
26
+ end
27
+
28
+ def addr
29
+ config[:BindAddress]
30
+ end
31
+
32
+ def port
33
+ config[:Port]
34
+ end
35
+
36
+ def scheme
37
+ 'http'
38
+ end
39
+
40
+ # Simple server that broadcasts Time.now
41
+ class SSETestServlet < WEBrick::HTTPServlet::AbstractServlet
42
+
43
+ def initialize(*args)
44
+ @event_id = Atomic.new(0)
45
+ super
46
+ end
47
+
48
+ def do_GET(req, res)
49
+ event = String(Array(req.path.match(/\/?(\w+)/i)).pop).to_sym
50
+ res.content_type = 'text/event-stream; charset=utf-8'
51
+ res['Cache-Control'] = 'no-cache'
52
+ r,w = IO.pipe
53
+ res.body = r
54
+ res.chunked = true
55
+ t = Thread.new do
56
+ begin
57
+ w << "retry: 1000\n"
58
+ case event
59
+ when :continuous_chunks
60
+ data = "data: %s\ndata: %s\ndata: %s\n\n" % ["o" * CHUNK_SIZE, "m" * CHUNK_SIZE, "g" * CHUNK_SIZE]
61
+ w << data
62
+ when :multiple_chunks
63
+ data = {test: "long_chunk", another_chunk: "a" * CHUNK_SIZE, chunks: "f" * CHUNK_SIZE}.to_json
64
+ w << "data: #{data}\n\n"
65
+ when :continuous
66
+ w << "data: YHOO\ndata: +2\ndata: 10\n\n"
67
+ when :chunk
68
+ data = "f" * (CHUNK_SIZE + 25)
69
+ w << "data: %s\n\n" % data
70
+ when :ping
71
+ w << ": ignore this line\n"
72
+ w << "event: \ndata: pong\n\n" # easy way to know a 'ping' has been sent
73
+ else
74
+ 42.times do
75
+ w << "id: %s\nevent: %s\ndata: %s\n\n" % [ @event_id.update { |v| v + 1 },
76
+ event,
77
+ Time.now ]
78
+ end
79
+ w << "event: %s\ndata: %s\n\n" % %w(end end)
80
+ end
81
+ rescue => ex
82
+ puts $!.inspect, $@ unless ex.is_a?(Errno::EPIPE)
83
+ ensure
84
+ w.close
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ class ErrorServlet < WEBrick::HTTPServlet::AbstractServlet
91
+ def do_GET(req, res)
92
+ res.content_type = 'application/json; charset=utf-8'
93
+ res.status = 400
94
+ res.keep_alive = false # true by default
95
+ res.body = '{"msg": "blop"}'
96
+ end
97
+ end
98
+ end
99
+
100
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: celluloid-eventsource
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leo Correa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-29 00:00:00.000000000 Z
11
+ date: 2015-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid-io
@@ -45,33 +45,19 @@ dependencies:
45
45
  - !ruby/object:Gem::Version
46
46
  version: 0.6.0
47
47
  - !ruby/object:Gem::Dependency
48
- name: timers
48
+ name: atomic
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: '0'
61
- - !ruby/object:Gem::Dependency
62
- name: reel
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
51
+ - - "~>"
66
52
  - !ruby/object:Gem::Version
67
- version: 0.5.0
53
+ version: 1.1.99
68
54
  type: :development
69
55
  prerelease: false
70
56
  version_requirements: !ruby/object:Gem::Requirement
71
57
  requirements:
72
- - - ">="
58
+ - - "~>"
73
59
  - !ruby/object:Gem::Version
74
- version: 0.5.0
60
+ version: 1.1.99
75
61
  - !ruby/object:Gem::Dependency
76
62
  name: rspec
77
63
  requirement: !ruby/object:Gem::Requirement
@@ -139,7 +125,7 @@ files:
139
125
  - ".rspec"
140
126
  - ".travis.yml"
141
127
  - Gemfile
142
- - LICENSE.md
128
+ - LICENSE
143
129
  - README.md
144
130
  - Rakefile
145
131
  - celluloid-eventsource.gemspec
@@ -150,6 +136,8 @@ files:
150
136
  - spec/celluloid/eventsource/response_parser_spec.rb
151
137
  - spec/celluloid/eventsource_spec.rb
152
138
  - spec/spec_helper.rb
139
+ - spec/support/black_hole.rb
140
+ - spec/support/dummy_server.rb
153
141
  homepage: https://github.com/Tonkpils/celluloid-eventsource
154
142
  licenses:
155
143
  - MIT
@@ -178,3 +166,5 @@ test_files:
178
166
  - spec/celluloid/eventsource/response_parser_spec.rb
179
167
  - spec/celluloid/eventsource_spec.rb
180
168
  - spec/spec_helper.rb
169
+ - spec/support/black_hole.rb
170
+ - spec/support/dummy_server.rb