jellyfish 0.9.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -2
- data/.travis.yml +3 -5
- data/CHANGES.md +18 -0
- data/Gemfile +10 -1
- data/README.md +121 -22
- data/Rakefile +6 -15
- data/config.ru +105 -0
- data/jellyfish.gemspec +21 -24
- data/lib/jellyfish.rb +24 -17
- data/lib/jellyfish/json.rb +64 -0
- data/lib/jellyfish/multi_actions.rb +1 -1
- data/lib/jellyfish/swagger.rb +166 -0
- data/lib/jellyfish/test.rb +4 -1
- data/lib/jellyfish/version.rb +1 -1
- data/public/css/screen.css +1070 -0
- data/public/index.html +45 -0
- data/public/js/shred.bundle.js +2765 -0
- data/public/js/shred/content.js +193 -0
- data/public/js/swagger-ui.js +2116 -0
- data/public/js/swagger.js +1400 -0
- data/task/README.md +54 -0
- data/task/gemgem.rb +151 -157
- data/test/sinatra/test_error.rb +31 -4
- data/test/test_from_readme.rb +2 -1
- data/test/test_log.rb +42 -0
- data/test/test_misc.rb +24 -0
- data/test/test_swagger.rb +131 -0
- data/test/test_threads.rb +1 -1
- metadata +25 -52
- data/task/.gitignore +0 -1
data/test/sinatra/test_error.rb
CHANGED
@@ -94,27 +94,54 @@ describe 'Sinatra mapped_error_test.rb' do
|
|
94
94
|
body.should.eq ["she's there."]
|
95
95
|
end
|
96
96
|
|
97
|
-
should '
|
97
|
+
should 'catch Jellyfish::NotFound' do
|
98
98
|
app = Class.new{
|
99
99
|
include Jellyfish
|
100
|
-
get('/'){
|
100
|
+
get('/'){ not_found }
|
101
101
|
}.new
|
102
102
|
|
103
103
|
status, _, _ = get('/', app)
|
104
104
|
status.should.eq 404
|
105
105
|
end
|
106
106
|
|
107
|
-
should '
|
107
|
+
should 'handle subclasses of Jellyfish::NotFound' do
|
108
108
|
e = Class.new(Jellyfish::NotFound)
|
109
109
|
app = Class.new{
|
110
110
|
include Jellyfish
|
111
|
-
get('/'){
|
111
|
+
get('/'){ halt e.new }
|
112
112
|
}.new
|
113
113
|
|
114
114
|
status, _, _ = get('/', app)
|
115
115
|
status.should.eq 404
|
116
116
|
end
|
117
117
|
|
118
|
+
should 'no longer cascade with Jellyfish::NotFound' do
|
119
|
+
app = Class.new{
|
120
|
+
include Jellyfish
|
121
|
+
get('/'){ not_found }
|
122
|
+
}.new(Class.new{
|
123
|
+
include Jellyfish
|
124
|
+
get('/'){ 'never'.should.eq 'reach' }
|
125
|
+
})
|
126
|
+
|
127
|
+
status, _, _ = get('/', app)
|
128
|
+
status.should.eq 404
|
129
|
+
end
|
130
|
+
|
131
|
+
should 'cascade with Jellyfish::Cascade' do
|
132
|
+
app = Class.new{
|
133
|
+
include Jellyfish
|
134
|
+
get('/'){ cascade }
|
135
|
+
}.new(Class.new{
|
136
|
+
include Jellyfish
|
137
|
+
get('/'){ 'reach' }
|
138
|
+
}.new)
|
139
|
+
|
140
|
+
status, _, body = get('/', app)
|
141
|
+
status.should.eq 200
|
142
|
+
body .should.eq ['reach']
|
143
|
+
end
|
144
|
+
|
118
145
|
should 'inherit error mappings from base class' do
|
119
146
|
sup = Class.new{
|
120
147
|
include Jellyfish
|
data/test/test_from_readme.rb
CHANGED
@@ -29,7 +29,8 @@ describe 'from README.md' do
|
|
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 , 'rack.input' => input
|
32
|
+
'QUERY_STRING' => query , 'rack.input' => input,
|
33
|
+
'SCRIPT_NAME' => '')
|
33
34
|
end
|
34
35
|
|
35
36
|
body.extend(Enumerable)
|
data/test/test_log.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
require 'jellyfish/test'
|
3
|
+
require 'muack'
|
4
|
+
|
5
|
+
include Muack::API
|
6
|
+
|
7
|
+
describe Jellyfish do
|
8
|
+
behaves_like :jellyfish
|
9
|
+
|
10
|
+
after do
|
11
|
+
Muack.verify
|
12
|
+
end
|
13
|
+
|
14
|
+
app = Class.new{
|
15
|
+
include Jellyfish
|
16
|
+
get('/log') { log('hi') }
|
17
|
+
get('/log_error'){
|
18
|
+
log_error(stub(RuntimeError.new).backtrace{ ['backtrace'] }.object)
|
19
|
+
}
|
20
|
+
def self.name
|
21
|
+
'Name'
|
22
|
+
end
|
23
|
+
}.new
|
24
|
+
|
25
|
+
def mock_log
|
26
|
+
log = []
|
27
|
+
mock(log).puts(is_a(String)){ |msg| log << msg }
|
28
|
+
log
|
29
|
+
end
|
30
|
+
|
31
|
+
should "log to env['rack.errors']" do
|
32
|
+
log = mock_log
|
33
|
+
get('/log', app, 'rack.errors' => log)
|
34
|
+
log.should.eq ['[Name] hi']
|
35
|
+
end
|
36
|
+
|
37
|
+
should "log_error to env['rack.errors']" do
|
38
|
+
log = mock_log
|
39
|
+
get('/log_error', app, 'rack.errors' => log)
|
40
|
+
log.should.eq ['[Name] #<RuntimeError: RuntimeError> ["backtrace"]']
|
41
|
+
end
|
42
|
+
end
|
data/test/test_misc.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
require 'jellyfish/test'
|
3
|
+
|
4
|
+
describe Jellyfish do
|
5
|
+
behaves_like :jellyfish
|
6
|
+
|
7
|
+
app = Class.new{
|
8
|
+
include Jellyfish
|
9
|
+
get
|
10
|
+
}.new
|
11
|
+
|
12
|
+
should 'match wildcard' do
|
13
|
+
get('/a', app).should.eq [200, {}, ['']]
|
14
|
+
get('/b', app).should.eq [200, {}, ['']]
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'accept to_path body' do
|
18
|
+
a = Class.new{
|
19
|
+
include Jellyfish
|
20
|
+
get{ File.open(__FILE__) }
|
21
|
+
}.new
|
22
|
+
get('/', a).last.to_path.should.eq __FILE__
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
|
2
|
+
require 'jellyfish/test'
|
3
|
+
|
4
|
+
describe Jellyfish do
|
5
|
+
behaves_like :jellyfish
|
6
|
+
|
7
|
+
app = Rack::Builder.app do
|
8
|
+
eval File.read("#{File.dirname(__FILE__)}/../config.ru")
|
9
|
+
end
|
10
|
+
|
11
|
+
def string_keys hash
|
12
|
+
hash.inject({}){ |r, (k, v)| r[k.to_s] = v; r }
|
13
|
+
end
|
14
|
+
|
15
|
+
should '/swagger' do
|
16
|
+
status, headers, body = get('/swagger', app)
|
17
|
+
status .should.eq 200
|
18
|
+
headers['Content-Type'].should.eq 'application/json; charset=utf-8'
|
19
|
+
res = Jellyfish::Json.decode(body.to_a.join)
|
20
|
+
res['swaggerVersion'].should.eq '1.2'
|
21
|
+
res['info'] .should.eq string_keys(Jelly.info)
|
22
|
+
res['apiVersion'] .should.eq Jelly.swagger_apiVersion
|
23
|
+
res['apis'] .should.eq \
|
24
|
+
[{'path' => '/users'}, {'path' => '/posts'}]
|
25
|
+
end
|
26
|
+
|
27
|
+
should '/swagger/users' do
|
28
|
+
status, headers, body = get('/swagger/users', app)
|
29
|
+
status .should.eq 200
|
30
|
+
res = Jellyfish::Json.decode(body.to_a.join)
|
31
|
+
res['basePath'] .should.eq 'https://localhost:8080'
|
32
|
+
res['resourcePath'].should.eq '/users'
|
33
|
+
res['apis'] .should.eq \
|
34
|
+
[{"path"=>"/users",
|
35
|
+
"operations"=>[{"summary"=>"List users",
|
36
|
+
"notes"=>"List users<br>Note that we do not really" \
|
37
|
+
" have users.",
|
38
|
+
"path"=>"/users",
|
39
|
+
"method"=>"GET",
|
40
|
+
"nickname"=>"/users",
|
41
|
+
"parameters"=>[]},
|
42
|
+
{"summary"=>"Create a user",
|
43
|
+
"notes"=>"Create a user<br>Here we demonstrate how" \
|
44
|
+
" to write the swagger doc.",
|
45
|
+
"parameters"=>[{"type"=>"string",
|
46
|
+
"required"=>true,
|
47
|
+
"description"=>"The name of the user",
|
48
|
+
"name"=>"name",
|
49
|
+
"paramType"=>"query"},
|
50
|
+
{"type"=>"boolean",
|
51
|
+
"description"=>"If the user is sane",
|
52
|
+
"name"=>"sane",
|
53
|
+
"required"=>false,
|
54
|
+
"paramType"=>"query"},
|
55
|
+
{"type"=>"string",
|
56
|
+
"description"=>"What kind of user",
|
57
|
+
"enum"=>["good", "neutral", "evil"],
|
58
|
+
"name"=>"type",
|
59
|
+
"required"=>false,
|
60
|
+
"paramType"=>"query"}],
|
61
|
+
"responseMessages"=>[{"code"=>400,
|
62
|
+
"message"=>"Invalid name"}],
|
63
|
+
"path"=>"/users",
|
64
|
+
"method"=>"POST",
|
65
|
+
"nickname"=>"/users"}]},
|
66
|
+
{"path"=>"/users/{id}",
|
67
|
+
"operations"=>[{"summary"=>"Update a user",
|
68
|
+
"parameters"=>[{"type"=>"integer",
|
69
|
+
"description"=>"The id of the user",
|
70
|
+
"name"=>"id",
|
71
|
+
"required"=>true,
|
72
|
+
"paramType"=>"path"}],
|
73
|
+
"path"=>"/users",
|
74
|
+
"method"=>"PUT",
|
75
|
+
"nickname"=>"/users/{id}",
|
76
|
+
"notes"=>"Update a user"},
|
77
|
+
{"path"=>"/users",
|
78
|
+
"method"=>"DELETE",
|
79
|
+
"nickname"=>"/users/{id}",
|
80
|
+
"summary"=>nil,
|
81
|
+
"notes"=>nil,
|
82
|
+
"parameters"=>[{"name"=>"id",
|
83
|
+
"type"=>"integer",
|
84
|
+
"required"=>true,
|
85
|
+
"paramType"=>"path"}]}]}]
|
86
|
+
end
|
87
|
+
|
88
|
+
swagger = Jellyfish::Swagger.new(Class.new{include Jellyfish})
|
89
|
+
|
90
|
+
should 'swagger_path' do
|
91
|
+
swagger.send(:swagger_path, '/') .should.eq '/'
|
92
|
+
swagger.send(:swagger_path, '/users/{id}').should.eq '/users'
|
93
|
+
end
|
94
|
+
|
95
|
+
should 'nickname' do
|
96
|
+
swagger.send(:nickname, '/') .should.eq '/'
|
97
|
+
swagger.send(:nickname, '/users/{id}') .should.eq '/users/{id}'
|
98
|
+
swagger.send(:nickname, %r{\A/users/(?<id>\d+)}).should.eq '/users/{id}'
|
99
|
+
swagger.send(:nickname, %r{^/users/(?<id>\d+)$}).should.eq '/users/{id}'
|
100
|
+
swagger.send(:nickname, %r{/(?<a>\d)/(?<b>\w)$}).should.eq '/{a}/{b}'
|
101
|
+
end
|
102
|
+
|
103
|
+
should 'notes' do
|
104
|
+
swagger.send(:notes, :summary => 'summary', :notes => 'notes').
|
105
|
+
should.eq 'summary<br>notes'
|
106
|
+
swagger.send(:notes, :summary => 'summary').
|
107
|
+
should.eq 'summary'
|
108
|
+
end
|
109
|
+
|
110
|
+
should 'path_parameters' do
|
111
|
+
swagger.send(:path_parameters, %r{/(?<a>\d)/(?<b>\w)/(?<c>\d)$},
|
112
|
+
:parameters => {:c => {:type => 'hash'}}).
|
113
|
+
should.eq([{:name => 'a', :type => 'integer',
|
114
|
+
:required => true, :paramType => 'path'},
|
115
|
+
{:name => 'b', :type => 'string',
|
116
|
+
:required => true, :paramType => 'path'},
|
117
|
+
{:name => 'c', :type => 'hash',
|
118
|
+
:required => true, :paramType => 'path'}])
|
119
|
+
end
|
120
|
+
|
121
|
+
should 'query_parameters' do
|
122
|
+
swagger.send(:query_parameters,
|
123
|
+
:parameters => {:c => {:type => 'hash'}}).
|
124
|
+
should.eq([:name => 'c', :type => 'hash',
|
125
|
+
:required => false, :paramType => 'query'])
|
126
|
+
swagger.send(:query_parameters,
|
127
|
+
:parameters => {:c => {:required => true}}).
|
128
|
+
should.eq([:name => 'c', :type => 'string',
|
129
|
+
:required => true, :paramType => 'query'])
|
130
|
+
end
|
131
|
+
end
|
data/test/test_threads.rb
CHANGED
@@ -21,7 +21,7 @@ describe Jellyfish do
|
|
21
21
|
ancestors = RuntimeError.ancestors
|
22
22
|
stub(RuntimeError).ancestors{ancestors}
|
23
23
|
flip = true
|
24
|
-
stub(ancestors).index(anything).
|
24
|
+
stub(ancestors).index(anything).peek_return do |i|
|
25
25
|
if flip
|
26
26
|
flip = false
|
27
27
|
sleep 0.0001
|
metadata
CHANGED
@@ -1,57 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jellyfish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
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:
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rack
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - '>='
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - '>='
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bacon
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - '>='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - '>='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: muack
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - '>='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
11
|
+
date: 2014-03-17 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
55
13
|
description: |-
|
56
14
|
Pico web framework for building API-centric web applications.
|
57
15
|
For Rack applications or Rack middlewares. Around 250 lines of code.
|
@@ -61,19 +19,21 @@ executables: []
|
|
61
19
|
extensions: []
|
62
20
|
extra_rdoc_files: []
|
63
21
|
files:
|
64
|
-
- .gitignore
|
65
|
-
- .gitmodules
|
66
|
-
- .travis.yml
|
22
|
+
- ".gitignore"
|
23
|
+
- ".gitmodules"
|
24
|
+
- ".travis.yml"
|
67
25
|
- CHANGES.md
|
68
26
|
- Gemfile
|
69
27
|
- LICENSE
|
70
28
|
- README.md
|
71
29
|
- Rakefile
|
72
30
|
- TODO.md
|
31
|
+
- config.ru
|
73
32
|
- jellyfish.gemspec
|
74
33
|
- jellyfish.png
|
75
34
|
- lib/jellyfish.rb
|
76
35
|
- lib/jellyfish/chunked_body.rb
|
36
|
+
- lib/jellyfish/json.rb
|
77
37
|
- lib/jellyfish/multi_actions.rb
|
78
38
|
- lib/jellyfish/newrelic.rb
|
79
39
|
- lib/jellyfish/normalized_params.rb
|
@@ -82,9 +42,16 @@ files:
|
|
82
42
|
- lib/jellyfish/public/404.html
|
83
43
|
- lib/jellyfish/public/500.html
|
84
44
|
- lib/jellyfish/sinatra.rb
|
45
|
+
- lib/jellyfish/swagger.rb
|
85
46
|
- lib/jellyfish/test.rb
|
86
47
|
- lib/jellyfish/version.rb
|
87
|
-
-
|
48
|
+
- public/css/screen.css
|
49
|
+
- public/index.html
|
50
|
+
- public/js/shred.bundle.js
|
51
|
+
- public/js/shred/content.js
|
52
|
+
- public/js/swagger-ui.js
|
53
|
+
- public/js/swagger.js
|
54
|
+
- task/README.md
|
88
55
|
- task/gemgem.rb
|
89
56
|
- test/sinatra/test_base.rb
|
90
57
|
- test/sinatra/test_chunked_body.rb
|
@@ -93,6 +60,9 @@ files:
|
|
93
60
|
- test/sinatra/test_routing.rb
|
94
61
|
- test/test_from_readme.rb
|
95
62
|
- test/test_inheritance.rb
|
63
|
+
- test/test_log.rb
|
64
|
+
- test/test_misc.rb
|
65
|
+
- test/test_swagger.rb
|
96
66
|
- test/test_threads.rb
|
97
67
|
homepage: https://github.com/godfat/jellyfish
|
98
68
|
licenses:
|
@@ -104,17 +74,17 @@ require_paths:
|
|
104
74
|
- lib
|
105
75
|
required_ruby_version: !ruby/object:Gem::Requirement
|
106
76
|
requirements:
|
107
|
-
- -
|
77
|
+
- - ">="
|
108
78
|
- !ruby/object:Gem::Version
|
109
79
|
version: '0'
|
110
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
81
|
requirements:
|
112
|
-
- -
|
82
|
+
- - ">="
|
113
83
|
- !ruby/object:Gem::Version
|
114
84
|
version: '0'
|
115
85
|
requirements: []
|
116
86
|
rubyforge_project:
|
117
|
-
rubygems_version: 2.
|
87
|
+
rubygems_version: 2.2.2
|
118
88
|
signing_key:
|
119
89
|
specification_version: 4
|
120
90
|
summary: Pico web framework for building API-centric web applications.
|
@@ -126,4 +96,7 @@ test_files:
|
|
126
96
|
- test/sinatra/test_routing.rb
|
127
97
|
- test/test_from_readme.rb
|
128
98
|
- test/test_inheritance.rb
|
99
|
+
- test/test_log.rb
|
100
|
+
- test/test_misc.rb
|
101
|
+
- test/test_swagger.rb
|
129
102
|
- test/test_threads.rb
|
data/task/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
*.rbc
|