celluloid-eventsource 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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