bradphelan-sinatras-hat 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/LICENSE +22 -0
- data/README.md +235 -0
- data/Rakefile +59 -0
- data/VERSION +1 -0
- data/bradphelan-sinatras-hat.gemspec +145 -0
- data/ci.rb +9 -0
- data/example/app-with-auth.rb +14 -0
- data/example/app-with-cache.rb +30 -0
- data/example/app.rb +23 -0
- data/example/lib/comment.rb +13 -0
- data/example/lib/common.rb +19 -0
- data/example/lib/post.rb +16 -0
- data/example/simple-app.rb +4 -0
- data/example/views/comments/index.erb +6 -0
- data/example/views/comments/show.erb +1 -0
- data/example/views/posts/index.erb +8 -0
- data/example/views/posts/new.erb +11 -0
- data/example/views/posts/show.erb +28 -0
- data/features/authenticated.feature +12 -0
- data/features/create.feature +16 -0
- data/features/destroy.feature +18 -0
- data/features/edit.feature +17 -0
- data/features/formats.feature +19 -0
- data/features/headers.feature +28 -0
- data/features/index.feature +23 -0
- data/features/layouts.feature +11 -0
- data/features/nested.feature +20 -0
- data/features/new.feature +20 -0
- data/features/only.feature +13 -0
- data/features/show.feature +31 -0
- data/features/steps/authenticated_steps.rb +10 -0
- data/features/steps/common_steps.rb +77 -0
- data/features/steps/create_steps.rb +21 -0
- data/features/steps/destroy_steps.rb +16 -0
- data/features/steps/edit_steps.rb +7 -0
- data/features/steps/format_steps.rb +11 -0
- data/features/steps/header_steps.rb +7 -0
- data/features/steps/index_steps.rb +26 -0
- data/features/steps/nested_steps.rb +11 -0
- data/features/steps/new_steps.rb +15 -0
- data/features/steps/only_steps.rb +10 -0
- data/features/steps/show_steps.rb +24 -0
- data/features/steps/update_steps.rb +22 -0
- data/features/support/env.rb +17 -0
- data/features/support/views/comments/index.erb +5 -0
- data/features/support/views/layout.erb +9 -0
- data/features/support/views/people/edit.erb +1 -0
- data/features/support/views/people/index.erb +1 -0
- data/features/support/views/people/layout.erb +9 -0
- data/features/support/views/people/new.erb +1 -0
- data/features/support/views/people/show.erb +1 -0
- data/features/update.feature +25 -0
- data/lib/core_ext/array.rb +5 -0
- data/lib/core_ext/hash.rb +23 -0
- data/lib/core_ext/module.rb +14 -0
- data/lib/core_ext/object.rb +45 -0
- data/lib/sinatras-hat.rb +22 -0
- data/lib/sinatras-hat/actions.rb +81 -0
- data/lib/sinatras-hat/authentication.rb +55 -0
- data/lib/sinatras-hat/extendor.rb +24 -0
- data/lib/sinatras-hat/hash_mutator.rb +18 -0
- data/lib/sinatras-hat/logger.rb +36 -0
- data/lib/sinatras-hat/maker.rb +187 -0
- data/lib/sinatras-hat/model.rb +110 -0
- data/lib/sinatras-hat/resource.rb +57 -0
- data/lib/sinatras-hat/responder.rb +106 -0
- data/lib/sinatras-hat/response.rb +60 -0
- data/lib/sinatras-hat/router.rb +46 -0
- data/sinatras-hat.gemspec +34 -0
- data/spec/actions/create_spec.rb +68 -0
- data/spec/actions/destroy_spec.rb +58 -0
- data/spec/actions/edit_spec.rb +52 -0
- data/spec/actions/index_spec.rb +72 -0
- data/spec/actions/new_spec.rb +39 -0
- data/spec/actions/show_spec.rb +85 -0
- data/spec/actions/update_spec.rb +83 -0
- data/spec/extendor_spec.rb +78 -0
- data/spec/fixtures/views/articles/edit.erb +1 -0
- data/spec/fixtures/views/articles/index.erb +1 -0
- data/spec/fixtures/views/articles/new.erb +1 -0
- data/spec/fixtures/views/articles/show.erb +1 -0
- data/spec/hash_mutator_spec.rb +23 -0
- data/spec/maker_spec.rb +411 -0
- data/spec/model_spec.rb +152 -0
- data/spec/resource_spec.rb +74 -0
- data/spec/responder_spec.rb +139 -0
- data/spec/response_spec.rb +120 -0
- data/spec/router_spec.rb +105 -0
- data/spec/spec_helper.rb +80 -0
- metadata +161 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2008-2009 Pat Nakajima
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
# Sinatra's Hat
|
2
|
+
|
3
|
+
Easy REST-ful apps with Sinatra.
|
4
|
+
|
5
|
+
Using Sinatra's Hat is centered around the `mount` method, which is
|
6
|
+
added to `Sinatra::Base`. It takes at bare minimum a model class. This
|
7
|
+
class will be mounted as a REST-ful resource, giving you all the CRUD
|
8
|
+
actions, as well as `new` and `edit` actions. Let's look at some code:
|
9
|
+
|
10
|
+
<pre>
|
11
|
+
mount Article
|
12
|
+
</pre>
|
13
|
+
|
14
|
+
Now you've basically got the same functionality as you'll get in Rails
|
15
|
+
by running `script/generate scaffold Article`. The views for your `Article`
|
16
|
+
will live in `views/articles`, and be named `index.erb`, `show.erb`, etc.
|
17
|
+
|
18
|
+
You can look at my [Hatter](http://github.com/nakajima/hatter/tree/master)
|
19
|
+
project, or the `examples/` directory in this one to see this in action.
|
20
|
+
|
21
|
+
Go ahead, try it.
|
22
|
+
|
23
|
+
## ORM agnostic? Or ORM atheist?
|
24
|
+
|
25
|
+
By default, Sinatra's Hat works with ActiveRecord. That means that going
|
26
|
+
to `/articles` will simply call `Article.all` to populate the `@articles`
|
27
|
+
instance variable. Going to `/articles/2` will call `Article.find_by_id(2)`
|
28
|
+
to populate the `@article` instance variable.
|
29
|
+
|
30
|
+
We call `find_by_id` instead of `find` because the `record` option should
|
31
|
+
simply return `nil` when the record can't be found.
|
32
|
+
|
33
|
+
Not every class is an ActiveRecord though (especially if you're not using
|
34
|
+
ActiveRecord). That's why you can use the `finder` and `record` options.
|
35
|
+
|
36
|
+
This example will show you how to use DataMapper with Sinatra's Hat:
|
37
|
+
|
38
|
+
<pre>
|
39
|
+
mount Article do
|
40
|
+
finder { |model, params| model.all }
|
41
|
+
record { |model, params| model.first(:id => params[:id]) }
|
42
|
+
end
|
43
|
+
</pre>
|
44
|
+
|
45
|
+
As you can see, both `finder` and `record` take a block, which will get
|
46
|
+
passed the "model" and `params` for each request. The reason you should use
|
47
|
+
the "model" argument instead of referencing the class directly is that
|
48
|
+
when you start nesting mounted models, then Sinatra's Hat will attempt to
|
49
|
+
pass the association proxy as the model argument instead of the class itself.
|
50
|
+
|
51
|
+
"Nested mounted models?" you ask?
|
52
|
+
|
53
|
+
## Nested mounted models.
|
54
|
+
|
55
|
+
You don't want to have to expose your entire application at the top level
|
56
|
+
of URL paths. That wouldn't be very RESTful, and more importantly, it'd be
|
57
|
+
damn ugly. So Sinatra's Hat allows you to nest resources:
|
58
|
+
|
59
|
+
<pre>
|
60
|
+
mount Article do
|
61
|
+
mount Comment
|
62
|
+
end
|
63
|
+
</pre>
|
64
|
+
|
65
|
+
With this example, you'd get `/articles/1/comments`, `/articles/1/comments/1`
|
66
|
+
and all the rest of the actions you get for articles, just nested. As long
|
67
|
+
as your `Article` model supports a `comments` association proxy, then the `finder`
|
68
|
+
and `record` options for `Comment` will automatically scope their results by
|
69
|
+
the parent `Article`.
|
70
|
+
|
71
|
+
## Limiting routes
|
72
|
+
|
73
|
+
By default, Sinatra's Hat creates seven routes for each mounted model (the
|
74
|
+
four ones for <acronym title="Create|Read|Update|Destroy">CRUD</acronym>
|
75
|
+
actions plus the routes for index, new and edit action), but you can reduce
|
76
|
+
the number of available routes with `only`:
|
77
|
+
|
78
|
+
<pre>
|
79
|
+
mount Article do
|
80
|
+
only :index, :show
|
81
|
+
end
|
82
|
+
</pre>
|
83
|
+
|
84
|
+
Only the listed actions will return valid responses; requests for the
|
85
|
+
"missing" routes will produce 404 "Not Found" HTTP responses.
|
86
|
+
|
87
|
+
## Basic Auth
|
88
|
+
|
89
|
+
To protect actions using basic authentication, you can use the `protect` method.
|
90
|
+
|
91
|
+
<pre>
|
92
|
+
mount Article do
|
93
|
+
protect :create, :update, :destroy, :username => "foo", :password => "bar", :realm => "BLOGZ"
|
94
|
+
end
|
95
|
+
</pre>
|
96
|
+
|
97
|
+
The above snippet will protect your <acronym title="Create|Update|Destroy">CUD</acronym>
|
98
|
+
actions with basic auth, using the username "foo" and password "bar". The realm
|
99
|
+
for the basic auth prompt will say "BLOGZ".
|
100
|
+
|
101
|
+
If you want to protect all of your actions, you cay say `protect :all`.
|
102
|
+
|
103
|
+
## `.xml`, `.json`, `.yaml`, and whatever else you want
|
104
|
+
|
105
|
+
If a request has a format extensions, then Sinatra's Hat will first check
|
106
|
+
to see if it has a custom way of serializing that format. To specify a
|
107
|
+
custom formatter, you can use the `formats` hash:
|
108
|
+
|
109
|
+
<pre>
|
110
|
+
mount Article do
|
111
|
+
formats[:ruby] = { |data| data.inspect }
|
112
|
+
end
|
113
|
+
</pre>
|
114
|
+
|
115
|
+
With that custom formatter, a request to `/articles.ruby` will return
|
116
|
+
the equivalent of `Article.all.inspect`.
|
117
|
+
|
118
|
+
### Automatic formatters
|
119
|
+
|
120
|
+
If you don't specify a custom formatter, then Sinatra's Hat will try to
|
121
|
+
call `to_#{format}` on the record object. That means that with most ORMs,
|
122
|
+
things like `to_xml`, `to_json`, and `to_yaml` will be supported right out
|
123
|
+
of the box.
|
124
|
+
|
125
|
+
Requests for unknow formats will produce 406 "Not Acceptable" HTTP responses.
|
126
|
+
|
127
|
+
## Default Flows
|
128
|
+
|
129
|
+
Sinatra's Hat has some default flows:
|
130
|
+
|
131
|
+
### After the `create` action
|
132
|
+
|
133
|
+
**On Success**: If a record is successfully created, Sinatra's Hat will redirect to that
|
134
|
+
record's show page.
|
135
|
+
|
136
|
+
**On Failure**: If a record cannot be saved, Sinatra's Hat will render the `new` action.
|
137
|
+
|
138
|
+
### After the `Update` action
|
139
|
+
|
140
|
+
**On Success**: If a record is successfully updated, Sinatra's Hat will redirect to that
|
141
|
+
record's show page.
|
142
|
+
|
143
|
+
**On Failure**: If a record cannot be updated, Sinatra's Hat will render the `edit` action.
|
144
|
+
|
145
|
+
## Custom Flows
|
146
|
+
|
147
|
+
To specify custom flows for your actions, you can use the `after` method.
|
148
|
+
|
149
|
+
Let's say that after a user creates an Article, you want to render the
|
150
|
+
article's edit action, and if it can't be created, you want to redirect
|
151
|
+
back to the articles index.
|
152
|
+
|
153
|
+
<pre>
|
154
|
+
mount Article do
|
155
|
+
after :create do |on|
|
156
|
+
on.success { |record| render(:edit) }
|
157
|
+
on.failure { |record| redirect(:index) }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
</pre>
|
161
|
+
|
162
|
+
Only `:create` and `:update` actions allow to handle success and failure
|
163
|
+
differently; for the other actions you can customize only the `success` result
|
164
|
+
and if something goes wrong (i.e., when a record cannot be found) they will
|
165
|
+
simply return a 404 "Not Found" HTTP response.
|
166
|
+
|
167
|
+
### `redirect` options
|
168
|
+
|
169
|
+
When specifying a custom redirect, you can pass one of a few things:
|
170
|
+
|
171
|
+
#### A String
|
172
|
+
|
173
|
+
When you pass `redirect` a string, the redirect will go to that string.
|
174
|
+
|
175
|
+
<pre>
|
176
|
+
after :create do |on|
|
177
|
+
on.success { |record| redirect("/articles/#{record.to_param}") }
|
178
|
+
end
|
179
|
+
</pre>
|
180
|
+
|
181
|
+
#### A Record
|
182
|
+
|
183
|
+
When you pass `redirect` a record, the redirect will go to the show
|
184
|
+
action for that record.
|
185
|
+
|
186
|
+
<pre>
|
187
|
+
after :create do |on|
|
188
|
+
on.success { |record| redirect(record) }
|
189
|
+
end
|
190
|
+
</pre>
|
191
|
+
|
192
|
+
#### A symbol
|
193
|
+
|
194
|
+
If you pass `redirect` the name of an action as a symbol (like `:index`),
|
195
|
+
then the redirect will go to the correct path for that option:
|
196
|
+
|
197
|
+
<pre>
|
198
|
+
after :create do |on|
|
199
|
+
on.success { redirect(:index) }
|
200
|
+
end
|
201
|
+
</pre>
|
202
|
+
|
203
|
+
When the action requires a record (like `:show`), then just pass the
|
204
|
+
record as a second argument:
|
205
|
+
|
206
|
+
<pre>
|
207
|
+
after :create do |on|
|
208
|
+
on.success { |record| redirect(:show, record) }
|
209
|
+
end
|
210
|
+
</pre>
|
211
|
+
|
212
|
+
### Responding with a `render`
|
213
|
+
|
214
|
+
When you want your response to just render a template, just call `render`
|
215
|
+
with the name of the template:
|
216
|
+
|
217
|
+
<pre>
|
218
|
+
after :create do |on|
|
219
|
+
on.failure { |record| render(:new) }
|
220
|
+
end
|
221
|
+
</pre>
|
222
|
+
|
223
|
+
## Todo
|
224
|
+
|
225
|
+
* Make `last_modified` calls more efficient
|
226
|
+
* Investigate other forms of caching
|
227
|
+
|
228
|
+
## Other Info
|
229
|
+
|
230
|
+
* [View the Lighthouse Project](http://nakajima.lighthouseapp.com/projects/24609-sinatras-hat/overview)
|
231
|
+
* [View the CI build](http://ci.patnakajima.com/sinatra-s-hat)
|
232
|
+
* Thanks a ton to the [Sinatra team](http://github.com/sinatra) for such an
|
233
|
+
awesome framework.
|
234
|
+
|
235
|
+
(c) Copyright 2008-2009 Pat Nakajima. All Rights Reserved.
|
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec/rake/spectask'
|
2
|
+
require 'rake/classic_namespace'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
|
5
|
+
task :default => [:spec, :features]
|
6
|
+
|
7
|
+
desc "Run all specs"
|
8
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
9
|
+
t.spec_files = FileList['spec/**/*.rb']
|
10
|
+
t.spec_opts = ['--colour']
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gemspec|
|
16
|
+
gemspec.name = "bradphelan-sinatras-hat"
|
17
|
+
gemspec.summary = "Easy peasy CRUD with sinatra"
|
18
|
+
gemspec.description = "Easy peasy CRUD with sinatra"
|
19
|
+
gemspec.email = "bradphelan@xtargets.com"
|
20
|
+
gemspec.homepage = "http://github.com/bradphelan/sinatras-hat"
|
21
|
+
gemspec.authors = ["Pat Nakajima", "Brad Phelan" ]
|
22
|
+
end
|
23
|
+
Jeweler::GemcutterTasks.new
|
24
|
+
rescue LoadError
|
25
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
26
|
+
end
|
27
|
+
|
28
|
+
Cucumber::Rake::Task.new do |c|
|
29
|
+
c.cucumber_opts = '--format progress'
|
30
|
+
end
|
31
|
+
|
32
|
+
namespace :sinatra do
|
33
|
+
desc "Clone edge Sinatra"
|
34
|
+
task :clone do
|
35
|
+
vendor_dir = File.join(File.dirname(__FILE__), 'vendor')
|
36
|
+
FileUtils.mkdir_p(vendor_dir)
|
37
|
+
puts "* cloning git://github.com/rtomayko/sinatra.git"
|
38
|
+
system("git clone git://github.com/rtomayko/sinatra.git #{File.expand_path(vendor_dir)}/sinatra")
|
39
|
+
puts "* done."
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Update edge Sinatra"
|
43
|
+
task :pull do
|
44
|
+
sinatra_dir = File.join(File.dirname(__FILE__), 'vendor', 'sinatra')
|
45
|
+
Task["sinatra:clone"].invoke unless File.exists?(sinatra_dir)
|
46
|
+
|
47
|
+
puts "* pulling from git://github.com/rtomayko/sinatra.git"
|
48
|
+
system("cd #{File.expand_path(sinatra_dir)} && git pull git://github.com/rtomayko/sinatra.git master")
|
49
|
+
puts "* done."
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Install edge Sinatra"
|
53
|
+
task :install => :pull do
|
54
|
+
sinatra_dir = File.join(File.dirname(__FILE__), 'vendor', 'sinatra')
|
55
|
+
Task["sinatra:clone"].invoke unless File.exists?(sinatra_dir)
|
56
|
+
puts "* installing edge sinatra"
|
57
|
+
system("cd #{File.expand_path(sinatra_dir)} && rake install")
|
58
|
+
end
|
59
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.2
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{bradphelan-sinatras-hat}
|
8
|
+
s.version = "0.1.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Pat Nakajima", "Brad Phelan"]
|
12
|
+
s.date = %q{2010-03-27}
|
13
|
+
s.description = %q{Easy peasy CRUD with sinatra}
|
14
|
+
s.email = %q{bradphelan@xtargets.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"LICENSE",
|
22
|
+
"README.md",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"bradphelan-sinatras-hat.gemspec",
|
26
|
+
"ci.rb",
|
27
|
+
"example/app-with-auth.rb",
|
28
|
+
"example/app-with-cache.rb",
|
29
|
+
"example/app.rb",
|
30
|
+
"example/lib/comment.rb",
|
31
|
+
"example/lib/common.rb",
|
32
|
+
"example/lib/post.rb",
|
33
|
+
"example/simple-app.rb",
|
34
|
+
"example/views/comments/index.erb",
|
35
|
+
"example/views/comments/show.erb",
|
36
|
+
"example/views/posts/index.erb",
|
37
|
+
"example/views/posts/new.erb",
|
38
|
+
"example/views/posts/show.erb",
|
39
|
+
"features/authenticated.feature",
|
40
|
+
"features/create.feature",
|
41
|
+
"features/destroy.feature",
|
42
|
+
"features/edit.feature",
|
43
|
+
"features/formats.feature",
|
44
|
+
"features/headers.feature",
|
45
|
+
"features/index.feature",
|
46
|
+
"features/layouts.feature",
|
47
|
+
"features/nested.feature",
|
48
|
+
"features/new.feature",
|
49
|
+
"features/only.feature",
|
50
|
+
"features/show.feature",
|
51
|
+
"features/steps/authenticated_steps.rb",
|
52
|
+
"features/steps/common_steps.rb",
|
53
|
+
"features/steps/create_steps.rb",
|
54
|
+
"features/steps/destroy_steps.rb",
|
55
|
+
"features/steps/edit_steps.rb",
|
56
|
+
"features/steps/format_steps.rb",
|
57
|
+
"features/steps/header_steps.rb",
|
58
|
+
"features/steps/index_steps.rb",
|
59
|
+
"features/steps/nested_steps.rb",
|
60
|
+
"features/steps/new_steps.rb",
|
61
|
+
"features/steps/only_steps.rb",
|
62
|
+
"features/steps/show_steps.rb",
|
63
|
+
"features/steps/update_steps.rb",
|
64
|
+
"features/support/env.rb",
|
65
|
+
"features/support/views/comments/index.erb",
|
66
|
+
"features/support/views/layout.erb",
|
67
|
+
"features/support/views/people/edit.erb",
|
68
|
+
"features/support/views/people/index.erb",
|
69
|
+
"features/support/views/people/layout.erb",
|
70
|
+
"features/support/views/people/new.erb",
|
71
|
+
"features/support/views/people/show.erb",
|
72
|
+
"features/update.feature",
|
73
|
+
"lib/core_ext/array.rb",
|
74
|
+
"lib/core_ext/hash.rb",
|
75
|
+
"lib/core_ext/module.rb",
|
76
|
+
"lib/core_ext/object.rb",
|
77
|
+
"lib/sinatras-hat.rb",
|
78
|
+
"lib/sinatras-hat/actions.rb",
|
79
|
+
"lib/sinatras-hat/authentication.rb",
|
80
|
+
"lib/sinatras-hat/extendor.rb",
|
81
|
+
"lib/sinatras-hat/hash_mutator.rb",
|
82
|
+
"lib/sinatras-hat/logger.rb",
|
83
|
+
"lib/sinatras-hat/maker.rb",
|
84
|
+
"lib/sinatras-hat/model.rb",
|
85
|
+
"lib/sinatras-hat/resource.rb",
|
86
|
+
"lib/sinatras-hat/responder.rb",
|
87
|
+
"lib/sinatras-hat/response.rb",
|
88
|
+
"lib/sinatras-hat/router.rb",
|
89
|
+
"sinatras-hat.gemspec",
|
90
|
+
"spec/actions/create_spec.rb",
|
91
|
+
"spec/actions/destroy_spec.rb",
|
92
|
+
"spec/actions/edit_spec.rb",
|
93
|
+
"spec/actions/index_spec.rb",
|
94
|
+
"spec/actions/new_spec.rb",
|
95
|
+
"spec/actions/show_spec.rb",
|
96
|
+
"spec/actions/update_spec.rb",
|
97
|
+
"spec/extendor_spec.rb",
|
98
|
+
"spec/fixtures/views/articles/edit.erb",
|
99
|
+
"spec/fixtures/views/articles/index.erb",
|
100
|
+
"spec/fixtures/views/articles/new.erb",
|
101
|
+
"spec/fixtures/views/articles/show.erb",
|
102
|
+
"spec/hash_mutator_spec.rb",
|
103
|
+
"spec/maker_spec.rb",
|
104
|
+
"spec/model_spec.rb",
|
105
|
+
"spec/resource_spec.rb",
|
106
|
+
"spec/responder_spec.rb",
|
107
|
+
"spec/response_spec.rb",
|
108
|
+
"spec/router_spec.rb",
|
109
|
+
"spec/spec_helper.rb"
|
110
|
+
]
|
111
|
+
s.homepage = %q{http://github.com/bradphelan/sinatras-hat}
|
112
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
113
|
+
s.require_paths = ["lib"]
|
114
|
+
s.rubygems_version = %q{1.3.5}
|
115
|
+
s.summary = %q{Easy peasy CRUD with sinatra}
|
116
|
+
s.test_files = [
|
117
|
+
"spec/actions/update_spec.rb",
|
118
|
+
"spec/actions/new_spec.rb",
|
119
|
+
"spec/actions/destroy_spec.rb",
|
120
|
+
"spec/actions/show_spec.rb",
|
121
|
+
"spec/actions/index_spec.rb",
|
122
|
+
"spec/actions/edit_spec.rb",
|
123
|
+
"spec/actions/create_spec.rb",
|
124
|
+
"spec/extendor_spec.rb",
|
125
|
+
"spec/resource_spec.rb",
|
126
|
+
"spec/router_spec.rb",
|
127
|
+
"spec/response_spec.rb",
|
128
|
+
"spec/maker_spec.rb",
|
129
|
+
"spec/model_spec.rb",
|
130
|
+
"spec/responder_spec.rb",
|
131
|
+
"spec/hash_mutator_spec.rb",
|
132
|
+
"spec/spec_helper.rb"
|
133
|
+
]
|
134
|
+
|
135
|
+
if s.respond_to? :specification_version then
|
136
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
137
|
+
s.specification_version = 3
|
138
|
+
|
139
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
140
|
+
else
|
141
|
+
end
|
142
|
+
else
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|