Commit 48c7a14e1352c12068961b181196222d95aabc2c

Authored by Dan Croak
1 parent d3a8294d

added josevalim's inherited resources for RESTful controllers

Showing 35 changed files with 4937 additions and 0 deletions   Show diff stats
vendor/gems/josevalim-inherited_resources-0.8.5/.specification 0 → 100644
... ... @@ -0,0 +1,104 @@
  1 +--- !ruby/object:Gem::Specification
  2 +name: josevalim-inherited_resources
  3 +version: !ruby/object:Gem::Version
  4 + version: 0.8.5
  5 +platform: ruby
  6 +authors:
  7 +- "Jos\xC3\xA9 Valim"
  8 +autorequire:
  9 +bindir: bin
  10 +cert_chain: []
  11 +
  12 +date: 2009-07-24 00:00:00 -04:00
  13 +default_executable:
  14 +dependencies: []
  15 +
  16 +description: Inherited Resources speeds up development by making your controllers inherit all restful actions so you just have to focus on what is important.
  17 +email: jose.valim@gmail.com
  18 +executables: []
  19 +
  20 +extensions: []
  21 +
  22 +extra_rdoc_files:
  23 +- README
  24 +files:
  25 +- CHANGELOG
  26 +- MIT-LICENSE
  27 +- README
  28 +- Rakefile
  29 +- VERSION
  30 +- lib/inherited_resources.rb
  31 +- lib/inherited_resources/actions.rb
  32 +- lib/inherited_resources/base.rb
  33 +- lib/inherited_resources/base_helpers.rb
  34 +- lib/inherited_resources/belongs_to_helpers.rb
  35 +- lib/inherited_resources/class_methods.rb
  36 +- lib/inherited_resources/dumb_responder.rb
  37 +- lib/inherited_resources/has_scope_helpers.rb
  38 +- lib/inherited_resources/polymorphic_helpers.rb
  39 +- lib/inherited_resources/respond_to.rb
  40 +- lib/inherited_resources/singleton_helpers.rb
  41 +- lib/inherited_resources/url_helpers.rb
  42 +- test/respond_to_test.rb
  43 +- test/customized_belongs_to_test.rb
  44 +- test/nested_belongs_to_test.rb
  45 +- test/base_test.rb
  46 +- test/redirect_to_test.rb
  47 +- test/has_scope_test.rb
  48 +- test/class_methods_test.rb
  49 +- test/aliases_test.rb
  50 +- test/flash_test.rb
  51 +- test/url_helpers_test.rb
  52 +- test/base_helpers_test.rb
  53 +- test/belongs_to_test.rb
  54 +- test/polymorphic_test.rb
  55 +- test/defaults_test.rb
  56 +- test/singleton_test.rb
  57 +- test/optional_belongs_to_test.rb
  58 +- test/test_helper.rb
  59 +has_rdoc: true
  60 +homepage: http://github.com/josevalim/inherited_resources
  61 +licenses: []
  62 +
  63 +post_install_message:
  64 +rdoc_options:
  65 +- --charset=UTF-8
  66 +require_paths:
  67 +- lib
  68 +required_ruby_version: !ruby/object:Gem::Requirement
  69 + requirements:
  70 + - - ">="
  71 + - !ruby/object:Gem::Version
  72 + version: "0"
  73 + version:
  74 +required_rubygems_version: !ruby/object:Gem::Requirement
  75 + requirements:
  76 + - - ">="
  77 + - !ruby/object:Gem::Version
  78 + version: "0"
  79 + version:
  80 +requirements: []
  81 +
  82 +rubyforge_project: inherited_resources
  83 +rubygems_version: 1.3.4
  84 +signing_key:
  85 +specification_version: 3
  86 +summary: Inherited Resources speeds up development by making your controllers inherit all restful actions so you just have to focus on what is important.
  87 +test_files:
  88 +- test/respond_to_test.rb
  89 +- test/customized_belongs_to_test.rb
  90 +- test/nested_belongs_to_test.rb
  91 +- test/base_test.rb
  92 +- test/redirect_to_test.rb
  93 +- test/has_scope_test.rb
  94 +- test/class_methods_test.rb
  95 +- test/aliases_test.rb
  96 +- test/flash_test.rb
  97 +- test/url_helpers_test.rb
  98 +- test/base_helpers_test.rb
  99 +- test/belongs_to_test.rb
  100 +- test/polymorphic_test.rb
  101 +- test/defaults_test.rb
  102 +- test/singleton_test.rb
  103 +- test/optional_belongs_to_test.rb
  104 +- test/test_helper.rb
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/CHANGELOG 0 → 100644
... ... @@ -0,0 +1,95 @@
  1 +# Version 0.8
  2 +
  3 +* Fixed a small bug on optional belongs to with namespaced controllers.
  4 +* Allow a parameter to be given to collection_url in polymorphic cases to replace
  5 + the parent.
  6 +* Allow InheritedResources to be called without inheritance.
  7 +* Ensure that controllers that inherit from a controller with InheritedResources
  8 + works properly.
  9 +
  10 +# Version 0.7
  11 +
  12 +* Allow procs as default value in has scope to be able to use values from session, for example.
  13 +* Allow blocks with arity 0 or -1 to be given as the redirect url:
  14 +
  15 + def destroy
  16 + destroy!{ project_url(@project) }
  17 + end
  18 +
  19 +* Allow interpolation_options to be set in the application controller.
  20 +* Added has_scope to controller (an interface for named_scopes).
  21 +* Added polymorphic_belongs_to, optional_belongs_to and singleton_belongs_to
  22 + as quick methods.
  23 +* Only load belongs_to, singleton and polymorphic helpers if they are actually
  24 + required. base_helpers, class_methods, dumb_responder and url_helpers are loaded
  25 + when you inherited from base for the first time.
  26 +
  27 +# Version 0.6
  28 +
  29 +* Ensure that the default template is not rendered if the default_template_format
  30 + is not accepted. This is somehow related with the security breach report:
  31 +
  32 + http://www.rorsecurity.info/journal/2009/4/24/hidden-actions-render-templates.html
  33 +
  34 + IR forbids based on mime types. For example: respond_to :html, :except => :index
  35 + ensures that the index.html.erb view is not rendered, making your IR controllers
  36 + safer.
  37 +
  38 +* Fixed a bug that happens only when format.xml is given to blocks and then it
  39 + acts as default, instead of format.html.
  40 +* Fixed a strange bug where when you have create.html.erb or update.html.erb,
  41 + it makes IE6 and IE7 return unprocessable entity (because they send Mime::ALL).
  42 +* Stop rescueing any error when constantizing the resource class and allow
  43 + route_prefix to be nil.
  44 +* Cleaned up tests and responder structure. Whenever you pass a block to aliases
  45 + and this block responds to the request, the other blocks are not parsed improving performance.
  46 +* [BACKWARDS INCOMPATIBLE] By default, Inherited Resources respond only :html requests.
  47 +* Added a quick way to overwrite the redirect to url in :create, :update and :destroy.
  48 +
  49 +# Version 0.5
  50 +
  51 +* Decoupled routes name from :instance_name and :collection_name. This way we
  52 + have more flexibility. Use route_instance_name and route_collection_name to
  53 + to change routes.
  54 +* Avoid calling human_name on nil when a resource class is not defined.
  55 +* Only call I18n if it's defined.
  56 +
  57 +# Version 0.4
  58 +
  59 +* Dealing with namespaced controllers out of the box.
  60 +* Added support to namespaced routes through :route_prefix.
  61 +* Added fix when resource_url is not defined.
  62 +* Added better handling for namespaced controllers.
  63 +* Added flash messages scoped by namespaced controllers.
  64 +* Deprecated {{resource}} in I18n, use {{resource_name}} instead.
  65 +* rspec bug fix is not automatically required anymore. User has to do it
  66 + explicitly.
  67 +* Added a file which fix a rspec bug when render is called inside a method
  68 + which receives a block.
  69 +* parent? does not take begin_of_association_chain into account anymore
  70 +* Added options to url helpers.
  71 +* Added :optional to belongs_to associations. It allows you to deal with
  72 + categories/1/products/2 and /products/2 with just one controller.
  73 +* Cleaned up tests.
  74 +
  75 +# Version 0.3
  76 +
  77 +* Minor bump after three bug fixes.
  78 +* Bug fix when showing warning of constant redefinition.
  79 +* Bug fix with ApplicationController not being unloaded properly on development.
  80 +* Bug fix when having root singleton resources. Calling collection_url would
  81 + raise "NoMethodError _url", not it will call root_url.
  82 +* More comments on UrlHelpers.
  83 +
  84 +# Version 0.2
  85 +
  86 +* Bug fix when ApplicationController is already loaded when we load respond_to.
  87 +* Added support success/failure blocks.
  88 +* Eager loading of files to work properly in multithreaded environments.
  89 +
  90 +# Version 0.1
  91 +
  92 +* Added more helper_methods.
  93 +* Added Rails 2.3.0 and changed tests to work with ActionController::TestCase.
  94 +* First release. Support to I18n, singleton controllers, polymorphic
  95 +controllers, belongs_to, nested_belongs_to and url helpers.
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/MIT-LICENSE 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +Copyright (c) 2009 José Valim
  2 +
  3 +Permission is hereby granted, free of charge, to any person obtaining
  4 +a copy of this software and associated documentation files (the
  5 +"Software"), to deal in the Software without restriction, including
  6 +without limitation the rights to use, copy, modify, merge, publish,
  7 +distribute, sublicense, and/or sell copies of the Software, and to
  8 +permit persons to whom the Software is furnished to do so, subject to
  9 +the following conditions:
  10 +
  11 +The above copyright notice and this permission notice shall be
  12 +included in all copies or substantial portions of the Software.
  13 +
  14 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17 +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18 +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19 +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20 +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/README 0 → 100644
... ... @@ -0,0 +1,517 @@
  1 +Inherited Resources
  2 +License: MIT
  3 +Version: 0.8.5
  4 +
  5 +You can also read this README in pretty html at the GitHub project Wiki page:
  6 +
  7 + http://wiki.github.com/josevalim/inherited_resources
  8 +
  9 +Description
  10 +-----------
  11 +
  12 +Inherited Resources speeds up development by making your controllers inherit
  13 +all restful actions so you just have to focus on what is important. It makes
  14 +your controllers more powerful and cleaner at the same time.
  15 +
  16 +Plus, making your controllers follow a pattern, it helps you to write better
  17 +code by following fat models and skinny controllers convention.
  18 +
  19 +Inherited Resources is tested and compatible with Rails 2.2.x and Rails 2.3.x.
  20 +
  21 +keywords: resources, controller, singleton, belongs_to, polymorphic, named_scope and I18n
  22 +
  23 +Installation
  24 +------------
  25 +
  26 +Install Inherited Resources is very easy. It is stored in GitHub, so just run
  27 +the following:
  28 +
  29 + gem sources -a http://gems.github.com
  30 + sudo gem install josevalim-inherited_resources
  31 +
  32 +If you want it as plugin, just do:
  33 +
  34 + script/plugin install git://github.com/josevalim/inherited_resources.git
  35 +
  36 +rspec-rails <= 1.1.12 known bug
  37 +-------------------------------
  38 +
  39 +InheritedResources has a known bug with rspec-rails. Please upgrade your rspec
  40 +version or use the fix which ships with InheritedResources:
  41 +
  42 + require 'inherited_resources/spec'
  43 +
  44 +Basic Usage
  45 +-----------
  46 +
  47 +To use Inherited Resources you just have to inherit (duh) it:
  48 +
  49 + class ProjectsController < InheritedResources::Base
  50 + end
  51 +
  52 +And all actions are defined and working, check it! Your projects collection
  53 +(in the index action) is still available in the instance variable @projects
  54 +and your project resource (all other actions) is available as @ project.
  55 +
  56 +The next step is to define which mime types this controller provides:
  57 +
  58 + class ProjectsController < InheritedResources::Base
  59 + respond_to :html, :xml, :json
  60 + end
  61 +
  62 +You can also specify them based per action:
  63 +
  64 + class ProjectsController < InheritedResources::Base
  65 + respond_to :html, :xml, :json
  66 + respond_to :js, :only => :create
  67 + respond_to :iphone, :except => [ :edit, :update ]
  68 + end
  69 +
  70 +For each request, it first checkes if the "controller/action.format" file is
  71 +available (for example "projects/create.xml") and if it's not, it checks if
  72 +the resource respond to :to_format (in this case, :to_xml). Otherwise returns 404.
  73 +
  74 +Another option is to specify which actions the controller will inherit from
  75 +the InheritedResources::Base:
  76 +
  77 + class ProjectsController < InheritedResources::Base
  78 + actions :index, :show, :new, :create
  79 + end
  80 +
  81 +Or:
  82 +
  83 + class ProjectsController < InheritedResources::Base
  84 + actions :all, :except => [ :edit, :update, :destroy ]
  85 + end
  86 +
  87 +In your views, you will get the following helpers:
  88 +
  89 + resource #=> @project
  90 + collection #=> @projects
  91 + resource_class #=> Project
  92 +
  93 +As you might expect, collection (@projects instance variable) is only available
  94 +on index actions.
  95 +
  96 +If for some reason you cannot inherit from InheritedResources::Base, you can
  97 +call inherit_resources or resource_controller in your controller class scope:
  98 +
  99 + class AccountsController < ApplicationController
  100 + inherit_resources # or resource_controller
  101 + end
  102 +
  103 +Overwriting defaults
  104 +--------------------
  105 +
  106 +Whenever you inherit from InheritedResources, several defaults are assumed.
  107 +For example you can have an AccountsController to account management while the
  108 +resource is an User:
  109 +
  110 + class AccountsController < InheritedResources::Base
  111 + defaults :resource_class => User, :collection_name, 'users', :instance_name => 'user'
  112 + end
  113 +
  114 +In the case above, in your views you will have @users and @user variables, but
  115 +the routes used will still be accounts_url and account_url. If you plan also to
  116 +change the routes, you can use :route_collection_name and :route_instance_name.
  117 +
  118 +Namespaced controllers work out of the box, but if you need to specify a
  119 +different route prefix, you can do the following:
  120 +
  121 + class Administrators::PeopleController < InheritedResources::Base
  122 + defaults :route_prefix => 'admin'
  123 + end
  124 +
  125 +Then your named routes will be: 'admin_people_url', 'admin_person_url' instead
  126 +of 'administrators_people_url' and 'administrators_person_url'.
  127 +
  128 +If you want to customize how resources are retrieved you can overwrite
  129 +collection and resource methods. The first is called on index action and the
  130 +second on all other actions. Let's suppose you want to add pagination to your
  131 +projects collection:
  132 +
  133 + class ProjectsController < InheritedResources::Base
  134 + protected
  135 + def collection
  136 + @projects ||= end_of_association_chain.paginate(params[:page]).all
  137 + end
  138 + end
  139 +
  140 +The end_of_association_chain returns your resource after nesting all associations
  141 +and scopes (more about this below).
  142 +
  143 +InheritedResources also introduces another method called begin_of_association_chain.
  144 +It's mostly used when you want to create resources based on the @current_user and
  145 +you have urls like "account/projects". In such cases, you have to do
  146 +@current_user.projects.find or @current_user.projects.build in your actions.
  147 +
  148 +You can deal with it just doing:
  149 +
  150 + class ProjectsController < InheritedResources::Base
  151 + protected
  152 + def begin_of_association_chain
  153 + @current_user
  154 + end
  155 + end
  156 +
  157 +Overwriting actions
  158 +-------------------
  159 +
  160 +Let's suppose that after destroying a project you want to redirect to your
  161 +root url instead of redirecting to projects url. You just have to do:
  162 +
  163 + class ProjectsController < InheritedResources::Base
  164 + def destroy
  165 + super do |format|
  166 + format.html { redirect_to root_url }
  167 + end
  168 + end
  169 + end
  170 +
  171 +You are opening your action and giving the parent action a new behavior. No
  172 +tricks, no DSL, just Ruby.
  173 +
  174 +On the other hand, I have to agree that calling super is not very readable.
  175 +That's why all methods have aliases. So this is equivalent:
  176 +
  177 + class ProjectsController < InheritedResources::Base
  178 + def destroy
  179 + destroy! do |format|
  180 + format.html { redirect_to root_url }
  181 + end
  182 + end
  183 + end
  184 +
  185 +Even more, since most of the times when you change a create, update or destroy
  186 +action is because you want to to change to where it redirects, a shortcut is
  187 +provided. So you can do:
  188 +
  189 + class ProjectsController < InheritedResources::Base
  190 + def destroy
  191 + destroy!{ root_url }
  192 + end
  193 + end
  194 +
  195 +Now let's suppose that before create a project you have to do something special
  196 +but you don't want to create a before filter for it:
  197 +
  198 + class ProjectsController < InheritedResources::Base
  199 + def create
  200 + @project = Project.new(params[:project])
  201 + @project.something_special!
  202 + create!
  203 + end
  204 + end
  205 +
  206 +Yes, that simple! The nice part is since you already set the instance variable
  207 +@project, it will not build a project again.
  208 +
  209 +Before we finish this topic, we should talk about one more thing: "success/failure
  210 +blocks". Let's suppose that when we update our project, in case of failure, we
  211 +want to redirect to the project url instead of re-rendering the edit template.
  212 +
  213 +Our first attempt to do this would be:
  214 +
  215 + class ProjectsController < InheritedResources::Base
  216 + def update
  217 + update! do |format|
  218 + unless @project.errors.empty? # failure
  219 + format.html { redirect_to project_url(@project) }
  220 + end
  221 + end
  222 + end
  223 + end
  224 +
  225 +Looks to verbose, right? We can actually do:
  226 +
  227 + class ProjectsController < InheritedResources::Base
  228 + def update
  229 + update! do |success, failure|
  230 + failure.html { redirect_to project_url(@project) }
  231 + end
  232 + end
  233 + end
  234 +
  235 +Much better! So explaining everything: when you give a block which expects one
  236 +argument it will be executed in both scenarios: success and failure. But If you
  237 +give a block that expects two arguments, the first will be executed only in
  238 +success scenarios and the second in failure scenarios. You keep everything
  239 +clean and organized inside the same action.
  240 +
  241 +Flash messages and I18n
  242 +-----------------------
  243 +
  244 +Flash messages are powered by I18n api. It checks for messages in the following
  245 +order:
  246 +
  247 + flash.controller_name.action_name.status
  248 + flash.actions.action_name.status
  249 +
  250 +If none is available, a default message in english set. In a create action
  251 +on projects controller, it will search for:
  252 +
  253 + flash.projects.create.status
  254 + flash.actions.create.status
  255 +
  256 +The status can be :notice (when the object can be created, updated
  257 +or destroyed with success) or :error (when the objecy cannot be created
  258 +or updated).
  259 +
  260 +Those messages are interpolated by using the resource class human name, which
  261 +is also localized and it means you can set:
  262 +
  263 + flash:
  264 + actions:
  265 + create:
  266 + notice: "Hooray! {{resource_name}} was successfully created!"
  267 +
  268 +It will replace {{resource_name}} by the human name of the resource class,
  269 +which is "Project" in this case.
  270 +
  271 +But sometimes, flash messages are not that simple. Sometimes you want to say
  272 +the title of the project while updating a project. Well, that's easy also:
  273 +
  274 + flash:
  275 + projects:
  276 + update:
  277 + notice: "Hooray! The project "{{project_title}}" was updated!"
  278 +
  279 +Since :project_title is not available for interpolation by default, you have
  280 +to overwrite interpolation_options.
  281 +
  282 + def interpolation_options
  283 + { :project_title => @project.title }
  284 + end
  285 +
  286 +Then you will finally have:
  287 +
  288 + "Hooray! The project "Plataforma" was updated!"
  289 +
  290 +By default, resource name is capitalized. If you want to make it lower case, you
  291 +can add to your application controller:
  292 +
  293 + def interpolation_options
  294 + { :resource_name => resource_class.human_name.downcase }
  295 + end
  296 +
  297 +Finally, if your controller is namespaced, for example Admin::ProjectsController,
  298 +the messages will be checked in the following order:
  299 +
  300 + flash.admin.projects.create.notice
  301 + flash.admin.actions.create.notice
  302 + flash.projects.create.notice
  303 + flash.actions.create.notice
  304 +
  305 +Has Scope
  306 +---------
  307 +
  308 +InheritedResources tries to integrate nicely with your model. In order to do so,
  309 +it also is named_scope fluent. Let's suppose our Project model with the scopes:
  310 +
  311 + class ProjectsController < ActiveRecord::Base
  312 + named_scope :featured, :conditions => { :featured => true }
  313 + named_scope :by_methodology, proc {|methodology| { :conditions => { :methodology => methodology } } }
  314 + named_scope :limit, proc{|limit| :limit => limit.to_i }
  315 + end
  316 +
  317 +Your controller:
  318 +
  319 + class ProjectsController < InheritedResources::Base
  320 + has_scope :featured, :boolean => true, :only => :index
  321 + has_scope :by_methodology
  322 + has_scope :limit, :default => 10
  323 + end
  324 +
  325 +Then for each request:
  326 +
  327 + /projects
  328 + #=> acts like a normal request, but returning 10 projects
  329 +
  330 + /projects?featured=true
  331 + #=> calls the featured named scope and bring 10 featured projects
  332 +
  333 + /projects?featured=true&by_methodology=agile&limit=20
  334 + #=> brings 20 featured projects with methodology agile
  335 +
  336 +You can retrieve the current scopes in use with :current_scopes method.
  337 +In the last case, it would return:
  338 +
  339 + { :featured => "true", :by_methodology => "agile", :limit => "20" }
  340 +
  341 +Finally, let's suppose you store on the session how many projects the user sees
  342 +per page. In such cases, you can give a proc as default value:
  343 +
  344 + has_scope :limit, :default => proc{|c| c.session[:limit] || 10 }
  345 +
  346 +Belongs to
  347 +----------
  348 +
  349 +Finally, our Projects are going to get some Tasks. Then you create a
  350 +TasksController and do:
  351 +
  352 + class TasksController < InheritedResources::Base
  353 + belongs_to :project
  354 + end
  355 +
  356 +belongs_to accepts several options to be able to configure the association.
  357 +For example, if you want urls like /projects/:project_title/tasks, you can
  358 +customize how InheritedResources find your projects:
  359 +
  360 + class TasksController < InheritedResources::Base
  361 + belongs_to :project, :finder => :find_by_title!, :param => :project_title
  362 + end
  363 +
  364 +It also accepts :route_name, :parent_class and :instance_name as options.
  365 +Check the lib/inherited_resources/class_methods.rb for more.
  366 +
  367 +Nested belongs to
  368 +-----------------
  369 +
  370 +Now, our Tasks get some Comments and you need to nest even deeper. Good
  371 +practices says that you should never nest more than two resources, but sometimes
  372 +you have to for security reasons. So this is an example of how you can do it:
  373 +
  374 + class CommentsController < InheritedResources::Base
  375 + nested_belongs_to :project, :task
  376 + end
  377 +
  378 +If you need to configure any of these belongs to, you can nested them using blocks:
  379 +
  380 + class CommentsController < InheritedResources::Base
  381 + belongs_to :project, :finder => :find_by_title!, :param => :project_title do
  382 + belongs_to :task
  383 + end
  384 + end
  385 +
  386 +Warning: calling several belongs_to is the same as nesting them:
  387 +
  388 + class CommentsConroller < InheritedResources::Base
  389 + belongs_to :project
  390 + belongs_to :task
  391 + end
  392 +
  393 +In other words, the code above is the same as calling nested_belongs_to.
  394 +
  395 +Polymorphic belongs to
  396 +----------------------
  397 +
  398 +We can go even further. Let's suppose our Projects can now have Files, Messages
  399 +and Tasks, and they are all commentable. In this case, the best solution is to
  400 +use polymorphism:
  401 +
  402 + class CommentsController < InheritedResources::Base
  403 + belongs_to :task, :file, :message, :polymorphic => true
  404 + # polymorphic_belongs_to :task, :file, :message
  405 + end
  406 +
  407 +You can even use it with nested resources:
  408 +
  409 + class CommentsController < InheritedResources::Base
  410 + belongs_to :project do
  411 + belongs_to :task, :file, :message, :polymorphic => true
  412 + end
  413 + end
  414 +
  415 +The url in such cases can be:
  416 +
  417 + /project/1/task/13/comments
  418 + /project/1/file/11/comments
  419 + /project/1/message/9/comments
  420 +
  421 +When using polymorphic associations, you get some free helpers:
  422 +
  423 + parent? #=> true
  424 + parent_type #=> :task
  425 + parent_class #=> Task
  426 + parent #=> @task
  427 +
  428 +Optional belongs to
  429 +-------------------
  430 +
  431 +Later you decide to create a view to show all comments, independent if they belong
  432 +to a task, file or message. You can reuse your polymorphic controller just doing:
  433 +
  434 + class ProjectsController < InheritedResources::Base
  435 + belongs_to :task, :file, :message, :optional => true
  436 + # optional_belongs_to :task, :file, :message
  437 + end
  438 +
  439 +This will handle all those urls properly:
  440 +
  441 + /comment/1
  442 + /tasks/2/comment/5
  443 + /files/10/comment/3
  444 + /messages/13/comment/11
  445 +
  446 +This is treated as a special type of polymorphic associations, thus all helpers
  447 +are available. As you expect, when no parent is found, the helpers return:
  448 +
  449 + parent? #=> false
  450 + parent_type #=> nil
  451 + parent_class #=> nil
  452 + parent #=> nil
  453 +
  454 +Singletons
  455 +----------
  456 +
  457 +Now we are going to add manager to projects. We say that Manager is a singleton
  458 +resource because a Project has just one manager. You should declare it as
  459 +has_one (or resource) in your routes.
  460 +
  461 +To declare an association as singleton, you just have to give the :singleton
  462 +option.
  463 +
  464 + class ManagersController < InheritedResources::Base
  465 + belongs_to :project, :singleton => true
  466 + # singleton_belongs_to :project
  467 + end
  468 +
  469 +It will deal with everything again and hide the action :index from you.
  470 +
  471 +URL Helpers
  472 +-----------
  473 +
  474 +When you use InheritedResources it creates some URL helpers.
  475 +And they handle everything for you. :)
  476 +
  477 + # /posts/1/comments
  478 + resource_url # => /posts/1/comments/#{@comment.to_param}
  479 + resource_url(comment) # => /posts/1/comments/#{comment.to_param}
  480 + new_resource_url # => /posts/1/comments/new
  481 + edit_resource_url # => /posts/1/comments/#{@comment.to_param}/edit
  482 + edit_resource_url(comment) #=> /posts/1/comments/#{comment.to_param}/edit
  483 + collection_url # => /posts/1/comments
  484 +
  485 + # /projects/1/tasks
  486 + resource_url # => /projects/1/tasks/#{@task.to_param}
  487 + resource_url(task) # => /projects/1/tasks/#{task.to_param}
  488 + new_resource_url # => /projects/1/tasks/new
  489 + edit_resource_url # => /projects/1/tasks/#{@task.to_param}/edit
  490 + edit_resource_url(task) # => /projects/1/tasks/#{task.to_param}/edit
  491 + collection_url # => /projects/1/tasks
  492 +
  493 + # /users
  494 + resource_url # => /users/#{@user.to_param}
  495 + resource_url(user) # => /users/#{user.to_param}
  496 + new_resource_url # => /users/new
  497 + edit_resource_url # => /users/#{@user.to_param}/edit
  498 + edit_resource_url(user) # => /users/#{user.to_param}/edit
  499 + collection_url # => /users
  500 +
  501 +Those urls helpers also accepts a hash as options, just as in named routes.
  502 +
  503 + # /projects/1/tasks
  504 + collection_url(:page => 1, :limit => 10) #=> /projects/1/tasks?page=1&limit=10
  505 +
  506 +Another nice thing is that those urls are not guessed during runtime. They are
  507 +all created when your application is loaded (except for polymorphic
  508 +associations, that relies on Rails polymorphic_url).
  509 +
  510 +Bugs and Feedback
  511 +-----------------
  512 +
  513 +If you discover any bugs, please send an e-mail to jose.valim@gmail.com
  514 +If you just want to give some positive feedback or drop a line, that's fine too!
  515 +
  516 +Copyright (c) 2009 José Valim
  517 +http://josevalim.blogspot.com/
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/Rakefile 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +require 'rake'
  2 +require 'rake/testtask'
  3 +require 'rake/rdoctask'
  4 +
  5 +begin
  6 + require 'jeweler'
  7 + Jeweler::Tasks.new do |s|
  8 + s.name = "inherited_resources"
  9 + s.rubyforge_project = "inherited_resources"
  10 + s.summary = "Inherited Resources speeds up development by making your controllers inherit all restful actions so you just have to focus on what is important."
  11 + s.email = "jose.valim@gmail.com"
  12 + s.homepage = "http://github.com/josevalim/inherited_resources"
  13 + s.description = "Inherited Resources speeds up development by making your controllers inherit all restful actions so you just have to focus on what is important."
  14 + s.authors = ['José Valim']
  15 + s.files = FileList["[A-Z]*", "{lib}/**/*"]
  16 + end
  17 +rescue LoadError
  18 + puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
  19 +end
  20 +
  21 +desc 'Run tests for InheritedResources.'
  22 +Rake::TestTask.new(:test) do |t|
  23 + t.pattern = 'test/**/*_test.rb'
  24 + t.verbose = true
  25 +end
  26 +
  27 +desc 'Generate documentation for InheritedResources.'
  28 +Rake::RDocTask.new(:rdoc) do |rdoc|
  29 + rdoc.rdoc_dir = 'rdoc'
  30 + rdoc.title = 'InheritedResources'
  31 + rdoc.options << '--line-numbers' << '--inline-source'
  32 + rdoc.rdoc_files.include('README')
  33 + rdoc.rdoc_files.include('MIT-LICENSE')
  34 + rdoc.rdoc_files.include('lib/**/*.rb')
  35 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/VERSION 0 → 100644
... ... @@ -0,0 +1 @@
  1 +0.8.5
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources.rb 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +# respond_to is the only file that should be loaded before hand. All others
  2 +# are loaded on demand.
  3 +#
  4 +require File.join(File.dirname(__FILE__), 'inherited_resources', 'respond_to')
  5 +
  6 +module InheritedResources; end
  7 +
  8 +class ActionController::Base
  9 + # If you cannot inherit from InheritedResources::Base you can call
  10 + # inherit_resource in your controller to have all the required modules and
  11 + # funcionality included.
  12 + #
  13 + def self.inherit_resources
  14 + InheritedResources::Base.inherit_resources(self)
  15 + initialize_resources_class_accessors!
  16 + create_resources_url_helpers!
  17 + end
  18 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/actions.rb 0 → 100644
... ... @@ -0,0 +1,96 @@
  1 +module InheritedResources
  2 + RESOURCES_ACTIONS = [ :index, :show, :new, :edit, :create, :update, :destroy ] unless self.const_defined?(:RESOURCES_ACTIONS)
  3 +
  4 + # Holds all default actions for InheritedResouces.
  5 + module Actions
  6 +
  7 + # GET /resources
  8 + def index(&block)
  9 + respond_to(:with => collection, &block)
  10 + end
  11 + alias :index! :index
  12 +
  13 + # GET /resources/1
  14 + def show(&block)
  15 + respond_to(:with => resource, &block)
  16 + end
  17 + alias :show! :show
  18 +
  19 + # GET /resources/new
  20 + def new(&block)
  21 + respond_to(:with => build_resource, &block)
  22 + end
  23 + alias :new! :new
  24 +
  25 + # GET /resources/1/edit
  26 + def edit(&block)
  27 + respond_to(:with => resource, &block)
  28 + end
  29 + alias :edit! :edit
  30 +
  31 + # POST /resources
  32 + def create(&block)
  33 + object = build_resource
  34 + respond_block, redirect_block = select_block_by_arity(block)
  35 +
  36 + if object.save
  37 + set_flash_message!(:notice, '{{resource_name}} was successfully created.')
  38 + options = { :with => object, :status => :created, :location => (resource_url rescue nil) }
  39 +
  40 + respond_to_with_dual_blocks(true, respond_block, options) do |format|
  41 + format.html { redirect_to(redirect_block ? redirect_block.call : resource_url) }
  42 + end
  43 + else
  44 + set_flash_message!(:error)
  45 + options = { :with => object.errors, :status => :unprocessable_entity }
  46 +
  47 + respond_to_with_dual_blocks(false, respond_block, options) do |format|
  48 + format.html { render :action => 'new' }
  49 + end
  50 + end
  51 + end
  52 + alias :create! :create
  53 +
  54 + # PUT /resources/1
  55 + def update(&block)
  56 + object = resource
  57 + respond_block, redirect_block = select_block_by_arity(block)
  58 +
  59 + if object.update_attributes(params[resource_instance_name])
  60 + set_flash_message!(:notice, '{{resource_name}} was successfully updated.')
  61 +
  62 + respond_to_with_dual_blocks(true, block) do |format|
  63 + format.html { redirect_to(redirect_block ? redirect_block.call : resource_url) }
  64 + format.all { head :ok }
  65 + end
  66 + else
  67 + set_flash_message!(:error)
  68 +
  69 + options = { :with => object.errors, :status => :unprocessable_entity }
  70 +
  71 + respond_to_with_dual_blocks(false, block, options) do |format|
  72 + format.html { render :action => 'edit' }
  73 + end
  74 + end
  75 + end
  76 + alias :update! :update
  77 +
  78 + # DELETE /resources/1
  79 + def destroy(&block)
  80 + resource.destroy
  81 + respond_block, redirect_block = select_block_by_arity(block)
  82 +
  83 + set_flash_message!(:notice, '{{resource_name}} was successfully destroyed.')
  84 +
  85 + respond_to_with_dual_blocks(nil, respond_block) do |format|
  86 + format.html { redirect_to(redirect_block ? redirect_block.call : collection_url) }
  87 + format.all { head :ok }
  88 + end
  89 + end
  90 + alias :destroy! :destroy
  91 +
  92 + # Make aliases protected
  93 + protected :index!, :show!, :new!, :create!, :edit!, :update!, :destroy!
  94 +
  95 + end
  96 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/base.rb 0 → 100644
... ... @@ -0,0 +1,39 @@
  1 +module InheritedResources
  2 + # = Base
  3 + #
  4 + # This is the base class that holds all actions. If you see the code for each
  5 + # action, they are quite similar to Rails default scaffold.
  6 + #
  7 + # To change your base behavior, you can overwrite your actions and call super,
  8 + # call <tt>default</tt> class method, call <<tt>actions</tt> class method
  9 + # or overwrite some helpers in the base_helpers.rb file.
  10 + #
  11 + class Base < ::ApplicationController
  12 + unloadable
  13 +
  14 + # Overwrite inherit_resources to add specific InheritedResources behavior.
  15 + #
  16 + def self.inherit_resources(base)
  17 + base.class_eval do
  18 + include InheritedResources::Actions
  19 + include InheritedResources::BaseHelpers
  20 + extend InheritedResources::ClassMethods
  21 + extend InheritedResources::UrlHelpers
  22 +
  23 + helper_method :collection_url, :collection_path, :resource_url, :resource_path,
  24 + :new_resource_url, :new_resource_path, :edit_resource_url, :edit_resource_path,
  25 + :resource, :collection, :resource_class
  26 +
  27 + base.with_options :instance_writer => false do |c|
  28 + c.class_inheritable_accessor :resource_class
  29 + c.class_inheritable_array :parents_symbols
  30 + c.class_inheritable_hash :resources_configuration, :scopes_configuration
  31 + end
  32 +
  33 + protected :resource_class, :parents_symbols, :resources_configuration, :scopes_configuration
  34 + end
  35 + end
  36 +
  37 + inherit_resources(self)
  38 + end
  39 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/base_helpers.rb 0 → 100644
... ... @@ -0,0 +1,329 @@
  1 +# Whenever base is required load the dumb responder since it's used inside actions.
  2 +require File.dirname(__FILE__) + '/dumb_responder.rb'
  3 +
  4 +module InheritedResources
  5 + # Base helpers for InheritedResource work. Some methods here can be overwriten
  6 + # and you will need to do that to customize your controllers from time to time.
  7 + #
  8 + module BaseHelpers
  9 +
  10 + protected
  11 +
  12 + # This is how the collection is loaded.
  13 + #
  14 + # You might want to overwrite this method if you want to add pagination
  15 + # for example. When you do that, don't forget to cache the result in an
  16 + # instance_variable:
  17 + #
  18 + # def collection
  19 + # @projects ||= end_of_association_chain.paginate(params[:page]).all
  20 + # end
  21 + #
  22 + def collection
  23 + get_collection_ivar || set_collection_ivar(end_of_association_chain.find(:all))
  24 + end
  25 +
  26 + # This is how the resource is loaded.
  27 + #
  28 + # You might want to overwrite this method when you are using permalink.
  29 + # When you do that, don't forget to cache the result in an
  30 + # instance_variable:
  31 + #
  32 + # def resource
  33 + # @project ||= end_of_association_chain.find_by_permalink!(params[:id])
  34 + # end
  35 + #
  36 + # You also might want to add the exclamation mark at the end of the method
  37 + # because it will raise a 404 if nothing can be found. Otherwise it will
  38 + # probably render a 500 error message.
  39 + #
  40 + def resource
  41 + get_resource_ivar || set_resource_ivar(end_of_association_chain.find(params[:id]))
  42 + end
  43 +
  44 + # This method is responsable for building the object on :new and :create
  45 + # methods. If you overwrite it, don't forget to cache the result in an
  46 + # instance variable.
  47 + #
  48 + def build_resource
  49 + get_resource_ivar || set_resource_ivar(end_of_association_chain.send(method_for_build, params[resource_instance_name]))
  50 + end
  51 +
  52 + # This class allows you to set a instance variable to begin your
  53 + # association chain. For example, usually your projects belongs to users
  54 + # and that means that they belong to the current logged in user. So you
  55 + # could do this:
  56 + #
  57 + # def begin_of_association_chain
  58 + # @current_user
  59 + # end
  60 + #
  61 + # So every time we instantiate a project, we will do:
  62 + #
  63 + # @current_user.projects.build(params[:project])
  64 + # @current_user.projects.find(params[:id])
  65 + #
  66 + # The variable set in begin_of_association_chain is not sent when building
  67 + # urls, so this is never going to happen when calling resource_url:
  68 + #
  69 + # project_url(@current_user, @project)
  70 + #
  71 + # If the user actually scopes the url, you should use belongs_to method
  72 + # and declare that projects belong to user.
  73 + #
  74 + def begin_of_association_chain
  75 + nil
  76 + end
  77 +
  78 + # Returns if the controller has a parent. When only base helpers are loaded,
  79 + # it's always false and should not be overwriten.
  80 + #
  81 + def parent?
  82 + false
  83 + end
  84 +
  85 + # Overwrite this method to provide other interpolation options when
  86 + # the flash message is going to be set.
  87 + #
  88 + # def interpolation_options
  89 + # { }
  90 + # end
  91 +
  92 + private
  93 +
  94 + # Fast accessor to resource_collection_name
  95 + #
  96 + def resource_collection_name #:nodoc:
  97 + self.resources_configuration[:self][:collection_name]
  98 + end
  99 +
  100 + # Fast accessor to resource_instance_name
  101 + #
  102 + def resource_instance_name #:nodoc:
  103 + self.resources_configuration[:self][:instance_name]
  104 + end
  105 +
  106 + # This methods gets your begin_of_association_chain, join it with your
  107 + # parents chain and returns the scoped association.
  108 + #
  109 + def end_of_association_chain #:nodoc:
  110 + chain = symbols_for_association_chain.inject(begin_of_association_chain) do |chain, symbol|
  111 + evaluate_parent(symbol, resources_configuration[symbol], chain)
  112 + end
  113 +
  114 + if chain
  115 + if method_for_association_chain
  116 + apply_scope_to(chain.send(method_for_association_chain))
  117 + else
  118 + # This only happens when we specify begin_of_association_chain in
  119 + # a singletion controller without parents. In this case, the chain
  120 + # is exactly the begin_of_association_chain which is already an
  121 + # instance and then not scopable.
  122 + chain
  123 + end
  124 + else
  125 + apply_scope_to(resource_class)
  126 + end
  127 + end
  128 +
  129 + # Returns the appropriated method to build the resource.
  130 + #
  131 + def method_for_build #:nodoc:
  132 + (begin_of_association_chain || parent?) ? method_for_association_build : :new
  133 + end
  134 +
  135 + # Returns the name of the method used for build the resource in cases
  136 + # where we have a parent. This is overwritten in singleton scenarios.
  137 + #
  138 + def method_for_association_build
  139 + :build
  140 + end
  141 +
  142 + # Returns the name of the method to be called, before returning the end
  143 + # of the association chain. This is overwriten by singleton cases
  144 + # where no method for association chain is called.
  145 + #
  146 + def method_for_association_chain #:nodoc:
  147 + resource_collection_name
  148 + end
  149 +
  150 + # Get resource ivar based on the current resource controller.
  151 + #
  152 + def get_resource_ivar #:nodoc:
  153 + instance_variable_get("@#{resource_instance_name}")
  154 + end
  155 +
  156 + # Set resource ivar based on the current resource controller.
  157 + #
  158 + def set_resource_ivar(resource) #:nodoc:
  159 + instance_variable_set("@#{resource_instance_name}", resource)
  160 + end
  161 +
  162 + # Get collection ivar based on the current resource controller.
  163 + #
  164 + def get_collection_ivar #:nodoc:
  165 + instance_variable_get("@#{resource_collection_name}")
  166 + end
  167 +
  168 + # Set collection ivar based on the current resource controller.
  169 + #
  170 + def set_collection_ivar(collection) #:nodoc:
  171 + instance_variable_set("@#{resource_collection_name}", collection)
  172 + end
  173 +
  174 + # Helper to set flash messages. It's powered by I18n API.
  175 + # It checks for messages in the following order:
  176 + #
  177 + # flash.controller_name.action_name.status
  178 + # flash.actions.action_name.status
  179 + #
  180 + # If none is available, a default message is set. So, if you have
  181 + # a CarsController, create action, it will check for:
  182 + #
  183 + # flash.cars.create.status
  184 + # flash.actions.create.status
  185 + #
  186 + # The statuses can be :notice (when the object can be created, updated
  187 + # or destroyed with success) or :error (when the objecy cannot be created
  188 + # or updated).
  189 + #
  190 + # Those messages are interpolated by using the resource class human name.
  191 + # This means you can set:
  192 + #
  193 + # flash:
  194 + # actions:
  195 + # create:
  196 + # notice: "Hooray! {{resource_name}} was successfully created!"
  197 + #
  198 + # But sometimes, flash messages are not that simple. Going back
  199 + # to cars example, you might want to say the brand of the car when it's
  200 + # updated. Well, that's easy also:
  201 + #
  202 + # flash:
  203 + # cars:
  204 + # update:
  205 + # notice: "Hooray! You just tuned your {{car_brand}}!"
  206 + #
  207 + # Since :car_name is not available for interpolation by default, you have
  208 + # to overwrite interpolation_options.
  209 + #
  210 + # def interpolation_options
  211 + # { :car_brand => @car.brand }
  212 + # end
  213 + #
  214 + # Then you will finally have:
  215 + #
  216 + # 'Hooray! You just tuned your Aston Martin!'
  217 + #
  218 + # If your controller is namespaced, for example Admin::CarsController,
  219 + # the messages will be checked in the following order:
  220 + #
  221 + # flash.admin.cars.create.status
  222 + # flash.admin.actions.create.status
  223 + # flash.cars.create.status
  224 + # flash.actions.create.status
  225 + #
  226 + def set_flash_message!(status, default_message=nil)
  227 + return flash[status] = default_message unless defined?(::I18n)
  228 +
  229 + resource_name = if resource_class
  230 + if resource_class.respond_to?(:human_name)
  231 + resource_class.human_name
  232 + else
  233 + resource_class.name.humanize
  234 + end
  235 + else
  236 + "Resource"
  237 + end
  238 +
  239 + given_options = if self.respond_to?(:interpolation_options)
  240 + interpolation_options
  241 + else
  242 + {}
  243 + end
  244 +
  245 + options = {
  246 + :default => default_message || '',
  247 + :resource_name => resource_name
  248 + }.merge(given_options)
  249 +
  250 + defaults = []
  251 + slices = controller_path.split('/')
  252 +
  253 + while slices.size > 0
  254 + defaults << :"flash.#{slices.fill(controller_name, -1).join('.')}.#{action_name}.#{status}"
  255 + defaults << :"flash.#{slices.fill(:actions, -1).join('.')}.#{action_name}.#{status}"
  256 + slices.shift
  257 + end
  258 +
  259 + options[:default] = defaults.push(options[:default])
  260 + options[:default].flatten!
  261 +
  262 + message = ::I18n.t options[:default].shift, options
  263 + flash[status] = message unless message.blank?
  264 + end
  265 +
  266 + # Used to allow to specify success and failure within just one block:
  267 + #
  268 + # def create
  269 + # create! do |success, failure|
  270 + # failure.html { redirect_to root_url }
  271 + # end
  272 + # end
  273 + #
  274 + def respond_to_with_dual_blocks(success, dual_block, options={}, &block) #:nodoc:
  275 + responder = ActionController::MimeResponds::Responder.new(self)
  276 +
  277 + if dual_block
  278 + if dual_block.arity == 2
  279 + dumb_responder = InheritedResources::DumbResponder.new
  280 + if success
  281 + dual_block.call(responder, dumb_responder)
  282 + else
  283 + dual_block.call(dumb_responder, responder)
  284 + end
  285 + else
  286 + dual_block.call(responder)
  287 + end
  288 +
  289 + # Try to respond with the block given
  290 + responder.respond_except_any
  291 + end
  292 +
  293 + respond_to(options.merge!(:responder => responder, :prioritize => :html), &block) unless performed?
  294 + end
  295 +
  296 + # Hook to apply scopes. By default returns only the target_object given.
  297 + # It's extend by HasScopeHelpers.
  298 + #
  299 + def apply_scope_to(target_object) #:nodoc:
  300 + target_object
  301 + end
  302 +
  303 + # Symbols chain in base helpers return nothing. This is later overwriten
  304 + # by belongs_to and can be complex in polymorphic cases.
  305 + #
  306 + def symbols_for_association_chain #:nodoc:
  307 + []
  308 + end
  309 +
  310 + # Holds InheritedResources block structure. It returns two blocks: the first
  311 + # is used in respond_to blocks and the second is the redirect_to url.
  312 + #
  313 + def select_block_by_arity(block) #:nodoc
  314 + if block
  315 + case block.arity
  316 + when 2, 1
  317 + [block, nil]
  318 + when 0, -1
  319 + [nil, block]
  320 + else
  321 + raise ScriptError, "InheritedResources does not know how to handle blocks with arity #{block.arity}"
  322 + end
  323 + else
  324 + [nil, nil]
  325 + end
  326 + end
  327 +
  328 + end
  329 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/belongs_to_helpers.rb 0 → 100644
... ... @@ -0,0 +1,89 @@
  1 +module InheritedResources
  2 +
  3 + # = belongs_to
  4 + #
  5 + # Let's suppose that we have some tasks that belongs to projects. To specify
  6 + # this assoication in your controllers, just do:
  7 + #
  8 + # class TasksController < InheritedResources::Base
  9 + # belongs_to :project
  10 + # end
  11 + #
  12 + # belongs_to accepts several options to be able to configure the association.
  13 + # For example, if you want urls like /projects/:project_title/tasks, you
  14 + # can customize how InheritedResources find your projects:
  15 + #
  16 + # class TasksController < InheritedResources::Base
  17 + # belongs_to :project, :finder => :find_by_title!, :param => :project_title
  18 + # end
  19 + #
  20 + # It also accepts :route_name, :parent_class and :instance_name as options.
  21 + # Check the lib/inherited_resources/class_methods.rb for more.
  22 + #
  23 + # = nested_belongs_to
  24 + #
  25 + # Now, our Tasks get some Comments and you need to nest even deeper. Good
  26 + # practices says that you should never nest more than two resources, but sometimes
  27 + # you have to for security reasons. So this is an example of how you can do it:
  28 + #
  29 + # class CommentsController < InheritedResources::Base
  30 + # nested_belongs_to :project, :task
  31 + # end
  32 + #
  33 + # If you need to configure any of these belongs to, you can nested them using blocks:
  34 + #
  35 + # class CommentsController < InheritedResources::Base
  36 + # belongs_to :project, :finder => :find_by_title!, :param => :project_title do
  37 + # belongs_to :task
  38 + # end
  39 + # end
  40 + #
  41 + # Warning: calling several belongs_to is the same as nesting them:
  42 + #
  43 + # class CommentsController < InheritedResources::Base
  44 + # belongs_to :project
  45 + # belongs_to :task
  46 + # end
  47 + #
  48 + # In other words, the code above is the same as calling nested_belongs_to.
  49 + #
  50 + module BelongsToHelpers
  51 +
  52 + protected
  53 +
  54 + # Parent is always true when belongs_to is called.
  55 + #
  56 + def parent?
  57 + true
  58 + end
  59 +
  60 + private
  61 +
  62 + # Evaluate the parent given. This is used to nest parents in the
  63 + # association chain.
  64 + #
  65 + def evaluate_parent(parent_symbol, parent_config, chain = nil) #:nodoc:
  66 + instantiated_object = instance_variable_get("@#{parent_config[:instance_name]}")
  67 + return instantiated_object if instantiated_object
  68 +
  69 + parent = if chain
  70 + chain.send(parent_config[:collection_name])
  71 + else
  72 + parent_config[:parent_class]
  73 + end
  74 +
  75 + parent = parent.send(parent_config[:finder], params[parent_config[:param]])
  76 +
  77 + instance_variable_set("@#{parent_config[:instance_name]}", parent)
  78 + end
  79 +
  80 + # Maps parents_symbols to build association chain. In this case, it
  81 + # simply return the parent_symbols, however on polymorphic belongs to,
  82 + # it has some customization.
  83 + #
  84 + def symbols_for_association_chain #:nodoc:
  85 + parents_symbols
  86 + end
  87 +
  88 + end
  89 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/class_methods.rb 0 → 100644
... ... @@ -0,0 +1,328 @@
  1 +module InheritedResources
  2 + module ClassMethods
  3 +
  4 + protected
  5 +
  6 + # Used to overwrite the default assumptions InheritedResources do. Whenever
  7 + # this method is called, it should be on the top of your controller, since
  8 + # almost other methods depends on the values given to <<tt>>defaults</tt>.
  9 + #
  10 + # == Options
  11 + #
  12 + # * <tt>:resource_class</tt> - The resource class which by default is guessed
  13 + # by the controller name. Defaults to Project in
  14 + # ProjectsController.
  15 + #
  16 + # * <tt>:collection_name</tt> - The name of the collection instance variable which
  17 + # is set on the index action. Defaults to :projects in
  18 + # ProjectsController.
  19 + #
  20 + # * <tt>:instance_name</tt> - The name of the singular instance variable which
  21 + # is set on all actions besides index action. Defaults to
  22 + # :project in ProjectsController.
  23 + #
  24 + # * <tt>:route_collection_name</tt> - The name of the collection route. Defaults to :collection_name.
  25 + #
  26 + # * <tt>:route_instance_name</tt> - The name of the singular route. Defaults to :instance_name.
  27 + #
  28 + # * <tt>:route_prefix</tt> - The route prefix which is automically set in namespaced
  29 + # controllers. Default to :admin on Admin::ProjectsController.
  30 + #
  31 + # * <tt>:singleton</tt> - Tells if this controller is singleton or not.
  32 + #
  33 + def defaults(options)
  34 + raise ArgumentError, 'Class method :defaults expects a hash of options.' unless options.is_a? Hash
  35 +
  36 + options.symbolize_keys!
  37 + options.assert_valid_keys(:resource_class, :collection_name, :instance_name,
  38 + :class_name, :route_prefix, :route_collection_name,
  39 + :route_instance_name, :singleton)
  40 +
  41 + self.resource_class = options.delete(:resource_class) if options.key?(:resource_class)
  42 + self.resource_class = options.delete(:class_name).constantize if options.key?(:class_name)
  43 +
  44 + acts_as_singleton! if options.delete(:singleton)
  45 +
  46 + config = self.resources_configuration[:self]
  47 + config[:route_prefix] = options.delete(:route_prefix) if options.key?(:route_prefix)
  48 +
  49 + options.each do |key, value|
  50 + config[key] = value.to_sym
  51 + end
  52 +
  53 + create_resources_url_helpers!
  54 + end
  55 +
  56 + # Defines wich actions to keep from the inherited controller.
  57 + # Syntax is borrowed from resource_controller.
  58 + #
  59 + # actions :index, :show, :edit
  60 + # actions :all, :except => :index
  61 + #
  62 + def actions(*actions_to_keep)
  63 + raise ArgumentError, 'Wrong number of arguments. You have to provide which actions you want to keep.' if actions_to_keep.empty?
  64 +
  65 + options = actions_to_keep.extract_options!
  66 + actions_to_keep.map!{ |a| a.to_s }
  67 +
  68 + actions_to_remove = Array(options[:except])
  69 + actions_to_remove.map!{ |a| a.to_s }
  70 +
  71 + actions_to_remove += RESOURCES_ACTIONS.map{|a| a.to_s } - actions_to_keep unless actions_to_keep.first == 'all'
  72 + actions_to_remove.uniq!
  73 +
  74 + (instance_methods & actions_to_remove).each do |action|
  75 + undef_method action, "#{action}!"
  76 + end
  77 + end
  78 +
  79 + # Detects params from url and apply as scopes to your classes.
  80 + #
  81 + # Your model:
  82 + #
  83 + # class Graduation < ActiveRecord::Base
  84 + # named_scope :featured, :conditions => { :featured => true }
  85 + # named_scope :by_degree, proc {|degree| { :conditions => { :degree => degree } } }
  86 + # end
  87 + #
  88 + # Your controller:
  89 + #
  90 + # class GraduationsController < InheritedResources::Base
  91 + # has_scope :featured, :boolean => true, :only => :index
  92 + # has_scope :by_degree, :only => :index
  93 + # end
  94 + #
  95 + # Then for each request:
  96 + #
  97 + # /graduations
  98 + # #=> acts like a normal request
  99 + #
  100 + # /graduations?featured=true
  101 + # #=> calls the named scope and bring featured graduations
  102 + #
  103 + # /graduations?featured=true&by_degree=phd
  104 + # #=> brings featured graduations with phd degree
  105 + #
  106 + # You can retrieve the current scopes in use with <tt>current_scopes</tt>
  107 + # method. In the last case, it would return: { :featured => "true", :by_degree => "phd" }
  108 + #
  109 + # == Options
  110 + #
  111 + # * <tt>:boolean</tt> - When set to true, call the scope only when the params is true or 1,
  112 + # and does not send the value as argument.
  113 + #
  114 + # * <tt>:only</tt> - In each actions the scope is applied. By default is :all.
  115 + #
  116 + # * <tt>:except</tt> - In each actions the scope is not applied. By default is :none.
  117 + #
  118 + # * <tt>:key</tt> - The key in the params hash expected to find the scope.
  119 + # Defaults to the scope name.
  120 + #
  121 + # * <tt>:default</tt> - Default value for the scope. Whenever supplied the scope
  122 + # is always called. This is useful to add easy pagination!
  123 + #
  124 + def has_scope(*scopes)
  125 + options = scopes.extract_options!
  126 +
  127 + options.symbolize_keys!
  128 + options.assert_valid_keys(:boolean, :key, :only, :except, :default)
  129 +
  130 + if self.scopes_configuration.empty?
  131 + include HasScopeHelpers
  132 + helper_method :current_scopes
  133 + end
  134 +
  135 + scopes.each do |scope|
  136 + self.scopes_configuration[scope] ||= {}
  137 + self.scopes_configuration[scope][:key] = options[:key] || scope
  138 + self.scopes_configuration[scope][:only] = Array(options[:only])
  139 + self.scopes_configuration[scope][:except] = Array(options[:except])
  140 + self.scopes_configuration[scope][:boolean] = options[:boolean] if options.key?(:boolean)
  141 + self.scopes_configuration[scope][:default] = options[:default] if options.key?(:default)
  142 + end
  143 + end
  144 +
  145 + # Defines that this controller belongs to another resource.
  146 + #
  147 + # belongs_to :projects
  148 + #
  149 + # == Options
  150 + #
  151 + # * <tt>:parent_class</tt> - Allows you to specify what is the parent class.
  152 + #
  153 + # belongs_to :project, :parent_class => AdminProject
  154 + #
  155 + # * <tt>:class_name</tt> - Also allows you to specify the parent class, but you should
  156 + # give a string. Added for ActiveRecord belongs to compatibility.
  157 + #
  158 + # * <tt>:instance_name</tt> - The instance variable name. By default is the name of the association.
  159 + #
  160 + # belongs_to :project, :instance_name => :my_project
  161 + #
  162 + # * <tt>:finder</tt> - Specifies which method should be called to instantiate the parent.
  163 + #
  164 + # belongs_to :project, :finder => :find_by_title!
  165 + #
  166 + # This will make your projects be instantiated as:
  167 + #
  168 + # Project.find_by_title!(params[:project_id])
  169 + #
  170 + # Instead of:
  171 + #
  172 + # Project.find(params[:project_id])
  173 + #
  174 + # * <tt>:param</tt> - Allows you to specify params key to retrieve the id.
  175 + # Default is :association_id, which in this case is :project_id.
  176 + #
  177 + # * <tt>:route_name</tt> - Allows you to specify what is the route name in your url
  178 + # helper. By default is association name.
  179 + #
  180 + # * <tt>:collection_name</tt> - Tell how to retrieve the next collection. Let's
  181 + # suppose you have Tasks which belongs to Projects
  182 + # which belongs to companies. This will do somewhere
  183 + # down the road:
  184 + #
  185 + # @company.projects
  186 + #
  187 + # But if you want to retrieve instead:
  188 + #
  189 + # @company.admin_projects
  190 + #
  191 + # You supply the collection name.
  192 + #
  193 + # * <tt>:polymorphic</tt> - Tell the association is polymorphic.
  194 + #
  195 + # * <tt>:singleton</tt> - Tell it's a singleton association.
  196 + #
  197 + # * <tt>:optional</tt> - Tell the association is optional (it's a special
  198 + # type of polymorphic association)
  199 + #
  200 + def belongs_to(*symbols, &block)
  201 + options = symbols.extract_options!
  202 +
  203 + options.symbolize_keys!
  204 + options.assert_valid_keys(:class_name, :parent_class, :instance_name, :param,
  205 + :finder, :route_name, :collection_name, :singleton,
  206 + :polymorphic, :optional)
  207 +
  208 + optional = options.delete(:optional)
  209 + singleton = options.delete(:singleton)
  210 + polymorphic = options.delete(:polymorphic)
  211 +
  212 + include BelongsToHelpers if self.parents_symbols.empty?
  213 +
  214 + acts_as_singleton! if singleton
  215 + acts_as_polymorphic! if polymorphic || optional
  216 +
  217 + raise ArgumentError, 'You have to give me at least one association name.' if symbols.empty?
  218 + raise ArgumentError, 'You cannot define multiple associations with options: #{options.keys.inspect} to belongs to.' unless symbols.size == 1 || options.empty?
  219 +
  220 + symbols.each do |symbol|
  221 + symbol = symbol.to_sym
  222 +
  223 + if polymorphic || optional
  224 + self.parents_symbols << :polymorphic unless self.parents_symbols.include?(:polymorphic)
  225 + self.resources_configuration[:polymorphic][:symbols] << symbol
  226 + self.resources_configuration[:polymorphic][:optional] ||= optional
  227 + else
  228 + self.parents_symbols << symbol
  229 + end
  230 +
  231 + config = self.resources_configuration[symbol] = {}
  232 + config[:parent_class] = options.delete(:parent_class)
  233 + config[:parent_class] ||= (options.delete(:class_name) || symbol).to_s.classify.constantize rescue nil
  234 + config[:collection_name] = options.delete(:collection_name) || symbol.to_s.pluralize.to_sym
  235 + config[:instance_name] = options.delete(:instance_name) || symbol
  236 + config[:param] = options.delete(:param) || :"#{symbol}_id"
  237 + config[:finder] = options.delete(:finder) || :find
  238 + config[:route_name] = options.delete(:route_name) || symbol
  239 + end
  240 +
  241 + if block_given?
  242 + class_eval(&block)
  243 + else
  244 + create_resources_url_helpers!
  245 + end
  246 + end
  247 + alias :nested_belongs_to :belongs_to
  248 +
  249 + # A quick method to declare polymorphic belongs to.
  250 + #
  251 + def polymorphic_belongs_to(*symbols, &block)
  252 + options = symbols.extract_options!
  253 + options.merge!(:polymorphic => true)
  254 + belongs_to(*symbols << options, &block)
  255 + end
  256 +
  257 + # A quick method to declare singleton belongs to.
  258 + #
  259 + def singleton_belongs_to(*symbols, &block)
  260 + options = symbols.extract_options!
  261 + options.merge!(:singleton => true)
  262 + belongs_to(*symbols << options, &block)
  263 + end
  264 +
  265 + # A quick method to declare optional belongs to.
  266 + #
  267 + def optional_belongs_to(*symbols, &block)
  268 + options = symbols.extract_options!
  269 + options.merge!(:optional => true)
  270 + belongs_to(*symbols << options, &block)
  271 + end
  272 +
  273 + private
  274 +
  275 + def acts_as_singleton! #:nodoc:
  276 + unless self.resources_configuration[:self][:singleton]
  277 + self.resources_configuration[:self][:singleton] = true
  278 + include SingletonHelpers
  279 + actions :all, :except => :index
  280 + end
  281 + end
  282 +
  283 + def acts_as_polymorphic! #:nodoc:
  284 + unless self.parents_symbols.include?(:polymorphic)
  285 + include PolymorphicHelpers
  286 + helper_method :parent, :parent_type, :parent_class, :parent?
  287 + end
  288 + end
  289 +
  290 + # Initialize resources class accessors and set their default values.
  291 + #
  292 + def initialize_resources_class_accessors! #:nodoc:
  293 + # Initialize resource class
  294 + self.resource_class = begin
  295 + self.controller_name.classify.constantize
  296 + rescue NameError
  297 + nil
  298 + end
  299 +
  300 + # Initialize resources configuration hash
  301 + self.resources_configuration ||= {}
  302 + config = self.resources_configuration[:self] = {}
  303 + config[:collection_name] = self.controller_name.to_sym
  304 + config[:instance_name] = self.controller_name.singularize.to_sym
  305 +
  306 + config[:route_collection_name] = config[:collection_name]
  307 + config[:route_instance_name] = config[:instance_name]
  308 +
  309 + # Deal with namespaced controllers
  310 + namespaces = self.controller_path.split('/')[0..-2]
  311 + config[:route_prefix] = namespaces.join('_') unless namespaces.empty?
  312 +
  313 + # Initialize polymorphic, singleton, scopes and belongs_to parameters
  314 + self.parents_symbols ||= []
  315 + self.scopes_configuration ||= {}
  316 + self.resources_configuration[:polymorphic] ||= { :symbols => [], :optional => false }
  317 + end
  318 +
  319 + # Hook called on inheritance.
  320 + #
  321 + def inherited(base) #:nodoc:
  322 + super(base)
  323 + base.send :initialize_resources_class_accessors!
  324 + base.send :create_resources_url_helpers!
  325 + end
  326 +
  327 + end
  328 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/dumb_responder.rb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +module InheritedResources
  2 + # = Dumb Responder
  3 + #
  4 + # This responder discards all messages sent to him.
  5 + #
  6 + class DumbResponder
  7 +
  8 + instance_methods.each do |m|
  9 + undef_method m unless m =~ /^__/
  10 + end
  11 +
  12 + # This is like a good husband, he will just listen everything that his wife
  13 + # says (which is a lot) without complaining. :)
  14 + #
  15 + def method_missing(*args)
  16 + nil
  17 + end
  18 +
  19 + end
  20 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/has_scope_helpers.rb 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +module InheritedResources
  2 +
  3 + # = has_scopes
  4 + #
  5 + # This module in included in your controller when has_scope is called for the
  6 + # first time.
  7 + #
  8 + module HasScopeHelpers
  9 + TRUE_VALUES = ["true", true, "1", 1] unless self.const_defined?(:TRUE_VALUES)
  10 +
  11 + protected
  12 +
  13 + # Overwrites apply to scope to implement default scope logic.
  14 + #
  15 + def apply_scope_to(target_object) #:nodoc:
  16 + @current_scopes ||= {}
  17 +
  18 + self.scopes_configuration.each do |scope, options|
  19 + next unless apply_scope_to_action?(options)
  20 + key = options[:key]
  21 +
  22 + if params.key?(key)
  23 + value, call_scope = params[key], true
  24 + elsif options.key?(:default)
  25 + value, call_scope = options[:default], true
  26 + value = value.call(self) if value.is_a?(Proc)
  27 + end
  28 +
  29 + if call_scope
  30 + @current_scopes[key] = value
  31 +
  32 + if options[:boolean]
  33 + target_object = target_object.send(scope) if TRUE_VALUES.include?(value)
  34 + else
  35 + target_object = target_object.send(scope, value)
  36 + end
  37 + end
  38 + end
  39 +
  40 + target_object
  41 + end
  42 +
  43 + # Given an options with :only and :except arrays, check if the scope
  44 + # can be performed in the current action.
  45 + #
  46 + def apply_scope_to_action?(options) #:nodoc:
  47 + if options[:only].empty?
  48 + if options[:except].empty?
  49 + true
  50 + else
  51 + !options[:except].include?(action_name.to_sym)
  52 + end
  53 + else
  54 + options[:only].include?(action_name.to_sym)
  55 + end
  56 + end
  57 +
  58 + # Returns the scopes used in this action.
  59 + #
  60 + def current_scopes
  61 + @current_scopes || {}
  62 + end
  63 +
  64 + end
  65 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/polymorphic_helpers.rb 0 → 100644
... ... @@ -0,0 +1,156 @@
  1 +module InheritedResources
  2 +
  3 + # = polymorphic associations
  4 + #
  5 + # In some cases you have a resource that belongs to two different resources
  6 + # but not at the same time. For example, let's suppose you have File, Message
  7 + # and Task as resources and they are all commentable.
  8 + #
  9 + # Polymorphic associations allows you to create just one controller that will
  10 + # deal with each case.
  11 + #
  12 + # class Comment < InheritedResources::Base
  13 + # belongs_to :file, :message, :task, :polymorphic => true
  14 + # end
  15 + #
  16 + # Your routes should be something like:
  17 + #
  18 + # m.resources :files, :has_many => :comments #=> /files/13/comments
  19 + # m.resources :tasks, :has_many => :comments #=> /tasks/17/comments
  20 + # m.resources :messages, :has_many => :comments #=> /messages/11/comments
  21 + #
  22 + # When using polymorphic associations, you get some free helpers:
  23 + #
  24 + # parent? #=> true
  25 + # parent_type #=> :task
  26 + # parent_class #=> Task
  27 + # parent #=> @task
  28 + #
  29 + # This polymorphic controllers thing is a great idea by James Golick and he
  30 + # built it in resource_controller. Here is just a re-implementation.
  31 + #
  32 + # = optional polymorphic associations
  33 + #
  34 + # Let's take another break from ProjectsController. Let's suppose we are
  35 + # building a store, which sell products.
  36 + #
  37 + # On the website, we can show all products, but also products scoped to
  38 + # categories, brands, users. In this case case, the association is optional, and
  39 + # we deal with it in the following way:
  40 + #
  41 + # class ProductsController < InheritedResources::Base
  42 + # belongs_to :category, :brand, :user, :polymorphic => true, :optional => true
  43 + # end
  44 + #
  45 + # This will handle all those urls properly:
  46 + #
  47 + # /products/1
  48 + # /categories/2/products/5
  49 + # /brands/10/products/3
  50 + # /user/13/products/11
  51 + #
  52 + # = nested polymorphic associations
  53 + #
  54 + # You can have polymorphic associations with nested resources. Let's suppose
  55 + # that our File, Task and Message resources in the previous example belongs to
  56 + # a project.
  57 + #
  58 + # This way we can have:
  59 + #
  60 + # class CommentsController < InheritedResources::Base
  61 + # belongs_to :project {
  62 + # belongs_to :file, :message, :task, :polymorphic => true
  63 + # }
  64 + # end
  65 + #
  66 + # Or:
  67 + #
  68 + # class CommentsController < InheritedResources::Base
  69 + # nested_belongs_to :project
  70 + # nested_belongs_to :file, :message, :task, :polymorphic => true
  71 + # end
  72 + #
  73 + # Choose the syntax that makes more sense to you. :)
  74 + #
  75 + # Finally your routes should be something like:
  76 + #
  77 + # map.resources :projects do |m|
  78 + # m.resources :files, :has_many => :comments #=> /projects/1/files/13/comments
  79 + # m.resources :tasks, :has_many => :comments #=> /projects/1/tasks/17/comments
  80 + # m.resources :messages, :has_many => :comments #=> /projects/1/messages/11/comments
  81 + # end
  82 + #
  83 + # The helpers work in the same way as above.
  84 + #
  85 + module PolymorphicHelpers
  86 +
  87 + protected
  88 +
  89 + # Returns the parent type. A Comments class can have :task, :file, :note
  90 + # as parent types.
  91 + #
  92 + def parent_type
  93 + @parent_type
  94 + end
  95 +
  96 + def parent_class
  97 + parent.class if @parent_type
  98 + end
  99 +
  100 + # Returns the parent object. They are also available with the instance
  101 + # variable name: @task, @file, @note...
  102 + #
  103 + def parent
  104 + instance_variable_get("@#{@parent_type}") if @parent_type
  105 + end
  106 +
  107 + # If the polymorphic association is optional, we might not have a parent.
  108 + #
  109 + def parent?
  110 + if resources_configuration[:polymorphic][:optional]
  111 + parents_symbols.size > 1 || !@parent_type.nil?
  112 + else
  113 + true
  114 + end
  115 + end
  116 +
  117 + private
  118 +
  119 + # Maps parents_symbols to build association chain.
  120 + #
  121 + # If the parents_symbols find :polymorphic, it goes through the
  122 + # params keys to see which polymorphic parent matches the given params.
  123 + #
  124 + # When optional is given, it does not raise errors if the polymorphic
  125 + # params are missing.
  126 + #
  127 + def symbols_for_association_chain #:nodoc:
  128 + polymorphic_config = resources_configuration[:polymorphic]
  129 +
  130 + parents_symbols.map do |symbol|
  131 + if symbol == :polymorphic
  132 + params_keys = params.keys
  133 +
  134 + key = polymorphic_config[:symbols].find do |poly|
  135 + params_keys.include? resources_configuration[poly][:param].to_s
  136 + end
  137 +
  138 + if key.nil?
  139 + raise ScriptError, "Could not find param for polymorphic association.
  140 + The request params keys are #{params.keys.inspect}
  141 + and the polymorphic associations are
  142 + #{polymorphic_symbols.inspect}." unless polymorphic_config[:optional]
  143 +
  144 + nil
  145 + else
  146 + @parent_type = key.to_sym
  147 + end
  148 + else
  149 + symbol
  150 + end
  151 + end.compact
  152 + end
  153 +
  154 + end
  155 +end
  156 +
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/respond_to.rb 0 → 100644
... ... @@ -0,0 +1,339 @@
  1 +module ActionController
  2 + # Provides an extension for Rails respond_to by expading MimeResponds::Responder
  3 + # and adding respond_to class method and respond_with instance method.
  4 + #
  5 + class Base
  6 +
  7 + protected
  8 + # Defines respond_to method to store formats that are rendered by default.
  9 + #
  10 + # Examples:
  11 + #
  12 + # respond_to :html, :xml, :json
  13 + #
  14 + # All actions on your controller will respond to :html, :xml and :json.
  15 + # But if you want to specify it based on your actions, you can use only and
  16 + # except:
  17 + #
  18 + # respond_to :html
  19 + # respond_to :xml, :json, :except => [ :edit ]
  20 + #
  21 + # The definition above explicits that all actions respond to :html. And all
  22 + # actions except :edit respond to :xml and :json.
  23 + #
  24 + # You can specify also only parameters:
  25 + #
  26 + # respond_to :rjs, :only => :create
  27 + #
  28 + # Which would be the same as:
  29 + #
  30 + # respond_to :rjs => :create
  31 + #
  32 + def self.respond_to(*formats)
  33 + options = formats.extract_options!
  34 + formats_hash = {}
  35 +
  36 + only_actions = Array(options.delete(:only))
  37 + except_actions = Array(options.delete(:except))
  38 +
  39 + only_actions.map!{ |a| a.to_sym }
  40 + except_actions.map!{ |a| a.to_sym }
  41 +
  42 + formats.each do |format|
  43 + formats_hash[format.to_sym] = {}
  44 + formats_hash[format.to_sym][:only] = only_actions unless only_actions.empty?
  45 + formats_hash[format.to_sym][:except] = except_actions unless except_actions.empty?
  46 + end
  47 +
  48 + options.each do |format, actions|
  49 + formats_hash[format.to_sym] = {}
  50 + next if actions == :all || actions == 'all'
  51 +
  52 + actions = Array(actions)
  53 + actions.map!{ |a| a.to_sym }
  54 +
  55 + formats_hash[format.to_sym][:only] = actions unless actions.empty?
  56 + end
  57 +
  58 + write_inheritable_hash(:formats_for_respond_to, formats_hash)
  59 + end
  60 + class_inheritable_reader :formats_for_respond_to
  61 +
  62 + # Method to clear all respond_to declared until the current controller.
  63 + # This is like freeing the controller from the inheritance chain. :)
  64 + #
  65 + def self.clear_respond_to!
  66 + formats = formats_for_respond_to
  67 + formats.each { |k,v| formats[k] = { :only => [] } }
  68 + write_inheritable_hash(:formats_for_respond_to, formats)
  69 + end
  70 +
  71 + # By default, responds only to :html
  72 + respond_to :html
  73 +
  74 + # If ApplicationController is already defined around here, we recriate
  75 + # the formats_for_respond_to hash. Since we respond only to :html by
  76 + # default, this is as easy as settings the :formats_for_respond_to key
  77 + # to {:html=>{}}.
  78 + #
  79 + if defined?(ApplicationController)
  80 + if inheritable = ApplicationController.instance_variable_get("@inheritable_attributes")
  81 + inheritable.merge!(:formats_for_respond_to => {:html => {}}) if inheritable
  82 + end
  83 + end
  84 +
  85 + # respond_with accepts an object and tries to render a view based in the
  86 + # controller and actions that called respond_with. If the view cannot be
  87 + # found, it will try to call :to_format in the object.
  88 + #
  89 + # class ProjectsController < ApplicationController
  90 + # respond_to :html, :xml
  91 + #
  92 + # def show
  93 + # @project = Project.find(:id)
  94 + # respond_with(@project)
  95 + # end
  96 + # end
  97 + #
  98 + # When the client request a xml, we will check first for projects/show.xml
  99 + # if it can't be found, we will call :to_xml in the object @project. If the
  100 + # object eventually doesn't respond to :to_xml it will render 404.
  101 + #
  102 + # If you want to overwrite the formats specified in the class, you can
  103 + # send your new formats using the options :to.
  104 + #
  105 + # def show
  106 + # @project = Project.find(:id)
  107 + # respond_with(@project, :to => :json)
  108 + # end
  109 + #
  110 + # That means that this action will ONLY reply to json requests.
  111 + #
  112 + # All other options sent will be forwarded to the render method. So you can
  113 + # do:
  114 + #
  115 + # def create
  116 + # # ...
  117 + # if @project.save
  118 + # respond_with(@project, :status => :ok, :location => @project)
  119 + # else
  120 + # respond_with(@project.errors, :status => :unprocessable_entity)
  121 + # end
  122 + # end
  123 + #
  124 + # respond_with does not accept blocks, if you want advanced configurations
  125 + # check respond_to method sending :with => @object as option.
  126 + #
  127 + # Returns true if anything is rendered. Returns false otherwise.
  128 + #
  129 + def respond_with(object, options = {})
  130 + attempt_to_respond = false
  131 +
  132 + responder = options.delete(:responder) || Responder.new(self)
  133 + skip_not_acceptable = options.delete(:skip_not_acceptable)
  134 + skip_default_template = options.delete(:skip_default_template)
  135 +
  136 + mime_types = Array(options.delete(:to))
  137 + mime_types.map!{ |mime| mime.to_sym }
  138 +
  139 + for priority in responder.mime_type_priority
  140 + if !skip_default_template && priority == Mime::ALL && respond_to_default_template?(responder)
  141 + render options.merge(:action => action_name)
  142 + return true
  143 +
  144 + elsif responder.action_respond_to_format?(priority.to_sym, mime_types)
  145 + attempt_to_respond = true
  146 + response.template.template_format = priority.to_sym
  147 + response.content_type = priority.to_s
  148 +
  149 + if template_exists?
  150 + render options.merge(:action => action_name)
  151 + return true
  152 + elsif object.respond_to?(:"to_#{priority.to_sym}")
  153 + render options.merge(:text => object.send(:"to_#{priority.to_sym}"))
  154 + return true
  155 + end
  156 + end
  157 + end
  158 +
  159 + # If we got here we could not render the object. But if attempted to
  160 + # render (this means, the format sent by the client was valid) we should
  161 + # render a 404.
  162 + #
  163 + # If we even didn't attempt to respond, we respond :not_acceptable
  164 + # unless is told otherwise.
  165 + #
  166 + if attempt_to_respond
  167 + render :text => '404 Not Found', :status => 404
  168 + return true
  169 + elsif !skip_not_acceptable
  170 + head :not_acceptable
  171 + return false
  172 + end
  173 +
  174 + return false
  175 + end
  176 +
  177 + # Extends respond_to behaviour.
  178 + #
  179 + # You can now pass objects using the options :with.
  180 + #
  181 + # respond_to(:html, :xml, :rjs, :with => @project)
  182 + #
  183 + # If you pass an object and send any block, it's exactly the same as:
  184 + #
  185 + # respond_with(@project, :to => [:html, :xml, :rjs])
  186 + #
  187 + # But the main difference of respond_to and respond_with is that the first
  188 + # allows further customizations:
  189 + #
  190 + # respond_to(:html, :with => @project) do |format|
  191 + # format.xml { render :xml => @project.errors }
  192 + # end
  193 + #
  194 + # It's the same as:
  195 + #
  196 + # 1. When responding to html, execute respond_with(@object).
  197 + # 2. When accessing a xml, execute the block given.
  198 + #
  199 + # Formats defined in blocks have precedence to formats sent as arguments.
  200 + # In other words, if you pass a format as argument and as block, the block
  201 + # will always be executed.
  202 + #
  203 + # And as in respond_with, all extra options sent will be forwarded to
  204 + # the render method:
  205 + #
  206 + # respond_to(:with => @projects.errors, :status => :unprocessable_entity) do |format|
  207 + # format.html { render :template => 'new' }
  208 + # end
  209 + #
  210 + # It also accepts an option called prioritize. It allows you to put a
  211 + # format as first, and then when Mime::ALL is sent, it will be the one
  212 + # used as response.
  213 + #
  214 + def respond_to(*types, &block)
  215 + options = types.extract_options!
  216 +
  217 + object = options.delete(:with)
  218 + responder = options.delete(:responder) || Responder.new(self)
  219 + prioritize = options.delete(:prioritize)
  220 +
  221 + if object.nil?
  222 + block ||= lambda { |responder| types.each { |type| responder.send(type) } }
  223 + block.call(responder)
  224 + responder.respond
  225 + return true
  226 + else
  227 + # Even if Mime::ALL is sent by the client, we do not respond_to it now.
  228 + # This is done using calling :respond_except_any instead of :respond.
  229 + #
  230 + if block_given?
  231 + block.call(responder)
  232 + return true if responder.respond_except_any
  233 + end
  234 +
  235 + # If the block includes the default template format, we don't render
  236 + # the default template (which uses the default_template_format).
  237 + options.merge!(:to => types, :responder => responder, :skip_not_acceptable => true,
  238 + :skip_default_template => responder.order.include?(default_template_format))
  239 +
  240 + if respond_with(object, options)
  241 + return true
  242 + elsif block_given?
  243 + responder.prioritize(prioritize) if prioritize
  244 + return true if responder.respond_any
  245 + end
  246 + end
  247 +
  248 + head :not_acceptable
  249 + return false
  250 + end
  251 +
  252 + private
  253 +
  254 + unless ActionController::Base.private_instance_methods.include?('template_exists?') ||
  255 + ActionController::Base.private_instance_methods.include?(:template_exists?)
  256 +
  257 + # Define template_exists? for Rails 2.3
  258 + def template_exists?
  259 + default_template ? true : false
  260 + rescue ActionView::MissingTemplate
  261 + false
  262 + end
  263 + end
  264 +
  265 + # We respond to the default template if it's a valid format AND the template
  266 + # exists.
  267 + #
  268 + def respond_to_default_template?(responder) #:nodoc:
  269 + responder.action_respond_to_format?(default_template_format) && template_exists?
  270 + end
  271 +
  272 + end
  273 +
  274 + module MimeResponds #:nodoc:
  275 + class Responder #:nodoc:
  276 +
  277 + attr_reader :mime_type_priority, :order
  278 +
  279 + # Similar as respond but if we can't find a valid mime type, we do not
  280 + # send :not_acceptable message as head and it does not respond to
  281 + # Mime::ALL in any case.
  282 + #
  283 + def respond_except_any
  284 + for priority in @mime_type_priority
  285 + next if priority == Mime::ALL
  286 +
  287 + if @responses[priority]
  288 + @responses[priority].call
  289 + return true
  290 + end
  291 + end
  292 +
  293 + false
  294 + end
  295 +
  296 + # Respond to the first format given if Mime::ALL is included in the
  297 + # mime type priorites. This is the behaviour expected when the client
  298 + # sends "*/*" as mime type.
  299 + #
  300 + def respond_any
  301 + any = @responses[@order.include?(Mime::ALL) ? Mime::ALL : @order.first]
  302 +
  303 + if any && @mime_type_priority.include?(Mime::ALL)
  304 + any.call
  305 + return true
  306 + end
  307 + end
  308 +
  309 + # Receives an format and checks if the current action responds to
  310 + # the given format. If additional mimes are sent, only them are checked.
  311 + #
  312 + def action_respond_to_format?(format, additional_mimes = [])
  313 + if !additional_mimes.blank?
  314 + additional_mimes.include?(format.to_sym)
  315 + elsif formats = @controller.formats_for_respond_to[format.to_sym]
  316 + if formats[:only]
  317 + formats[:only].include?(@controller.action_name.to_sym)
  318 + elsif formats[:except]
  319 + !formats[:except].include?(@controller.action_name.to_sym)
  320 + else
  321 + true
  322 + end
  323 + else
  324 + false
  325 + end
  326 + end
  327 +
  328 + # Makes a given format the first in the @order array.
  329 + #
  330 + def prioritize(format)
  331 + if index = @order.index(format)
  332 + @order.unshift(@order.delete_at(index))
  333 + end
  334 + @order
  335 + end
  336 +
  337 + end
  338 + end
  339 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/singleton_helpers.rb 0 → 100644
... ... @@ -0,0 +1,95 @@
  1 +module InheritedResources
  2 +
  3 + # = singleton
  4 + #
  5 + # Singletons are usually used in associations which are related through has_one
  6 + # and belongs_to. You declare those associations like this:
  7 + #
  8 + # class ManagersController < InheritedResources::Base
  9 + # belongs_to :project, :singleton => true
  10 + # end
  11 + #
  12 + # But in some cases, like an AccountsController, you have a singleton object
  13 + # that is not necessarily associated with another:
  14 + #
  15 + # class AccountsController < InheritedResources::Base
  16 + # defaults :singleton => true
  17 + # end
  18 + #
  19 + # Besides that, you should overwrite the methods :resource and :build_resource
  20 + # to make it work properly:
  21 + #
  22 + # class AccountsController < InheritedResources::Base
  23 + # defaults :singleton => true
  24 + #
  25 + # protected
  26 + # def resource
  27 + # @current_user.account
  28 + # end
  29 + #
  30 + # def build_resource(attributes = {})
  31 + # Account.new(attributes)
  32 + # end
  33 + # end
  34 + #
  35 + # When you have a singleton controller, the action index is removed.
  36 + #
  37 + module SingletonHelpers
  38 +
  39 + protected
  40 +
  41 + # Singleton methods does not deal with collections.
  42 + #
  43 + def collection
  44 + nil
  45 + end
  46 +
  47 + # Overwrites how singleton deals with resource.
  48 + #
  49 + # If you are going to overwrite it, you should notice that the
  50 + # end_of_association_chain here is not the same as in default belongs_to.
  51 + #
  52 + # class TasksController < InheritedResources::Base
  53 + # belongs_to :project
  54 + # end
  55 + #
  56 + # In this case, the association chain would be:
  57 + #
  58 + # Project.find(params[:project_id]).tasks
  59 + #
  60 + # So you would just have to call find(:all) at the end of association
  61 + # chain. And this is what happened.
  62 + #
  63 + # In singleton controllers:
  64 + #
  65 + # class ManagersController < InheritedResources::Base
  66 + # belongs_to :project, :singleton => true
  67 + # end
  68 + #
  69 + # The association chain will be:
  70 + #
  71 + # Project.find(params[:project_id])
  72 + #
  73 + # So we have to call manager on it, not find.
  74 + #
  75 + def resource
  76 + get_resource_ivar || set_resource_ivar(end_of_association_chain.send(resource_instance_name))
  77 + end
  78 +
  79 + private
  80 +
  81 + # Returns the appropriated method to build the resource.
  82 + #
  83 + def method_for_association_build #:nodoc:
  84 + :"build_#{resource_instance_name}"
  85 + end
  86 +
  87 + # Sets the method_for_association_chain to nil. See <tt>resource</tt>
  88 + # above for more information.
  89 + #
  90 + def method_for_association_chain #:nodoc:
  91 + nil
  92 + end
  93 +
  94 + end
  95 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/lib/inherited_resources/url_helpers.rb 0 → 100644
... ... @@ -0,0 +1,173 @@
  1 +module InheritedResources
  2 + # = URLHelpers
  3 + #
  4 + # When you use InheritedResources it creates some UrlHelpers for you.
  5 + # And they handle everything for you.
  6 + #
  7 + # # /posts/1/comments
  8 + # resource_url # => /posts/1/comments/#{@comment.to_param}
  9 + # resource_url(comment) # => /posts/1/comments/#{comment.to_param}
  10 + # new_resource_url # => /posts/1/comments/new
  11 + # edit_resource_url # => /posts/1/comments/#{@comment.to_param}/edit
  12 + # collection_url # => /posts/1/comments
  13 + #
  14 + # # /projects/1/tasks
  15 + # resource_url # => /products/1/tasks/#{@task.to_param}
  16 + # resource_url(task) # => /products/1/tasks/#{task.to_param}
  17 + # new_resource_url # => /products/1/tasks/new
  18 + # edit_resource_url # => /products/1/tasks/#{@task.to_param}/edit
  19 + # collection_url # => /products/1/tasks
  20 + #
  21 + # # /users
  22 + # resource_url # => /users/#{@user.to_param}
  23 + # resource_url(user) # => /users/#{user.to_param}
  24 + # new_resource_url # => /users/new
  25 + # edit_resource_url # => /users/#{@user.to_param}/edit
  26 + # collection_url # => /users
  27 + #
  28 + # The nice thing is that those urls are not guessed during runtime. They are
  29 + # all created when you inherit.
  30 + #
  31 + module UrlHelpers
  32 +
  33 + # This method hard code url helpers in the class.
  34 + #
  35 + # We are doing this because is cheaper than guessing them when our action
  36 + # is being processed (and even more cheaper when we are using nested
  37 + # resources).
  38 + #
  39 + # When we are using polymorphic associations, those helpers rely on
  40 + # polymorphic_url Rails helper.
  41 + #
  42 + def create_resources_url_helpers!
  43 + resource_segments, resource_ivars = [], []
  44 + resource_config = self.resources_configuration[:self]
  45 +
  46 + singleton = self.resources_configuration[:self][:singleton]
  47 + polymorphic = self.parents_symbols.include?(:polymorphic)
  48 +
  49 + # Add route_prefix if any.
  50 + unless resource_config[:route_prefix].blank?
  51 + if polymorphic
  52 + resource_ivars << resource_config[:route_prefix].to_s.inspect
  53 + else
  54 + resource_segments << resource_config[:route_prefix]
  55 + end
  56 + end
  57 +
  58 + # Deal with belongs_to associations and polymorphic associations.
  59 + # Remember that we don't have to build the segments in polymorphic cases,
  60 + # because the url will be polymorphic_url.
  61 + #
  62 + self.parents_symbols.each do |symbol|
  63 + if symbol == :polymorphic
  64 + resource_ivars << :parent
  65 + else
  66 + config = self.resources_configuration[symbol]
  67 + resource_segments << config[:route_name]
  68 + resource_ivars << :"@#{config[:instance_name]}"
  69 + end
  70 + end
  71 +
  72 + collection_ivars = resource_ivars.dup
  73 + collection_segments = resource_segments.dup
  74 +
  75 + # This is the default route configuration, later we have to deal with
  76 + # exception from polymorphic and singleton cases.
  77 + #
  78 + collection_segments << resource_config[:route_collection_name]
  79 + resource_segments << resource_config[:route_instance_name]
  80 + resource_ivars << :"@#{resource_config[:instance_name]}"
  81 +
  82 + # In singleton cases, we do not send the current element instance variable
  83 + # because the id is not in the URL. For example, we should call:
  84 + #
  85 + # project_manager_url(@project)
  86 + #
  87 + # Instead of:
  88 + #
  89 + # project_manager_url(@project, @manager)
  90 + #
  91 + # Another exception in singleton cases is that collection url does not
  92 + # exist. In such cases, we create the parent collection url. So in the
  93 + # manager case above, the collection url will be:
  94 + #
  95 + # project_url(@project)
  96 + #
  97 + # If the singleton does not have a parent, it will default to root_url.
  98 + #
  99 + # Finally, polymorphic cases we have to give hints to the polymorphic url
  100 + # builder. This works by attaching new ivars as symbols or records.
  101 + #
  102 + if singleton
  103 + collection_segments.pop
  104 + resource_ivars.pop
  105 +
  106 + if polymorphic
  107 + resource_ivars << resource_config[:instance_name].inspect
  108 + new_ivars = resource_ivars
  109 + end
  110 + elsif polymorphic
  111 + collection_ivars << '(@_resource_class_new ||= resource_class.new)'
  112 + end
  113 +
  114 + generate_url_and_path_helpers nil, :collection, collection_segments, collection_ivars
  115 + generate_url_and_path_helpers :new, :resource, resource_segments, new_ivars || collection_ivars
  116 + generate_url_and_path_helpers nil, :resource, resource_segments, resource_ivars
  117 + generate_url_and_path_helpers :edit, :resource, resource_segments, resource_ivars
  118 + end
  119 +
  120 + def generate_url_and_path_helpers(prefix, name, resource_segments, resource_ivars) #:nodoc:
  121 + ivars = resource_ivars.dup
  122 +
  123 + singleton = self.resources_configuration[:self][:singleton]
  124 + polymorphic = self.parents_symbols.include?(:polymorphic)
  125 +
  126 + # If it's not a singleton, ivars are not empty, not a collection or
  127 + # not a "new" named route, we can pass a resource as argument.
  128 + #
  129 + unless singleton || ivars.empty? || name == :collection || prefix == :new
  130 + ivars.push "(given_args.first || #{ivars.pop})"
  131 + end
  132 +
  133 + # In collection in polymorphic cases, allow an argument to be given as a
  134 + # replacemente for the parent.
  135 + #
  136 + if name == :collection && polymorphic
  137 + index = ivars.index(:parent)
  138 + ivars.insert index, "(given_args.first || parent)"
  139 + ivars.delete(:parent)
  140 + end
  141 +
  142 + # When polymorphic is true, the segments must be replace by :polymorphic
  143 + # and ivars should be gathered into an array, which is compacted when
  144 + # optional.
  145 + #
  146 + if polymorphic
  147 + segments = :polymorphic
  148 + ivars = "[#{ivars.join(', ')}]"
  149 + ivars << '.compact' if self.resources_configuration[:polymorphic][:optional]
  150 + else
  151 + segments = resource_segments.empty? ? 'root' : resource_segments.join('_')
  152 + ivars = ivars.join(', ')
  153 + end
  154 +
  155 + prefix = prefix ? "#{prefix}_" : ''
  156 + ivars << (ivars.empty? ? 'given_options' : ', given_options')
  157 +
  158 + class_eval <<-URL_HELPERS, __FILE__, __LINE__
  159 + protected
  160 + def #{prefix}#{name}_path(*given_args)
  161 + given_options = given_args.extract_options!
  162 + #{prefix}#{segments}_path(#{ivars})
  163 + end
  164 +
  165 + def #{prefix}#{name}_url(*given_args)
  166 + given_options = given_args.extract_options!
  167 + #{prefix}#{segments}_url(#{ivars})
  168 + end
  169 + URL_HELPERS
  170 + end
  171 +
  172 + end
  173 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/aliases_test.rb 0 → 100644
... ... @@ -0,0 +1,134 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Student;
  4 + def self.human_name; 'Student'; end
  5 +end
  6 +
  7 +class StudentsController < ApplicationController
  8 + inherit_resources
  9 +
  10 + def edit
  11 + edit! do |format|
  12 + format.xml { render :text => 'Render XML' }
  13 + end
  14 + end
  15 +
  16 + def new
  17 + @something = 'magical'
  18 + new!
  19 + end
  20 +
  21 + def create
  22 + create! do |success, failure|
  23 + success.html { render :text => "I won't redirect!" }
  24 + failure.xml { render :text => "I shouldn't be rendered" }
  25 + end
  26 + end
  27 +
  28 + def update
  29 + update! do |success, failure|
  30 + success.html { redirect_to(resource_url) }
  31 + failure.html { render :text => "I won't render!" }
  32 + end
  33 + end
  34 +
  35 + def destroy
  36 + destroy! do |format|
  37 + format.html { render :text => "Destroyed!" }
  38 + end
  39 + end
  40 +
  41 +end
  42 +
  43 +class AliasesTest < ActionController::TestCase
  44 + tests StudentsController
  45 +
  46 + def test_assignments_before_calling_alias
  47 + Student.stubs(:new).returns(mock_student)
  48 + get :new
  49 + assert_response :success
  50 + assert_equal 'magical', assigns(:something)
  51 + end
  52 +
  53 + def test_controller_should_render_new
  54 + Student.stubs(:new).returns(mock_student)
  55 + get :new
  56 + assert_response :success
  57 + assert_equal 'New HTML', @response.body.strip
  58 + end
  59 +
  60 + def test_expose_the_resquested_user_on_edit
  61 + Student.expects(:find).with('42').returns(mock_student)
  62 + get :edit, :id => '42'
  63 + assert_equal mock_student, assigns(:student)
  64 + assert_response :success
  65 + end
  66 +
  67 + def test_controller_should_render_edit
  68 + Student.stubs(:find).returns(mock_student)
  69 + get :edit
  70 + assert_response :success
  71 + assert_equal 'Edit HTML', @response.body.strip
  72 + end
  73 +
  74 + def test_render_xml_when_it_is_given_as_a_block
  75 + @request.accept = 'application/xml'
  76 + Student.stubs(:find).returns(mock_student)
  77 + get :edit
  78 + assert_response :success
  79 + assert_equal 'Render XML', @response.body
  80 + end
  81 +
  82 + def test_is_not_redirected_on_create_with_success_if_success_block_is_given
  83 + Student.stubs(:new).returns(mock_student(:save => true))
  84 + @controller.stubs(:resource_url).returns('http://test.host/')
  85 + post :create
  86 + assert_response :success
  87 + assert_equal "I won't redirect!", @response.body
  88 + end
  89 +
  90 + def test_dumb_responder_quietly_receives_everything_on_failure
  91 + @request.accept = 'text/html'
  92 + Student.stubs(:new).returns(mock_student(:save => false, :errors => []))
  93 + @controller.stubs(:resource_url).returns('http://test.host/')
  94 + post :create
  95 + assert_response :success
  96 + assert_equal "New HTML", @response.body.strip
  97 + end
  98 +
  99 + def test_html_is_the_default_when_only_xml_is_overwriten
  100 + @request.accept = '*/*'
  101 + Student.stubs(:new).returns(mock_student(:save => false, :errors => []))
  102 + @controller.stubs(:resource_url).returns('http://test.host/')
  103 + post :create
  104 + assert_response :success
  105 + assert_equal "New HTML", @response.body.strip
  106 + end
  107 +
  108 + def test_wont_render_edit_template_on_update_with_failure_if_failure_block_is_given
  109 + Student.stubs(:find).returns(mock_student(:update_attributes => false, :errors => []))
  110 + put :update
  111 + assert_response :success
  112 + assert_equal "I won't render!", @response.body
  113 + end
  114 +
  115 + def test_dumb_responder_quietly_receives_everything_on_success
  116 + Student.stubs(:find).returns(mock_student(:update_attributes => true))
  117 + @controller.stubs(:resource_url).returns('http://test.host/')
  118 + put :update, :id => '42', :student => {:these => 'params'}
  119 + assert_equal mock_student, assigns(:student)
  120 + end
  121 +
  122 + def test_block_is_called_when_student_is_destroyed
  123 + Student.stubs(:find).returns(mock_student(:destroy => true))
  124 + delete :destroy
  125 + assert_response :success
  126 + assert_equal "Destroyed!", @response.body
  127 + end
  128 +
  129 + protected
  130 + def mock_student(stubs={})
  131 + @mock_student ||= mock(stubs)
  132 + end
  133 +end
  134 +
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/base_helpers_test.rb 0 → 100644
... ... @@ -0,0 +1,70 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Pet
  4 + def self.human_name; 'Pet'; end
  5 +end
  6 +
  7 +class PetsController < InheritedResources::Base
  8 + attr_accessor :current_user
  9 +
  10 + def edit
  11 + @pet = 'new pet'
  12 + edit!
  13 + end
  14 +
  15 + protected
  16 + def collection
  17 + @pets ||= end_of_association_chain.all
  18 + end
  19 +
  20 + def begin_of_association_chain
  21 + @current_user
  22 + end
  23 +end
  24 +
  25 +class AssociationChainBaseHelpersTest < ActionController::TestCase
  26 + tests PetsController
  27 +
  28 + def setup
  29 + @controller.current_user = mock()
  30 + end
  31 +
  32 + def test_begin_of_association_chain_is_called_on_index
  33 + @controller.current_user.expects(:pets).returns(Pet)
  34 + Pet.expects(:all).returns(mock_pet)
  35 + get :index
  36 + assert_response :success
  37 + assert 'Index HTML', @response.body.strip
  38 + end
  39 +
  40 + def test_begin_of_association_chain_is_called_on_new
  41 + @controller.current_user.expects(:pets).returns(Pet)
  42 + Pet.expects(:build).returns(mock_pet)
  43 + get :new
  44 + assert_response :success
  45 + assert 'New HTML', @response.body.strip
  46 + end
  47 +
  48 + def test_begin_of_association_chain_is_called_on_show
  49 + @controller.current_user.expects(:pets).returns(Pet)
  50 + Pet.expects(:find).with('47').returns(mock_pet)
  51 + get :show, :id => '47'
  52 + assert_response :success
  53 + assert 'Show HTML', @response.body.strip
  54 + end
  55 +
  56 + def test_instance_variable_should_not_be_set_if_already_defined
  57 + @controller.current_user.expects(:pets).never
  58 + Pet.expects(:find).never
  59 + get :edit
  60 + assert_response :success
  61 + assert_equal 'new pet', assigns(:pet)
  62 + end
  63 +
  64 + protected
  65 + def mock_pet(stubs={})
  66 + @mock_pet ||= mock(stubs)
  67 + end
  68 +
  69 +end
  70 +
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/base_test.rb 0 → 100644
... ... @@ -0,0 +1,219 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class User
  4 + def self.human_name; 'User'; end
  5 +end
  6 +
  7 +class AccountsController < InheritedResources::Base
  8 +end
  9 +
  10 +class UsersController < AccountsController
  11 + respond_to :html, :xml
  12 +end
  13 +
  14 +module UserTestHelper
  15 + def setup
  16 + @controller = UsersController.new
  17 + @controller.request = @request = ActionController::TestRequest.new
  18 + @controller.response = @response = ActionController::TestResponse.new
  19 + end
  20 +
  21 + protected
  22 + def mock_user(stubs={})
  23 + @mock_user ||= mock(stubs)
  24 + end
  25 +end
  26 +
  27 +class IndexActionBaseTest < ActionController::TestCase
  28 + include UserTestHelper
  29 +
  30 + def test_expose_all_users_as_instance_variable
  31 + User.expects(:find).with(:all).returns([mock_user])
  32 + get :index
  33 + assert_equal [mock_user], assigns(:users)
  34 + end
  35 +
  36 + def test_controller_should_render_index
  37 + User.stubs(:find).returns([mock_user])
  38 + get :index
  39 + assert_response :success
  40 + assert_equal 'Index HTML', @response.body.strip
  41 + end
  42 +
  43 + def test_render_all_users_as_xml_when_mime_type_is_xml
  44 + @request.accept = 'application/xml'
  45 + User.expects(:find).with(:all).returns(mock_user)
  46 + mock_user.expects(:to_xml).returns('Generated XML')
  47 + get :index
  48 + assert_response :success
  49 + assert_equal 'Generated XML', @response.body
  50 + end
  51 +end
  52 +
  53 +class ShowActionBaseTest < ActionController::TestCase
  54 + include UserTestHelper
  55 +
  56 + def test_expose_the_resquested_user
  57 + User.expects(:find).with('42').returns(mock_user)
  58 + get :show, :id => '42'
  59 + assert_equal mock_user, assigns(:user)
  60 + end
  61 +
  62 + def test_controller_should_render_show
  63 + User.stubs(:find).returns(mock_user)
  64 + get :show
  65 + assert_response :success
  66 + assert_equal 'Show HTML', @response.body.strip
  67 + end
  68 +
  69 + def test_render_exposed_user_as_xml_when_mime_type_is_xml
  70 + @request.accept = 'application/xml'
  71 + User.expects(:find).with('42').returns(mock_user)
  72 + mock_user.expects(:to_xml).returns("Generated XML")
  73 + get :show, :id => '42'
  74 + assert_response :success
  75 + assert_equal 'Generated XML', @response.body
  76 + end
  77 +end
  78 +
  79 +class NewActionBaseTest < ActionController::TestCase
  80 + include UserTestHelper
  81 +
  82 + def test_expose_a_new_user
  83 + User.expects(:new).returns(mock_user)
  84 + get :new
  85 + assert_equal mock_user, assigns(:user)
  86 + end
  87 +
  88 + def test_controller_should_render_new
  89 + User.stubs(:new).returns(mock_user)
  90 + get :new
  91 + assert_response :success
  92 + assert_equal 'New HTML', @response.body.strip
  93 + end
  94 +
  95 + def test_render_exposed_a_new_user_as_xml_when_mime_type_is_xml
  96 + @request.accept = 'application/xml'
  97 + User.expects(:new).returns(mock_user)
  98 + mock_user.expects(:to_xml).returns("Generated XML")
  99 + get :new
  100 + assert_response :success
  101 + assert_equal 'Generated XML', @response.body
  102 + end
  103 +end
  104 +
  105 +class EditActionBaseTest < ActionController::TestCase
  106 + include UserTestHelper
  107 +
  108 + def test_expose_the_resquested_user
  109 + User.expects(:find).with('42').returns(mock_user)
  110 + get :edit, :id => '42'
  111 + assert_response :success
  112 + assert_equal mock_user, assigns(:user)
  113 + end
  114 +
  115 + def test_controller_should_render_edit
  116 + User.stubs(:find).returns(mock_user)
  117 + get :edit
  118 + assert_response :success
  119 + assert_equal 'Edit HTML', @response.body.strip
  120 + end
  121 +end
  122 +
  123 +class CreateActionBaseTest < ActionController::TestCase
  124 + include UserTestHelper
  125 +
  126 + def test_expose_a_newly_create_user_when_saved_with_success
  127 + User.expects(:new).with({'these' => 'params'}).returns(mock_user(:save => true))
  128 + post :create, :user => {:these => 'params'}
  129 + assert_equal mock_user, assigns(:user)
  130 + end
  131 +
  132 + def test_redirect_to_the_created_user
  133 + User.stubs(:new).returns(mock_user(:save => true))
  134 + @controller.expects(:resource_url).returns('http://test.host/').times(2)
  135 + post :create
  136 + assert_redirected_to 'http://test.host/'
  137 + end
  138 +
  139 + def test_show_flash_message_when_success
  140 + User.stubs(:new).returns(mock_user(:save => true))
  141 + post :create
  142 + assert_equal flash[:notice], 'User was successfully created.'
  143 + end
  144 +
  145 + def test_render_new_template_when_user_cannot_be_saved
  146 + User.stubs(:new).returns(mock_user(:save => false, :errors => []))
  147 + post :create
  148 + assert_response :success
  149 + assert_template :new
  150 + end
  151 +
  152 + def test_dont_show_flash_message_when_user_cannot_be_saved
  153 + User.stubs(:new).returns(mock_user(:save => false, :errors => []))
  154 + post :create
  155 + assert flash.empty?
  156 + end
  157 +end
  158 +
  159 +class UpdateActionBaseTest < ActionController::TestCase
  160 + include UserTestHelper
  161 +
  162 + def test_update_the_requested_object
  163 + User.expects(:find).with('42').returns(mock_user)
  164 + mock_user.expects(:update_attributes).with({'these' => 'params'}).returns(true)
  165 + put :update, :id => '42', :user => {:these => 'params'}
  166 + assert_equal mock_user, assigns(:user)
  167 + end
  168 +
  169 + def test_redirect_to_the_created_user
  170 + User.stubs(:find).returns(mock_user(:update_attributes => true))
  171 + @controller.expects(:resource_url).returns('http://test.host/')
  172 + put :update
  173 + assert_redirected_to 'http://test.host/'
  174 + end
  175 +
  176 + def test_show_flash_message_when_success
  177 + User.stubs(:find).returns(mock_user(:update_attributes => true))
  178 + put :update
  179 + assert_equal flash[:notice], 'User was successfully updated.'
  180 + end
  181 +
  182 + def test_render_edit_template_when_user_cannot_be_saved
  183 + User.stubs(:find).returns(mock_user(:update_attributes => false, :errors => []))
  184 + put :update
  185 + assert_response :success
  186 + assert_template :edit
  187 + end
  188 +
  189 + def test_dont_show_flash_message_when_user_cannot_be_saved
  190 + User.stubs(:find).returns(mock_user(:update_attributes => false, :errors => []))
  191 + put :update
  192 + assert flash.empty?
  193 + end
  194 +end
  195 +
  196 +class DestroyActionBaseTest < ActionController::TestCase
  197 + include UserTestHelper
  198 +
  199 + def test_the_resquested_user_is_destroyed
  200 + User.expects(:find).with('42').returns(mock_user)
  201 + mock_user.expects(:destroy)
  202 + delete :destroy, :id => '42'
  203 + assert_equal mock_user, assigns(:user)
  204 + end
  205 +
  206 + def test_show_flash_message
  207 + User.stubs(:find).returns(mock_user(:destroy => true))
  208 + delete :destroy
  209 + assert_equal flash[:notice], 'User was successfully destroyed.'
  210 + end
  211 +
  212 + def test_redirects_to_users_list
  213 + User.stubs(:find).returns(mock_user(:destroy => true))
  214 + @controller.expects(:collection_url).returns('http://test.host/')
  215 + delete :destroy
  216 + assert_redirected_to 'http://test.host/'
  217 + end
  218 +end
  219 +
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/belongs_to_test.rb 0 → 100644
... ... @@ -0,0 +1,87 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Post
  4 +end
  5 +
  6 +class Comment
  7 + def self.human_name; 'Comment'; end
  8 +end
  9 +
  10 +class CommentsController < InheritedResources::Base
  11 + belongs_to :post
  12 +end
  13 +
  14 +class BelongsToTest < ActionController::TestCase
  15 + tests CommentsController
  16 +
  17 + def setup
  18 + Post.expects(:find).with('37').returns(mock_post)
  19 + mock_post.expects(:comments).returns(Comment)
  20 +
  21 + @controller.stubs(:resource_url).returns('/')
  22 + @controller.stubs(:collection_url).returns('/')
  23 + end
  24 +
  25 + def test_expose_all_comments_as_instance_variable_on_index
  26 + Comment.expects(:find).with(:all).returns([mock_comment])
  27 + get :index, :post_id => '37'
  28 + assert_equal mock_post, assigns(:post)
  29 + assert_equal [mock_comment], assigns(:comments)
  30 + end
  31 +
  32 + def test_expose_the_resquested_comment_on_show
  33 + Comment.expects(:find).with('42').returns(mock_comment)
  34 + get :show, :id => '42', :post_id => '37'
  35 + assert_equal mock_post, assigns(:post)
  36 + assert_equal mock_comment, assigns(:comment)
  37 + end
  38 +
  39 + def test_expose_a_new_comment_on_new
  40 + Comment.expects(:build).returns(mock_comment)
  41 + get :new, :post_id => '37'
  42 + assert_equal mock_post, assigns(:post)
  43 + assert_equal mock_comment, assigns(:comment)
  44 + end
  45 +
  46 + def test_expose_the_resquested_comment_on_edit
  47 + Comment.expects(:find).with('42').returns(mock_comment)
  48 + get :edit, :id => '42', :post_id => '37'
  49 + assert_equal mock_post, assigns(:post)
  50 + assert_equal mock_comment, assigns(:comment)
  51 + end
  52 +
  53 + def test_expose_a_newly_create_comment_on_create
  54 + Comment.expects(:build).with({'these' => 'params'}).returns(mock_comment(:save => true))
  55 + post :create, :post_id => '37', :comment => {:these => 'params'}
  56 + assert_equal mock_post, assigns(:post)
  57 + assert_equal mock_comment, assigns(:comment)
  58 + end
  59 +
  60 + def test_update_the_requested_object_on_update
  61 + Comment.expects(:find).with('42').returns(mock_comment)
  62 + mock_comment.expects(:update_attributes).with({'these' => 'params'}).returns(true)
  63 + put :update, :id => '42', :post_id => '37', :comment => {:these => 'params'}
  64 + assert_equal mock_post, assigns(:post)
  65 + assert_equal mock_comment, assigns(:comment)
  66 + end
  67 +
  68 + def test_the_resquested_comment_is_destroyed_on_destroy
  69 + Comment.expects(:find).with('42').returns(mock_comment)
  70 + mock_comment.expects(:destroy)
  71 + delete :destroy, :id => '42', :post_id => '37'
  72 + assert_equal mock_post, assigns(:post)
  73 + assert_equal mock_comment, assigns(:comment)
  74 + end
  75 +
  76 + protected
  77 +
  78 + def mock_post(stubs={})
  79 + @mock_post ||= mock(stubs)
  80 + end
  81 +
  82 + def mock_comment(stubs={})
  83 + @mock_comment ||= mock(stubs)
  84 + end
  85 +
  86 +end
  87 +
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/class_methods_test.rb 0 → 100644
... ... @@ -0,0 +1,137 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Book; end
  4 +class Folder; end
  5 +
  6 +class BooksController < InheritedResources::Base
  7 + actions :index, :show
  8 +end
  9 +
  10 +class ReadersController < InheritedResources::Base
  11 + actions :all, :except => [ :edit, :update ]
  12 +end
  13 +
  14 +class FoldersController < InheritedResources::Base
  15 +end
  16 +
  17 +class Dean
  18 + def self.human_name; 'Dean'; end
  19 +end
  20 +
  21 +class SchoolsController < InheritedResources::Base
  22 + has_scope :by_city
  23 + has_scope :featured, :boolean => true, :only => :index, :key => :by_featured
  24 +end
  25 +
  26 +class DeansController < InheritedResources::Base
  27 + belongs_to :school
  28 +end
  29 +
  30 +
  31 +class ActionsClassMethodTest < ActiveSupport::TestCase
  32 + def test_actions_are_undefined
  33 + action_methods = BooksController.send(:action_methods)
  34 + assert_equal 2, action_methods.size
  35 +
  36 + ['index', 'show'].each do |action|
  37 + assert action_methods.include? action
  38 + end
  39 + end
  40 +
  41 + def test_actions_are_undefined_when_except_option_is_given
  42 + action_methods = ReadersController.send(:action_methods)
  43 + assert_equal 5, action_methods.size
  44 +
  45 + ['index', 'new', 'show', 'create', 'destroy'].each do |action|
  46 + assert action_methods.include? action
  47 + end
  48 + end
  49 +end
  50 +
  51 +
  52 +class DefaultsClassMethodTest < ActiveSupport::TestCase
  53 + def test_resource_class_is_set_to_nil_when_resource_model_cannot_be_found
  54 + assert_nil ReadersController.send(:resource_class)
  55 + end
  56 +
  57 + def test_defaults_are_set
  58 + assert Folder, FoldersController.send(:resource_class)
  59 + assert :folder, FoldersController.send(:resources_configuration)[:self][:instance_name]
  60 + assert :folders, FoldersController.send(:resources_configuration)[:self][:collection_name]
  61 + end
  62 +
  63 + def test_defaults_can_be_overwriten
  64 + BooksController.send(:defaults, :resource_class => String, :instance_name => 'string', :collection_name => 'strings')
  65 +
  66 + assert String, BooksController.send(:resource_class)
  67 + assert :string, BooksController.send(:resources_configuration)[:self][:instance_name]
  68 + assert :strings, BooksController.send(:resources_configuration)[:self][:collection_name]
  69 +
  70 + BooksController.send(:defaults, :class_name => 'Fixnum', :instance_name => :fixnum, :collection_name => :fixnums)
  71 +
  72 + assert String, BooksController.send(:resource_class)
  73 + assert :string, BooksController.send(:resources_configuration)[:self][:instance_name]
  74 + assert :strings, BooksController.send(:resources_configuration)[:self][:collection_name]
  75 + end
  76 +
  77 + def test_defaults_raises_invalid_key
  78 + assert_raise ArgumentError do
  79 + BooksController.send(:defaults, :boom => String)
  80 + end
  81 + end
  82 +
  83 + def test_url_helpers_are_recreated_when_defaults_change
  84 + BooksController.expects(:create_resources_url_helpers!).returns(true).once
  85 + BooksController.send(:defaults, :instance_name => 'string', :collection_name => 'strings')
  86 + end
  87 +end
  88 +
  89 +class BelongsToErrorsTest < ActiveSupport::TestCase
  90 + def test_belongs_to_raise_errors_with_invalid_arguments
  91 + assert_raise ArgumentError do
  92 + DeansController.send(:belongs_to)
  93 + end
  94 +
  95 + assert_raise ArgumentError do
  96 + DeansController.send(:belongs_to, :nice, :invalid_key => '')
  97 + end
  98 + end
  99 +
  100 + def test_belongs_to_raises_an_error_when_multiple_associations_are_given_with_options
  101 + assert_raise ArgumentError do
  102 + DeansController.send(:belongs_to, :arguments, :with_options, :parent_class => Professor)
  103 + end
  104 + end
  105 +
  106 + def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_block
  107 + DeansController.expects(:create_resources_url_helpers!).returns(true).once
  108 + DeansController.send(:belongs_to, :school) do
  109 + belongs_to :association
  110 + end
  111 + ensure
  112 + DeansController.send(:parents_symbols=, [:school])
  113 + end
  114 +
  115 + def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_multiple_blocks
  116 + DeansController.expects(:create_resources_url_helpers!).returns(true).once
  117 + DeansController.send(:belongs_to, :school) do
  118 + belongs_to :association do
  119 + belongs_to :nested
  120 + end
  121 + end
  122 + ensure
  123 + DeansController.send(:parents_symbols=, [:school])
  124 + end
  125 +end
  126 +
  127 +class HasScopeClassMethods < ActiveSupport::TestCase
  128 + def test_scope_configuration_is_stored_as_hashes
  129 + config = SchoolsController.send(:scopes_configuration)
  130 +
  131 + assert config.key?(:by_city)
  132 + assert config.key?(:featured)
  133 +
  134 + assert_equal config[:by_city], { :key => :by_city, :only => [], :except => [] }
  135 + assert_equal config[:featured], { :key => :by_featured, :only => [ :index ], :except => [], :boolean => true }
  136 + end
  137 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/customized_belongs_to_test.rb 0 → 100644
... ... @@ -0,0 +1,76 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class GreatSchool
  4 +end
  5 +
  6 +class Professor
  7 + def self.human_name; 'Professor'; end
  8 +end
  9 +
  10 +class ProfessorsController < InheritedResources::Base
  11 + belongs_to :school, :parent_class => GreatSchool, :instance_name => :great_school,
  12 + :finder => :find_by_title!, :param => :school_title
  13 +end
  14 +
  15 +class CustomizedBelongsToTest < ActionController::TestCase
  16 + tests ProfessorsController
  17 +
  18 + def setup
  19 + GreatSchool.expects(:find_by_title!).with('nice').returns(mock_school(:professors => Professor))
  20 + @controller.stubs(:resource_url).returns('/')
  21 + @controller.stubs(:collection_url).returns('/')
  22 + end
  23 +
  24 + def test_expose_the_resquested_school_with_chosen_instance_variable_on_index
  25 + Professor.stubs(:find).returns([mock_professor])
  26 + get :index, :school_title => 'nice'
  27 + assert_equal mock_school, assigns(:great_school)
  28 + end
  29 +
  30 + def test_expose_the_resquested_school_with_chosen_instance_variable_on_show
  31 + Professor.stubs(:find).returns(mock_professor)
  32 + get :show, :school_title => 'nice'
  33 + assert_equal mock_school, assigns(:great_school)
  34 + end
  35 +
  36 + def test_expose_the_resquested_school_with_chosen_instance_variable_on_new
  37 + Professor.stubs(:build).returns(mock_professor)
  38 + get :new, :school_title => 'nice'
  39 + assert_equal mock_school, assigns(:great_school)
  40 + end
  41 +
  42 + def test_expose_the_resquested_school_with_chosen_instance_variable_on_edit
  43 + Professor.stubs(:find).returns(mock_professor)
  44 + get :edit, :school_title => 'nice'
  45 + assert_equal mock_school, assigns(:great_school)
  46 + end
  47 +
  48 + def test_expose_the_resquested_school_with_chosen_instance_variable_on_create
  49 + Professor.stubs(:build).returns(mock_professor(:save => true))
  50 + post :create, :school_title => 'nice'
  51 + assert_equal mock_school, assigns(:great_school)
  52 + end
  53 +
  54 + def test_expose_the_resquested_school_with_chosen_instance_variable_on_update
  55 + Professor.stubs(:find).returns(mock_professor(:update_attributes => true))
  56 + put :update, :school_title => 'nice'
  57 + assert_equal mock_school, assigns(:great_school)
  58 + end
  59 +
  60 + def test_expose_the_resquested_school_with_chosen_instance_variable_on_destroy
  61 + Professor.stubs(:find).returns(mock_professor(:destroy => true))
  62 + delete :destroy, :school_title => 'nice'
  63 + assert_equal mock_school, assigns(:great_school)
  64 + end
  65 +
  66 + protected
  67 +
  68 + def mock_school(stubs={})
  69 + @mock_school ||= mock(stubs)
  70 + end
  71 +
  72 + def mock_professor(stubs={})
  73 + @mock_professor ||= mock(stubs)
  74 + end
  75 +end
  76 +
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/defaults_test.rb 0 → 100644
... ... @@ -0,0 +1,70 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Malarz
  4 + def self.human_name; 'Painter'; end
  5 +end
  6 +
  7 +class PaintersController < InheritedResources::Base
  8 + defaults :instance_name => 'malarz', :collection_name => 'malarze',
  9 + :resource_class => Malarz, :route_prefix => nil
  10 +end
  11 +
  12 +class DefaultsTest < ActionController::TestCase
  13 + tests PaintersController
  14 +
  15 + def setup
  16 + @controller.stubs(:resource_url).returns('/')
  17 + @controller.stubs(:collection_url).returns('/')
  18 + end
  19 +
  20 + def test_expose_all_painters_as_instance_variable
  21 + Malarz.expects(:find).with(:all).returns([mock_painter])
  22 + get :index
  23 + assert_equal [mock_painter], assigns(:malarze)
  24 + end
  25 +
  26 + def test_expose_the_resquested_painter_on_show
  27 + Malarz.expects(:find).with('42').returns(mock_painter)
  28 + get :show, :id => '42'
  29 + assert_equal mock_painter, assigns(:malarz)
  30 + end
  31 +
  32 + def test_expose_a_new_painter
  33 + Malarz.expects(:new).returns(mock_painter)
  34 + get :new
  35 + assert_equal mock_painter, assigns(:malarz)
  36 + end
  37 +
  38 + def test_expose_the_resquested_painter_on_edit
  39 + Malarz.expects(:find).with('42').returns(mock_painter)
  40 + get :edit, :id => '42'
  41 + assert_response :success
  42 + assert_equal mock_painter, assigns(:malarz)
  43 + end
  44 +
  45 + def test_expose_a_newly_create_painter_when_saved_with_success
  46 + Malarz.expects(:new).with({'these' => 'params'}).returns(mock_painter(:save => true))
  47 + post :create, :malarz => {:these => 'params'}
  48 + assert_equal mock_painter, assigns(:malarz)
  49 + end
  50 +
  51 + def test_update_the_requested_object
  52 + Malarz.expects(:find).with('42').returns(mock_painter)
  53 + mock_painter.expects(:update_attributes).with({'these' => 'params'}).returns(true)
  54 + put :update, :id => '42', :malarz => {:these => 'params'}
  55 + assert_equal mock_painter, assigns(:malarz)
  56 + end
  57 +
  58 + def test_the_resquested_painter_is_destroyed
  59 + Malarz.expects(:find).with('42').returns(mock_painter)
  60 + mock_painter.expects(:destroy)
  61 + delete :destroy, :id => '42'
  62 + assert_equal mock_painter, assigns(:malarz)
  63 + end
  64 +
  65 + protected
  66 + def mock_painter(stubs={})
  67 + @mock_painter ||= mock(stubs)
  68 + end
  69 +end
  70 +
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/flash_test.rb 0 → 100644
... ... @@ -0,0 +1,83 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Address
  4 + def self.human_name; 'Address'; end
  5 +end
  6 +
  7 +class AddressesController < InheritedResources::Base
  8 + protected
  9 + def interpolation_options
  10 + { :reference => 'Ocean Avenue' }
  11 + end
  12 +end
  13 +
  14 +module Admin; end
  15 +class Admin::AddressesController < InheritedResources::Base
  16 + protected
  17 + def interpolation_options
  18 + { :reference => 'Ocean Avenue' }
  19 + end
  20 +end
  21 +
  22 +class FlashBaseHelpersTest < ActionController::TestCase
  23 + tests AddressesController
  24 +
  25 + def setup
  26 + @request.accept = 'application/xml'
  27 + end
  28 +
  29 + def test_success_flash_message_on_create_with_yml
  30 + Address.stubs(:new).returns(mock_address(:save => true))
  31 + @controller.stubs(:address_url)
  32 + post :create
  33 + assert_equal 'You created a new address close to <b>Ocean Avenue</b>.', flash[:notice]
  34 + end
  35 +
  36 + def test_success_flash_message_on_create_with_namespaced_controller
  37 + @controller = Admin::AddressesController.new
  38 + Address.stubs(:new).returns(mock_address(:save => true))
  39 + @controller.stubs(:address_url)
  40 + post :create
  41 + assert_equal 'Admin, you created a new address close to <b>Ocean Avenue</b>.', flash[:notice]
  42 + end
  43 +
  44 + def test_failure_flash_message_on_create_with_namespaced_controller_actions
  45 + @controller = Admin::AddressesController.new
  46 + Address.stubs(:new).returns(mock_address(:save => false))
  47 + @controller.stubs(:address_url)
  48 + post :create
  49 + assert_equal 'Admin error message.', flash[:error]
  50 + end
  51 +
  52 + def test_inherited_success_flash_message_on_update_on_namespaced_controllers
  53 + @controller = Admin::AddressesController.new
  54 + Address.stubs(:find).returns(mock_address(:update_attributes => true))
  55 + put :update
  56 + assert_response :success
  57 + assert_equal 'Nice! Address was updated with success!', flash[:notice]
  58 + end
  59 +
  60 + def test_success_flash_message_on_update
  61 + Address.stubs(:find).returns(mock_address(:update_attributes => true))
  62 + put :update
  63 + assert_response :success
  64 + assert_equal 'Nice! Address was updated with success!', flash[:notice]
  65 + end
  66 +
  67 + def test_failure_flash_message_on_update
  68 + Address.stubs(:find).returns(mock_address(:update_attributes => false, :errors => []))
  69 + put :update
  70 + assert_equal 'Oh no! We could not update your address!', flash[:error]
  71 + end
  72 +
  73 + def test_success_flash_message_on_destroy
  74 + Address.stubs(:find).returns(mock_address(:destroy => true))
  75 + delete :destroy
  76 + assert_equal 'Address was successfully destroyed.', flash[:notice]
  77 + end
  78 +
  79 + protected
  80 + def mock_address(stubs={})
  81 + @mock_address ||= mock(stubs)
  82 + end
  83 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/has_scope_test.rb 0 → 100644
... ... @@ -0,0 +1,112 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Tree
  4 + def self.human_name; 'Tree'; end
  5 +end
  6 +
  7 +class TreesController < InheritedResources::Base
  8 + has_scope :color
  9 + has_scope :only_tall, :boolean => true, :only => :index
  10 + has_scope :shadown_range, :default => 10, :except => [ :index, :show, :destroy, :new ]
  11 + has_scope :root_type, :key => :root
  12 + has_scope :calculate_height, :default => proc {|c| c.session[:height] || 20 }, :only => :new
  13 +end
  14 +
  15 +class HasScopeTest < ActionController::TestCase
  16 + tests TreesController
  17 +
  18 + def setup
  19 + @controller.stubs(:resource_url).returns('/')
  20 + @controller.stubs(:collection_url).returns('/')
  21 + end
  22 +
  23 + def test_boolean_scope_is_called_when_boolean_param_is_true
  24 + Tree.expects(:only_tall).with().returns(Tree).in_sequence
  25 + Tree.expects(:find).with(:all).returns([mock_tree]).in_sequence
  26 + get :index, :only_tall => 'true'
  27 + assert_equal([mock_tree], assigns(:trees))
  28 + assert_equal({ :only_tall => 'true' }, assigns(:current_scopes))
  29 + end
  30 +
  31 + def test_boolean_scope_is_called_when_boolean_param_is_false
  32 + Tree.expects(:only_tall).never
  33 + Tree.expects(:find).with(:all).returns([mock_tree])
  34 + get :index, :only_tall => 'false'
  35 + assert_equal([mock_tree], assigns(:trees))
  36 + assert_equal({ :only_tall => 'false' }, assigns(:current_scopes))
  37 + end
  38 +
  39 + def test_scope_is_called_only_on_index
  40 + Tree.expects(:only_tall).never
  41 + Tree.expects(:find).with('42').returns(mock_tree)
  42 + get :show, :only_tall => 'true', :id => '42'
  43 + assert_equal(mock_tree, assigns(:tree))
  44 + assert_equal({ }, assigns(:current_scopes))
  45 + end
  46 +
  47 + def test_scope_is_called_except_on_index
  48 + Tree.expects(:shadown_range).with().never
  49 + Tree.expects(:find).with(:all).returns([mock_tree])
  50 + get :index, :shadown_range => 20
  51 + assert_equal([mock_tree], assigns(:trees))
  52 + assert_equal({ }, assigns(:current_scopes))
  53 + end
  54 +
  55 + def test_scope_is_called_with_arguments
  56 + Tree.expects(:color).with('blue').returns(Tree).in_sequence
  57 + Tree.expects(:find).with(:all).returns([mock_tree]).in_sequence
  58 + get :index, :color => 'blue'
  59 + assert_equal([mock_tree], assigns(:trees))
  60 + assert_equal({ :color => 'blue' }, assigns(:current_scopes))
  61 + end
  62 +
  63 + def test_multiple_scopes_are_called
  64 + Tree.expects(:only_tall).with().returns(Tree)
  65 + Tree.expects(:color).with('blue').returns(Tree)
  66 + Tree.expects(:find).with(:all).returns([mock_tree])
  67 + get :index, :color => 'blue', :only_tall => 'true'
  68 + assert_equal([mock_tree], assigns(:trees))
  69 + assert_equal({ :color => 'blue', :only_tall => 'true' }, assigns(:current_scopes))
  70 + end
  71 +
  72 + def test_scope_is_called_with_default_value
  73 + Tree.expects(:shadown_range).with(10).returns(Tree).in_sequence
  74 + Tree.expects(:find).with('42').returns(mock_tree).in_sequence
  75 + get :edit, :id => '42'
  76 + assert_equal(mock_tree, assigns(:tree))
  77 + assert_equal({ :shadown_range => 10 }, assigns(:current_scopes))
  78 + end
  79 +
  80 + def test_default_scope_value_can_be_overwritten
  81 + Tree.expects(:shadown_range).with('20').returns(Tree).in_sequence
  82 + Tree.expects(:find).with('42').returns(mock_tree).in_sequence
  83 + get :edit, :id => '42', :shadown_range => '20'
  84 + assert_equal(mock_tree, assigns(:tree))
  85 + assert_equal({ :shadown_range => '20' }, assigns(:current_scopes))
  86 + end
  87 +
  88 + def test_scope_with_different_key
  89 + Tree.expects(:root_type).with('outside').returns(Tree).in_sequence
  90 + Tree.expects(:find).with('42').returns(mock_tree).in_sequence
  91 + get :show, :id => '42', :root => 'outside'
  92 + assert_equal(mock_tree, assigns(:tree))
  93 + assert_equal({ :root => 'outside' }, assigns(:current_scopes))
  94 + end
  95 +
  96 + def test_scope_with_default_value_as_proc
  97 + session[:height] = 100
  98 + Tree.expects(:calculate_height).with(100).returns(Tree).in_sequence
  99 + Tree.expects(:new).returns(mock_tree).in_sequence
  100 + get :new
  101 + assert_equal(mock_tree, assigns(:tree))
  102 + assert_equal({ :calculate_height => 100 }, assigns(:current_scopes))
  103 + end
  104 +
  105 + protected
  106 +
  107 + def mock_tree(stubs={})
  108 + @mock_tree ||= mock(stubs)
  109 + end
  110 +
  111 +end
  112 +
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/nested_belongs_to_test.rb 0 → 100644
... ... @@ -0,0 +1,108 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Country
  4 +end
  5 +
  6 +class State
  7 +end
  8 +
  9 +class City
  10 + def self.human_name; 'City'; end
  11 +end
  12 +
  13 +class CitiesController < InheritedResources::Base
  14 + belongs_to :country, :state
  15 +end
  16 +
  17 +class NestedBelongsToTest < ActionController::TestCase
  18 + tests CitiesController
  19 +
  20 + def setup
  21 + Country.expects(:find).with('13').returns(mock_country)
  22 + mock_country.expects(:states).returns(State)
  23 + State.expects(:find).with('37').returns(mock_state)
  24 + mock_state.expects(:cities).returns(City)
  25 +
  26 + @controller.stubs(:resource_url).returns('/')
  27 + @controller.stubs(:collection_url).returns('/')
  28 + end
  29 +
  30 + def test_assigns_country_and_state_and_city_on_create
  31 + City.expects(:find).with(:all).returns([mock_city])
  32 + get :index, :state_id => '37', :country_id => '13'
  33 +
  34 + assert_equal mock_country, assigns(:country)
  35 + assert_equal mock_state, assigns(:state)
  36 + assert_equal [mock_city], assigns(:cities)
  37 + end
  38 +
  39 + def test_assigns_country_and_state_and_city_on_show
  40 + City.expects(:find).with('42').returns(mock_city)
  41 + get :show, :id => '42', :state_id => '37', :country_id => '13'
  42 +
  43 + assert_equal mock_country, assigns(:country)
  44 + assert_equal mock_state, assigns(:state)
  45 + assert_equal mock_city, assigns(:city)
  46 + end
  47 +
  48 + def test_assigns_country_and_state_and_city_on_new
  49 + City.expects(:build).returns(mock_city)
  50 + get :new, :state_id => '37', :country_id => '13'
  51 +
  52 + assert_equal mock_country, assigns(:country)
  53 + assert_equal mock_state, assigns(:state)
  54 + assert_equal mock_city, assigns(:city)
  55 + end
  56 +
  57 + def test_assigns_country_and_state_and_city_on_edit
  58 + City.expects(:find).with('42').returns(mock_city)
  59 + get :edit, :id => '42', :state_id => '37', :country_id => '13'
  60 +
  61 + assert_equal mock_country, assigns(:country)
  62 + assert_equal mock_state, assigns(:state)
  63 + assert_equal mock_city, assigns(:city)
  64 + end
  65 +
  66 + def test_assigns_country_and_state_and_city_on_create
  67 + City.expects(:build).with({'these' => 'params'}).returns(mock_city)
  68 + mock_city.expects(:save).returns(true)
  69 + post :create, :state_id => '37', :country_id => '13', :city => {:these => 'params'}
  70 +
  71 + assert_equal mock_country, assigns(:country)
  72 + assert_equal mock_state, assigns(:state)
  73 + assert_equal mock_city, assigns(:city)
  74 + end
  75 +
  76 + def test_assigns_country_and_state_and_city_on_update
  77 + City.expects(:find).with('42').returns(mock_city)
  78 + mock_city.expects(:update_attributes).returns(true)
  79 + put :update, :id => '42', :state_id => '37', :country_id => '13', :city => {:these => 'params'}
  80 +
  81 + assert_equal mock_country, assigns(:country)
  82 + assert_equal mock_state, assigns(:state)
  83 + assert_equal mock_city, assigns(:city)
  84 + end
  85 +
  86 + def test_assigns_country_and_state_and_city_on_destroy
  87 + City.expects(:find).with('42').returns(mock_city)
  88 + mock_city.expects(:destroy)
  89 + delete :destroy, :id => '42', :state_id => '37', :country_id => '13'
  90 +
  91 + assert_equal mock_country, assigns(:country)
  92 + assert_equal mock_state, assigns(:state)
  93 + assert_equal mock_city, assigns(:city)
  94 + end
  95 +
  96 + protected
  97 + def mock_country(stubs={})
  98 + @mock_country ||= mock(stubs)
  99 + end
  100 +
  101 + def mock_state(stubs={})
  102 + @mock_state ||= mock(stubs)
  103 + end
  104 +
  105 + def mock_city(stubs={})
  106 + @mock_city ||= mock(stubs)
  107 + end
  108 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/optional_belongs_to_test.rb 0 → 100644
... ... @@ -0,0 +1,164 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Brands; end
  4 +class Category; end
  5 +
  6 +class Product
  7 + def self.human_name; 'Product'; end
  8 +end
  9 +
  10 +class ProductsController < InheritedResources::Base
  11 + belongs_to :brand, :category, :polymorphic => true, :optional => true
  12 +end
  13 +
  14 +class OptionalTest < ActionController::TestCase
  15 + tests ProductsController
  16 +
  17 + def setup
  18 + @controller.stubs(:resource_url).returns('/')
  19 + @controller.stubs(:collection_url).returns('/')
  20 + end
  21 +
  22 + def test_expose_all_products_as_instance_variable_with_category
  23 + Category.expects(:find).with('37').returns(mock_category)
  24 + mock_category.expects(:products).returns(Product)
  25 + Product.expects(:find).with(:all).returns([mock_product])
  26 + get :index, :category_id => '37'
  27 + assert_equal mock_category, assigns(:category)
  28 + assert_equal [mock_product], assigns(:products)
  29 + end
  30 +
  31 + def test_expose_all_products_as_instance_variable_without_category
  32 + Product.expects(:find).with(:all).returns([mock_product])
  33 + get :index
  34 + assert_equal nil, assigns(:category)
  35 + assert_equal [mock_product], assigns(:products)
  36 + end
  37 +
  38 + def test_expose_the_resquested_product_with_category
  39 + Category.expects(:find).with('37').returns(mock_category)
  40 + mock_category.expects(:products).returns(Product)
  41 + Product.expects(:find).with('42').returns(mock_product)
  42 + get :show, :id => '42', :category_id => '37'
  43 + assert_equal mock_category, assigns(:category)
  44 + assert_equal mock_product, assigns(:product)
  45 + end
  46 +
  47 + def test_expose_the_resquested_product_without_category
  48 + Product.expects(:find).with('42').returns(mock_product)
  49 + get :show, :id => '42'
  50 + assert_equal nil, assigns(:category)
  51 + assert_equal mock_product, assigns(:product)
  52 + end
  53 +
  54 + def test_expose_a_new_product_with_category
  55 + Category.expects(:find).with('37').returns(mock_category)
  56 + mock_category.expects(:products).returns(Product)
  57 + Product.expects(:build).returns(mock_product)
  58 + get :new, :category_id => '37'
  59 + assert_equal mock_category, assigns(:category)
  60 + assert_equal mock_product, assigns(:product)
  61 + end
  62 +
  63 + def test_expose_a_new_product_without_category
  64 + Product.expects(:new).returns(mock_product)
  65 + get :new
  66 + assert_equal nil, assigns(:category)
  67 + assert_equal mock_product, assigns(:product)
  68 + end
  69 +
  70 + def test_expose_the_resquested_product_for_edition_with_category
  71 + Category.expects(:find).with('37').returns(mock_category)
  72 + mock_category.expects(:products).returns(Product)
  73 + Product.expects(:find).with('42').returns(mock_product)
  74 + get :edit, :id => '42', :category_id => '37'
  75 + assert_equal mock_category, assigns(:category)
  76 + assert_equal mock_product, assigns(:product)
  77 + end
  78 +
  79 + def test_expose_the_resquested_product_for_edition_without_category
  80 + Product.expects(:find).with('42').returns(mock_product)
  81 + get :edit, :id => '42'
  82 + assert_equal nil, assigns(:category)
  83 + assert_equal mock_product, assigns(:product)
  84 + end
  85 +
  86 + def test_expose_a_newly_create_product_with_category
  87 + Category.expects(:find).with('37').returns(mock_category)
  88 + mock_category.expects(:products).returns(Product)
  89 + Product.expects(:build).with({'these' => 'params'}).returns(mock_product(:save => true))
  90 + post :create, :category_id => '37', :product => {:these => 'params'}
  91 + assert_equal mock_category, assigns(:category)
  92 + assert_equal mock_product, assigns(:product)
  93 + end
  94 +
  95 + def test_expose_a_newly_create_product_without_category
  96 + Product.expects(:new).with({'these' => 'params'}).returns(mock_product(:save => true))
  97 + post :create, :product => {:these => 'params'}
  98 + assert_equal nil, assigns(:category)
  99 + assert_equal mock_product, assigns(:product)
  100 + end
  101 +
  102 + def test_update_the_requested_object_with_category
  103 + Category.expects(:find).with('37').returns(mock_category)
  104 + mock_category.expects(:products).returns(Product)
  105 + Product.expects(:find).with('42').returns(mock_product)
  106 + mock_product.expects(:update_attributes).with({'these' => 'params'}).returns(true)
  107 +
  108 + put :update, :id => '42', :category_id => '37', :product => {:these => 'params'}
  109 + assert_equal mock_category, assigns(:category)
  110 + assert_equal mock_product, assigns(:product)
  111 + end
  112 +
  113 + def test_update_the_requested_object_without_category
  114 + Product.expects(:find).with('42').returns(mock_product)
  115 + mock_product.expects(:update_attributes).with({'these' => 'params'}).returns(true)
  116 +
  117 + put :update, :id => '42', :product => {:these => 'params'}
  118 + assert_equal nil, assigns(:category)
  119 + assert_equal mock_product, assigns(:product)
  120 + end
  121 +
  122 + def test_the_resquested_product_is_destroyed_with_category
  123 + Category.expects(:find).with('37').returns(mock_category)
  124 + mock_category.expects(:products).returns(Product)
  125 + Product.expects(:find).with('42').returns(mock_product)
  126 + mock_product.expects(:destroy)
  127 + @controller.expects(:collection_url).returns('/')
  128 +
  129 + delete :destroy, :id => '42', :category_id => '37'
  130 + assert_equal mock_category, assigns(:category)
  131 + assert_equal mock_product, assigns(:product)
  132 + end
  133 +
  134 + def test_the_resquested_product_is_destroyed_without_category
  135 + Product.expects(:find).with('42').returns(mock_product)
  136 + mock_product.expects(:destroy)
  137 + @controller.expects(:collection_url).returns('/')
  138 +
  139 + delete :destroy, :id => '42'
  140 + assert_equal nil, assigns(:category)
  141 + assert_equal mock_product, assigns(:product)
  142 + end
  143 +
  144 + def test_polymorphic_helpers
  145 + Product.expects(:find).with(:all).returns([mock_product])
  146 + get :index
  147 +
  148 + assert !@controller.send(:parent?)
  149 + assert_equal nil, assigns(:parent_type)
  150 + assert_equal nil, @controller.send(:parent_type)
  151 + assert_equal nil, @controller.send(:parent_class)
  152 + assert_equal nil, assigns(:category)
  153 + assert_equal nil, @controller.send(:parent)
  154 + end
  155 +
  156 + protected
  157 + def mock_category(stubs={})
  158 + @mock_category ||= mock(stubs)
  159 + end
  160 +
  161 + def mock_product(stubs={})
  162 + @mock_product ||= mock(stubs)
  163 + end
  164 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/polymorphic_test.rb 0 → 100644
... ... @@ -0,0 +1,186 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Factory; end
  4 +class Company; end
  5 +
  6 +class Employee
  7 + def self.human_name; 'Employee'; end
  8 +end
  9 +
  10 +class EmployeesController < InheritedResources::Base
  11 + belongs_to :factory, :company, :polymorphic => true
  12 +end
  13 +
  14 +class PolymorphicFactoriesTest < ActionController::TestCase
  15 + tests EmployeesController
  16 +
  17 + def setup
  18 + Factory.expects(:find).with('37').returns(mock_factory)
  19 + mock_factory.expects(:employees).returns(Employee)
  20 +
  21 + @controller.stubs(:resource_url).returns('/')
  22 + @controller.stubs(:collection_url).returns('/')
  23 + end
  24 +
  25 + def test_expose_all_employees_as_instance_variable_on_index
  26 + Employee.expects(:find).with(:all).returns([mock_employee])
  27 + get :index, :factory_id => '37'
  28 + assert_equal mock_factory, assigns(:factory)
  29 + assert_equal [mock_employee], assigns(:employees)
  30 + end
  31 +
  32 + def test_expose_the_resquested_employee_on_show
  33 + Employee.expects(:find).with('42').returns(mock_employee)
  34 + get :show, :id => '42', :factory_id => '37'
  35 + assert_equal mock_factory, assigns(:factory)
  36 + assert_equal mock_employee, assigns(:employee)
  37 + end
  38 +
  39 + def test_expose_a_new_employee_on_new
  40 + Employee.expects(:build).returns(mock_employee)
  41 + get :new, :factory_id => '37'
  42 + assert_equal mock_factory, assigns(:factory)
  43 + assert_equal mock_employee, assigns(:employee)
  44 + end
  45 +
  46 + def test_expose_the_resquested_employee_on_edit
  47 + Employee.expects(:find).with('42').returns(mock_employee)
  48 + get :edit, :id => '42', :factory_id => '37'
  49 + assert_equal mock_factory, assigns(:factory)
  50 + assert_equal mock_employee, assigns(:employee)
  51 + assert_response :success
  52 + end
  53 +
  54 + def test_expose_a_newly_create_employee_on_create
  55 + Employee.expects(:build).with({'these' => 'params'}).returns(mock_employee(:save => true))
  56 + post :create, :factory_id => '37', :employee => {:these => 'params'}
  57 + assert_equal mock_factory, assigns(:factory)
  58 + assert_equal mock_employee, assigns(:employee)
  59 + end
  60 +
  61 + def test_update_the_requested_object_on_update
  62 + Employee.expects(:find).with('42').returns(mock_employee)
  63 + mock_employee.expects(:update_attributes).with({'these' => 'params'}).returns(true)
  64 + put :update, :id => '42', :factory_id => '37', :employee => {:these => 'params'}
  65 + assert_equal mock_factory, assigns(:factory)
  66 + assert_equal mock_employee, assigns(:employee)
  67 + end
  68 +
  69 + def test_the_resquested_employee_is_destroyed_on_destroy
  70 + Employee.expects(:find).with('42').returns(mock_employee)
  71 + mock_employee.expects(:destroy)
  72 + delete :destroy, :id => '42', :factory_id => '37'
  73 + assert_equal mock_factory, assigns(:factory)
  74 + assert_equal mock_employee, assigns(:employee)
  75 + end
  76 +
  77 + def test_polymorphic_helpers
  78 + mock_factory.stubs(:class).returns(Factory)
  79 +
  80 + Employee.expects(:find).with(:all).returns([mock_employee])
  81 + get :index, :factory_id => '37'
  82 +
  83 + assert @controller.send(:parent?)
  84 + assert_equal :factory, assigns(:parent_type)
  85 + assert_equal :factory, @controller.send(:parent_type)
  86 + assert_equal Factory, @controller.send(:parent_class)
  87 + assert_equal mock_factory, assigns(:factory)
  88 + assert_equal mock_factory, @controller.send(:parent)
  89 + end
  90 +
  91 + protected
  92 + def mock_factory(stubs={})
  93 + @mock_factory ||= mock(stubs)
  94 + end
  95 +
  96 + def mock_employee(stubs={})
  97 + @mock_employee ||= mock(stubs)
  98 + end
  99 +end
  100 +
  101 +class PolymorphicCompanyTest < ActionController::TestCase
  102 + tests EmployeesController
  103 +
  104 + def setup
  105 + Company.expects(:find).with('37').returns(mock_company)
  106 + mock_company.expects(:employees).returns(Employee)
  107 +
  108 + @controller.stubs(:resource_url).returns('/')
  109 + @controller.stubs(:collection_url).returns('/')
  110 + end
  111 +
  112 + def test_expose_all_employees_as_instance_variable_on_index
  113 + Employee.expects(:find).with(:all).returns([mock_employee])
  114 + get :index, :company_id => '37'
  115 + assert_equal mock_company, assigns(:company)
  116 + assert_equal [mock_employee], assigns(:employees)
  117 + end
  118 +
  119 + def test_expose_the_resquested_employee_on_show
  120 + Employee.expects(:find).with('42').returns(mock_employee)
  121 + get :show, :id => '42', :company_id => '37'
  122 + assert_equal mock_company, assigns(:company)
  123 + assert_equal mock_employee, assigns(:employee)
  124 + end
  125 +
  126 + def test_expose_a_new_employee_on_new
  127 + Employee.expects(:build).returns(mock_employee)
  128 + get :new, :company_id => '37'
  129 + assert_equal mock_company, assigns(:company)
  130 + assert_equal mock_employee, assigns(:employee)
  131 + end
  132 +
  133 + def test_expose_the_resquested_employee_on_edit
  134 + Employee.expects(:find).with('42').returns(mock_employee)
  135 + get :edit, :id => '42', :company_id => '37'
  136 + assert_equal mock_company, assigns(:company)
  137 + assert_equal mock_employee, assigns(:employee)
  138 + assert_response :success
  139 + end
  140 +
  141 + def test_expose_a_newly_create_employee_on_create
  142 + Employee.expects(:build).with({'these' => 'params'}).returns(mock_employee(:save => true))
  143 + post :create, :company_id => '37', :employee => {:these => 'params'}
  144 + assert_equal mock_company, assigns(:company)
  145 + assert_equal mock_employee, assigns(:employee)
  146 + end
  147 +
  148 + def test_update_the_requested_object_on_update
  149 + Employee.expects(:find).with('42').returns(mock_employee)
  150 + mock_employee.expects(:update_attributes).with({'these' => 'params'}).returns(true)
  151 + put :update, :id => '42', :company_id => '37', :employee => {:these => 'params'}
  152 + assert_equal mock_company, assigns(:company)
  153 + assert_equal mock_employee, assigns(:employee)
  154 + end
  155 +
  156 + def test_the_resquested_employee_is_destroyed_on_destroy
  157 + Employee.expects(:find).with('42').returns(mock_employee)
  158 + mock_employee.expects(:destroy)
  159 + delete :destroy, :id => '42', :company_id => '37'
  160 + assert_equal mock_company, assigns(:company)
  161 + assert_equal mock_employee, assigns(:employee)
  162 + end
  163 +
  164 + def test_polymorphic_helpers
  165 + mock_company.stubs(:class).returns(Company)
  166 +
  167 + Employee.expects(:find).with(:all).returns([mock_employee])
  168 + get :index, :company_id => '37'
  169 +
  170 + assert @controller.send(:parent?)
  171 + assert_equal :company, assigns(:parent_type)
  172 + assert_equal :company, @controller.send(:parent_type)
  173 + assert_equal Company, @controller.send(:parent_class)
  174 + assert_equal mock_company, assigns(:company)
  175 + assert_equal mock_company, @controller.send(:parent)
  176 + end
  177 +
  178 + protected
  179 + def mock_company(stubs={})
  180 + @mock_company ||= mock(stubs)
  181 + end
  182 +
  183 + def mock_employee(stubs={})
  184 + @mock_employee ||= mock(stubs)
  185 + end
  186 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/redirect_to_test.rb 0 → 100644
... ... @@ -0,0 +1,77 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Machine;
  4 + def self.human_name; 'Machine'; end
  5 +end
  6 +
  7 +class MachinesController < InheritedResources::Base
  8 + def create
  9 + create!{ complex_url(:create, true, true) }
  10 + end
  11 +
  12 + def update
  13 + update!{ complex_url(:update, false, false) }
  14 + end
  15 +
  16 + def destroy
  17 + destroy!{ complex_url(:destroy, true, false) }
  18 + end
  19 +
  20 + protected
  21 + def complex_url(name, arg2, arg3)
  22 + 'http://test.host/' + name.to_s
  23 + end
  24 +end
  25 +
  26 +class RedirectToWithBlockTest < ActionController::TestCase
  27 + tests MachinesController
  28 +
  29 + def test_redirect_to_the_given_url_on_create
  30 + Machine.stubs(:new).returns(mock_machine(:save => true))
  31 + @controller.expects(:resource_url).times(0)
  32 + post :create
  33 + assert_redirected_to 'http://test.host/create'
  34 + end
  35 +
  36 + def test_redirect_to_the_given_url_on_update
  37 + Machine.stubs(:find).returns(mock_machine(:update_attributes => true))
  38 + @controller.expects(:resource_url).times(0)
  39 + put :update
  40 + assert_redirected_to 'http://test.host/update'
  41 + end
  42 +
  43 + def test_redirect_to_the_given_url_on_destroy
  44 + Machine.stubs(:find).returns(mock_machine(:destroy => true))
  45 + @controller.expects(:collection_url).times(0)
  46 + delete :destroy
  47 + assert_redirected_to 'http://test.host/destroy'
  48 + end
  49 +
  50 + protected
  51 + def mock_machine(stubs={})
  52 + @mock_machine ||= mock(stubs)
  53 + end
  54 +end
  55 +
  56 +
  57 +# Use this to test blocks with multiple arity in the future.
  58 +class SuperMachinesController < InheritedResources::Base
  59 + defaults :resource_class => Machine
  60 +
  61 + def create
  62 + create! do |arg1, arg2, arg3|
  63 + # nothing
  64 + end
  65 + end
  66 +end
  67 +
  68 +class RedirectToArityTest < ActionController::TestCase
  69 + tests SuperMachinesController
  70 +
  71 + def test_redirect_to_the_given_url_on_create
  72 + Machine.stubs(:new).returns(:anything)
  73 + assert_raise ScriptError, /arity/ do
  74 + post :create
  75 + end
  76 + end
  77 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/respond_to_test.rb 0 → 100644
... ... @@ -0,0 +1,314 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Project
  4 + def to_html
  5 + 'Generated HTML'
  6 + end
  7 +
  8 + def to_xml
  9 + 'Generated XML'
  10 + end
  11 +
  12 + [:to_json, :to_rss, :to_rjs].each do |method|
  13 + undef_method method if respond_to? method
  14 + end
  15 +end
  16 +
  17 +class ProjectsController < ActionController::Base
  18 + # Inherited respond_to definition is:
  19 + # respond_to :html
  20 + respond_to :html
  21 + respond_to :xml, :except => :edit
  22 + respond_to :rjs => :edit
  23 + respond_to :rss, :only => 'index'
  24 + respond_to :json, :except => :index
  25 + respond_to :csv, :except => :index
  26 +
  27 + def index
  28 + respond_with(Project.new)
  29 + end
  30 +
  31 + def respond_with_options
  32 + respond_with(Project.new, :to => [:xml, :json], :location => 'http://test.host/')
  33 + end
  34 +
  35 + def skip_not_acceptable
  36 + respond_with(Project.new, :skip_not_acceptable => true)
  37 + render :text => 'Will not raise double render error.'
  38 + end
  39 +
  40 + def respond_to_with_resource
  41 + respond_to(:with => Project.new)
  42 + end
  43 +
  44 + def respond_to_with_resource_and_blocks
  45 + respond_to(:with => Project.new) do |format|
  46 + format.json { render :text => 'Render JSON' }
  47 + format.rss { render :text => 'Render RSS' }
  48 + end
  49 + end
  50 +
  51 + # If the user request Mime::ALL and we have a template called action.html.erb,
  52 + # the html template should be rendered *unless* html is specified inside the
  53 + # block. This tests exactly this case.
  54 + #
  55 + def respond_to_skip_default_template
  56 + respond_to(:with => Project.new) do |format|
  57 + format.html { render :text => 'Render HTML' }
  58 + end
  59 + end
  60 +end
  61 +
  62 +class SuperProjectsController < ProjectsController
  63 +end
  64 +
  65 +class RespondToUnitTest < ActionController::TestCase
  66 + tests ProjectsController
  67 +
  68 + def setup
  69 + @formats = @controller.formats_for_respond_to
  70 + @responder = ActionController::MimeResponds::Responder.new(@controller)
  71 + end
  72 +
  73 + def test_respond_to_class_method_without_options
  74 + assert_nil @formats[:html][:only]
  75 + assert_nil @formats[:html][:except]
  76 + end
  77 +
  78 + def test_respond_to_class_method_inheritance
  79 + assert_nil @formats[:xml][:only]
  80 + assert_equal [:edit], @formats[:xml][:except]
  81 + end
  82 +
  83 + def test_respond_to_class_method_with_implicit_only
  84 + assert_equal [:edit], @formats[:rjs][:only]
  85 + assert_nil @formats[:rjs][:except]
  86 + end
  87 +
  88 + def test_respond_to_class_method_with_explicit_only
  89 + assert_equal [:index], @formats[:rss][:only]
  90 + assert_nil @formats[:rss][:except]
  91 + end
  92 +
  93 + def test_respond_to_class_method_with_explicit_except
  94 + assert_nil @formats[:json][:only]
  95 + assert_equal [:index], @formats[:json][:except]
  96 + end
  97 +
  98 + def test_action_respond_to_format
  99 + @controller.action_name = 'index'
  100 + assert @responder.action_respond_to_format?('html') # defined
  101 + assert @responder.action_respond_to_format?('xml') # inherited
  102 + assert @responder.action_respond_to_format?('rss') # explicit only
  103 + assert !@responder.action_respond_to_format?('json') # exception
  104 +
  105 + @controller.action_name = 'edit'
  106 + assert !@responder.action_respond_to_format?('xml') # inherited
  107 + assert @responder.action_respond_to_format?('rjs') # implicit only
  108 + assert @responder.action_respond_to_format?('json') # exception
  109 + end
  110 +
  111 + def test_action_respond_to_format_with_additional_mimes
  112 + assert @responder.action_respond_to_format?('html', [:xml, :html, :json])
  113 + assert !@responder.action_respond_to_format?('html', [:xml, :rss, :json])
  114 +
  115 + @controller.action_name = 'index'
  116 + assert @responder.action_respond_to_format?('html', [])
  117 + assert !@responder.action_respond_to_format?('json', [])
  118 + end
  119 +
  120 + def test_clear_respond_to
  121 + @controller = SuperProjectsController.new
  122 + @controller.request = ActionController::TestRequest.new
  123 +
  124 + @controller.action_name = 'index'
  125 + @responder = ActionController::MimeResponds::Responder.new(@controller)
  126 +
  127 + # Those responses are inherited from ProjectsController
  128 + assert @responder.action_respond_to_format?('html') # defined
  129 + assert @responder.action_respond_to_format?('xml') # inherited
  130 + assert @responder.action_respond_to_format?('rss') # explicit only
  131 +
  132 + # Let's clear respond_to definitions
  133 + SuperProjectsController.send(:clear_respond_to!)
  134 +
  135 + assert !@responder.action_respond_to_format?('html')
  136 + assert !@responder.action_respond_to_format?('xml')
  137 + assert !@responder.action_respond_to_format?('rss')
  138 + end
  139 +
  140 + def test_respond_except_any_does_not_respond_to_mime_all
  141 + prepare_responder_to_respond!
  142 +
  143 + @responder.respond_except_any
  144 + assert !@performed
  145 +
  146 + @responder.respond
  147 + assert @performed
  148 + end
  149 +
  150 + def test_respond_any_responds_to_mime_all
  151 + prepare_responder_to_respond!
  152 +
  153 + @responder.respond_any
  154 + assert @performed
  155 + end
  156 +
  157 + def test_respond_any_responds_only_to_all
  158 + prepare_responder_to_respond!('text/html')
  159 +
  160 + @responder.respond_any
  161 + assert !@performed
  162 + end
  163 +
  164 + def test_responder_prioritize
  165 + prepare_responder_to_respond!
  166 + assert_equal [Mime::HTML, Mime::XML], @responder.order
  167 +
  168 + @responder.prioritize(:xml)
  169 + assert_equal [Mime::XML, Mime::HTML], @responder.order
  170 +
  171 + @responder.prioritize(:js)
  172 + assert_equal [Mime::XML, Mime::HTML], @responder.order
  173 + end
  174 +
  175 + protected
  176 + def prepare_responder_to_respond!(content_type='*/*')
  177 + @controller.request = @request = ActionController::TestRequest.new
  178 + @controller.response = @response = ActionController::TestResponse.new
  179 +
  180 + @request.accept = content_type
  181 + @responder = ActionController::MimeResponds::Responder.new(@controller)
  182 + @performed = false
  183 +
  184 + # Mock template
  185 + template = mock()
  186 + @response.stubs(:template).returns(template)
  187 + template.stubs(:template_format=).returns(true)
  188 +
  189 + respond_to_declaration = proc { |format|
  190 + format.html { @performed = true }
  191 + format.xml { }
  192 + }
  193 +
  194 + respond_to_declaration.call(@responder)
  195 + end
  196 +end
  197 +
  198 +class RespondToFunctionalTest < ActionController::TestCase
  199 + tests ProjectsController
  200 +
  201 + def test_respond_with_layout_rendering
  202 + @request.accept = 'text/html'
  203 + get :index
  204 + assert_equal 'Index HTML', @response.body.strip
  205 + end
  206 +
  207 + def test_respond_with_calls_to_format_on_resource
  208 + @request.accept = 'application/xml'
  209 + get :index
  210 + assert_equal 'Generated XML', @response.body.strip
  211 + end
  212 +
  213 + def test_respond_with_inherits_format
  214 + @request.accept = 'application/xml'
  215 + get :index
  216 + assert_equal 'Generated XML', @response.body.strip
  217 + end
  218 +
  219 + def test_respond_with_renders_status_not_acceptable_if_mime_type_is_not_registered
  220 + @request.accept = 'text/csv'
  221 + get :index
  222 + assert_equal '406 Not Acceptable', @response.status
  223 + end
  224 +
  225 + def test_respond_with_renders_not_found_when_mime_type_is_valid_but_could_not_render
  226 + @request.accept = 'application/rss+xml'
  227 + get :index
  228 + assert_equal '404 Not Found', @response.status
  229 + end
  230 +
  231 + def test_respond_to_all
  232 + @request.accept = '*/*'
  233 + get :index
  234 + assert_equal 'Index HTML', @response.body.strip
  235 + end
  236 +
  237 + def test_default_template_is_not_rendered_if_template_format_is_not_accepted
  238 + @controller.stubs(:default_template_format).returns(:json)
  239 + @request.accept = '*/*'
  240 + get :index
  241 + assert_equal '406 Not Acceptable', @response.status
  242 + end
  243 +
  244 + def test_respond_with_sets_content_type_properly
  245 + @request.accept = 'text/html'
  246 + get :index
  247 + assert_equal 'text/html', @response.content_type
  248 + assert_equal :html, @response.template.template_format
  249 +
  250 + @request.accept = 'application/xml'
  251 + get :index
  252 + assert_equal 'application/xml', @response.content_type
  253 + assert_equal :xml, @response.template.template_format
  254 + end
  255 +
  256 + def test_respond_with_when_to_is_given_as_option
  257 + @request.accept = 'text/html'
  258 + get :respond_with_options
  259 + assert_equal '406 Not Acceptable', @response.status
  260 +
  261 + @request.accept = 'application/xml'
  262 + get :respond_with_options
  263 + assert_equal 'Generated XML', @response.body.strip
  264 + end
  265 +
  266 + def test_respond_with_forwads_extra_options_to_render
  267 + @request.accept = 'application/xml'
  268 + get :respond_with_options
  269 + assert_equal 'Generated XML', @response.body.strip
  270 + assert_equal 'http://test.host/', @response.headers['Location']
  271 + end
  272 +
  273 + def test_respond_with_skips_head_when_skip_not_acceptable_is_given
  274 + @request.accept = 'application/rss+xml'
  275 + get :skip_not_acceptable
  276 + assert_equal 'Will not raise double render error.', @response.body.strip
  277 + end
  278 +
  279 + def test_respond_to_when_a_resource_is_given_as_option
  280 + @request.accept = 'text/html'
  281 + get :respond_to_with_resource
  282 + assert_equal 'RespondTo HTML', @response.body.strip
  283 +
  284 + @request.accept = 'application/xml'
  285 + get :respond_to_with_resource
  286 + assert_equal 'Generated XML', @response.body.strip
  287 +
  288 + @request.accept = 'application/json'
  289 + get :respond_to_with_resource
  290 + assert_equal '404 Not Found', @response.status
  291 +
  292 + @request.accept = 'application/rss+xml'
  293 + get :respond_to_with_resource
  294 + assert_equal '406 Not Acceptable', @response.status
  295 + end
  296 +
  297 + def test_respond_to_overwrite_class_method_definition
  298 + @request.accept = 'application/rss+xml'
  299 + get :respond_to_with_resource_and_blocks
  300 + assert_equal 'Render RSS', @response.body.strip
  301 + end
  302 +
  303 + def test_respond_to_fallback_to_first_block_when_mime_type_is_all
  304 + @request.accept = '*/*'
  305 + get :respond_to_with_resource_and_blocks
  306 + assert_equal 'Render JSON', @response.body.strip
  307 + end
  308 +
  309 + def test_respond_to_skip_default_template_when_it_is_in_block
  310 + @request.accept = '*/*'
  311 + get :respond_to_skip_default_template
  312 + assert_equal 'Render HTML', @response.body.strip
  313 + end
  314 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/singleton_test.rb 0 → 100644
... ... @@ -0,0 +1,83 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +# This test file is instead to test the how controller flow and actions
  4 +# using a belongs_to association. This is done using mocks a la rspec.
  5 +#
  6 +class Store
  7 +end
  8 +
  9 +class Manager
  10 + def self.human_name; 'Manager'; end
  11 +end
  12 +
  13 +class ManagersController < InheritedResources::Base
  14 + belongs_to :store, :singleton => true
  15 +end
  16 +
  17 +class SingletonTest < ActionController::TestCase
  18 + tests ManagersController
  19 +
  20 + def setup
  21 + @controller.stubs(:resource_url).returns('/')
  22 + @controller.stubs(:collection_url).returns('/')
  23 + end
  24 +
  25 + def test_expose_the_resquested_manager_on_show
  26 + Store.expects(:find).with('37').returns(mock_store)
  27 + mock_store.expects(:manager).returns(mock_manager)
  28 + get :show, :store_id => '37'
  29 + assert_equal mock_store, assigns(:store)
  30 + assert_equal mock_manager, assigns(:manager)
  31 + end
  32 +
  33 + def test_expose_a_new_manager_on_new
  34 + Store.expects(:find).with('37').returns(mock_store)
  35 + mock_store.expects(:build_manager).returns(mock_manager)
  36 + get :new, :store_id => '37'
  37 + assert_equal mock_store, assigns(:store)
  38 + assert_equal mock_manager, assigns(:manager)
  39 + end
  40 +
  41 + def test_expose_the_resquested_manager_on_edit
  42 + Store.expects(:find).with('37').returns(mock_store)
  43 + mock_store.expects(:manager).returns(mock_manager)
  44 + get :edit, :store_id => '37'
  45 + assert_equal mock_store, assigns(:store)
  46 + assert_equal mock_manager, assigns(:manager)
  47 + assert_response :success
  48 + end
  49 +
  50 + def test_expose_a_newly_create_manager_on_create
  51 + Store.expects(:find).with('37').returns(mock_store)
  52 + mock_store.expects(:build_manager).with({'these' => 'params'}).returns(mock_manager(:save => true))
  53 + post :create, :store_id => '37', :manager => {:these => 'params'}
  54 + assert_equal mock_store, assigns(:store)
  55 + assert_equal mock_manager, assigns(:manager)
  56 + end
  57 +
  58 + def test_update_the_requested_object_on_update
  59 + Store.expects(:find).with('37').returns(mock_store(:manager => mock_manager))
  60 + mock_manager.expects(:update_attributes).with({'these' => 'params'}).returns(true)
  61 + put :update, :store_id => '37', :manager => {:these => 'params'}
  62 + assert_equal mock_store, assigns(:store)
  63 + assert_equal mock_manager, assigns(:manager)
  64 + end
  65 +
  66 + def test_the_resquested_manager_is_destroyed_on_destroy
  67 + Store.expects(:find).with('37').returns(mock_store)
  68 + mock_store.expects(:manager).returns(mock_manager)
  69 + mock_manager.expects(:destroy)
  70 + delete :destroy, :store_id => '37'
  71 + assert_equal mock_store, assigns(:store)
  72 + assert_equal mock_manager, assigns(:manager)
  73 + end
  74 +
  75 + protected
  76 + def mock_store(stubs={})
  77 + @mock_store ||= mock(stubs)
  78 + end
  79 +
  80 + def mock_manager(stubs={})
  81 + @mock_manager ||= mock(stubs)
  82 + end
  83 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/test_helper.rb 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +require 'test/unit'
  2 +require 'rubygems'
  3 +require 'ruby-debug'
  4 +require 'mocha'
  5 +
  6 +ENV["RAILS_ENV"] = "test"
  7 +RAILS_ROOT = "anywhere"
  8 +
  9 +require 'active_support'
  10 +require 'action_controller'
  11 +require 'action_controller/test_case'
  12 +require 'action_controller/test_process'
  13 +
  14 +I18n.load_path << File.join(File.dirname(__FILE__), 'locales', 'en.yml')
  15 +I18n.reload!
  16 +
  17 +class ApplicationController < ActionController::Base; end
  18 +
  19 +# Add IR to load path and load the main file
  20 +ActiveSupport::Dependencies.load_paths << File.expand_path(File.dirname(__FILE__) + '/../lib')
  21 +require_dependency 'inherited_resources'
  22 +
  23 +ActionController::Base.view_paths = File.join(File.dirname(__FILE__), 'views')
  24 +
  25 +ActionController::Routing::Routes.draw do |map|
  26 + map.connect ':controller/:action/:id'
  27 +end
... ...
vendor/gems/josevalim-inherited_resources-0.8.5/test/url_helpers_test.rb 0 → 100644
... ... @@ -0,0 +1,471 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class Universe; end
  4 +class UniversesController < InheritedResources::Base
  5 + defaults :singleton => true, :route_instance_name => 'universum'
  6 +end
  7 +
  8 +class House; end
  9 +class HousesController < InheritedResources::Base
  10 +end
  11 +
  12 +class Backpack; end
  13 +module Admin; end
  14 +class Admin::BackpacksController < InheritedResources::Base
  15 + defaults :route_collection_name => 'tour_backpacks'
  16 +end
  17 +
  18 +class Table; end
  19 +class TablesController < InheritedResources::Base
  20 + belongs_to :house
  21 +end
  22 +
  23 +class RoomsController < InheritedResources::Base
  24 + belongs_to :house, :route_name => 'big_house'
  25 +end
  26 +
  27 +class ChairsController < InheritedResources::Base
  28 + belongs_to :house do
  29 + belongs_to :table
  30 + end
  31 +end
  32 +
  33 +class OwnersController < InheritedResources::Base
  34 + singleton_belongs_to :house
  35 +end
  36 +
  37 +class Bed; end
  38 +class BedsController < InheritedResources::Base
  39 + optional_belongs_to :house, :building
  40 +end
  41 +
  42 +class Desk; end
  43 +module Admin
  44 + class DesksController < InheritedResources::Base
  45 + optional_belongs_to :house
  46 + end
  47 +end
  48 +
  49 +class Dish; end
  50 +class DishesController < InheritedResources::Base
  51 + belongs_to :house do
  52 + polymorphic_belongs_to :table, :kitchen
  53 + end
  54 +end
  55 +
  56 +class Center; end
  57 +class CentersController < InheritedResources::Base
  58 + acts_as_singleton!
  59 +
  60 + belongs_to :house do
  61 + belongs_to :table, :kitchen, :polymorphic => true
  62 + end
  63 +end
  64 +
  65 +# Create a TestHelper module with some helpers
  66 +class UrlHelpersTest < ActiveSupport::TestCase
  67 +
  68 + def test_url_helpers_on_simple_inherited_resource
  69 + controller = HousesController.new
  70 + controller.instance_variable_set('@house', :house)
  71 +
  72 + [:url, :path].each do |path_or_url|
  73 + controller.expects("houses_#{path_or_url}").with({}).once
  74 + controller.send("collection_#{path_or_url}")
  75 +
  76 + controller.expects("house_#{path_or_url}").with(:house, {}).once
  77 + controller.send("resource_#{path_or_url}")
  78 +
  79 + controller.expects("new_house_#{path_or_url}").with({}).once
  80 + controller.send("new_resource_#{path_or_url}")
  81 +
  82 + controller.expects("edit_house_#{path_or_url}").with(:house, {}).once
  83 + controller.send("edit_resource_#{path_or_url}")
  84 +
  85 + # With arg
  86 + controller.expects("house_#{path_or_url}").with(:arg, {}).once
  87 + controller.send("resource_#{path_or_url}", :arg)
  88 +
  89 + controller.expects("house_#{path_or_url}").with(:arg, {}).once
  90 + controller.send("resource_#{path_or_url}", :arg)
  91 +
  92 + # With options
  93 + controller.expects("house_#{path_or_url}").with(:arg, :page => 1).once
  94 + controller.send("resource_#{path_or_url}", :arg, :page => 1)
  95 + end
  96 + end
  97 +
  98 + def test_url_helpers_on_simple_inherited_namespaced_resource
  99 + controller = Admin::BackpacksController.new
  100 + controller.instance_variable_set('@backpack', :backpack)
  101 +
  102 + assert_equal 'admin', controller.class.resources_configuration[:self][:route_prefix]
  103 +
  104 + [:url, :path].each do |path_or_url|
  105 + controller.expects("admin_tour_backpacks_#{path_or_url}").with({}).once
  106 + controller.send("collection_#{path_or_url}")
  107 +
  108 + controller.expects("admin_backpack_#{path_or_url}").with(:backpack, {}).once
  109 + controller.send("resource_#{path_or_url}")
  110 +
  111 + controller.expects("new_admin_backpack_#{path_or_url}").with({}).once
  112 + controller.send("new_resource_#{path_or_url}")
  113 +
  114 + controller.expects("edit_admin_backpack_#{path_or_url}").with(:backpack, {}).once
  115 + controller.send("edit_resource_#{path_or_url}")
  116 +
  117 + # With arg
  118 + controller.expects("admin_backpack_#{path_or_url}").with(:arg, {}).once
  119 + controller.send("resource_#{path_or_url}", :arg)
  120 +
  121 + controller.expects("admin_backpack_#{path_or_url}").with(:arg, {}).once
  122 + controller.send("resource_#{path_or_url}", :arg)
  123 +
  124 + # With options
  125 + controller.expects("admin_backpack_#{path_or_url}").with(:arg, :page => 1).once
  126 + controller.send("resource_#{path_or_url}", :arg, :page => 1)
  127 + end
  128 + end
  129 +
  130 + def test_url_helpers_on_simple_inherited_singleton_resource
  131 + controller = UniversesController.new
  132 + controller.instance_variable_set('@universe', :universe)
  133 +
  134 + [:url, :path].each do |path_or_url|
  135 + controller.expects("root_#{path_or_url}").with({}).once
  136 + controller.send("collection_#{path_or_url}")
  137 +
  138 + controller.expects("universum_#{path_or_url}").with({}).once
  139 + controller.send("resource_#{path_or_url}")
  140 +
  141 + controller.expects("new_universum_#{path_or_url}").with({}).once
  142 + controller.send("new_resource_#{path_or_url}")
  143 +
  144 + controller.expects("edit_universum_#{path_or_url}").with({}).once
  145 + controller.send("edit_resource_#{path_or_url}")
  146 +
  147 + # With options
  148 + # Also tests that argument sent are not used
  149 + controller.expects("universum_#{path_or_url}").with(:page => 1).once
  150 + controller.send("resource_#{path_or_url}", :arg, :page => 1)
  151 + end
  152 + end
  153 +
  154 + def test_url_helpers_on_belongs_to
  155 + controller = TablesController.new
  156 + controller.instance_variable_set('@house', :house)
  157 + controller.instance_variable_set('@table', :table)
  158 +
  159 + [:url, :path].each do |path_or_url|
  160 + controller.expects("house_tables_#{path_or_url}").with(:house, {}).once
  161 + controller.send("collection_#{path_or_url}")
  162 +
  163 + controller.expects("house_table_#{path_or_url}").with(:house, :table, {}).once
  164 + controller.send("resource_#{path_or_url}")
  165 +
  166 + controller.expects("new_house_table_#{path_or_url}").with(:house, {}).once
  167 + controller.send("new_resource_#{path_or_url}")
  168 +
  169 + controller.expects("edit_house_table_#{path_or_url}").with(:house, :table, {}).once
  170 + controller.send("edit_resource_#{path_or_url}")
  171 +
  172 + # With arg
  173 + controller.expects("house_table_#{path_or_url}").with(:house, :arg, {}).once
  174 + controller.send("resource_#{path_or_url}", :arg)
  175 +
  176 + controller.expects("edit_house_table_#{path_or_url}").with(:house, :arg, {}).once
  177 + controller.send("edit_resource_#{path_or_url}", :arg)
  178 +
  179 + # With options
  180 + controller.expects("house_table_#{path_or_url}").with(:house, :arg, :page => 1).once
  181 + controller.send("resource_#{path_or_url}", :arg, :page => 1)
  182 + end
  183 + end
  184 +
  185 + def test_url_helpers_on_not_default_belongs_to
  186 + controller = RoomsController.new
  187 + controller.instance_variable_set('@house', :house)
  188 + controller.instance_variable_set('@room', :room)
  189 +
  190 + [:url, :path].each do |path_or_url|
  191 + controller.expects("big_house_rooms_#{path_or_url}").with(:house, {}).once
  192 + controller.send("collection_#{path_or_url}")
  193 +
  194 + controller.expects("big_house_room_#{path_or_url}").with(:house, :room, {}).once
  195 + controller.send("resource_#{path_or_url}")
  196 +
  197 + controller.expects("new_big_house_room_#{path_or_url}").with(:house, {}).once
  198 + controller.send("new_resource_#{path_or_url}")
  199 +
  200 + controller.expects("edit_big_house_room_#{path_or_url}").with(:house, :room, {}).once
  201 + controller.send("edit_resource_#{path_or_url}")
  202 +
  203 + # With args
  204 + controller.expects("big_house_room_#{path_or_url}").with(:house, :arg, {}).once
  205 + controller.send("resource_#{path_or_url}", :arg)
  206 +
  207 + controller.expects("edit_big_house_room_#{path_or_url}").with(:house, :arg, {}).once
  208 + controller.send("edit_resource_#{path_or_url}", :arg)
  209 +
  210 + # With options
  211 + controller.expects("big_house_room_#{path_or_url}").with(:house, :arg, :page => 1).once
  212 + controller.send("resource_#{path_or_url}", :arg, :page => 1)
  213 + end
  214 + end
  215 +
  216 + def test_url_helpers_on_nested_belongs_to
  217 + controller = ChairsController.new
  218 + controller.instance_variable_set('@house', :house)
  219 + controller.instance_variable_set('@table', :table)
  220 + controller.instance_variable_set('@chair', :chair)
  221 +
  222 + [:url, :path].each do |path_or_url|
  223 + controller.expects("house_table_chairs_#{path_or_url}").with(:house, :table, {}).once
  224 + controller.send("collection_#{path_or_url}")
  225 +
  226 + controller.expects("house_table_chair_#{path_or_url}").with(:house, :table, :chair, {}).once
  227 + controller.send("resource_#{path_or_url}")
  228 +
  229 + controller.expects("new_house_table_chair_#{path_or_url}").with(:house, :table, {}).once
  230 + controller.send("new_resource_#{path_or_url}")
  231 +
  232 + controller.expects("edit_house_table_chair_#{path_or_url}").with(:house, :table, :chair, {}).once
  233 + controller.send("edit_resource_#{path_or_url}")
  234 +
  235 + # With args
  236 + controller.expects("edit_house_table_chair_#{path_or_url}").with(:house, :table, :arg, {}).once
  237 + controller.send("edit_resource_#{path_or_url}", :arg)
  238 +
  239 + controller.expects("house_table_chair_#{path_or_url}").with(:house, :table, :arg, {}).once
  240 + controller.send("resource_#{path_or_url}", :arg)
  241 +
  242 + # With options
  243 + controller.expects("edit_house_table_chair_#{path_or_url}").with(:house, :table, :arg, :page => 1).once
  244 + controller.send("edit_resource_#{path_or_url}", :arg, :page => 1)
  245 + end
  246 + end
  247 +
  248 + def test_url_helpers_on_singletons_with_belongs_to
  249 + controller = OwnersController.new
  250 + controller.instance_variable_set('@house', :house)
  251 + controller.instance_variable_set('@owner', :owner)
  252 +
  253 + [:url, :path].each do |path_or_url|
  254 + controller.expects("house_#{path_or_url}").with(:house, {}).once
  255 + controller.send("collection_#{path_or_url}")
  256 +
  257 + controller.expects("house_owner_#{path_or_url}").with(:house, {}).once
  258 + controller.send("resource_#{path_or_url}")
  259 +
  260 + controller.expects("new_house_owner_#{path_or_url}").with(:house, {}).once
  261 + controller.send("new_resource_#{path_or_url}")
  262 +
  263 + controller.expects("edit_house_owner_#{path_or_url}").with(:house, {}).once
  264 + controller.send("edit_resource_#{path_or_url}")
  265 +
  266 + # With options
  267 + # Also tests that argument sent are not used
  268 + controller.expects("house_owner_#{path_or_url}").with(:house, :page => 1).once
  269 + controller.send("resource_#{path_or_url}", :arg, :page => 1)
  270 + end
  271 + end
  272 +
  273 + def test_url_helpers_on_polymorphic_belongs_to
  274 + house = House.new
  275 + bed = Bed.new
  276 +
  277 + new_bed = Bed.new
  278 + Bed.stubs(:new).returns(new_bed)
  279 + new_bed.stubs(:new_record?).returns(true)
  280 +
  281 + controller = BedsController.new
  282 + controller.instance_variable_set('@parent_type', :house)
  283 + controller.instance_variable_set('@house', house)
  284 + controller.instance_variable_set('@bed', bed)
  285 +
  286 + [:url, :path].each do |path_or_url|
  287 + controller.expects("house_beds_#{path_or_url}").with(house).once
  288 + controller.send("collection_#{path_or_url}")
  289 +
  290 + controller.expects("house_bed_#{path_or_url}").with(house, bed).once
  291 + controller.send("resource_#{path_or_url}")
  292 +
  293 + controller.expects("new_house_bed_#{path_or_url}").with(house).once
  294 + controller.send("new_resource_#{path_or_url}")
  295 +
  296 + controller.expects("edit_house_bed_#{path_or_url}").with(house, bed).once
  297 + controller.send("edit_resource_#{path_or_url}")
  298 + end
  299 +
  300 + # With options
  301 + controller.expects("house_bed_url").with(house, bed, :page => 1).once
  302 + controller.send("resource_url", :page => 1)
  303 +
  304 + # With args
  305 + controller.expects("polymorphic_url").with([:arg, new_bed], {}).once
  306 + controller.send("collection_url", :arg)
  307 +
  308 + controller.expects("polymorphic_url").with([house, :arg], {}).once
  309 + controller.send("resource_url", :arg)
  310 +
  311 + controller.expects("edit_polymorphic_url").with([house, :arg], {}).once
  312 + controller.send("edit_resource_url", :arg)
  313 + end
  314 +
  315 + def test_url_helpers_on_namespaced_polymorphic_belongs_to
  316 + house = House.new
  317 + desk = Desk.new
  318 +
  319 + new_desk = Desk.new
  320 + Desk.stubs(:new).returns(new_desk)
  321 + new_desk.stubs(:new_record?).returns(true)
  322 +
  323 + controller = Admin::DesksController.new
  324 + controller.instance_variable_set('@parent_type', :house)
  325 + controller.instance_variable_set('@house', house)
  326 + controller.instance_variable_set('@desk', desk)
  327 +
  328 + [:url, :path].each do |path_or_url|
  329 + controller.expects("admin_house_desks_#{path_or_url}").with(house).once
  330 + controller.send("collection_#{path_or_url}")
  331 +
  332 + controller.expects("admin_house_desk_#{path_or_url}").with(house, desk).once
  333 + controller.send("resource_#{path_or_url}")
  334 +
  335 + controller.expects("new_admin_house_desk_#{path_or_url}").with(house).once
  336 + controller.send("new_resource_#{path_or_url}")
  337 +
  338 + controller.expects("edit_admin_house_desk_#{path_or_url}").with(house, desk).once
  339 + controller.send("edit_resource_#{path_or_url}")
  340 + end
  341 +
  342 + # With options
  343 + controller.expects("admin_house_desk_url").with(house, desk, :page => 1).once
  344 + controller.send("resource_url", :page => 1)
  345 +
  346 + # With args
  347 + controller.expects("polymorphic_url").with(['admin', :arg, new_desk], {}).once
  348 + controller.send("collection_url", :arg)
  349 +
  350 + controller.expects("polymorphic_url").with(['admin', house, :arg], {}).once
  351 + controller.send("resource_url", :arg)
  352 +
  353 + controller.expects("edit_polymorphic_url").with(['admin', house, :arg], {}).once
  354 + controller.send("edit_resource_url", :arg)
  355 + end
  356 +
  357 + def test_url_helpers_on_nested_polymorphic_belongs_to
  358 + house = House.new
  359 + table = Table.new
  360 + dish = Dish.new
  361 +
  362 + new_dish = Dish.new
  363 + Dish.stubs(:new).returns(new_dish)
  364 + new_dish.stubs(:new_record?).returns(true)
  365 +
  366 + controller = DishesController.new
  367 + controller.instance_variable_set('@parent_type', :table)
  368 + controller.instance_variable_set('@house', house)
  369 + controller.instance_variable_set('@table', table)
  370 + controller.instance_variable_set('@dish', dish)
  371 +
  372 + [:url, :path].each do |path_or_url|
  373 + controller.expects("house_table_dishes_#{path_or_url}").with(house, table).once
  374 + controller.send("collection_#{path_or_url}")
  375 +
  376 + controller.expects("house_table_dish_#{path_or_url}").with(house, table, dish).once
  377 + controller.send("resource_#{path_or_url}")
  378 +
  379 + controller.expects("new_house_table_dish_#{path_or_url}").with(house, table).once
  380 + controller.send("new_resource_#{path_or_url}")
  381 +
  382 + controller.expects("edit_house_table_dish_#{path_or_url}").with(house, table, dish).once
  383 + controller.send("edit_resource_#{path_or_url}")
  384 + end
  385 +
  386 + # With options
  387 + controller.expects("house_table_dish_url").with(house, table, dish, :page => 1).once
  388 + controller.send("resource_url", :page => 1)
  389 +
  390 + # With args
  391 + controller.expects("polymorphic_url").with([house, table, :arg], {}).once
  392 + controller.send("resource_url", :arg)
  393 +
  394 + controller.expects("edit_polymorphic_url").with([house, table, :arg], {}).once
  395 + controller.send("edit_resource_url", :arg)
  396 + end
  397 +
  398 + def test_url_helpers_on_singleton_nested_polymorphic_belongs_to
  399 + # This must not be usefull in singleton controllers...
  400 + # Center.new
  401 + house = House.new
  402 + table = Table.new
  403 +
  404 + controller = CentersController.new
  405 + controller.instance_variable_set('@parent_type', :table)
  406 + controller.instance_variable_set('@house', house)
  407 + controller.instance_variable_set('@table', table)
  408 +
  409 + # This must not be useful in singleton controllers...
  410 + # controller.instance_variable_set('@center', :center)
  411 +
  412 + [:url, :path].each do |path_or_url|
  413 + controller.expects("house_table_#{path_or_url}").with(house, table).once
  414 + controller.send("collection_#{path_or_url}")
  415 +
  416 + controller.expects("house_table_center_#{path_or_url}").with(house, table).once
  417 + controller.send("resource_#{path_or_url}")
  418 +
  419 + controller.expects("new_house_table_center_#{path_or_url}").with(house, table).once
  420 + controller.send("new_resource_#{path_or_url}")
  421 +
  422 + controller.expects("edit_house_table_center_#{path_or_url}").with(house, table).once
  423 + controller.send("edit_resource_#{path_or_url}")
  424 + end
  425 +
  426 + # With options
  427 + controller.expects("house_table_center_url").with(house, table, :page => 1)
  428 + controller.send("resource_url", :page => 1)
  429 +
  430 + # With args
  431 + controller.expects("polymorphic_url").with([house, table, :center], {}).once
  432 + controller.send("resource_url", :arg)
  433 + end
  434 +
  435 + def test_url_helpers_on_optional_polymorphic_belongs_to
  436 + bed = Bed.new
  437 + new_bed = Bed.new
  438 + Bed.stubs(:new).returns(new_bed)
  439 + new_bed.stubs(:new_record?).returns(true)
  440 +
  441 + controller = BedsController.new
  442 + controller.instance_variable_set('@parent_type', nil)
  443 + controller.instance_variable_set('@bed', bed)
  444 +
  445 + [:url, :path].each do |path_or_url|
  446 + controller.expects("beds_#{path_or_url}").with().once
  447 + controller.send("collection_#{path_or_url}")
  448 +
  449 + controller.expects("bed_#{path_or_url}").with(bed).once
  450 + controller.send("resource_#{path_or_url}")
  451 +
  452 + controller.expects("new_bed_#{path_or_url}").with().once
  453 + controller.send("new_resource_#{path_or_url}")
  454 +
  455 + controller.expects("edit_bed_#{path_or_url}").with(bed).once
  456 + controller.send("edit_resource_#{path_or_url}")
  457 + end
  458 +
  459 + # With options
  460 + controller.expects("bed_url").with(bed, :page => 1).once
  461 + controller.send("resource_url", :page => 1)
  462 +
  463 + # With args
  464 + controller.expects("polymorphic_url").with([:arg], {}).once
  465 + controller.send("resource_url", :arg)
  466 +
  467 + controller.expects("edit_polymorphic_url").with([:arg], {}).once
  468 + controller.send("edit_resource_url", :arg)
  469 + end
  470 +
  471 +end
... ...