hovercraft 0.0.2 → 0.1.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.
- data/.rspec +1 -0
- data/lib/hovercraft/builder.rb +4 -2
- data/lib/hovercraft/helpers.rb +38 -0
- data/lib/hovercraft/{actions.rb → routes.rb} +11 -13
- data/lib/hovercraft/version.rb +1 -1
- data/spec/hovercraft/builder_spec.rb +7 -1
- data/spec/hovercraft/helpers_spec.rb +86 -0
- data/spec/hovercraft/{actions_spec.rb → routes_spec.rb} +11 -8
- metadata +11 -7
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/lib/hovercraft/builder.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'hovercraft/loader'
|
2
|
-
require 'hovercraft/
|
2
|
+
require 'hovercraft/routes'
|
3
|
+
require 'hovercraft/helpers'
|
3
4
|
require 'sinatra/base'
|
4
5
|
require 'rack/contrib'
|
5
6
|
require 'forwardable'
|
@@ -22,7 +23,8 @@ module Hovercraft
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def configure(application)
|
25
|
-
application.register(Hovercraft::
|
26
|
+
application.register(Hovercraft::Helpers)
|
27
|
+
application.register(Hovercraft::Routes)
|
26
28
|
application.use(Rack::PostBodyContentTypeParser)
|
27
29
|
application
|
28
30
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Hovercraft
|
2
|
+
module Helpers
|
3
|
+
def self.registered(application)
|
4
|
+
application.helpers(Hovercraft::Helpers)
|
5
|
+
end
|
6
|
+
|
7
|
+
def respond_with(content)
|
8
|
+
if content.respond_to?(format_method_name)
|
9
|
+
content.send(format_method_name)
|
10
|
+
else
|
11
|
+
fail "Serialization method not supported: #{format_method_name}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def format_method_name
|
16
|
+
"to_#{format}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def format
|
20
|
+
params[:format] ||
|
21
|
+
preferred_type ||
|
22
|
+
default_format
|
23
|
+
end
|
24
|
+
|
25
|
+
def preferred_type
|
26
|
+
case request.preferred_type
|
27
|
+
when /.*\/json/ then :json
|
28
|
+
when /.*\/xml/ then :xml
|
29
|
+
when /.*\/\*/ then default_format
|
30
|
+
else fail "Unknown media type: %p" % request.preferred_type
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_format
|
35
|
+
:json
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,46 +1,44 @@
|
|
1
|
-
require 'sinatra/base'
|
2
|
-
|
3
1
|
module Hovercraft
|
4
|
-
module
|
2
|
+
module Routes
|
5
3
|
def generate_index(model_class, model_name, plural_model_name)
|
6
|
-
get(
|
4
|
+
get(%r{^/#{plural_model_name}(\.(?<format>[^\./?#]+))?$}) do
|
7
5
|
model_instances = model_class.all
|
8
6
|
status 200
|
9
|
-
model_instances
|
7
|
+
respond_with model_instances
|
10
8
|
end
|
11
9
|
end
|
12
10
|
|
13
11
|
def generate_create(model_class, model_name, plural_model_name)
|
14
|
-
post(
|
12
|
+
post(%r{^/#{plural_model_name}(\.(?<format>[^\./?#]+))?$}) do
|
15
13
|
model_instance = model_class.create(params[model_name.to_sym])
|
16
14
|
status model_instance.valid? ? 201 : 400
|
17
|
-
model_instance
|
15
|
+
respond_with model_instance
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
21
19
|
def generate_show(model_class, model_name, plural_model_name)
|
22
|
-
get(
|
20
|
+
get(%r{^/#{plural_model_name}/(?<id>[^\./?#]+)(\.(?<format>[^\./?#]+))?$}) do
|
23
21
|
model_instance = model_class.find(params[:id])
|
24
22
|
status 200
|
25
|
-
model_instance
|
23
|
+
respond_with model_instance
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
27
|
def generate_update(model_class, model_name, plural_model_name)
|
30
|
-
put(
|
28
|
+
put(%r{^/#{plural_model_name}/(?<id>[^\./?#]+)(\.(?<format>[^\./?#]+))?$}) do
|
31
29
|
model_instance = model_class.find(params[:id])
|
32
30
|
model_instance.update_attributes(params[model_name.to_sym])
|
33
31
|
status model_instance.valid? ? 204 : 400
|
34
|
-
model_instance
|
32
|
+
respond_with model_instance
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
38
36
|
def generate_destroy(model_class, model_name, plural_model_name)
|
39
|
-
delete(
|
37
|
+
delete(%r{^/#{plural_model_name}/(?<id>[^\./?#]+)(\.(?<format>[^\./?#]+))?$}) do
|
40
38
|
model_instance = model_class.find(params[:id])
|
41
39
|
model_instance.destroy
|
42
40
|
status 204
|
43
|
-
model_instance
|
41
|
+
respond_with model_instance
|
44
42
|
end
|
45
43
|
end
|
46
44
|
end
|
data/lib/hovercraft/version.rb
CHANGED
@@ -33,8 +33,14 @@ describe Hovercraft::Builder do
|
|
33
33
|
describe '#configure' do
|
34
34
|
let(:application) { stub(register: nil, use: nil) }
|
35
35
|
|
36
|
+
it 'registers the helper methods' do
|
37
|
+
application.should_receive(:register).with(Hovercraft::Helpers)
|
38
|
+
|
39
|
+
subject.configure(application)
|
40
|
+
end
|
41
|
+
|
36
42
|
it 'registers the methods to generate actions' do
|
37
|
-
application.should_receive(:register).with(Hovercraft::
|
43
|
+
application.should_receive(:register).with(Hovercraft::Routes)
|
38
44
|
|
39
45
|
subject.configure(application)
|
40
46
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'hovercraft/helpers'
|
2
|
+
|
3
|
+
describe Hovercraft::Helpers do
|
4
|
+
subject { Class.new { extend Hovercraft::Helpers } }
|
5
|
+
let(:model_to_json) { stub }
|
6
|
+
let(:model) { stub(to_json: model_to_json) }
|
7
|
+
|
8
|
+
describe '.registered' do
|
9
|
+
let(:application) { stub }
|
10
|
+
|
11
|
+
it 'includes the helpers in the application' do
|
12
|
+
application.should_receive(:helpers).with(described_class)
|
13
|
+
|
14
|
+
Hovercraft::Helpers.registered(application)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#respond_with' do
|
19
|
+
it 'serializes the content to the preferred format' do
|
20
|
+
subject.stub(format: :json)
|
21
|
+
|
22
|
+
subject.respond_with(model).should == model_to_json
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'fails if the preferred format is not supported' do
|
26
|
+
subject.stub(format: :xml)
|
27
|
+
|
28
|
+
lambda { subject.respond_with(model) }.should raise_error
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#format' do
|
33
|
+
let(:format_param) { stub }
|
34
|
+
let(:preferred_type) { stub }
|
35
|
+
let(:default_format) { stub }
|
36
|
+
|
37
|
+
before do
|
38
|
+
subject.stub(
|
39
|
+
params: { format: nil },
|
40
|
+
preferred_type: nil,
|
41
|
+
default_format: nil
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'defaults to the format param' do
|
46
|
+
subject.stub(params: { format: format_param })
|
47
|
+
subject.format.should == format_param
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'falls back on the preferred_type' do
|
51
|
+
subject.stub(preferred_type: preferred_type)
|
52
|
+
subject.format.should == preferred_type
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'uses the default format as a worst case' do
|
56
|
+
subject.stub(default_format: default_format)
|
57
|
+
subject.format.should == default_format
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#preferred_type' do
|
62
|
+
let(:default_format) { stub }
|
63
|
+
|
64
|
+
before { subject.stub(default_format: default_format) }
|
65
|
+
|
66
|
+
it 'checks for json' do
|
67
|
+
subject.stub_chain(:request, :preferred_type) { 'application/json' }
|
68
|
+
subject.preferred_type.should == :json
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'checks for xml' do
|
72
|
+
subject.stub_chain(:request, :preferred_type) { 'application/xml' }
|
73
|
+
subject.preferred_type.should == :xml
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'defaults to json if any format is allowed' do
|
77
|
+
subject.stub_chain(:request, :preferred_type) { '*/*' }
|
78
|
+
subject.preferred_type.should == default_format
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'fails if the acceptable type is unknown' do
|
82
|
+
subject.stub_chain(:request, :preferred_type) { 'unknown/type' }
|
83
|
+
lambda { subject.preferred_type.should }.should raise_error
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
|
-
require 'hovercraft/
|
1
|
+
require 'hovercraft/routes'
|
2
|
+
require 'hovercraft/helpers'
|
3
|
+
require 'sinatra'
|
2
4
|
require 'rack/test'
|
3
5
|
|
4
|
-
describe Hovercraft::
|
6
|
+
describe Hovercraft::Routes do
|
5
7
|
include Rack::Test::Methods
|
6
8
|
|
7
9
|
let(:application) { Sinatra.new }
|
@@ -50,7 +52,8 @@ describe Hovercraft::Actions do
|
|
50
52
|
alias :app :application
|
51
53
|
|
52
54
|
before do
|
53
|
-
application.register(Hovercraft::
|
55
|
+
application.register(Hovercraft::Helpers)
|
56
|
+
application.register(Hovercraft::Routes)
|
54
57
|
|
55
58
|
model_class.stub(all: models, create: model, find: model)
|
56
59
|
end
|
@@ -61,7 +64,7 @@ describe Hovercraft::Actions do
|
|
61
64
|
end
|
62
65
|
|
63
66
|
it 'generates a GET collection route' do
|
64
|
-
application.routes['GET'][0][0].should == %r{^/employees(
|
67
|
+
application.routes['GET'][0][0].should == %r{^/employees(\.(?<format>[^\./?#]+))?$}
|
65
68
|
application.routes['GET'][0][1].should == ['format']
|
66
69
|
end
|
67
70
|
|
@@ -78,7 +81,7 @@ describe Hovercraft::Actions do
|
|
78
81
|
end
|
79
82
|
|
80
83
|
it 'generates a POST collection route' do
|
81
|
-
application.routes['POST'][0][0].should == %r{^/employees(
|
84
|
+
application.routes['POST'][0][0].should == %r{^/employees(\.(?<format>[^\./?#]+))?$}
|
82
85
|
application.routes['POST'][0][1].should == ['format']
|
83
86
|
end
|
84
87
|
|
@@ -103,7 +106,7 @@ describe Hovercraft::Actions do
|
|
103
106
|
end
|
104
107
|
|
105
108
|
it 'generates a GET member route' do
|
106
|
-
application.routes['GET'][0][0].should == %r{^/employees/([
|
109
|
+
application.routes['GET'][0][0].should == %r{^/employees/(?<id>[^\./?#]+)(\.(?<format>[^\./?#]+))?$}
|
107
110
|
application.routes['GET'][0][1].should == ['id', 'format']
|
108
111
|
end
|
109
112
|
|
@@ -120,7 +123,7 @@ describe Hovercraft::Actions do
|
|
120
123
|
end
|
121
124
|
|
122
125
|
it 'generates a PUT member route' do
|
123
|
-
application.routes['PUT'][0][0].should == %r{^/employees/([
|
126
|
+
application.routes['PUT'][0][0].should == %r{^/employees/(?<id>[^\./?#]+)(\.(?<format>[^\./?#]+))?$}
|
124
127
|
application.routes['PUT'][0][1].should == ['id', 'format']
|
125
128
|
end
|
126
129
|
|
@@ -145,7 +148,7 @@ describe Hovercraft::Actions do
|
|
145
148
|
end
|
146
149
|
|
147
150
|
it 'generates a DELETE member route' do
|
148
|
-
application.routes['DELETE'][0][0].should == %r{^/employees/([
|
151
|
+
application.routes['DELETE'][0][0].should == %r{^/employees/(?<id>[^\./?#]+)(\.(?<format>[^\./?#]+))?$}
|
149
152
|
application.routes['DELETE'][0][1].should == ['id', 'format']
|
150
153
|
end
|
151
154
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hovercraft
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra-activerecord
|
@@ -115,6 +115,7 @@ extensions: []
|
|
115
115
|
extra_rdoc_files: []
|
116
116
|
files:
|
117
117
|
- .gitignore
|
118
|
+
- .rspec
|
118
119
|
- .travis.yml
|
119
120
|
- Gemfile
|
120
121
|
- LICENSE
|
@@ -122,16 +123,18 @@ files:
|
|
122
123
|
- Rakefile
|
123
124
|
- hovercraft.gemspec
|
124
125
|
- lib/hovercraft.rb
|
125
|
-
- lib/hovercraft/actions.rb
|
126
126
|
- lib/hovercraft/builder.rb
|
127
127
|
- lib/hovercraft/caller.rb
|
128
|
+
- lib/hovercraft/helpers.rb
|
128
129
|
- lib/hovercraft/loader.rb
|
130
|
+
- lib/hovercraft/routes.rb
|
129
131
|
- lib/hovercraft/server.rb
|
130
132
|
- lib/hovercraft/version.rb
|
131
|
-
- spec/hovercraft/actions_spec.rb
|
132
133
|
- spec/hovercraft/builder_spec.rb
|
133
134
|
- spec/hovercraft/caller_spec.rb
|
135
|
+
- spec/hovercraft/helpers_spec.rb
|
134
136
|
- spec/hovercraft/loader_spec.rb
|
137
|
+
- spec/hovercraft/routes_spec.rb
|
135
138
|
- spec/hovercraft/server_spec.rb
|
136
139
|
homepage: ''
|
137
140
|
licenses: []
|
@@ -147,7 +150,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
150
|
version: '0'
|
148
151
|
segments:
|
149
152
|
- 0
|
150
|
-
hash:
|
153
|
+
hash: -800613418121454242
|
151
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
155
|
none: false
|
153
156
|
requirements:
|
@@ -156,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
159
|
version: '0'
|
157
160
|
segments:
|
158
161
|
- 0
|
159
|
-
hash:
|
162
|
+
hash: -800613418121454242
|
160
163
|
requirements: []
|
161
164
|
rubyforge_project:
|
162
165
|
rubygems_version: 1.8.23
|
@@ -167,8 +170,9 @@ summary: There's a lot of boiler plate code that goes into creating an API so wh
|
|
167
170
|
directory and call the server from the rackup file and you have yourself a perfect
|
168
171
|
API.
|
169
172
|
test_files:
|
170
|
-
- spec/hovercraft/actions_spec.rb
|
171
173
|
- spec/hovercraft/builder_spec.rb
|
172
174
|
- spec/hovercraft/caller_spec.rb
|
175
|
+
- spec/hovercraft/helpers_spec.rb
|
173
176
|
- spec/hovercraft/loader_spec.rb
|
177
|
+
- spec/hovercraft/routes_spec.rb
|
174
178
|
- spec/hovercraft/server_spec.rb
|