rasti-web 0.2.3 → 1.0.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: 7228c96c1a32e1eca7001403d09d17031d1bdc22
4
- data.tar.gz: a07edbbbbc8ef67d38932d7e4badd46fa8968cab
3
+ metadata.gz: 50a62a6c007c11424a97fd9eb207ca0cb1641bb0
4
+ data.tar.gz: 04bf7b2fe637a40625b401227d8c1ffe61088b6c
5
5
  SHA512:
6
- metadata.gz: 85d1b34deeeee8725d484d713d262b14bbd47651c62f41cc4c723b75a1449846077d3fff716a48df79dedabdfde4ed3b8ae54f4734b6bfc591d0b952cac6cffd
7
- data.tar.gz: 19b9db628da84226503daf87be120ea6f298c692d6a6a566119c7e0eb241fd118849505e2972cf96c2809a53ec6f3177a0e71c067024fb476ae3870ae356bb8d
6
+ metadata.gz: 22684f3a9e873bdf5e3a30e468013ebe310d33c555e7b37068f016e765eecfbd0d89e9109d2434305ba2b90afd21e6b4fc972fd1e00e5a0967848b9da90bdb95
7
+ data.tar.gz: f8ec4a69517f0c2c8eec1d130b0b70bb3ae34ac7752cdff43da466fa49b439dd072df5ed243ff303adcce1090a9b5fa28ceefa53f6c3dd12b6f223cd3ec0fda1
data/.travis.yml CHANGED
@@ -5,8 +5,7 @@ rvm:
5
5
  - 2.1
6
6
  - 2.2
7
7
  - 2.3.0
8
+ - 2.4.0
8
9
  - jruby
9
10
  before_install:
10
- - gem install bundler
11
- services:
12
- - redis-server
11
+ - gem install bundler
@@ -72,14 +72,6 @@ module Rasti
72
72
  layout(layout_template) { view_context.render template, locals }
73
73
  end
74
74
 
75
- def server_sent_events(channel_id)
76
- response.status = 200
77
- response['Content-Type'] = 'text/event-stream'
78
- response['Cache-Control'] = 'no-cache'
79
- response['Connection'] = 'keep-alive'
80
- response.body = Channel[channel_id].subscribe
81
- end
82
-
83
75
  private
84
76
 
85
77
  def respond_with(status, headers, body)
@@ -15,8 +15,8 @@ module Rasti
15
15
  end
16
16
 
17
17
  def extract_params(path)
18
- result = @regexp.match path
19
- result ? result.names.each_with_object({}) { |v,h| h[v] = result[v] } : {}
18
+ result = @regexp.match normalize(path)
19
+ result ? result.names.each_with_object(Hash::Indifferent.new) { |v,h| h[v] = result[v] } : {}
20
20
  end
21
21
 
22
22
  def call(env)
@@ -26,7 +26,10 @@ module Rasti
26
26
  private
27
27
 
28
28
  def compile
29
- %r{^#{pattern.gsub(')', '){0,1}').gsub(/:[a-z0-9_-]+/) { |var| "(?<#{var[1..-1]}>[^\/?#]+)" }}$}
29
+ compiled = pattern.gsub(')', '){0,1}')
30
+ .gsub('/*', '(\/(?<wildcard>.*))?')
31
+ .gsub(/:[a-z0-9_-]+/) { |var| "(?<#{var[1..-1]}>[^\/?#]+)" }
32
+ %r{^#{compiled}$}
30
33
  end
31
34
 
32
35
  def normalize(path)
@@ -1,5 +1,5 @@
1
1
  module Rasti
2
2
  module Web
3
- VERSION = '0.2.3'
3
+ VERSION = '1.0.0'
4
4
  end
5
5
  end
data/lib/rasti/web.rb CHANGED
@@ -7,7 +7,6 @@ require 'class_config'
7
7
  require 'forwardable'
8
8
  require 'logger'
9
9
  require 'hash_ext'
10
- require 'broadcaster'
11
10
 
12
11
  require_relative 'web/route'
13
12
  require_relative 'web/router'
@@ -18,13 +17,11 @@ require_relative 'web/view_context'
18
17
  require_relative 'web/render'
19
18
  require_relative 'web/request'
20
19
  require_relative 'web/controller'
21
- require_relative 'web/channel'
22
- require_relative 'web/stream'
23
- require_relative 'web/server_sent_event'
24
20
  require_relative 'web/version'
25
21
 
26
22
  module Rasti
27
23
  module Web
24
+
28
25
  ROUTE_PARAMS = 'rack.request.route_params'
29
26
 
30
27
  extend ClassConfig
@@ -34,10 +31,10 @@ module Rasti
34
31
  attr_config :default_layout, 'layout'
35
32
  attr_config :helpers, []
36
33
  attr_config :logger, Logger.new(STDOUT)
37
- attr_config :channels_prefix, 'rasti-web:channels'
38
34
 
39
35
  after_config do |config|
40
36
  config.helpers.each { |h| ViewContext.send :include, h }
41
37
  end
38
+
42
39
  end
43
40
  end
data/rasti-web.gemspec CHANGED
@@ -24,7 +24,6 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'class_config', '~> 0.0.2'
25
25
  spec.add_dependency 'hash_ext', '~> 0.1'
26
26
  spec.add_dependency 'content-type', '~> 0.0'
27
- spec.add_dependency 'broadcaster', '~> 0.1'
28
27
 
29
28
  spec.add_development_dependency 'bundler', '~> 1.12'
30
29
  spec.add_development_dependency 'rake', '~> 11.0'
@@ -34,7 +33,7 @@ Gem::Specification.new do |spec|
34
33
  spec.add_development_dependency 'simplecov', '~> 0.12'
35
34
  spec.add_development_dependency 'coveralls', '~> 0.8'
36
35
  spec.add_development_dependency 'pry-nav', '~> 0.2'
37
- spec.add_development_dependency 'rack-test'
36
+ spec.add_development_dependency 'rack-test', '~> 0.6'
38
37
 
39
38
  if RUBY_VERSION < '2'
40
39
  spec.add_development_dependency 'term-ansicolor', '~> 1.3.0'
@@ -15,8 +15,4 @@ Rasti::Web.configure do |config|
15
15
  config.views_path = File.expand_path '../views', __FILE__
16
16
  config.helpers << ContextMethodHelper
17
17
  config.logger.level = Logger::ERROR
18
- end
19
-
20
- Broadcaster.configure do |config|
21
- config.logger = Rasti::Web.logger
22
18
  end
data/spec/route_spec.rb CHANGED
@@ -4,6 +4,10 @@ describe Rasti::Web::Route do
4
4
 
5
5
  ROUTES = [
6
6
  '/',
7
+ '/*/wildcard/action',
8
+ '/wildcard/*/action',
9
+ '/wildcard/*/action/:id',
10
+ '/wildcard/*',
7
11
  '/resource',
8
12
  '/resource/:id/:action',
9
13
  '/:resource(/:id(/:action))'
@@ -45,7 +49,7 @@ describe Rasti::Web::Route do
45
49
  route = route_for path
46
50
 
47
51
  route.pattern.must_equal '/resource/:id/:action'
48
- route.extract_params(path).must_equal 'id' => '123', 'action' => 'show'
52
+ route.extract_params(path).must_equal id: '123', action: 'show'
49
53
  route.call({}).must_equal RESPONSE
50
54
  end
51
55
 
@@ -55,7 +59,49 @@ describe Rasti::Web::Route do
55
59
  sections = path[1..-1].split('/')
56
60
 
57
61
  route.pattern.must_equal '/:resource(/:id(/:action))'
58
- route.extract_params(path).must_equal 'resource' => sections[0], 'id' => sections[1], 'action' => sections[2]
62
+ route.extract_params(path).must_equal resource: sections[0], id: sections[1], action: sections[2]
63
+ route.call({}).must_equal RESPONSE
64
+ end
65
+ end
66
+
67
+ describe 'Wildcard' do
68
+ it 'Head' do
69
+ path = '/section/sub_section/wildcard/action'
70
+
71
+ route = route_for path
72
+
73
+ route.pattern.must_equal '/*/wildcard/action'
74
+ route.extract_params(path).must_equal wildcard: 'section/sub_section'
75
+ route.call({}).must_equal RESPONSE
76
+ end
77
+
78
+ it 'Middle' do
79
+ path = '/wildcard/section/sub_section/action'
80
+
81
+ route = route_for path
82
+
83
+ route.pattern.must_equal '/wildcard/*/action'
84
+ route.extract_params(path).must_equal wildcard: 'section/sub_section'
85
+ route.call({}).must_equal RESPONSE
86
+ end
87
+
88
+ ['/wildcard', '/wildcard/123', '/wildcard/123/edit'].each do |path|
89
+ it "Tail #{path}" do
90
+ route = route_for path
91
+
92
+ route.pattern.must_equal '/wildcard/*'
93
+ route.extract_params(path).must_equal wildcard: path["/wildcard/".size..-1]
94
+ route.call({}).must_equal RESPONSE
95
+ end
96
+ end
97
+
98
+ it 'Params' do
99
+ path = '/wildcard/section/sub_section/action/123'
100
+
101
+ route = route_for path
102
+
103
+ route.pattern.must_equal '/wildcard/*/action/:id'
104
+ route.extract_params(path).must_equal wildcard: 'section/sub_section', id: '123'
59
105
  route.call({}).must_equal RESPONSE
60
106
  end
61
107
  end
data/spec/router_spec.rb CHANGED
@@ -32,6 +32,7 @@ describe Rasti::Web::Router do
32
32
  status, headers, response = router.call get('/not_found')
33
33
 
34
34
  status.must_equal 404
35
+ headers.must_equal 'Content-Length' => '25'
35
36
  response.body.must_equal ['Not found: GET /not_found']
36
37
  end
37
38
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rasti-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriel Naiman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-04 00:00:00.000000000 Z
11
+ date: 2017-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -94,20 +94,6 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.0'
97
- - !ruby/object:Gem::Dependency
98
- name: broadcaster
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '0.1'
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '0.1'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: bundler
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -224,16 +210,16 @@ dependencies:
224
210
  name: rack-test
225
211
  requirement: !ruby/object:Gem::Requirement
226
212
  requirements:
227
- - - ">="
213
+ - - "~>"
228
214
  - !ruby/object:Gem::Version
229
- version: '0'
215
+ version: '0.6'
230
216
  type: :development
231
217
  prerelease: false
232
218
  version_requirements: !ruby/object:Gem::Requirement
233
219
  requirements:
234
- - - ">="
220
+ - - "~>"
235
221
  - !ruby/object:Gem::Version
236
- version: '0'
222
+ version: '0.6'
237
223
  description: Web blocks to build robust applications
238
224
  email:
239
225
  - gabynaiman@gmail.com
@@ -253,15 +239,12 @@ files:
253
239
  - lib/rasti-web.rb
254
240
  - lib/rasti/web.rb
255
241
  - lib/rasti/web/application.rb
256
- - lib/rasti/web/channel.rb
257
242
  - lib/rasti/web/controller.rb
258
243
  - lib/rasti/web/endpoint.rb
259
244
  - lib/rasti/web/render.rb
260
245
  - lib/rasti/web/request.rb
261
246
  - lib/rasti/web/route.rb
262
247
  - lib/rasti/web/router.rb
263
- - lib/rasti/web/server_sent_event.rb
264
- - lib/rasti/web/stream.rb
265
248
  - lib/rasti/web/template.rb
266
249
  - lib/rasti/web/version.rb
267
250
  - lib/rasti/web/view_context.rb
@@ -276,7 +259,6 @@ files:
276
259
  - spec/route_spec.rb
277
260
  - spec/router_spec.rb
278
261
  - spec/sample_file.zip
279
- - spec/streaming_spec.rb
280
262
  - spec/template_spec.rb
281
263
  - spec/views/context_and_locals.erb
282
264
  - spec/views/context_method.erb
@@ -319,7 +301,6 @@ test_files:
319
301
  - spec/route_spec.rb
320
302
  - spec/router_spec.rb
321
303
  - spec/sample_file.zip
322
- - spec/streaming_spec.rb
323
304
  - spec/template_spec.rb
324
305
  - spec/views/context_and_locals.erb
325
306
  - spec/views/context_method.erb
@@ -1,54 +0,0 @@
1
- module Rasti
2
- module Web
3
-
4
- class Channel
5
-
6
- attr_reader :id
7
-
8
- def initialize(id)
9
- @id = id
10
- @subscriptions = {}
11
- @mutex = Mutex.new
12
- end
13
-
14
- def subscribe
15
- stream = Stream.new
16
-
17
- subscription_id = broadcaster.subscribe id do |message|
18
- if stream.open?
19
- stream.write message
20
- else
21
- sid = mutex.synchronize { subscriptions.delete stream }
22
- broadcaster.unsubscribe sid
23
- end
24
- end
25
-
26
- mutex.synchronize { subscriptions[stream] = subscription_id }
27
-
28
- stream
29
- end
30
-
31
- def publish(message)
32
- broadcaster.publish id, message
33
- end
34
-
35
- def self.broadcaster
36
- @broadcaster ||= Broadcaster.new id: Web.channels_prefix, logger: Web.logger
37
- end
38
-
39
- def self.[](id)
40
- @channels ||= Hash.new { |h,k| h[k] = self.new k }
41
- @channels[id]
42
- end
43
-
44
- private
45
-
46
- attr_reader :subscriptions, :mutex
47
-
48
- def broadcaster
49
- self.class.broadcaster
50
- end
51
-
52
- end
53
- end
54
- end
@@ -1,31 +0,0 @@
1
- module Rasti
2
- module Web
3
- class ServerSentEvent < String
4
-
5
- attr_reader :data, :id, :event
6
-
7
- private
8
-
9
- def initialize(data, options={})
10
- @data = data
11
- @id = options[:id]
12
- @event = options[:event]
13
-
14
- super serialize
15
- end
16
-
17
- def serialize
18
- serialized_data = data.respond_to?(:to_json) ? data.to_json : data.to_s
19
-
20
- message = ''
21
- message << "id: #{id}\n" if id
22
- message << "event: #{event}\n" if event
23
- serialized_data.split("\n").each do |d|
24
- message << "data: #{d}\n"
25
- end
26
- message << "\n"
27
- end
28
-
29
- end
30
- end
31
- end
@@ -1,39 +0,0 @@
1
- module Rasti
2
- module Web
3
- class Stream
4
-
5
- TIMEOUT = 0.0001
6
-
7
- def initialize
8
- @queue = Queue.new
9
- @closed = false
10
- end
11
-
12
- def write(message)
13
- raise 'Closed stream' if closed?
14
- @queue << message
15
- end
16
-
17
- def each
18
- while open?
19
- message = @queue.pop
20
- yield message if message
21
- sleep TIMEOUT
22
- end
23
- end
24
-
25
- def close
26
- @closed = true
27
- end
28
-
29
- def closed?
30
- @closed
31
- end
32
-
33
- def open?
34
- !closed?
35
- end
36
-
37
- end
38
- end
39
- end
@@ -1,49 +0,0 @@
1
- require 'minitest_helper'
2
-
3
- describe 'Straming' do
4
-
5
- let(:request) { Rack::Request.new Hash.new }
6
- let(:response) { Rack::Response.new }
7
- let(:render) { Rasti::Web::Render.new request, response }
8
-
9
- def wait_for(&block)
10
- Timeout.timeout(3) do
11
- while !block.call
12
- sleep 0.0001
13
- end
14
- end
15
- end
16
-
17
- it 'Server sent events' do
18
- render.server_sent_events :channel_1
19
-
20
- response.status.must_equal 200
21
- response['Content-Type'].must_equal 'text/event-stream'
22
- response['Cache-Control'].must_equal 'no-cache'
23
- response['Connection'].must_equal 'keep-alive'
24
- response.body.must_be_instance_of Rasti::Web::Stream
25
-
26
- events = []
27
-
28
- Thread.new do
29
- response.body.each { |e| events << e }
30
- end
31
-
32
- channel_1 = Rasti::Web::Channel[:channel_1]
33
- channel_2 = Rasti::Web::Channel[:channel_2]
34
-
35
- 3.times do |i|
36
- data = {text: "Tick #{i}"}
37
- event = Rasti::Web::ServerSentEvent.new data, id: i, event: 'tick'
38
- channel_1.publish event
39
- channel_2.publish event
40
- end
41
-
42
- wait_for { events.count == 3 }
43
-
44
- response.body.close
45
-
46
- events.must_equal 3.times.map { |i| "id: #{i}\nevent: tick\ndata: {\"text\":\"Tick #{i}\"}\n\n" }
47
- end
48
-
49
- end