apipie-rails 0.0.19 → 0.0.20

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -2,6 +2,14 @@
2
2
  Changelog
3
3
  ===========
4
4
 
5
+ v0.0.20
6
+ -------
7
+
8
+ * namespaced resources - prevent collisions when one resource defined
9
+ in more modules
10
+ * ``Apipie::DSL::Concern`` for being able to use the DSL in module
11
+ that is included into controllers
12
+
5
13
  v0.0.19
6
14
  -------
7
15
 
data/README.rst CHANGED
@@ -371,6 +371,85 @@ with ``allow_nil`` set explicitly don't have this value changed.
371
371
  Action awareness is being inherited from ancestors (in terms of
372
372
  nested params).
373
373
 
374
+ Concerns
375
+ --------
376
+
377
+ Sometimes, the actions are not defined in the controller class
378
+ directly but included from a module instead. You can load the Apipie
379
+ DSL into the module by extending it with ``Apipie::DSL::Concern``.
380
+
381
+ The module can be used in more controllers. Therefore there is a way
382
+ how to substitute parts of the documentation in the module with controller
383
+ specific values. The substitutions can be stated explicitly with
384
+ ``apipie_concern_subst(:key => "value")`` (needs to be called before
385
+ the module is included to take effect). The substitutions are
386
+ performed in paths and descriptions of APIs and names and descriptions
387
+ of params.
388
+
389
+ There are some default substitutions available:
390
+
391
+ :controller_path
392
+ value of ``controller.controller_path``, e.g. ``api/users`` for
393
+ ``Api::UsersController``
394
+
395
+ :resource_id
396
+ Apipie identifier of the resource, e.g. ``users`` for
397
+ ``Api::UsersController`` or set by ``resource_id``
398
+
399
+ Example
400
+ ~~~~~~~
401
+
402
+ .. code:: ruby
403
+
404
+ # users_module.rb
405
+ module UsersModule
406
+ extend Apipie::DSL::Concern
407
+
408
+ api :GET, '/:controller_path', 'List :resource_id'
409
+ def index
410
+ # ...
411
+ end
412
+
413
+ api :GET, '/:resource_id/:id', 'Show a :resource'
414
+ def show
415
+ # ...
416
+ end
417
+
418
+ api :POST, '/:resource_id', "Create a :resource"
419
+ param :concern, Hash, :required => true
420
+ param :name, String, 'Name of a :resource'
421
+ param :resource_type, ['standard','vip']
422
+ end
423
+ def create
424
+ # ...
425
+ end
426
+
427
+ api :GET, '/:resource_id/:custom_subst'
428
+ def custom
429
+ # ...
430
+ end
431
+ end
432
+
433
+ # users_controller.rb
434
+ class UsersController < ApplicationController
435
+
436
+ resource_description { resource_id 'customers' }
437
+
438
+ apipie_concern_subst(:custom_subst => 'custom', :resource => 'customer')
439
+ include UsersModule
440
+
441
+ # the following paths are documented
442
+ # api :GET, '/users'
443
+ # api :GET, '/customers/:id', 'Show a customer'
444
+ # api :POST, '/customers', 'Create a customer'
445
+ # param :customer, :required => true do
446
+ # param :name, String, 'Name of a customer'
447
+ # param :customer_type, ['standard', 'vip']
448
+ # end
449
+ # api :GET, '/customers/:custom'
450
+ end
451
+
452
+
374
453
 
375
454
  =========================
376
455
  Configuration Reference
@@ -427,6 +506,10 @@ ignored
427
506
  to be ignored when generationg the documentation
428
507
  e.g. ``%w[Api::CommentsController Api::PostsController#post]``
429
508
 
509
+ namespaced_resources
510
+ Use controller paths instead of controller names as resource id.
511
+ This prevents same named controllers overwriting each other.
512
+
430
513
 
431
514
  Example:
432
515
 
@@ -94,12 +94,12 @@ module Apipie
94
94
  end
95
95
 
96
96
  def add_param_group(controller, name, &block)
97
- key = "#{controller.controller_path}##{name}"
97
+ key = "#{controller.name}##{name}"
98
98
  @param_groups[key] = block
99
99
  end
100
100
 
101
101
  def get_param_group(controller, name)
102
- key = "#{controller.controller_path}##{name}"
102
+ key = "#{controller.name}##{name}"
103
103
  if @param_groups.has_key?(key)
104
104
  return @param_groups[key]
105
105
  else
@@ -276,6 +276,10 @@ module Apipie
276
276
  klass
277
277
  elsif @controller_to_resource_id.has_key?(klass)
278
278
  @controller_to_resource_id[klass]
279
+ elsif Apipie.configuration.namespaced_resources? && klass.respond_to?(:controller_path)
280
+ return nil if klass == ActionController::Base
281
+ path = klass.controller_path
282
+ path.gsub(version_prefix(klass), "").gsub("/", "-")
279
283
  elsif klass.respond_to?(:controller_name)
280
284
  return nil if klass == ActionController::Base
281
285
  klass.controller_name
@@ -286,6 +290,12 @@ module Apipie
286
290
 
287
291
  private
288
292
 
293
+ def version_prefix(klass)
294
+ version = controller_versions(klass).first
295
+ path = Apipie.configuration.api_base_url[version]
296
+ path[1..-1] + "/"
297
+ end
298
+
289
299
  def get_resource_version(resource_description)
290
300
  if resource_description.respond_to? :_version
291
301
  resource_description._version
@@ -3,10 +3,11 @@ module Apipie
3
3
 
4
4
  attr_accessor :app_name, :app_info, :copyright, :markup, :disqus_shortname,
5
5
  :validate, :api_base_url, :doc_base_url, :required_by_default, :layout,
6
- :default_version, :debug, :version_in_url
6
+ :default_version, :debug, :version_in_url, :namespaced_resources
7
7
 
8
8
  alias_method :validate?, :validate
9
9
  alias_method :required_by_default?, :required_by_default
10
+ alias_method :namespaced_resources?, :namespaced_resources
10
11
 
11
12
  # matcher to be used in Dir.glob to find controllers to be reloaded e.g.
12
13
  #
@@ -107,6 +108,7 @@ module Apipie
107
108
  @default_version = "1.0"
108
109
  @debug = false
109
110
  @version_in_url = true
111
+ @namespaced_resources = false
110
112
  end
111
113
  end
112
114
  end
@@ -118,52 +118,6 @@ module Apipie
118
118
  Apipie.set_controller_versions(self, versions)
119
119
  end
120
120
 
121
- # create method api and redefine newly added method
122
- def method_added(method_name) #:doc:
123
- super
124
-
125
- if ! Apipie.active_dsl? || _apipie_dsl_data[:api_args].blank?
126
- _apipie_dsl_data_clear
127
- return
128
- end
129
-
130
- begin
131
- # remove method description if exists and create new one
132
- Apipie.remove_method_description(self, _apipie_dsl_data[:api_versions], method_name)
133
- description = Apipie.define_method_description(self, method_name, _apipie_dsl_data)
134
- ensure
135
- _apipie_dsl_data_clear
136
- end
137
-
138
- # redefine method only if validation is turned on
139
- if description && Apipie.configuration.validate == true
140
-
141
- old_method = instance_method(method_name)
142
-
143
- define_method(method_name) do |*args|
144
-
145
- if Apipie.configuration.validate == true
146
- description.params.each do |_, param|
147
-
148
- # check if required parameters are present
149
- if param.required && !params.has_key?(param.name)
150
- raise ParamMissing.new(param.name)
151
- end
152
-
153
- # params validations
154
- if params.has_key?(param.name)
155
- param.validate(params[:"#{param.name}"])
156
- end
157
-
158
- end
159
- end
160
-
161
- # run the original method code
162
- old_method.bind(self).call(*args)
163
- end
164
-
165
- end
166
- end # def method_added
167
121
  end
168
122
 
169
123
  module Common
@@ -213,6 +167,38 @@ module Apipie
213
167
  _apipie_dsl_data[:errors] << args
214
168
  end
215
169
 
170
+ def _apipie_define_validators(description)
171
+ # redefine method only if validation is turned on
172
+ if description && Apipie.configuration.validate == true
173
+
174
+ old_method = instance_method(description.method)
175
+
176
+ define_method(description.method) do |*args|
177
+
178
+ if Apipie.configuration.validate == true
179
+ description.params.each do |_, param|
180
+
181
+ # check if required parameters are present
182
+ if param.required && !params.has_key?(param.name)
183
+ raise ParamMissing.new(param.name)
184
+ end
185
+
186
+ # params validations
187
+ if params.has_key?(param.name)
188
+ param.validate(params[:"#{param.name}"])
189
+ end
190
+
191
+ end
192
+ end
193
+
194
+ # run the original method code
195
+ old_method.bind(self).call(*args)
196
+ end
197
+
198
+ end
199
+
200
+ end
201
+
216
202
  end
217
203
 
218
204
  # this describes the params, it's in separate module because it's
@@ -261,6 +247,111 @@ module Apipie
261
247
  end
262
248
  end
263
249
 
250
+ module Controller
251
+ include Apipie::DSL::Base
252
+ include Apipie::DSL::Common
253
+ include Apipie::DSL::Action
254
+ include Apipie::DSL::Param
255
+
256
+ # defines the substitutions to be made in the API paths deifned
257
+ # in concerns included. For example:
258
+ #
259
+ # There is this method defined in concern:
260
+ #
261
+ # api GET ':controller_path/:id'
262
+ # def show
263
+ # # ...
264
+ # end
265
+ #
266
+ # If you include the concern into some controller, you can
267
+ # specify the value for :controller_path like this:
268
+ #
269
+ # apipie_concern_subst(:controller_path => '/users')
270
+ # include ::Concerns::SampleController
271
+ #
272
+ # The resulting path will be '/users/:id'.
273
+ #
274
+ # It has to be specified before the concern is included.
275
+ #
276
+ # If not specified, the default predefined substitions are
277
+ #
278
+ # {:conroller_path => controller.controller_path,
279
+ # :resource_id => `resource_id_from_apipie` }
280
+ def apipie_concern_subst(subst_hash)
281
+ _apipie_concern_subst.merge!(subst_hash)
282
+ end
283
+
284
+ def _apipie_concern_subst
285
+ @_apipie_concern_subst ||= {:controller_path => self.controller_path,
286
+ :resource_id => Apipie.get_resource_name(self)}
287
+ end
288
+
289
+ def _apipie_perform_concern_subst(string)
290
+ return _apipie_concern_subst.reduce(string) do |ret, (key, val)|
291
+ ret.gsub(":#{key}", val)
292
+ end
293
+ end
294
+
295
+ # create method api and redefine newly added method
296
+ def method_added(method_name) #:doc:
297
+ super
298
+
299
+ if ! Apipie.active_dsl? || _apipie_dsl_data[:api_args].blank?
300
+ _apipie_dsl_data_clear
301
+ return
302
+ end
303
+
304
+ begin
305
+ # remove method description if exists and create new one
306
+ Apipie.remove_method_description(self, _apipie_dsl_data[:api_versions], method_name)
307
+ description = Apipie.define_method_description(self, method_name, _apipie_dsl_data)
308
+ ensure
309
+ _apipie_dsl_data_clear
310
+ end
311
+
312
+ _apipie_define_validators(description)
313
+ end # def method_added
314
+ end
315
+
316
+ module Concern
317
+ include Apipie::DSL::Base
318
+ include Apipie::DSL::Common
319
+ include Apipie::DSL::Action
320
+ include Apipie::DSL::Param
321
+
322
+ # the concern was included into a controller
323
+ def included(controller)
324
+ super
325
+ _apipie_concern_data.each do |method_name, _apipie_dsl_data|
326
+ # remove method description if exists and create new one
327
+ description = Apipie.define_method_description(controller, method_name, _apipie_dsl_data)
328
+ controller._apipie_define_validators(description)
329
+ end
330
+ end
331
+
332
+ def _apipie_concern_data
333
+ @_apipie_concern_data ||= []
334
+ end
335
+
336
+ # create method api and redefine newly added method
337
+ def method_added(method_name) #:doc:
338
+ super
339
+
340
+ if ! Apipie.active_dsl? || _apipie_dsl_data[:api_args].blank?
341
+ _apipie_dsl_data_clear
342
+ return
343
+ end
344
+
345
+ begin
346
+ _apipie_concern_data << [method_name, _apipie_dsl_data.merge(:from_concern => true)]
347
+ ensure
348
+ _apipie_dsl_data_clear
349
+ end
350
+
351
+ end # def method_added
352
+
353
+ end
354
+
264
355
  class ResourceDescriptionDsl
265
356
  include Apipie::DSL::Base
266
357
  include Apipie::DSL::Common
@@ -271,7 +362,6 @@ module Apipie
271
362
  @controller = controller
272
363
  end
273
364
 
274
-
275
365
  def _eval_dsl(&block)
276
366
  instance_eval(&block)
277
367
  return _apipie_dsl_data
@@ -20,9 +20,10 @@ module Apipie
20
20
  def initialize(method, resource, dsl_data)
21
21
  @method = method.to_s
22
22
  @resource = resource
23
+ @from_concern = dsl_data[:from_concern]
23
24
 
24
25
  @apis = dsl_data[:api_args].map do |method, path, desc|
25
- MethodDescription::Api.new(method, path, desc)
26
+ MethodDescription::Api.new(method, concern_subst(path), concern_subst(desc))
26
27
  end
27
28
 
28
29
  desc = dsl_data[:description] || ''
@@ -137,6 +138,11 @@ module Apipie
137
138
  }
138
139
  end
139
140
 
141
+ # was the description defines in a module instead of directly in controller?
142
+ def from_concern?
143
+ @from_concern
144
+ end
145
+
140
146
  private
141
147
 
142
148
  def merge_params(params, new_params)
@@ -171,6 +177,15 @@ module Apipie
171
177
  example
172
178
  end
173
179
 
180
+ def concern_subst(string)
181
+ return if string.nil?
182
+ if from_concern?
183
+ resource.controller._apipie_perform_concern_subst(string)
184
+ else
185
+ string
186
+ end
187
+ end
188
+
174
189
  end
175
190
 
176
191
  end
@@ -38,8 +38,8 @@ module Apipie
38
38
  @options = options
39
39
 
40
40
  @method_description = method_description
41
- @name = name
42
- @desc = Apipie.markup_to_html(@options[:desc] || '')
41
+ @name = concern_subst(name)
42
+ @desc = concern_subst(Apipie.markup_to_html(@options[:desc] || ''))
43
43
  @parent = @options[:parent]
44
44
  @required = if @options.has_key? :required
45
45
  @options[:required]
@@ -179,6 +179,19 @@ module Apipie
179
179
  end
180
180
  end
181
181
 
182
+ def concern_subst(string)
183
+ return if string.nil?
184
+ original = string
185
+ if method_description.from_concern?
186
+ string = ":#{original}" if original.is_a? Symbol
187
+ ret = method_description.resource.controller._apipie_perform_concern_subst(string)
188
+ ret = ret.to_sym if original.is_a? Symbol
189
+ ret
190
+ else
191
+ string
192
+ end
193
+ end
194
+
182
195
  end
183
196
 
184
197
  end
@@ -2,10 +2,7 @@ module Apipie
2
2
  class Railtie < Rails::Railtie
3
3
  initializer 'apipie.controller_additions' do
4
4
  ActiveSupport.on_load :action_controller do
5
- extend Apipie::DSL::Base
6
- extend Apipie::DSL::Common
7
- extend Apipie::DSL::Action
8
- extend Apipie::DSL::Param
5
+ extend Apipie::DSL::Controller
9
6
  end
10
7
  end
11
8
  end
@@ -1,3 +1,3 @@
1
1
  module Apipie
2
- VERSION = '0.0.19'
2
+ VERSION = '0.0.20'
3
3
  end
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+
3
+ describe ConcernsController do
4
+
5
+ it "displays is every controller the concern is included" do
6
+ Apipie["concern_resources#index"].should be
7
+ Apipie["concern_resources#show"].should be
8
+ end
9
+
10
+ it "should reply to valid request" do
11
+ get :show, :id => '5', :session => "secret_hash"
12
+ assert_response :success
13
+ end
14
+
15
+ it "should pass if required parameter is missing" do
16
+ lambda { get :show, :id => 5 }.should_not raise_error
17
+ end
18
+
19
+ it "peserved the order of methods being defined in file" do
20
+ doc_methods = Apipie.get_resource_description('concern_resources')._methods.keys
21
+ doc_methods.should == [:index, :show, :create, :update, :custom]
22
+ end
23
+
24
+ it "replaces a placeholder doc specified in concern with a real path" do
25
+ path = Apipie["concern_resources#index"].apis.first.path
26
+ path.should == '/concerns'
27
+
28
+ path = Apipie["concern_resources#show"].apis.first.path
29
+ path.should == '/concern_resources/:id'
30
+
31
+ path = Apipie["concern_resources#custom"].apis.first.path
32
+ path.should == '/concern_resources/custom'
33
+ end
34
+
35
+ it "replaces placeholders in param names and descriptions" do
36
+ create_desc = Apipie["concern_resources#create"].params[:user]
37
+ name_param, concern_type_param = create_desc.validator.hash_params_ordered
38
+ name_param.desc.should include "Name of a user"
39
+ concern_type_param.name.should == :user_type
40
+ end
41
+ end
42
+
@@ -0,0 +1,30 @@
1
+ module Api
2
+ module V2
3
+ class Nested::ArchitecturesController < V2::BaseController
4
+ resource_description { name 'Architectures' }
5
+ api :GET, "/nested/architectures/", "List all nested architectures."
6
+ def index
7
+ end
8
+
9
+ api :GET, "/nested/architectures/:id/", "Show a nested architecture."
10
+ def show
11
+ end
12
+
13
+ api :POST, "/nested/architectures/", "Create a nested architecture."
14
+ param_group :arch, Api::V1::ArchitecturesController
15
+ def create
16
+ end
17
+
18
+ api :PUT, "/nested/architectures/:id/", "Update a nested architecture."
19
+ param :architecture, Hash, :required => true do
20
+ param :name, String
21
+ end
22
+ def update
23
+ end
24
+
25
+ api :DELETE, "/architecturess/:id/", "Delete a nested architecture."
26
+ def destroy
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,39 @@
1
+ module Concerns::SampleController
2
+ extend Apipie::DSL::Concern
3
+
4
+ api :GET, '/:controller_path'
5
+ def index
6
+ render :text => "OK #{params.inspect}"
7
+ end
8
+
9
+ api :GET, '/:resource_id/:id'
10
+ param :id, String
11
+ def show
12
+ render :text => "OK #{params.inspect}"
13
+ end
14
+
15
+ def_param_group :concern do
16
+ param :concern, Hash, :required => true, :action_aware => true do
17
+ param :name, String, "Name of a :concern"
18
+ param :concern_type, String
19
+ end
20
+ end
21
+
22
+ api :POST, '/:resource_id', "Create a :concern"
23
+ param_group :concern
24
+ def create
25
+ render :text => "OK #{params.inspect}"
26
+ end
27
+
28
+ api :PUT, '/:resource_id/:id'
29
+ param :id, String
30
+ param_group :concern
31
+ def update
32
+ render :text => "OK #{params.inspect}"
33
+ end
34
+
35
+ api :GET, '/:resource_id/:custom_subst'
36
+ def custom
37
+ render :text => "OK #{params.inspect}"
38
+ end
39
+ end
@@ -0,0 +1,8 @@
1
+ class ConcernsController < ApplicationController
2
+
3
+ resource_description { resource_id 'concern_resources' }
4
+
5
+ apipie_concern_subst(:concern => 'user', :custom_subst => 'custom')
6
+ include ::Concerns::SampleController
7
+
8
+ end
@@ -1,9 +1,10 @@
1
1
  Dummy::Application.routes.draw do
2
2
 
3
3
  scope ENV['RAILS_RELATIVE_URL_ROOT'] || '/' do
4
-
4
+
5
5
  scope '/api' do
6
6
  resources :users
7
+ resources :concerns, :only => [:index, :show]
7
8
  resources :twitter_example do
8
9
  collection do
9
10
  get :lookup
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ describe Apipie::Application do
4
+
5
+ describe "get_resource_name" do
6
+ subject {Apipie.get_resource_name(Api::V2::Nested::ArchitecturesController)}
7
+ context "with namespaced_resources enabled" do
8
+ before { Apipie.configuration.namespaced_resources = true }
9
+
10
+ it "should not overwrite the parent resource" do
11
+ subject.should_not eq(Apipie.get_resource_name(Api::V2::ArchitecturesController))
12
+ end
13
+ end
14
+
15
+ context "with namespaced_resources enabled" do
16
+ before { Apipie.configuration.namespaced_resources = false }
17
+
18
+ it "should overwrite the the parent" do
19
+ subject.should eq(Apipie.get_resource_name(Api::V2::ArchitecturesController))
20
+ end
21
+ end
22
+ end
23
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apipie-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.19
4
+ version: 0.0.20
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-03-13 00:00:00.000000000 Z
13
+ date: 2013-03-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -198,6 +198,7 @@ files:
198
198
  - spec/controllers/api/v2/architectures_controller_spec.rb
199
199
  - spec/controllers/api/v2/nested/resources_controller_spec.rb
200
200
  - spec/controllers/apipies_controller_spec.rb
201
+ - spec/controllers/concerns_controller_spec.rb
201
202
  - spec/controllers/users_controller_spec.rb
202
203
  - spec/dummy/Rakefile
203
204
  - spec/dummy/app/controllers/api/base_controller.rb
@@ -205,8 +206,11 @@ files:
205
206
  - spec/dummy/app/controllers/api/v1/base_controller.rb
206
207
  - spec/dummy/app/controllers/api/v2/architectures_controller.rb
207
208
  - spec/dummy/app/controllers/api/v2/base_controller.rb
209
+ - spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb
208
210
  - spec/dummy/app/controllers/api/v2/nested/resources_controller.rb
209
211
  - spec/dummy/app/controllers/application_controller.rb
212
+ - spec/dummy/app/controllers/concerns/sample_controller.rb
213
+ - spec/dummy/app/controllers/concerns_controller.rb
210
214
  - spec/dummy/app/controllers/twitter_example_controller.rb
211
215
  - spec/dummy/app/controllers/users_controller.rb
212
216
  - spec/dummy/app/views/layouts/application.html.erb
@@ -240,6 +244,7 @@ files:
240
244
  - spec/dummy/public/javascripts/rails.js
241
245
  - spec/dummy/public/stylesheets/.gitkeep
242
246
  - spec/dummy/script/rails
247
+ - spec/lib/application_spec.rb
243
248
  - spec/lib/method_description_spec.rb
244
249
  - spec/lib/param_description_spec.rb
245
250
  - spec/lib/param_group_spec.rb
@@ -274,6 +279,7 @@ test_files:
274
279
  - spec/controllers/api/v2/architectures_controller_spec.rb
275
280
  - spec/controllers/api/v2/nested/resources_controller_spec.rb
276
281
  - spec/controllers/apipies_controller_spec.rb
282
+ - spec/controllers/concerns_controller_spec.rb
277
283
  - spec/controllers/users_controller_spec.rb
278
284
  - spec/dummy/Rakefile
279
285
  - spec/dummy/app/controllers/api/base_controller.rb
@@ -281,8 +287,11 @@ test_files:
281
287
  - spec/dummy/app/controllers/api/v1/base_controller.rb
282
288
  - spec/dummy/app/controllers/api/v2/architectures_controller.rb
283
289
  - spec/dummy/app/controllers/api/v2/base_controller.rb
290
+ - spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb
284
291
  - spec/dummy/app/controllers/api/v2/nested/resources_controller.rb
285
292
  - spec/dummy/app/controllers/application_controller.rb
293
+ - spec/dummy/app/controllers/concerns/sample_controller.rb
294
+ - spec/dummy/app/controllers/concerns_controller.rb
286
295
  - spec/dummy/app/controllers/twitter_example_controller.rb
287
296
  - spec/dummy/app/controllers/users_controller.rb
288
297
  - spec/dummy/app/views/layouts/application.html.erb
@@ -316,6 +325,7 @@ test_files:
316
325
  - spec/dummy/public/javascripts/rails.js
317
326
  - spec/dummy/public/stylesheets/.gitkeep
318
327
  - spec/dummy/script/rails
328
+ - spec/lib/application_spec.rb
319
329
  - spec/lib/method_description_spec.rb
320
330
  - spec/lib/param_description_spec.rb
321
331
  - spec/lib/param_group_spec.rb