coast 0.9.1 → 0.9.3

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.
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Nathan Hopkins
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,186 @@
1
+ # Coast
2
+
3
+ ## Providing resourceful behavior for [Rails controllers](http://guides.rubyonrails.org/action_controller_overview.html)
4
+
5
+ ![Coast GEM](http://hopsoft.github.com/coast/images/coast.png)
6
+
7
+ ### ...if only the REST of life were this easy
8
+
9
+ Simply include the Coast module in your controller and get these actions for free.
10
+
11
+ `new` `edit` `index` `show` `create` `update` `destroy`
12
+
13
+ But wait... there's more.
14
+
15
+ * **Lightweight** - about 200 lines of code... *you can grok it in 5 minutes by skimming lib/coast.rb*
16
+ * **Unobtrusive** - no monkey patches
17
+ * **Flexible** - support for html, xml, and json formats
18
+ * **Familiar** - simple DSL for hooking into action callbacks
19
+ * **Secure** - implicit authorization with your favorite libs... *such as [CanCan](https://github.com/ryanb/cancan)*
20
+
21
+ ### Works best when you stick to [Rails conventions](http://guides.rubyonrails.org/getting_started.html)
22
+
23
+ ## Quick-start for the lazy
24
+
25
+ Assume you have a simple app structure for beach bums.
26
+
27
+ ```bash
28
+ app/controllers/beach_bums_controller.rb
29
+ app/models/beach_bum.rb
30
+ ```
31
+
32
+ Install the GEM.
33
+
34
+ ```bash
35
+ $gem install coast
36
+ ```
37
+
38
+ Tweak some files.
39
+
40
+ ```ruby
41
+ # config/routes.rb
42
+ Beach::Application.routes.draw do
43
+ resources :beach_bums
44
+ end
45
+ ```
46
+
47
+ ```ruby
48
+ # app/controllers/beach_bums_controller.rb
49
+ class BeachBumsController < ApplicationController
50
+ include Coast
51
+ end
52
+ ```
53
+
54
+ Congratulations... you now have a RESTful API for **beach bums**.
55
+
56
+ ## Callbacks
57
+
58
+ Coast uses a [Sinatra](http://www.sinatrarb.com/) like DSL to provide hooks into the action lifecycle.
59
+
60
+ The following hooks are supported for each action.
61
+
62
+ * `before` *- before any other action logic is performed... just like a [Rails before_filter](http://guides.rubyonrails.org/action_controller_overview.html#filters)*
63
+ * `respond_to` *- after authorization and db work but before rendering or redirecting*
64
+ * `after` *- after all other action logic is performed... just like a [Rails after_filter](http://guides.rubyonrails.org/action_controller_overview.html#filters)*
65
+
66
+ ### How to use the callbacks
67
+
68
+ ```ruby
69
+ # app/controllers/beach_bums_controller.rb
70
+ class BeachBumsController < ApplicationController
71
+ include Coast
72
+
73
+ before :show do
74
+ # take control and load a 'beach_bum' instead of letting Coast do it for us
75
+ @resourceful_item = BeachBum.find(params[:id])
76
+
77
+ # Coast will implicitly create an @beach_bum variable that references @resourceful_item
78
+ # cool eh?
79
+ end
80
+
81
+ respond_to :show do
82
+ # take control of rendering or redirecting instead of letting Coast do it for us
83
+ render :text => "Out surfing."
84
+ end
85
+
86
+ after :show do
87
+ # do some last minute housekeeping after every thing else is done
88
+ Rails.logger.info "Hey brah... we just completed the show action."
89
+ end
90
+
91
+ end
92
+ ```
93
+
94
+ ## Authorization
95
+
96
+ Coast implicitly calls an authorize method prior to executing any action logic.
97
+
98
+ You have complete control over this method. Here's an example.
99
+
100
+ ```ruby
101
+ # app/controllers/beach_bums_controller.rb
102
+ class BeachBumsController < ApplicationController
103
+ include Coast
104
+ set_authorize_method :authorize
105
+
106
+ def authorize(action, data, request)
107
+ # restrict all RESTful actions
108
+ raise "Unauthorized"
109
+ end
110
+
111
+ rescue_from Exception do |ex|
112
+ render :text => "Not Allowed", :status => 401
113
+ end
114
+ end
115
+ ```
116
+
117
+ Note the authorize method signature. The first arg is the **action** being performed. The second arg is the **record(s)** being operated on. The last arg is the **request** object.
118
+
119
+ While originally written to support [CanCan](https://github.com/ryanb/cancan), its pretty simple to take control and manage authorization yourself.
120
+
121
+ ## Advanced Usage
122
+
123
+ Coast comes with few tricks up its sleeve.
124
+
125
+ If your model and controller names deviate from Rails conventions, you can explicitly set the model like so.
126
+
127
+ ```ruby
128
+ # app/controllers/beach_bums_controller.rb
129
+ class BeachBumsController < ApplicationController
130
+ include Coast
131
+ set_resourceful_model SurferDude
132
+ end
133
+ ```
134
+
135
+ You can conditionally prevent mutating behavior on the server by setting an instance variable like so. *It's a little arcane, but that's on purpose.*
136
+
137
+ ```ruby
138
+ # app/controllers/beach_bums_controller.rb
139
+ class BeachBumsController < ApplicationController
140
+ include Coast
141
+
142
+ before :create do
143
+ # prevent the user from actually creating a record
144
+ @skip_db_create = true
145
+ end
146
+
147
+ before :update do
148
+ # prevent the user from actually saving a record
149
+ @skip_db_update = true
150
+ end
151
+
152
+ before :destroy do
153
+ # prevent the user from actually destroying a record
154
+ @skip_db_destroy = true
155
+ end
156
+
157
+ end
158
+ ```
159
+
160
+ ## Testing
161
+
162
+ There are some interesting additions to MiniTest::Mock since I mock some of Rails to make testing fast & fun.
163
+
164
+ Poke around the test code and let me know what you think.
165
+
166
+ How to run the tests.
167
+
168
+ ```bash
169
+ $rvm 1.9.3
170
+ $gem install bundler
171
+ $bundle
172
+ $rake test
173
+ ```
174
+
175
+ Ahh... passing tests.
176
+
177
+ ## Contributing
178
+
179
+ I'm looking for hand-outs, so please fork and submit pull requests. Bug fixes, features, whatever...
180
+
181
+ ## Nods
182
+
183
+ [I'm tired of writing RESTful boilerplate (& scaffold is overkill), so I'm stoked natehop released the Coast gem.](https://twitter.com/tehviking/status/189739333857710080)
184
+
185
+ -- Brandon Hayes, April 10, 2012
186
+
@@ -1,3 +1,8 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.require :default
4
+ require File.join(File.dirname(__FILE__), "coast", "version")
5
+
1
6
  # Makes any controller resourceful by providing the following actions:
2
7
  # * new
3
8
  # * edit
@@ -32,6 +37,14 @@
32
37
  module Coast
33
38
 
34
39
  module ClassMethods
40
+ def set_localized(arg)
41
+ @set_localized = arg
42
+ end
43
+ alias :localized= :set_localized
44
+
45
+ def localized?
46
+ @set_localized
47
+ end
35
48
 
36
49
  def set_authorize_method(arg)
37
50
  @authorize_method = arg
@@ -155,7 +168,7 @@ module Coast
155
168
  unless performed?
156
169
  respond_to do |format|
157
170
  if success
158
- flash[:notice] = "#{resourceful_model.name} was successfully created."
171
+ write_to_flash :notice, "#{resourceful_model.name} was successfully created."
159
172
  format.html { redirect_to(@resourceful_item) }
160
173
  format_json_and_xml(format, @resourceful_item, :status => :created, :location => @resourceful_item)
161
174
  else
@@ -177,7 +190,7 @@ module Coast
177
190
  unless performed?
178
191
  respond_to do |format|
179
192
  if success
180
- flash[:notice] = "#{resourceful_model.name} was successfully updated."
193
+ write_to_flash :notice, "#{resourceful_model.name} was successfully updated."
181
194
  format.html { redirect_to(@resourceful_item) }
182
195
  format_json_and_xml(format, @resourceful_item)
183
196
  else
@@ -197,7 +210,7 @@ module Coast
197
210
  @resourceful_item.destroy unless @skip_db_destroy
198
211
  invoke_callback(:respond_to_destroy)
199
212
  unless performed?
200
- flash[:notice] = "#{resourceful_model.name} was successfully destroyed" if @resourceful_item.destroyed?
213
+ write_to_flash(:notice, "#{resourceful_model.name} was successfully destroyed.") if @resourceful_item.destroyed?
201
214
  respond_to do |format|
202
215
  format.html { redirect_to root_url }
203
216
  format_json_and_xml(format, @resourceful_item)
@@ -233,6 +246,15 @@ module Coast
233
246
 
234
247
  private
235
248
 
249
+ def write_to_flash(key, message)
250
+ if self.class.localized?
251
+ message_key = message.downcase.strip.gsub(/\W+$/, "").gsub(/\W/, "_")
252
+ flash[key] = I18n.translate(message_key)
253
+ else
254
+ flash[key] = message
255
+ end
256
+ end
257
+
236
258
  def invoke_callback(name)
237
259
  send(name) if respond_to?(name)
238
260
  end
@@ -0,0 +1,3 @@
1
+ module Coast
2
+ VERSION = "0.9.3"
3
+ end
@@ -0,0 +1,248 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.require(:default, :test)
4
+ require "active_support/all"
5
+ require File.join(File.dirname(__FILE__), "..", "lib", "coast")
6
+
7
+ class TestCoast < MicroTest::Test
8
+
9
+ RESTFUL_METHODS = %w(index show new edit create update destroy)
10
+ ITEM_METHODS = %w(show new edit create update destroy)
11
+ UI_METHODS = %w(new edit)
12
+ READ_METHODS = %w(index show)
13
+ MUTATE_METHODS = %w(create update destroy)
14
+
15
+ # Creates a mock model instance [ActiveRecord::Base].
16
+ def self.mock_model
17
+ mock = MicroMock.make.new
18
+ mock.stub(:destroy) { @destroyed = true }
19
+ mock.stub(:destroyed?) { @destroyed }
20
+ mock.stub(:update_attributes) { |*args| @attributes_updated = true }
21
+ mock.stub(:save) { |*args| @saved = true }
22
+ mock.stub(:table_name) { "mocks" }
23
+ mock.class.stub(:find) { |*args| TestCoast.mock_model }
24
+ mock.class.stub(:all) { [1..5].map { TestCoast.mock_model } }
25
+ mock
26
+ end
27
+
28
+ # Creates a mock request instance [ActionDispatch::Request].
29
+ def self.mock_request
30
+ mock = MicroMock.make.new
31
+ mock.stub(:request) { @request ||= MicroMock.make.new }
32
+ mock.stub(:params) { @params ||= {} }
33
+ mock.stub(:flash) { @flash ||= {} }
34
+ mock
35
+ end
36
+
37
+ # Creates a mock controller instance [ActionController::Base].
38
+ def self.mock_controller
39
+ mock = MicroMock.make.new
40
+ mock.class.send :include, Coast
41
+ mock.stub(:authorize!) { |*args| @authorize_invoked = true }
42
+ mock.stub(:authorize_invoked?) { @authorize_invoked }
43
+ mock.stub(:respond_to) { |&block| @responded = true; block.call(format) }
44
+ mock.stub(:responded?) { @responded }
45
+ mock.stub(:render) { |*args| @performed = @rendered = true }
46
+ mock.stub(:performed?) { @performed }
47
+ mock.stub(:rendered?) { @rendered }
48
+ mock.stub(:redirect_to) { |*args| @redirected = true; render }
49
+ mock.stub(:redirected?) { @redirected }
50
+ mock.stub(:request) { @request ||= TestCoast.mock_request }
51
+ mock.stub(:params) { request.params }
52
+ mock.stub(:flash) { request.flash }
53
+ mock.stub(:format) { @format ||= TestCoast.mock_format }
54
+ mock.stub(:root_url) { "/" }
55
+ mock
56
+ end
57
+
58
+ # Creates a mock format instance [ActionController::MimeResponds::Collector].
59
+ def self.mock_format
60
+ mock = MicroMock.make.new
61
+ mock.stub(:html) { |&block| @html = true; block.call if block }
62
+ mock.stub(:xml) { |&block| @xml = true; block.call if block }
63
+ mock.stub(:json) { |&block| @json = true; block.call if block }
64
+ mock
65
+ end
66
+
67
+ before do
68
+ @model = TestCoast.mock_model
69
+ @controller = TestCoast.mock_controller
70
+ @controller.class.set_resourceful_model @model.class
71
+ end
72
+
73
+ test ".set_localized" do
74
+ @controller.class.set_localized true
75
+ assert @controller.class.localized?
76
+ end
77
+
78
+ test ".localized=" do
79
+ @controller.class.localized = true
80
+ assert @controller.class.localized?
81
+ end
82
+
83
+ test ".set_authorize_method" do
84
+ @controller.class.set_authorize_method :authorize!
85
+ assert @controller.class.authorize_method == :authorize!
86
+ end
87
+
88
+ test ".authorize=" do
89
+ @controller.class.authorize_method = :authorize!
90
+ assert @controller.class.authorize_method == :authorize!
91
+ end
92
+
93
+ test ".set_resourceful_model" do
94
+ model = Object.new
95
+ @controller.class.set_resourceful_model model
96
+ assert @controller.class.resourceful_model == model
97
+ end
98
+
99
+ test ".resourceful_model=" do
100
+ model = Object.new
101
+ @controller.class.resourceful_model = model
102
+ assert @controller.class.resourceful_model == model
103
+ end
104
+
105
+ test "set before callbacks" do
106
+ RESTFUL_METHODS.each do |method|
107
+ assert !@controller.respond_to?("before_#{method}")
108
+ @controller.class.before(method) {}
109
+ assert @controller.respond_to?("before_#{method}")
110
+ end
111
+ end
112
+
113
+ test "set respond_to callbacks" do
114
+ RESTFUL_METHODS.each do |method|
115
+ assert !@controller.respond_to?("respond_to_#{method}")
116
+ @controller.class.respond_to(method) {}
117
+ assert @controller.respond_to?("respond_to_#{method}")
118
+ end
119
+ end
120
+
121
+ test "set after callbacks" do
122
+ RESTFUL_METHODS.each do |method|
123
+ assert !@controller.respond_to?("after_#{method}")
124
+ @controller.class.after(method) {}
125
+ assert @controller.respond_to?("after_#{method}")
126
+ end
127
+ end
128
+
129
+ test "RESTful methods exist" do
130
+ RESTFUL_METHODS.each do |method|
131
+ assert @controller.respond_to?(method)
132
+ end
133
+ end
134
+
135
+ test "<create> flash message" do
136
+ @controller.create
137
+ assert @controller.flash[:notice].ends_with?("was successfully created.")
138
+ end
139
+
140
+ test "<create> localized flash message" do
141
+ @controller.class.localized = true
142
+ @controller.create
143
+ assert @controller.flash[:notice] =~ /translation missing: .+was_successfully_created/
144
+ end
145
+
146
+ test "<update> flash message" do
147
+ @controller.update
148
+ assert @controller.flash[:notice].ends_with?("was successfully updated.")
149
+ end
150
+
151
+ test "<update> localized flash message" do
152
+ @controller.class.localized = true
153
+ @controller.update
154
+ assert @controller.flash[:notice] =~ /translation missing: .+was_successfully_updated/
155
+ end
156
+
157
+ test "<destroy> flash message" do
158
+ @controller.destroy
159
+ assert @controller.flash[:notice].ends_with?("was successfully destroyed.")
160
+ end
161
+
162
+ test "<destroy> localized flash message" do
163
+ @controller.class.localized = true
164
+ @controller.destroy
165
+ assert @controller.flash[:notice] =~ /translation missing: .+was_successfully_destroyed/
166
+ end
167
+
168
+ RESTFUL_METHODS.each do |method|
169
+
170
+ test "<#{method}> responds and renders" do
171
+ @controller.send(method)
172
+ assert @controller.responded?
173
+ assert @controller.rendered?
174
+ end
175
+
176
+ test "<#{method}> renders for the formats html, xml, json" do
177
+ @controller.send(method)
178
+ assert(@controller.format.instance_eval { @html })
179
+ assert(@controller.format.instance_eval { @xml })
180
+ assert(@controller.format.instance_eval { @json })
181
+ end
182
+
183
+ test "<#{method}> invokes before, respond_to, after callbacks" do
184
+ callbacks = []
185
+ @controller.class.before(method) { callbacks << :before }
186
+ @controller.class.respond_to(method) { callbacks << :respond_to }
187
+ @controller.class.after(method) { callbacks << :after }
188
+ @controller.send(method)
189
+ assert callbacks.include?(:before)
190
+ assert callbacks.include?(:respond_to)
191
+ assert callbacks.include?(:after)
192
+ end
193
+
194
+ test "<#{method}> allows :respond_to callback to perform the render" do
195
+ @controller.class.respond_to(method) { @performed = true }
196
+ @controller.send(method)
197
+ assert @controller.performed?
198
+ assert !@controller.responded?
199
+ end
200
+
201
+ test "<#{method}> invokes the authorize_method when set" do
202
+ @controller.class.authorize_method = :authorize!
203
+ @controller.send(method)
204
+ assert @controller.authorize_invoked?
205
+ end
206
+
207
+ end
208
+
209
+ ITEM_METHODS.each do |method|
210
+ test "<#{method}> allows :before callback to set the resourceful_item" do
211
+ item = TestCoast.mock_model
212
+ @controller.class.before(method) { @resourceful_item = item }
213
+ @controller.send(method)
214
+ assert @controller.instance_eval { @resourceful_item.object_id } == item.object_id
215
+ end
216
+
217
+ test "<#{method}> sets a custom named instance variable for the item" do
218
+ item = TestCoast.mock_model
219
+ @controller.class.before(method) { @resourceful_item = item }
220
+ @controller.send(method)
221
+ variable = @controller.instance_eval { instance_variable_get(item_instance_var_name) }
222
+ assert variable.object_id == item.object_id
223
+ end
224
+ end
225
+
226
+ MUTATE_METHODS.each do |method|
227
+ test "<#{method}> redirects" do
228
+ @controller.send(method)
229
+ assert @controller.redirected?
230
+ end
231
+ end
232
+
233
+ test "<index> allows :before callback to set the list" do
234
+ list = TestCoast.mock_model.class.all
235
+ @controller.class.before(:index) { @resourceful_list = list }
236
+ @controller.index
237
+ assert @controller.instance_eval{ @resourceful_list }.object_id == list.object_id
238
+ end
239
+
240
+ test "<index> sets a custom named instance variable for the item" do
241
+ list = TestCoast.mock_model.class.all
242
+ @controller.class.before(:index) { @resourceful_list = list }
243
+ @controller.index
244
+ variable = @controller.instance_eval { instance_variable_get(list_instance_var_name) }
245
+ assert variable.object_id == list.object_id
246
+ end
247
+
248
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-06 00:00:00.000000000 Z
12
+ date: 2012-11-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &2160361220 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,16 +21,104 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2160361220
25
- description: Resourceful behavior for Rails controllers with a Sinatra like DSL.
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: micro_test
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.3.0.rc4
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.3.0.rc4
46
+ - !ruby/object:Gem::Dependency
47
+ name: micro_mock
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.0.5
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.5
62
+ - !ruby/object:Gem::Dependency
63
+ name: pry
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: pry-stack_explorer
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: awesome_print
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Resourceful behavior for Rails controllers with a simple DSL.
26
111
  email:
27
- - nate.hop@gmail.com
112
+ - natehop@gmail.com
28
113
  executables: []
29
114
  extensions: []
30
115
  extra_rdoc_files: []
31
116
  files:
32
117
  - lib/coast.rb
33
- - spec/coast_spec.rb
118
+ - lib/coast/version.rb
119
+ - LICENSE.txt
120
+ - README.md
121
+ - test/test_coast.rb
34
122
  homepage: https://github.com/hopsoft/coast
35
123
  licenses:
36
124
  - MIT
@@ -52,9 +140,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
140
  version: '0'
53
141
  requirements: []
54
142
  rubyforge_project:
55
- rubygems_version: 1.8.10
143
+ rubygems_version: 1.8.23
56
144
  signing_key:
57
145
  specification_version: 3
58
- summary: Coast
146
+ summary: A small mixin for Rails controllers that provides restful behavior.
59
147
  test_files:
60
- - spec/coast_spec.rb
148
+ - test/test_coast.rb
149
+ has_rdoc:
@@ -1,245 +0,0 @@
1
- require "rubygems"
2
-
3
- # fix MiniTest issue with 1.9
4
- unless defined? Gem::Deprecate
5
- module Gem
6
- Deprecate = Module.new do
7
- include Deprecate
8
- end
9
- end
10
- end
11
-
12
- require "bundler/setup"
13
- require "minitest/autorun"
14
- require "active_support/all"
15
- require "turn"
16
- require "pry"
17
-
18
- dirname = File.dirname(__FILE__)
19
- require File.join(dirname, "mock")
20
- Dir.glob(File.join(dirname, "..", "lib", "*.rb")) { |f| require f }
21
- MODEL_PATH = File.join(dirname, "testable_model.rb")
22
- CONTROLLER_PATH = File.join(dirname, "testable_controller.rb")
23
- load MODEL_PATH
24
- load CONTROLLER_PATH
25
-
26
-
27
-
28
-
29
- describe Coast do
30
- RESTFUL_METHODS = %w(index show new edit create update destroy)
31
- ITEM_METHODS = %w(show new edit create update destroy)
32
- UI_METHODS = %w(new edit)
33
- READ_METHODS = %w(index show)
34
- MUTATE_METHODS = %w(create update destroy)
35
-
36
- # Resets the mock class defs.
37
- def reset
38
- Coast.send(:remove_const, :TestableController)
39
- Coast.send(:remove_const, :TestableModel)
40
- load MODEL_PATH
41
- load CONTROLLER_PATH
42
- Coast::TestableController.set_resourceful_model Coast::TestableModel
43
- end
44
-
45
- # class method tests ============================================================================
46
-
47
- describe :set_authorize_method do
48
- it "sets the method used to perform authorization checks" do
49
- reset
50
- Coast::TestableController.set_authorize_method :authorize!
51
- assert Coast::TestableController.authorize_method == :authorize!
52
- end
53
- end
54
-
55
- describe :authorize_method= do
56
- it "sets the method used to perform authorization checks" do
57
- reset
58
- Coast::TestableController.authorize_method = :authorize!
59
- assert Coast::TestableController.authorize_method == :authorize!
60
- end
61
- end
62
-
63
- describe :set_resourceful_model do
64
- it "sets the model that the controller manages" do
65
- reset
66
- model = Object.new
67
- Coast::TestableController.set_resourceful_model model
68
- assert Coast::TestableController.resourceful_model == model
69
- end
70
- end
71
-
72
- describe :resourceful_model= do
73
- it "sets the model that the controller manages" do
74
- reset
75
- model = Object.new
76
- Coast::TestableController.resourceful_model = model
77
- assert Coast::TestableController.resourceful_model == model
78
- end
79
- end
80
-
81
- def verify_callback_setter(event, action)
82
- reset
83
- Coast::TestableController.send(event, action, &(lambda {}))
84
- assert Coast::TestableController.new.respond_to?("#{event}_#{action}")
85
- end
86
-
87
- describe :before do
88
- it "stores a before callback for all RESTful actions" do
89
- RESTFUL_METHODS.each { |m| verify_callback_setter :before, m }
90
- end
91
- end
92
-
93
- describe :respond_to do
94
- it "stores a respond_to callback for all RESTful actions" do
95
- RESTFUL_METHODS.each { |m| verify_callback_setter :respond_to, m }
96
- end
97
- end
98
-
99
- describe :after do
100
- it "stores an after callback for all RESTful actions" do
101
- RESTFUL_METHODS.each { |m| verify_callback_setter :after, m }
102
- end
103
- end
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
- # instance method tests =========================================================================
116
-
117
-
118
- it "supports all RESTful methods" do
119
- reset
120
- controller = Coast::TestableController.new
121
- RESTFUL_METHODS.each { |m| controller.must_respond_to m }
122
- end
123
-
124
- # %w(index show new).each do |method|
125
- RESTFUL_METHODS.each do |method|
126
- describe "##{method}" do
127
- before do
128
- reset
129
- end
130
-
131
- it "responds and renders" do
132
- controller = Coast::TestableController.new
133
- controller.send(method)
134
- assert controller.responded?, "Did not respond"
135
- assert controller.rendered?, "Did not render"
136
- end
137
-
138
- it "renders for the formats html, xml, json" do
139
- controller = Coast::TestableController.new
140
- controller.send(method)
141
- assert controller.html, "Did not respond to the html format"
142
- assert controller.xml, "Did not respond to the xml format"
143
- assert controller.json, "Did not respond to the json format"
144
- end
145
-
146
- it "invokes the callbacks before, respond_to, after" do
147
- callbacks = []
148
-
149
- Coast::TestableController.class_eval do
150
- before(method) { callbacks << :before }
151
- respond_to(method) { callbacks << :respond_to }
152
- after(method) { callbacks << :after }
153
- end
154
-
155
- controller = Coast::TestableController.new
156
- controller.send(method)
157
- assert callbacks.include?(:before), "Did not invoke the before callback"
158
- assert callbacks.include?(:respond_to), "Did not invoke the respond_to callback"
159
- assert callbacks.include?(:after), "Did not invoke the after callback"
160
- end
161
-
162
- it "allows :respond_to callback to perform the render" do
163
- Coast::TestableController.respond_to(method) { @performed = true }
164
- controller = Coast::TestableController.new
165
- controller.send(method)
166
- assert controller.responded? == false, "Did not allow :respond_to callback to perform the render"
167
- end
168
-
169
- it "invokes the authorize_method when set" do
170
- Coast::TestableController.authorize_method = :authorize!
171
- controller = Coast::TestableController.new
172
- controller.send(:index)
173
- assert controller.authorize_invoked?, "Did not invoke the authorize_method"
174
- end
175
-
176
- end
177
- end
178
-
179
- ITEM_METHODS.each do |method|
180
- describe "##{method}" do
181
- before do
182
- reset
183
- end
184
-
185
- it "allows :before callback to set the item" do
186
- item = Object.new
187
- Coast::TestableController.before(:index) { @resourceful_item = item }
188
- controller = Coast::TestableController.new
189
- controller.index
190
- assert controller.instance_eval { @resourceful_item } == item, "Did not allow :before callback to set the resourceful_item"
191
- end
192
-
193
- it "sets a custom named instance variable for the item" do
194
- item = Object.new
195
- Coast::TestableController.before(:index) { @resourceful_item = item }
196
- controller = Coast::TestableController.new
197
- controller.index
198
- variable = controller.instance_eval { instance_variable_get(item_instance_var_name) }
199
- assert variable != nil, "Did not set a custom instance variable for the item"
200
- assert variable == item, "Did not set a custom instance variable for the item to the correct value"
201
- end
202
-
203
- end
204
- end
205
-
206
- MUTATE_METHODS.each do |method|
207
- describe "##{method}" do
208
- before do
209
- reset
210
- end
211
-
212
- it "redirects" do
213
- controller = Coast::TestableController.new
214
- controller.send(method)
215
- assert controller.redirected?, "Did not redirect"
216
- end
217
- end
218
- end
219
-
220
-
221
- describe "#index" do
222
- before do
223
- reset
224
- end
225
-
226
- it "allows :before callback to set the list" do
227
- list = [ Object.new ]
228
- Coast::TestableController.before(:index) { @resourceful_list = list }
229
- controller = Coast::TestableController.new
230
- controller.index
231
- assert controller.instance_eval { @resourceful_list } == list, "Did not allow :before callback to set the resourceful_list"
232
- end
233
-
234
- it "sets a custom named instance variable for the item" do
235
- list = [ Object.new ]
236
- Coast::TestableController.before(:index) { @resourceful_list = list }
237
- controller = Coast::TestableController.new
238
- controller.index
239
- variable = controller.instance_eval { instance_variable_get(list_instance_var_name) }
240
- assert variable != nil, "Did not set a custom instance variable for the item"
241
- assert variable == list, "Did not set a custom instance variable for the item to the correct value"
242
- end
243
- end
244
-
245
- end