jellyfish 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +7 -6
- data/CHANGES.md +10 -0
- data/Gemfile +3 -2
- data/README.md +80 -4
- data/jellyfish.gemspec +9 -6
- data/lib/jellyfish.rb +11 -3
- data/lib/jellyfish/test.rb +8 -13
- data/lib/jellyfish/version.rb +1 -1
- data/lib/jellyfish/websocket.rb +51 -0
- data/task/gemgem.rb +1 -5
- data/test/sinatra/test_base.rb +9 -9
- data/test/sinatra/test_chunked_body.rb +4 -4
- data/test/sinatra/test_error.rb +14 -15
- data/test/sinatra/test_multi_actions.rb +17 -17
- data/test/sinatra/test_routing.rb +27 -27
- data/test/test_from_readme.rb +13 -7
- data/test/test_inheritance.rb +5 -5
- data/test/test_log.rb +5 -7
- data/test/test_misc.rb +13 -3
- data/test/test_swagger.rb +8 -8
- data/test/test_threads.rb +1 -4
- data/test/test_websocket.rb +44 -0
- metadata +6 -3
data/test/test_from_readme.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
|
2
2
|
require 'jellyfish/test'
|
3
3
|
require 'uri'
|
4
|
+
require 'stringio'
|
4
5
|
|
5
6
|
describe 'from README.md' do
|
6
7
|
after do
|
7
8
|
[:Tank, :Heater, :Protector].each do |const|
|
8
9
|
Object.send(:remove_const, const) if Object.const_defined?(const)
|
9
10
|
end
|
11
|
+
Muack.verify
|
10
12
|
end
|
11
13
|
|
12
14
|
readme = File.read(
|
@@ -15,22 +17,26 @@ describe 'from README.md' do
|
|
15
17
|
/### ([^\n]+).+?``` ruby\n(.+?)\n```\n\n<!---(.+?)-->/m)
|
16
18
|
|
17
19
|
codes.each.with_index do |(title, code, test), index|
|
18
|
-
if title =~ /NewRelic/i
|
19
|
-
warn "Skip NewRelic Test" unless Bacon.kind_of?(Bacon::TestUnitOutput)
|
20
|
-
next
|
21
|
-
end
|
20
|
+
next if title =~ /NewRelic/i
|
22
21
|
|
23
|
-
|
22
|
+
would "pass from README.md #%02d #{title}" % index do
|
24
23
|
method_path, expect = test.strip.split("\n", 2)
|
25
24
|
method, path = method_path.split(' ')
|
26
25
|
uri = URI.parse(path)
|
27
26
|
pinfo, query = uri.path, uri.query
|
28
27
|
|
28
|
+
sock = nil
|
29
29
|
status, headers, body = File.open(File::NULL) do |input|
|
30
30
|
Rack::Builder.app{ eval(code) }.call(
|
31
31
|
'REQUEST_METHOD' => method, 'PATH_INFO' => pinfo,
|
32
|
-
'QUERY_STRING' => query , '
|
33
|
-
'
|
32
|
+
'QUERY_STRING' => query , 'SCRIPT_NAME'=> '' ,
|
33
|
+
'rack.input' => input ,
|
34
|
+
'rack.hijack' => lambda{
|
35
|
+
sock = StringIO.new
|
36
|
+
# or TypeError: no implicit conversion of StringIO into IO
|
37
|
+
mock(IO).select([sock]){ [[sock], [], []] }
|
38
|
+
sock
|
39
|
+
})
|
34
40
|
end
|
35
41
|
|
36
42
|
body.extend(Enumerable)
|
data/test/test_inheritance.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
require 'jellyfish/test'
|
3
3
|
|
4
4
|
describe 'Inheritance' do
|
5
|
-
|
5
|
+
paste :jellyfish
|
6
6
|
|
7
|
-
|
7
|
+
would 'inherit routes' do
|
8
8
|
sup = Class.new{
|
9
9
|
include Jellyfish
|
10
10
|
get('/0'){ 'a' }
|
@@ -27,7 +27,7 @@ describe 'Inheritance' do
|
|
27
27
|
app.class.routes['get'].size.should.eq 2
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
would 'inherit handlers' do
|
31
31
|
sup = Class.new{
|
32
32
|
include Jellyfish
|
33
33
|
handle(TypeError){ 'a' }
|
@@ -47,7 +47,7 @@ describe 'Inheritance' do
|
|
47
47
|
app.class.handlers.size.should.eq 2
|
48
48
|
end
|
49
49
|
|
50
|
-
|
50
|
+
would 'inherit controller' do
|
51
51
|
sup = Class.new{
|
52
52
|
include Jellyfish
|
53
53
|
controller_include Module.new{ def f; 'a'; end }
|
@@ -66,7 +66,7 @@ describe 'Inheritance' do
|
|
66
66
|
app.class.controller_include.size.should.eq 1
|
67
67
|
end
|
68
68
|
|
69
|
-
|
69
|
+
would 'inherit handle_exceptions' do
|
70
70
|
sup = Class.new{
|
71
71
|
include Jellyfish
|
72
72
|
handle_exceptions false
|
data/test/test_log.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
|
2
2
|
require 'jellyfish/test'
|
3
|
-
require 'muack'
|
4
|
-
|
5
|
-
include Muack::API
|
6
3
|
|
7
4
|
describe Jellyfish do
|
8
|
-
|
5
|
+
paste :jellyfish
|
9
6
|
|
10
7
|
after do
|
11
8
|
Muack.verify
|
@@ -15,7 +12,8 @@ describe Jellyfish do
|
|
15
12
|
include Jellyfish
|
16
13
|
get('/log') { log('hi') }
|
17
14
|
get('/log_error'){
|
18
|
-
log_error(
|
15
|
+
log_error(
|
16
|
+
Muack::API.stub(RuntimeError.new).backtrace{ ['backtrace'] }.object)
|
19
17
|
}
|
20
18
|
def self.name
|
21
19
|
'Name'
|
@@ -28,13 +26,13 @@ describe Jellyfish do
|
|
28
26
|
log
|
29
27
|
end
|
30
28
|
|
31
|
-
|
29
|
+
would "log to env['rack.errors']" do
|
32
30
|
log = mock_log
|
33
31
|
get('/log', app, 'rack.errors' => log)
|
34
32
|
log.should.eq ['[Name] hi']
|
35
33
|
end
|
36
34
|
|
37
|
-
|
35
|
+
would "log_error to env['rack.errors']" do
|
38
36
|
log = mock_log
|
39
37
|
get('/log_error', app, 'rack.errors' => log)
|
40
38
|
log.should.eq ['[Name] #<RuntimeError: RuntimeError> ["backtrace"]']
|
data/test/test_misc.rb
CHANGED
@@ -2,23 +2,33 @@
|
|
2
2
|
require 'jellyfish/test'
|
3
3
|
|
4
4
|
describe Jellyfish do
|
5
|
-
|
5
|
+
paste :jellyfish
|
6
6
|
|
7
7
|
app = Class.new{
|
8
8
|
include Jellyfish
|
9
|
+
handle_exceptions false
|
10
|
+
get('/boom'){ halt 'string' }
|
9
11
|
get
|
10
12
|
}.new
|
11
13
|
|
12
|
-
|
14
|
+
would 'match wildcard' do
|
13
15
|
get('/a', app).should.eq [200, {}, ['']]
|
14
16
|
get('/b', app).should.eq [200, {}, ['']]
|
15
17
|
end
|
16
18
|
|
17
|
-
|
19
|
+
would 'accept to_path body' do
|
18
20
|
a = Class.new{
|
19
21
|
include Jellyfish
|
20
22
|
get{ File.open(__FILE__) }
|
21
23
|
}.new
|
22
24
|
get('/', a).last.to_path.should.eq __FILE__
|
23
25
|
end
|
26
|
+
|
27
|
+
would 'raise TypeError if we try to respond non-Response or non-Rack' do
|
28
|
+
begin
|
29
|
+
get('/boom', app)
|
30
|
+
rescue TypeError => e
|
31
|
+
e.message.should.include? '"string"'
|
32
|
+
end
|
33
|
+
end
|
24
34
|
end
|
data/test/test_swagger.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
require 'jellyfish/test'
|
3
3
|
|
4
4
|
describe Jellyfish do
|
5
|
-
|
5
|
+
paste :jellyfish
|
6
6
|
|
7
7
|
app = Rack::Builder.app do
|
8
8
|
eval File.read("#{File.dirname(__FILE__)}/../config.ru")
|
@@ -12,7 +12,7 @@ describe Jellyfish do
|
|
12
12
|
hash.inject({}){ |r, (k, v)| r[k.to_s] = v; r }
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
would '/swagger' do
|
16
16
|
status, headers, body = get('/swagger', app)
|
17
17
|
status .should.eq 200
|
18
18
|
headers['Content-Type'].should.eq 'application/json; charset=utf-8'
|
@@ -24,7 +24,7 @@ describe Jellyfish do
|
|
24
24
|
[{'path' => '/users'}, {'path' => '/posts'}]
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
would '/swagger/users' do
|
28
28
|
status, headers, body = get('/swagger/users', app)
|
29
29
|
status .should.eq 200
|
30
30
|
res = Jellyfish::Json.decode(body.to_a.join)
|
@@ -87,12 +87,12 @@ describe Jellyfish do
|
|
87
87
|
|
88
88
|
swagger = Jellyfish::Swagger.new(Class.new{include Jellyfish})
|
89
89
|
|
90
|
-
|
90
|
+
would 'swagger_path' do
|
91
91
|
swagger.send(:swagger_path, '/') .should.eq '/'
|
92
92
|
swagger.send(:swagger_path, '/users/{id}').should.eq '/users'
|
93
93
|
end
|
94
94
|
|
95
|
-
|
95
|
+
would 'nickname' do
|
96
96
|
swagger.send(:nickname, '/') .should.eq '/'
|
97
97
|
swagger.send(:nickname, '/users/{id}') .should.eq '/users/{id}'
|
98
98
|
swagger.send(:nickname, %r{\A/users/(?<id>\d+)}).should.eq '/users/{id}'
|
@@ -100,14 +100,14 @@ describe Jellyfish do
|
|
100
100
|
swagger.send(:nickname, %r{/(?<a>\d)/(?<b>\w)$}).should.eq '/{a}/{b}'
|
101
101
|
end
|
102
102
|
|
103
|
-
|
103
|
+
would 'notes' do
|
104
104
|
swagger.send(:notes, :summary => 'summary', :notes => 'notes').
|
105
105
|
should.eq 'summary<br>notes'
|
106
106
|
swagger.send(:notes, :summary => 'summary').
|
107
107
|
should.eq 'summary'
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
would 'path_parameters' do
|
111
111
|
swagger.send(:path_parameters, %r{/(?<a>\d)/(?<b>\w)/(?<c>\d)$},
|
112
112
|
:parameters => {:c => {:type => 'hash'}}).
|
113
113
|
should.eq([{:name => 'a', :type => 'integer',
|
@@ -118,7 +118,7 @@ describe Jellyfish do
|
|
118
118
|
:required => true, :paramType => 'path'}])
|
119
119
|
end
|
120
120
|
|
121
|
-
|
121
|
+
would 'query_parameters' do
|
122
122
|
swagger.send(:query_parameters,
|
123
123
|
:parameters => {:c => {:type => 'hash'}}).
|
124
124
|
should.eq([:name => 'c', :type => 'hash',
|
data/test/test_threads.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
|
2
2
|
require 'jellyfish/test'
|
3
|
-
require 'muack'
|
4
|
-
|
5
|
-
include Muack::API
|
6
3
|
|
7
4
|
describe Jellyfish do
|
8
5
|
after do
|
@@ -16,7 +13,7 @@ describe Jellyfish do
|
|
16
13
|
|
17
14
|
exp = RuntimeError.new
|
18
15
|
|
19
|
-
|
16
|
+
would "no RuntimeError: can't add a new key into hash during iteration" do
|
20
17
|
# make static ancestors so that we could stub it
|
21
18
|
ancestors = RuntimeError.ancestors
|
22
19
|
stub(RuntimeError).ancestors{ancestors}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
require 'jellyfish/test'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
describe Jellyfish do
|
6
|
+
after do
|
7
|
+
Muack.verify
|
8
|
+
end
|
9
|
+
|
10
|
+
app = Class.new do
|
11
|
+
include Jellyfish
|
12
|
+
controller_include Jellyfish::WebSocket
|
13
|
+
get '/echo' do
|
14
|
+
switch_protocol do |msg|
|
15
|
+
ws_write(msg)
|
16
|
+
end
|
17
|
+
ws_write('ping')
|
18
|
+
ws_start
|
19
|
+
end
|
20
|
+
end.new
|
21
|
+
|
22
|
+
def create_env
|
23
|
+
sock = StringIO.new
|
24
|
+
mock(IO).select([sock]) do # or EOFError, not sure why?
|
25
|
+
sock << WebSocket::Message.new('pong').to_data * 2
|
26
|
+
[[sock], [], []]
|
27
|
+
end
|
28
|
+
[{'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/echo',
|
29
|
+
'rack.hijack' => lambda{ sock }}, sock]
|
30
|
+
end
|
31
|
+
|
32
|
+
would 'ping pong' do
|
33
|
+
env, sock = create_env
|
34
|
+
app.call(env)
|
35
|
+
sock.string.should.eq <<-HTTP.chomp
|
36
|
+
HTTP/1.1 101 Switching Protocols\r
|
37
|
+
Upgrade: websocket\r
|
38
|
+
Connection: Upgrade\r
|
39
|
+
Sec-WebSocket-Accept: Kfh9QIsMVZcl6xEPYxPHzW8SZ8w=\r
|
40
|
+
\r
|
41
|
+
\x81\u0004ping\x81\u0004pong\x81\u0004pong
|
42
|
+
HTTP
|
43
|
+
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jellyfish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lin Jen-Shin (godfat)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |-
|
14
14
|
Pico web framework for building API-centric web applications.
|
@@ -45,6 +45,7 @@ files:
|
|
45
45
|
- lib/jellyfish/swagger.rb
|
46
46
|
- lib/jellyfish/test.rb
|
47
47
|
- lib/jellyfish/version.rb
|
48
|
+
- lib/jellyfish/websocket.rb
|
48
49
|
- public/css/screen.css
|
49
50
|
- public/index.html
|
50
51
|
- public/js/shred.bundle.js
|
@@ -64,6 +65,7 @@ files:
|
|
64
65
|
- test/test_misc.rb
|
65
66
|
- test/test_swagger.rb
|
66
67
|
- test/test_threads.rb
|
68
|
+
- test/test_websocket.rb
|
67
69
|
homepage: https://github.com/godfat/jellyfish
|
68
70
|
licenses:
|
69
71
|
- Apache License 2.0
|
@@ -84,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
86
|
version: '0'
|
85
87
|
requirements: []
|
86
88
|
rubyforge_project:
|
87
|
-
rubygems_version: 2.
|
89
|
+
rubygems_version: 2.4.2
|
88
90
|
signing_key:
|
89
91
|
specification_version: 4
|
90
92
|
summary: Pico web framework for building API-centric web applications.
|
@@ -100,3 +102,4 @@ test_files:
|
|
100
102
|
- test/test_misc.rb
|
101
103
|
- test/test_swagger.rb
|
102
104
|
- test/test_threads.rb
|
105
|
+
- test/test_websocket.rb
|