rasti-web 0.2.3 → 1.0.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: 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